Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[style manager] imporve import and export experience, save symbols' tags & favorite flag #3789

Merged
merged 5 commits into from
Nov 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions python/core/symbology-ng/qgsstyle.sip
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading