From 4db68570c0d9ef91854e4b9580c41932cd970a76 Mon Sep 17 00:00:00 2001
From: Arunmozhi <aruntheguy@gmail.com>
Date: Wed, 22 Aug 2012 12:16:18 +0530
Subject: [PATCH 1/2] added documentation to the QgsStyleV2 functions

---
 src/core/symbology-ng/qgsstylev2.h |  197 ++++++++++++++++++++++++++++--------
 1 file changed, 153 insertions(+), 44 deletions(-)

diff --git a/src/core/symbology-ng/qgsstylev2.h b/src/core/symbology-ng/qgsstylev2.h
index be68666..5bec2d1 100644
--- a/src/core/symbology-ng/qgsstylev2.h
+++ b/src/core/symbology-ng/qgsstylev2.h
@@ -33,6 +33,26 @@ class QDomElement;
 
 typedef QMap<QString, QgsVectorColorRampV2* > QgsVectorColorRampV2Map;
 typedef QMap<int, QString> QgsSymbolGroupMap;
+
+/*!
+ *  A multimap to hold the smart group conditions as constraint and parameter pairs.
+ *  Both the key and the value of the map are QString. The key is the constraint of the condition and the value is the parameter which is applied for the constraint.
+ *
+ *  The supported constraints are:
+ *  tag -> symbol has the tag matching the parameter
+ *  !tag -> symbol doesnot have the tag matching the parameter
+ *  group -> symbol belongs to group specified by the parameter
+ *  !group -> symbol doesn't belong to the group specified by the parameter
+ *  name -> symbol has a part of its name matching the parameter
+ *  !name -> symbol doesn't have any part of the name matching the parameter
+ *
+ *  Example Usage:
+ *  QgsSmartConditionMap conditions;
+ *  conditions.insert( "tag", "red" ); // adds the condition: Symbol has the tag red
+ *  conditions.insert( "!name", "way" ); // add the condition: Symbol doesn't have any part of its name matching `way`
+ *
+ *  \note This is a Multimap, which means it will contain multiple values for the same key.
+ */
 typedef QMultiMap<QString, QString> QgsSmartConditionMap;
 
 // enumerators representing sqlite DB columns
@@ -43,7 +63,12 @@ enum TagmapTable { TagmapTagId, TagmapSymbolId };
 enum ColorrampTable { ColorrampId, ColorrampName, ColorrampXML, ColorrampGroupId };
 enum SmartgroupTable { SmartgroupId, SmartgroupName, SmartgroupXML };
 
-// Enums for types
+//! Enum for Entities involved in a style
+/*!
+    The enumarator is used for identifying the entity being operated on when generic
+    database functions are being run.
+    \sa group(), rename(), remove(), symbolsOfGroup(), symbolsWithTag(), symbolsOfSmartgroup()
+ */
 enum StyleEntity { SymbolEntity, GroupEntity, TagEntity, ColorrampEntity, SmartgroupEntity };
 
 class CORE_EXPORT QgsStyleV2
@@ -53,15 +78,80 @@ class CORE_EXPORT QgsStyleV2
     QgsStyleV2();
     ~QgsStyleV2();
 
-    //! return default application-wide style
-    static QgsStyleV2* defaultStyle();
+    //! add color ramp to style. takes ramp's ownership
+    bool addColorRamp( QString name, QgsVectorColorRampV2* colorRamp );
 
-    //! remove all contents of the style
-    void clear();
+    //! adds a new group and returns the group's id
+    /*!
+     *  \param groupname the name of the new group as QString
+     *  \param parent is the id of the parent group when a subgrouo is to be created. By default it is 0 indicating it is not a sub-group
+     *  \return returns an int, which is the DB id of the new group created, 0 if the group couldn't be created
+     */
+    int addGroup( QString groupName, int parent = 0 );
+
+    //! adds new smartgroup to the database and returns the id
+    /*!
+     *  \param name is the name of the new Smart Group to be added
+     *  \param op is the operator between the conditions; AND/OR as QString
+     *  \param conditions are the smart group conditions
+     */
+    int addSmartgroup( QString name, QString op, QgsSmartConditionMap conditions );
 
     //! add symbol to style. takes symbol's ownership
     bool addSymbol( QString name, QgsSymbolV2* symbol );
 
