18 #include "ui_qgsstyleexportimportdialogbase.h" 28 #include <QInputDialog> 29 #include <QCloseEvent> 30 #include <QFileDialog> 31 #include <QMessageBox> 32 #include <QPushButton> 33 #include <QStandardItemModel> 44 QPushButton *pb =
nullptr;
45 pb =
new QPushButton( tr(
"Select all" ) );
46 buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
49 pb =
new QPushButton( tr(
"Clear selection" ) );
50 buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
53 QStandardItemModel *model =
new QStandardItemModel( listItems );
54 listItems->setModel( model );
55 connect( listItems->selectionModel(), &QItemSelectionModel::selectionChanged,
56 this, &QgsStyleExportImportDialog::selectionChanged );
59 mTempStyle->createMemoryDatabase();
62 mProgressDlg =
nullptr;
63 mGroupSelectionDlg =
nullptr;
65 mNetManager =
new QNetworkAccessManager(
this );
68 if ( mDialogMode ==
Import )
70 setWindowTitle( tr(
"Import Symbol(s)" ) );
72 importTypeCombo->addItem( tr(
"file specified below" ), QVariant(
"file" ) );
74 importTypeCombo->addItem( tr(
"URL specified below" ), QVariant(
"url" ) );
77 mSymbolTags->setText( QStringLiteral(
"imported" ) );
79 btnBrowse->setText( QStringLiteral(
"Browse" ) );
82 label->setText( tr(
"Select symbols to import" ) );
83 buttonBox->button( QDialogButtonBox::Ok )->setText( tr(
"Import" ) );
87 setWindowTitle( tr(
"Export Symbol(s)" ) );
89 btnBrowse->setHidden(
true );
90 fromLabel->setHidden(
true );
91 importTypeCombo->setHidden(
true );
92 locationLabel->setHidden(
true );
93 locationLineEdit->setHidden(
true );
95 mFavorite->setHidden(
true );
96 mIgnoreXMLTags->setHidden(
true );
98 pb =
new QPushButton( tr(
"Select by group" ) );
99 buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
101 tagLabel->setHidden(
true );
102 mSymbolTags->setHidden(
true );
103 tagHintLabel->setHidden(
true );
105 buttonBox->button( QDialogButtonBox::Ok )->setText( tr(
"Export" ) );
106 if ( !populateStyles( mStyle ) )
108 QApplication::postEvent(
this,
new QCloseEvent() );
113 disconnect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
115 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
117 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsStyleExportImportDialog::showHelp );
122 QModelIndexList selection = listItems->selectionModel()->selectedIndexes();
123 if ( selection.isEmpty() )
125 QMessageBox::warning(
this, tr(
"Export/import Symbols or Color Ramps" ),
126 tr(
"You should select at least one symbol/color ramp." ) );
130 if ( mDialogMode ==
Export )
132 QString fileName = QFileDialog::getSaveFileName(
this, tr(
"Save Styles" ), QDir::homePath(),
133 tr(
"XML files (*.xml *.XML)" ) );
134 if ( fileName.isEmpty() )
140 if ( !fileName.endsWith( QLatin1String(
".xml" ), Qt::CaseInsensitive ) )
142 fileName += QLatin1String(
".xml" );
145 mFileName = fileName;
148 moveStyles( &selection, mStyle, mTempStyle );
149 if ( !mTempStyle->
exportXml( mFileName ) )
152 QMessageBox::warning(
this, tr(
"Export Symbols" ),
153 tr(
"Error when saving selected symbols to file:\n%1" )
160 QMessageBox::information(
this, tr(
"Export Symbols" ),
161 tr(
"The selected symbols were successfully exported to file:\n%1" )
168 moveStyles( &selection, mTempStyle, mStyle );
171 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( listItems->model() );
180 bool QgsStyleExportImportDialog::populateStyles(
QgsStyle *style )
185 if ( mDialogMode ==
Import )
191 QMessageBox::warning(
this, tr(
"Import Symbols or Color Ramps" ),
192 tr(
"An error occurred during import:\n%1" ).arg( style->
errorString() ) );
197 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( listItems->model() );
204 for (
int i = 0; i < styleNames.count(); ++i )
206 name = styleNames[i];
209 QStandardItem *item =
new QStandardItem( name );
211 item->setIcon( icon );
212 item->setToolTip( QStringLiteral(
"<b>%1</b><br><i>%2</i>" ).arg( name, tags.count() > 0 ? tags.join( QStringLiteral(
", " ) ) : tr(
"Not tagged" ) ) );
214 QFont itemFont = item->font();
215 itemFont.setPointSize( 10 );
216 item->setFont( itemFont );
217 model->appendRow( item );
224 for (
int i = 0; i < styleNames.count(); ++i )
226 name = styleNames[i];
227 std::unique_ptr< QgsColorRamp > ramp( style->
colorRamp( name ) );
229 QStandardItem *item =
new QStandardItem( name );
231 item->setIcon( icon );
232 model->appendRow( item );
237 void QgsStyleExportImportDialog::moveStyles( QModelIndexList *selection,
QgsStyle *src,
QgsStyle *dst )
241 QStringList symbolTags;
245 bool isSymbol =
true;
247 bool overwrite =
true;
249 QStringList importTags = mSymbolTags->text().split(
',' );
254 for (
int i = 0; i < selection->size(); ++i )
256 index = selection->at( i );
257 symbolName = index.model()->data( index, 0 ).toString();
258 symbol = src->
symbol( symbolName );
260 if ( !mIgnoreXMLTags->isChecked() )
269 if ( mDialogMode ==
Import )
271 symbolTags << importTags;
272 symbolFavorite = mFavorite->isChecked();
276 symbolFavorite = !symbol ? favoriteColorramps.contains( symbolName ) : favoriteSymbols.contains( symbolName );
287 if ( dst->
symbolNames().contains( symbolName ) && prompt )
289 int res = QMessageBox::warning(
this, tr(
"Export/import Symbols" ),
290 tr(
"Symbol with name '%1' already exists.\nOverwrite?" )
292 QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
295 case QMessageBox::Cancel:
297 case QMessageBox::No:
299 case QMessageBox::Yes:
301 dst->
saveSymbol( symbolName, symbol, symbolFavorite, symbolTags );
303 case QMessageBox::YesToAll:
307 case QMessageBox::NoToAll:
314 if ( dst->
symbolNames().contains( symbolName ) && overwrite )
317 dst->
saveSymbol( symbolName, symbol, symbolFavorite, symbolTags );
319 else if ( dst->
symbolNames().contains( symbolName ) && !overwrite )
326 dst->
saveSymbol( symbolName, symbol, symbolFavorite, symbolTags );
333 int res = QMessageBox::warning(
this, tr(
"Export/import Color Ramps" ),
334 tr(
"Color ramp with name '%1' already exists.\nOverwrite?" )
336 QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel );
339 case QMessageBox::Cancel:
341 case QMessageBox::No:
343 case QMessageBox::Yes:
345 dst->
saveColorRamp( symbolName, ramp, symbolFavorite, symbolTags );
347 case QMessageBox::YesToAll:
351 case QMessageBox::NoToAll:
361 dst->
saveColorRamp( symbolName, ramp, symbolFavorite, symbolTags );
363 else if ( dst->
colorRampNames().contains( symbolName ) && !overwrite )
370 dst->
saveColorRamp( symbolName, ramp, symbolFavorite, symbolTags );
380 delete mGroupSelectionDlg;
385 listItems->selectAll();
390 listItems->clearSelection();
395 Q_FOREACH (
const QString &symbolName, symbolNames )
397 QModelIndexList indexes = listItems->model()->match( listItems->model()->index( 0, 0 ), Qt::DisplayRole, symbolName, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
398 Q_FOREACH (
const QModelIndex &index, indexes )
400 listItems->selectionModel()->select( index, QItemSelectionModel::Select );
407 Q_FOREACH (
const QString &symbolName, symbolNames )
409 QModelIndexList indexes = listItems->model()->match( listItems->model()->index( 0, 0 ), Qt::DisplayRole, symbolName, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
410 Q_FOREACH (
const QModelIndex &index, indexes )
412 QItemSelection deselection( index, index );
413 listItems->selectionModel()->select( deselection, QItemSelectionModel::Deselect );
448 if ( ! mGroupSelectionDlg )
451 mGroupSelectionDlg->setWindowTitle( tr(
"Select Symbols by Group" ) );
459 mGroupSelectionDlg->show();
460 mGroupSelectionDlg->raise();
461 mGroupSelectionDlg->activateWindow();
466 QString type = importTypeCombo->itemData( index ).toString();
468 locationLineEdit->clear();
470 if ( type == QLatin1String(
"file" ) )
472 locationLineEdit->setEnabled(
true );
473 btnBrowse->setText( QStringLiteral(
"Browse" ) );
475 else if ( type == QLatin1String(
"official" ) )
477 btnBrowse->setText( QStringLiteral(
"Fetch Symbols" ) );
478 locationLineEdit->setEnabled(
false );
482 btnBrowse->setText( QStringLiteral(
"Fetch Symbols" ) );
483 locationLineEdit->setEnabled(
true );
489 QString type = importTypeCombo->currentData().toString();
491 if ( type == QLatin1String(
"file" ) )
493 mFileName = QFileDialog::getOpenFileName(
this, tr(
"Load Styles" ), QDir::homePath(),
494 tr(
"XML files (*.xml *XML)" ) );
495 if ( mFileName.isEmpty() )
499 QFileInfo pathInfo( mFileName );
500 QString tag = pathInfo.fileName().remove( QStringLiteral(
".xml" ) );
501 mSymbolTags->setText( tag );
502 locationLineEdit->setText( mFileName );
503 populateStyles( mTempStyle );
505 else if ( type == QLatin1String(
"official" ) )
512 downloadStyleXml( QUrl( locationLineEdit->text() ) );
516 void QgsStyleExportImportDialog::downloadStyleXml(
const QUrl &url )
521 mTempFile =
new QTemporaryFile();
522 if ( mTempFile->open() )
524 mFileName = mTempFile->fileName();
528 QProgressDialog *dummy = mProgressDlg;
529 mProgressDlg =
nullptr;
532 mProgressDlg =
new QProgressDialog();
533 mProgressDlg->setLabelText( tr(
"Downloading style…" ) );
534 mProgressDlg->setAutoClose(
true );
536 connect( mProgressDlg, &QProgressDialog::canceled,
this, &QgsStyleExportImportDialog::downloadCanceled );
541 QNetworkReply *dummyReply = mNetReply;
545 mNetReply = mNetManager->get( QNetworkRequest( url ) );
547 connect( mNetReply, &QNetworkReply::finished,
this, &QgsStyleExportImportDialog::httpFinished );
548 connect( mNetReply, &QIODevice::readyRead,
this, &QgsStyleExportImportDialog::fileReadyRead );
549 connect( mNetReply, &QNetworkReply::downloadProgress,
this, &QgsStyleExportImportDialog::updateProgress );
553 void QgsStyleExportImportDialog::httpFinished()
555 if ( mNetReply->error() )
559 mProgressDlg->hide();
560 QMessageBox::information(
this, tr(
"Import from URL" ),
561 tr(
"HTTP Error! Download failed: %1." ).arg( mNetReply->errorString() ) );
568 populateStyles( mTempStyle );
572 void QgsStyleExportImportDialog::fileReadyRead()
574 mTempFile->write( mNetReply->readAll() );
577 void QgsStyleExportImportDialog::updateProgress( qint64 bytesRead, qint64 bytesTotal )
579 mProgressDlg->setMaximum( bytesTotal );
580 mProgressDlg->setValue( bytesRead );
583 void QgsStyleExportImportDialog::downloadCanceled()
590 void QgsStyleExportImportDialog::selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected )
592 Q_UNUSED( selected );
593 Q_UNUSED( deselected );
594 bool nothingSelected = listItems->selectionModel()->selectedIndexes().empty();
595 buttonBox->button( QDialogButtonBox::Ok )->setDisabled( nothingSelected );
598 void QgsStyleExportImportDialog::showHelp()
600 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
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
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 release()
Releases the cursor override early (i.e.
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)