QGIS API Documentation  3.23.0-Master (dd0cd13a00)
qgscptcitycolorrampdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscptcitycolorrampdialog.cpp
3  ---------------------
4  begin : July 2012
5  copyright : (C) 2012 by Etienne Tourigny
6  email : etourigny dot dev at gmail.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 
17 
18 #include "qgscptcityarchive.h"
19 #include "qgscolorramp.h"
20 #include "qgslogger.h"
21 #include "qgsapplication.h"
22 #include "qgsdialog.h"
23 #include "qgssymbollayerutils.h"
24 #include "qgssettings.h"
25 #include "qgsgui.h"
26 
27 #include <QPushButton>
28 #include <QTextEdit>
29 #include <QTime>
30 #include <QMessageBox>
31 #include <QSortFilterProxyModel>
32 
34 
35 // TODO
36 // - fix Diverging children when first show Selections
37 // - fix crash on Diverging?
38 
39 
41  : QDialog( parent )
42  , mRamp( ramp )
43  , mArchiveViewType( QgsCptCityBrowserModel::Selections )
44 {
45  setupUi( this );
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 );
54 
55  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
56 
57  const QgsSettings settings;
58  mSplitter->setSizes( QList<int>() << 250 << 550 );
59  mSplitter->restoreState( settings.value( QStringLiteral( "Windows/CptCityColorRampV2Dialog/splitter" ) ).toByteArray() );
60 
61  mModel = mAuthorsModel = mSelectionsModel = nullptr; //mListModel = 0;
62  mTreeFilter = nullptr;
63 
66 
67  // show information on how to install cpt-city files if none are found
68  if ( ! mArchive || mArchive->isEmpty() )
69  {
70  // QgsDialog dlg( this );
71  // dlg.setWindowTitle( tr( "Cpt-city Gradient Files Not Found" ) );
72  QTextEdit *edit = new QTextEdit( nullptr );
73  edit->setReadOnly( true );
74  // not sure if we want this long string to be translated
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 );
91  // dlg.layout()->addWidget( edit );
92  // dlg.resize(500,400);
93  // dlg.exec();
94  return;
95  }
96 
97  if ( ! mArchive )
98  return;
99  QgsDebugMsg( "archive: " + mArchive->archiveName() );
100 
101  QgsDebugMsg( QStringLiteral( "ramp name= %1 variant= %2 - %3 variants" ).arg( mRamp.schemeName(), mRamp.variantName() ).arg( mRamp.variantList().count() ) );
102 
103  // model / view
104  QgsDebugMsg( QStringLiteral( "loading model/view objects" ) );
105 
106  delete mAuthorsModel;
107  mAuthorsModel = new QgsCptCityBrowserModel( this, mArchive, QgsCptCityBrowserModel::Authors );
108 
109  delete mSelectionsModel;
110  mSelectionsModel = new QgsCptCityBrowserModel( this, mArchive, QgsCptCityBrowserModel::Selections );
111  setTreeModel( mSelectionsModel );
112 
113  mTreeView->setSelectionMode( QAbstractItemView::SingleSelection );
114  mTreeView->setColumnHidden( 1, true );
115  QgsDebugMsg( QStringLiteral( "done loading model/view objects" ) );
116 
117  // setup ui
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 ); // mouse click on preview label shows svg render
123 
124  updateUi();
125 
126  tabBar->blockSignals( false );
127 
128  connect( this, &QDialog::finished, this, &QgsCptCityColorRampDialog::onFinished );
129 
130 }
131 
133 {
134  mRamp = ramp;
135  updateUi();
136 }
137 
138 void QgsCptCityColorRampDialog::populateVariants()
139 {
140  const QStringList variantList = mRamp.variantList();
141 
142  QgsDebugMsg( QStringLiteral( "ramp %1%2 has %3 variants" ).arg( mRamp.schemeName(), mRamp.variantName() ).arg( variantList.count() ) );
143 
144  cboVariantName->blockSignals( true );
145  cboVariantName->clear();
146 
147  if ( variantList.isEmpty() )
148  {
149  cboVariantName->setEnabled( false );
150  cboVariantName->setVisible( false );
151  cboVariantName_currentIndexChanged( -1 );
152  }
153  else
154  {
155  // populate variant combobox
156  const QString oldVariant = cboVariantName->currentText();
157  QgsCptCityColorRamp ramp( mRamp.schemeName(), mRamp.variantList(), QString() );
158  QPixmap blankPixmap( cboVariantName->iconSize() );
159  blankPixmap.fill( Qt::white );
160  const QIcon blankIcon( blankPixmap );
161  int index;
162 
163  const auto constVariantList = variantList;
164  for ( const QString &variant : constVariantList )
165  {
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 );
172 
173  ramp.setVariantName( variant );
174  if ( ramp.loadFile() )
175  cboVariantName->setItemIcon( index,
176  QgsSymbolLayerUtils::colorRampPreviewIcon( &ramp, cboVariantName->iconSize() ) );
177  else
178  cboVariantName->setItemIcon( index, blankIcon );
179  cboVariantName->setItemData( index, Qt::AlignHCenter, Qt::TextAlignmentRole );
180  }
181 
182  cboVariantName->blockSignals( false );
183 
184  // try to set the original variant again (if exists)
185  int idx = -1;
186  QString newVariant = mRamp.variantName();
187  QgsDebugMsg( QStringLiteral( "variant= %1 - %2 variants" ).arg( mRamp.variantName() ).arg( mRamp.variantList().count() ) );
188  if ( newVariant != QString() )
189  {
190  if ( newVariant.startsWith( '-' ) || newVariant.startsWith( '_' ) )
191  newVariant.remove( 0, 1 );
192  newVariant = ' ' + newVariant;
193  idx = cboVariantName->findText( newVariant );
194  }
195  else
196  idx = cboVariantName->findText( oldVariant );
197 
198  // if not found use the item in the middle
199  if ( idx == -1 )
200  {
201  idx = cboVariantName->count() / 2;
202  }
203  cboVariantName->setCurrentIndex( idx );
204  // updatePreview();
205 
206  cboVariantName->setEnabled( true );
207  cboVariantName->setVisible( true );
208  }
209 
210 }
211 
212 void QgsCptCityColorRampDialog::mTreeView_clicked( const QModelIndex &index )
213 {
214  const QModelIndex &sourceIndex = mTreeFilter->mapToSource( index );
215  QgsCptCityDataItem *item = mModel->dataItem( sourceIndex );
216  if ( ! item )
217  return;
218  QgsDebugMsg( QStringLiteral( "item %1 clicked" ).arg( item->name() ) );
219  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
220  updateTreeView( item );
221 }
222 
223 void QgsCptCityColorRampDialog::updateTreeView( QgsCptCityDataItem *item, bool resetRamp )
224 {
225  if ( ! item )
226  {
227  QgsDebugMsg( QStringLiteral( "invalid item" ) );
228  return;
229  }
230  if ( item->type() == QgsCptCityDataItem::Directory )
231  {
232  if ( resetRamp )
233  {
234  mRamp.setName( QString(), QString() );
235  QgsDebugMsg( QStringLiteral( "variant= %1 - %2 variants" ).arg( mRamp.variantName() ).arg( mRamp.variantList().count() ) );
236  lblSchemeName->clear();
237  populateVariants();
238  }
239  updateListWidget( item );
240  lblSchemePath->setText( item->path() );
241  lblCollectionInfo->setText( QStringLiteral( "%1 (%2)" ).arg( item->info() ).arg( item->leafCount() ) );
242  updateCopyingInfo( mArchive->copyingInfo( mArchive->copyingFileName( item->path() ) ) );
243  }
244  else if ( item->type() == QgsCptCityDataItem::Selection )
245  {
246  lblSchemePath->clear();
247  clearCopyingInfo();
248  updateListWidget( item );
249  lblCollectionInfo->setText( QStringLiteral( "%1 (%2)" ).arg( item->info() ).arg( item->leafCount() ) );
250  }
251  else if ( item->type() == QgsCptCityDataItem::AllRamps )
252  {
253  lblSchemePath->clear();
254  clearCopyingInfo();
255  updateListWidget( item );
256  lblCollectionInfo->setText( tr( "All Ramps (%1)" ).arg( item->leafCount() ) );
257  }
258  else
259  {
260  QgsDebugMsg( QStringLiteral( "item %1 has invalid type %2" ).arg( item->path() ).arg( static_cast<int>( item->type() ) ) );
261  }
262 }
263 
264 void QgsCptCityColorRampDialog::mListWidget_itemClicked( QListWidgetItem *item )
265 {
266  QgsCptCityColorRampItem *rampItem = mListRamps.at( item->data( Qt::UserRole ).toInt() );
267  if ( rampItem )
268  {
269  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( true );
270  lblSchemeName->setText( QFileInfo( rampItem->name() ).fileName() );
271  mRamp.copy( &rampItem->ramp() );
272  QgsDebugMsg( QStringLiteral( "variant= %1 - %2 variants" ).arg( mRamp.variantName() ).arg( mRamp.variantList().count() ) );
273  populateVariants();
274  }
275  else
276  {
277  QgsDebugMsg( QStringLiteral( "invalid item" ) );
278  }
279 }
280 
281 void QgsCptCityColorRampDialog::mListWidget_itemSelectionChanged()
282 {
283  if ( mListWidget->selectedItems().isEmpty() )
284  {
285  mRamp.setName( QString(), QString() );
286  }
287 }
288 
289 void QgsCptCityColorRampDialog::tabBar_currentChanged( int index )
290 {
291  if ( index == 0 )
292  {
293  setTreeModel( mSelectionsModel );
294  mArchiveViewType = QgsCptCityBrowserModel::Selections;
295  }
296  else if ( index == 1 )
297  {
298  setTreeModel( mAuthorsModel );
299  mArchiveViewType = QgsCptCityBrowserModel::Authors;
300  }
301  else
302  {
303  QgsDebugMsg( QStringLiteral( "invalid index %1" ).arg( index ) );
304  setTreeModel( mAuthorsModel );
305  mArchiveViewType = QgsCptCityBrowserModel::Authors;
306  }
307 
308  mListWidget->blockSignals( true );
309  updateRamp();
310  mListWidget->blockSignals( false );
311 }
312 
313 
314 void QgsCptCityColorRampDialog::pbtnLicenseDetails_pressed()
315 {
316  QString path, title, copyFile, descFile;
317 
318  // get basic information, depending on if is color ramp or directory
319  QgsCptCityDataItem *item = mModel->dataItem( mTreeFilter->mapToSource( mTreeView->currentIndex() ) );
320  if ( ! item )
321  return;
322 
323  path = item->path();
324  if ( item->type() == QgsCptCityDataItem::Directory )
325  {
326  title = tr( "%1 Directory Details" ).arg( item->path() );
327  }
328  else if ( item->type() == QgsCptCityColorRampItem::Directory )
329  {
330  title = tr( "%1 Gradient Details" ).arg( path );
331  }
332  else
333  {
334  return;
335  }
336  copyFile = mArchive->copyingFileName( path );
337  descFile = mArchive->descFileName( path );
338 
339  // prepare dialog
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 );
346 
347  // add contents of DESC.xml and COPYING.xml
348  QString copyText;
349  if ( ! copyFile.isNull() )
350  {
351  QFile file( copyFile );
352  if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
353  {
354  copyText = QString( file.readAll() );
355  file.close();
356  }
357  }
358  QString descText;
359  if ( ! descFile.isNull() )
360  {
361  QFile file( descFile );
362  if ( file.open( QIODevice::ReadOnly | QIODevice::Text ) )
363  {
364  descText = QString( file.readAll() );
365  file.close();
366  }
367  }
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 );
379 
380  dlg.resize( 600, 600 );
381  dlg.exec();
382 }
383 
384 void QgsCptCityColorRampDialog::updatePreview( bool clear )
385 {
386  const QSize size = lblPreview->size();
387 
388  if ( clear || mRamp.schemeName().isEmpty() )
389  {
390  lblSchemeName->clear();
391  lblSchemePath->clear();
392  lblLicensePreview->clear();
393  QPixmap blankPixmap( size );
394  blankPixmap.fill( Qt::transparent );
395  lblPreview->setPixmap( blankPixmap );
396  return;
397  }
398 
399  mRamp.loadFile();
400 
401  lblSchemePath->setText( mRamp.schemeName() + mRamp.variantName() );
402 
403  // update pixmap
404  // TODO draw checker-board/transparent background
405  // for transparent, add [ pixmap.fill( Qt::transparent ); ] to QgsSymbolLayerUtils::colorRampPreviewPixmap
406  const QPixmap pixmap = QgsSymbolLayerUtils::colorRampPreviewPixmap( &mRamp, size );
407  lblPreview->setPixmap( pixmap );
408 
409  // add copyright information from COPYING.xml file
410  updateCopyingInfo( mRamp.copyingInfo() );
411 }
412 
413 void QgsCptCityColorRampDialog::clearCopyingInfo()
414 {
415  updateCopyingInfo( QMap< QString, QString >() );
416 }
417 
418 void QgsCptCityColorRampDialog::updateCopyingInfo( const QMap< QString, QString > &copyingMap )
419 {
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" ) ) + " ]";
431  else
432  licenseStr += '\n';
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" ) ) );
439  else
440  lblSrcLink->clear();
441 }
442 
443 void QgsCptCityColorRampDialog::cboVariantName_currentIndexChanged( int index )
444 {
445  Q_UNUSED( index )
446  if ( cboVariantName->currentIndex() != -1 )
447  mRamp.setVariantName( cboVariantName->currentData( Qt::UserRole ).toString() );
448  QgsDebugMsg( QStringLiteral( "variant= %1 - %2 variants" ).arg( mRamp.variantName() ).arg( mRamp.variantList().count() ) );
449  updatePreview();
450  emit changed();
451 }
452 
453 void QgsCptCityColorRampDialog::onFinished()
454 {
455  // save settings
456  QgsSettings settings;
457  settings.setValue( QStringLiteral( "Windows/CptCityColorRampV2Dialog/splitter" ), mSplitter->saveState() );
458 }
459 
460 void QgsCptCityColorRampDialog::showHelp()
461 {
462  // show error message to use color ramp manager to get more gradients
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"
466  );
467  QMessageBox *msg = new QMessageBox( this );
468  msg->setWindowTitle( tr( "Download More Cpt-city Gradients" ) );
469  msg->setText( helpText );
470  msg->exec();
471 }
472 
473 void QgsCptCityColorRampDialog::updateUi()
474 {
475  // look for item, if not found in selections archive, look for in authors
476  QgsDebugMsg( "looking for ramp " + mRamp.schemeName() );
477  if ( !mRamp.schemeName().isEmpty() )
478  {
479  bool found = updateRamp();
480  if ( ! found )
481  {
482  tabBar->setCurrentIndex( 1 );
483  setTreeModel( mAuthorsModel );
484  found = updateRamp();
485  // if not found, go back to selections model
486  if ( ! found )
487  {
488  tabBar->setCurrentIndex( 0 );
489  setTreeModel( mSelectionsModel );
490  }
491  }
492  if ( found )
493  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( true );
494  }
495  else
496  {
497  updateRamp();
498  }
499 }
500 
502 {
503  QgsDebugMsg( QStringLiteral( "result: %1 checked: %2" ).arg( result() ).arg( cboConvertStandard->isChecked() ) );
504  // if "save as standard gradient" is checked, convert to QgsVectorGradientColorRamp
505  return ( result() == Accepted && cboConvertStandard->isChecked() );
506 }
507 
508 QDialogButtonBox *QgsCptCityColorRampDialog::buttonBox() const
509 {
510  return mButtonBox;
511 }
512 
513 void QgsCptCityColorRampDialog::updateListWidget( QgsCptCityDataItem *item )
514 {
515  mListWidget->blockSignals( true );
516  mListWidget->clear();
517  mListRamps.clear();
518  QgsCptCityCollectionItem *colItem = qobject_cast<QgsCptCityCollectionItem *>( item );
519  if ( colItem )
520  {
521  QgsDebugMsg( "path= " + item->path() );
522  // recursively get children ramps
523  QVector<QgsCptCityDataItem *> childrenRamps = colItem->childrenRamps( true );
524  for ( int i = 0; i < childrenRamps.count(); i++ )
525  {
526  QgsCptCityColorRampItem *rampItem = qobject_cast<QgsCptCityColorRampItem *>( childrenRamps[i] );
527  if ( ! rampItem )
528  {
529  QgsDebugMsg( "invalid item " + childrenRamps[i]->path() );
530  continue;
531  }
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;
539  }
540  }
541  else
542  {
543  QgsDebugMsg( QStringLiteral( "invalid item" ) );
544  }
545  mListWidget->blockSignals( false );
546 }
547 
548 // this function is for a svg preview, available if the svg files have been processed with svgx
549 // e.g. for f in `ls */*/*/*/*.svg`; do echo $f ; svgx -p -t svg $f > tmp1.svg; mv tmp1.svg $f; done
550 // perhaps a future version of the cpt-city svg gradients will have them by default
551 bool QgsCptCityColorRampDialog::eventFilter( QObject *obj, QEvent *event )
552 {
553  const QSize size = lblPreview->size();
554 
555  if ( event->type() == QEvent::MouseButtonPress )
556  {
557  // create preview from svg file if supported - depends on file versions
558  const QPixmap pixmap( mRamp.fileName() );
559  if ( ! pixmap.isNull() )
560  lblPreview->setPixmap( pixmap.scaled( size ) );
561  return true;
562  }
563  else if ( event->type() == QEvent::MouseButtonRelease )
564  {
565  // restore preview
566  const QPixmap pixmap = QgsSymbolLayerUtils::colorRampPreviewPixmap( &mRamp, size );
567  lblPreview->setPixmap( pixmap );
568  return true;
569  }
570  else
571  {
572  // standard event processing
573  return QDialog::eventFilter( obj, event );
574  }
575 }
576 
577 bool QgsCptCityColorRampDialog::updateRamp()
578 {
579  mListWidget->clear();
580  mListRamps.clear();
581  cboVariantName->clear();
582  clearCopyingInfo();
583  lblCollectionInfo->clear();
584 
585  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
586  updatePreview( true );
587 
588  QgsDebugMsg( "schemeName= " + mRamp.schemeName() );
589  if ( mRamp.schemeName().isEmpty() )
590  {
591  showAll();
592  return false;
593  }
594 
595  // search for item in model
596  const QModelIndex modelIndex = mModel->findPath( mRamp.schemeName() );
597  if ( modelIndex == QModelIndex() )
598  {
599  return false;
600  }
601  QgsCptCityColorRampItem *childItem =
602  qobject_cast<QgsCptCityColorRampItem *>( mModel->dataItem( modelIndex ) );
603  if ( ! childItem )
604  return false;
605  if ( mRamp.schemeName() != childItem->ramp().schemeName() )
606  return false;
607 
608  // found child, set mRamp variantList
609  // mRamp.copy( &childItem->ramp() );
610  mRamp.setVariantList( childItem->ramp().variantList() );
611 
612  // found child, update tree
613  QgsDebugMsg( QStringLiteral( "found item %1" ).arg( mRamp.schemeName() ) );
614  lblSchemeName->setText( QFileInfo( mRamp.schemeName() ).fileName() );
615  const QModelIndex parentIndex = modelIndex.parent();
616  const QModelIndex selIndex = mTreeFilter->mapFromSource( parentIndex );
617 
618  // QgsDebugMsg(QString("parent row=%1 path=%2 parentRow=%3").arg(parentIndex.row()).arg(mModel->dataItem( parentIndex )->path()).arg(parentIndex.parent().row()));
619  mTreeView->setCurrentIndex( selIndex );
620  mTreeView->setExpanded( selIndex, true );
621  mTreeView->scrollTo( selIndex, QAbstractItemView::PositionAtCenter );
622  updateTreeView( mModel->dataItem( parentIndex ), false );
623 
624  // update listWidget, find appropriate item in mListRamps
625  for ( int i = 0; i < mListRamps.count(); i++ )
626  {
627  if ( mListRamps.at( i ) == childItem )
628  {
629  QgsDebugMsg( QStringLiteral( "found matching item %1 target=%2" ).arg( mListRamps.at( i )->path(), childItem->path() ) );
630  QListWidgetItem *listItem = mListWidget->item( i );
631  mListWidget->setCurrentItem( listItem );
632  // mListWidget_itemClicked( listItem );
633  populateVariants();
634  mListWidget->scrollToItem( listItem, QAbstractItemView::EnsureVisible );
635  // mListView->selectionModel()->select( childIndex, QItemSelectionModel::Select );
636  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( true );
637  emit changed();
638  return true;
639  }
640  }
641 
642  return false;
643 }
644 
645 void QgsCptCityColorRampDialog::showAll()
646 {
647  const QModelIndex modelIndex = mModel->findPath( QString() );
648  if ( modelIndex != QModelIndex() )
649  {
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 );
655  }
656 }
657 
658 void QgsCptCityColorRampDialog::setTreeModel( QgsCptCityBrowserModel *model )
659 {
660  mModel = model;
661 
662  delete mTreeFilter;
663  mTreeFilter = new TreeFilterProxyModel( this, mModel );
664  mTreeView->setModel( mTreeFilter );
665 }
666 
667 #if 0
668 void QgsCptCityColorRampDialog::refresh()
669 {
670  QApplication::setOverrideCursor( Qt::WaitCursor );
671  refreshModel( QModelIndex() );
672  QApplication::restoreOverrideCursor();
673 }
674 
675 void QgsCptCityColorRampDialog::refreshModel( const QModelIndex &index )
676 {
677  if ( index.isValid() )
678  {
679  QgsCptCityDataItem *item = mModel->dataItem( index );
680  if ( item )
681  {
682  QgsDebugMsg( "path = " + item->path() );
683  }
684  else
685  {
686  QgsDebugMsg( QStringLiteral( "invalid item" ) );
687  }
688  }
689 
690  mModel->refresh( index );
691 
692  for ( int i = 0; i < mModel->rowCount( index ); i++ )
693  {
694  QModelIndex idx = mModel->index( i, 0, index );
695  if ( mTreeView->isExpanded( idx ) || !mModel->hasChildren( idx ) )
696  {
697  refreshModel( idx );
698  }
699  }
700 }
701 #endif
702 
704 
705 TreeFilterProxyModel::TreeFilterProxyModel( QObject *parent, QgsCptCityBrowserModel *model )
706  : QSortFilterProxyModel( parent )
707  , mModel( model )
708 {
709  setSourceModel( mModel );
710 }
711 
712 bool TreeFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
713 {
714  QgsCptCityDataItem *item = mModel->dataItem( mModel->index( sourceRow, 0, sourceParent ) );
715  return ( item && !( item->type() == QgsCptCityDataItem::ColorRamp ) );
716 }
717 
718 
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
static void initDefaultArchive()
void refresh(const QString &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 a list of mime that can describe model indexes.
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
void setName(const QString &schemeName, const QString &variantName=QString(), const QStringList &variantList=QStringList())
QgsStringMap copyingInfo() const
void setVariantList(const QStringList &variantList)
QStringList variantList() const
QString fileName() 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
QString info() const
QString name() const
QString path() const
virtual int leafCount() const
A generic dialog with layout and button box.
Definition: qgsdialog.h:34
static QgsGui * instance()
Returns a pointer to the singleton instance.
Definition: qgsgui.cpp:67
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...
Definition: qgsgui.cpp:168
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 QgsDebugMsg(str)
Definition: qgslogger.h:38