+    //! adds a new tag and returns the tag's id
+    /*!
+     *  \param tagName the name of the new tag to be created
+     *  \return returns an int, which is the DB id of the new tag created, 0 if the tag couldn't be created
+     */
+    int addTag( QString tagName );
+
+    //! return a map of groupid and names for the given parent
+    QgsSymbolGroupMap childGroupNames( QString parent = "" );
+
+    //! remove all contents of the style
+    void clear();
+
+    //! return a NEW copy of color ramp
+    QgsVectorColorRampV2* colorRamp( QString name );
+
+    //! return count of color ramps
+    int colorRampCount();
+
+    //! return a list of names of color ramps
+    QStringList colorRampNames();
+
+    //! return a const pointer to a symbol (doesn't create new instance)
+    const QgsVectorColorRampV2* colorRampRef( QString name ) const;
+
+    //! return the id in the style database for the given colorramp name
+    //! returns 0 if not found
+    int colorrampId( QString name );
+
+    //! return default application-wide style
+    static QgsStyleV2* defaultStyle();
+
+    //! tags the symbol with the tags in the list
+    /*!
+     *  Applies the given tags to the given symbol or colorramp
+     *  \param type is either SymbolEntity or ColorrampEntity
+     *  \param symbol is the name of the symbol or colorramp as QString
+     *  \param tags is the list of the tags that are to be applied as QStringList
+     *  \return returns the success state of the operation
+     */
+    bool tagSymbol( StyleEntity type, QString symbol, QStringList tags );
+
+    //! detags the symbol with the given list
+    /*!
+     *  Removes the given tags for the specified symbol or colorramp
+     *  \param type is either SymbolEntity or ColorrampEntity
+     *  \param symbol is the name of the symbol or colorramp
+     *  \param tags is the list of tags that are to be removed as QStringList
+     *  \return returns the sucess state of the operation
+     */
+    bool detagSymbol( StyleEntity type, QString symbol, QStringList tags );
+
     //! remove symbol from style (and delete it)
     bool removeSymbol( QString name );
 
@@ -84,44 +174,76 @@ class CORE_EXPORT QgsStyleV2
     //! return the id in the style database for the given symbol name
     //! returns 0 if not found
     int symbolId( QString name );
-    int colorrampId( QString name );
-
-    //! return the id in the style database for the given group name
+    //! return the DB id for the given group name
     int groupId( QString group );
+    //! return the DB id for the given tag name
     int tagId( QString tag );
+    //! return the DB id for the given smartgroup name
     int smartgroupId( QString smartgroup );
 
     //! return the all the groups in the style
     QStringList groupNames();
 
-    //! return a map of groupid and names for the given parent
-    QgsSymbolGroupMap childGroupNames( QString parent = "" );
-
     //! returns the symbolnames of a given groupid
+    /*!
+     *  \param type is either SymbolEntity or ColorampEntity
+     *  \param groupid is id of the group to which the symbols belong to, as int
+     *  \return A QStringList of the symbol or colorramp names for the given group id
+     */
     QStringList symbolsOfGroup( StyleEntity type, int groupid );
+
     //! returns the symbol names with which have the given tag
+    /*!
+     *  \param type is either SymbolEntity or ColorampEntity
+     *  \param tagid is id of the tag which has been applied over the symbol as int
+     *  \return A QStringList of the symbol or colorramp names for the given tag id
+     */
     QStringList symbolsWithTag( StyleEntity type, int tagid );
-    //! adds a new group and returns the group's id
-    int addGroup( QString groupName, int parent = 0 );
-    //! adds a new tag and returns the tag's id
-    int addTag( QString tagName );
 
     //! applies the specifed group to the symbol or colorramp specified by StyleEntity
+    /*!
+     *  \param type is either SymbolEntity of ColorrampEntity
+     *  \param name is the name of the symbol or coloramp whose group is to be set
+     *  \param groupid is the id of the group to which the entity is assigned
+     *  \return returns the success state as bool
+     */
     bool group( StyleEntity type, QString name, int groupid );
 
     //! rename the given entity with the specified id
+    /*!
+     *  \param type is any of the style entites. Refer enum StyleEntity.
+     *  \param id is the DB id of the entity which is to be renamed
+     *  \param newName is the new name of the entity
+     */
     void rename( StyleEntity type, int id, QString newName );
+
     //! remove the specified entity from the db
+    /*!
+     *  \param type is any of the style entites. Refer enum StyleEntity.
+     *  \param id is the DB id of the entity to be removed
+     */
     void remove( StyleEntity type, int id );
 
     //! add the symbol to the DB with the tags
