18#include "ui_qgsstyleexportimportdialogbase.h" 
   31#include <QInputDialog> 
   35#include <QNetworkReply> 
   36#include <QProgressDialog> 
   38#include <QStandardItemModel> 
   39#include <QTemporaryFile> 
   51  QPushButton *pb = 
nullptr;
 
   52  pb = 
new QPushButton( tr( 
"Select All" ) );
 
   53  buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
 
   56  pb = 
new QPushButton( tr( 
"Clear Selection" ) );
 
   57  buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
 
   60  mTempStyle = std::make_unique< QgsStyle >();
 
   61  mTempStyle->createMemoryDatabase();
 
   64  mGroupSelectionDlg = 
nullptr;
 
   68  if ( mDialogMode == 
Import )
 
   70    setWindowTitle( tr( 
"Import Item(s)" ) );
 
   72    importTypeCombo->addItem( tr( 
"File" ), ImportSource::File );
 
   74    importTypeCombo->addItem( tr( 
"URL" ), ImportSource::Url );
 
   78    mSymbolTags->setText( QStringLiteral( 
"imported" ) );
 
   80    connect( mButtonFetch, &QAbstractButton::clicked, 
this, &QgsStyleExportImportDialog::fetch );
 
   83    mImportFileWidget->setDialogTitle( tr( 
"Load Styles" ) );
 
   84    mImportFileWidget->setFilter( tr( 
"XML files (*.xml *.XML)" ) );
 
   87    mImportFileWidget->setDefaultRoot( settings.
value( QStringLiteral( 
"StyleManager/lastImportDir" ), QDir::homePath(), 
QgsSettings::Gui ).toString() );
 
   90    label->setText( tr( 
"Select items to import" ) );
 
   91    buttonBox->button( QDialogButtonBox::Ok )->setText( tr( 
"Import" ) );
 
   93    dialogStyle = mTempStyle.get();
 
   97    setWindowTitle( tr( 
"Export Item(s)" ) );
 
   99    mLocationStackedEdit->setHidden( 
true );
 
  100    fromLabel->setHidden( 
true );
 
  101    importTypeCombo->setHidden( 
true );
 
  102    mLocationLabel->setHidden( 
true );
 
  104    mFavorite->setHidden( 
true );
 
  105    mIgnoreXMLTags->setHidden( 
true );
 
  107    pb = 
new QPushButton( tr( 
"Select by Group…" ) );
 
  108    buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
 
  110    tagLabel->setHidden( 
true );
 
  111    mSymbolTags->setHidden( 
true );
 
  112    tagHintLabel->setHidden( 
true );
 
  114    buttonBox->button( QDialogButtonBox::Ok )->setText( tr( 
"Export" ) );
 
  116    dialogStyle = mStyle;
 
  120  listItems->setIconSize( QSize( 
static_cast< int >( iconSize ), 
static_cast< int >( iconSize * 0.9 ) ) );  
 
  122  listItems->setGridSize( QSize( 
static_cast< int >( listItems->iconSize().width() * 1.4 ), 
static_cast< int >( listItems->iconSize().height() * 1.7 ) ) );
 
  123  listItems->setTextElideMode( Qt::TextElideMode::ElideRight );
 
  130  listItems->setModel( mModel );
 
  132  connect( listItems->selectionModel(), &QItemSelectionModel::selectionChanged,
 
  133           this, &QgsStyleExportImportDialog::selectionChanged );
 
  136  disconnect( buttonBox, &QDialogButtonBox::accepted, 
this, &QDialog::accept );
 
  138  buttonBox->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
  140  connect( buttonBox, &QDialogButtonBox::helpRequested, 
this, &QgsStyleExportImportDialog::showHelp );
 
 
  145  QModelIndexList selection = listItems->selectionModel()->selectedIndexes();
 
  146  if ( selection.isEmpty() )
 
  148    QMessageBox::warning( 
this, tr( 
"Export/import Item(s)" ),
 
  149                          tr( 
"You should select at least one symbol/color ramp." ) );
 
  153  if ( mDialogMode == 
Export )
 
  156    const QString lastUsedDir = settings.
value( QStringLiteral( 
"StyleManager/lastExportDir" ), QDir::homePath(), 
QgsSettings::Gui ).toString();
 
  157    QString fileName = QFileDialog::getSaveFileName( 
this, tr( 
"Save Styles" ), lastUsedDir,
 
  158                       tr( 
"XML files (*.xml *.XML)" ) );
 
  162    if ( fileName.isEmpty() )
 
  166    settings.
