Skip to content
Permalink
Browse files

[FEATURE] Show QGIS style xml libraries in browser and support

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 Oct 31, 2018
1 parent 620643e commit 187f74148c0340fa040e21f44efa140fee7857a5
@@ -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
@@ -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();
@@ -15,6 +15,8 @@

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

//
@@ -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;
}

@@ -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
@@ -370,6 +370,11 @@ QgsStyleExportImportDialog::~QgsStyleExportImportDialog()
delete mGroupSelectionDlg;
}

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

void QgsStyleExportImportDialog::selectAll()
{
listItems->selectAll();
@@ -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

0 comments on commit 187f741

Please sign in to comment.
You can’t perform that action at this time.