17#include "moc_qgscolorschemelist.cpp" 
   25#include <QColorDialog> 
   32#ifdef ENABLE_MODELTEST 
   41#ifdef ENABLE_MODELTEST 
   42  new ModelTest( mModel, 
this );
 
   47  setItemDelegateForColumn( 0, mSwatchDelegate );
 
   49  setRootIsDecorated( 
false );
 
   50  setSelectionMode( QAbstractItemView::ExtendedSelection );
 
   51  setSelectionBehavior( QAbstractItemView::SelectRows );
 
   52  setDragEnabled( 
true );
 
   53  setAcceptDrops( 
true );
 
   54  setDragDropMode( QTreeView::DragDrop );
 
   55  setDropIndicatorShown( 
true );
 
   56  setDefaultDropAction( Qt::CopyAction );
 
 
   79  const auto constSelectedIndexes = selectedIndexes();
 
   80  for ( 
const QModelIndex &index : constSelectedIndexes )
 
   85  QList<int> rowsToRemove = qgis::setToList( qgis::listToSet( rows ) );
 
   88  std::sort( rowsToRemove.begin(), rowsToRemove.end(), std::greater<int>() );
 
   89  const auto constRowsToRemove = rowsToRemove;
 
   90  for ( 
const int row : constRowsToRemove )
 
   92    mModel->removeRow( row );
 
 
   98  mModel->
addColor( color, label, allowDuplicate );
 
 
  105  if ( pastedColors.length() == 0 )
 
  112  QgsNamedColorList::const_iterator colorIt = pastedColors.constBegin();
 
  113  for ( ; colorIt != pastedColors.constEnd(); ++colorIt )
 
 
  122  const auto constSelectedIndexes = selectedIndexes();
 
  123  for ( 
const QModelIndex &index : constSelectedIndexes )
 
  128  const QList<int> rowsToCopy = qgis::setToList( qgis::listToSet( rows ) );
 
  131  const auto constRowsToCopy = rowsToCopy;
 
  132  for ( 
const int row : constRowsToCopy )
 
  134    colorsToCopy << mModel->
colors().at( row );
 
  139  QApplication::clipboard()->setMimeData( mimeData );
 
 
  145  const QString lastDir = s.
value( QStringLiteral( 
"/UI/lastGplPaletteDir" ), QDir::homePath() ).toString();
 
  146  const QString filePath = QFileDialog::getOpenFileName( 
this, tr( 
"Select Palette File" ), lastDir, QStringLiteral( 
"GPL (*.gpl);;All files (*.*)" ) );
 
  148  if ( filePath.isEmpty() )
 
  154  const QFileInfo fileInfo( filePath );
 
  155  if ( !fileInfo.exists() || !fileInfo.isReadable() )
 
  157    QMessageBox::critical( 
nullptr, tr( 
"Import Colors" ), tr( 
"Error, file does not exist or is not readable." ) );
 
  161  s.
setValue( QStringLiteral( 
"/UI/lastGplPaletteDir" ), fileInfo.absolutePath() );
 
  162  QFile file( filePath );
 
  166    QMessageBox::critical( 
nullptr, tr( 
"Import Colors" ), tr( 
"Error, no colors found in palette file." ) );
 
 
  174  const QString lastDir = s.
value( QStringLiteral( 
"/UI/lastGplPaletteDir" ), QDir::homePath() ).toString();
 
  175  QString fileName = QFileDialog::getSaveFileName( 
this, tr( 
"Palette file" ), lastDir, QStringLiteral( 
"GPL (*.gpl)" ) );
 
  177  if ( fileName.isEmpty() )
 
  183  if ( !fileName.endsWith( QLatin1String( 
".gpl" ), Qt::CaseInsensitive ) )
 
  185    fileName += QLatin1String( 
".gpl" );
 
  188  const QFileInfo fileInfo( fileName );
 
  189  s.
setValue( QStringLiteral( 
"/UI/lastGplPaletteDir" ), fileInfo.absolutePath() );
 
  191  QFile file( fileName );
 
  195    QMessageBox::critical( 
nullptr, tr( 
"Export Colors" ), tr( 
"Error writing palette file." ) );
 
 
  203  if ( ( event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete ) )
 
  206    const auto constSelectedIndexes = selectedIndexes();
 
  207    for ( 
const QModelIndex &index : constSelectedIndexes )
 
  212    QList<int> rowsToRemove = qgis::setToList( qgis::listToSet( rows ) );
 
  215    std::sort( rowsToRemove.begin(), rowsToRemove.end(), std::greater<int>() );
 
  216    const auto constRowsToRemove = rowsToRemove;
 
  217    for ( 
const int row : constRowsToRemove )
 
  219      mModel->removeRow( row );
 
  224  QTreeView::keyPressEvent( event );
 
 
  229  if ( event->button() == Qt::LeftButton )
 
  232    mDragStartPosition = 
event->pos();
 
  234  QTreeView::mousePressEvent( event );
 
 
  239  if ( ( event->button() == Qt::LeftButton ) && ( event->pos() - mDragStartPosition ).manhattanLength() <= QApplication::startDragDistance() )
 
  245    if ( selectedIndexes().length() == mModel->
columnCount() )
 
  247      const QModelIndex selectedColor = selectedIndexes().at( 0 );
 
  252  QTreeView::mouseReleaseEvent( event );
 
 
  266  if ( importedColors.length() == 0 )
 
  273  QgsNamedColorList::const_iterator colorIt = importedColors.constBegin();
 
  274  for ( ; colorIt != importedColors.constEnd(); ++colorIt )
 
 
  307  : QAbstractItemModel( parent )
 
  309  , mContext( context )
 
  310  , mBaseColor( baseColor )
 
 
  324    return QModelIndex();
 
  327  if ( !
parent.isValid() && row >= 0 && row < mColors.size() )
 
  330    return createIndex( row, column );
 
  334  return QModelIndex();
 
 
  342  return QModelIndex();
 
 
  349    return mColors.size();
 
 
  366  if ( !
index.isValid() )
 
  369  const QPair<QColor, QString> namedColor = mColors.at( 
index.row() );
 
  372    case Qt::DisplayRole:
 
  374      switch ( 
index.column() )
 
  377          return namedColor.first;
 
  379          return namedColor.second;
 
  384    case Qt::TextAlignmentRole:
 
  385      return static_cast<Qt::Alignment::Int
>( Qt::AlignLeft | Qt::AlignVCenter );
 
 
  394  Qt::ItemFlags 
flags = QAbstractItemModel::flags( 
index );
 
  396  if ( !
index.isValid() )
 
  398    return flags | Qt::ItemIsDropEnabled;
 
  401  switch ( 
index.column() )
 
  409      return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
 
  411      return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
 
 
  422  if ( !
index.isValid() )
 
  425  if ( 
index.row() >= mColors.length() )
 
  428  switch ( 
index.column() )
 
  431      mColors[
index.row()].first = value.value<QColor>();
 
  437      mColors[
index.row()].second = value.toString();
 
 
  451    case Qt::DisplayRole:
 
  456          return tr( 
"Color" );
 
  458          return tr( 
"Label" );
 
  464    case Qt::TextAlignmentRole:
 
  468          return static_cast<Qt::Alignment::Int
>( Qt::AlignHCenter | Qt::AlignVCenter );
 
  470          return static_cast<Qt::Alignment::Int
>( Qt::AlignLeft | Qt::AlignVCenter );
 
  475      return QAbstractItemModel::headerData( section, orientation, role );
 
 
  483    return Qt::CopyAction | Qt::MoveAction;
 
  487    return Qt::CopyAction;
 
 
  495    return QStringList();
 
  499  types << QStringLiteral( 
"text/xml" );
 
  500  types << QStringLiteral( 
"text/plain" );
 
  501  types << QStringLiteral( 
"application/x-color" );
 
  502  types << QStringLiteral( 
"application/x-colorobject-list" );
 
 
  510  QModelIndexList::const_iterator indexIt = indexes.constBegin();
 
  511  for ( ; indexIt != indexes.constEnd(); ++indexIt )
 
  513    if ( ( *indexIt ).column() > 0 )
 
  516    colorList << qMakePair( mColors[( *indexIt ).row()].first, mColors[( *indexIt ).row()].second );
 
 
  532  if ( action == Qt::IgnoreAction )
 
  542  int beginRow = row != -1 ? row : 
rowCount( QModelIndex() );
 
  545  if ( droppedColors.length() == 0 )
 
  552  QgsNamedColorList::const_iterator colorIt = droppedColors.constBegin();
 
  553  for ( ; colorIt != droppedColors.constEnd(); ++colorIt )
 
  556    const QPair<QColor, QString> color = qMakePair( ( *colorIt ).first, !( *colorIt ).second.isEmpty() ? ( *colorIt ).second : 
QgsSymbolLayerUtils::colorToName( ( *colorIt ).first ) );
 
  558    const int existingIndex = mColors.indexOf( color );
 
  559    if ( existingIndex >= 0 )
 
  561      if ( existingIndex < beginRow )
 
  567      beginRemoveRows( 
parent, existingIndex, existingIndex );
 
  568      mColors.removeAt( existingIndex );
 
  574  insertRows( beginRow, droppedColors.length(), QModelIndex() );
 
  575  colorIt = droppedColors.constBegin();
 
  576  for ( ; colorIt != droppedColors.constEnd(); ++colorIt )
 
  578    const QModelIndex colorIdx = 
