Move internals of QgsColorDialogV2 to new QgsCompoundColorWidget widget

This allows reuse of the full options from the color dialog when
required in a widget form.
This commit is contained in:
Nyall Dawson 2016-04-03 17:10:28 +10:00
parent 0332157d8a
commit 77fc122bed
10 changed files with 2031 additions and 1676 deletions

View File

@ -53,6 +53,7 @@
%Include qgscomposeritemcombobox.sip
%Include qgscomposerruler.sip
%Include qgscomposerview.sip
%Include qgscompoundcolorwidget.sip
%Include qgscredentialdialog.sip
%Include qgsdatadefinedbutton.sip
%Include qgsdetaileditemdata.sip

View File

@ -114,11 +114,4 @@ class QgsColorDialogV2 : QDialog
void closeEvent( QCloseEvent* e );
void mousePressEvent( QMouseEvent* e );
void mouseMoveEvent( QMouseEvent *e );
void mouseReleaseEvent( QMouseEvent *e );
void keyPressEvent( QKeyEvent *e );
};

View File

@ -0,0 +1,64 @@
/** \ingroup gui
* \class QgsCompoundColorWidget
* A custom QGIS widget for selecting a color, including options for selecting colors via
* hue wheel, color swatches, and a color sampler.
* \note Added in version 2.16
*/
class QgsCompoundColorWidget : QWidget
{
%TypeHeaderCode
#include <qgscompoundcolorwidget.h>
%End
public:
/** Constructor for QgsCompoundColorWidget
* @param parent parent widget
* @param color initial color for dialog
*/
QgsCompoundColorWidget( QWidget *parent /TransferThis/ = nullptr, const QColor& color = QColor() );
~QgsCompoundColorWidget();
/** Returns the current color for the dialog
* @returns dialog color
*/
QColor color() const;
/** Sets whether alpha modification (transparency) is permitted
* for the color dialog. Defaults to true.
* @param allowAlpha set to false to disable alpha modification
*/
void setAllowAlpha( const bool allowAlpha );
signals:
/** Emitted when the dialog's color changes
* @param color current color
*/
void currentColorChanged( const QColor &color );
public slots:
/** Sets the current color for the dialog
* @param color desired color
*/
void setColor( const QColor &color );
/** Sets the color to show in an optional "previous color" section
* @param color previous color
*/
void setPreviousColor( const QColor& color );
protected:
void mousePressEvent( QMouseEvent* e );
void mouseMoveEvent( QMouseEvent *e );
void mouseReleaseEvent( QMouseEvent *e );
void keyPressEvent( QKeyEvent *e );
};

View File

