Skip to content

Commit

Permalink
Merge pull request #3789 from nirvn/style_import_export_imp
Browse files Browse the repository at this point in the history
[style manager] imporve import and export experience, save symbols' tags & favorite flag
  • Loading branch information
nyalldawson committed Nov 21, 2016
2 parents eda412d + 2260780 commit ee71077
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 59 deletions.
3 changes: 3 additions & 0 deletions python/core/symbology-ng/qgsstyle.sip
Expand Up @@ -208,6 +208,9 @@ class QgsStyle : QObject
//! Changes ramp's name
bool renameColorRamp( const QString& oldName, const QString& newName );

//! Creates a temporary memory database
bool createMemoryDB();

//! Loads a file into the style
bool load( const QString& filename );

Expand Down
114 changes: 105 additions & 9 deletions src/core/symbology-ng/qgsstyle.cpp
Expand Up @@ -289,6 +289,42 @@ bool QgsStyle::openDB( const QString& filename )
return true;
}

bool QgsStyle::createMemoryDB()
{
mErrorString.clear();
if ( !openDB( QStringLiteral( ":memory:" ) ) )
{
mErrorString = QStringLiteral( "Unable to create temporary memory database" );
QgsDebugMsg( mErrorString );
return false;
}
char *query = sqlite3_mprintf( "CREATE TABLE symbol("\
"id INTEGER PRIMARY KEY,"\
"name TEXT UNIQUE,"\
"xml TEXT,"\
"favorite INTEGER);"\
"CREATE TABLE colorramp("\
"id INTEGER PRIMARY KEY,"\
"name TEXT UNIQUE,"\
"xml TEXT,"\
"favorite INTEGER);"\
"CREATE TABLE tag("\
"id INTEGER PRIMARY KEY,"\
"name TEXT);"\
"CREATE TABLE tagmap("\
"tag_id INTEGER NOT NULL,"\
"symbol_id INTEGER);"\
"CREATE TABLE ctagmap("\
"tag_id INTEGER NOT NULL,"\
"colorramp_id INTEGER);"\
"CREATE TABLE smartgroup("\
"id INTEGER PRIMARY KEY,"\
"name TEXT,"\
"xml TEXT);" );
runEmptyQuery( query );
return true;
}

bool QgsStyle::load( const QString& filename )
{
mErrorString.clear();
Expand Down Expand Up @@ -1391,14 +1427,42 @@ bool QgsStyle::exportXml( const QString& filename )
root.setAttribute( QStringLiteral( "version" ), STYLE_CURRENT_VERSION );
doc.appendChild( root );

// TODO work on the groups and tags
QStringList favoriteSymbols = symbolsOfFavorite( SymbolEntity );
QStringList favoriteColorramps = symbolsOfFavorite( ColorrampEntity );

// save symbols and attach tags
QDomElement symbolsElem = QgsSymbolLayerUtils::saveSymbols( mSymbols, QStringLiteral( "symbols" ), doc );
QDomElement rampsElem = doc.createElement( QStringLiteral( "colorramps" ) );
QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral( "symbol" ) );
int nbSymbols = symbolsList.count();
for ( int i = 0; i < nbSymbols; ++i )
{
QDomElement symbol = symbolsList.at( i ).toElement();
QString name = symbol.attribute( QStringLiteral( "name" ) );
QStringList tags = tagsOfSymbol( SymbolEntity, name );
if ( tags.count() > 0 )
{
symbol.setAttribute( QStringLiteral( "tags" ), tags.join( "," ) );
}
if ( favoriteSymbols.contains( name ) )
{
symbol.setAttribute( QStringLiteral( "favorite" ), "1" );
}
}

