24 #include <QColorDialog>
28 #include <QFileDialog>
29 #include <QMessageBox>
31 #ifdef ENABLE_MODELTEST
32 #include "modeltest.h"
40 #ifdef ENABLE_MODELTEST
41 new ModelTest( mModel,
this );
46 setItemDelegateForColumn( 0, mSwatchDelegate );
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 );
78 const auto constSelectedIndexes = selectedIndexes();
79 for (
const QModelIndex &index : constSelectedIndexes )
84 QList<int> rowsToRemove = qgis::setToList( qgis::listToSet( rows ) );
87 std::sort( rowsToRemove.begin(), rowsToRemove.end(), std::greater<int>() );
88 const auto constRowsToRemove = rowsToRemove;
89 for (
const int row : constRowsToRemove )
91 mModel->removeRow( row );
97 mModel->
addColor( color, label, allowDuplicate );
104 if ( pastedColors.length() == 0 )
111 QgsNamedColorList::const_iterator colorIt = pastedColors.constBegin();
112 for ( ; colorIt != pastedColors.constEnd(); ++colorIt )
121 const auto constSelectedIndexes = selectedIndexes();
122 for (
const QModelIndex &index : constSelectedIndexes )
127 const QList<int> rowsToCopy = qgis::setToList( qgis::listToSet( rows ) );
130 const auto constRowsToCopy = rowsToCopy;
131 for (
const int row : constRowsToCopy )
133 colorsToCopy << mModel->
colors().at( row );
138 QApplication::clipboard()->setMimeData( mimeData );
144 const QString lastDir = s.
value( QStringLiteral(
"/UI/lastGplPaletteDir" ), QDir::homePath() ).toString();
145 const QString filePath = QFileDialog::getOpenFileName(
this, tr(
"Select Palette File" ), lastDir, QStringLiteral(
"GPL (*.gpl);;All files (*.*)" ) );
147 if ( filePath.isEmpty() )
153 const QFileInfo fileInfo( filePath );
154 if ( !fileInfo.exists() || !fileInfo.isReadable() )
156 QMessageBox::critical(
nullptr, tr(
"Import Colors" ), tr(
"Error, file does not exist or is not readable." ) );
160 s.
setValue( QStringLiteral(
"/UI/lastGplPaletteDir" ), fileInfo.absolutePath() );
161 QFile file( filePath );
165 QMessageBox::critical(
nullptr, tr(
"Import Colors" ), tr(
"Error, no colors found in palette file." ) );
173 const QString lastDir = s.
value( QStringLiteral(
"/UI/lastGplPaletteDir" ), QDir::homePath() ).toString();
174 QString fileName = QFileDialog::getSaveFileName(
this, tr(
"Palette file" ), lastDir, QStringLiteral(
"GPL (*.gpl)" ) );
176 if ( fileName.isEmpty() )
182 if ( !fileName.endsWith( QLatin1String(
".gpl" ), Qt::CaseInsensitive ) )
184 fileName += QLatin1String(
".gpl" );
187 const QFileInfo fileInfo( fileName );
188 s.
setValue( QStringLiteral(
"/UI/lastGplPaletteDir" ), fileInfo.absolutePath() );
190 QFile file( fileName );
194 QMessageBox::critical(
nullptr, tr(
"Export Colors" ), tr(
"Error writing palette file." ) );
202 if ( ( event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete ) )
205 const auto constSelectedIndexes = selectedIndexes();
206 for (
const QModelIndex &index : constSelectedIndexes )
211 QList<int> rowsToRemove = qgis::setToList( qgis::listToSet( rows ) );
214 std::sort( rowsToRemove.begin(), rowsToRemove.end(), std::greater<int>() );
215 const auto constRowsToRemove = rowsToRemove;
216 for (
const int row : constRowsToRemove )
218 mModel->removeRow( row );
223 QTreeView::keyPressEvent( event );
228 if ( event->button() == Qt::LeftButton )
231 mDragStartPosition =
event->pos();
233 QTreeView::mousePressEvent( event );
238 if ( ( event->button() == Qt::LeftButton ) &&
239 ( 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 )
691 if ( option.state & QStyle::State_Selected )
693 painter->setPen( QPen( Qt::NoPen ) );
694 if ( option.state & QStyle::State_Active )
696 painter->setBrush( QBrush( option.widget->palette().highlight() ) );
700 painter->setBrush( QBrush( option.widget->palette().color( QPalette::Inactive,
701 QPalette::Highlight ) ) );
703 painter->drawRect( option.rect );
706 const QColor color = index.model()->data( index, Qt::DisplayRole ).value<QColor>();
707 if ( !color.isValid() )
712 QRect rect = option.rect;
715 const int cornerSize =
iconSize / 6;
717 rect.setLeft( option.rect.center().x() -
iconSize / 2 );
720 rect.adjust( 0, 1, 0, 1 );
723 painter->setRenderHint( QPainter::Antialiasing );
724 painter->setPen( Qt::NoPen );
725 if ( color.alpha() < 255 )
728 const QBrush checkBrush = QBrush( transparentBackground() );
729 painter->setBrush( checkBrush );
730 painter->drawRoundedRect( rect, cornerSize, cornerSize );
734 painter->setBrush( color );
735 painter->drawRoundedRect( rect, cornerSize, cornerSize );
738 QPixmap QgsColorSwatchDelegate::transparentBackground()
const
740 static QPixmap sTranspBkgrd;
742 if ( sTranspBkgrd.isNull() )
759 if ( event->type() == QEvent::MouseButtonDblClick )
761 if ( !index.model()->flags( index ).testFlag( Qt::ItemIsEditable ) )
767 const QColor color = index.model()->data( index, Qt::DisplayRole ).value<QColor>();
770 if ( panel && panel->dockMode() )
775 colorWidget->setProperty(
"index", index );
777 panel->openPanel( colorWidget );
782 if ( !newColor.isValid() )
787 return model->setData( index, newColor, Qt::EditRole );
793 void QgsColorSwatchDelegate::colorChanged()
797 const QModelIndex index = colorWidget->property(
"index" ).toModelIndex();
798 const_cast< QAbstractItemModel *
>( index.model() )->setData( index, colorWidget->color(), Qt::EditRole );