New GUI control for an editable list of colors from a color scheme.

Supports drag and drop reordering, drag and drop colors from external
apps (on supported OS).
This commit is contained in:
Nyall Dawson 2014-08-16 16:28:18 +10:00
parent 6312ff5853
commit cd54d6a355
8 changed files with 888 additions and 126 deletions

View File

@ -36,6 +36,7 @@
%Include qgscolorbuttonv2.sip
%Include qgscolordialog.sip
%Include qgscolorswatchgrid.sip
%Include qgscolorschemelist.sip
%Include qgscomposerview.sip
%Include qgscredentialdialog.sip
%Include qgsdetaileditemdata.sip

View File

@ -0,0 +1,140 @@
/** \ingroup gui
* \class QgsColorSwatchDelegate
* A delegate for showing a color swatch in a list
* @see QgsColorSchemeList
* @note introduced in QGIS 2.5
*/
class QgsColorSwatchDelegate : QAbstractItemDelegate
{
%TypeHeaderCode
#include <qgscolorschemelist.h>
%End
public:
QgsColorSwatchDelegate( QWidget *parent /TransferThis/ = 0 );
void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
QSize sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
bool editorEvent( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index );
};
/** \ingroup gui
* \class QgsColorSchemeModel
* A model for colors in a color scheme
* @see QgsColorSchemeList
* @note introduced in QGIS 2.5
*/
class QgsColorSchemeModel: QAbstractItemModel
{
%TypeHeaderCode
#include <qgscolorschemelist.h>
%End
public:
/**Constructor
* @param scheme color scheme for list
* @param context context string for color scheme
* @param baseColor base color for color scheme
* @param parent parent object
*/
explicit QgsColorSchemeModel( QgsColorScheme* scheme, const QString context = QString(), const QColor baseColor = QColor(), QObject* parent /TransferThis/ = 0 );
~QgsColorSchemeModel();
//reimplemented QAbstractItemModel methods
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
QModelIndex parent( const QModelIndex &index ) const;
int rowCount( const QModelIndex &parent = QModelIndex() ) const;
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
Qt::ItemFlags flags( const QModelIndex & index ) const;
bool setData( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
Qt::DropActions supportedDropActions() const;
QStringList mimeTypes() const;
bool removeRows( int row, int count, const QModelIndex & parent = QModelIndex() );
bool insertRows( int row, int count, const QModelIndex &parent = QModelIndex() );
QMimeData *mimeData( const QModelIndexList &indexes ) const;
bool dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent );
/**Returns a list of colors shown in the widget
* @returns colors shown in the widget
*/
QgsNamedColorList colors() const;
/**Sets the color scheme to show in the widget
* @param scheme color scheme
* @param context context for color scheme
* @param baseColor base color for color scheme
*/
void setScheme( QgsColorScheme* scheme, const QString context = QString(), const QColor baseColor = QColor() );
/**Get the current color scheme context for the model
* @returns context string which is passed to scheme for color generation
* @see baseColor
*/
QString context() const;
/**Get the base color for the color scheme used by the model
* @returns base color which is passed to scheme for color generation
* @see context
*/
QColor baseColor() const;
/**Add a color to the list
* @param color color to add
* @param label label for color
*/
void addColor( const QColor color, const QString label = QString() );
};
/** \ingroup gui
* \class QgsColorSchemeList
* An editable list of color swatches, taken from an associated QgsColorScheme.
* @see QgsColorSchemeList
* @note introduced in QGIS 2.5
*/
class QgsColorSchemeList: QTreeView
{
%TypeHeaderCode
#include <qgscolorschemelist.h>
%End
public:
/**Construct a new color swatch grid.
* @param parent parent widget
* @param scheme QgsColorScheme for colors to show in the list
* @param context context string provided to color scheme
* @param baseColor base color for color scheme
*/
QgsColorSchemeList( QWidget *parent /TransferThis/ = 0, QgsColorScheme* scheme = 0, const QString context = QString(), const QColor baseColor = QColor() );
virtual ~QgsColorSchemeList();
/**Sets the color scheme to show in the list
* @param scheme QgsColorScheme for colors to show in the list
* @param context context string provided to color scheme
* @param baseColor base color for color scheme
*/
void setScheme( QgsColorScheme* scheme, const QString context = QString(), const QColor baseColor = QColor() );
/**Saves the current colors shown in the list back to a color scheme, if supported
* by the color scheme.
* @note this method is only effective if the color scheme is editable
*/
bool saveColorsToScheme();
/**Removes any selected colors from the list
*/
void removeSelection();
/**Adds a color to the list
* @param color color to add
* @param label optional label for color
*/
void addColor( const QColor color, const QString label = QString() );
};