@ -181,6 +181,7 @@ SET(QGIS_GUI_SRCS
qgscomposeritemcombobox.cpp
qgscomposerruler.cpp
qgscomposerview.cpp
qgscompoundcolorwidget.cpp
qgscredentialdialog.cpp
qgscursors.cpp
qgsdatadefinedbutton.cpp
@ -328,6 +329,7 @@ SET(QGIS_GUI_MOC_HDRS
qgscomposeritemcombobox.h
qgscomposerruler.h
qgscomposerview.h
qgscompoundcolorwidget.h
qgscredentialdialog.h
qgsdatadefinedbutton.h
qgsdatumtransformdialog.h

View File

@ -69,208 +69,27 @@ QColor QgsColorDialog::getLiveColor( const QColor& initialColor, QObject* update
QgsColorDialogV2::QgsColorDialogV2( QWidget *parent, const Qt::WindowFlags& fl, const QColor& color )
: QDialog( parent, fl )
, mPreviousColor( color )
, mAllowAlpha( true )
, mLastCustomColorIndex( 0 )
, mPickingColor( false )
{
setupUi( this );
QSettings settings;
restoreGeometry( settings.value( "/Windows/ColorDialog/geometry" ).toByteArray() );
mSchemeList->header()->hide();
mSchemeList->setColumnWidth( 0, 44 );
//get schemes with ShowInColorDialog set
refreshSchemeComboBox();
QList<QgsColorScheme *> schemeList = QgsColorSchemeRegistry::instance()->schemes( QgsColorScheme::ShowInColorDialog );
//choose a reasonable starting scheme
int activeScheme = settings.value( "/Windows/ColorDialog/activeScheme", 0 ).toInt();
activeScheme = activeScheme >= mSchemeComboBox->count() ? 0 : activeScheme;
mSchemeList->setScheme( schemeList.at( activeScheme ) );
mSchemeComboBox->setCurrentIndex( activeScheme );
mActionImportColors->setEnabled( schemeList.at( activeScheme )->isEditable() );
mActionPasteColors->setEnabled( schemeList.at( activeScheme )->isEditable() );
mAddColorToSchemeButton->setEnabled( schemeList.at( activeScheme )->isEditable() );
mRemoveColorsFromSchemeButton->setEnabled( schemeList.at( activeScheme )->isEditable() );
QgsUserColorScheme* userScheme = dynamic_cast<QgsUserColorScheme*>( schemeList.at( activeScheme ) );
mActionRemovePalette->setEnabled( userScheme ? true : false );
//listen out for selection changes in list, so we can enable/disable the copy colors option
connect( mSchemeList->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), this, SLOT( listSelectionChanged( QItemSelection, QItemSelection ) ) );
//copy action defaults to disabled
mActionCopyColors->setEnabled( false );
connect( mActionCopyColors, SIGNAL( triggered() ), mSchemeList, SLOT( copyColors() ) );
connect( mActionPasteColors, SIGNAL( triggered() ), mSchemeList, SLOT( pasteColors() ) );
connect( mActionExportColors, SIGNAL( triggered() ), this, SLOT( exportColors() ) );
connect( mActionImportColors, SIGNAL( triggered() ), this, SLOT( importColors() ) );
connect( mActionImportPalette, SIGNAL( triggered() ), this, SLOT( importPalette() ) );
connect( mActionRemovePalette, SIGNAL( triggered() ), this, SLOT( removePalette() ) );
connect( mActionNewPalette, SIGNAL( triggered() ), this, SLOT( newPalette() ) );
connect( mRemoveColorsFromSchemeButton, SIGNAL( clicked() ), mSchemeList, SLOT( removeSelection() ) );
QMenu* schemeMenu = new QMenu( mSchemeToolButton );
schemeMenu->addAction( mActionCopyColors );
schemeMenu->addAction( mActionPasteColors );
schemeMenu->addSeparator();
schemeMenu->addAction( mActionImportColors );
schemeMenu->addAction( mActionExportColors );
schemeMenu->addSeparator();
schemeMenu->addAction( mActionNewPalette );
schemeMenu->addAction( mActionImportPalette );
schemeMenu->addAction( mActionRemovePalette );
mSchemeToolButton->setMenu( schemeMenu );
connect( mSchemeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( schemeIndexChanged( int ) ) );
connect( mSchemeList, SIGNAL( colorSelected( QColor ) ), this, SLOT( setColor( QColor ) ) );
if ( mPreviousColor.isValid() )
{
QPushButton* resetButton = new QPushButton( tr( "Reset" ) );
mButtonBox->addButton( resetButton, QDialogButtonBox::ResetRole );
}
else
{
mOldColorLabel->hide();
}
mVerticalRamp->setOrientation( QgsColorRampWidget::Vertical );
mVerticalRamp->setInteriorMargin( 2 );
mVerticalRamp->setShowFrame( true );
mRedSlider->setComponent( QgsColorWidget::Red );
mGreenSlider->setComponent( QgsColorWidget::Green );
mBlueSlider->setComponent( QgsColorWidget::Blue );
mHueSlider->setComponent( QgsColorWidget::Hue );
mSaturationSlider->setComponent( QgsColorWidget::Saturation );
mValueSlider->setComponent( QgsColorWidget::Value );
mAlphaSlider->setComponent( QgsColorWidget::Alpha );
mSwatchButton1->setShowMenu( false );
mSwatchButton1->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton2->setShowMenu( false );
mSwatchButton2->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton3->setShowMenu( false );
mSwatchButton3->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton4->setShowMenu( false );
mSwatchButton4->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton5->setShowMenu( false );
mSwatchButton5->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton6->setShowMenu( false );
mSwatchButton6->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton7->setShowMenu( false );
mSwatchButton7->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton8->setShowMenu( false );
mSwatchButton8->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton9->setShowMenu( false );
mSwatchButton9->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton10->setShowMenu( false );
mSwatchButton10->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton11->setShowMenu( false );
mSwatchButton11->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton12->setShowMenu( false );
mSwatchButton12->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton13->setShowMenu( false );
mSwatchButton13->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton14->setShowMenu( false );
mSwatchButton14->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton15->setShowMenu( false );
mSwatchButton15->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton16->setShowMenu( false );
mSwatchButton16->setBehaviour( QgsColorButtonV2::SignalOnly );
//restore custom colors
mSwatchButton1->setColor( settings.value( "/Windows/ColorDialog/customColor1", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton2->setColor( settings.value( "/Windows/ColorDialog/customColor2", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton3->setColor( settings.value( "/Windows/ColorDialog/customColor3", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton4->setColor( settings.value( "/Windows/ColorDialog/customColor4", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton5->setColor( settings.value( "/Windows/ColorDialog/customColor5", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton6->setColor( settings.value( "/Windows/ColorDialog/customColor6", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton7->setColor( settings.value( "/Windows/ColorDialog/customColor7", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton8->setColor( settings.value( "/Windows/ColorDialog/customColor8", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton9->setColor( settings.value( "/Windows/ColorDialog/customColor9", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton10->setColor( settings.value( "/Windows/ColorDialog/customColor10", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton11->setColor( settings.value( "/Windows/ColorDialog/customColor11", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton12->setColor( settings.value( "/Windows/ColorDialog/customColor12", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton13->setColor( settings.value( "/Windows/ColorDialog/customColor13", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton14->setColor( settings.value( "/Windows/ColorDialog/customColor14", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton15->setColor( settings.value( "/Windows/ColorDialog/customColor15", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton16->setColor( settings.value( "/Windows/ColorDialog/customColor16", QVariant( QColor() ) ).value<QColor>() );
//restore sample radius
mSpinBoxRadius->setValue( settings.value( "/Windows/ColorDialog/sampleRadius", 1 ).toInt() );
mSamplePreview->setColor( QColor() );
if ( color.isValid() )
{
setColor( color );
mColorPreview->setColor2( color );
mColorWidget->setColor( color );
mColorWidget->setPreviousColor( color );
}
//restore active component radio button
int activeRadio = settings.value( "/Windows/ColorDialog/activeComponent", 2 ).toInt();
switch ( activeRadio )
{
case 0:
mHueRadio->setChecked( true );
break;
case 1:
mSaturationRadio->setChecked( true );
break;
case 2:
mValueRadio->setChecked( true );
break;
case 3:
mRedRadio->setChecked( true );
break;
case 4:
mGreenRadio->setChecked( true );
break;
case 5:
mBlueRadio->setChecked( true );
break;
}
int currentTab = settings.value( "/Windows/ColorDialog/activeTab", 0 ).toInt();
mTabWidget->setCurrentIndex( currentTab );
mColorWidget->setAllowAlpha( true );
#ifdef Q_OS_MAC
//disable color picker tab for OSX, as it is impossible to grab the mouse under OSX
//see note for QWidget::grabMouse() re OSX Cocoa
//http://qt-project.org/doc/qt-4.8/qwidget.html#grabMouse
mTabWidget->removeTab( 3 );
#endif
//setup connections
connect( mColorBox, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mColorWheel, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mColorText, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mVerticalRamp, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mRedSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mGreenSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mBlueSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mHueSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mValueSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSaturationSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mAlphaSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mColorPreview, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton1, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton2, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton3, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton4, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton5, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton6, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton7, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton8, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton9, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton10, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton11, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton12, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton13, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton14, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton15, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton16, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mColorWidget, SIGNAL( currentColorChanged( QColor ) ), this, SIGNAL( currentColorChanged( QColor ) ) );
}
QgsColorDialogV2::~QgsColorDialogV2()
@ -280,9 +99,7 @@ QgsColorDialogV2::~QgsColorDialogV2()
QColor QgsColorDialogV2::color() const
{
//all widgets should have the same color, so it shouldn't matter
//which we fetch it from
return mColorPreview->color();
return mColorWidget->color();
}
void QgsColorDialogV2::setTitle( const QString& title )
@ -293,13 +110,7 @@ void QgsColorDialogV2::setTitle( const QString& title )
void QgsColorDialogV2::setAllowAlpha( const bool allowAlpha )
{
mAllowAlpha = allowAlpha;
mAlphaLabel->setVisible( allowAlpha );
mAlphaSlider->setVisible( allowAlpha );
if ( !allowAlpha )
{
mAlphaLayout->setContentsMargins( 0, 0, 0, 0 );
mAlphaLayout->setSpacing( 0 );
}
mColorWidget->setAllowAlpha( allowAlpha );
}
QColor QgsColorDialogV2::getLiveColor( const QColor &initialColor, QObject *updateObject, const char *updateSlot, QWidget *parent, const QString &title, const bool allowAlpha )
@ -376,410 +187,10 @@ void QgsColorDialogV2::on_mButtonBox_clicked( QAbstractButton * button )
}
}
void QgsColorDialogV2::importColors()
{
QSettings s;
QString lastDir = s.value( "/UI/lastGplPaletteDir", QDir::homePath() ).toString();
QString filePath = QFileDialog::getOpenFileName( this, tr( "Select palette file" ), lastDir, "GPL (*.gpl);;All files (*.*)" );
activateWindow();
if ( filePath.isEmpty() )
{
return;
}
//check if file exists
QFileInfo fileInfo( filePath );
if ( !fileInfo.exists() || !fileInfo.isReadable() )
{
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "Error, file does not exist or is not readable" ) );
return;
}
s.setValue( "/UI/lastGplPaletteDir", fileInfo.absolutePath() );
QFile file( filePath );
bool importOk = mSchemeList->importColorsFromGpl( file );
if ( !importOk )
{
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "Error, no colors found in palette file" ) );
return;
}
}
void QgsColorDialogV2::refreshSchemeComboBox()
{
mSchemeComboBox->blockSignals( true );
mSchemeComboBox->clear();
QList<QgsColorScheme *> schemeList = QgsColorSchemeRegistry::instance()->schemes( QgsColorScheme::ShowInColorDialog );
QList<QgsColorScheme *>::const_iterator schemeIt = schemeList.constBegin();
for ( ; schemeIt != schemeList.constEnd(); ++schemeIt )
{
mSchemeComboBox->addItem(( *schemeIt )->schemeName() );
}
mSchemeComboBox->blockSignals( false );
}
void QgsColorDialogV2::importPalette()
{
QSettings s;
QString lastDir = s.value( "/UI/lastGplPaletteDir", QDir::homePath() ).toString();
QString filePath = QFileDialog::getOpenFileName( this, tr( "Select palette file" ), lastDir, "GPL (*.gpl);;All files (*.*)" );
activateWindow();
if ( filePath.isEmpty() )
{
return;
}
//check if file exists
QFileInfo fileInfo( filePath );
if ( !fileInfo.exists() || !fileInfo.isReadable() )
{
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "Error, file does not exist or is not readable" ) );
return;
}
s.setValue( "/UI/lastGplPaletteDir", fileInfo.absolutePath() );
QFile file( filePath );
QgsNamedColorList importedColors;
bool ok = false;
QString paletteName;
importedColors = QgsSymbolLayerV2Utils::importColorsFromGpl( file, ok, paletteName );
if ( !ok )
{
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "Palette file is not readable" ) );
return;
}
if ( importedColors.length() == 0 )
{
//no imported colors
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "No colors found in palette file" ) );
return;
}
//TODO - handle conflicting file names, name for new palette
QgsUserColorScheme* importedScheme = new QgsUserColorScheme( fileInfo.fileName() );
importedScheme->setName( paletteName );
importedScheme->setColors( importedColors );
QgsColorSchemeRegistry::instance()->addColorScheme( importedScheme );
//refresh combobox
refreshSchemeComboBox();
mSchemeComboBox->setCurrentIndex( mSchemeComboBox->count() - 1 );
}
void QgsColorDialogV2::removePalette()
{
//get current scheme
QList<QgsColorScheme *> schemeList = QgsColorSchemeRegistry::instance()->schemes( QgsColorScheme::ShowInColorDialog );
int prevIndex = mSchemeComboBox->currentIndex();
if ( prevIndex >= schemeList.length() )
{
return;
}
//make user scheme is a user removable scheme
QgsUserColorScheme* userScheme = dynamic_cast<QgsUserColorScheme*>( schemeList.at( prevIndex ) );
if ( !userScheme )
{
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 )
{
//user cancelled
return;
}
//remove palette and associated gpl file
if ( !userScheme->erase() )
{
//something went wrong
return;
}
//remove scheme from registry
QgsColorSchemeRegistry::instance()->removeColorScheme( userScheme );
refreshSchemeComboBox();
prevIndex = qMax( qMin( prevIndex, mSchemeComboBox->count() - 1 ), 0 );
mSchemeComboBox->setCurrentIndex( prevIndex );
}
void QgsColorDialogV2::newPalette()
{
bool ok = false;
QString name = QInputDialog::getText( this, tr( "Create New Palette" ), tr( "Enter a name for the new palette:" ),
QLineEdit::Normal, tr( "New palette" ), &ok );
if ( !ok || name.isEmpty() )
{
//user cancelled
return;
}
//generate file name for new palette
QDir palettePath( gplFilePath() );
QRegExp badChars( "[,^@={}\\[\\]~!?:&*\"|#%<>$\"'();`' /\\\\]" );
QString filename = name.simplified().toLower().replace( badChars, QLatin1String( "_" ) );
if ( filename.isEmpty() )
{
filename = tr( "new_palette" );
}
QFileInfo destFileInfo( palettePath.filePath( filename + ".gpl" ) );
int fileNumber = 1;
while ( destFileInfo.exists() )
{
//try to generate a unique file name
destFileInfo = QFileInfo( palettePath.filePath( filename + QString( "%1.gpl" ).arg( fileNumber ) ) );
fileNumber++;
}
QgsUserColorScheme* newScheme = new QgsUserColorScheme( destFileInfo.fileName() );
newScheme->setName( name );
QgsColorSchemeRegistry::instance()->addColorScheme( newScheme );
//refresh combobox and set new scheme as active
refreshSchemeComboBox();
mSchemeComboBox->setCurrentIndex( mSchemeComboBox->count() - 1 );
}
QString QgsColorDialogV2::gplFilePath()
{
QString palettesDir = QgsApplication::qgisSettingsDirPath() + "/palettes";
QDir localDir;
if ( !localDir.mkpath( palettesDir ) )
{
return QString();
}
return palettesDir;
}
void QgsColorDialogV2::exportColors()
{
QSettings s;
QString lastDir = s.value( "/UI/lastGplPaletteDir", QDir::homePath() ).toString();
QString fileName = QFileDialog::getSaveFileName( this, tr( "Palette file" ), lastDir, "GPL (*.gpl)" );
activateWindow();
if ( fileName.isEmpty() )
{
return;
}
// ensure filename contains extension
if ( !fileName.endsWith( ".gpl", Qt::CaseInsensitive ) )
{
fileName += ".gpl";
}
QFileInfo fileInfo( fileName );
s.setValue( "/UI/lastGplPaletteDir", fileInfo.absolutePath() );
QFile file( fileName );
bool exportOk = mSchemeList->exportColorsToGpl( file );
if ( !exportOk )
{
QMessageBox::critical( nullptr, tr( "Error exporting" ), tr( "Error writing palette file" ) );
return;
}
}
void QgsColorDialogV2::schemeIndexChanged( int index )
{
//save changes to scheme
if ( mSchemeList->isDirty() )
{
mSchemeList->saveColorsToScheme();
}
//get schemes with ShowInColorDialog set
QList<QgsColorScheme *> schemeList = QgsColorSchemeRegistry::instance()->schemes( QgsColorScheme::ShowInColorDialog );
if ( index >= schemeList.length() )
{
return;
}
QgsColorScheme* scheme = schemeList.at( index );
mSchemeList->setScheme( scheme );
mActionImportColors->setEnabled( scheme->isEditable() );
mActionPasteColors->setEnabled( scheme->isEditable() );
mAddColorToSchemeButton->setEnabled( scheme->isEditable() );
mRemoveColorsFromSchemeButton->setEnabled( scheme->isEditable() );
QgsUserColorScheme* userScheme = dynamic_cast<QgsUserColorScheme*>( scheme );
mActionRemovePalette->setEnabled( userScheme ? true : false );
//copy action defaults to disabled
mActionCopyColors->setEnabled( false );
}
void QgsColorDialogV2::listSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected )
{
Q_UNUSED( deselected );
mActionCopyColors->setEnabled( selected.length() > 0 );
}
void QgsColorDialogV2::on_mAddCustomColorButton_clicked()
{
switch ( mLastCustomColorIndex )
{
case 0:
mSwatchButton1->setColor( mColorPreview->color() );
break;
case 1:
mSwatchButton2->setColor( mColorPreview->color() );
break;
case 2:
mSwatchButton3->setColor( mColorPreview->color() );
break;
case 3:
mSwatchButton4->setColor( mColorPreview->color() );
break;
case 4:
mSwatchButton5->setColor( mColorPreview->color() );
break;
case 5:
mSwatchButton6->setColor( mColorPreview->color() );
break;
case 6:
mSwatchButton7->setColor( mColorPreview->color() );
break;
case 7:
mSwatchButton8->setColor( mColorPreview->color() );
break;
case 8:
mSwatchButton9->setColor( mColorPreview->color() );
break;
case 9:
mSwatchButton10->setColor( mColorPreview->color() );
break;
case 10:
mSwatchButton11->setColor( mColorPreview->color() );
break;
case 11:
mSwatchButton12->setColor( mColorPreview->color() );
break;
case 12:
mSwatchButton13->setColor( mColorPreview->color() );
break;
case 13:
mSwatchButton14->setColor( mColorPreview->color() );
break;
case 14:
mSwatchButton15->setColor( mColorPreview->color() );
break;
case 15:
mSwatchButton16->setColor( mColorPreview->color() );
break;
}
mLastCustomColorIndex++;
if ( mLastCustomColorIndex >= 16 )
{
mLastCustomColorIndex = 0;
}
}
void QgsColorDialogV2::on_mSampleButton_clicked()
{
//activate picker color
QPixmap samplerPixmap = QPixmap(( const char ** ) sampler_cursor );
setCursor( QCursor( samplerPixmap, 0, 0 ) );
grabMouse();
grabKeyboard();
mPickingColor = true;
setMouseTracking( true );
}
void QgsColorDialogV2::on_mTabWidget_currentChanged( int index )
{
//disable radio buttons if not using the first tab, as they have no meaning for other tabs
bool enabled = index == 0;
mRedRadio->setEnabled( enabled );
mBlueRadio->setEnabled( enabled );
mGreenRadio->setEnabled( enabled );
mHueRadio->setEnabled( enabled );
mSaturationRadio->setEnabled( enabled );
mValueRadio->setEnabled( enabled );
}
void QgsColorDialogV2::saveSettings()
{
//save changes to scheme
if ( mSchemeList->isDirty() )
{
mSchemeList->saveColorsToScheme();
}
QSettings settings;
settings.setValue( "/Windows/ColorDialog/geometry", saveGeometry() );
//record active component
int activeRadio = 0;
if ( mHueRadio->isChecked() )
activeRadio = 0;
if ( mSaturationRadio->isChecked() )
activeRadio = 1;
if ( mValueRadio->isChecked() )
activeRadio = 2;
if ( mRedRadio->isChecked() )
activeRadio = 3;
if ( mGreenRadio->isChecked() )
activeRadio = 4;
if ( mBlueRadio->isChecked() )
activeRadio = 5;
settings.setValue( "/Windows/ColorDialog/activeComponent", activeRadio );
//record current scheme
settings.setValue( "/Windows/ColorDialog/activeScheme", mSchemeComboBox->currentIndex() );
//record current tab
settings.setValue( "/Windows/ColorDialog/activeTab", mTabWidget->currentIndex() );
//record custom colors
settings.setValue( "/Windows/ColorDialog/customColor1", QVariant( mSwatchButton1->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor2", QVariant( mSwatchButton2->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor3", QVariant( mSwatchButton3->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor4", QVariant( mSwatchButton4->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor5", QVariant( mSwatchButton5->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor6", QVariant( mSwatchButton6->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor7", QVariant( mSwatchButton7->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor8", QVariant( mSwatchButton8->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor9", QVariant( mSwatchButton9->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor10", QVariant( mSwatchButton10->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor11", QVariant( mSwatchButton11->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor12", QVariant( mSwatchButton12->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor13", QVariant( mSwatchButton13->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor14", QVariant( mSwatchButton14->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor15", QVariant( mSwatchButton15->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor16", QVariant( mSwatchButton16->color() ) );
//sample radius
settings.setValue( "/Windows/ColorDialog/sampleRadius", mSpinBoxRadius->value() );
}
void QgsColorDialogV2::stopPicking( QPoint eventPos, const bool takeSample )
{
//release mouse and keyboard, and reset cursor
releaseMouse();
releaseKeyboard();
unsetCursor();
setMouseTracking( false );
mPickingColor = false;
if ( !takeSample )
{
//not sampling color, nothing more to do
return;
}
//grab snapshot of pixel under mouse cursor
QColor snappedColor = sampleColor( eventPos );
mSamplePreview->setColor( snappedColor );
mColorPreview->setColor( snappedColor, true );
}
void QgsColorDialogV2::setColor( const QColor &color )
@ -795,17 +206,8 @@ void QgsColorDialogV2::setColor( const QColor &color )
//alpha disallowed, so don't permit transparent colors
fixedColor.setAlpha( 255 );
}
QList<QgsColorWidget*> colorWidgets = this->findChildren<QgsColorWidget *>();
Q_FOREACH ( QgsColorWidget* widget, colorWidgets )
{
if ( widget == mSamplePreview )
{
continue;
}
widget->blockSignals( true );
widget->setColor( fixedColor );
widget->blockSignals( false );
}
mColorWidget->setColor( fixedColor );
emit currentColorChanged( fixedColor );
}
@ -814,155 +216,3 @@ void QgsColorDialogV2::closeEvent( QCloseEvent *e )
saveSettings();
QDialog::closeEvent( e );
}
void QgsColorDialogV2::mousePressEvent( QMouseEvent *e )
{
if ( mPickingColor )
{
//don't show dialog if in color picker mode
e->accept();
return;
}
QDialog::mousePressEvent( e );
}
QColor QgsColorDialogV2::averageColor( const QImage &image ) const
{
QRgb tmpRgb;
int colorCount = 0;
int sumRed = 0;
int sumBlue = 0;
int sumGreen = 0;
//scan through image and sum rgb components
for ( int heightIndex = 0; heightIndex < image.height(); ++heightIndex )
{
QRgb* scanLine = ( QRgb* )image.constScanLine( heightIndex );
for ( int widthIndex = 0; widthIndex < image.width(); ++widthIndex )
{
tmpRgb = scanLine[widthIndex];
sumRed += qRed( tmpRgb );
sumBlue += qBlue( tmpRgb );
sumGreen += qGreen( tmpRgb );
colorCount++;
}
}
//calculate average components as floats
double avgRed = ( double )sumRed / ( 255.0 * colorCount );
double avgGreen = ( double )sumGreen / ( 255.0 * colorCount );
double avgBlue = ( double )sumBlue / ( 255.0 * colorCount );
//create a new color representing the average
return QColor::fromRgbF( avgRed, avgGreen, avgBlue );
}
QColor QgsColorDialogV2::sampleColor( QPoint point ) const
{
int sampleRadius = mSpinBoxRadius->value() - 1;
QPixmap snappedPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), point.x() - sampleRadius, point.y() - sampleRadius,
1 + sampleRadius * 2, 1 + sampleRadius * 2 );
QImage snappedImage = snappedPixmap.toImage();
//scan all pixels and take average color
return averageColor( snappedImage );
}
void QgsColorDialogV2::mouseMoveEvent( QMouseEvent *e )
{
if ( mPickingColor )
{
//currently in color picker mode
//sample color under cursor update preview widget to give feedback to user
QColor hoverColor = sampleColor( e->globalPos() );
mSamplePreview->setColor( hoverColor );
e->accept();
return;
}
QDialog::mouseMoveEvent( e );
}
void QgsColorDialogV2::mouseReleaseEvent( QMouseEvent *e )
{
if ( mPickingColor )
{
//end color picking operation by sampling the color under cursor
stopPicking( e->globalPos() );
e->accept();
return;
}
QDialog::mouseReleaseEvent( e );
}
void QgsColorDialogV2::keyPressEvent( QKeyEvent *e )
{
if ( !mPickingColor )
{
//if not picking a color, use default tool button behaviour
QDialog::keyPressEvent( e );
return;
}
//cancel picking, sampling the color if space was pressed
stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
}
void QgsColorDialogV2::on_mHueRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Hue );
mVerticalRamp->setComponent( QgsColorWidget::Hue );
}
}
void QgsColorDialogV2::on_mSaturationRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Saturation );
mVerticalRamp->setComponent( QgsColorWidget::Saturation );
}
}
void QgsColorDialogV2::on_mValueRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Value );
mVerticalRamp->setComponent( QgsColorWidget::Value );
}
}
void QgsColorDialogV2::on_mRedRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Red );
mVerticalRamp->setComponent( QgsColorWidget::Red );
}
}
void QgsColorDialogV2::on_mGreenRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Green );
mVerticalRamp->setComponent( QgsColorWidget::Green );
}
}
void QgsColorDialogV2::on_mBlueRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Blue );
mVerticalRamp->setComponent( QgsColorWidget::Blue );
}
}
void QgsColorDialogV2::on_mAddColorToSchemeButton_clicked()
{
mSchemeList->addColor( mColorPreview->color(), QgsSymbolLayerV2Utils::colorToName( mColorPreview->color() ) );
}

View File

@ -136,41 +136,11 @@ class GUI_EXPORT QgsColorDialogV2 : public QDialog, private Ui::QgsColorDialogBa
void closeEvent( QCloseEvent* e ) override;
void mousePressEvent( QMouseEvent* e ) override;
void mouseMoveEvent( QMouseEvent *e ) override;
void mouseReleaseEvent( QMouseEvent *e ) override;
void keyPressEvent( QKeyEvent *e ) override;
private slots:
void on_mHueRadio_toggled( bool checked );
void on_mSaturationRadio_toggled( bool checked );
void on_mValueRadio_toggled( bool checked );
void on_mRedRadio_toggled( bool checked );
void on_mGreenRadio_toggled( bool checked );
void on_mBlueRadio_toggled( bool checked );
void on_mButtonBox_accepted();
void on_mButtonBox_rejected();
void on_mButtonBox_clicked( QAbstractButton * button );
void on_mAddColorToSchemeButton_clicked();
void exportColors();
void importColors();
void importPalette();
void removePalette();
void newPalette();
void schemeIndexChanged( int index );
void listSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected );
void on_mAddCustomColorButton_clicked();
void on_mSampleButton_clicked();
void on_mTabWidget_currentChanged( int index );
private:
@ -178,40 +148,10 @@ class GUI_EXPORT QgsColorDialogV2 : public QDialog, private Ui::QgsColorDialogBa
bool mAllowAlpha;
int mLastCustomColorIndex;
bool mPickingColor;
/** Saves all dialog and widget settings
*/
void saveSettings();
/** Ends a color picking operation
* @param eventPos global position of pixel to sample color from
* @param takeSample set to true to actually sample the color, false to just cancel
* the color picking operation
*/
void stopPicking( QPoint eventPos, const bool takeSample = true );
/** Returns the average color from the pixels in an image
* @param image image to sample
* @returns average color from image
*/
QColor averageColor( const QImage &image ) const;
/** Samples a color from the desktop
* @param point position of color to sample
* @returns average color from sampled position
*/
QColor sampleColor( QPoint point ) const;
/** Repopulates the scheme combo box with current color schemes
*/
void refreshSchemeComboBox();
/** Returns the path to the user's palette folder
*/
QString gplFilePath();
};
#endif // #ifndef QGSCOLORDIALOG_H

View File

@ -0,0 +1,840 @@
/***************************************************************************
qgscompoundcolorwidget.cpp
--------------------------
begin : April 2016
copyright : (C) 2016 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgscompoundcolorwidget.h"
#include "qgscolorscheme.h"
#include "qgscolorschemeregistry.h"
#include "qgssymbollayerv2utils.h"
#include "qgscursors.h"
#include "qgsapplication.h"
#include <QSettings>
#include <QPushButton>
#include <QMenu>
#include <QToolButton>
#include <QFileDialog>
#include <QMessageBox>
#include <QDesktopWidget>
#include <QMouseEvent>
#include <QInputDialog>
QgsCompoundColorWidget::QgsCompoundColorWidget( QWidget *parent, const QColor& color )
: QWidget( parent )
, mAllowAlpha( true )
, mLastCustomColorIndex( 0 )
, mPickingColor( false )
{
setupUi( this );
QSettings settings;
mSchemeList->header()->hide();
mSchemeList->setColumnWidth( 0, 44 );
//get schemes with ShowInColorDialog set
refreshSchemeComboBox();
QList<QgsColorScheme *> schemeList = QgsColorSchemeRegistry::instance()->schemes( QgsColorScheme::ShowInColorDialog );
//choose a reasonable starting scheme
int activeScheme = settings.value( "/Windows/ColorDialog/activeScheme", 0 ).toInt();
activeScheme = activeScheme >= mSchemeComboBox->count() ? 0 : activeScheme;
mSchemeList->setScheme( schemeList.at( activeScheme ) );
mSchemeComboBox->setCurrentIndex( activeScheme );
mActionImportColors->setEnabled( schemeList.at( activeScheme )->isEditable() );
mActionPasteColors->setEnabled( schemeList.at( activeScheme )->isEditable() );
mAddColorToSchemeButton->setEnabled( schemeList.at( activeScheme )->isEditable() );
mRemoveColorsFromSchemeButton->setEnabled( schemeList.at( activeScheme )->isEditable() );
QgsUserColorScheme* userScheme = dynamic_cast<QgsUserColorScheme*>( schemeList.at( activeScheme ) );
mActionRemovePalette->setEnabled( userScheme ? true : false );
//listen out for selection changes in list, so we can enable/disable the copy colors option
connect( mSchemeList->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), this, SLOT( listSelectionChanged( QItemSelection, QItemSelection ) ) );
//copy action defaults to disabled
mActionCopyColors->setEnabled( false );
connect( mActionCopyColors, SIGNAL( triggered() ), mSchemeList, SLOT( copyColors() ) );
connect( mActionPasteColors, SIGNAL( triggered() ), mSchemeList, SLOT( pasteColors() ) );
connect( mActionExportColors, SIGNAL( triggered() ), this, SLOT( exportColors() ) );
connect( mActionImportColors, SIGNAL( triggered() ), this, SLOT( importColors() ) );
connect( mActionImportPalette, SIGNAL( triggered() ), this, SLOT( importPalette() ) );
connect( mActionRemovePalette, SIGNAL( triggered() ), this, SLOT( removePalette() ) );
connect( mActionNewPalette, SIGNAL( triggered() ), this, SLOT( newPalette() ) );
connect( mRemoveColorsFromSchemeButton, SIGNAL( clicked() ), mSchemeList, SLOT( removeSelection() ) );
QMenu* schemeMenu = new QMenu( mSchemeToolButton );
schemeMenu->addAction( mActionCopyColors );
schemeMenu->addAction( mActionPasteColors );
schemeMenu->addSeparator();
schemeMenu->addAction( mActionImportColors );
schemeMenu->addAction( mActionExportColors );
schemeMenu->addSeparator();
schemeMenu->addAction( mActionNewPalette );
schemeMenu->addAction( mActionImportPalette );
schemeMenu->addAction( mActionRemovePalette );
mSchemeToolButton->setMenu( schemeMenu );
connect( mSchemeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( schemeIndexChanged( int ) ) );
connect( mSchemeList, SIGNAL( colorSelected( QColor ) ), this, SLOT( setColor( QColor ) ) );
mOldColorLabel->hide();
mVerticalRamp->setOrientation( QgsColorRampWidget::Vertical );
mVerticalRamp->setInteriorMargin( 2 );
mVerticalRamp->setShowFrame( true );
mRedSlider->setComponent( QgsColorWidget::Red );
mGreenSlider->setComponent( QgsColorWidget::Green );
mBlueSlider->setComponent( QgsColorWidget::Blue );
mHueSlider->setComponent( QgsColorWidget::Hue );
mSaturationSlider->setComponent( QgsColorWidget::Saturation );
mValueSlider->setComponent( QgsColorWidget::Value );
mAlphaSlider->setComponent( QgsColorWidget::Alpha );
mSwatchButton1->setShowMenu( false );
mSwatchButton1->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton2->setShowMenu( false );
mSwatchButton2->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton3->setShowMenu( false );
mSwatchButton3->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton4->setShowMenu( false );
mSwatchButton4->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton5->setShowMenu( false );
mSwatchButton5->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton6->setShowMenu( false );
mSwatchButton6->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton7->setShowMenu( false );
mSwatchButton7->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton8->setShowMenu( false );
mSwatchButton8->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton9->setShowMenu( false );
mSwatchButton9->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton10->setShowMenu( false );
mSwatchButton10->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton11->setShowMenu( false );
mSwatchButton11->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton12->setShowMenu( false );
mSwatchButton12->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton13->setShowMenu( false );
mSwatchButton13->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton14->setShowMenu( false );
mSwatchButton14->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton15->setShowMenu( false );
mSwatchButton15->setBehaviour( QgsColorButtonV2::SignalOnly );
mSwatchButton16->setShowMenu( false );
mSwatchButton16->setBehaviour( QgsColorButtonV2::SignalOnly );
//restore custom colors
mSwatchButton1->setColor( settings.value( "/Windows/ColorDialog/customColor1", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton2->setColor( settings.value( "/Windows/ColorDialog/customColor2", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton3->setColor( settings.value( "/Windows/ColorDialog/customColor3", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton4->setColor( settings.value( "/Windows/ColorDialog/customColor4", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton5->setColor( settings.value( "/Windows/ColorDialog/customColor5", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton6->setColor( settings.value( "/Windows/ColorDialog/customColor6", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton7->setColor( settings.value( "/Windows/ColorDialog/customColor7", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton8->setColor( settings.value( "/Windows/ColorDialog/customColor8", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton9->setColor( settings.value( "/Windows/ColorDialog/customColor9", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton10->setColor( settings.value( "/Windows/ColorDialog/customColor10", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton11->setColor( settings.value( "/Windows/ColorDialog/customColor11", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton12->setColor( settings.value( "/Windows/ColorDialog/customColor12", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton13->setColor( settings.value( "/Windows/ColorDialog/customColor13", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton14->setColor( settings.value( "/Windows/ColorDialog/customColor14", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton15->setColor( settings.value( "/Windows/ColorDialog/customColor15", QVariant( QColor() ) ).value<QColor>() );
mSwatchButton16->setColor( settings.value( "/Windows/ColorDialog/customColor16", QVariant( QColor() ) ).value<QColor>() );
//restore sample radius
mSpinBoxRadius->setValue( settings.value( "/Windows/ColorDialog/sampleRadius", 1 ).toInt() );
mSamplePreview->setColor( QColor() );
if ( color.isValid() )
{
setColor( color );
}
//restore active component radio button
int activeRadio = settings.value( "/Windows/ColorDialog/activeComponent", 2 ).toInt();
switch ( activeRadio )
{
case 0:
mHueRadio->setChecked( true );
break;
case 1:
mSaturationRadio->setChecked( true );
break;
case 2:
mValueRadio->setChecked( true );
break;
case 3:
mRedRadio->setChecked( true );
break;
case 4:
mGreenRadio->setChecked( true );
break;
case 5:
mBlueRadio->setChecked( true );
break;
}
int currentTab = settings.value( "/Windows/ColorDialog/activeTab", 0 ).toInt();
mTabWidget->setCurrentIndex( currentTab );
#ifdef Q_OS_MAC
//disable color picker tab for OSX, as it is impossible to grab the mouse under OSX
//see note for QWidget::grabMouse() re OSX Cocoa
//http://qt-project.org/doc/qt-4.8/qwidget.html#grabMouse
mTabWidget->removeTab( 3 );
#endif
//setup connections
connect( mColorBox, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mColorWheel, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mColorText, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mVerticalRamp, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mRedSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mGreenSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mBlueSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mHueSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mValueSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSaturationSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mAlphaSlider, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mColorPreview, SIGNAL( colorChanged( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton1, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton2, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton3, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton4, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton5, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton6, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton7, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton8, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton9, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton10, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton11, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton12, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton13, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton14, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton15, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
connect( mSwatchButton16, SIGNAL( colorClicked( QColor ) ), this, SLOT( setColor( QColor ) ) );
}
QgsCompoundColorWidget::~QgsCompoundColorWidget()
{
saveSettings();
}
QColor QgsCompoundColorWidget::color() const
{
//all widgets should have the same color, so it shouldn't matter
//which we fetch it from
return mColorPreview->color();
}
void QgsCompoundColorWidget::setAllowAlpha( const bool allowAlpha )
{
mAllowAlpha = allowAlpha;
mAlphaLabel->setVisible( allowAlpha );
mAlphaSlider->setVisible( allowAlpha );
if ( !allowAlpha )
{
mAlphaLayout->setContentsMargins( 0, 0, 0, 0 );
mAlphaLayout->setSpacing( 0 );
}
}
void QgsCompoundColorWidget::importColors()
{
QSettings s;
QString lastDir = s.value( "/UI/lastGplPaletteDir", QDir::homePath() ).toString();
QString filePath = QFileDialog::getOpenFileName( this, tr( "Select palette file" ), lastDir, "GPL (*.gpl);;All files (*.*)" );
activateWindow();
if ( filePath.isEmpty() )
{
return;
}
//check if file exists
QFileInfo fileInfo( filePath );
if ( !fileInfo.exists() || !fileInfo.isReadable() )
{
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "Error, file does not exist or is not readable" ) );
return;
}
s.setValue( "/UI/lastGplPaletteDir", fileInfo.absolutePath() );
QFile file( filePath );
bool importOk = mSchemeList->importColorsFromGpl( file );
if ( !importOk )
{
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "Error, no colors found in palette file" ) );
return;
}
}
void QgsCompoundColorWidget::refreshSchemeComboBox()
{
mSchemeComboBox->blockSignals( true );
mSchemeComboBox->clear();
QList<QgsColorScheme *> schemeList = QgsColorSchemeRegistry::instance()->schemes( QgsColorScheme::ShowInColorDialog );
QList<QgsColorScheme *>::const_iterator schemeIt = schemeList.constBegin();
for ( ; schemeIt != schemeList.constEnd(); ++schemeIt )
{
mSchemeComboBox->addItem(( *schemeIt )->schemeName() );
}
mSchemeComboBox->blockSignals( false );
}
void QgsCompoundColorWidget::importPalette()
{
QSettings s;
QString lastDir = s.value( "/UI/lastGplPaletteDir", QDir::homePath() ).toString();
QString filePath = QFileDialog::getOpenFileName( this, tr( "Select palette file" ), lastDir, "GPL (*.gpl);;All files (*.*)" );
activateWindow();
if ( filePath.isEmpty() )
{
return;
}
//check if file exists
QFileInfo fileInfo( filePath );
if ( !fileInfo.exists() || !fileInfo.isReadable() )
{
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "Error, file does not exist or is not readable" ) );
return;
}
s.setValue( "/UI/lastGplPaletteDir", fileInfo.absolutePath() );
QFile file( filePath );
QgsNamedColorList importedColors;
bool ok = false;
QString paletteName;
importedColors = QgsSymbolLayerV2Utils::importColorsFromGpl( file, ok, paletteName );
if ( !ok )
{
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "Palette file is not readable" ) );
return;
}
if ( importedColors.length() == 0 )
{
//no imported colors
QMessageBox::critical( nullptr, tr( "Invalid file" ), tr( "No colors found in palette file" ) );
return;
}
//TODO - handle conflicting file names, name for new palette
QgsUserColorScheme* importedScheme = new QgsUserColorScheme( fileInfo.fileName() );
importedScheme->setName( paletteName );
importedScheme->setColors( importedColors );
QgsColorSchemeRegistry::instance()->addColorScheme( importedScheme );
//refresh combobox
refreshSchemeComboBox();
mSchemeComboBox->setCurrentIndex( mSchemeComboBox->count() - 1 );
}
void QgsCompoundColorWidget::removePalette()
{
//get current scheme
QList<QgsColorScheme *> schemeList = QgsColorSchemeRegistry::instance()->schemes( QgsColorScheme::ShowInColorDialog );
int prevIndex = mSchemeComboBox->currentIndex();
if ( prevIndex >= schemeList.length() )
{
return;
}
//make user scheme is a user removable scheme
QgsUserColorScheme* userScheme = dynamic_cast<QgsUserColorScheme*>( schemeList.at( prevIndex ) );
if ( !userScheme )
{
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 )
{
//user cancelled
return;
}
//remove palette and associated gpl file
if ( !userScheme->erase() )
{
//something went wrong
return;
}
//remove scheme from registry
QgsColorSchemeRegistry::instance()->removeColorScheme( userScheme );
refreshSchemeComboBox();
prevIndex = qMax( qMin( prevIndex, mSchemeComboBox->count() - 1 ), 0 );
mSchemeComboBox->setCurrentIndex( prevIndex );
}
void QgsCompoundColorWidget::newPalette()
{
bool ok = false;
QString name = QInputDialog::getText( this, tr( "Create New Palette" ), tr( "Enter a name for the new palette:" ),
QLineEdit::Normal, tr( "New palette" ), &ok );
if ( !ok || name.isEmpty() )
{
//user cancelled
return;
}
//generate file name for new palette
QDir palettePath( gplFilePath() );
QRegExp badChars( "[,^@={}\\[\\]~!?:&*\"|#%<>$\"'();`' /\\\\]" );
QString filename = name.simplified().toLower().replace( badChars, QLatin1String( "_" ) );
if ( filename.isEmpty() )
{
filename = tr( "new_palette" );
}
QFileInfo destFileInfo( palettePath.filePath( filename + ".gpl" ) );
int fileNumber = 1;
while ( destFileInfo.exists() )
{
//try to generate a unique file name
destFileInfo = QFileInfo( palettePath.filePath( filename + QString( "%1.gpl" ).arg( fileNumber ) ) );
fileNumber++;
}
QgsUserColorScheme* newScheme = new QgsUserColorScheme( destFileInfo.fileName() );
newScheme->setName( name );
QgsColorSchemeRegistry::instance()->addColorScheme( newScheme );
//refresh combobox and set new scheme as active
refreshSchemeComboBox();
mSchemeComboBox->setCurrentIndex( mSchemeComboBox->count() - 1 );
}
QString QgsCompoundColorWidget::gplFilePath()
{
QString palettesDir = QgsApplication::qgisSettingsDirPath() + "/palettes";
QDir localDir;
if ( !localDir.mkpath( palettesDir ) )
{
return QString();
}
return palettesDir;
}
void QgsCompoundColorWidget::exportColors()
{
QSettings s;
QString lastDir = s.value( "/UI/lastGplPaletteDir", QDir::homePath() ).toString();
QString fileName = QFileDialog::getSaveFileName( this, tr( "Palette file" ), lastDir, "GPL (*.gpl)" );
activateWindow();
if ( fileName.isEmpty() )
{
return;
}
// ensure filename contains extension
if ( !fileName.endsWith( ".gpl", Qt::CaseInsensitive ) )
{
fileName += ".gpl";
}
QFileInfo fileInfo( fileName );
s.setValue( "/UI/lastGplPaletteDir", fileInfo.absolutePath() );
QFile file( fileName );
bool exportOk = mSchemeList->exportColorsToGpl( file );
if ( !exportOk )
{
QMessageBox::critical( nullptr, tr( "Error exporting" ), tr( "Error writing palette file" ) );
return;
}
}
void QgsCompoundColorWidget::schemeIndexChanged( int index )
{
//save changes to scheme
if ( mSchemeList->isDirty() )
{
mSchemeList->saveColorsToScheme();
}
//get schemes with ShowInColorDialog set
QList<QgsColorScheme *> schemeList = QgsColorSchemeRegistry::instance()->schemes( QgsColorScheme::ShowInColorDialog );
if ( index >= schemeList.length() )
{
return;
}
QgsColorScheme* scheme = schemeList.at( index );
mSchemeList->setScheme( scheme );
mActionImportColors->setEnabled( scheme->isEditable() );
mActionPasteColors->setEnabled( scheme->isEditable() );
mAddColorToSchemeButton->setEnabled( scheme->isEditable() );
mRemoveColorsFromSchemeButton->setEnabled( scheme->isEditable() );
QgsUserColorScheme* userScheme = dynamic_cast<QgsUserColorScheme*>( scheme );
mActionRemovePalette->setEnabled( userScheme ? true : false );
//copy action defaults to disabled
mActionCopyColors->setEnabled( false );
}
void QgsCompoundColorWidget::listSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected )
{
Q_UNUSED( deselected );
mActionCopyColors->setEnabled( selected.length() > 0 );
}
void QgsCompoundColorWidget::on_mAddCustomColorButton_clicked()
{
switch ( mLastCustomColorIndex )
{
case 0:
mSwatchButton1->setColor( mColorPreview->color() );
break;
case 1:
mSwatchButton2->setColor( mColorPreview->color() );
break;
case 2:
mSwatchButton3->setColor( mColorPreview->color() );
break;
case 3:
mSwatchButton4->setColor( mColorPreview->color() );
break;
case 4:
mSwatchButton5->setColor( mColorPreview->color() );
break;
case 5:
mSwatchButton6->setColor( mColorPreview->color() );
break;
case 6:
mSwatchButton7->setColor( mColorPreview->color() );
break;
case 7:
mSwatchButton8->setColor( mColorPreview->color() );
break;
case 8:
mSwatchButton9->setColor( mColorPreview->color() );
break;
case 9:
mSwatchButton10->setColor( mColorPreview->color() );
break;
case 10:
mSwatchButton11->setColor( mColorPreview->color() );
break;
case 11:
mSwatchButton12->setColor( mColorPreview->color() );
break;
case 12:
mSwatchButton13->setColor( mColorPreview->color() );
break;
case 13:
mSwatchButton14->setColor( mColorPreview->color() );
break;
case 14:
mSwatchButton15->setColor( mColorPreview->color() );
break;
case 15:
mSwatchButton16->setColor( mColorPreview->color() );
break;
}
mLastCustomColorIndex++;
if ( mLastCustomColorIndex >= 16 )
{
mLastCustomColorIndex = 0;
}
}
void QgsCompoundColorWidget::on_mSampleButton_clicked()
{
//activate picker color
QPixmap samplerPixmap = QPixmap(( const char ** ) sampler_cursor );
setCursor( QCursor( samplerPixmap, 0, 0 ) );
grabMouse();
grabKeyboard();
mPickingColor = true;
setMouseTracking( true );
}
void QgsCompoundColorWidget::on_mTabWidget_currentChanged( int index )
{
//disable radio buttons if not using the first tab, as they have no meaning for other tabs
bool enabled = index == 0;
mRedRadio->setEnabled( enabled );
mBlueRadio->setEnabled( enabled );
mGreenRadio->setEnabled( enabled );
mHueRadio->setEnabled( enabled );
mSaturationRadio->setEnabled( enabled );
mValueRadio->setEnabled( enabled );
}
void QgsCompoundColorWidget::saveSettings()
{
//save changes to scheme
if ( mSchemeList->isDirty() )
{
mSchemeList->saveColorsToScheme();
}
QSettings settings;
//record active component
int activeRadio = 0;
if ( mHueRadio->isChecked() )
activeRadio = 0;
if ( mSaturationRadio->isChecked() )
activeRadio = 1;
if ( mValueRadio->isChecked() )
activeRadio = 2;
if ( mRedRadio->isChecked() )
activeRadio = 3;
if ( mGreenRadio->isChecked() )
activeRadio = 4;
if ( mBlueRadio->isChecked() )
activeRadio = 5;
settings.setValue( "/Windows/ColorDialog/activeComponent", activeRadio );
//record current scheme
settings.setValue( "/Windows/ColorDialog/activeScheme", mSchemeComboBox->currentIndex() );
//record current tab
settings.setValue( "/Windows/ColorDialog/activeTab", mTabWidget->currentIndex() );
//record custom colors
settings.setValue( "/Windows/ColorDialog/customColor1", QVariant( mSwatchButton1->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor2", QVariant( mSwatchButton2->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor3", QVariant( mSwatchButton3->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor4", QVariant( mSwatchButton4->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor5", QVariant( mSwatchButton5->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor6", QVariant( mSwatchButton6->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor7", QVariant( mSwatchButton7->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor8", QVariant( mSwatchButton8->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor9", QVariant( mSwatchButton9->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor10", QVariant( mSwatchButton10->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor11", QVariant( mSwatchButton11->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor12", QVariant( mSwatchButton12->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor13", QVariant( mSwatchButton13->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor14", QVariant( mSwatchButton14->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor15", QVariant( mSwatchButton15->color() ) );
settings.setValue( "/Windows/ColorDialog/customColor16", QVariant( mSwatchButton16->color() ) );
//sample radius
settings.setValue( "/Windows/ColorDialog/sampleRadius", mSpinBoxRadius->value() );
}
void QgsCompoundColorWidget::stopPicking( QPoint eventPos, const bool takeSample )
{
//release mouse and keyboard, and reset cursor
releaseMouse();
releaseKeyboard();
unsetCursor();
setMouseTracking( false );
mPickingColor = false;
if ( !takeSample )
{
//not sampling color, nothing more to do
return;
}
//grab snapshot of pixel under mouse cursor
QColor snappedColor = sampleColor( eventPos );
mSamplePreview->setColor( snappedColor );
mColorPreview->setColor( snappedColor, true );
}
void QgsCompoundColorWidget::setColor( const QColor &color )
{
if ( !color.isValid() )
{
return;
}
QColor fixedColor = QColor( color );
if ( !mAllowAlpha )
{
//alpha disallowed, so don't permit transparent colors
fixedColor.setAlpha( 255 );
}
QList<QgsColorWidget*> colorWidgets = this->findChildren<QgsColorWidget *>();
Q_FOREACH ( QgsColorWidget* widget, colorWidgets )
{
if ( widget == mSamplePreview )
{
continue;
}
widget->blockSignals( true );
widget->setColor( fixedColor );
widget->blockSignals( false );
}
emit currentColorChanged( fixedColor );
}
void QgsCompoundColorWidget::setPreviousColor( const QColor &color )
{
mOldColorLabel->setVisible( color.isValid() );
mColorPreview->setColor2( color );
}
void QgsCompoundColorWidget::mousePressEvent( QMouseEvent *e )
{
if ( mPickingColor )
{
//don't show dialog if in color picker mode
e->accept();
return;
}
QWidget::mousePressEvent( e );
}
QColor QgsCompoundColorWidget::averageColor( const QImage &image ) const
{
QRgb tmpRgb;
int colorCount = 0;
int sumRed = 0;
int sumBlue = 0;
int sumGreen = 0;
//scan through image and sum rgb components
for ( int heightIndex = 0; heightIndex < image.height(); ++heightIndex )
{
QRgb* scanLine = ( QRgb* )image.constScanLine( heightIndex );
for ( int widthIndex = 0; widthIndex < image.width(); ++widthIndex )
{
tmpRgb = scanLine[widthIndex];
sumRed += qRed( tmpRgb );
sumBlue += qBlue( tmpRgb );
sumGreen += qGreen( tmpRgb );
colorCount++;
}
}
//calculate average components as floats
double avgRed = ( double )sumRed / ( 255.0 * colorCount );
double avgGreen = ( double )sumGreen / ( 255.0 * colorCount );
double avgBlue = ( double )sumBlue / ( 255.0 * colorCount );
//create a new color representing the average
return QColor::fromRgbF( avgRed, avgGreen, avgBlue );
}
QColor QgsCompoundColorWidget::sampleColor( QPoint point ) const
{
int sampleRadius = mSpinBoxRadius->value() - 1;
QPixmap snappedPixmap = QPixmap::grabWindow( QApplication::desktop()->winId(), point.x() - sampleRadius, point.y() - sampleRadius,
1 + sampleRadius * 2, 1 + sampleRadius * 2 );
QImage snappedImage = snappedPixmap.toImage();
//scan all pixels and take average color
return averageColor( snappedImage );
}
void QgsCompoundColorWidget::mouseMoveEvent( QMouseEvent *e )
{
if ( mPickingColor )
{
//currently in color picker mode
//sample color under cursor update preview widget to give feedback to user
QColor hoverColor = sampleColor( e->globalPos() );
mSamplePreview->setColor( hoverColor );
e->accept();
return;
}
QWidget::mouseMoveEvent( e );
}
void QgsCompoundColorWidget::mouseReleaseEvent( QMouseEvent *e )
{
if ( mPickingColor )
{
//end color picking operation by sampling the color under cursor
stopPicking( e->globalPos() );
e->accept();
return;
}
QWidget::mouseReleaseEvent( e );
}
void QgsCompoundColorWidget::keyPressEvent( QKeyEvent *e )
{
if ( !mPickingColor )
{
//if not picking a color, use default tool button behaviour
QWidget::keyPressEvent( e );
return;
}
//cancel picking, sampling the color if space was pressed
stopPicking( QCursor::pos(), e->key() == Qt::Key_Space );
}
void QgsCompoundColorWidget::on_mHueRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Hue );
mVerticalRamp->setComponent( QgsColorWidget::Hue );
}
}
void QgsCompoundColorWidget::on_mSaturationRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Saturation );
mVerticalRamp->setComponent( QgsColorWidget::Saturation );
}
}
void QgsCompoundColorWidget::on_mValueRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Value );
mVerticalRamp->setComponent( QgsColorWidget::Value );
}
}
void QgsCompoundColorWidget::on_mRedRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Red );
mVerticalRamp->setComponent( QgsColorWidget::Red );
}
}
void QgsCompoundColorWidget::on_mGreenRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Green );
mVerticalRamp->setComponent( QgsColorWidget::Green );
}
}
void QgsCompoundColorWidget::on_mBlueRadio_toggled( bool checked )
{
if ( checked )
{
mColorBox->setComponent( QgsColorWidget::Blue );
mVerticalRamp->setComponent( QgsColorWidget::Blue );
}
}
void QgsCompoundColorWidget::on_mAddColorToSchemeButton_clicked()
{
mSchemeList->addColor( mColorPreview->color(), QgsSymbolLayerV2Utils::colorToName( mColorPreview->color() ) );
}

View File

@ -0,0 +1,149 @@
/***************************************************************************
qgscompoundcolorwidget.h
------------------------
begin : April 2016
copyright : (C) 2016 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCOMPOUNDCOLORWIDGET_H
#define QGSCOMPOUNDCOLORWIDGET_H
#include "qgisgui.h"
#include "ui_qgscompoundcolorwidget.h"
/** \ingroup gui
* \class QgsCompoundColorWidget
* A custom QGIS widget for selecting a color, including options for selecting colors via
* hue wheel, color swatches, and a color sampler.
* \note Added in version 2.16
*/
class GUI_EXPORT QgsCompoundColorWidget : public QWidget, private Ui::QgsCompoundColorWidgetBase
{
Q_OBJECT
public:
/** Constructor for QgsCompoundColorWidget
* @param parent parent widget
* @param color initial color for dialog
*/
QgsCompoundColorWidget( QWidget *parent = nullptr, const QColor& color = QColor() );
~QgsCompoundColorWidget();
/** Returns the current color for the dialog
* @returns dialog color
*/
QColor color() const;
/** Sets whether alpha modification (transparency) is permitted
* for the color dialog. Defaults to true.
* @param allowAlpha set to false to disable alpha modification
*/
void setAllowAlpha( const bool allowAlpha );
signals:
/** Emitted when the dialog's color changes
* @param color current color
*/
void currentColorChanged( const QColor &color );
public slots:
/** Sets the current color for the dialog
* @param color desired color
*/
void setColor( const QColor &color );
/** Sets the color to show in an optional "previous color" section
* @param color previous color
*/
void setPreviousColor( const QColor& color );
protected:
void mousePressEvent( QMouseEvent* e ) override;
void mouseMoveEvent( QMouseEvent *e ) override;
void mouseReleaseEvent( QMouseEvent *e ) override;
void keyPressEvent( QKeyEvent *e ) override;
private slots:
void on_mHueRadio_toggled( bool checked );
void on_mSaturationRadio_toggled( bool checked );
void on_mValueRadio_toggled( bool checked );
void on_mRedRadio_toggled( bool checked );
void on_mGreenRadio_toggled( bool checked );
void on_mBlueRadio_toggled( bool checked );
void on_mAddColorToSchemeButton_clicked();
void exportColors();
void importColors();
void importPalette();
void removePalette();
void newPalette();
void schemeIndexChanged( int index );
void listSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected );
void on_mAddCustomColorButton_clicked();
void on_mSampleButton_clicked();
void on_mTabWidget_currentChanged( int index );
private:
bool mAllowAlpha;
int mLastCustomColorIndex;
bool mPickingColor;
/** Saves all widget settings
*/
void saveSettings();
/** Ends a color picking operation
* @param eventPos global position of pixel to sample color from
* @param takeSample set to true to actually sample the color, false to just cancel
* the color picking operation
*/
void stopPicking( QPoint eventPos, const bool takeSample = true );
/** Returns the average color from the pixels in an image
* @param image image to sample
* @returns average color from image
*/
QColor averageColor( const QImage &image ) const;
/** Samples a color from the desktop
* @param point position of color to sample
* @returns average color from sampled position
*/
QColor sampleColor( QPoint point ) const;
/** Repopulates the scheme combo box with current color schemes
*/
void refreshSchemeComboBox();
/** Returns the path to the user's palette folder
*/
QString gplFilePath();
};
#endif // QGSCOMPOUNDCOLORWIDGET_H

View File

@ -18,805 +18,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="mGridLayout" rowstretch="1,0" columnstretch="1,0">
<property name="horizontalSpacing">
<number>6</number>
</property>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mHueRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>H</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mHueSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mSaturationRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>S</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mSaturationSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mValueRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>V</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mValueSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mRedRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>R</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mRedSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mGreenRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>G</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mGreenSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mBlueRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>B</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mBlueSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="mAlphaLayout">
<item>
<widget class="QLabel" name="mAlphaLabel">
<property name="text">
<string>Opacity</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mAlphaSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>HTML notation</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorTextWidget" name="mColorText" native="true"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout_4">
<property name="spacing">
<number>1</number>
</property>
<item row="1" column="0">
<widget class="QgsColorButtonV2" name="mSwatchButton9">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QgsColorButtonV2" name="mSwatchButton11">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QgsColorButtonV2" name="mSwatchButton12">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QgsColorButtonV2" name="mSwatchButton5">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QgsColorButtonV2" name="mSwatchButton2">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QgsColorButtonV2" name="mSwatchButton3">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QgsColorButtonV2" name="mSwatchButton1">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QgsColorButtonV2" name="mSwatchButton13">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QgsColorButtonV2" name="mSwatchButton6">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QgsColorButtonV2" name="mSwatchButton7">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QgsColorButtonV2" name="mSwatchButton14">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QgsColorButtonV2" name="mSwatchButton15">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QgsColorButtonV2" name="mSwatchButton8">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QgsColorButtonV2" name="mSwatchButton16">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QgsColorButtonV2" name="mSwatchButton4">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsColorButtonV2" name="mSwatchButton10">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QTabWidget" name="mTabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<widget class="QWidget" name="iconColorBox">
<attribute name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconColorBox.svg</normaloff>:/images/themes/default/mIconColorBox.svg</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Color ramp</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QgsColorBox" name="mColorBox" native="true"/>
</item>
<item>
<widget class="QgsColorRampWidget" name="mVerticalRamp" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="widget">
<attribute name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconColorWheel.svg</normaloff>:/images/themes/default/mIconColorWheel.svg</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Color wheel</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QgsColorWheel" name="mColorWheel" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconColorSwatches.svg</normaloff>:/images/themes/default/mIconColorSwatches.svg</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Color swatches</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,1,0">
<property name="spacing">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="QComboBox" name="mSchemeComboBox"/>
</item>
<item>
<widget class="QToolButton" name="mSchemeToolButton">
<property name="text">
<string>...</string>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QgsColorSchemeList" name="mSchemeList" native="true"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="spacing">
<number>1</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="mAddColorToSchemeButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mRemoveColorsFromSchemeButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconColorPicker.svg</normaloff>:/images/themes/default/mIconColorPicker.svg</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Color picker</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Sample average radius</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="mSpinBoxRadius">
<property name="suffix">
<string> px</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="mSampleButton">
<property name="text">
<string>Sample color</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>&lt;i&gt;Press space to sample a color from under the mouse cursor&lt;/i&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="margin">
<number>1</number>
</property>
<item>
<widget class="QgsColorPreviewWidget" name="mSamplePreview" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Current</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mOldColorLabel">
<property name="text">
<string>Old</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QPushButton" name="mAddCustomColorButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>28</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>28</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionAtlasNext.svg</normaloff>:/images/themes/default/mActionAtlasNext.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<property name="margin">
<number>1</number>
</property>
<item>
<widget class="QgsColorPreviewWidget" name="mColorPreview" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
<widget class="QgsCompoundColorWidget" name="mColorWidget" native="true"/>
</item>
<item>
<widget class="QDialogButtonBox" name="mButtonBox">
@ -887,57 +89,14 @@
</action>
</widget>
<customwidgets>
<customwidget>
<class>QgsColorBox</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorRampWidget</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorWheel</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorSliderWidget</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorTextWidget</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorPreviewWidget</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorSchemeList</class>
<extends>QWidget</extends>
<header location="global">qgscolorschemelist.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorButtonV2</class>
<extends>QToolButton</extends>
<header location="global">qgscolorbuttonv2.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../images/images.qrc"/>
</resources>
<customwidget>
<class>QgsCompoundColorWidget</class>
<extends>QWidget</extends>
<header>qgscompoundcolorwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,957 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsCompoundColorWidgetBase</class>
<widget class="QWidget" name="QgsCompoundColorWidgetBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>620</width>
<height>402</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="mGridLayout" rowstretch="1,0" columnstretch="1,0">
<property name="horizontalSpacing">
<number>6</number>
</property>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mHueRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>H</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mHueSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mSaturationRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>S</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mSaturationSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mValueRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>V</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mValueSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mRedRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>R</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mRedSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mGreenRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>G</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mGreenSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,0,1">
<item>
<widget class="QRadioButton" name="mBlueRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>B</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mBlueSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="mAlphaLayout">
<item>
<widget class="QLabel" name="mAlphaLabel">
<property name="text">
<string>Opacity</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorSliderWidget" name="mAlphaSlider" native="true"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>HTML notation</string>
</property>
</widget>
</item>
<item>
<widget class="QgsColorTextWidget" name="mColorText" native="true"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout_4">
<property name="spacing">
<number>1</number>
</property>
<item row="1" column="0">
<widget class="QgsColorButtonV2" name="mSwatchButton9">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QgsColorButtonV2" name="mSwatchButton11">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QgsColorButtonV2" name="mSwatchButton12">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QgsColorButtonV2" name="mSwatchButton5">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QgsColorButtonV2" name="mSwatchButton2">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QgsColorButtonV2" name="mSwatchButton3">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QgsColorButtonV2" name="mSwatchButton1">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QgsColorButtonV2" name="mSwatchButton13">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QgsColorButtonV2" name="mSwatchButton6">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QgsColorButtonV2" name="mSwatchButton7">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QgsColorButtonV2" name="mSwatchButton14">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QgsColorButtonV2" name="mSwatchButton15">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QgsColorButtonV2" name="mSwatchButton8">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QgsColorButtonV2" name="mSwatchButton16">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QgsColorButtonV2" name="mSwatchButton4">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsColorButtonV2" name="mSwatchButton10">
<property name="minimumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>38</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QTabWidget" name="mTabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<widget class="QWidget" name="iconColorBox">
<attribute name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconColorBox.svg</normaloff>:/images/themes/default/mIconColorBox.svg</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Color ramp</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QgsColorBox" name="mColorBox" native="true"/>
</item>
<item>
<widget class="QgsColorRampWidget" name="mVerticalRamp" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="widget">
<attribute name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconColorWheel.svg</normaloff>:/images/themes/default/mIconColorWheel.svg</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Color wheel</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QgsColorWheel" name="mColorWheel" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconColorSwatches.svg</normaloff>:/images/themes/default/mIconColorSwatches.svg</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Color swatches</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,1,0">
<property name="spacing">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
<number>1</number>
</property>
<item>
<widget class="QComboBox" name="mSchemeComboBox"/>
</item>
<item>
<widget class="QToolButton" name="mSchemeToolButton">
<property name="text">
<string>...</string>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QgsColorSchemeList" name="mSchemeList" native="true"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="spacing">
<number>1</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="mAddColorToSchemeButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mRemoveColorsFromSchemeButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconColorPicker.svg</normaloff>:/images/themes/default/mIconColorPicker.svg</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Color picker</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Sample average radius</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="mSpinBoxRadius">
<property name="suffix">
<string> px</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="mSampleButton">
<property name="text">
<string>Sample color</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>&lt;i&gt;Press space to sample a color from under the mouse cursor&lt;/i&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item>
<widget class="QgsColorPreviewWidget" name="mSamplePreview" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Current</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mOldColorLabel">
<property name="text">
<string>Old</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QPushButton" name="mAddCustomColorButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>28</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>28</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionAtlasNext.svg</normaloff>:/images/themes/default/mActionAtlasNext.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item>
<widget class="QgsColorPreviewWidget" name="mColorPreview" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
<action name="mActionImportColors">
<property name="text">
<string>Import Colors...</string>
</property>
<property name="toolTip">
<string>Import colors from file</string>
</property>
</action>
<action name="mActionExportColors">
<property name="text">
<string>Export Colors...</string>
</property>
<property name="toolTip">
<string>Export colors to file</string>
</property>
</action>
<action name="mActionPasteColors">
<property name="text">
<string>Paste Colors</string>
</property>
<property name="toolTip">
<string>Paste colors from clipboard</string>
</property>
</action>
<action name="mActionImportPalette">
<property name="text">
<string>Import Palette...</string>
</property>
<property name="toolTip">
<string>Import palette from file</string>
</property>
</action>
<action name="mActionRemovePalette">
<property name="text">
<string>Remove Palette</string>
</property>
<property name="toolTip">
<string>Remove current palette</string>
</property>
</action>
<action name="mActionNewPalette">
<property name="text">
<string>New Palette...</string>
</property>
<property name="toolTip">
<string>Create a new palette</string>
</property>
</action>
<action name="mActionCopyColors">
<property name="text">
<string>Copy Colors</string>
</property>
<property name="toolTip">
<string>Copy selected colors</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>QgsColorButtonV2</class>
<extends>QToolButton</extends>
<header>qgscolorbuttonv2.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorBox</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorRampWidget</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorWheel</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorSliderWidget</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorTextWidget</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorPreviewWidget</class>
<extends>QWidget</extends>
<header location="global">qgscolorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsColorSchemeList</class>
<extends>QWidget</extends>
<header location="global">qgscolorschemelist.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../images/images.qrc"/>
</resources>
<connections/>
</ui>