Skip to content

Commit

Permalink
[FEATURE] Show QGIS style xml libraries in browser and support
Browse files Browse the repository at this point in the history
drag and drop of style .xml files to main QGIS window

Double clicking the databases or dragging them to QGIS
triggers the import from style dialog with the corresponding
input file already selected
  • Loading branch information
nyalldawson committed Nov 1, 2018
1 parent 620643e commit 187f741
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 5 deletions.
Expand Up @@ -17,15 +17,29 @@ class QgsStyleExportImportDialog : QDialog
#include "qgsstyleexportimportdialog.h"
%End
public:

enum Mode
{
Export,
Import
Import,
};

QgsStyleExportImportDialog( QgsStyle *style, QWidget *parent /TransferThis/ = 0, Mode mode = Export );
%Docstring
Constructor for QgsStyleExportImportDialog, with the specified ``parent`` widget.

Creates a dialog for importing symbols into the given ``style``, or exporting symbols from the ``style``.
The ``mode`` argument dictates whether the dialog is to be used for exporting or importing symbols.
%End
~QgsStyleExportImportDialog();

void setImportFilePath( const QString &path );
%Docstring
Sets the initial ``path`` to use for importing files, when the dialog is in a Import mode.

.. versionadded:: 3.6
%End

void selectSymbols( const QStringList &symbolNames );
%Docstring
selectSymbols select symbols by name
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -1149,6 +1149,9 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
registerCustomDropHandler( new QgsQlrDropHandler() );
QgsApplication::dataItemProviderRegistry()->addProvider( new QgsQptDataItemProvider() );
registerCustomDropHandler( new QgsQptDropHandler() );
QgsApplication::dataItemProviderRegistry()->addProvider( new QgsStyleXmlDataItemProvider() );
registerCustomDropHandler( new QgsStyleXmlDropHandler() );

mSplash->showMessage( tr( "Starting Python" ), Qt::AlignHCenter | Qt::AlignBottom );
qApp->processEvents();
loadPythonSupport();
Expand Down
127 changes: 127 additions & 0 deletions src/app/qgsappbrowserproviders.cpp
Expand Up @@ -15,6 +15,8 @@

#include "qgsappbrowserproviders.h"
#include "qgisapp.h"
#include "qgsstyleexportimportdialog.h"
#include "qgsstyle.h"
#include <QDesktopServices>

//
Expand Down Expand Up @@ -272,3 +274,128 @@ bool QgsPyDropHandler::handleFileDrop( const QString &file )
}
return false;
}




//
// QgsStyleXmlDataItem
//

QgsStyleXmlDataItem::QgsStyleXmlDataItem( QgsDataItem *parent, const QString &name, const QString &path )
: QgsDataItem( QgsDataItem::Custom, parent, name, path )
{
setState( QgsDataItem::Populated ); // no children
setIconName( QStringLiteral( "/mActionStyleManager.svg" ) );
setToolTip( QStringLiteral( "<b>%1</b><br>%2" ).arg( tr( "QGIS style library" ), QDir::toNativeSeparators( path ) ) );
}

bool QgsStyleXmlDataItem::hasDragEnabled() const
{
return true;
}

QgsMimeDataUtils::Uri QgsStyleXmlDataItem::mimeUri() const
{
QgsMimeDataUtils::Uri u;
u.layerType = QStringLiteral( "custom" );
u.providerKey = QStringLiteral( "style_xml" );
u.name = name();
u.uri = path();
return u;
}

bool QgsStyleXmlDataItem::handleDoubleClick()
{
QgsStyleExportImportDialog dlg( QgsStyle::defaultStyle(), QgisApp::instance(), QgsStyleExportImportDialog::Import );
dlg.setImportFilePath( mPath );
dlg.exec();

return true;
}

QList<QAction *> QgsStyleXmlDataItem::actions( QWidget *parent )
{
QAction *importAction = new QAction( tr( "&Import Style…" ), parent );
const QString path = mPath;
connect( importAction, &QAction::triggered, this, [path]
{
QgsStyleExportImportDialog dlg( QgsStyle::defaultStyle(), QgisApp::instance(), QgsStyleExportImportDialog::Import );
dlg.setImportFilePath( path );
dlg.exec();
} );
return QList<QAction *>() << importAction;
}

//
// QgsStyleXmlDataItemProvider
//


bool isStyleFile( const QString &path )
{
QFileInfo fileInfo( path );

if ( fileInfo.suffix().compare( QLatin1String( "xml" ), Qt::CaseInsensitive ) != 0 )
return false;

// sniff the first line of the file to see if it's a style file
if ( !QFile::exists( path ) )
return false;

QFile inputFile( path );
if ( !inputFile.open( QIODevice::ReadOnly ) )
return false;

QTextStream stream( &inputFile );
const QString line = stream.readLine();
return line == QLatin1String( "<!DOCTYPE qgis_style>" );
}