View File

@ -36,6 +36,7 @@
#include "qgsrasterpyramidsoptionswidget.h"
#include "qgsdialog.h"
#include "qgscomposer.h"
#include "qgscolorschemeregistry.h"
#include <QInputDialog>
#include <QFileDialog>
@ -687,33 +688,14 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl ) :
//
// Color palette
//
QList< QVariant > customColorVariants = settings.value( QString( "/colors/palettecolors" ) ).toList();
QList< QVariant > customColorLabels = settings.value( QString( "/colors/palettelabels" ) ).toList();
QList<QTreeWidgetItem *> customColors;
int colorIndex = 0;
for ( QList< QVariant >::iterator it = customColorVariants.begin();
it != customColorVariants.end(); ++it )
//find custom color scheme from registry
QList<QgsCustomColorScheme *> customSchemes;
QgsColorSchemeRegistry::instance()->schemes( customSchemes );
if ( customSchemes.length() > 0 )
{
QColor color = ( *it ).value<QColor>();
QString label;
if ( customColorLabels.length() > colorIndex )
{
label = customColorLabels.at( colorIndex ).toString();
}
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setData( 0, PaletteLabelRole, label );
item->setText( 1, label );
setPaletteColor( item, color );
customColors.append( item );
colorIndex++;
mTreeCustomColors->setScheme( customSchemes.at( 0 ) );
}
mTreeCustomColors->clear();
mTreeCustomColors->insertTopLevelItems( 0, customColors );
mTreeCustomColors->resizeColumnToContents( 0 );
mTreeCustomColors->setColumnWidth( 0, mTreeCustomColors->columnWidth( 0 ) + 20 );
//
// Composer settings
@ -1329,19 +1311,7 @@ void QgsOptions::saveOptions()
//
// Color palette
//
QList< QVariant > customColors;
QList< QVariant > customColorLabels;
int colorCount = mTreeCustomColors->topLevelItemCount();
for ( int i = 0; i < colorCount; i++ )
{
QTreeWidgetItem* item = mTreeCustomColors->topLevelItem( i );
QVariant label = item->data( 0, PaletteLabelRole );
QVariant color = item->data( 0, PaletteColorRole );
customColors.append( color );
customColorLabels.append( label );
}
settings.setValue( QString( "/colors/palettecolors" ), customColors );
settings.setValue( QString( "/colors/palettelabels" ), customColorLabels );
mTreeCustomColors->saveColorsToScheme();
//
// Composer settings
@ -2114,73 +2084,10 @@ void QgsOptions::on_mButtonAddColor_clicked()
}
activateWindow();
QString newLabel = QInputDialog::getText( this, tr( "Color label" ),
tr( "Please enter a label for the color" ) );
activateWindow();
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setData( 0, PaletteLabelRole, newLabel );
item->setText( 1, newLabel );
setPaletteColor( item, newColor );
mTreeCustomColors->addTopLevelItem( item );
mTreeCustomColors->resizeColumnToContents( 0 );
mTreeCustomColors->setColumnWidth( 0, mTreeCustomColors->columnWidth( 0 ) + 20 );
mTreeCustomColors->addColor( newColor );
}
void QgsOptions::on_mButtonRemoveColor_clicked()
{
QTreeWidgetItem* item = mTreeCustomColors->currentItem();
if ( !item )
return;
int index = mTreeCustomColors->indexOfTopLevelItem( item );
mTreeCustomColors->takeTopLevelItem( index );
}
void QgsOptions::on_mTreeCustomColors_itemDoubleClicked( QTreeWidgetItem* item, int column )
{
if ( column == 0 )
{
QColor newColor = QColorDialog::getColor( item->data( 0, PaletteColorRole ).value<QColor>(), this->parentWidget(), tr( "Select color" ), QColorDialog::ShowAlphaChannel );
if ( !newColor.isValid() )
{
return;
}
setPaletteColor( item, newColor );
}
else
{
bool ok;
QString label = item->data( 0, PaletteLabelRole ).toString();
QString newLabel = QInputDialog::getText( this, tr( "Color label" ),
tr( "Please enter a label for the color" ),
QLineEdit::Normal, label, &ok );
if ( !ok )
{
return;
}
item->setText( 1, newLabel );
item->setData( 0, PaletteLabelRole, newLabel );
}
}
void QgsOptions::setPaletteColor( QTreeWidgetItem* item, QColor color )
{
QSize iconSize( 16, 16 );
QPixmap pixmap( iconSize );
pixmap.fill( QColor( 0, 0, 0, 0 ) );
QRect rect( 1, 1, iconSize.width() - 2, iconSize.height() - 2 );
// draw a slightly rounded rectangle
QPainter p;
p.begin( &pixmap );
p.setPen( Qt::NoPen );
p.setRenderHint( QPainter::Antialiasing );
p.setBrush( color );
p.drawRoundedRect( rect, 2, 2 );
p.end();
item->setIcon( 0, QIcon( pixmap ) );
item->setData( 0, PaletteColorRole, color );
item->setText( 0, color.name() );
mTreeCustomColors->removeSelection();
}