+    /*!
+     *  \param name is the name of the symbol as QString
+     *  \param symbol is the pointer to the new QgsSymbolV2 being saved
+     *  \param groupid is the id of the group to which the symbol belongs. Pass 0 if it doesn't belong to any group or not known.
+     *  \param tags is a list of tags that are associated with the symbol as a QStringList.
+     *  \return returns the sucess state of the save operation
+     */
     bool saveSymbol( QString name, QgsSymbolV2* symbol, int groupid, QStringList tags );
+
     //! add the colorramp to the DB
+    /*!
+     *  \param name is the name of the colorramp as QString
+     *  \param ramp is the pointer to the new QgsVectorColorRampV2 being saved
+     *  \param groupid is the id of the group to which the Color Ramp belongs. Pass 0 if it doesn't belong to any group or not known.
+     *  \param tags is a list of tags that are associated with the color ramp as a QStringList.
+     *  \return returns the sucess state of the save operation
+     */
     bool saveColorRamp( QString name, QgsVectorColorRampV2* ramp, int groupid, QStringList tags );
 
-    //! add color ramp to style. takes ramp's ownership
-    bool addColorRamp( QString name, QgsVectorColorRampV2* colorRamp );
-
     //! remove color ramp from style (and delete it)
     bool removeColorRamp( QString name );
 
@@ -129,18 +251,6 @@ class CORE_EXPORT QgsStyleV2
     //! @note added in v1.7
     bool renameColorRamp( QString oldName, QString newName );
 
-    //! return a NEW copy of color ramp
-    QgsVectorColorRampV2* colorRamp( QString name );
-
-    //! return a const pointer to a symbol (doesn't create new instance)
-    const QgsVectorColorRampV2* colorRampRef( QString name ) const;
-
-    //! return count of color ramps
-    int colorRampCount();
-
-    //! return a list of names of color ramps
-    QStringList colorRampNames();
-
 
     //! load a file into the style
     bool load( QString filename );
@@ -157,19 +267,15 @@ class CORE_EXPORT QgsStyleV2
     //! return the names of the symbols which have a matching 'substring' in its defintion
     QStringList findSymbols( QString qword );
 
-    //! tags the symbol with the tags in the list, the remove flag DE-TAGS
-    bool tagSymbol( StyleEntity type, QString symbol, QStringList tags );
-
-    //! detags the symbol with the given list
-    bool detagSymbol( StyleEntity type, QString symbol, QStringList tags );
-
     //! return the tags associated with the symbol
+    /*!
+     *  \param type is either SymbolEntity or ColorrampEntity
+     *  \param symbol is the name of the symbol or color ramp
+     *  \return A QStringList of the tags that have been applied to that symbol/colorramp
+     */
     QStringList tagsOfSymbol( StyleEntity type, QString symbol );
 
-    //! adds the smartgroup to the database and returns the id
-    int addSmartgroup( QString name, QString op, QgsSmartConditionMap conditions );
-
-    //! returns the smart groups map
+    //! returns the smart groups map with id as key and name as value
     QgsSymbolGroupMap smartgroupsListMap();
 
     //! returns the smart groups list
@@ -179,7 +285,7 @@ class CORE_EXPORT QgsStyleV2
     QgsSmartConditionMap smartgroup( int id );
 
     //! returns the operator for the smartgroup
-    //! @note: clumsy implementation TODO create a class for smartgroups
+    //clumsy implementation TODO create a class for smartgroups
     QString smartgroupOperator( int id );
 
     //! returns the symbols for the smartgroup
@@ -205,13 +311,16 @@ class CORE_EXPORT QgsStyleV2
 
     //! convenience function to open the DB and return a sqlite3 object
     bool openDB( QString filename );
+
     //! convenience function that would run queries which don't generate return values
-    //! @param query query to run
-    //! @param freeQuery release query memory
-    //! @return success true on success
+    //! \param query query to run
+    //! \param freeQuery release query memory
+    //! \return success true on success
     bool runEmptyQuery( char* query, bool freeQuery = true );
+
     //! prepares the complex query for removing a group, so that the children are not abandoned
     char* getGroupRemoveQuery( int id );
+
     //! gets the id from the table for the given name from the database, 0 if not found
     int getId( QString table, QString name );
 };
-- 
1.7.9.5


From 447c0d1e545b5c956ff43cd64f28592d578d3595 Mon Sep 17 00:00:00 2001
From: Arunmozhi <aruntheguy@gmail.com>
Date: Wed, 22 Aug 2012 22:52:53 +0530
Subject: [PATCH 2/2] bug fix for issue #6229

---
 src/core/symbology-ng/qgsstylev2.cpp             |   76 ++++++++++++++++++++--
 src/core/symbology-ng/qgsstylev2.h               |   29 ++++++++-
 src/gui/symbology-ng/qgsstylev2managerdialog.cpp |    4 +-
 3 files changed, 99 insertions(+), 10 deletions(-)