QString QgsStyleXmlDataItemProvider::name()
{
return QStringLiteral( "style_xml" );
}

int QgsStyleXmlDataItemProvider::capabilities()
{
return QgsDataProvider::File;
}

QgsDataItem *QgsStyleXmlDataItemProvider::createDataItem( const QString &path, QgsDataItem *parentItem )
{
if ( isStyleFile( path ) )
{
return new QgsStyleXmlDataItem( parentItem, QFileInfo( path ).fileName(), path );
}
return nullptr;
}

//
// QgsStyleXmlDropHandler
//

QString QgsStyleXmlDropHandler::customUriProviderKey() const
{
return QStringLiteral( "style_xml" );
}

void QgsStyleXmlDropHandler::handleCustomUriDrop( const QgsMimeDataUtils::Uri &uri ) const
{
QgsStyleExportImportDialog dlg( QgsStyle::defaultStyle(), QgisApp::instance(), QgsStyleExportImportDialog::Import );
dlg.setImportFilePath( uri.uri );
dlg.exec();
}

bool QgsStyleXmlDropHandler::handleFileDrop( const QString &file )
{
if ( isStyleFile( file ) )
{
QgsStyleExportImportDialog dlg( QgsStyle::defaultStyle(), QgisApp::instance(), QgsStyleExportImportDialog::Import );
dlg.setImportFilePath( file );
dlg.exec();
return true;
}
return false;
}

43 changes: 43 additions & 0 deletions src/app/qgsappbrowserproviders.h
Expand Up @@ -146,4 +146,47 @@ class QgsPyDropHandler : public QgsCustomDropHandler
bool handleFileDrop( const QString &file ) override;
};


/**
* Custom data item for XML style libraries.
*/
class QgsStyleXmlDataItem : public QgsDataItem
{
Q_OBJECT

public:

QgsStyleXmlDataItem( QgsDataItem *parent, const QString &name, const QString &path );
bool hasDragEnabled() const override;
QgsMimeDataUtils::Uri mimeUri() const override;
bool handleDoubleClick() override;
QList< QAction * > actions( QWidget *parent ) override;

};

/**
* Data item provider for showing style XML libraries in the browser.
*/
class QgsStyleXmlDataItemProvider : public QgsDataItemProvider
{
public:
QString name() override;
int capabilities() override;
QgsDataItem *createDataItem( const QString &path, QgsDataItem *parentItem ) override;
};

/**
* Handles drag and drop of style XML libraries to app.
*/
class QgsStyleXmlDropHandler : public QgsCustomDropHandler
{
Q_OBJECT

public:

QString customUriProviderKey() const override;
void handleCustomUriDrop( const QgsMimeDataUtils::Uri &uri ) const override;
bool handleFileDrop( const QString &file ) override;
};

#endif // QGSAPPBROWSERPROVIDERS_H
5 changes: 5 additions & 0 deletions src/gui/symbology/qgsstyleexportimportdialog.cpp
Expand Up @@ -370,6 +370,11 @@ QgsStyleExportImportDialog::~QgsStyleExportImportDialog()
delete mGroupSelectionDlg;
}

void QgsStyleExportImportDialog::setImportFilePath( const QString &path )
{
mImportFileWidget->setFilePath( path );
}

void QgsStyleExportImportDialog::selectAll()
{
listItems->selectAll();
Expand Down
21 changes: 17 additions & 4 deletions src/gui/symbology/qgsstyleexportimportdialog.h
Expand Up @@ -44,17 +44,30 @@ class GUI_EXPORT QgsStyleExportImportDialog : public QDialog, private Ui::QgsSty
Q_OBJECT

public:

//! Dialog modes
enum Mode
{
Export,
Import
Export, //!< Export existing symbols mode
Import, //!< Import xml file mode
};

// constructor
// mode argument must be 0 for saving and 1 for loading
/**
* Constructor for QgsStyleExportImportDialog, with the specified \a parent widget.
*
* Creates a dialog for importing symbols into the given \a style, or exporting symbols from the \a style.
* The \a mode argument dictates whether the dialog is to be used for exporting or importing symbols.
*/
QgsStyleExportImportDialog( QgsStyle *style, QWidget *parent SIP_TRANSFERTHIS = nullptr, Mode mode = Export );
~QgsStyleExportImportDialog() override;

/**
* Sets the initial \a path to use for importing files, when the dialog is in a Import mode.
*
* \since QGIS 3.6
*/
void setImportFilePath( const QString &path );

/**
* \brief selectSymbols select symbols by name
* \param symbolNames list of symbol names
Expand Down

0 comments on commit 187f741

Please sign in to comment.