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