Index: src/gui/symbology-ng/qgsstylev2managerdialog.cpp =================================================================== --- src/gui/symbology-ng/qgsstylev2managerdialog.cpp (revision 15231) +++ src/gui/symbology-ng/qgsstylev2managerdialog.cpp (working copy) @@ -10,8 +10,10 @@ #include "qgsvectorgradientcolorrampv2dialog.h" #include "qgsvectorrandomcolorrampv2dialog.h" #include "qgsvectorcolorbrewercolorrampv2dialog.h" +#include "qgsstylev2exportimportdialog.h" #include +#include #include #include @@ -42,6 +44,8 @@ connect( btnAddItem, SIGNAL( clicked() ), this, SLOT( addItem() ) ); connect( btnEditItem, SIGNAL( clicked() ), this, SLOT( editItem() ) ); connect( btnRemoveItem, SIGNAL( clicked() ), this, SLOT( removeItem() ) ); + connect( btnExportItems, SIGNAL( clicked() ), this, SLOT( exportItems() ) ); + connect( btnImportItems, SIGNAL( clicked() ), this, SLOT( importItems() ) ); QStandardItemModel* model = new QStandardItemModel( listItems ); listItems->setModel( model ); @@ -479,3 +483,23 @@ mModified = true; } } + +void QgsStyleV2ManagerDialog::exportItems() +{ + QgsStyleV2ExportImportDialog dlg( mStyle, this, QgsStyleV2ExportImportDialog::Export); + dlg.exec(); +} + +void QgsStyleV2ManagerDialog::importItems() +{ + QString fileName = QFileDialog::getOpenFileName( this, tr( "Load styles" ), ".", + tr( "XML files (*.xml *XML)" ) ); + if ( fileName.isEmpty() ) + { + return; + } + + QgsStyleV2ExportImportDialog dlg( mStyle, this, QgsStyleV2ExportImportDialog::Import, fileName ); + dlg.exec(); + populateList(); +} Index: src/gui/symbology-ng/qgsstylev2exportimportdialog.cpp =================================================================== --- src/gui/symbology-ng/qgsstylev2exportimportdialog.cpp (revision 0) +++ src/gui/symbology-ng/qgsstylev2exportimportdialog.cpp (revision 0) @@ -0,0 +1,286 @@ +/*************************************************************************** + qgsstylev2exportimportdialog.cpp + --------------------- + begin : Dec 2011 + copyright : (C) 2011 by Alexander Bruy + email : alexander dot bruy at gmail dot com + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +/* $Id: qgsstylev2exportimportdialog.cpp 13187 2010-03-28 22:14:44Z jef $ */ + +#include +#include +#include +#include +#include + +#include "qgsstylev2exportimportdialog.h" + +#include "qgsstylev2.h" +#include "qgssymbolv2.h" +#include "qgssymbollayerv2utils.h" +#include "qgsvectorcolorrampv2.h" + +QgsStyleV2ExportImportDialog::QgsStyleV2ExportImportDialog( QgsStyleV2* style, + QWidget *parent, Mode mode, QString fileName ) + : QDialog( parent ), mDialogMode( mode ), mQgisStyle( style ), mFileName( fileName ) +{ + setupUi( this ); + + // additional buttons + QPushButton *pb; + pb = new QPushButton( tr( "Select all" ) ); + buttonBox->addButton( pb, QDialogButtonBox::ActionRole ); + connect( pb, SIGNAL( clicked() ), this, SLOT( selectAll() ) ); + + pb = new QPushButton( tr( "Clear selection" ) ); + buttonBox->addButton( pb, QDialogButtonBox::ActionRole ); + connect( pb, SIGNAL( clicked() ), this, SLOT( clearSelection() ) ); + + QStandardItemModel* model = new QStandardItemModel( listItems ); + listItems->setModel( model ); + + mTempStyle = new QgsStyleV2(); + + if ( mDialogMode == Import ) + { + label->setText( tr( "Select symbols to import" ) ); + buttonBox->button( QDialogButtonBox::Ok )->setText( tr( "Import" ) ); + if ( !populateStyles( mTempStyle ) ) + { + QApplication::postEvent( this, new QCloseEvent() ); + } + } + else + { + buttonBox->button( QDialogButtonBox::Ok )->setText( tr( "Export" ) ); + if ( !populateStyles( mQgisStyle ) ) + { + QApplication::postEvent( this, new QCloseEvent() ); + } + } + + // use Ok button for starting import and export operations + disconnect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) ); + connect( buttonBox, SIGNAL( accepted() ), this, SLOT( doExportImport() ) ); +} + +void QgsStyleV2ExportImportDialog::doExportImport() +{ + QModelIndexList selection = listItems->selectionModel()->selectedIndexes(); + if ( selection.isEmpty() ) + { + QMessageBox::warning( this, tr( "Export/import error" ), + tr( "You should select at least one symbol/color ramp." ) ); + return; + } + + if ( mDialogMode == Export ) + { + QString fileName = QFileDialog::getSaveFileName( this, tr( "Save styles" ), ".", + tr( "XML files (*.xml *.XML)" ) ); + if ( fileName.isEmpty() ) + { + return; + } + + // ensure the user never ommited the extension from the file name + if ( !fileName.toLower().endsWith( ".xml" ) ) + { + fileName += ".xml"; + } + + mFileName = fileName; + + moveStyles( &selection, mQgisStyle, mTempStyle ); + if ( !mTempStyle->save( mFileName ) ) + { + QMessageBox::warning( this, tr( "Export/import error" ), + tr( "Error when saving selected symbols to file:\n%1" ) + .arg( mTempStyle->errorString() ) ); + return; + } + } + else // import + { + moveStyles( &selection, mTempStyle, mQgisStyle ); + mQgisStyle->save(); + + // clear model + QStandardItemModel* model = qobject_cast( listItems->model() ); + model->clear(); + accept(); + } + + mFileName = ""; + mTempStyle->clear(); + + return; +} + +bool QgsStyleV2ExportImportDialog::populateStyles( QgsStyleV2* style ) +{ + // load symbols and color ramps from file + if ( mDialogMode == Import ) + { + if ( !mTempStyle->load( mFileName ) ) + { + QMessageBox::warning( this, tr( "Import error" ), + tr( "An error was occured during import:\n%1" ).arg( mTempStyle->errorString() ) ); + return false; + } + } + + QStandardItemModel* model = qobject_cast( listItems->model() ); + model->clear(); + + // populate symbols + QStringList styleNames = style->symbolNames(); + QString name; + + for ( int i = 0; i < styleNames.count(); ++i ) + { + name = styleNames[i]; + QgsSymbolV2* symbol = style->symbol( name ); + QStandardItem* item = new QStandardItem( name ); + QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( symbol, listItems->iconSize() ); + item->setIcon( icon ); + model->appendRow( item ); + delete symbol; + } + + // and color ramps + styleNames = style->colorRampNames(); + + for ( int i = 0; i < styleNames.count(); ++i ) + { + name = styleNames[i]; + QgsVectorColorRampV2* ramp = style->colorRamp( name ); + + QStandardItem* item = new QStandardItem( name ); + QIcon icon = QgsSymbolLayerV2Utils::colorRampPreviewIcon( ramp, listItems->iconSize() ); + item->setIcon( icon ); + model->appendRow( item ); + delete ramp; + } + return true; +} + +void QgsStyleV2ExportImportDialog::moveStyles( QModelIndexList* selection, QgsStyleV2* src, QgsStyleV2* dst ) +{ + QString symbolName; + QgsSymbolV2* symbol; + QgsVectorColorRampV2* ramp; + QModelIndex index; + bool isSymbol = true; + bool prompt = true; + bool overwrite = true; + + for( int i = 0; i < selection->size(); ++i ) + { + index = selection->at( i ); + symbolName = index.model()->data( index, 0 ).toString(); + symbol = src->symbol( symbolName ); + if ( symbol == NULL ) + { + isSymbol = false; + ramp = src->colorRamp( symbolName ); + } + + if ( isSymbol ) + { + if ( dst->symbolNames().contains( symbolName ) && prompt ) + { + int res = QMessageBox::warning( this, tr( "Duplicate symbol names" ), + tr( "Symbol with name '%1' already exists.\nOverwrite?" ) + .arg( symbolName ), + QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel ); + switch ( res ) + { + case QMessageBox::Cancel: return; + case QMessageBox::No: continue; + case QMessageBox::Yes: dst->addSymbol( symbolName, symbol ); + continue; + case QMessageBox::YesToAll: prompt = false; + overwrite = true; + break; + case QMessageBox::NoToAll: prompt = false; + overwrite = false; + break; + } + } + + if ( dst->symbolNames().contains( symbolName ) && overwrite ) + { + dst->addSymbol( symbolName, symbol ); + } + else if ( dst->symbolNames().contains( symbolName ) && !overwrite ) + { + continue; + } + else + { + dst->addSymbol( symbolName, symbol ); + } + } + else + { + if ( dst->colorRampNames().contains( symbolName ) && prompt ) + { + int res = QMessageBox::warning( this, tr( "Duplicate symbol names" ), + tr( "Symbol with name '%1' already exists.\nOverwrite?" ) + .arg( symbolName ), + QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll | QMessageBox::Cancel ); + switch ( res ) + { + case QMessageBox::Cancel: return; + case QMessageBox::No: continue; + case QMessageBox::Yes: dst->addColorRamp( symbolName, ramp ); + continue; + case QMessageBox::YesToAll: prompt = false; + overwrite = true; + break; + case QMessageBox::NoToAll: prompt = false; + overwrite = false; + break; + } + } + + if ( dst->colorRampNames().contains( symbolName ) && overwrite ) + { + dst->addColorRamp( symbolName, ramp ); + } + else if ( dst->colorRampNames().contains( symbolName ) && !overwrite ) + { + continue; + } + else + { + dst->addColorRamp( symbolName, ramp ); + } + } + } +} + +QgsStyleV2ExportImportDialog::~QgsStyleV2ExportImportDialog() +{ + delete mTempStyle; +} + +void QgsStyleV2ExportImportDialog::selectAll() +{ + listItems->selectAll(); +} + +void QgsStyleV2ExportImportDialog::clearSelection() +{ + listItems->clearSelection(); +} Index: src/gui/symbology-ng/qgsstylev2managerdialog.h =================================================================== --- src/gui/symbology-ng/qgsstylev2managerdialog.h (revision 15231) +++ src/gui/symbology-ng/qgsstylev2managerdialog.h (working copy) @@ -24,6 +24,8 @@ void addItem(); void editItem(); void removeItem(); + void exportItems(); + void importItems(); //! adds symbols of some type to list void populateList(); Index: src/gui/symbology-ng/qgsstylev2exportimportdialog.h =================================================================== --- src/gui/symbology-ng/qgsstylev2exportimportdialog.h (revision 0) +++ src/gui/symbology-ng/qgsstylev2exportimportdialog.h (revision 0) @@ -0,0 +1,60 @@ +/*************************************************************************** + qgsstylev2exportimportdialog.h + --------------------- + begin : Dec 2011 + copyright : (C) 2011 by Alexander Bruy + email : alexander dot bruy at gmail dot com + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +/* $Id: qgsstylev2exportimportdialog.h 13187 2010-03-28 22:14:44Z jef $ */ + +#ifndef QGSSTYLEV2EXPORTIMPORTDIALOG_H +#define QGSSTYLEV2EXPORTIMPORTDIALOG_H + +#include + +#include "ui_qgsstylev2exportimportdialogbase.h" + +class QgsStyleV2; + +class QgsStyleV2ExportImportDialog : public QDialog, private Ui::QgsStyleV2ExportImportDialogBase +{ + Q_OBJECT + + public: + enum Mode + { + Export, + Import + }; + + // constructor + // mode argument must be 0 for saving and 1 for loading + QgsStyleV2ExportImportDialog( QgsStyleV2* style, QWidget *parent = NULL, Mode mode = Export, QString fileName = "" ); + ~QgsStyleV2ExportImportDialog(); + + public slots: + void doExportImport(); + void selectAll(); + void clearSelection(); + + private: + bool populateStyles( QgsStyleV2* style ); + void moveStyles( QModelIndexList* selection, QgsStyleV2* src, QgsStyleV2* dst ); + + QString mFileName; + Mode mDialogMode; + + QgsStyleV2* mQgisStyle; + QgsStyleV2* mTempStyle; +}; + +#endif // QGSSTYLEV2EXPORTIMPORTDIALOG_H Index: src/gui/CMakeLists.txt =================================================================== --- src/gui/CMakeLists.txt (revision 15231) +++ src/gui/CMakeLists.txt (working copy) @@ -20,6 +20,7 @@ symbology-ng/qgsvectorrandomcolorrampv2dialog.cpp symbology-ng/qgsvectorcolorbrewercolorrampv2dialog.cpp symbology-ng/characterwidget.cpp +symbology-ng/qgsstylev2exportimportdialog.cpp qgisgui.cpp qgisinterface.cpp @@ -79,6 +80,7 @@ symbology-ng/characterwidget.h symbology-ng/qgspenstylecombobox.h symbology-ng/qgsbrushstylecombobox.h +symbology-ng/qgsstylev2exportimportdialog.h qgsattributeeditor.h qgscomposerview.h Index: src/ui/qgsstylev2exportimportdialogbase.ui =================================================================== --- src/ui/qgsstylev2exportimportdialogbase.ui (revision 0) +++ src/ui/qgsstylev2exportimportdialogbase.ui (revision 0) @@ -0,0 +1,105 @@ + + + QgsStyleV2ExportImportDialogBase + + + + 0 + 0 + 400 + 300 + + + + Styles import/export + + + + + + Select symbols to export + + + + + + + + 0 + 3 + + + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + QAbstractItemView::ExtendedSelection + + + + 48 + 48 + + + + QListView::Static + + + QListView::Adjust + + + 5 + + + QListView::IconMode + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + QgsStyleV2ExportImportDialogBase + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + QgsStyleV2ExportImportDialogBase + reject() + + + 316 + 260 + + + 286 + 274 + + + + + Index: src/ui/qgsstylev2managerdialogbase.ui =================================================================== --- src/ui/qgsstylev2managerdialogbase.ui (revision 15231) +++ src/ui/qgsstylev2managerdialogbase.ui (working copy) @@ -169,6 +169,20 @@ + + + + Export + + + + + + + Import + + + @@ -187,7 +201,6 @@ listItems btnAddItem btnEditItem - btnRemoveItem buttonBox