// save color ramps
QDomElement rampsElem = doc.createElement( QStringLiteral( "colorramps" ) );
for ( QMap<QString, QgsColorRamp*>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
{
QDomElement rampEl = QgsSymbolLayerUtils::saveColorRamp( itr.key(), itr.value(), doc );
QStringList tags = tagsOfSymbol( ColorrampEntity, itr.key() );
if ( tags.count() > 0 )
{
rampEl.setAttribute( QStringLiteral( "tags" ), tags.join( "," ) );
}
if ( favoriteColorramps.contains( itr.key() ) )
{
rampEl.setAttribute( QStringLiteral( "favorite" ), "1" );
}
rampsElem.appendChild( rampEl );
}

Expand Down Expand Up @@ -1469,10 +1533,26 @@ bool QgsStyle::importXml( const QString& filename )
{
if ( e.tagName() == QLatin1String( "symbol" ) )
{
QString name = e.attribute( QStringLiteral( "name" ) );
QStringList tags;
if ( e.hasAttribute( QStringLiteral( "tags" ) ) )
{
tags = e.attribute( QStringLiteral( "tags" ) ).split( "," );
}
bool favorite = false;
if ( e.hasAttribute( QStringLiteral( "favorite" ) ) && e.attribute( QStringLiteral( "favorite" ) ) == "1" )
{
favorite = true;
}

QgsSymbol* symbol = QgsSymbolLayerUtils::loadSymbol( e );
if ( symbol )
{
symbols.insert( e.attribute( QStringLiteral( "name" ) ), symbol );
addSymbol( name, symbol );
if ( mCurrentDB )
{
saveSymbol( name, symbol, favorite, tags );
}
}
}
else
Expand All @@ -1486,12 +1566,12 @@ bool QgsStyle::importXml( const QString& filename )
{
// for the old version, use the utility function to solve @symbol@layer subsymbols
symbols = QgsSymbolLayerUtils::loadSymbols( symbolsElement );
}

// save the symbols with proper name
for ( QMap<QString, QgsSymbol*>::iterator it = symbols.begin(); it != symbols.end(); ++it )
{
addSymbol( it.key(), it.value() );
// save the symbols with proper name
for ( QMap<QString, QgsSymbol*>::iterator it = symbols.begin(); it != symbols.end(); ++it )
{
addSymbol( it.key(), it.value() );
}
}

// load color ramps
Expand All @@ -1501,10 +1581,26 @@ bool QgsStyle::importXml( const QString& filename )
{
if ( e.tagName() == QLatin1String( "colorramp" ) )
{
QString name = e.attribute( QStringLiteral( "name" ) );
QStringList tags;
if ( e.hasAttribute( QStringLiteral( "tags" ) ) )
{
tags = e.attribute( QStringLiteral( "tags" ) ).split( "," );
}
bool favorite = false;
if ( e.hasAttribute( QStringLiteral( "favorite" ) ) && e.attribute( QStringLiteral( "favorite" ) ) == "1" )
{
favorite = true;
}

QgsColorRamp* ramp = QgsSymbolLayerUtils::loadColorRamp( e );
if ( ramp )
{
addColorRamp( e.attribute( QStringLiteral( "name" ) ), ramp );
addColorRamp( name, ramp );
if ( mCurrentDB )
{
saveColorRamp( name, ramp, favorite, tags );
}
}
}
else
Expand Down
14 changes: 13 additions & 1 deletion src/core/symbology-ng/qgsstyle.h
Expand Up @@ -273,7 +273,19 @@ class CORE_EXPORT QgsStyle : public QObject
//! Changes ramp's name
bool renameColorRamp( const QString& oldName, const QString& newName );

//! Loads a file into the style
/** Creates a temporary memory database
*
* This function is used if you do not need to associate styles with a permanent on-disk database.
* \return returns the success state of the temporary memory database creation
*/
bool createMemoryDB();

/** Loads a file into the style
*
* This function will populate styles from an on-disk database.
* \param filename location of the database to load styles from
* \return returns the success state of the database being loaded
*/
bool load( const QString& filename );

//! Saves style into a file (will use current filename if empty string is passed)
Expand Down
71 changes: 49 additions & 22 deletions src/gui/symbology-ng/qgsstyleexportimportdialog.cpp
Expand Up @@ -50,12 +50,13 @@ QgsStyleExportImportDialog::QgsStyleExportImportDialog( QgsStyle* style, QWidget
connect( pb, SIGNAL( clicked() ), this, SLOT( clearSelection() ) );

QStandardItemModel* model = new QStandardItemModel( listItems );

listItems->setModel( model );
connect( listItems->selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ),
this, SLOT( selectionChanged( const QItemSelection&, const QItemSelection& ) ) );

mTempStyle = new QgsStyle();
mTempStyle->createMemoryDB();

// TODO validate
mFileName = QLatin1String( "" );
mProgressDlg = nullptr;
Expand Down Expand Up @@ -92,6 +93,7 @@ QgsStyleExportImportDialog::QgsStyleExportImportDialog( QgsStyle* style, QWidget
locationLineEdit->setHidden( true );

mFavorite->setHidden( true );
mIgnoreXMLTags->setHidden( true );

pb = new QPushButton( tr( "Select by group" ) );
buttonBox->addButton( pb, QDialogButtonBox::ActionRole );
Expand Down Expand Up @@ -148,6 +150,12 @@ void QgsStyleExportImportDialog::doExportImport()
.arg( mTempStyle->errorString() ) );
return;
}
else
{
QMessageBox::information( this, tr( "Export successful" ),
tr( "The selected symbols were successfully exported to file:\n%1" )
.arg( mFileName ) );
}
}
else // import
{
Expand Down Expand Up @@ -187,10 +195,16 @@ bool QgsStyleExportImportDialog::populateStyles( QgsStyle* style )
for ( int i = 0; i < styleNames.count(); ++i )
{
name = styleNames[i];
QStringList tags = style->tagsOfSymbol( QgsStyle::SymbolEntity, name );
QgsSymbol* symbol = style->symbol( name );
QStandardItem* item = new QStandardItem( name );
QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( symbol, listItems->iconSize() );
QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( symbol, listItems->iconSize(), 15 );
item->setIcon( icon );
item->setToolTip( QString( "<b>%1</b><br><i>%2</i>" ).arg( name ).arg( tags.count() > 0 ? tags.join( ", " ) : tr( "Not tagged" ) ) );
// Set font to 10points to show reasonable text
QFont itemFont = item->font();
itemFont.setPointSize( 10 );
item->setFont( itemFont );
model->appendRow( item );
delete symbol;
}
Expand All @@ -204,7 +218,7 @@ bool QgsStyleExportImportDialog::populateStyles( QgsStyle* style )
QScopedPointer< QgsColorRamp > ramp( style->colorRamp( name ) );

QStandardItem* item = new QStandardItem( name );
QIcon icon = QgsSymbolLayerUtils::colorRampPreviewIcon( ramp.data(), listItems->iconSize() );
QIcon icon = QgsSymbolLayerUtils::colorRampPreviewIcon( ramp.data(), listItems->iconSize(), 15 );
item->setIcon( icon );
model->appendRow( item );
}
Expand All @@ -215,25 +229,44 @@ void QgsStyleExportImportDialog::moveStyles( QModelIndexList* selection, QgsStyl
{
QString symbolName;
QgsSymbol* symbol;
QStringList symbolTags;
bool symbolFavorite;
QgsColorRamp *ramp = nullptr;
QModelIndex index;
bool isSymbol = true;
bool prompt = true;
bool overwrite = true;
QStringList tags;

// get the groupid when going for import
if ( mDialogMode == Import )
{
// get the name the user entered
tags = mSymbolTags->text().split( ',' );
}
QStringList importTags = mSymbolTags->text().split( ',' );

QStringList favoriteSymbols = src->symbolsOfFavorite( QgsStyle::SymbolEntity );
QStringList favoriteColorramps = src->symbolsOfFavorite( QgsStyle::ColorrampEntity );

for ( int i = 0; i < selection->size(); ++i )
{
index = selection->at( i );
symbolName = index.model()->data( index, 0 ).toString();
symbol = src->symbol( symbolName );

if ( !mIgnoreXMLTags->isChecked() )
{
symbolTags = src->tagsOfSymbol( !symbol ? QgsStyle::ColorrampEntity : QgsStyle::SymbolEntity, symbolName );
}
else
{
symbolTags.clear();
}

if ( mDialogMode == Import )
{
symbolTags << importTags;
symbolFavorite = mFavorite->isChecked();
}
else
{
symbolFavorite = !symbol ? favoriteColorramps.contains( symbolName ) : favoriteSymbols.contains( symbolName );
}

if ( !symbol )
{
isSymbol = false;
Expand All @@ -256,8 +289,7 @@ void QgsStyleExportImportDialog::moveStyles( QModelIndexList* selection, QgsStyl
continue;
case QMessageBox::Yes:
dst->addSymbol( symbolName, symbol );
if ( mDialogMode == Import )
dst->saveSymbol( symbolName, symbol, mFavorite->isChecked(), tags );
dst->saveSymbol( symbolName, symbol, symbolFavorite, symbolTags );
continue;
case QMessageBox::YesToAll:
prompt = false;
Expand All @@ -273,8 +305,7 @@ void QgsStyleExportImportDialog::moveStyles( QModelIndexList* selection, QgsStyl
if ( dst->symbolNames().contains( symbolName ) && overwrite )
{
dst->addSymbol( symbolName, symbol );
if ( mDialogMode == Import )
dst->saveSymbol( symbolName, symbol, mFavorite->isChecked(), tags );
dst->saveSymbol( symbolName, symbol, symbolFavorite, symbolTags );
}
else if ( dst->symbolNames().contains( symbolName ) && !overwrite )
{
Expand All @@ -283,8 +314,7 @@ void QgsStyleExportImportDialog::moveStyles( QModelIndexList* selection, QgsStyl
else
{
dst->addSymbol( symbolName, symbol );
if ( mDialogMode == Import )
dst->saveSymbol( symbolName, symbol, mFavorite->isChecked(), tags );
dst->saveSymbol( symbolName, symbol, symbolFavorite, symbolTags );
}
}
else
Expand All @@ -303,8 +333,7 @@ void QgsStyleExportImportDialog::moveStyles( QModelIndexList* selection, QgsStyl
continue;
case QMessageBox::Yes:
dst->addColorRamp( symbolName, ramp );
if ( mDialogMode == Import )
dst->saveColorRamp( symbolName, ramp, mFavorite->isChecked(), tags );
dst->saveColorRamp( symbolName, ramp, symbolFavorite, symbolTags );
continue;
case QMessageBox::YesToAll:
prompt = false;
Expand All @@ -320,8 +349,7 @@ void QgsStyleExportImportDialog::moveStyles( QModelIndexList* selection, QgsStyl
if ( dst->colorRampNames().contains( symbolName ) && overwrite )
{
dst->addColorRamp( symbolName, ramp );
if ( mDialogMode == Import )
dst->saveColorRamp( symbolName, ramp, mFavorite->isChecked(), tags );
dst->saveColorRamp( symbolName, ramp, symbolFavorite, symbolTags );
}
else if ( dst->colorRampNames().contains( symbolName ) && !overwrite )
{
Expand All @@ -330,8 +358,7 @@ void QgsStyleExportImportDialog::moveStyles( QModelIndexList* selection, QgsStyl
else
{
dst->addColorRamp( symbolName, ramp );
if ( mDialogMode == Import )
dst->saveColorRamp( symbolName, ramp, mFavorite->isChecked() , tags );
dst->saveColorRamp( symbolName, ramp, symbolFavorite, symbolTags );
}
}
}
Expand Down

0 comments on commit ee71077

Please sign in to comment.