QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgscolorschemelist.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscolorschemelist.cpp
3  ----------------------
4  Date : August 2014
5  Copyright : (C) 2014 by Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgscolorschemelist.h"
17 #include "qgsapplication.h"
18 #include "qgslogger.h"
19 #include "qgssymbollayerutils.h"
20 #include "qgscolordialog.h"
21 #include "qgssettings.h"
22 
23 #include <QPainter>
24 #include <QColorDialog>
25 #include <QMimeData>
26 #include <QClipboard>
27 #include <QKeyEvent>
28 #include <QFileDialog>
29 #include <QMessageBox>
30 
31 #ifdef ENABLE_MODELTEST
32 #include "modeltest.h"
33 #endif
34 
35 QgsColorSchemeList::QgsColorSchemeList( QWidget *parent, QgsColorScheme *scheme, const QString &context, const QColor &baseColor )
36  : QTreeView( parent )
37  , mScheme( scheme )
38 {
39  mModel = new QgsColorSchemeModel( scheme, context, baseColor, this );
40 #ifdef ENABLE_MODELTEST
41  new ModelTest( mModel, this );
42 #endif
43  setModel( mModel );
44 
45  mSwatchDelegate = new QgsColorSwatchDelegate( this );
46  setItemDelegateForColumn( 0, mSwatchDelegate );
47 
48  setRootIsDecorated( false );
49  setSelectionMode( QAbstractItemView::ExtendedSelection );
50  setSelectionBehavior( QAbstractItemView::SelectRows );
51  setDragEnabled( true );
52  setAcceptDrops( true );
53  setDragDropMode( QTreeView::DragDrop );
54  setDropIndicatorShown( true );
55  setDefaultDropAction( Qt::CopyAction );
56 }
57 
58 void QgsColorSchemeList::setScheme( QgsColorScheme *scheme, const QString &context, const QColor &baseColor )
59 {
60  mScheme = scheme;
61  mModel->setScheme( scheme, context, baseColor );
62 }
63 
65 {
66  if ( !mScheme || !mScheme->isEditable() )
67  {
68  return false;
69  }
70 
71  mScheme->setColors( mModel->colors(), mModel->context(), mModel->baseColor() );
72  return true;
73 }
74 
76 {
77  QList<int> rows;
78  Q_FOREACH ( const QModelIndex &index, selectedIndexes() )
79  {
80  rows << index.row();
81  }
82  //remove duplicates
83  QList<int> rowsToRemove = QList<int>::fromSet( rows.toSet() );
84 
85  //remove rows in descending order
86  std::sort( rowsToRemove.begin(), rowsToRemove.end(), std::greater<int>() );
87  Q_FOREACH ( int row, rowsToRemove )
88  {
89  mModel->removeRow( row );
90  }
91 }
92 
93 void QgsColorSchemeList::addColor( const QColor &color, const QString &label, bool allowDuplicate )
94 {
95  mModel->addColor( color, label, allowDuplicate );
96 }
97 
99 {
100  QgsNamedColorList pastedColors = QgsSymbolLayerUtils::colorListFromMimeData( QApplication::clipboard()->mimeData() );
101 
102  if ( pastedColors.length() == 0 )
103  {
104  //no pasted colors
105  return;
106  }
107 
108  //insert pasted colors
109  QgsNamedColorList::const_iterator colorIt = pastedColors.constBegin();
110  for ( ; colorIt != pastedColors.constEnd(); ++colorIt )
111  {
112  mModel->addColor( ( *colorIt ).first, !( *colorIt ).second.isEmpty() ? ( *colorIt ).second : QgsSymbolLayerUtils::colorToName( ( *colorIt ).first ) );
113  }
114 }
115 
117 {
118  QList<int> rows;
119  Q_FOREACH ( const QModelIndex &index, selectedIndexes() )
120  {
121  rows << index.row();
122  }
123  //remove duplicates
124  QList<int> rowsToCopy = QList<int>::fromSet( rows.toSet() );
125 
126  QgsNamedColorList colorsToCopy;
127  Q_FOREACH ( int row, rowsToCopy )
128  {
129  colorsToCopy << mModel->colors().at( row );
130  }
131 
132  //copy colors
133  QMimeData *mimeData = QgsSymbolLayerUtils::colorListToMimeData( colorsToCopy );
134  QApplication::clipboard()->setMimeData( mimeData );
135 }
136 
138 {
139  QgsSettings s;
140  QString lastDir = s.value( QStringLiteral( "/UI/lastGplPaletteDir" ), QDir::homePath() ).toString();
141  QString filePath = QFileDialog::getOpenFileName( this, tr( "Select Palette File" ), lastDir, QStringLiteral( "GPL (*.gpl);;All files (*.*)" ) );
142  activateWindow();
143  if ( filePath.isEmpty() )
144  {
145  return;
146  }
147 
148  //check if file exists
149  QFileInfo fileInfo( filePath );
150  if ( !fileInfo.exists() || !fileInfo.isReadable() )
151  {
152  QMessageBox::critical( nullptr, tr( "Import Colors" ), tr( "Error, file does not exist or is not readable." ) );
153  return;
154  }
155 
156  s.setValue( QStringLiteral( "/UI/lastGplPaletteDir" ), fileInfo.absolutePath() );
157  QFile file( filePath );
158  bool importOk = importColorsFromGpl( file );
159  if ( !importOk )
160  {
161  QMessageBox::critical( nullptr, tr( "Import Colors" ), tr( "Error, no colors found in palette file." ) );
162  return;
163  }
164 }
165 
167 {
168  QgsSettings s;
169  QString lastDir = s.value( QStringLiteral( "/UI/lastGplPaletteDir" ), QDir::homePath() ).toString();
170  QString fileName = QFileDialog::getSaveFileName( this, tr( "Palette file" ), lastDir, QStringLiteral( "GPL (*.gpl)" ) );
171  activateWindow();
172  if ( fileName.isEmpty() )
173  {
174  return;
175  }
176 
177  // ensure filename contains extension
178  if ( !fileName.endsWith( QLatin1String( ".gpl" ), Qt::CaseInsensitive ) )
179  {
180  fileName += QLatin1String( ".gpl" );
181  }
182 
183  QFileInfo fileInfo( fileName );
184  s.setValue( QStringLiteral( "/UI/lastGplPaletteDir" ), fileInfo.absolutePath() );
185 
186  QFile file( fileName );
187  bool exportOk = exportColorsToGpl( file );
188  if ( !exportOk )
189  {
190  QMessageBox::critical( nullptr, tr( "Export Colors" ), tr( "Error writing palette file." ) );
191  return;
192  }
193 }
194 
195 void QgsColorSchemeList::keyPressEvent( QKeyEvent *event )
196 {
197  //listen out for delete/backspace presses and remove selected colors
198  if ( ( event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete ) )
199  {
200  QList<int> rows;
201  Q_FOREACH ( const QModelIndex &index, selectedIndexes() )
202  {
203  rows << index.row();
204  }
205  //remove duplicates
206  QList<int> rowsToRemove = QList<int>::fromSet( rows.toSet() );
207 
208  //remove rows in descending order
209  std::sort( rowsToRemove.begin(), rowsToRemove.end(), std::greater<int>() );
210  Q_FOREACH ( int row, rowsToRemove )
211  {
212  mModel->removeRow( row );
213  }
214  return;
215  }
216 
217  QTreeView::keyPressEvent( event );
218 }
219 
220 void QgsColorSchemeList::mousePressEvent( QMouseEvent *event )
221 {
222  if ( event->button() == Qt::LeftButton )
223  {
224  //record press start position
225  mDragStartPosition = event->pos();
226  }
227  QTreeView::mousePressEvent( event );
228 }
229 
230 void QgsColorSchemeList::mouseReleaseEvent( QMouseEvent *event )
231 {
232  if ( ( event->button() == Qt::LeftButton ) &&
233  ( event->pos() - mDragStartPosition ).manhattanLength() <= QApplication::startDragDistance() )
234  {
235  //just a click, not a drag
236 
237  //if only one item is selected, emit color changed signal
238  //(if multiple are selected, user probably was interacting with color list rather than trying to pick a color)
239  if ( selectedIndexes().length() == mModel->columnCount() )
240  {
241  QModelIndex selectedColor = selectedIndexes().at( 0 );
242  emit colorSelected( mModel->colors().at( selectedColor.row() ).first );
243  }
244  }
245 
246  QTreeView::mouseReleaseEvent( event );
247 }
248 
250 {
251  QgsNamedColorList importedColors;
252  bool ok = false;
253  QString name;
254  importedColors = QgsSymbolLayerUtils::importColorsFromGpl( file, ok, name );
255  if ( !ok )
256  {
257  return false;
258  }
259 
260  if ( importedColors.length() == 0 )
261  {
262  //no imported colors
263  return false;
264  }
265 
266  //insert imported colors
267  QgsNamedColorList::const_iterator colorIt = importedColors.constBegin();
268  for ( ; colorIt != importedColors.constEnd(); ++colorIt )
269  {
270  mModel->addColor( ( *colorIt ).first, !( *colorIt ).second.isEmpty() ? ( *colorIt ).second : QgsSymbolLayerUtils::colorToName( ( *colorIt ).first ) );
271  }
272 
273  return true;
274 }
275 
277 {
278  return QgsSymbolLayerUtils::saveColorsToGpl( file, QString(), mModel->colors() );
279 }
280 
282 {
283  if ( !mModel )
284  {
285  return false;
286  }
287 
288  return mModel->isDirty();
289 }
290 
292 {
293  return mScheme;
294 }
295 
296 //
297 // QgsColorSchemeModel
298 //
299 
300 QgsColorSchemeModel::QgsColorSchemeModel( QgsColorScheme *scheme, const QString &context, const QColor &baseColor, QObject *parent )
301  : QAbstractItemModel( parent )
302  , mScheme( scheme )
303  , mContext( context )
304  , mBaseColor( baseColor )
305  , mIsDirty( false )
306 {
307  if ( scheme )
308  {
309  mColors = scheme->fetchColors( context, baseColor );
310  }
311 }
312 
313 QModelIndex QgsColorSchemeModel::index( int row, int column, const QModelIndex &parent ) const
314 {
315  if ( column < 0 || column >= columnCount() )
316  {
317  //column out of bounds
318  return QModelIndex();
319  }
320 
321  if ( !parent.isValid() && row >= 0 && row < mColors.size() )
322  {
323  //return an index for the color item at this position
324  return createIndex( row, column );
325  }
326 
327  //only top level supported
328  return QModelIndex();
329 }
330 
331 QModelIndex QgsColorSchemeModel::parent( const QModelIndex &index ) const
332 {
333  Q_UNUSED( index );
334 
335  //all items are top level
336  return QModelIndex();
337 }
338 
339 int QgsColorSchemeModel::rowCount( const QModelIndex &parent ) const
340 {
341  if ( !parent.isValid() )
342  {
343  return mColors.size();
344  }
345  else
346  {
347  //no children
348  return 0;
349  }
350 }
351 
352 int QgsColorSchemeModel::columnCount( const QModelIndex &parent ) const
353 {
354  Q_UNUSED( parent );
355  return 2;
356 }
357 
358 QVariant QgsColorSchemeModel::data( const QModelIndex &index, int role ) const
359 {
360  if ( !index.isValid() )
361  return QVariant();
362 
363  QPair< QColor, QString > namedColor = mColors.at( index.row() );
364  switch ( role )
365  {
366  case Qt::DisplayRole:
367  case Qt::EditRole:
368  switch ( index.column() )
369  {
370  case ColorSwatch:
371  return namedColor.first;
372  case ColorLabel:
373  return namedColor.second;
374  default:
375  return QVariant();
376  }
377 
378  case Qt::TextAlignmentRole:
379  return QVariant( Qt::AlignLeft | Qt::AlignVCenter );
380 
381  default:
382  return QVariant();
383  }
384 }
385 
386 Qt::ItemFlags QgsColorSchemeModel::flags( const QModelIndex &index ) const
387 {
388  Qt::ItemFlags flags = QAbstractItemModel::flags( index );
389 
390  if ( ! index.isValid() )
391  {
392  return flags | Qt::ItemIsDropEnabled;
393  }
394 
395  switch ( index.column() )
396  {
397  case ColorSwatch:
398  case ColorLabel:
399  if ( mScheme && mScheme->isEditable() )
400  {
401  flags = flags | Qt::ItemIsEditable;
402  }
403  return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
404  default:
405  return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
406  }
407 }
408 
409 bool QgsColorSchemeModel::setData( const QModelIndex &index, const QVariant &value, int role )
410 {
411  Q_UNUSED( role );
412 
413  if ( !mScheme || !mScheme->isEditable() )
414  return false;
415 
416  if ( !index.isValid() )
417  return false;
418 
419  if ( index.row() >= mColors.length() )
420  return false;
421 
422  switch ( index.column() )
423  {
424  case ColorSwatch:
425  mColors[ index.row()].first = value.value<QColor>();
426  emit dataChanged( index, index );
427  mIsDirty = true;
428  return true;
429 
430  case ColorLabel:
431  mColors[ index.row()].second = value.toString();
432  emit dataChanged( index, index );
433  mIsDirty = true;
434  return true;
435 
436  default:
437  return false;
438  }
439 }
440 
441 QVariant QgsColorSchemeModel::headerData( int section, Qt::Orientation orientation, int role ) const
442 {
443  switch ( role )
444  {
445  case Qt::DisplayRole:
446  {
447  switch ( section )
448  {
449  case ColorSwatch:
450  return tr( "Color" );
451  case ColorLabel:
452  return tr( "Label" );
453  default:
454  return QVariant();
455  }
456  }
457 
458  case Qt::TextAlignmentRole:
459  switch ( section )
460  {
461  case ColorSwatch:
462  return QVariant( Qt::AlignHCenter | Qt::AlignVCenter );
463  case ColorLabel:
464  return QVariant( Qt::AlignLeft | Qt::AlignVCenter );
465  default:
466  return QVariant();
467  }
468  default:
469  return QAbstractItemModel::headerData( section, orientation, role );
470  }
471 }
472 
474 {
475  if ( mScheme && mScheme->isEditable() )
476  {
477  return Qt::CopyAction | Qt::MoveAction;
478  }
479  else
480  {
481  return Qt::CopyAction;
482  }
483 }
484 
486 {
487  if ( !mScheme || !mScheme->isEditable() )
488  {
489  return QStringList();
490  }
491 
492  QStringList types;
493  types << QStringLiteral( "text/xml" );
494  types << QStringLiteral( "text/plain" );
495  types << QStringLiteral( "application/x-color" );
496  types << QStringLiteral( "application/x-colorobject-list" );
497  return types;
498 }
499 
500 QMimeData *QgsColorSchemeModel::mimeData( const QModelIndexList &indexes ) const
501 {
502  QgsNamedColorList colorList;
503 
504  QModelIndexList::const_iterator indexIt = indexes.constBegin();
505  for ( ; indexIt != indexes.constEnd(); ++indexIt )
506  {
507  if ( ( *indexIt ).column() > 0 )
508  continue;
509 
510  colorList << qMakePair( mColors[( *indexIt ).row()].first, mColors[( *indexIt ).row()].second );
511  }
512 
513  QMimeData *mimeData = QgsSymbolLayerUtils::colorListToMimeData( colorList );
514  return mimeData;
515 }
516 
517 bool QgsColorSchemeModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
518 {
519  Q_UNUSED( column );
520 
521  if ( !mScheme || !mScheme->isEditable() )
522  {
523  return false;
524  }
525 
526  if ( action == Qt::IgnoreAction )
527  {
528  return true;
529  }
530 
531  if ( parent.isValid() )
532  {
533  return false;
534  }
535 
536  int beginRow = row != -1 ? row : rowCount( QModelIndex() );
538 
539  if ( droppedColors.length() == 0 )
540  {
541  //no dropped colors
542  return false;
543  }
544 
545  //any existing colors? if so, remove them first
546  QgsNamedColorList::const_iterator colorIt = droppedColors.constBegin();
547  for ( ; colorIt != droppedColors.constEnd(); ++colorIt )
548  {
549  //dest color
550  QPair< QColor, QString > color = qMakePair( ( *colorIt ).first, !( *colorIt ).second.isEmpty() ? ( *colorIt ).second : QgsSymbolLayerUtils::colorToName( ( *colorIt ).first ) );
551  //if color already exists, remove it
552  int existingIndex = mColors.indexOf( color );
553  if ( existingIndex >= 0 )
554  {
555  if ( existingIndex < beginRow )
556  {
557  //color is before destination row, so decrease destination row to account for removal
558  beginRow--;
559  }
560 
561  beginRemoveRows( parent, existingIndex, existingIndex );
562  mColors.removeAt( existingIndex );
563  endRemoveRows();
564  }
565  }
566 
567  //insert dropped colors
568  insertRows( beginRow, droppedColors.length(), QModelIndex() );
569  colorIt = droppedColors.constBegin();
570  for ( ; colorIt != droppedColors.constEnd(); ++colorIt )
571  {
572  QModelIndex colorIdx = index( beginRow, 0, QModelIndex() );
573  setData( colorIdx, QVariant( ( *colorIt ).first ) );
574  QModelIndex labelIdx = index( beginRow, 1, QModelIndex() );
575  setData( labelIdx, !( *colorIt ).second.isEmpty() ? ( *colorIt ).second : QgsSymbolLayerUtils::colorToName( ( *colorIt ).first ) );
576  beginRow++;
577  }
578  mIsDirty = true;
579 
580  return true;
581 }
582 
583 void QgsColorSchemeModel::setScheme( QgsColorScheme *scheme, const QString &context, const QColor &baseColor )
584 {
585  mScheme = scheme;
586  mContext = context;
587  mBaseColor = baseColor;
588  mIsDirty = false;
589  beginResetModel();
590  mColors = scheme->fetchColors( mContext, mBaseColor );
591  endResetModel();
592 }
593 
594 bool QgsColorSchemeModel::removeRows( int row, int count, const QModelIndex &parent )
595 {
596  if ( !mScheme || !mScheme->isEditable() )
597  {
598  return false;
599  }
600 
601  if ( parent.isValid() )
602  {
603  return false;
604  }
605 
606  if ( row >= mColors.count() )
607  {
608  return false;
609  }
610 
611  for ( int i = row + count - 1; i >= row; --i )
612  {
613  beginRemoveRows( parent, i, i );
614  mColors.removeAt( i );
615  endRemoveRows();
616  }
617 
618  mIsDirty = true;
619  return true;
620 }
621 
622 bool QgsColorSchemeModel::insertRows( int row, int count, const QModelIndex &parent )
623 {
624  Q_UNUSED( parent );
625 
626  if ( !mScheme || !mScheme->isEditable() )
627  {
628  return false;
629  }
630 
631  beginInsertRows( QModelIndex(), row, row + count - 1 );
632  for ( int i = row; i < row + count; ++i )
633  {
634  QPair< QColor, QString > newColor;
635  mColors.insert( i, newColor );
636  }
637  endInsertRows();
638  mIsDirty = true;
639  return true;
640 }
641 
642 void QgsColorSchemeModel::addColor( const QColor &color, const QString &label, bool allowDuplicate )
643 {
644  if ( !mScheme || !mScheme->isEditable() )
645  {
646  return;
647  }
648 
649  if ( !allowDuplicate )
650  {
651  //matches existing color? if so, remove it first
652  QPair< QColor, QString > newColor = qMakePair( color, !label.isEmpty() ? label : QgsSymbolLayerUtils::colorToName( color ) );
653  //if color already exists, remove it
654  int existingIndex = mColors.indexOf( newColor );
655  if ( existingIndex >= 0 )
656  {
657  beginRemoveRows( QModelIndex(), existingIndex, existingIndex );
658  mColors.removeAt( existingIndex );
659  endRemoveRows();
660  }
661  }
662 
663  int row = rowCount();
664  insertRow( row );
665  QModelIndex colorIdx = index( row, 0, QModelIndex() );
666  setData( colorIdx, QVariant( color ) );
667  QModelIndex labelIdx = index( row, 1, QModelIndex() );
668  setData( labelIdx, QVariant( label ) );
669  mIsDirty = true;
670 }
671 
672 
673 //
674 // QgsColorSwatchDelegate
675 //
677  : QAbstractItemDelegate( parent )
678  , mParent( parent )
679 {
680 
681 }
682 
683 void QgsColorSwatchDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
684 {
685  if ( option.state & QStyle::State_Selected )
686  {
687  painter->setPen( QPen( Qt::NoPen ) );
688  if ( option.state & QStyle::State_Active )
689  {
690  painter->setBrush( QBrush( option.widget->palette().highlight() ) );
691  }
692  else
693  {
694  painter->setBrush( QBrush( option.widget->palette().color( QPalette::Inactive,
695  QPalette::Highlight ) ) );
696  }
697  painter->drawRect( option.rect );
698  }
699 
700  QColor color = index.model()->data( index, Qt::DisplayRole ).value<QColor>();
701  if ( !color.isValid() )
702  {
703  return;
704  }
705 
706  QRect rect = option.rect;
707  const int iconSize = Qgis::UI_SCALE_FACTOR * option.fontMetrics.width( 'X' ) * 4;
708  const int cornerSize = iconSize / 6;
709  //center it
710  rect.setLeft( option.rect.center().x() - iconSize / 2 );
711 
712  rect.setSize( QSize( iconSize, iconSize ) );
713  rect.adjust( 0, 1, 0, 1 );
714  //create an icon pixmap
715  painter->save();
716  painter->setRenderHint( QPainter::Antialiasing );
717  painter->setPen( Qt::NoPen );
718  if ( color.alpha() < 255 )
719  {
720  //start with checkboard pattern
721  QBrush checkBrush = QBrush( transparentBackground() );
722  painter->setBrush( checkBrush );
723  painter->drawRoundedRect( rect, cornerSize, cornerSize );
724  }
725 
726  //draw semi-transparent color on top
727  painter->setBrush( color );
728  painter->drawRoundedRect( rect, cornerSize, cornerSize );
729  painter->restore();
730 }
731 
732 QPixmap QgsColorSwatchDelegate::transparentBackground() const
733 {
734  static QPixmap sTranspBkgrd;
735 
736  if ( sTranspBkgrd.isNull() )
737  sTranspBkgrd = QgsApplication::getThemePixmap( QStringLiteral( "/transp-background_8x8.png" ) );
738 
739  return sTranspBkgrd;
740 }
741 
742 QSize QgsColorSwatchDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
743 {
744  Q_UNUSED( index );
745 
746  const int iconSize = Qgis::UI_SCALE_FACTOR * option.fontMetrics.width( 'X' ) * 4;
747  return QSize( iconSize, iconSize * 32 / 30.0 );
748 }
749 
750 bool QgsColorSwatchDelegate::editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index )
751 {
752  Q_UNUSED( option );
753  if ( event->type() == QEvent::MouseButtonDblClick )
754  {
755  if ( !index.model()->flags( index ).testFlag( Qt::ItemIsEditable ) )
756  {
757  //item not editable
758  return false;
759  }
760 
761  QColor color = index.model()->data( index, Qt::DisplayRole ).value<QColor>();
762 
763  QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( qobject_cast< QWidget * >( parent() ) );
764  if ( panel && panel->dockMode() )
765  {
767  colorWidget->setPanelTitle( tr( "Select Color" ) );
768  colorWidget->setAllowOpacity( true );
769  colorWidget->setProperty( "index", index );
770  connect( colorWidget, &QgsCompoundColorWidget::currentColorChanged, this, &QgsColorSwatchDelegate::colorChanged );
771  panel->openPanel( colorWidget );
772  return true;
773  }
774 
775  QColor newColor = QgsColorDialog::getColor( color, mParent, tr( "Select color" ), true );
776  if ( !newColor.isValid() )
777  {
778  return false;
779  }
780 
781  return model->setData( index, newColor, Qt::EditRole );
782  }
783 
784  return false;
785 }
786 
787 void QgsColorSwatchDelegate::colorChanged()
788 {
789  if ( QgsCompoundColorWidget *colorWidget = qobject_cast< QgsCompoundColorWidget * >( sender() ) )
790  {
791  QModelIndex index = colorWidget->property( "index" ).toModelIndex();
792  const_cast< QAbstractItemModel * >( index.model() )->setData( index, colorWidget->color(), Qt::EditRole );
793  }
794 }
Qt::DropActions supportedDropActions() const override
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
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 colorSelected(const QColor &color)
Emitted when a color is selected from the list.
QString context() const
Gets the current color scheme context for the model.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void removeSelection()
Removes any selected colors from the list.
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition: qgis.h:152
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
Abstract base class for color schemes.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
static QgsNamedColorList colorListFromMimeData(const QMimeData *data)
Attempts to parse mime data as a list of named colors.
QModelIndex parent(const QModelIndex &index) const override
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setScheme(QgsColorScheme *scheme, const QString &context=QString(), const QColor &baseColor=QColor())
Sets the color scheme to show in the widget.
Qt::ItemFlags flags(const QModelIndex &index) const override
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
void setScheme(QgsColorScheme *scheme, const QString &context=QString(), const QColor &baseColor=QColor())
Sets the color scheme to show in the list.
Base class for any widget that can be shown as a inline panel.
void addColor(const QColor &color, const QString &label=QString(), bool allowDuplicate=false)
Adds a color to the list.
void pasteColors()
Pastes colors from clipboard to the list.
QgsColorSchemeModel(QgsColorScheme *scheme, const QString &context=QString(), const QColor &baseColor=QColor(), QObject *parent=nullptr)
Constructor.
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
static QPixmap getThemePixmap(const QString &name)
Helper to get a theme icon as a pixmap.
bool importColorsFromGpl(QFile &file)
Import colors from a GPL palette file to the list.
void mouseReleaseEvent(QMouseEvent *event) override
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
QgsColorScheme * scheme()
Returns the scheme currently selected in the list.
void showExportColorsDialog()
Displays a file picker dialog allowing users to export colors from the list into a file...
static QgsNamedColorList importColorsFromGpl(QFile &file, bool &ok, QString &name)
Imports colors from a gpl GIMP palette file.
virtual bool isEditable() const
Returns whether the color scheme is editable.
void mousePressEvent(QMouseEvent *event) override
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget...
void showImportColorsDialog()
Displays a file picker dialog allowing users to import colors into the list from a file...
A custom QGIS widget for selecting a color, including options for selecting colors via hue wheel...
bool isDirty() const
Returns whether the color scheme model has been modified.
static QString colorToName(const QColor &color)
Returns a friendly display name for a color.
bool isDirty() const
Returns whether the color scheme list has been modified.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
QgsColorSwatchDelegate(QWidget *parent=nullptr)
bool saveColorsToScheme()
Saves the current colors shown in the list back to a color scheme, if supported by the color scheme...
void setAllowOpacity(bool allowOpacity)
Sets whether opacity modification (transparency) is permitted for the color dialog.
static bool saveColorsToGpl(QFile &file, const QString &paletteName, const QgsNamedColorList &colors)
Exports colors to a gpl GIMP palette file.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
void copyColors()
Copies colors from the list to the clipboard.
void currentColorChanged(const QColor &color)
Emitted when the dialog&#39;s color changes.
virtual QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor())=0
Gets a list of colors from the scheme.
QStringList mimeTypes() const override
QgsColorSchemeList(QWidget *parent=nullptr, QgsColorScheme *scheme=nullptr, const QString &context=QString(), const QColor &baseColor=QColor())
Construct a new color swatch grid.
static QMimeData * colorListToMimeData(const QgsNamedColorList &colorList, bool allFormats=true)
Creates mime data from a list of named colors.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QgsNamedColorList colors() const
Returns a list of colors shown in the widget.
void keyPressEvent(QKeyEvent *event) override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
void addColor(const QColor &color, const QString &label=QString(), bool allowDuplicate=false)
Add a color to the list.
Use a narrower, vertically stacked layout.
virtual bool setColors(const QgsNamedColorList &colors, const QString &context=QString(), const QColor &baseColor=QColor())
Sets the colors for the scheme.
QColor baseColor() const
Gets the base color for the color scheme used by the model.
A delegate for showing a color swatch in a list.
QMimeData * mimeData(const QModelIndexList &indexes) const override
A model for colors in a color scheme.