index( beginRow, 0, QModelIndex() );
 
  579    setData( colorIdx, QVariant( ( *colorIt ).first ) );
 
  580    const QModelIndex labelIdx = 
index( beginRow, 1, QModelIndex() );
 
 
  596  mColors = scheme->
fetchColors( mContext, mBaseColor );
 
 
  612  if ( row >= mColors.count() )
 
  617  for ( 
int i = row + count - 1; i >= row; --i )
 
  619    beginRemoveRows( 
parent, i, i );
 
  620    mColors.removeAt( i );
 
 
  637  beginInsertRows( QModelIndex(), row, row + count - 1 );
 
  638  for ( 
int i = row; i < row + count; ++i )
 
  640    const QPair<QColor, QString> newColor;
 
  641    mColors.insert( i, newColor );
 
 
  655  if ( !allowDuplicate )
 
  660    const int existingIndex = mColors.indexOf( newColor );
 
  661    if ( existingIndex >= 0 )
 
  663      beginRemoveRows( QModelIndex(), existingIndex, existingIndex );
 
  664      mColors.removeAt( existingIndex );
 
  671  const QModelIndex colorIdx = 
index( row, 0, QModelIndex() );
 
  672  setData( colorIdx, QVariant( color ) );
 
  673  const QModelIndex labelIdx = 
index( row, 1, QModelIndex() );
 
  674  setData( labelIdx, QVariant( label ) );
 
 
  683  : QAbstractItemDelegate( parent )
 
 
  690  if ( option.state & QStyle::State_Selected )
 
  692    painter->setPen( QPen( Qt::NoPen ) );
 
  693    if ( option.state & QStyle::State_Active )
 
  695      painter->setBrush( QBrush( option.widget->palette().highlight() ) );
 
  699      painter->setBrush( QBrush( option.widget->palette().color( QPalette::Inactive, QPalette::Highlight ) ) );
 
  701    painter->drawRect( option.rect );
 
  704  QColor color = index.model()->data( index, Qt::DisplayRole ).value<QColor>();
 
  705  if ( !color.isValid() )
 
  710  QRect rect = option.rect;
 
  713  const int cornerSize = iconSize / 6;
 
  715  rect.setLeft( option.rect.center().x() - iconSize / 2 );
 
  717  rect.setSize( QSize( iconSize, iconSize ) );
 
  718  rect.adjust( 0, 1, 0, 1 );
 
  721  painter->setRenderHint( QPainter::Antialiasing );
 
  722  painter->setPen( Qt::NoPen );
 
  723  if ( color.alpha() < 255 )
 
  726    const QBrush checkBrush = QBrush( transparentBackground() );
 
  727    painter->setBrush( checkBrush );
 
  728    painter->drawRoundedRect( rect, cornerSize, cornerSize );
 
  730    painter->setBrush( color );
 
  731    painter->drawRoundedRect( rect, cornerSize, cornerSize );
 
  733    const QRectF clipRect( rect.left(), rect.top(), 
static_cast<qreal
>( rect.width() ) / 2.0, rect.height() );
 
  734    painter->setClipRect( clipRect );
 
  735    color.setAlpha( 255 );
 
  736    painter->setBrush( color );
 
  737    painter->drawRoundedRect( rect, cornerSize, cornerSize );
 
  741    painter->setBrush( color );
 
  742    painter->drawRoundedRect( rect, cornerSize, cornerSize );
 
 
  746QPixmap QgsColorSwatchDelegate::transparentBackground()
 const 
  748  static QPixmap sTranspBkgrd;
 
  750  if ( sTranspBkgrd.isNull() )
 
  761  return QSize( iconSize, iconSize * 32 / 30.0 );
 
 
  767  if ( event->type() == QEvent::MouseButtonDblClick )
 
  769    if ( !index.model()->flags( index ).testFlag( Qt::ItemIsEditable ) )
 
  775    const QColor color = index.model()->data( index, Qt::DisplayRole ).value<QColor>();
 
  778    if ( panel && panel->dockMode() )
 
  783      colorWidget->setProperty( 
"index", index );
 
  785      panel->openPanel( colorWidget );
 
  790    if ( !newColor.isValid() )
 
  795    return model->setData( index, newColor, Qt::EditRole );
 
 
  801void QgsColorSwatchDelegate::colorChanged()
 
  805    const QModelIndex index = colorWidget->property( 
"index" ).toModelIndex();
 
  806    const_cast<QAbstractItemModel *