View File

@ -243,7 +243,6 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
void on_mButtonAddColor_clicked();
void on_mButtonRemoveColor_clicked();
void on_mTreeCustomColors_itemDoubleClicked( QTreeWidgetItem* item, int column );
private:
QStringList i18nList();
@ -260,8 +259,6 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
void saveDefaultDatumTransformations();
void setPaletteColor( QTreeWidgetItem *item, QColor color );
protected:
QgisAppStyleSheet* mStyleSheetBuilder;
QMap<QString, QVariant> mStyleSheetNewOpts;

View File

@ -128,6 +128,7 @@ qgscolorbutton.cpp
qgscolorbuttonv2.cpp
qgscolordialog.cpp
qgscolorswatchgrid.cpp
qgscolorschemelist.cpp
qgscodeeditor.cpp
qgscodeeditorpython.cpp
qgscodeeditorsql.cpp
@ -226,6 +227,7 @@ SET(QGIS_GUI_MOC_HDRS
qgscolorbutton.h
qgscolorbuttonv2.h
qgscolorswatchgrid.h
qgscolorschemelist.h
raster/qgsrasterminmaxwidget.h
raster/qgspalettedrendererwidget.h

View File

@ -0,0 +1,541 @@
/***************************************************************************
qgscolorschemelist.cpp
----------------------
Date : August 2014
Copyright : (C) 2014 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 "qgscolorschemelist.h"
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgssymbollayerv2utils.h"
#include <QPainter>
#include <QColorDialog>
#include <QDomDocument>
#include <QMimeData>
//For model testing
//#include "modeltest.h"
QgsColorSchemeList::QgsColorSchemeList( QWidget *parent , QgsColorScheme *scheme, const QString context, const QColor baseColor )
: QTreeView( parent )
, mScheme( scheme )
{
mModel = new QgsColorSchemeModel( scheme, context, baseColor, this );
//for testing:
//new ModelTest( mModel, this );
setModel( mModel );
mSwatchDelegate = new QgsColorSwatchDelegate( this );
setItemDelegateForColumn( 0, mSwatchDelegate );
setRootIsDecorated( false );
setSelectionMode( QAbstractItemView::ExtendedSelection );
setSelectionBehavior( QAbstractItemView::SelectRows );
setDragEnabled( true );
setAcceptDrops( true );
setDragDropMode( QTreeView::DragDrop );
setDropIndicatorShown( true );
setDefaultDropAction( Qt::MoveAction );
}
QgsColorSchemeList::~QgsColorSchemeList()
{
}
void QgsColorSchemeList::setScheme( QgsColorScheme *scheme, const QString context, const QColor baseColor )
{
mScheme = scheme;
mModel->setScheme( scheme, context, baseColor );
}
bool QgsColorSchemeList::saveColorsToScheme()
{
if ( !mScheme || !mScheme->isEditable() )
{
return false;
}
mScheme->setColors( mModel->colors(), mModel->context(), mModel->baseColor() );
return true;
}
void QgsColorSchemeList::removeSelection()
{
QList<int> rows;
foreach ( const QModelIndex &index, selectedIndexes() )
{
rows << index.row();
}
//remove duplicates
QList<int> rowsToRemove = QList<int>::fromSet( rows.toSet() );
//remove rows in descending order
qSort( rowsToRemove.begin(), rowsToRemove.end(), qGreater<int>() );
foreach ( const int row, rowsToRemove )
{
mModel->removeRow( row );
}
}
void QgsColorSchemeList::addColor( const QColor color, const QString label )
{
mModel->addColor( color, label );
}
//
// QgsColorSchemeModel
//
QgsColorSchemeModel::QgsColorSchemeModel( QgsColorScheme *scheme, const QString context, const QColor baseColor, QObject *parent )
: QAbstractItemModel( parent )
, mScheme( scheme )
, mContext( context )
, mBaseColor( baseColor )
{
if ( scheme )
{
mColors = scheme->fetchColors( context, baseColor );
}
}
QgsColorSchemeModel::~QgsColorSchemeModel()
{
}
QModelIndex QgsColorSchemeModel::index( int row, int column, const QModelIndex &parent ) const
{
if ( column < 0 || column >= columnCount() )
{
//column out of bounds
return QModelIndex();
}
if ( !parent.isValid() && row >= 0 && row < mColors.size() )
{
//return an index for the composer item at this position
return createIndex( row, column );
}
//only top level supported
return QModelIndex();
}
QModelIndex QgsColorSchemeModel::parent( const QModelIndex &index ) const
{
Q_UNUSED( index );
//all items are top level
return QModelIndex();
}
int QgsColorSchemeModel::rowCount( const QModelIndex &parent ) const
{
if ( !parent.isValid() )
{
return mColors.size();
}
else
{
//no children
return 0;
}
}
int QgsColorSchemeModel::columnCount( const QModelIndex &parent ) const
{
Q_UNUSED( parent );
return 2;
}
QVariant QgsColorSchemeModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() )
return QVariant();
QPair< QColor, QString > namedColor = mColors.at( index.row() );
switch ( role )
{
case Qt::DisplayRole:
case Qt::EditRole:
switch ( index.column() )
{
case ColorSwatch:
return namedColor.first;
case ColorLabel:
return namedColor.second;
default:
return QVariant();
}
case Qt::TextAlignmentRole:
return QVariant( Qt::AlignLeft | Qt::AlignVCenter );
default:
return QVariant();
}
}
Qt::ItemFlags QgsColorSchemeModel::flags( const QModelIndex &index ) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags( index );
if ( ! index.isValid() )
{
return flags | Qt::ItemIsDropEnabled;
}
switch ( index.column() )
{
case ColorSwatch:
case ColorLabel:
return flags | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
default:
return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
}
bool QgsColorSchemeModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
Q_UNUSED( role );
if ( !index.isValid() )
return false;
if ( index.row() >= mColors.length() )
return false;
switch ( index.column() )
{
case ColorSwatch:
mColors[ index.row()].first = value.value<QColor>();
emit dataChanged( index, index );
return true;
case ColorLabel:
mColors[ index.row()].second = value.toString();
emit dataChanged( index, index );
return true;
default:
return false;
}
}
QVariant QgsColorSchemeModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
switch ( role )
{
case Qt::DisplayRole:
{
switch ( section )
{
case ColorSwatch:
return tr( "Color" );
case ColorLabel:
return tr( "Label" );
default:
return QVariant();
}
break;
}
case Qt::TextAlignmentRole:
switch ( section )
{
case ColorSwatch:
return QVariant( Qt::AlignHCenter | Qt::AlignVCenter );
case ColorLabel:
return QVariant( Qt::AlignLeft | Qt::AlignVCenter );
default:
return QVariant();
}
default:
return QAbstractItemModel::headerData( section, orientation, role );
}
}
Qt::DropActions QgsColorSchemeModel::supportedDropActions() const
{
return Qt::MoveAction | Qt::CopyAction;;
}
QStringList QgsColorSchemeModel::mimeTypes() const
{
QStringList types;
types << "text/xml";
types << "text/plain";
types << "application/x-color";
return types;
}
QMimeData* QgsColorSchemeModel::mimeData( const QModelIndexList &indexes ) const
{
QMimeData* mimeData = new QMimeData();
QDomDocument xmlDoc;
QDomElement xmlRootElement = xmlDoc.createElement( "ColorSchemeModelDragData" );
xmlDoc.appendChild( xmlRootElement );
QModelIndexList::const_iterator indexIt = indexes.constBegin();
for ( ; indexIt != indexes.constEnd(); ++indexIt )
{
if (( *indexIt ).column() > 0 )
continue;
QDomElement namedColor = xmlDoc.createElement( "NamedColor" );
namedColor.setAttribute( "color", QgsSymbolLayerV2Utils::encodeColor( mColors[( *indexIt ).row()].first ) );
namedColor.setAttribute( "label", mColors[( *indexIt ).row()].second );
xmlRootElement.appendChild( namedColor );
}
mimeData->setData( "text/xml", xmlDoc.toByteArray() );
return mimeData;
}
bool QgsColorSchemeModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
{
Q_UNUSED( column );
if ( action == Qt::IgnoreAction )
{
return true;
}
if ( parent.isValid() )
{
return false;
}
int beginRow = row != -1 ? row : rowCount( QModelIndex() );
QgsNamedColorList droppedColors;
//prefer xml format
if ( data->hasFormat( "text/xml" ) )
{
//get XML doc
QByteArray encodedData = data->data( "text/xml" );
QDomDocument xmlDoc;
xmlDoc.setContent( encodedData );
QDomElement dragDataElem = xmlDoc.documentElement();
if ( dragDataElem.tagName() != "ColorSchemeModelDragData" )
{
return false;
}
QDomNodeList nodeList = dragDataElem.childNodes();
int nChildNodes = nodeList.size();
QDomElement currentElem;
for ( int i = 0; i < nChildNodes; ++i )
{
currentElem = nodeList.at( i ).toElement();
if ( currentElem.isNull() )
{
continue;
}
QPair< QColor, QString> namedColor;
namedColor.first = QgsSymbolLayerV2Utils::decodeColor( currentElem.attribute( "color", "255,255,255,255" ) );
namedColor.second = currentElem.attribute( "label", "" );
droppedColors << namedColor;
}
}
if ( droppedColors.length() == 0 && data->hasColor() )
{
//attempt to read color data directly from mime
QColor mimeColor = data->colorData().value<QColor>();
if ( mimeColor.isValid() )
{
droppedColors << qMakePair( mimeColor, QString() );
}
}
if ( droppedColors.length() == 0 && data->hasText() )
{
//attempt to read color data from mime text
QColor textColor = QgsSymbolLayerV2Utils::parseColor( data->text() );
if ( textColor.isValid() )
{
droppedColors << qMakePair( textColor, QString() );
}
}
if ( droppedColors.length() == 0 )
{
//no dropped colors
return false;
}
//insert dropped colors
insertRows( beginRow, droppedColors.length(), QModelIndex() );
QgsNamedColorList::const_iterator colorIt = droppedColors.constBegin();
for ( ; colorIt != droppedColors.constEnd(); ++colorIt )
{
QModelIndex colorIdx = index( beginRow, 0, QModelIndex() );
setData( colorIdx, QVariant(( *colorIt ).first ) );
QModelIndex labelIdx = index( beginRow, 1, QModelIndex() );
setData( labelIdx, QVariant(( *colorIt ).second ) );
beginRow++;
}
return true;
}
void QgsColorSchemeModel::setScheme( QgsColorScheme *scheme, const QString context, const QColor baseColor )
{
mScheme = scheme;
mContext = context;
mBaseColor = baseColor;
beginResetModel();
mColors = scheme->fetchColors( mContext, mBaseColor );
endResetModel();
}
bool QgsColorSchemeModel::removeRows( int row, int count, const QModelIndex &parent )
{
if ( parent.isValid() )
{
return false;
}
if ( row >= mColors.count() )
{
return false;
}
for ( int i = row + count - 1; i >= row; --i )
{
beginRemoveRows( parent, i, i );
mColors.removeAt( i );
endRemoveRows();
}
return true;
}
bool QgsColorSchemeModel::insertRows( int row, int count, const QModelIndex& parent )
{
Q_UNUSED( parent );
beginInsertRows( QModelIndex(), row, row + count - 1 );
for ( int i = row; i < row + count; ++i )
{
QPair< QColor, QString > newColor;
mColors.insert( i, newColor );
}
endInsertRows();
return true;
}
void QgsColorSchemeModel::addColor( const QColor color, const QString label )
{
int row = rowCount();
insertRow( row );
QModelIndex colorIdx = index( row, 0, QModelIndex() );
setData( colorIdx, QVariant( color ) );
QModelIndex labelIdx = index( row, 1, QModelIndex() );
setData( labelIdx, QVariant( label ) );
}
//
// QgsColorSwatchDelegate
//
QgsColorSwatchDelegate::QgsColorSwatchDelegate( QWidget *parent )
: QAbstractItemDelegate( parent )
, mParent( parent )
{
}
void QgsColorSwatchDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
if ( option.state & QStyle::State_Selected )
{
painter->setPen( QPen( Qt::NoPen ) );
if ( option.state & QStyle::State_Active )
{
painter->setBrush( QBrush( QPalette().highlight() ) );
}
else
{
painter->setBrush( QBrush( QPalette().color( QPalette::Inactive,
QPalette::Highlight ) ) );
}
painter->drawRect( option.rect );
}
QColor color = index.model()->data( index, Qt::DisplayRole ).value<QColor>();
if ( !color.isValid() )
{
return;
}
QRect rect = option.rect;
//center it
rect.setLeft( option.rect.center().x() - 15 );
rect.setSize( QSize( 30, 30 ) );
rect.adjust( 0, 1, 0, 1 );
//create an icon pixmap
painter->save();
painter->setRenderHint( QPainter::Antialiasing );
painter->setPen( Qt::NoPen );
if ( color.alpha() < 255 )
{
//start with checkboard pattern
QBrush checkBrush = QBrush( transparentBackground() );
painter->setBrush( checkBrush );
painter->drawRoundedRect( rect, 5, 5 );
}
//draw semi-transparent color on top
painter->setBrush( color );
painter->drawRoundedRect( rect, 5, 5 );
painter->restore();
}
const QPixmap& QgsColorSwatchDelegate::transparentBackground() const
{
static QPixmap transpBkgrd;
if ( transpBkgrd.isNull() )
transpBkgrd = QgsApplication::getThemePixmap( "/transp-background_8x8.png" );
return transpBkgrd;
}
QSize QgsColorSwatchDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
Q_UNUSED( option );
Q_UNUSED( index );
return QSize( 30, 32 );
}
bool QgsColorSwatchDelegate::editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index )
{
Q_UNUSED( option );
if ( event->type() == QEvent::MouseButtonDblClick )
{
QColor color = index.model()->data( index, Qt::DisplayRole ).value<QColor>();
QColor newColor = QColorDialog::getColor( color, mParent, tr( "Select color" ), QColorDialog::ShowAlphaChannel );
if ( !newColor.isValid() )
{
return false;
}
return model->setData( index, newColor, Qt::EditRole );
}
return false;
}

View File

@ -0,0 +1,185 @@
/***************************************************************************
qgscolorschemelist.h
--------------------
Date : August 2014
Copyright : (C) 2014 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 QGSCOLORSCHEMELIST_H
#define QGSCOLORSCHEMELIST_H
#include "qgscolorscheme.h"
#include <QTreeView>
#include <QAbstractItemModel>
#include <QItemDelegate>
class QMimeData;
/** \ingroup gui
* \class QgsColorSwatchDelegate
* A delegate for showing a color swatch in a list
* @see QgsColorSchemeList
* @note introduced in QGIS 2.5
*/
class QgsColorSwatchDelegate : public QAbstractItemDelegate
{
Q_OBJECT
public:
QgsColorSwatchDelegate( QWidget *parent = 0 );
void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
QSize sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
bool editorEvent( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index );
private:
QWidget* mParent;
/**Generates a checkboard pattern for transparent color backgrounds
* @returns checkboard pixmap
*/
const QPixmap &transparentBackground() const;
};
/** \ingroup gui
* \class QgsColorSchemeModel
* A model for colors in a color scheme
* @see QgsColorSchemeList
* @note introduced in QGIS 2.5
*/
class CORE_EXPORT QgsColorSchemeModel: public QAbstractItemModel
{
Q_OBJECT
public:
/**Constructor
* @param scheme color scheme for list
* @param context context string for color scheme
* @param baseColor base color for color scheme
* @param parent parent object
*/
explicit QgsColorSchemeModel( QgsColorScheme* scheme, const QString context = QString(), const QColor baseColor = QColor(), QObject* parent = 0 );
~QgsColorSchemeModel();
//reimplemented QAbstractItemModel methods
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
QModelIndex parent( const QModelIndex &index ) const;
int rowCount( const QModelIndex &parent = QModelIndex() ) const;
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
Qt::ItemFlags flags( const QModelIndex & index ) const;
bool setData( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
Qt::DropActions supportedDropActions() const;
QStringList mimeTypes() const;
bool removeRows( int row, int count, const QModelIndex & parent = QModelIndex() );
bool insertRows( int row, int count, const QModelIndex &parent = QModelIndex() );
QMimeData *mimeData( const QModelIndexList &indexes ) const;
bool dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent );
/**Returns a list of colors shown in the widget
* @returns colors shown in the widget
*/
QgsNamedColorList colors() const { return mColors; }
/**Sets the color scheme to show in the widget
* @param scheme color scheme
* @param context context for color scheme
* @param baseColor base color for color scheme
*/
void setScheme( QgsColorScheme* scheme, const QString context = QString(), const QColor baseColor = QColor() );
/**Get the current color scheme context for the model
* @returns context string which is passed to scheme for color generation
* @see baseColor
*/
QString context() const { return mContext; }
/**Get the base color for the color scheme used by the model
* @returns base color which is passed to scheme for color generation
* @see context
*/
QColor baseColor() const { return mBaseColor; }
/**Add a color to the list
* @param color color to add
* @param label label for color
*/
void addColor( const QColor color, const QString label = QString() );
private:
enum Columns
{
ColorSwatch = 0,
ColorLabel
};
QgsNamedColorList mColors;
QgsColorScheme* mScheme;
QString mContext;
QColor mBaseColor;
};
/** \ingroup gui
* \class QgsColorSchemeList
* An editable list of color swatches, taken from an associated QgsColorScheme.
* @see QgsColorSchemeList
* @note introduced in QGIS 2.5
*/
class GUI_EXPORT QgsColorSchemeList: public QTreeView
{
Q_OBJECT
public:
/**Construct a new color swatch grid.
* @param parent parent widget
* @param scheme QgsColorScheme for colors to show in the list
* @param context context string provided to color scheme
* @param baseColor base color for color scheme
*/
QgsColorSchemeList( QWidget *parent = 0, QgsColorScheme* scheme = 0, const QString context = QString(), const QColor baseColor = QColor() );
virtual ~QgsColorSchemeList();
/**Sets the color scheme to show in the list
* @param scheme QgsColorScheme for colors to show in the list
* @param context context string provided to color scheme
* @param baseColor base color for color scheme
*/
void setScheme( QgsColorScheme* scheme, const QString context = QString(), const QColor baseColor = QColor() );
/**Saves the current colors shown in the list back to a color scheme, if supported
* by the color scheme.
* @note this method is only effective if the color scheme is editable
*/
bool saveColorsToScheme();
/**Removes any selected colors from the list
*/
void removeSelection();
/**Adds a color to the list
* @param color color to add
* @param label optional label for color
*/
void addColor( const QColor color, const QString label = QString() );
private:
QgsColorScheme* mScheme;
QgsColorSchemeModel* mModel;
QgsColorSwatchDelegate* mSwatchDelegate;
};
#endif

View File

@ -263,7 +263,7 @@
<item>
<widget class="QStackedWidget" name="mOptionsStackedWidget">
<property name="currentIndex">
<number>0</number>
<number>4</number>
</property>
<widget class="QWidget" name="mOptionsPageGeneral">
<layout class="QVBoxLayout" name="verticalLayout_3">
@ -2301,26 +2301,6 @@
</property>
</widget>
</item>
<item row="0" column="0" rowspan="4">
<widget class="QTreeWidget" name="mTreeCustomColors">
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="columnCount">
<number>2</number>
</property>
<column>
<property name="text">
<string>Color</string>
</property>
</column>
<column>
<property name="text">
<string>Label</string>
</property>
</column>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="mButtonRemoveColor">
<property name="text">
@ -2328,6 +2308,10 @@
</property>
</widget>
</item>
<item row="0" column="0" rowspan="4">
<widget class="QgsColorSchemeList" name="mTreeCustomColors">
</widget>
</item>
</layout>
</widget>
</item>
@ -4708,6 +4692,11 @@
<extends>QWidget</extends>
<header>qgsscalecombobox.h</header>
</customwidget>
<customwidget>
<class>QgsColorSchemeList</class>
<extends>QTreeView</extends>
<header>qgscolorschemelist.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../images/images.qrc"/>