31#include <QSortFilterProxyModel>
47 connect( mTreeView, &QTreeView::clicked,
this, &QgsCptCityColorRampDialog::mTreeView_clicked );
48 connect( mListWidget, &QListWidget::itemClicked,
this, &QgsCptCityColorRampDialog::mListWidget_itemClicked );
49 connect( mListWidget, &QListWidget::itemSelectionChanged,
this, &QgsCptCityColorRampDialog::mListWidget_itemSelectionChanged );
50 connect( tabBar, &QTabBar::currentChanged,
this, &QgsCptCityColorRampDialog::tabBar_currentChanged );
51 connect( pbtnLicenseDetails, &QToolButton::pressed,
this, &QgsCptCityColorRampDialog::pbtnLicenseDetails_pressed );
52 connect( cboVariantName,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsCptCityColorRampDialog::cboVariantName_currentIndexChanged );
53 connect( mButtonBox, &QDialogButtonBox::helpRequested,
this, &QgsCptCityColorRampDialog::showHelp );
55 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
58 mSplitter->setSizes( QList<int>() << 250 << 550 );
59 mSplitter->restoreState( settings.
value( QStringLiteral(
"Windows/CptCityColorRampV2Dialog/splitter" ) ).toByteArray() );
61 mModel = mAuthorsModel = mSelectionsModel =
nullptr;
62 mTreeFilter =
nullptr;
68 if ( ! mArchive || mArchive->
isEmpty() )
72 QTextEdit *edit =
new QTextEdit(
nullptr );
73 edit->setReadOnly(
true );
75 const QString helpText = tr(
"Error - cpt-city gradient files not found.\n\n"
76 "You have two means of installing them:\n\n"
77 "1) Install the \"Color Ramp Manager\" python plugin "
78 "(you must enable Experimental plugins in the plugin manager) "
79 "and use it to download latest cpt-city package.\n"
80 "You can install the entire cpt-city archive or a selection for QGIS.\n\n"
81 "2) Download the complete archive (in svg format) "
82 "and unzip it to your QGIS settings directory [%1] .\n\n"
83 "This file can be found at [%2]\nand current file is [%3]"
85 QStringLiteral(
"http://soliton.vm.bytemark.co.uk/pub/cpt-city/pkg/" ),
86 QStringLiteral(
"http://soliton.vm.bytemark.co.uk/pub/cpt-city/pkg/cpt-city-svg-2.07.zip" ) );
87 edit->setText( helpText );
88 mStackedWidget->addWidget( edit );
89 mStackedWidget->setCurrentIndex( 1 );
90 tabBar->setVisible(
false );
106 delete mAuthorsModel;
109 delete mSelectionsModel;
111 setTreeModel( mSelectionsModel );
113 mTreeView->setSelectionMode( QAbstractItemView::SingleSelection );
114 mTreeView->setColumnHidden( 1,
true );
118 tabBar->blockSignals(
true );
119 tabBar->addTab( tr(
"Selections by theme" ) );
120 tabBar->addTab( tr(
"All by author" ) );
121 cboVariantName->setIconSize( QSize( 100, 15 ) );
122 lblPreview->installEventFilter(
this );
126 tabBar->blockSignals(
false );
128 connect(
this, &QDialog::finished,
this, &QgsCptCityColorRampDialog::onFinished );
138void QgsCptCityColorRampDialog::populateVariants()
140 const QStringList variantList = mRamp.
variantList();
144 cboVariantName->blockSignals(
true );
145 cboVariantName->clear();
147 if ( variantList.isEmpty() )
149 cboVariantName->setEnabled(
false );
150 cboVariantName->setVisible(
false );
151 cboVariantName_currentIndexChanged( -1 );
156 const QString oldVariant = cboVariantName->currentText();
158 QPixmap blankPixmap( cboVariantName->iconSize() );
159 blankPixmap.fill( Qt::white );
160 const QIcon blankIcon( blankPixmap );
163 const auto constVariantList = variantList;
164 for (
const QString &variant : constVariantList )
166 QString variantStr = variant;
167 if ( variantStr.startsWith(
'-' ) || variantStr.startsWith(
'_' ) )
168 variantStr.remove( 0, 1 );
169 cboVariantName->addItem(
' ' + variantStr );
170 index = cboVariantName->count() - 1;
171 cboVariantName->setItemData( index, variant, Qt::UserRole );
175 cboVariantName->setItemIcon( index,
178 cboVariantName->setItemIcon( index, blankIcon );
179 cboVariantName->setItemData( index, Qt::AlignHCenter, Qt::TextAlignmentRole );
182 cboVariantName->blockSignals(
false );
188 if ( newVariant != QString() )
190 if ( newVariant.startsWith(
'-' ) || newVariant.startsWith(
'_' ) )
191 newVariant.remove( 0, 1 );
192 newVariant =
' ' + newVariant;
193 idx = cboVariantName->findText( newVariant );
196 idx = cboVariantName->findText( oldVariant );
201 idx = cboVariantName->count() / 2;
203 cboVariantName->setCurrentIndex( idx );
206 cboVariantName->setEnabled(
true );
207 cboVariantName->setVisible(
true );
212void QgsCptCityColorRampDialog::mTreeView_clicked(
const QModelIndex &index )
214 const QModelIndex &sourceIndex = mTreeFilter->mapToSource( index );
219 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
220 updateTreeView( item );
223void QgsCptCityColorRampDialog::updateTreeView(
QgsCptCityDataItem *item,
bool resetRamp )
234 mRamp.
setName( QString(), QString() );
236 lblSchemeName->clear();
239 updateListWidget( item );
240 lblSchemePath->setText( item->
path() );
241 lblCollectionInfo->setText( QStringLiteral(
"%1 (%2)" ).arg( item->
info() ).arg( item->
leafCount() ) );
246 lblSchemePath->clear();
248 updateListWidget( item );
249 lblCollectionInfo->setText( QStringLiteral(
"%1 (%2)" ).arg( item->
info() ).arg( item->
leafCount() ) );
253 lblSchemePath->clear();
255 updateListWidget( item );
256 lblCollectionInfo->setText( tr(
"All Ramps (%1)" ).arg( item->
leafCount() ) );
260 QgsDebugError( QStringLiteral(
"item %1 has invalid type %2" ).arg( item->
path() ).arg(
static_cast<int>( item->
type() ) ) );
264void QgsCptCityColorRampDialog::mListWidget_itemClicked( QListWidgetItem *item )
269 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled(
true );
270 lblSchemeName->setText( QFileInfo( rampItem->
name() ).fileName() );
281void QgsCptCityColorRampDialog::mListWidget_itemSelectionChanged()
283 if ( mListWidget->selectedItems().isEmpty() )
285 mRamp.
setName( QString(), QString() );
289void QgsCptCityColorRampDialog::tabBar_currentChanged(
int index )
293 setTreeModel( mSelectionsModel );
296 else if ( index == 1 )
298 setTreeModel( mAuthorsModel );
303 QgsDebugError( QStringLiteral(
"invalid index %1" ).arg( index ) );
304 setTreeModel( mAuthorsModel );
308 mListWidget->blockSignals(
true );
310 mListWidget->blockSignals(
false );
314void QgsCptCityColorRampDialog::pbtnLicenseDetails_pressed()
316 QString path, title, copyFile, descFile;
326 title = tr(
"%1 Directory Details" ).arg( item->
path() );
330 title = tr(
"%1 Gradient Details" ).arg( path );
340 QgsDialog dlg(
this, Qt::WindowFlags(), QDialogButtonBox::Close );
341 QVBoxLayout *layout = dlg.layout();
342 dlg.setWindowTitle( title );
343 QTextEdit *textEdit =
new QTextEdit( &dlg );
344 textEdit->setReadOnly(
true );
345 layout->addWidget( textEdit );
349 if ( ! copyFile.isNull() )
351 QFile file( copyFile );
352 if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
354 copyText = QString( file.readAll() );
359 if ( ! descFile.isNull() )
361 QFile file( descFile );
362 if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
364 descText = QString( file.readAll() );
368 textEdit->insertPlainText( title +
"\n\n" );
369 textEdit->insertPlainText( QStringLiteral(
"===================" ) );
370 textEdit->insertPlainText( QStringLiteral(
" copying " ) );
371 textEdit->insertPlainText( QStringLiteral(
"===================\n" ) );
372 textEdit->insertPlainText( copyText );
373 textEdit->insertPlainText( QStringLiteral(
"\n" ) );
374 textEdit->insertPlainText( QStringLiteral(
"==================" ) );
375 textEdit->insertPlainText( QStringLiteral(
" description " ) );
376 textEdit->insertPlainText( QStringLiteral(
"==================\n" ) );
377 textEdit->insertPlainText( descText );
378 textEdit->moveCursor( QTextCursor::Start );
380 dlg.resize( 600, 600 );
384void QgsCptCityColorRampDialog::updatePreview(
bool clear )
386 const QSize size = lblPreview->size();
390 lblSchemeName->clear();
391 lblSchemePath->clear();
392 lblLicensePreview->clear();
393 QPixmap blankPixmap( size );
394 blankPixmap.fill( Qt::transparent );
395 lblPreview->setPixmap( blankPixmap );
407 lblPreview->setPixmap( pixmap );
413void QgsCptCityColorRampDialog::clearCopyingInfo()
415 updateCopyingInfo( QMap< QString, QString >() );
418void QgsCptCityColorRampDialog::updateCopyingInfo(
const QMap< QString, QString > ©ingMap )
420 QString authorStr = copyingMap.value( QStringLiteral(
"authors" ) );
421 if ( authorStr.length() > 80 )
422 authorStr.replace( authorStr.indexOf(
' ', 80 ), 1, QStringLiteral(
"\n" ) );
423 lblAuthorName->setText( authorStr );
424 QString licenseStr = copyingMap.value( QStringLiteral(
"license/informal" ) );
425 if ( copyingMap.contains( QStringLiteral(
"license/year" ) ) )
426 licenseStr +=
" (" + copyingMap.value( QStringLiteral(
"license/year" ) ) +
')';
427 if ( licenseStr.length() > 80 )
428 licenseStr.replace( licenseStr.indexOf(
' ', 80 ), 1, QStringLiteral(
"\n" ) );
429 if ( copyingMap.contains( QStringLiteral(
"license/url" ) ) )
430 licenseStr +=
"\n[ " + copyingMap.value( QStringLiteral(
"license/url" ) ) +
" ]";
433 lblLicenseName->setText( licenseStr );
434 licenseStr.replace(
'\n', QLatin1String(
" " ) );
435 lblLicensePreview->setText( licenseStr );
436 lblLicensePreview->setCursorPosition( 0 );
437 if ( copyingMap.contains( QStringLiteral(
"src/link" ) ) )
438 lblSrcLink->setText( copyingMap.value( QStringLiteral(
"src/link" ) ) );
443void QgsCptCityColorRampDialog::cboVariantName_currentIndexChanged(
int index )
446 if ( cboVariantName->currentIndex() != -1 )
447 mRamp.
setVariantName( cboVariantName->currentData( Qt::UserRole ).toString() );
453void QgsCptCityColorRampDialog::onFinished()
457 settings.
setValue( QStringLiteral(
"Windows/CptCityColorRampV2Dialog/splitter" ), mSplitter->saveState() );
460void QgsCptCityColorRampDialog::showHelp()
463 const QString helpText = tr(
"You can download a more complete set of cpt-city gradients "
464 "by installing the \"Color Ramp Manager\" plugin "
465 "(you must enable Experimental plugins in the plugin manager).\n\n"
467 QMessageBox *msg =
new QMessageBox(
this );
468 msg->setWindowTitle( tr(
"Download More Cpt-city Gradients" ) );
469 msg->setText( helpText );
473void QgsCptCityColorRampDialog::updateUi()
479 bool found = updateRamp();
482 tabBar->setCurrentIndex( 1 );
483 setTreeModel( mAuthorsModel );
484 found = updateRamp();
488 tabBar->setCurrentIndex( 0 );
489 setTreeModel( mSelectionsModel );
493 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled(
true );
503 QgsDebugMsgLevel( QStringLiteral(
"result: %1 checked: %2" ).arg( result() ).arg( cboConvertStandard->isChecked() ), 2 );
505 return ( result() == Accepted && cboConvertStandard->isChecked() );
515 mListWidget->blockSignals(
true );
516 mListWidget->clear();
523 QVector<QgsCptCityDataItem *> childrenRamps = colItem->
childrenRamps(
true );
524 for (
int i = 0; i < childrenRamps.count(); i++ )
532 QListWidgetItem *listItem =
new QListWidgetItem();
533 listItem->setText( rampItem->
shortInfo() );
534 listItem->setIcon( rampItem->
icon( QSize( 75, 50 ) ) );
535 listItem->setToolTip( rampItem->
path() +
'\n' + rampItem->
info() );
536 listItem->setData( Qt::UserRole, QVariant( i ) );
537 mListWidget->addItem( listItem );
538 mListRamps << rampItem;
545 mListWidget->blockSignals(
false );
553 const QSize size = lblPreview->size();
555 if ( event->type() == QEvent::MouseButtonPress )
558 const QPixmap pixmap( mRamp.
fileName() );
559 if ( ! pixmap.isNull() )
560 lblPreview->setPixmap( pixmap.scaled( size ) );
563 else if ( event->type() == QEvent::MouseButtonRelease )
567 lblPreview->setPixmap( pixmap );
573 return QDialog::eventFilter( obj, event );
577bool QgsCptCityColorRampDialog::updateRamp()
579 mListWidget->clear();
581 cboVariantName->clear();
583 lblCollectionInfo->clear();
585 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
586 updatePreview(
true );
597 if ( modelIndex == QModelIndex() )
602 qobject_cast<QgsCptCityColorRampItem *>( mModel->
dataItem( modelIndex ) );
614 lblSchemeName->setText( QFileInfo( mRamp.
schemeName() ).fileName() );
615 const QModelIndex parentIndex = modelIndex.parent();
616 const QModelIndex selIndex = mTreeFilter->mapFromSource( parentIndex );
619 mTreeView->setCurrentIndex( selIndex );
620 mTreeView->setExpanded( selIndex,
true );
621 mTreeView->scrollTo( selIndex, QAbstractItemView::PositionAtCenter );
622 updateTreeView( mModel->
dataItem( parentIndex ),
false );
625 for (
int i = 0; i < mListRamps.count(); i++ )
627 if ( mListRamps.at( i ) == childItem )
629 QgsDebugMsgLevel( QStringLiteral(
"found matching item %1 target=%2" ).arg( mListRamps.at( i )->path(), childItem->
path() ), 2 );
630 QListWidgetItem *listItem = mListWidget->item( i );
631 mListWidget->setCurrentItem( listItem );
634 mListWidget->scrollToItem( listItem, QAbstractItemView::EnsureVisible );
636 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled(
true );
645void QgsCptCityColorRampDialog::showAll()
647 const QModelIndex modelIndex = mModel->
findPath( QString() );
648 if ( modelIndex != QModelIndex() )
650 const QModelIndex selIndex = mTreeFilter->mapFromSource( modelIndex );
651 mTreeView->setCurrentIndex( selIndex );
652 mTreeView->setExpanded( selIndex,
true );
653 mTreeView->scrollTo( selIndex, QAbstractItemView::PositionAtCenter );
654 updateTreeView( mModel->
dataItem( modelIndex ),
false );
663 mTreeFilter =
new TreeFilterProxyModel(
this, mModel );
664 mTreeView->setModel( mTreeFilter );
668void QgsCptCityColorRampDialog::refresh()
670 QApplication::setOverrideCursor( Qt::WaitCursor );
671 refreshModel( QModelIndex() );
672 QApplication::restoreOverrideCursor();
675void QgsCptCityColorRampDialog::refreshModel(
const QModelIndex &index )
677 if ( index.isValid() )
692 for (
int i = 0; i < mModel->
rowCount( index ); i++ )
694 QModelIndex idx = mModel->
index( i, 0, index );
695 if ( mTreeView->isExpanded( idx ) || !mModel->
hasChildren( idx ) )
706 : QSortFilterProxyModel( parent )
709 setSourceModel( mModel );
712bool TreeFilterProxyModel::filterAcceptsRow(
int sourceRow,
const QModelIndex &sourceParent )
const
714 QgsCptCityDataItem *item = mModel->dataItem( mModel->index( sourceRow, 0, sourceParent ) );
static QString qgisSettingsDirPath()
Returns the path to the settings directory in user's home dir.
QString descFileName(const QString &dirName) const
static QMap< QString, QString > copyingInfo(const QString &fileName)
QString archiveName() const
static QgsCptCityArchive * defaultArchive()
QString copyingFileName(const QString &dirName) const
bool isEmpty() const
Returns true if archive is empty.
static void initDefaultArchive()
A custom item model for display of CPT City color palettes.
void refresh(const QString &path)
Refresh the item specified by path.
QModelIndex findPath(const QString &path)
Returns index of a path.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QgsCptCityDataItem * dataItem(const QModelIndex &idx) const
Returns the data item corresponding to the given index.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
bool hasChildren(const QModelIndex &parent=QModelIndex()) const override
A Collection: logical collection of subcollections and color ramps.
QVector< QgsCptCityDataItem * > childrenRamps(bool recursive)
QgsCptCityColorRampDialog(const QgsCptCityColorRamp &ramp, QWidget *parent=nullptr)
Constructor for QgsCptCityColorRampDialog.
void setRamp(const QgsCptCityColorRamp &ramp)
Sets the color ramp to show in the dialog.
bool saveAsGradientRamp() const
Returns true if the ramp should be converted to a QgsGradientColorRamp.
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
bool eventFilter(QObject *obj, QEvent *event) override
void changed()
Emitted when the dialog settings change.
Item that represents a layer that can be opened with one of the providers.
const QgsCptCityColorRamp & ramp() const
A color ramp from the CPT City collection.
void setName(const QString &schemeName, const QString &variantName=QString(), const QStringList &variantList=QStringList())
QgsStringMap copyingInfo() const
void setVariantList(const QStringList &variantList)
QStringList variantList() const
void copy(const QgsCptCityColorRamp *other)
void setVariantName(const QString &variantName)
QString schemeName() const
QString variantName() const
Base class for all items in the model.
QString shortInfo() const
virtual int leafCount() const
Returns the total count of "leaf" items (all children which are end nodes).
A generic dialog with layout and button box.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
This class is a composition of two QSettings instances:
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 QIcon colorRampPreviewIcon(QgsColorRamp *ramp, QSize size, int padding=0)
Returns an icon preview for a color ramp.
static QPixmap colorRampPreviewPixmap(QgsColorRamp *ramp, QSize size, int padding=0, Qt::Orientation direction=Qt::Horizontal, bool flipDirection=false, bool drawTransparentBackground=true)
Returns a pixmap preview for a color ramp.
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)