18 #include "ui_qgsstyleexportimportdialogbase.h"
29 #include "qgssettings.h"
34 #include <QInputDialog>
35 #include <QCloseEvent>
36 #include <QFileDialog>
37 #include <QMessageBox>
38 #include <QNetworkReply>
39 #include <QProgressDialog>
40 #include <QPushButton>
41 #include <QStandardItemModel>
42 #include <QTemporaryFile>
54 QPushButton *pb =
nullptr;
55 pb =
new QPushButton( tr(
"Select All" ) );
56 buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
59 pb =
new QPushButton( tr(
"Clear Selection" ) );
60 buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
63 mTempStyle = std::make_unique< QgsStyle >();
64 mTempStyle->createMemoryDatabase();
67 mGroupSelectionDlg =
nullptr;
71 if ( mDialogMode ==
Import )
73 setWindowTitle( tr(
"Import Item(s)" ) );
75 importTypeCombo->addItem( tr(
"File" ), ImportSource::File );
77 importTypeCombo->addItem( tr(
"URL" ), ImportSource::Url );
81 mSymbolTags->setText( QStringLiteral(
"imported" ) );
83 connect( mButtonFetch, &QAbstractButton::clicked,
this, &QgsStyleExportImportDialog::fetch );
86 mImportFileWidget->setDialogTitle( tr(
"Load Styles" ) );
87 mImportFileWidget->setFilter( tr(
"XML files (*.xml *.XML)" ) );
90 mImportFileWidget->setDefaultRoot( settings.value( QStringLiteral(
"StyleManager/lastImportDir" ), QDir::homePath(), QgsSettings::Gui ).toString() );
93 label->setText( tr(
"Select items to import" ) );
94 buttonBox->button( QDialogButtonBox::Ok )->setText( tr(
"Import" ) );
96 dialogStyle = mTempStyle.get();
100 setWindowTitle( tr(
"Export Item(s)" ) );
102 mLocationStackedEdit->setHidden(
true );
103 fromLabel->setHidden(
true );
104 importTypeCombo->setHidden(
true );
105 mLocationLabel->setHidden(
true );
107 mFavorite->setHidden(
true );
108 mIgnoreXMLTags->setHidden(
true );
110 pb =
new QPushButton( tr(
"Select by Group…" ) );
111 buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
113 tagLabel->setHidden(
true );
114 mSymbolTags->setHidden(
true );
115 tagHintLabel->setHidden(
true );
117 buttonBox->button( QDialogButtonBox::Ok )->setText( tr(
"Export" ) );
119 dialogStyle = mStyle;
123 listItems->setIconSize( QSize(
static_cast< int >(
iconSize ),
static_cast< int >(
iconSize * 0.9 ) ) );
129 listItems->setModel( mModel );
131 connect( listItems->selectionModel(), &QItemSelectionModel::selectionChanged,
132 this, &QgsStyleExportImportDialog::selectionChanged );
135 disconnect( buttonBox, &QDialogButtonBox::accepted,
this, &QDialog::accept );
137 buttonBox->button( QDialogButtonBox::Ok )->setEnabled(
false );
139 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsStyleExportImportDialog::showHelp );
144 QModelIndexList selection = listItems->selectionModel()->selectedIndexes();
145 if ( selection.isEmpty() )
147 QMessageBox::warning(
this, tr(
"Export/import Item(s)" ),
148 tr(
"You should select at least one symbol/color ramp." ) );
152 if ( mDialogMode ==
Export )
154 QString fileName = QFileDialog::getSaveFileName(
this, tr(
"Save Styles" ), QDir::homePath(),
155 tr(
"XML files (*.xml *.XML)" ) );
156 if ( fileName.isEmpty() )
162 if ( !fileName.endsWith( QLatin1String(
".xml" ), Qt::CaseInsensitive ) )
164 fileName += QLatin1String(
".xml" );
167 mFileName = fileName;
169 mCursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
170 moveStyles( &selection, mStyle, mTempStyle.get() );
171 if ( !mTempStyle->exportXml( mFileName ) )
173 mCursorOverride.reset();
174 QMessageBox::warning(
this, tr(
"Export Symbols" ),
175 tr(
"Error when saving selected symbols to file:\n%1" )
176 .arg( mTempStyle->errorString() ) );
181 mCursorOverride.reset();
182 QMessageBox::information(
this, tr(
"Export Symbols" ),
183 tr(
"The selected symbols were successfully exported to file:\n%1" )
189 mCursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
190 moveStyles( &selection, mTempStyle.get(), mStyle );
193 mCursorOverride.reset();
200 bool QgsStyleExportImportDialog::populateStyles()
207 if ( !mTempStyle->importXml( mFileName ) )
210 QMessageBox::warning(
this, tr(
"Import Symbols or Color Ramps" ),
211 tr(
"An error occurred during import:\n%1" ).arg( mTempStyle->errorString() ) );
217 void QgsStyleExportImportDialog::moveStyles( QModelIndexList *selection,
QgsStyle *src,
QgsStyle *dst )
219 QList< QgsStyleManagerDialog::ItemDetails > items;
220 items.reserve( selection->size() );
221 for (
int i = 0; i < selection->size(); ++i )
223 QModelIndex index = selection->at( i );
225 QgsStyleManagerDialog::ItemDetails details;
229 details.name = mModel->data( mModel->index( index.row(),
QgsStyleModel::Name, index.parent() ), Qt::DisplayRole ).toString();
233 QgsStyleManagerDialog::copyItems( items, src, dst,
this, mCursorOverride, mDialogMode ==
Import,
234 mSymbolTags->text().split(
',' ), mFavorite->isChecked(), mIgnoreXMLTags->isChecked() );
240 delete mGroupSelectionDlg;
245 mImportFileWidget->setFilePath( path );
250 listItems->selectAll();
255 listItems->clearSelection();
272 const auto constSymbolNames = symbolNames;
273 for (
const QString &symbolName : constSymbolNames )
275 QModelIndexList indexes = listItems->model()->match( listItems->model()->index( 0,
QgsStyleModel::Name ), Qt::DisplayRole, symbolName, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
276 const auto constIndexes = indexes;
277 for (
const QModelIndex &index : constIndexes )
279 listItems->selectionModel()->select( index, QItemSelectionModel::Select );
286 const auto constSymbolNames = symbolNames;
287 for (
const QString &symbolName : constSymbolNames )
289 QModelIndexList indexes = listItems->model()->match( listItems->model()->index( 0,
QgsStyleModel::Name ), Qt::DisplayRole, symbolName, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
290 const auto constIndexes = indexes;
291 for (
const QModelIndex &index : constIndexes )
293 QItemSelection deselection( index, index );
294 listItems->selectionModel()->select( deselection, QItemSelectionModel::Deselect );
333 if ( ! mGroupSelectionDlg )
336 mGroupSelectionDlg->setWindowTitle( tr(
"Select Item(s) by Group" ) );
346 mGroupSelectionDlg->show();
347 mGroupSelectionDlg->raise();
348 mGroupSelectionDlg->activateWindow();
353 ImportSource source =
static_cast< ImportSource
>( importTypeCombo->itemData( index ).toInt() );
357 case ImportSource::File:
359 mLocationStackedEdit->setCurrentIndex( 0 );
360 mLocationLabel->setText( tr(
"File" ) );
364 case ImportSource::Official:
366 btnBrowse->setText( QStringLiteral(
"Fetch Items" ) );
367 locationLineEdit->setEnabled(
false );
371 case ImportSource::Url:
373 mLocationStackedEdit->setCurrentIndex( 1 );
374 mLocationLabel->setText( tr(
"URL" ) );
380 void QgsStyleExportImportDialog::fetch()
382 downloadStyleXml( QUrl( mUrlLineEdit->text() ) );
385 void QgsStyleExportImportDialog::importFileChanged(
const QString &path )
387 if ( path.isEmpty() )
391 QFileInfo pathInfo( mFileName );
392 QString tag = pathInfo.fileName().remove( QStringLiteral(
".xml" ) );
393 mSymbolTags->setText( tag );
394 if ( QFileInfo::exists( mFileName ) )
398 mImportFileWidget->setDefaultRoot( pathInfo.absolutePath() );
399 QgsSettings settings;
400 settings.setValue( QStringLiteral(
"StyleManager/lastImportDir" ), pathInfo.absolutePath(), QgsSettings::Gui );
404 void QgsStyleExportImportDialog::downloadStyleXml(
const QUrl &url )
406 mTempFile =
new QTemporaryFile();
407 if ( mTempFile->open() )
409 mFileName = mTempFile->fileName();
411 QProgressDialog *progressDlg =
new QProgressDialog(
this );
412 progressDlg->setLabelText( tr(
"Downloading style…" ) );
413 progressDlg->setAutoClose(
true );
422 QNetworkReply *reply = fetcher->
reply();
423 if ( !reply || reply->error() != QNetworkReply::NoError )
428 QMessageBox::information( this, tr(
"Import from URL" ),
429 tr(
"HTTP Error! Download failed: %1." ).arg( reply->errorString() ) );
433 mTempFile->write( reply->readAll() );
438 progressDlg->deleteLater();
445 void QgsStyleExportImportDialog::selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected )
448 Q_UNUSED( deselected )
449 bool nothingSelected = listItems->selectionModel()->selectedIndexes().empty();
450 buttonBox->button( QDialogButtonBox::Ok )->setDisabled( nothingSelected );
453 void QgsStyleExportImportDialog::showHelp()
455 QgsHelp::openHelp( QStringLiteral(
"style_library/style_manager.html#sharing-style-items" ) );
static const double UI_SCALE_FACTOR
UI scaling factor.
static QgsTaskManager * taskManager()
Returns the application's task manager, used for managing application wide background task handling.
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...
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Handles HTTP network content fetching in a background task.
void fetched()
Emitted when the network content has been fetched, regardless of whether the fetch was successful or ...
QNetworkReply * reply()
Returns the network reply.
void cancel() override
Notifies the task that it should terminate.
void clearSelection()
clearSelection deselects all symbols
void selectTag(const QString &tagName)
Select the symbols belonging to the given tag.
@ Export
Export existing symbols mode.
@ Import
Import xml file mode.
void deselectSymbols(const QStringList &symbolNames)
deselectSymbols deselect symbols by name
void importTypeChanged(int)
void selectAll()
selectAll selects all symbols
void selectSymbols(const QStringList &symbolNames)
selectSymbols select symbols by name
void selectSmartgroup(const QString &groupName)
selectSmartgroup selects all symbols from a smart group
void selectByGroup()
selectByGroup open select by group dialog
void deselectFavorites()
Deselects favorite symbols.
void setImportFilePath(const QString &path)
Sets the initial path to use for importing files, when the dialog is in a Import mode.
void deselectSmartgroup(const QString &groupName)
deselectSmartgroup deselects all symbols from a smart group
QgsStyleExportImportDialog(QgsStyle *style, QWidget *parent=nullptr, Mode mode=Export)
Constructor for QgsStyleExportImportDialog, with the specified parent widget.
void selectFavorites()
Selects favorite symbols.
~QgsStyleExportImportDialog() override
void deselectTag(const QString &tagName)
Deselect the symbols belonging to the given tag.
void favoritesDeselected()
Favorites has been deselected.
void allDeselected()
all deselected
void tagSelected(const QString &tagName)
tag with tagName has been selected
void tagDeselected(const QString &tagName)
tag with tagName has been deselected
void smartgroupDeselected(const QString &groupName)
smart group with groupName has been deselected
void favoritesSelected()
Favorites has need selected.
void smartgroupSelected(const QString &groupName)
smartgroup with groupName has been selected
void allSelected()
all selected
@ TypeRole
Style entity type, see QgsStyle::StyleEntity.
@ SymbolTypeRole
Symbol type (for symbol or legend patch shape entities)
A QSortFilterProxyModel subclass for showing filtered symbol and color ramps entries from a QgsStyle ...
void addDesiredIconSize(QSize size)
Adds an additional icon size to generate for Qt::DecorationRole data.
QStringList symbolsWithTag(StyleEntity type, int tagid) const
Returns the symbol names with which have the given tag.
QStringList symbolsOfSmartgroup(StyleEntity type, int id)
Returns the symbols for the smartgroup.
StyleEntity
Enum for Entities involved in a style.
@ TextFormatEntity
Text formats.
@ ColorrampEntity
Color ramps.
int smartgroupId(const QString &smartgroup)
Returns the database id for the given smartgroup name.
int tagId(const QString &tag)
Returns the database id for the given tag name.
QStringList symbolsOfFavorite(StyleEntity type) const
Returns the symbol names which are flagged as favorite.
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
void progressChanged(double progress)
Will be emitted by task when its progress changes.
void setDescription(const QString &description)
Sets the task's description.
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.