diff --git a/python/gui/qgscompoundcolorwidget.sip.in b/python/gui/qgscompoundcolorwidget.sip.in index e61be858bb2..d43760fd0b4 100644 --- a/python/gui/qgscompoundcolorwidget.sip.in +++ b/python/gui/qgscompoundcolorwidget.sip.in @@ -65,6 +65,45 @@ be stored in the recent color list. :param discarded: set to true to avoid adding color to recent color list on widget destruction. .. versionadded:: 3.0 +%End + + static QgsUserColorScheme *importUserPaletteFromFile( QWidget *parent ); +%Docstring +Triggers a user prompt for importing a new color scheme from an existing GPL file. + +The ``parent`` argument must be set to a valid parent widget for the dialog prompts. + +.. versionadded:: 3.2 + +.. seealso:: :py:func:`createNewUserPalette` + +.. seealso:: :py:func:`removeUserPalette` +%End + + static QgsUserColorScheme *createNewUserPalette( QWidget *parent ); +%Docstring +Triggers a user prompt for creating a new user color scheme. + +The ``parent`` argument must be set to a valid parent widget for the dialog prompts. + +.. versionadded:: 3.2 + +.. seealso:: :py:func:`importUserPaletteFromFile` + +.. seealso:: :py:func:`removeUserPalette` +%End + + static bool removeUserPalette( QgsUserColorScheme *scheme, QWidget *parent ); +%Docstring +Triggers a user prompt for removing an existing user color ``scheme``. + +The ``parent`` argument must be set to a valid parent widget for the dialog prompts. + +.. versionadded:: 3.2 + +.. seealso:: :py:func:`importUserPaletteFromFile` + +.. seealso:: :py:func:`createNewUserPalette` %End signals: diff --git a/src/app/qgsoptions.cpp b/src/app/qgsoptions.cpp index 531574b540a..023028acc59 100644 --- a/src/app/qgsoptions.cpp +++ b/src/app/qgsoptions.cpp @@ -754,6 +754,66 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListsetCurrentIndex( mColorSchemesComboBox->count() - 1 ); + } + } ); + connect( mActionRemovePalette, &QAction::triggered, this, [ = ] + { + //get current scheme + QList schemeList = QgsApplication::colorSchemeRegistry()->schemes(); + int prevIndex = mColorSchemesComboBox->currentIndex(); + if ( prevIndex >= schemeList.length() ) + { + return; + } + + //make user scheme is a user removable scheme + QgsUserColorScheme *userScheme = dynamic_cast( schemeList.at( prevIndex ) ); + if ( !userScheme ) + { + return; + } + + if ( QgsCompoundColorWidget::removeUserPalette( userScheme, this ) ) + { + refreshSchemeComboBox(); + prevIndex = std::max( std::min( prevIndex, mColorSchemesComboBox->count() - 1 ), 0 ); + mColorSchemesComboBox->setCurrentIndex( prevIndex ); + } + } ); + connect( mActionNewPalette, &QAction::triggered, this, [ = ] + { + if ( QgsCompoundColorWidget::createNewUserPalette( this ) ) + { + //refresh combobox + refreshSchemeComboBox(); + mColorSchemesComboBox->setCurrentIndex( mColorSchemesComboBox->count() - 1 ); + } + } ); + + connect( mActionShowInButtons, &QAction::toggled, this, [ = ]( bool state ) + { + QgsUserColorScheme *scheme = dynamic_cast< QgsUserColorScheme * >( mTreeCustomColors->scheme() ); + if ( scheme ) + { + scheme->setShowSchemeInMenu( state ); + } + } ); + + QMenu *schemeMenu = new QMenu( mSchemeToolButton ); + schemeMenu->addAction( mActionNewPalette ); + schemeMenu->addAction( mActionImportPalette ); + schemeMenu->addAction( mActionRemovePalette ); + schemeMenu->addSeparator(); + schemeMenu->addAction( mActionShowInButtons ); + mSchemeToolButton->setMenu( schemeMenu ); + //find custom color scheme from registry refreshSchemeComboBox(); QList customSchemes; @@ -762,6 +822,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListsetScheme( customSchemes.at( 0 ) ); mColorSchemesComboBox->setCurrentIndex( mColorSchemesComboBox->findText( customSchemes.at( 0 )->schemeName() ) ); + updateActionsForCurrentColorScheme( customSchemes.at( 0 ) ); } connect( mColorSchemesComboBox, static_cast( &QComboBox::currentIndexChanged ), this, [ = ]( int index ) { @@ -774,8 +835,9 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListschemes().value( index ); if ( scheme ) mTreeCustomColors->setScheme( scheme ); - } ); + updateActionsForCurrentColorScheme( scheme ); + } ); // // Layout settings @@ -2272,6 +2334,27 @@ void QgsOptions::refreshSchemeComboBox() mColorSchemesComboBox->blockSignals( false ); } +void QgsOptions::updateActionsForCurrentColorScheme( QgsColorScheme *scheme ) +{ + mButtonImportColors->setEnabled( scheme->isEditable() ); + mButtonPasteColors->setEnabled( scheme->isEditable() ); + mButtonAddColor->setEnabled( scheme->isEditable() ); + mButtonRemoveColor->setEnabled( scheme->isEditable() ); + + QgsUserColorScheme *userScheme = dynamic_cast( scheme ); + mActionRemovePalette->setEnabled( static_cast< bool >( userScheme ) && userScheme->isEditable() ); + if ( userScheme ) + { + mActionShowInButtons->setEnabled( true ); + whileBlocking( mActionShowInButtons )->setChecked( userScheme->flags() & QgsColorScheme::ShowInColorButtonMenu ); + } + else + { + whileBlocking( mActionShowInButtons )->setChecked( false ); + mActionShowInButtons->setEnabled( false ); + } +} + void QgsOptions::scaleItemChanged( QListWidgetItem *changedScaleItem ) { // Check if the new value is valid, restore the old value if not. diff --git a/src/app/qgsoptions.h b/src/app/qgsoptions.h index c370b5bc987..d8d12e7f187 100644 --- a/src/app/qgsoptions.h +++ b/src/app/qgsoptions.h @@ -264,6 +264,10 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption QList< QgsOptionsPageWidget * > mAdditionalOptionWidgets; QgsLocatorOptionsWidget *mLocatorOptionsWidget = nullptr; + + void updateActionsForCurrentColorScheme( QgsColorScheme *scheme ); + + }; #endif // #ifndef QGSOPTIONS_H diff --git a/src/core/qgscolorscheme.cpp b/src/core/qgscolorscheme.cpp index 0301ce276ce..cea419a69ac 100644 --- a/src/core/qgscolorscheme.cpp +++ b/src/core/qgscolorscheme.cpp @@ -303,8 +303,6 @@ QgsUserColorScheme::QgsUserColorScheme( const QString &filename ) : mFilename( filename ) { QFile sourceFile( gplFilePath() ); - QFileInfo sourceFileInfo( gplFilePath() ); - mEditable = sourceFileInfo.isWritable(); //read in name if ( sourceFile.open( QIODevice::ReadOnly ) ) @@ -394,7 +392,7 @@ void QgsUserColorScheme::setShowSchemeInMenu( bool show ) QString QgsUserColorScheme::gplFilePath() { - QString palettesDir = QgsApplication::qgisSettingsDirPath() + "/palettes"; + QString palettesDir = QgsApplication::qgisSettingsDirPath() + "palettes"; QDir localDir; if ( !localDir.mkpath( palettesDir ) ) diff --git a/src/core/qgscolorschemeregistry.cpp b/src/core/qgscolorschemeregistry.cpp index 24d59fa2f4a..85a1874659c 100644 --- a/src/core/qgscolorschemeregistry.cpp +++ b/src/core/qgscolorschemeregistry.cpp @@ -64,7 +64,7 @@ void QgsColorSchemeRegistry::initStyleScheme() void QgsColorSchemeRegistry::addUserSchemes() { - QString palettesDir = QgsApplication::qgisSettingsDirPath() + "/palettes"; + QString palettesDir = QgsApplication::qgisSettingsDirPath() + "palettes"; QDir localDir; if ( !localDir.mkpath( palettesDir ) ) diff --git a/src/gui/qgscompoundcolorwidget.cpp b/src/gui/qgscompoundcolorwidget.cpp index a7dbb775011..0adf991e563 100644 --- a/src/gui/qgscompoundcolorwidget.cpp +++ b/src/gui/qgscompoundcolorwidget.cpp @@ -280,15 +280,17 @@ void QgsCompoundColorWidget::refreshSchemeComboBox() mSchemeComboBox->blockSignals( false ); } -void QgsCompoundColorWidget::importPalette() + +QgsUserColorScheme *QgsCompoundColorWidget::importUserPaletteFromFile( QWidget *parent ) { QgsSettings s; QString lastDir = s.value( QStringLiteral( "/UI/lastGplPaletteDir" ), QDir::homePath() ).toString(); - QString filePath = QFileDialog::getOpenFileName( this, tr( "Select Palette File" ), lastDir, QStringLiteral( "GPL (*.gpl);;All files (*.*)" ) ); - activateWindow(); + QString filePath = QFileDialog::getOpenFileName( parent, tr( "Select Palette File" ), lastDir, QStringLiteral( "GPL (*.gpl);;All files (*.*)" ) ); + if ( parent ) + parent->activateWindow(); if ( filePath.isEmpty() ) { - return; + return nullptr; } //check if file exists @@ -296,7 +298,7 @@ void QgsCompoundColorWidget::importPalette() if ( !fileInfo.exists() || !fileInfo.isReadable() ) { QMessageBox::critical( nullptr, tr( "Import Color Palette" ), tr( "Error, file does not exist or is not readable." ) ); - return; + return nullptr; } s.setValue( QStringLiteral( "/UI/lastGplPaletteDir" ), fileInfo.absolutePath() ); @@ -309,14 +311,14 @@ void QgsCompoundColorWidget::importPalette() if ( !ok ) { QMessageBox::critical( nullptr, tr( "Import Color Palette" ), tr( "Palette file is not readable." ) ); - return; + return nullptr; } if ( importedColors.length() == 0 ) { //no imported colors QMessageBox::critical( nullptr, tr( "Import Color Palette" ), tr( "No colors found in palette file." ) ); - return; + return nullptr; } //TODO - handle conflicting file names, name for new palette @@ -325,10 +327,40 @@ void QgsCompoundColorWidget::importPalette() importedScheme->setColors( importedColors ); QgsApplication::colorSchemeRegistry()->addColorScheme( importedScheme ); + return importedScheme; +} - //refresh combobox - refreshSchemeComboBox(); - mSchemeComboBox->setCurrentIndex( mSchemeComboBox->count() - 1 ); +void QgsCompoundColorWidget::importPalette() +{ + if ( importUserPaletteFromFile( this ) ) + { + //refresh combobox + refreshSchemeComboBox(); + mSchemeComboBox->setCurrentIndex( mSchemeComboBox->count() - 1 ); + } +} + + +bool QgsCompoundColorWidget::removeUserPalette( QgsUserColorScheme *scheme, QWidget *parent ) +{ + if ( QMessageBox::question( parent, tr( "Remove Color Palette" ), + QString( tr( "Are you sure you want to remove %1?" ) ).arg( scheme->schemeName() ), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes ) + { + //user canceled + return false; + } + + //remove palette and associated gpl file + if ( !scheme->erase() ) + { + //something went wrong + return false; + } + + //remove scheme from registry + QgsApplication::colorSchemeRegistry()->removeColorScheme( scheme ); + return true; } void QgsCompoundColorWidget::removePalette() @@ -348,41 +380,27 @@ void QgsCompoundColorWidget::removePalette() return; } - if ( QMessageBox::question( this, tr( "Remove Color Palette" ), - QString( tr( "Are you sure you want to remove %1?" ) ).arg( userScheme->schemeName() ), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes ) + if ( removeUserPalette( userScheme, this ) ) { - //user canceled - return; + refreshSchemeComboBox(); + prevIndex = std::max( std::min( prevIndex, mSchemeComboBox->count() - 1 ), 0 ); + mSchemeComboBox->setCurrentIndex( prevIndex ); } - - //remove palette and associated gpl file - if ( !userScheme->erase() ) - { - //something went wrong - return; - } - - //remove scheme from registry - QgsApplication::colorSchemeRegistry()->removeColorScheme( userScheme ); - refreshSchemeComboBox(); - prevIndex = std::max( std::min( prevIndex, mSchemeComboBox->count() - 1 ), 0 ); - mSchemeComboBox->setCurrentIndex( prevIndex ); } -void QgsCompoundColorWidget::newPalette() +QgsUserColorScheme *QgsCompoundColorWidget::createNewUserPalette( QWidget *parent ) { bool ok = false; - QString name = QInputDialog::getText( this, tr( "Create New Palette" ), tr( "Enter a name for the new palette:" ), + QString name = QInputDialog::getText( parent, tr( "Create New Palette" ), tr( "Enter a name for the new palette:" ), QLineEdit::Normal, tr( "New palette" ), &ok ); if ( !ok || name.isEmpty() ) { //user canceled - return; + return nullptr; } - //generate file name for new palette +//generate file name for new palette QDir palettePath( gplFilePath() ); QRegExp badChars( "[,^@={}\\[\\]~!?:&*\"|#%<>$\"'();`' /\\\\]" ); QString filename = name.simplified().toLower().replace( badChars, QStringLiteral( "_" ) ); @@ -403,15 +421,22 @@ void QgsCompoundColorWidget::newPalette() newScheme->setName( name ); QgsApplication::colorSchemeRegistry()->addColorScheme( newScheme ); + return newScheme; +} - //refresh combobox and set new scheme as active - refreshSchemeComboBox(); - mSchemeComboBox->setCurrentIndex( mSchemeComboBox->count() - 1 ); +void QgsCompoundColorWidget::newPalette() +{ + if ( createNewUserPalette( this ) ) + { + //refresh combobox and set new scheme as active + refreshSchemeComboBox(); + mSchemeComboBox->setCurrentIndex( mSchemeComboBox->count() - 1 ); + } } QString QgsCompoundColorWidget::gplFilePath() { - QString palettesDir = QgsApplication::qgisSettingsDirPath() + "/palettes"; + QString palettesDir = QgsApplication::qgisSettingsDirPath() + "palettes"; QDir localDir; if ( !localDir.mkpath( palettesDir ) ) diff --git a/src/gui/qgscompoundcolorwidget.h b/src/gui/qgscompoundcolorwidget.h index 1ab9ed381a0..5d0ec2a8ea2 100644 --- a/src/gui/qgscompoundcolorwidget.h +++ b/src/gui/qgscompoundcolorwidget.h @@ -76,6 +76,42 @@ class GUI_EXPORT QgsCompoundColorWidget : public QgsPanelWidget, private Ui::Qgs */ void setDiscarded( bool discarded ) { mDiscarded = discarded; } + /** + * Triggers a user prompt for importing a new color scheme from an existing GPL file. + * + * The \a parent argument must be set to a valid parent widget for the dialog prompts. + * + * \since QGIS 3.2 + * + * \see createNewUserPalette() + * \see removeUserPalette() + */ + static QgsUserColorScheme *importUserPaletteFromFile( QWidget *parent ); + + /** + * Triggers a user prompt for creating a new user color scheme. + * + * The \a parent argument must be set to a valid parent widget for the dialog prompts. + * + * \since QGIS 3.2 + * + * \see importUserPaletteFromFile() + * \see removeUserPalette() + */ + static QgsUserColorScheme *createNewUserPalette( QWidget *parent ); + + /** + * Triggers a user prompt for removing an existing user color \a scheme. + * + * The \a parent argument must be set to a valid parent widget for the dialog prompts. + * + * \since QGIS 3.2 + * + * \see importUserPaletteFromFile() + * \see createNewUserPalette() + */ + static bool removeUserPalette( QgsUserColorScheme *scheme, QWidget *parent ); + signals: /** @@ -182,7 +218,7 @@ class GUI_EXPORT QgsCompoundColorWidget : public QgsPanelWidget, private Ui::Qgs /** * Returns the path to the user's palette folder */ - QString gplFilePath(); + static QString gplFilePath(); //! Updates the state of actions for the current selected scheme void updateActionsForCurrentScheme(); diff --git a/src/ui/qgsoptionsbase.ui b/src/ui/qgsoptionsbase.ui index 49d5a379de9..509086ba144 100644 --- a/src/ui/qgsoptionsbase.ui +++ b/src/ui/qgsoptionsbase.ui @@ -320,7 +320,7 @@ - 0 + 7 @@ -1040,7 +1040,7 @@ 0 0 - 579 + 843 1110 @@ -1576,8 +1576,8 @@ 0 0 - 593 - 387 + 857 + 826 @@ -1743,8 +1743,8 @@ 0 0 - 531 - 787 + 857 + 826 @@ -2111,7 +2111,7 @@ 0 0 - 713 + 843 1110 @@ -2862,8 +2862,8 @@ 0 0 - 523 - 246 + 857 + 826 @@ -3119,8 +3119,8 @@ 0 0 - 640 - 660 + 857 + 826 @@ -3563,8 +3563,8 @@ The bigger the number, the faster zooming with the mouse wheel will be. 0 0 - 151 - 239 + 857 + 826 @@ -3601,6 +3601,13 @@ The bigger the number, the faster zooming with the mouse wheel will be. + + + + Qt::StrongFocus + + + @@ -3629,13 +3636,6 @@ The bigger the number, the faster zooming with the mouse wheel will be. - - - - Qt::StrongFocus - - - @@ -3664,6 +3664,13 @@ The bigger the number, the faster zooming with the mouse wheel will be. + + + + + + + @@ -3678,12 +3685,15 @@ The bigger the number, the faster zooming with the mouse wheel will be. - - - - - - + + + + + + + QToolButton::InstantPopup + + @@ -5259,9 +5269,53 @@ The bigger the number, the faster zooming with the mouse wheel will be. + + + Import Palette... + + + Import palette from file + + + + + Remove Palette + + + Remove current palette + + + + + New Palette... + + + Create a new palette + + + + + true + + + Show in Color Buttons + + + + QgsColorButton + QToolButton +
qgscolorbutton.h
+ 1 +
+ + QgsColorSchemeList + QWidget +
qgscolorschemelist.h
+ 1 +
QgsCollapsibleGroupBox QGroupBox @@ -5280,12 +5334,6 @@ The bigger the number, the faster zooming with the mouse wheel will be.
qgsprojectionselectionwidget.h
1
- - QgsColorButton - QToolButton -
qgscolorbutton.h
- 1 -
QgsSpinBox QSpinBox @@ -5307,12 +5355,6 @@ The bigger the number, the faster zooming with the mouse wheel will be. QLineEdit
qgsfilterlineedit.h
- - QgsColorSchemeList - QWidget -
qgscolorschemelist.h
- 1 -
QgsSettingsTree QWidget