>( index.model() )->setData( index, colorWidget->color(), Qt::EditRole );
 
static const double UI_SCALE_FACTOR
UI scaling factor.
 
static QPixmap getThemePixmap(const QString &name, const QColor &foreColor=QColor(), const QColor &backColor=QColor(), int size=16)
Helper to get a theme icon as a pixmap.
 
static QColor getColor(const QColor &initialColor, QWidget *parent, const QString &title=QString(), bool allowOpacity=false)
Returns a color selection from a color dialog.
 
bool exportColorsToGpl(QFile &file)
Export colors to a GPL palette file from the list.
 
void setScheme(QgsColorScheme *scheme, const QString &context=QString(), const QColor &baseColor=QColor())
Sets the color scheme to show in the list.
 
void pasteColors()
Pastes colors from clipboard to the list.
 
void removeSelection()
Removes any selected colors from the list.
 
bool importColorsFromGpl(QFile &file)
Import colors from a GPL palette file to the list.
 
void copyColors()
Copies colors from the list to the clipboard.
 
bool isDirty() const
Returns whether the color scheme list has been modified.
 
void mouseReleaseEvent(QMouseEvent *event) override
 
void mousePressEvent(QMouseEvent *event) override
 
QgsColorScheme * scheme()
Returns the scheme currently selected in the list.
 
void addColor(const QColor &color, const QString &label=QString(), bool allowDuplicate=false)
Adds a color to the list.
 
void showExportColorsDialog()
Displays a file picker dialog allowing users to export colors from the list into a file.
 
void colorSelected(const QColor &color)
Emitted when a color is selected from the list.
 
void keyPressEvent(QKeyEvent *event) override
 
QgsColorSchemeList(QWidget *parent=nullptr, QgsColorScheme *scheme=nullptr, const QString &context=QString(), const QColor &baseColor=QColor())
Construct a new color swatch grid.
 
bool saveColorsToScheme()
Saves the current colors shown in the list back to a color scheme, if supported by the color scheme.
 
void showImportColorsDialog()
Displays a file picker dialog allowing users to import colors into the list from a file.
 
A model for colors in a color scheme.
 
QgsNamedColorList colors() const
Returns a list of colors shown in the widget.
 
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
 
void addColor(const QColor &color, const QString &label=QString(), bool allowDuplicate=false)
Add a color to the list.
 
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
 
QColor baseColor() const
Gets the base color for the color scheme used by the model.
 
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
 
int rowCount(const QModelIndex &parent=QModelIndex()) const override
 
Qt::DropActions supportedDropActions() const override
 
QModelIndex parent(const QModelIndex &index) const override
 
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
 
Qt::ItemFlags flags(const QModelIndex &index) const override
 
void setScheme(QgsColorScheme *scheme, const QString &context=QString(), const QColor &baseColor=QColor())
Sets the color scheme to show in the widget.
 
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
 
QMimeData * mimeData(const QModelIndexList &indexes) const override
 
bool isDirty() const
Returns whether the color scheme model has been modified.
 
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
 
QgsColorSchemeModel(QgsColorScheme *scheme, const QString &context=QString(), const QColor &baseColor=QColor(), QObject *parent=nullptr)
Constructor.
 
QStringList mimeTypes() const override
 
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
 
QString context() const
Gets the current color scheme context for the model.
 
int columnCount(const QModelIndex &parent=QModelIndex()) const override
 
Abstract base class for color schemes.
 
virtual bool setColors(const QgsNamedColorList &colors, const QString &context=QString(), const QColor &baseColor=QColor())
Sets the colors for the scheme.
 
virtual QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor())=0
Gets a list of colors from the scheme.
 
virtual bool isEditable() const
Returns whether the color scheme is editable.
 
A delegate for showing a color swatch in a list.
 
QgsColorSwatchDelegate(QWidget *parent=nullptr)
 
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
 
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
 
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
 
Scoped object for saving and restoring a QPainter object's state.
 
Stores settings for use within QGIS.
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
 
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
 
static bool saveColorsToGpl(QFile &file, const QString &paletteName, const QgsNamedColorList &colors)
Exports colors to a gpl GIMP palette file.
 
static QgsNamedColorList colorListFromMimeData(const QMimeData *data)
Attempts to parse mime data as a list of named colors.
 
static QMimeData * colorListToMimeData(const QgsNamedColorList &colorList, bool allFormats=true)
Creates mime data from a list of named colors.
 
static QgsNamedColorList importColorsFromGpl(QFile &file, bool &ok, QString &name)
Imports colors from a gpl GIMP palette file.
 
static QString colorToName(const QColor &color)
Returns a friendly display name for a color.
 
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.