18 #include "ui_qgsstyleexportimportdialogbase.h" 27 #include <QInputDialog> 28 #include <QCloseEvent> 29 #include <QFileDialog> 30 #include <QMessageBox> 31 #include <QPushButton> 32 #include <QStandardItemModel> 43 QPushButton *pb =
nullptr;
44 pb =
new QPushButton( tr(
"Select all" ) );
45 buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
48 pb =
new QPushButton( tr(
"Clear selection" ) );
49 buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
52 QStandardItemModel *model =
new QStandardItemModel( listItems );
53 listItems->setModel( model );
54 connect( listItems->selectionModel(), &QItemSelectionModel::selectionChanged,
55 this, &QgsStyleExportImportDialog::selectionChanged );
58 mTempStyle->createMemoryDatabase();
61 mProgressDlg =
nullptr;
62 mGroupSelectionDlg =
nullptr;
64 mNetManager =
new QNetworkAccessManager(
this );
67 if ( mDialogMode ==
Import )
69 setWindowTitle( tr(
"Import Symbol(s)" ) );
71 importTypeCombo->addItem( tr(
"file specified below" ), QVariant(
"file" ) );
73 importTypeCombo->addItem( tr(
"URL specified below" ), QVariant(
"url" ) );
76 mSymbolTags->setText( QStringLiteral(
"imported" ) );
78 btnBrowse->setText( QStringLiteral(
"Browse" ) );
81 label->setText( tr(
"Select symbols to import" ) );
82 buttonBox->button( QDialogButtonBox::Ok )->setText( tr(
"Import" ) );
86 setWindowTitle( tr(
"Export Symbol(s)" ) );
88 btnBrowse->setHidden(
true );
89 fromLabel->setHidden(
true );
90 importTypeCombo->setHidden(
true );
91 locationLabel->setHidden(
true );
92 locationLineEdit->setHidden(
true );
94 mFavorite->setHidden(
true );
95 mIgnoreXMLTags->setHidden(
true );
97 pb =
new QPushButton( tr(
"Select by group" ) );
98 buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
100 tagLabel->setHidden(
true );
101 mSymbolTags->setHidden(
true );
102 tagHintLabel->setHidden(
true );
104 buttonBox->button( QDialogButtonBox::Ok )->setText( tr(
"Export" ) );
105 if ( !populateStyles( mStyle ) )
107 QApplication::postEvent(
this,
new QCloseEvent() );
112 disconnect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
114 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
116 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsStyleExportImportDialog::showHelp );
121 QModelIndexList selection = listItems->selectionModel()->selectedIndexes();
122 if ( selection.isEmpty() )
124 QMessageBox::warning(
this, tr(
"Export/import Symbols or Color Ramps" ),
125 tr(
"You should select at least one symbol/color ramp." ) );
129 if ( mDialogMode ==
Export )
131 QString fileName = QFileDialog::getSaveFileName(
this, tr(
"Save Styles" ), QDir::homePath(),
132 tr(
"XML files (*.xml *.XML)" ) );
133 if ( fileName.isEmpty() )
139 if ( !fileName.endsWith( QLatin1String(
".xml" ), Qt::CaseInsensitive ) )
141 fileName += QLatin1String(
".xml" );
144 mFileName = fileName;
146 moveStyles( &selection, mStyle, mTempStyle );
147 if ( !mTempStyle->
exportXml( mFileName ) )
149 QMessageBox::warning(
this, tr(
"Export Symbols" ),
150 tr(
"Error when saving selected symbols to file:\n%1" )
156 QMessageBox::information(
this, tr(
"Export Symbols" ),
157 tr(
"The selected symbols were successfully exported to file:\n%1" )
163 moveStyles( &selection, mTempStyle, mStyle );
166 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( listItems->model() );
175 bool QgsStyleExportImportDialog::populateStyles(
QgsStyle *style )
178 if ( mDialogMode ==
Import )
183 QMessageBox::warning(
this, tr(
"Import Symbols or Color Ramps" ),
184 tr(
"An error occurred during import:\n%1" ).arg( style->
errorString() ) );
189 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( listItems->model() );
196 for (
int i = 0; i < styleNames.count(); ++i )
198 name = styleNames[i];
201 QStandardItem *item =
new QStandardItem( name );
203 item->setIcon( icon );
204 item->setToolTip( QStringLiteral(
"<b>%1</b><br><i>%2</i>" ).arg( name, tags.count() > 0 ? tags.join( QStringLiteral(
", " ) ) : tr(
"Not tagged" ) ) );
206 QFont itemFont = item->font();
207 itemFont.setPointSize( 10 );
208 item->setFont( itemFont );
209 model->appendRow( item );
216 for (
int i = 0; i < styleNames.count(); ++i )
218 name = styleNames[i];
219 std::unique_ptr< QgsColorRamp > ramp( style->
colorRamp( name ) );
221 QStandardItem *item =
new QStandardItem( name );
223 item->setIcon( icon );
224 model->appendRow( item );
229 void QgsStyleExportImportDialog::moveStyles( QModelIndexList *selection,
QgsStyle *src,
QgsStyle *dst )
233 QStringList symbolTags;
237 bool isSymbol =
true;
239 bool overwrite =
true;
241 QStringList importTags = mSymbolTags->text().split(
',' );
246 for (
int i = 0; i < selection->size(); ++i )
248 index = selection->at( i );
249 symbolName = index.model()->data( index, 0 ).toString();
250 symbol = src->
symbol( symbolName );
252 if ( !mIgnoreXMLTags->isChecked() )
261 if ( mDialogMode ==
Import )
263 symbolTags << importTags;
264 symbolFavorite = mFavorite->isChecked();
268 symbolFavorite = !symbol ? favoriteColorramps.contains( symbolName ) : favoriteSymbols.contains( symbolName );
279 if ( dst->
symbolNames().contains( symbolName ) && prompt )
281 int res = QMessageBox::warning(
this, tr(
"Export/import Symbols" ),
282 tr(
"Symbol with name '%1' already exists.\nOverwrite?" )
284 QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
287 case QMessageBox::Cancel:
289 case QMessageBox::No:
291 case QMessageBox::Yes:
293 dst->
saveSymbol( symbolName, symbol, symbolFavorite, symbolTags );
295 case QMessageBox::YesToAll:
299 case QMessageBox::NoToAll:
306 if ( dst->
symbolNames().contains( symbolName ) && overwrite )
309 dst->
saveSymbol( symbolName, symbol, symbolFavorite, symbolTags );
311 else if ( dst->
symbolNames().contains( symbolName ) && !overwrite )
318 dst->
saveSymbol( symbolName, symbol, symbolFavorite, symbolTags );
325 int res = QMessageBox::warning(
this, tr(
"Export/import Color Ramps" ),
326 tr(
"Color ramp with name '%1' already exists.\nOverwrite?" )
328 QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
331 case QMessageBox::Cancel:
333 case QMessageBox::No:
335 case QMessageBox::Yes:
337 dst->
saveColorRamp( symbolName, ramp, symbolFavorite, symbolTags );
339 case QMessageBox::YesToAll:
343 case QMessageBox::NoToAll:
353 dst->
saveColorRamp( symbolName, ramp, symbolFavorite, symbolTags );
355 else if ( dst->
colorRampNames().contains( symbolName ) && !overwrite )
362 dst->
saveColorRamp( symbolName, ramp, symbolFavorite, symbolTags );
372 delete mGroupSelectionDlg;
377 listItems->selectAll();
382 listItems->clearSelection();
387 Q_FOREACH (
const QString &symbolName, symbolNames )
389 QModelIndexList indexes = listItems->model()->match( listItems->model()->index( 0, 0 ), Qt::DisplayRole, symbolName, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
390 Q_FOREACH (
const QModelIndex &index, indexes )
392 listItems->selectionModel()->select( index, QItemSelectionModel::Select );
399 Q_FOREACH (
const QString &symbolName, symbolNames )
401 QModelIndexList indexes = listItems->model()->match( listItems->model()->index( 0, 0 ), Qt::DisplayRole, symbolName, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
402 Q_FOREACH (
const QModelIndex &index, indexes )
404 QItemSelection deselection( index, index );
405 listItems->selectionModel()->select( deselection, QItemSelectionModel::Deselect );
440 if ( ! mGroupSelectionDlg )
443 mGroupSelectionDlg->setWindowTitle( tr(
"Select Symbols by Group" ) );
451 mGroupSelectionDlg->show();
452 mGroupSelectionDlg->raise();
453 mGroupSelectionDlg->activateWindow();
458 QString type = importTypeCombo->itemData( index ).toString();
460 locationLineEdit->clear();
462 if ( type == QLatin1String(
"file" ) )
464 locationLineEdit->setEnabled(
true );
465 btnBrowse->setText( QStringLiteral(
"Browse" ) );
467 else if ( type == QLatin1String(
"official" ) )
469 btnBrowse->setText( QStringLiteral(
"Fetch Symbols" ) );
470 locationLineEdit->setEnabled(
false );
474 btnBrowse->setText( QStringLiteral(
"Fetch Symbols" ) );
475 locationLineEdit->setEnabled(
true );
481 QString type = importTypeCombo->currentData().toString();
483 if ( type == QLatin1String(
"file" ) )
485 mFileName = QFileDialog::getOpenFileName(
this, tr(
"Load Styles" ), QDir::homePath(),
486 tr(
"XML files (*.xml *XML)" ) );
487 if ( mFileName.isEmpty() )
491 QFileInfo pathInfo( mFileName );
492 QString tag = pathInfo.fileName().remove( QStringLiteral(
".xml" ) );
493 mSymbolTags->setText( tag );
494 locationLineEdit->setText( mFileName );
495 populateStyles( mTempStyle );
497 else if ( type == QLatin1String(
"official" ) )
504 downloadStyleXml( QUrl( locationLineEdit->text() ) );
508 void QgsStyleExportImportDialog::downloadStyleXml(
const QUrl &url )
513 mTempFile =
new QTemporaryFile();
514 if ( mTempFile->open() )
516 mFileName = mTempFile->fileName();
520 QProgressDialog *dummy = mProgressDlg;
521 mProgressDlg =
nullptr;
524 mProgressDlg =
new QProgressDialog();
525 mProgressDlg->setLabelText( tr(
"Downloading style…" ) );
526 mProgressDlg->setAutoClose(
true );
528 connect( mProgressDlg, &QProgressDialog::canceled,
this, &QgsStyleExportImportDialog::downloadCanceled );
533 QNetworkReply *dummyReply = mNetReply;
537 mNetReply = mNetManager->get( QNetworkRequest( url ) );
539 connect( mNetReply, &QNetworkReply::finished,
this, &QgsStyleExportImportDialog::httpFinished );
540 connect( mNetReply, &QIODevice::readyRead,
this, &QgsStyleExportImportDialog::fileReadyRead );
541 connect( mNetReply, &QNetworkReply::downloadProgress,
this, &QgsStyleExportImportDialog::updateProgress );
545 void QgsStyleExportImportDialog::httpFinished()
547 if ( mNetReply->error() )
551 mProgressDlg->hide();
552 QMessageBox::information(
this, tr(
"Import from URL" ),
553 tr(
"HTTP Error! Download failed: %1." ).arg( mNetReply->errorString() ) );
560 populateStyles( mTempStyle );
564 void QgsStyleExportImportDialog::fileReadyRead()
566 mTempFile->write( mNetReply->readAll() );
569 void QgsStyleExportImportDialog::updateProgress( qint64 bytesRead, qint64 bytesTotal )
571 mProgressDlg->setMaximum( bytesTotal );
572 mProgressDlg->setValue( bytesRead );
575 void QgsStyleExportImportDialog::downloadCanceled()
582 void QgsStyleExportImportDialog::selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected )
584 Q_UNUSED( selected );
585 Q_UNUSED( deselected );
586 bool nothingSelected = listItems->selectionModel()->selectedIndexes().empty();
587 buttonBox->button( QDialogButtonBox::Ok )->setDisabled( nothingSelected );
590 void QgsStyleExportImportDialog::showHelp()
592 QgsHelp::openHelp( QStringLiteral(
"working_with_vector/style_library.html#share-symbols" ) );
bool exportXml(const QString &filename)
Exports the style as a XML file.
void clear()
Removes all contents of the style.
void selectByGroup()
selectByGroup open select by group dialog
void deselectSmartgroup(const QString &groupName)
deselectSmartgroup deselects all symbols from a smart group
bool addColorRamp(const QString &name, QgsColorRamp *colorRamp, bool update=false)
Adds a color ramp to the style.
QgsStyleExportImportDialog(QgsStyle *style, QWidget *parent=nullptr, Mode mode=Export)
QStringList symbolsWithTag(StyleEntity type, int tagid) const
Returns the symbol names with which have the given tag.
QStringList tagsOfSymbol(StyleEntity type, const QString &symbol)
Returns the tags associated with the symbol.
~QgsStyleExportImportDialog() override
Abstract base class for color ramps.
bool saveColorRamp(const QString &name, QgsColorRamp *ramp, bool favorite, const QStringList &tags)
Adds the colorramp to the DB.
void tagSelected(const QString &tagName)
tag with tagName has been selected
void clearSelection()
clearSelection deselects all symbols
void smartgroupSelected(const QString &groupName)
smartgroup with groupName has been selected
QgsColorRamp * colorRamp(const QString &name) const
Returns a new copy of the specified color ramp.
void selectSmartgroup(const QString &groupName)
selectSmartgroup selects all symbols from a smart group
void allDeselected()
all deselected
static QIcon symbolPreviewIcon(QgsSymbol *symbol, QSize size, int padding=0)
Returns an icon preview for a color ramp.
bool importXml(const QString &filename)
Imports the symbols and colorramps into the default style database from the given XML file...
void deselectSymbols(const QStringList &symbolNames)
deselectSymbols deselect symbols by name
QStringList symbolNames()
Returns a list of names of symbols.
static QIcon colorRampPreviewIcon(QgsColorRamp *ramp, QSize size, int padding=0)
Returns an icon preview for a color ramp.
void allSelected()
all selected
QStringList colorRampNames()
Returns a list of names of color ramps.
QStringList symbolsOfSmartgroup(StyleEntity type, int id)
Returns the symbols for the smartgroup.
int smartgroupId(const QString &smartgroup)
Returns the DB id for the given smartgroup name.
int tagId(const QString &tag)
Returns the DB id for the given tag name.
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
void selectTag(const QString &tagName)
Select the symbols belonging to the given tag.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
void selectSymbols(const QStringList &symbolNames)
selectSymbols select symbols by name
void deselectTag(const QString &tagName)
Deselect the symbols belonging to the given tag.
QString errorString()
Returns last error from load/save operation.
void selectAll()
selectAll selects all symbols
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
void smartgroupDeselected(const QString &groupName)
smart group with groupName has been deselected
bool saveSymbol(const QString &name, QgsSymbol *symbol, bool favorite, const QStringList &tags)
Adds the symbol to the DB with the tags.
QStringList symbolsOfFavorite(StyleEntity type) const
Returns the symbol names which are flagged as favorite.
void tagDeselected(const QString &tagName)
tag with tagName has been deselected
void importTypeChanged(int)