mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-15 00:02:52 -04:00
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:
parent
6312ff5853
commit
cd54d6a355
@ -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
|
||||
|
140
python/gui/qgscolorschemelist.sip
Normal file
140
python/gui/qgscolorschemelist.sip
Normal 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() );
|
||||
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
541
src/gui/qgscolorschemelist.cpp
Normal file
541
src/gui/qgscolorschemelist.cpp
Normal 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;
|
||||
}
|
185
src/gui/qgscolorschemelist.h
Normal file
185
src/gui/qgscolorschemelist.h
Normal 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
|
@ -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"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user