diff --git a/src/core/symbology-ng/qgsstylev2.cpp b/src/core/symbology-ng/qgsstylev2.cpp
index 6380e17..42590bc 100644
--- a/src/core/symbology-ng/qgsstylev2.cpp
+++ b/src/core/symbology-ng/qgsstylev2.cpp
@@ -80,7 +80,7 @@ void QgsStyleV2::clear()
     sqlite3_close( mCurrentDB );
 }
 
-bool QgsStyleV2::addSymbol( QString name, QgsSymbolV2* symbol )
+bool QgsStyleV2::addSymbol( QString name, QgsSymbolV2* symbol, bool update )
 {
   if ( !symbol || name.isEmpty() )
     return false;
@@ -89,6 +89,9 @@ bool QgsStyleV2::addSymbol( QString name, QgsSymbolV2* symbol )
 
   mSymbols.insert( name, symbol );
 
+  if ( update )
+    updateSymbol( SymbolEntity, name );
+
   return true;
 }
 
@@ -108,7 +111,7 @@ bool QgsStyleV2::saveSymbol( QString name, QgsSymbolV2* symbol, int groupid, QSt
   QByteArray xmlArray;
   QTextStream stream( &xmlArray );
   symEl.save( stream, 4 );
-  char *query = sqlite3_mprintf( "INSERT INTO symbol VALUES (NULL, '%q', '%q', %d)",
+  char *query = sqlite3_mprintf( "INSERT INTO symbol VALUES (NULL, '%q', '%q', %d);",
                                  name.toUtf8().constData(), xmlArray.constData(), groupid );
 
   if ( !runEmptyQuery( query ) )
@@ -170,7 +173,7 @@ QStringList QgsStyleV2::symbolNames()
 }
 
 
-bool QgsStyleV2::addColorRamp( QString name, QgsVectorColorRampV2* colorRamp )
+bool QgsStyleV2::addColorRamp( QString name, QgsVectorColorRampV2* colorRamp, bool update )
 {
   if ( !colorRamp || name.isEmpty() )
     return false;
@@ -178,9 +181,11 @@ bool QgsStyleV2::addColorRamp( QString name, QgsVectorColorRampV2* colorRamp )
   // delete previous symbol (if any)
   delete mColorRamps.value( name );
 
-  QgsDebugMsg( "Inserted " + name );
   mColorRamps.insert( name, colorRamp );
 
+  if ( update )
+    updateSymbol( ColorrampEntity, name );
+
   return true;
 }
 
@@ -201,7 +206,7 @@ bool QgsStyleV2::saveColorRamp( QString name, QgsVectorColorRampV2* ramp, int gr
   QByteArray xmlArray;
   QTextStream stream( &xmlArray );
   rampEl.save( stream, 4 );
-  char *query = sqlite3_mprintf( "INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d)",
+  char *query = sqlite3_mprintf( "INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
                                  name.toUtf8().constData(), xmlArray.constData(), groupid );
 
   if ( !runEmptyQuery( query ) )
@@ -1378,3 +1383,64 @@ bool QgsStyleV2::importXML( QString filename )
   mFileName = filename;
   return true;
 }
+
+bool QgsStyleV2::updateSymbol( StyleEntity type, QString name )
+{
+  QDomDocument doc( "dummy" );
+  QDomElement symEl;
+  QByteArray xmlArray;
+  QTextStream stream( &xmlArray );
+
+  char *query;
+
+  if ( type == SymbolEntity )
+  {
+    // check if it is an existing symbol
+    if ( !symbolNames().contains( name ) )
+    {
+      QgsDebugMsg( "Update request recieved for unavailable symbol" );
+      return false;
+    }
+
+    symEl = QgsSymbolLayerV2Utils::saveSymbol( name, symbol( name ), doc );
+    if ( symEl.isNull() )
+    {
+      QgsDebugMsg( "Couldn't convert symbol to valid XML!" );
+      return false;
+    }
+    symEl.save( stream, 4 );
+    query = sqlite3_mprintf( "UPDATE symbol SET xml='%q' WHERE name='%q';",
+                                 xmlArray.constData(), name.toUtf8().constData() );
+  }
+  else if ( type == ColorrampEntity )
+  {
+    if ( !colorRampNames().contains( name ) )
+    {
+      QgsDebugMsg( "Update requested for unavailable color ramp." );
+      return false;
+    }
+
+    symEl = QgsSymbolLayerV2Utils::saveColorRamp( name, colorRamp( name ), doc );
+    if ( symEl.isNull() )
+    {
+      QgsDebugMsg( "Couldn't convert color ramp to valid XML!" );
+      return false;
+    }
+    symEl.save( stream, 4 );
+    query = sqlite3_mprintf( "UPDATE colorramp SET xml='%q' WHERE name='%q';",
+                                 xmlArray.constData(), name.toUtf8().constData() );
+  }
+  else
+  {
+    QgsDebugMsg( "Updating the unsupported StyleEntity" );
+    return false;
+  }
+
+
+  if ( !runEmptyQuery( query ) )
+  {
+    QgsDebugMsg( "Couldn't insert symbol into the database!" );
+    return false;
+  }
+  return true;
+}
diff --git a/src/core/symbology-ng/qgsstylev2.h b/src/core/symbology-ng/qgsstylev2.h
index 5bec2d1..4ce727d 100644
--- a/src/core/symbology-ng/qgsstylev2.h
+++ b/src/core/symbology-ng/qgsstylev2.h
@@ -79,7 +79,14 @@ class CORE_EXPORT QgsStyleV2
     ~QgsStyleV2();
 
     //! add color ramp to style. takes ramp's ownership
-    bool addColorRamp( QString name, QgsVectorColorRampV2* colorRamp );
+    /*!
+     *  \note Adding a color ramp with the name of existing one replaces it.
+     *  \param name is the name of the color ramp being added or updated
+     *  \param colorRamp is the Vector color ramp
+     *  \param update set to true when the style DB has to be updated, by default it is false
+     *  \return sucess status of the operation
+     */
+    bool addColorRamp( QString name, QgsVectorColorRampV2* colorRamp, bool update = false );
 
     //! adds a new group and returns the group's id
     /*!
@@ -98,7 +105,14 @@ class CORE_EXPORT QgsStyleV2
     int addSmartgroup( QString name, QString op, QgsSmartConditionMap conditions );
 
     //! add symbol to style. takes symbol's ownership
-    bool addSymbol( QString name, QgsSymbolV2* symbol );
+    /*!
+     *  \note Adding a symbol with the name of existing one replaces it.
+     *  \param name is the name of the symbol being added or updated
+     *  \param symbol is the Vector symbol
+     *  \param update set to true when the style DB has to be updated, by default it is false
+     *  \return sucess status of the operation
+     */
+    bool addSymbol( QString name, QgsSymbolV2* symbol, bool update = false );
 
     //! adds a new tag and returns the tag's id
     /*!
@@ -107,7 +121,7 @@ class CORE_EXPORT QgsStyleV2
      */
     int addTag( QString tagName );
 
-    //! return a map of groupid and names for the given parent
+    //! return a map of groupid and names for the given parent group
     QgsSymbolGroupMap childGroupNames( QString parent = "" );
 
     //! remove all contents of the style
@@ -323,6 +337,15 @@ class CORE_EXPORT QgsStyleV2
 
     //! gets the id from the table for the given name from the database, 0 if not found
     int getId( QString table, QString name );
+
+    //! updates the properties of an existing symbol/colorramp
+    /*!
+     *  \note This should not be called seperately, only called through addSymbol or addColorRamp
+     *  \param type is either SymbolEntity or ColorrampEntity
+     *  \param name is the name of an existing symbol or a color ramp
+     *  \return Success state of the update operation
+     */
+    bool updateSymbol( StyleEntity type, QString name );
 };
 
 
diff --git a/src/gui/symbology-ng/qgsstylev2managerdialog.cpp b/src/gui/symbology-ng/qgsstylev2managerdialog.cpp
index 1c7465a..2b0d312 100644
--- a/src/gui/symbology-ng/qgsstylev2managerdialog.cpp
+++ b/src/gui/symbology-ng/qgsstylev2managerdialog.cpp
@@ -490,7 +490,7 @@ bool QgsStyleV2ManagerDialog::editSymbol()
   }
 
   // by adding symbol to style with the same name the old effectively gets overwritten
-  mStyle->addSymbol( symbolName, symbol );
+  mStyle->addSymbol( symbolName, symbol, true );
   mModified = true;
   return true;
 }
@@ -548,7 +548,7 @@ bool QgsStyleV2ManagerDialog::editColorRamp()
     Q_ASSERT( 0 && "invalid ramp type" );
   }
 
-  mStyle->addColorRamp( name, ramp );
+  mStyle->addColorRamp( name, ramp, true );
   mModified = true;
   return true;
 }
-- 
1.7.9.5