setValue( QStringLiteral( 
"StyleManager/lastExportDir" ), QFileInfo( fileName ).absolutePath(), 
QgsSettings::Gui );
 
  169    if ( !fileName.endsWith( QLatin1String( 
".xml" ), Qt::CaseInsensitive ) )
 
  171      fileName += QLatin1String( 
".xml" );
 
  174    mFileName = fileName;
 
  176    mCursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
 
  177    moveStyles( &selection, mStyle, mTempStyle.get() );
 
  178    if ( !mTempStyle->exportXml( mFileName ) )
 
  180      mCursorOverride.reset();
 
  181      QMessageBox::warning( 
this, tr( 
"Export Symbols" ),
 
  182                            tr( 
"Error when saving selected symbols to file:\n%1" )
 
  183                            .arg( mTempStyle->errorString() ) );
 
  188      mCursorOverride.reset();
 
  189      QMessageBox::information( 
this, tr( 
"Export Symbols" ),
 
  190                                tr( 
"The selected symbols were successfully exported to file:\n%1" )
 
  196    mCursorOverride = std::make_unique< QgsTemporaryCursorOverride >( Qt::WaitCursor );
 
  197    moveStyles( &selection, mTempStyle.get(), mStyle );
 
  200    mCursorOverride.reset();
 
 
  207bool QgsStyleExportImportDialog::populateStyles()
 
  214  if ( !mTempStyle->importXml( mFileName ) )
 
  217    QMessageBox::warning( 
this, tr( 
"Import Symbols or Color Ramps" ),
 
  218                          tr( 
"An error occurred during import:\n%1" ).arg( mTempStyle->errorString() ) );
 
  224void QgsStyleExportImportDialog::moveStyles( QModelIndexList *selection, 
QgsStyle *src, 
QgsStyle *dst )
 
  226  QList< QgsStyleManagerDialog::ItemDetails > items;
 
  227  items.reserve( selection->size() );
 
  228  for ( 
int i = 0; i < selection->size(); ++i )
 
  230    const QModelIndex index = selection->at( i );
 
  232    QgsStyleManagerDialog::ItemDetails details;
 
  236    details.name = mModel->data( mModel->index( index.row(), 
QgsStyleModel::Name, index.parent() ), Qt::DisplayRole ).toString();
 
  240  QgsStyleManagerDialog::copyItems( items, src, dst, 
this, mCursorOverride, mDialogMode == 
Import,
 
  241                                    mSymbolTags->text().split( 
',' ), mFavorite->isChecked(), mIgnoreXMLTags->isChecked() );
 
  247  delete mGroupSelectionDlg;
 
 
  252  mImportFileWidget->setFilePath( path );
 
 
  257  listItems->selectAll();
 
 
  262  listItems->clearSelection();
 
 
  267  for ( 
int row = 0; row < listItems->model()->rowCount(); ++row )
 
  269    const QModelIndex index = listItems->model()->index( row, 0 );
 
  272      listItems->selectionModel()->select( index, QItemSelectionModel::Select );
 
 
  279  for ( 
int row = 0; row < listItems->model()->rowCount(); ++row )
 
  281    const QModelIndex index = listItems->model()->index( row, 0 );
 
  284      const QItemSelection deselection( index, index );
 
  285      listItems->selectionModel()->select( deselection, QItemSelectionModel::Deselect );
 
 
  292  const auto constSymbolNames = symbolNames;
 
  293  for ( 
const QString &symbolName : constSymbolNames )
 
  295    const QModelIndexList indexes = listItems->model()->match( listItems->model()->index( 0, 
QgsStyleModel::Name ), Qt::DisplayRole, symbolName, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
 
  296    const auto constIndexes = indexes;
 
  297    for ( 
const QModelIndex &index : constIndexes )
 
  299      listItems->selectionModel()->select( index, QItemSelectionModel::Select );
 
 
  306  const auto constSymbolNames = symbolNames;
 
  307  for ( 
const QString &symbolName : constSymbolNames )
 
  309    const QModelIndexList indexes = listItems->model()->match( listItems->model()->index( 0, 
QgsStyleModel::Name ), Qt::DisplayRole, symbolName, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
 
  310    const auto constIndexes = indexes;
 
  311    for ( 
const QModelIndex &index : constIndexes )
 
  313      const QItemSelection deselection( index, index );
 
  314      listItems->selectionModel()->select( deselection, QItemSelectionModel::Deselect );
 
 
  321  for ( 
int row = 0; row < listItems->model()->rowCount(); ++row )
 
  323    const QModelIndex index = listItems->model()->index( row, 0 );
 
  326      listItems->selectionModel()->select( index, QItemSelectionModel::Select );
 
 
  333  for ( 
int row = 0; row < listItems->model()->rowCount(); ++row )
 
  335    const QModelIndex index = listItems->model()->index( row, 0 );
 
  338      const QItemSelection deselection( index, index );
 
  339      listItems->selectionModel()->select( deselection, QItemSelectionModel::Deselect );
 
 
  366  if ( ! mGroupSelectionDlg )
 
  369    mGroupSelectionDlg->setWindowTitle( tr( 
"Select Item(s) by Group" ) );
 
  379  mGroupSelectionDlg->show();
 
  380  mGroupSelectionDlg->raise();
 
  381  mGroupSelectionDlg->activateWindow();
 
 
  386  const ImportSource source = 
static_cast< ImportSource 
>( importTypeCombo->itemData( index ).toInt() );
 
  390    case ImportSource::File:
 
  392      mLocationStackedEdit->setCurrentIndex( 0 );
 
  393      mLocationLabel->setText( tr( 
"File" ) );
 
  397    case ImportSource::Official:
 
  399      btnBrowse->setText( QStringLiteral( 
"Fetch Items" ) );
 
  400      locationLineEdit->setEnabled( 
false );
 
  404    case ImportSource::Url:
 
  406      mLocationStackedEdit->setCurrentIndex( 1 );
 
  407      mLocationLabel->setText( tr( 
"URL" ) );
 
 
  413void QgsStyleExportImportDialog::fetch()
 
  415  downloadStyleXml( QUrl( mUrlLineEdit->text() ) );
 
  418void QgsStyleExportImportDialog::importFileChanged( 
const QString &path )
 
  420  if ( path.isEmpty() )
 
  424  const QFileInfo pathInfo( mFileName );
 
  425  const QString tag = pathInfo.fileName().remove( QStringLiteral( 
".xml" ) );
 
  426  mSymbolTags->setText( tag );
 
  427  if ( QFileInfo::exists( mFileName ) )
 
  431    mImportFileWidget->setDefaultRoot( pathInfo.absolutePath() );
 
  437void QgsStyleExportImportDialog::downloadStyleXml( 
const QUrl &url )
 
  439  mTempFile = 
new QTemporaryFile();
 
  440  if ( mTempFile->open() )
 
  442    mFileName = mTempFile->fileName();
 
  444    QProgressDialog *progressDlg = 
new QProgressDialog( 
this );
 
  445    progressDlg->setLabelText( tr( 
"Downloading style…" ) );
 
  446    progressDlg->setAutoClose( 
true );
 
  455      QNetworkReply *reply = fetcher->
reply();
 
  456      if ( !reply || reply->error() != QNetworkReply::NoError )
 
  461          QMessageBox::information( this, tr( 
"Import from URL" ),
 
  462                                    tr( 
"HTTP Error! Download failed: %1." ).arg( reply->errorString() ) );
 
  466        mTempFile->write( reply->readAll() );
 
  471      progressDlg->deleteLater();
 
  478void QgsStyleExportImportDialog::selectionChanged( 
const QItemSelection &selected, 
const QItemSelection &deselected )
 
  481  Q_UNUSED( deselected )
 
  482  const bool nothingSelected = listItems->selectionModel()->selectedIndexes().empty();
 
  483  buttonBox->button( QDialogButtonBox::Ok )->setDisabled( nothingSelected );
 
  486void QgsStyleExportImportDialog::showHelp()
 
  488  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.
 
Stores properties relating to a screen.
 
This class is a composition of two QSettings instances:
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
 
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
 
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
 
@ IsFavorite
Whether entity is flagged as a favorite.
 
@ SymbolType
Symbol type (for symbol or legend patch shape entities)
 
@ Type
Style entity type, see QgsStyle::StyleEntity.
 
@ Tag
String list of tags.
 
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.
 
void addTargetScreenProperties(const QgsScreenProperties &properties)
Adds additional target screen properties to use when generating icons for Qt::DecorationRole data.
 
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.
 
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.