QGIS API Documentation  3.6.0-Noosa (5873452)
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.
QgsNamedColorList colors() const
Returns a list of colors shown in the widget.
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:139
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
QColor baseColor() const
Gets the base color for the color scheme used by the model.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Abstract base class for color schemes.
QString context() const
Gets the current color scheme context for the model.
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
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.
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...
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.
bool isDirty() const
Returns whether the color scheme list has been modified.
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.
virtual bool isEditable() const
Returns whether the color scheme is editable.
static bool saveColorsToGpl(QFile &file, const QString &paletteName, const QgsNamedColorList &colors)
Exports colors to a gpl GIMP palette file.
bool isDirty() const
Returns whether the color scheme model has been modified.
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
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.
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.