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.