[QGIS Commit] r11881 - in branches/symbology-ng-branch: resources
src/core src/core/symbology-ng
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Sun Nov 1 18:47:56 EST 2009
Author: wonder
Date: 2009-11-01 18:47:56 -0500 (Sun, 01 Nov 2009)
New Revision: 11881
Modified:
branches/symbology-ng-branch/resources/symbology-ng-style.xml
branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp
branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.cpp
branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.h
branches/symbology-ng-branch/src/core/symbology-ng/qgsstylev2.cpp
branches/symbology-ng-branch/src/core/symbology-ng/qgsstylev2.h
branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.cpp
branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.h
Log:
Added loading and saving of renderers v2 in project files.
Modified: branches/symbology-ng-branch/resources/symbology-ng-style.xml
===================================================================
--- branches/symbology-ng-branch/resources/symbology-ng-style.xml 2009-11-01 23:45:49 UTC (rev 11880)
+++ branches/symbology-ng-branch/resources/symbology-ng-style.xml 2009-11-01 23:47:56 UTC (rev 11881)
@@ -1,5 +1,6 @@
<!DOCTYPE qgis_style>
<qgis_style version="0" >
+ <symbols>
<symbol type="marker" name="blue square" >
<layer class="SimpleMarker" locked="0" >
<prop k="angle" v="0" />
@@ -97,6 +98,8 @@
<prop k="size" v="12" />
</layer>
</symbol>
+ </symbols>
+ <colorramps>
<colorramp type="gradient" name="blue" >
<prop k="color1" v="0,0,255" />
<prop k="color2" v="207,205,255" />
@@ -109,4 +112,5 @@
<prop k="color1" v="255,0,0" />
<prop k="color2" v="255,255,0" />
</colorramp>
+ </colorramps>
</qgis_style>
Modified: branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp 2009-11-01 23:45:49 UTC (rev 11880)
+++ branches/symbology-ng-branch/src/core/qgsvectorlayer.cpp 2009-11-01 23:47:56 UTC (rev 11881)
@@ -2315,12 +2315,28 @@
}
}
- QString errorMsg;
- if ( !readSymbology( layer_node, errorMsg ) )
+ QDomElement rendererElement = layer_node.firstChildElement(RENDERER_TAG_NAME);
+ if (!rendererElement.isNull())
{
- return false;
+ // using renderer v2
+ setUsingRendererV2(true);
+
+ QgsFeatureRendererV2* r = QgsFeatureRendererV2::load(rendererElement);
+ if (r == NULL)
+ return false;
+ setRendererV2(r);
}
+ else
+ {
+ // using renderer v1
+ setUsingRendererV2(false);
+ QString errorMsg;
+ if ( !readSymbology( layer_node, errorMsg ) )
+ {
+ return false;
+ }
+ }
return mValid; // should be true if read successfully
@@ -2455,14 +2471,20 @@
}
// renderer specific settings
-
- QString errorMsg;
- if ( !writeSymbology( layer_node, document, errorMsg ) )
+ if (mUsingRendererV2)
{
- return false;
+ QDomElement rendererElement = mRendererV2->save(document);
+ layer_node.appendChild(rendererElement);
}
+ else
+ {
+ QString errorMsg;
+ if ( !writeSymbology( layer_node, document, errorMsg ) )
+ {
+ return false;
+ }
+ }
-
return true;
} // bool QgsVectorLayer::writeXml
Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.cpp 2009-11-01 23:45:49 UTC (rev 11880)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.cpp 2009-11-01 23:47:56 UTC (rev 11881)
@@ -1,14 +1,18 @@
#include "qgsrendererv2.h"
#include "qgssymbolv2.h"
+#include "qgssymbollayerv2utils.h"
#include "qgsrendercontext.h"
#include "qgsgeometry.h"
#include "qgsfeature.h"
#include "qgslogger.h"
+#include <QDomElement>
+#include <QDomDocument>
#include <QPolygonF>
+
static unsigned char* _getPoint(QPointF& pt, const QgsMapToPixel& mapToPixel, unsigned char* wkb)
{
wkb++; // jump over endian info
@@ -247,6 +251,40 @@
}
+QgsFeatureRendererV2* QgsFeatureRendererV2::load(QDomElement& element)
+{
+ // <renderer-v2 type=""> ... </renderer-v2>
+
+ if (element.isNull())
+ return NULL;
+
+ // load renderer
+ QString rendererType = element.attribute("type");
+
+ // TODO: use renderer registry
+ if (rendererType == "singleSymbol")
+ {
+ return QgsSingleSymbolRendererV2::create(element);
+ }
+ else if (rendererType == "categorizedSymbol")
+ {
+ return QgsCategorizedSymbolRendererV2::create(element);
+ }
+ else if (rendererType == "graduatedSymbol")
+ {
+ return QgsGraduatedSymbolRendererV2::create(element);
+ }
+
+ // unknown renderer type
+ return NULL;
+}
+
+QDomElement QgsFeatureRendererV2::save(QDomDocument& doc)
+{
+ // create empty renderer element
+ return doc.createElement(RENDERER_TAG_NAME);
+}
+
///////////////////
QgsSingleSymbolRendererV2::QgsSingleSymbolRendererV2(QgsSymbolV2* symbol)
@@ -310,6 +348,39 @@
return lst;
}
+QgsFeatureRendererV2* QgsSingleSymbolRendererV2::create(QDomElement& element)
+{
+ QDomElement symbolsElem = element.firstChildElement("symbols");
+ if (symbolsElem.isNull())
+ return NULL;
+
+ QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols(symbolsElem);
+
+ if (!symbolMap.contains("0"))
+ return NULL;
+
+ QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( symbolMap.take("0") );
+
+ // delete symbols if there are any more
+ QgsSymbolLayerV2Utils::clearSymbolMap(symbolMap);
+
+ // TODO: symbol levels
+ return r;
+}
+
+QDomElement QgsSingleSymbolRendererV2::save(QDomDocument& doc)
+{
+ QDomElement rendererElem = doc.createElement(RENDERER_TAG_NAME);
+ rendererElem.setAttribute("type", "singleSymbol");
+
+ QgsSymbolV2Map symbols;
+ symbols["0"] = mSymbol;
+ QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(symbols, doc);
+ rendererElem.appendChild(symbolsElem);
+
+ return rendererElem;
+}
+
///////////////////
QgsRendererCategoryV2::QgsRendererCategoryV2(QVariant value, QgsSymbolV2* symbol, QString label)
@@ -513,6 +584,81 @@
return lst;
}
+QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::create(QDomElement& element)
+{
+ QDomElement symbolsElem = element.firstChildElement("symbols");
+ if (symbolsElem.isNull())
+ return NULL;
+
+ QDomElement catsElem = element.firstChildElement("categories");
+ if (catsElem.isNull())
+ return NULL;
+
+ QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols(symbolsElem);
+ QgsCategoryList cats;
+
+ QDomElement catElem = catsElem.firstChildElement();
+ while (!catElem.isNull())
+ {
+ if (catElem.tagName() == "category")
+ {
+ QVariant value = QVariant(catElem.attribute("value"));
+ QString symbolName = catElem.attribute("symbol");
+ QString label = catElem.attribute("label");
+ if (symbolMap.contains(symbolName))
+ {
+ QgsSymbolV2* symbol = symbolMap.take(symbolName);
+ cats.append( QgsRendererCategoryV2(value, symbol, label) );
+ }
+ }
+ catElem = catElem.nextSiblingElement();
+ }
+
+ int attrNum = element.attribute("attr").toInt();
+
+ QgsCategorizedSymbolRendererV2* r = new QgsCategorizedSymbolRendererV2(attrNum, cats);
+
+ // delete symbols if there are any more
+ QgsSymbolLayerV2Utils::clearSymbolMap(symbolMap);
+
+ // TODO: symbol levels
+ return r;
+}
+
+QDomElement QgsCategorizedSymbolRendererV2::save(QDomDocument& doc)
+{
+ QDomElement rendererElem = doc.createElement(RENDERER_TAG_NAME);
+ rendererElem.setAttribute("type", "categorizedSymbol");
+ rendererElem.setAttribute("attr", mAttrNum);
+
+ // categories
+ int i = 0;
+ QgsSymbolV2Map symbols;
+ QDomElement catsElem = doc.createElement("categories");
+ QgsCategoryList::const_iterator it = mCategories.constBegin();
+ for ( ; it != mCategories.end(); it++)
+ {
+ const QgsRendererCategoryV2& cat = *it;
+ QString symbolName = QString::number(i);
+ symbols.insert(symbolName, cat.symbol());
+
+ QDomElement catElem = doc.createElement("category");
+ catElem.setAttribute("value", cat.value().toString());
+ catElem.setAttribute("symbol", symbolName);
+ catElem.setAttribute("label", cat.label());
+ catsElem.appendChild(catElem);
+ i++;
+ }
+
+ rendererElem.appendChild(catsElem);
+
+ // save symbols
+ QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(symbols, doc);
+ rendererElem.appendChild(symbolsElem);
+
+ return rendererElem;
+}
+
/////////////////////////
// graduated
@@ -778,3 +924,82 @@
return new QgsGraduatedSymbolRendererV2( attrNum, ranges );
}
+
+
+
+QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::create(QDomElement& element)
+{
+ QDomElement symbolsElem = element.firstChildElement("symbols");
+ if (symbolsElem.isNull())
+ return NULL;
+
+ QDomElement rangesElem = element.firstChildElement("ranges");
+ if (rangesElem.isNull())
+ return NULL;
+
+ QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols(symbolsElem);
+ QgsRangeList ranges;
+
+ QDomElement rangeElem = rangesElem.firstChildElement();
+ while (!rangeElem.isNull())
+ {
+ if (rangeElem.tagName() == "range")
+ {
+ double lowerValue = rangeElem.attribute("lower").toDouble();
+ double upperValue = rangeElem.attribute("upper").toDouble();
+ QString symbolName = rangeElem.attribute("symbol");
+ QString label = rangeElem.attribute("label");
+ if (symbolMap.contains(symbolName))
+ {
+ QgsSymbolV2* symbol = symbolMap.take(symbolName);
+ ranges.append( QgsRendererRangeV2(lowerValue, upperValue, symbol, label) );
+ }
+ }
+ rangeElem = rangeElem.nextSiblingElement();
+ }
+
+ int attrNum = element.attribute("attr").toInt();
+
+ QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2(attrNum, ranges);
+
+ // delete symbols if there are any more
+ QgsSymbolLayerV2Utils::clearSymbolMap(symbolMap);
+
+ // TODO: symbol levels
+ return r;
+}
+
+QDomElement QgsGraduatedSymbolRendererV2::save(QDomDocument& doc)
+{
+ QDomElement rendererElem = doc.createElement(RENDERER_TAG_NAME);
+ rendererElem.setAttribute("type", "graduatedSymbol");
+ rendererElem.setAttribute("attr", mAttrNum);
+
+ // ranges
+ int i = 0;
+ QgsSymbolV2Map symbols;
+ QDomElement rangesElem = doc.createElement("ranges");
+ QgsRangeList::const_iterator it = mRanges.constBegin();
+ for ( ; it != mRanges.end(); it++)
+ {
+ const QgsRendererRangeV2& range = *it;
+ QString symbolName = QString::number(i);
+ symbols.insert(symbolName, range.symbol());
+
+ QDomElement rangeElem = doc.createElement("range");
+ rangeElem.setAttribute("lower", range.lowerValue());
+ rangeElem.setAttribute("upper", range.upperValue());
+ rangeElem.setAttribute("symbol", symbolName);
+ rangeElem.setAttribute("label", range.label());
+ rangesElem.appendChild(rangeElem);
+ i++;
+ }
+
+ rendererElem.appendChild(rangesElem);
+
+ // save symbols
+ QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(symbols, doc);
+ rendererElem.appendChild(symbolsElem);
+
+ return rendererElem;
+}
Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.h
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.h 2009-11-01 23:45:49 UTC (rev 11880)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgsrendererv2.h 2009-11-01 23:47:56 UTC (rev 11881)
@@ -9,12 +9,18 @@
#include <QString>
#include <QVariant>
+class QDomDocument;
+class QDomElement;
+
class QgsSymbolV2;
class QgsRenderContext;
class QgsFeature;
typedef QList<QgsSymbolV2*> QgsSymbolV2List;
+typedef QMap<QString, QgsSymbolV2* > QgsSymbolV2Map;
+#define RENDERER_TAG_NAME "renderer-v2"
+
////////
// symbol levels
@@ -80,6 +86,12 @@
bool usingSymbolLevels() const { return mUsingSymbolLevels; }
void setUsingSymbolLevels(bool usingSymbolLevels) { mUsingSymbolLevels = usingSymbolLevels; }
+
+ //! create a renderer from XML element
+ static QgsFeatureRendererV2* load(QDomElement& symbologyElem);
+
+ //! store renderer info to XML element
+ virtual QDomElement save(QDomDocument& doc);
protected:
QgsFeatureRendererV2(RendererType type);
@@ -114,6 +126,12 @@
virtual QgsSymbolV2List symbols();
+ //! create renderer from XML element
+ static QgsFeatureRendererV2* create(QDomElement& element);
+
+ //! store renderer info to XML element
+ virtual QDomElement save(QDomDocument& doc);
+
protected:
QgsSymbolV2* mSymbol;
};
@@ -185,6 +203,12 @@
int attributeIndex() const { return mAttrNum; }
void setAttributeIndex(int attr) { mAttrNum = attr; }
+ //! create renderer from XML element
+ static QgsFeatureRendererV2* create(QDomElement& element);
+
+ //! store renderer info to XML element
+ virtual QDomElement save(QDomDocument& doc);
+
protected:
QgsCategoryList mCategories;
int mAttrNum;
@@ -278,6 +302,12 @@
QgsSymbolV2* symbol,
QgsVectorColorRampV2* ramp);
+ //! create renderer from XML element
+ static QgsFeatureRendererV2* create(QDomElement& element);
+
+ //! store renderer info to XML element
+ virtual QDomElement save(QDomDocument& doc);
+
protected:
QgsRangeList mRanges;
int mAttrNum;
Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgsstylev2.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgsstylev2.cpp 2009-11-01 23:45:49 UTC (rev 11880)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgsstylev2.cpp 2009-11-01 23:47:56 UTC (rev 11881)
@@ -190,165 +190,42 @@
mErrorString = "Unknown style file version: " + version;
return false;
}
-
- QDomNode node = docElem.firstChild();
- QString name;
-
- while (!node.isNull())
+
+ // load symbols
+ QDomElement symbolsElement = docElem.firstChildElement("symbols");
+ if (!symbolsElement.isNull())
{
- QDomElement e = node.toElement();
- if (!e.isNull()) // comments are null elements
- {
- if (e.tagName() == "symbol")
- {
- name = e.attribute("name");
- QgsSymbolV2* symbol = loadSymbol(e);
- if (symbol != NULL)
- addSymbol(name, symbol);
- }
- else if (e.tagName() == "colorramp")
- {
- name = e.attribute("name");
- QgsVectorColorRampV2* ramp = loadColorRamp(e);
- if (ramp != NULL)
- addColorRamp(name, ramp);
- }
- else
- {
- QgsDebugMsg("unknown tag: " + e.tagName());
- }
- }
- node = node.nextSibling();
+ mSymbols = QgsSymbolLayerV2Utils::loadSymbols(symbolsElement);
}
-
- // now walk through the list of symbols and find those prefixed with @
- // these symbols are sub-symbols of some other symbol layers
- // e.g. symbol named "@foo at 1" is sub-symbol of layer 1 in symbol "foo"
- QStringList subsymbols;
-
- for (QMap<QString, QgsSymbolV2*>::iterator it = mSymbols.begin(); it != mSymbols.end(); ++it)
+
+ // load color ramps
+ QDomElement rampsElement = docElem.firstChildElement("colorramps");
+ QDomElement e = rampsElement.firstChildElement();
+ while (!e.isNull())
{
- if (it.key()[0] != '@')
- continue;
-
- // add to array (for deletion)
- subsymbols.append(it.key());
-
- QStringList parts = it.key().split("@");
- if (parts.count() < 3)
+ if (e.tagName() == "colorramp")
{
- QgsDebugMsg("found subsymbol with invalid name: "+it.key());
- delete it.value(); // we must delete it
- continue; // some invalid syntax
+ QgsVectorColorRampV2* ramp = loadColorRamp(e);
+ if (ramp != NULL)
+ addColorRamp(e.attribute("name"), ramp);
}
- QString symname = parts[1];
- int symlayer = parts[2].toInt();
-
- if (!mSymbols.contains(symname))
+ else
{
- QgsDebugMsg("subsymbol references invalid symbol: " + symname);
- delete it.value(); // we must delete it
- continue;
+ QgsDebugMsg("unknown tag: " + e.tagName());
}
-
- QgsSymbolV2* sym = mSymbols[symname];
- if (symlayer < 0 || symlayer >= sym->symbolLayerCount())
- {
- QgsDebugMsg("subsymbol references invalid symbol layer: "+ QString::number(symlayer));
- delete it.value(); // we must delete it
- continue;
- }
-
- // set subsymbol takes ownership
- bool res = sym->symbolLayer(symlayer)->setSubSymbol( it.value() );
- if (!res)
- {
- QgsDebugMsg("symbol layer refused subsymbol: " + it.key());
- }
-
-
+ e = e.nextSiblingElement();
}
-
- // now safely remove sub-symbol entries (they have been already deleted or the ownership was taken away)
- for (int i = 0; i < subsymbols.count(); i++)
- mSymbols.take(subsymbols[i]);
-
+
return true;
}
-QgsSymbolV2* QgsStyleV2::loadSymbol(QDomElement& element)
-{
- QgsSymbolLayerV2List layers;
- QDomNode layerNode = element.firstChild();
-
- while (!layerNode.isNull())
- {
- QDomElement e = layerNode.toElement();
- if (!e.isNull())
- {
- if (e.tagName() != "layer")
- {
- QgsDebugMsg("unknown tag " + e.tagName());
- }
- else
- {
- QgsSymbolLayerV2* layer = loadSymbolLayer(e);
- if (layer != NULL)
- layers.append(layer);
- }
- }
- layerNode = layerNode.nextSibling();
- }
-
- if (layers.count() == 0)
- {
- QgsDebugMsg("no layers for symbol");
- return NULL;
- }
-
- QString symbolType = element.attribute("type");
- if (symbolType == "line")
- return new QgsLineSymbolV2(layers);
- else if (symbolType == "fill")
- return new QgsFillSymbolV2(layers);
- else if (symbolType == "marker")
- return new QgsMarkerSymbolV2(layers);
- else
- {
- QgsDebugMsg("unknown symbol type " + symbolType);
- return NULL;
- }
-}
-
-QgsSymbolLayerV2* QgsStyleV2::loadSymbolLayer(QDomElement& element)
-{
- QString layerClass = element.attribute("class");
- bool locked = element.attribute("locked").toInt();
-
- // parse properties
- QgsStringMap props = parseProperties(element);
-
- QgsSymbolLayerV2* layer;
- layer = QgsSymbolLayerV2Registry::instance()->createSymbolLayer(layerClass, props);
- if (layer)
- {
- layer->setLocked(locked);
- return layer;
- }
- else
- {
- QgsDebugMsg("unknown class " + layerClass);
- return NULL;
- }
-}
-
QgsVectorColorRampV2* QgsStyleV2::loadColorRamp(QDomElement& element)
{
QString rampType = element.attribute("type");
// parse properties
- QgsStringMap props = parseProperties(element);
+ QgsStringMap props = QgsSymbolLayerV2Utils::parseProperties(element);
if (rampType == "gradient")
return QgsVectorGradientColorRampV2::create(props);
@@ -362,43 +239,7 @@
}
-QgsStringMap QgsStyleV2::parseProperties(QDomElement& element)
-{
- QgsStringMap props;
- QDomNode propNode = element.firstChild();
- while (!propNode.isNull())
- {
- QDomElement e = propNode.toElement();
- if (!e.isNull())
- {
- if (e.tagName() != "prop")
- {
- QgsDebugMsg("unknown tag " + e.tagName());
- }
- else
- {
- QString propKey = e.attribute("k");
- QString propValue = e.attribute("v");
- props[propKey] = propValue;
- }
- }
- propNode = propNode.nextSibling();
- }
- return props;
-}
-void QgsStyleV2::saveProperties(QgsStringMap props, QDomDocument& doc, QDomElement& element)
-{
- for (QgsStringMap::iterator it = props.begin(); it != props.end(); ++it)
- {
- QDomElement propEl = doc.createElement("prop");
- propEl.setAttribute("k", it.key());
- propEl.setAttribute("v", it.value());
- element.appendChild(propEl);
- }
-}
-
-
bool QgsStyleV2::save(QString filename)
{
mErrorString = QString();
@@ -409,29 +250,20 @@
QDomElement root = doc.createElement("qgis_style");
root.setAttribute("version", STYLE_CURRENT_VERSION);
doc.appendChild(root);
+
+ QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols(mSymbols, doc);
+
+ QDomElement rampsElem = doc.createElement("colorramps");
- QMap<QString, QgsSymbolV2*> subSymbols;
-
- // save symbols
- for (QMap<QString, QgsSymbolV2*>::iterator its = mSymbols.begin(); its != mSymbols.end(); ++its)
- {
- QDomElement symEl = saveSymbol(its.key(), its.value(), doc, &subSymbols);
- root.appendChild(symEl);
- }
-
- // add subsymbols, don't allow subsymbols for them (to keep things simple)
- for (QMap<QString, QgsSymbolV2*>::iterator itsub = subSymbols.begin(); itsub != subSymbols.end(); ++itsub)
- {
- QDomElement subsymEl = saveSymbol(itsub.key(), itsub.value(), doc);
- root.appendChild(subsymEl);
- }
-
// save color ramps
for (QMap<QString, QgsVectorColorRampV2*>::iterator itr = mColorRamps.begin(); itr != mColorRamps.end(); ++itr)
{
QDomElement rampEl = saveColorRamp(itr.key(), itr.value(), doc);
- root.appendChild(rampEl);
+ rampsElem.appendChild(rampEl);
}
+
+ root.appendChild(symbolsElem);
+ root.appendChild(rampsElem);
// save
QFile f(filename);
@@ -447,49 +279,12 @@
return true;
}
-static QString _nameForSymbolType(QgsSymbolV2::SymbolType type)
-{
- switch (type)
- {
- case QgsSymbolV2::Line: return "line";
- case QgsSymbolV2::Marker: return "marker";
- case QgsSymbolV2::Fill: return "fill";
- }
-}
-
-QDomElement QgsStyleV2::saveSymbol(QString name, QgsSymbolV2* symbol, QDomDocument& doc, QgsSymbolV2Map* subSymbols)
-{
- QDomElement symEl = doc.createElement("symbol");
- symEl.setAttribute("type", _nameForSymbolType(symbol->type()) );
- symEl.setAttribute("name", name);
-
- for (int i = 0; i < symbol->symbolLayerCount(); i++)
- {
- QgsSymbolLayerV2* layer = symbol->symbolLayer(i);
-
- QDomElement layerEl = doc.createElement("layer");
- layerEl.setAttribute("class", layer->layerType());
- layerEl.setAttribute("locked", layer->isLocked());
-
- if (subSymbols != NULL && layer->subSymbol() != NULL)
- {
- QString subname = QString("@%1@%2").arg(name).arg(i);
- subSymbols->insert(subname, layer->subSymbol());
- }
-
- saveProperties(layer->properties(), doc, layerEl);
- symEl.appendChild(layerEl);
- }
-
- return symEl;
-}
-
QDomElement QgsStyleV2::saveColorRamp(QString name, QgsVectorColorRampV2* ramp, QDomDocument& doc)
{
QDomElement rampEl = doc.createElement("colorramp");
rampEl.setAttribute("type", ramp->type());
rampEl.setAttribute("name", name);
- saveProperties(ramp->properties(), doc, rampEl);
+ QgsSymbolLayerV2Utils::saveProperties(ramp->properties(), doc, rampEl);
return rampEl;
}
Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgsstylev2.h
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgsstylev2.h 2009-11-01 23:45:49 UTC (rev 11880)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgsstylev2.h 2009-11-01 23:47:56 UTC (rev 11881)
@@ -14,7 +14,6 @@
class QDomDocument;
class QDomElement;
-typedef QMap<QString, QgsSymbolV2* > QgsSymbolV2Map;
typedef QMap<QString, QgsVectorColorRampV2* > QgsVectorColorRampV2Map;
class QgsStyleV2
@@ -79,16 +78,10 @@
protected:
- QgsStringMap parseProperties(QDomElement& element);
- void saveProperties(QgsStringMap props, QDomDocument& doc, QDomElement& element);
-
- QgsSymbolV2* loadSymbol(QDomElement& element);
- QgsSymbolLayerV2* loadSymbolLayer(QDomElement& element);
QgsVectorColorRampV2* loadColorRamp(QDomElement& element);
- QDomElement saveSymbol(QString name, QgsSymbolV2* symbol, QDomDocument& doc, QgsSymbolV2Map* subSymbols = NULL);
QDomElement saveColorRamp(QString name, QgsVectorColorRampV2* ramp, QDomDocument& doc);
-
+
QgsSymbolV2Map mSymbols;
QgsVectorColorRampV2Map mColorRamps;
Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.cpp 2009-11-01 23:45:49 UTC (rev 11880)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.cpp 2009-11-01 23:47:56 UTC (rev 11881)
@@ -2,10 +2,15 @@
#include "qgssymbollayerv2utils.h"
#include "qgssymbollayerv2.h"
+#include "qgssymbollayerv2registry.h"
#include "qgssymbolv2.h"
#include "qgsvectorcolorrampv2.h"
+#include "qgslogger.h"
+
#include <QColor>
+#include <QDomNode>
+#include <QDomElement>
#include <QIcon>
#include <QPainter>
@@ -290,3 +295,252 @@
newLine.append(pt_new);
return newLine;
}
+
+/////
+
+
+QgsSymbolV2* QgsSymbolLayerV2Utils::loadSymbol(QDomElement& element)
+{
+ QgsSymbolLayerV2List layers;
+ QDomNode layerNode = element.firstChild();
+
+ while (!layerNode.isNull())
+ {
+ QDomElement e = layerNode.toElement();
+ if (!e.isNull())
+ {
+ if (e.tagName() != "layer")
+ {
+ QgsDebugMsg("unknown tag " + e.tagName());
+ }
+ else
+ {
+ QgsSymbolLayerV2* layer = loadSymbolLayer(e);
+ if (layer != NULL)
+ layers.append(layer);
+ }
+ }
+ layerNode = layerNode.nextSibling();
+ }
+
+ if (layers.count() == 0)
+ {
+ QgsDebugMsg("no layers for symbol");
+ return NULL;
+ }
+
+ QString symbolType = element.attribute("type");
+ if (symbolType == "line")
+ return new QgsLineSymbolV2(layers);
+ else if (symbolType == "fill")
+ return new QgsFillSymbolV2(layers);
+ else if (symbolType == "marker")
+ return new QgsMarkerSymbolV2(layers);
+ else
+ {
+ QgsDebugMsg("unknown symbol type " + symbolType);
+ return NULL;
+ }
+}
+
+QgsSymbolLayerV2* QgsSymbolLayerV2Utils::loadSymbolLayer(QDomElement& element)
+{
+ QString layerClass = element.attribute("class");
+ bool locked = element.attribute("locked").toInt();
+
+ // parse properties
+ QgsStringMap props = parseProperties(element);
+
+ QgsSymbolLayerV2* layer;
+ layer = QgsSymbolLayerV2Registry::instance()->createSymbolLayer(layerClass, props);
+ if (layer)
+ {
+ layer->setLocked(locked);
+ return layer;
+ }
+ else
+ {
+ QgsDebugMsg("unknown class " + layerClass);
+ return NULL;
+ }
+}
+
+static QString _nameForSymbolType(QgsSymbolV2::SymbolType type)
+{
+ switch (type)
+ {
+ case QgsSymbolV2::Line: return "line";
+ case QgsSymbolV2::Marker: return "marker";
+ case QgsSymbolV2::Fill: return "fill";
+ }
+}
+
+QDomElement QgsSymbolLayerV2Utils::saveSymbol(QString name, QgsSymbolV2* symbol, QDomDocument& doc, QgsSymbolV2Map* subSymbols)
+{
+ QDomElement symEl = doc.createElement("symbol");
+ symEl.setAttribute("type", _nameForSymbolType(symbol->type()) );
+ symEl.setAttribute("name", name);
+
+ QgsDebugMsg("num layers " + QString::number(symbol->symbolLayerCount()));
+ for (int i = 0; i < symbol->symbolLayerCount(); i++)
+ {
+ QgsSymbolLayerV2* layer = symbol->symbolLayer(i);
+
+ QDomElement layerEl = doc.createElement("layer");
+ layerEl.setAttribute("class", layer->layerType());
+ layerEl.setAttribute("locked", layer->isLocked());
+
+ if (subSymbols != NULL && layer->subSymbol() != NULL)
+ {
+ QString subname = QString("@%1@%2").arg(name).arg(i);
+ subSymbols->insert(subname, layer->subSymbol());
+ }
+
+ saveProperties(layer->properties(), doc, layerEl);
+ symEl.appendChild(layerEl);
+ }
+
+ return symEl;
+}
+
+
+QgsStringMap QgsSymbolLayerV2Utils::parseProperties(QDomElement& element)
+{
+ QgsStringMap props;
+ QDomElement e = element.firstChildElement();
+ while (!e.isNull())
+ {
+ if (e.tagName() != "prop")
+ {
+ QgsDebugMsg("unknown tag " + e.tagName());
+ }
+ else
+ {
+ QString propKey = e.attribute("k");
+ QString propValue = e.attribute("v");
+ props[propKey] = propValue;
+ }
+ e = e.nextSiblingElement();
+ }
+ return props;
+}
+
+
+void QgsSymbolLayerV2Utils::saveProperties(QgsStringMap props, QDomDocument& doc, QDomElement& element)
+{
+ for (QgsStringMap::iterator it = props.begin(); it != props.end(); ++it)
+ {
+ QDomElement propEl = doc.createElement("prop");
+ propEl.setAttribute("k", it.key());
+ propEl.setAttribute("v", it.value());
+ element.appendChild(propEl);
+ }
+}
+
+QgsSymbolV2Map QgsSymbolLayerV2Utils::loadSymbols(QDomElement& element)
+{
+ // go through symbols one-by-one and load them
+
+ QgsSymbolV2Map symbols;
+ QDomElement e = element.firstChildElement();
+
+ while (!e.isNull())
+ {
+ if (e.tagName() == "symbol")
+ {
+ QgsSymbolV2* symbol = QgsSymbolLayerV2Utils::loadSymbol(e);
+ if (symbol != NULL)
+ symbols.insert(e.attribute("name"), symbol);
+ }
+ else
+ {
+ QgsDebugMsg("unknown tag: " + e.tagName());
+ }
+ e = e.nextSiblingElement();
+ }
+
+
+ // now walk through the list of symbols and find those prefixed with @
+ // these symbols are sub-symbols of some other symbol layers
+ // e.g. symbol named "@foo at 1" is sub-symbol of layer 1 in symbol "foo"
+ QStringList subsymbols;
+
+ for (QMap<QString, QgsSymbolV2*>::iterator it = symbols.begin(); it != symbols.end(); ++it)
+ {
+ if (it.key()[0] != '@')
+ continue;
+
+ // add to array (for deletion)
+ subsymbols.append(it.key());
+
+ QStringList parts = it.key().split("@");
+ if (parts.count() < 3)
+ {
+ QgsDebugMsg("found subsymbol with invalid name: "+it.key());
+ delete it.value(); // we must delete it
+ continue; // some invalid syntax
+ }
+ QString symname = parts[1];
+ int symlayer = parts[2].toInt();
+
+ if (!symbols.contains(symname))
+ {
+ QgsDebugMsg("subsymbol references invalid symbol: " + symname);
+ delete it.value(); // we must delete it
+ continue;
+ }
+
+ QgsSymbolV2* sym = symbols[symname];
+ if (symlayer < 0 || symlayer >= sym->symbolLayerCount())
+ {
+ QgsDebugMsg("subsymbol references invalid symbol layer: "+ QString::number(symlayer));
+ delete it.value(); // we must delete it
+ continue;
+ }
+
+ // set subsymbol takes ownership
+ bool res = sym->symbolLayer(symlayer)->setSubSymbol( it.value() );
+ if (!res)
+ {
+ QgsDebugMsg("symbol layer refused subsymbol: " + it.key());
+ }
+
+
+ }
+
+ // now safely remove sub-symbol entries (they have been already deleted or the ownership was taken away)
+ for (int i = 0; i < subsymbols.count(); i++)
+ symbols.take(subsymbols[i]);
+
+ return symbols;
+}
+
+QDomElement QgsSymbolLayerV2Utils::saveSymbols(QgsSymbolV2Map& symbols, QDomDocument& doc)
+{
+ QDomElement symbolsElem = doc.createElement("symbols");
+
+ QMap<QString, QgsSymbolV2*> subSymbols;
+
+ // save symbols
+ for (QMap<QString, QgsSymbolV2*>::iterator its = symbols.begin(); its != symbols.end(); ++its)
+ {
+ QDomElement symEl = saveSymbol(its.key(), its.value(), doc, &subSymbols);
+ symbolsElem.appendChild(symEl);
+ }
+
+ // add subsymbols, don't allow subsymbols for them (to keep things simple)
+ for (QMap<QString, QgsSymbolV2*>::iterator itsub = subSymbols.begin(); itsub != subSymbols.end(); ++itsub)
+ {
+ QDomElement subsymEl = saveSymbol(itsub.key(), itsub.value(), doc);
+ symbolsElem.appendChild(subsymEl);
+ }
+
+ return symbolsElem;
+}
+
+void QgsSymbolLayerV2Utils::clearSymbolMap(QgsSymbolV2Map& symbols)
+{
+ foreach (QString name, symbols.keys())
+ delete symbols.value(name);
+ symbols.clear();
+}
Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.h
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.h 2009-11-01 23:45:49 UTC (rev 11880)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.h 2009-11-01 23:47:56 UTC (rev 11881)
@@ -6,13 +6,16 @@
#include <QMap>
#include <Qt>
-typedef QMap<QString, QString> QgsStringMap;
-
class QgsSymbolV2;
class QgsSymbolLayerV2;
class QgsVectorColorRampV2;
+typedef QMap<QString, QString> QgsStringMap;
+typedef QMap<QString, QgsSymbolV2* > QgsSymbolV2Map;
+
class QColor;
+class QDomDocument;
+class QDomElement;
class QIcon;
class QPixmap;
class QPointF;
@@ -45,6 +48,18 @@
static QIcon colorRampPreviewIcon(QgsVectorColorRampV2* ramp, QSize size);
static QPixmap colorRampPreviewPixmap(QgsVectorColorRampV2* ramp, QSize size);
+
+ static QgsSymbolV2* loadSymbol(QDomElement& element);
+ static QgsSymbolLayerV2* loadSymbolLayer(QDomElement& element);
+ static QDomElement saveSymbol(QString name, QgsSymbolV2* symbol, QDomDocument& doc, QgsSymbolV2Map* subSymbols = NULL);
+
+ static QgsStringMap parseProperties(QDomElement& element);
+ static void saveProperties(QgsStringMap props, QDomDocument& doc, QDomElement& element);
+
+ static QgsSymbolV2Map loadSymbols(QDomElement& element);
+ static QDomElement saveSymbols(QgsSymbolV2Map& symbols, QDomDocument& doc);
+
+ static void clearSymbolMap(QgsSymbolV2Map& symbols);
};
class QPolygonF;
More information about the QGIS-commit
mailing list