widgets/se/StyleExplorer.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/qt/widgets/se/StyleExplorer.cpp
22 
23  \brief A widget used to explore a style.
24 */
25 
26 // TerraLib
27 #include "../../../se/Style.h"
28 #include "../../../se/Symbolizer.h"
29 #include "../../../se/Rule.h"
30 #include "StyleExplorer.h"
31 #include "SymbologyPreview.h"
32 
33 // STL
34 #include <cassert>
35 #include <vector>
36 
38  : QTreeWidget(parent),
39  m_style(nullptr)
40 {
41  // Setup
42  setAlternatingRowColors(true);
43  setSelectionMode(QAbstractItemView::SingleSelection);
44  setHeaderHidden(true);
45  setIconSize(QSize(16, 16));
46 
47  m_symbolizerNames["PolygonSymbolizer"] = tr("Polygon Symbol");
48  m_symbolizerNames["LineSymbolizer"] = tr("Line Symbol");
49  m_symbolizerNames["PointSymbolizer"] = tr("Point Symbol");
50  m_symbolizerNames["RasterSymbolizer"] = tr("Raster Symbol");
51  m_symbolizerNames["TextSymbolizer"] = tr("Text Symbol");
52 
53  // Signals & slots
54  connect(this, SIGNAL(itemClicked(QTreeWidgetItem*, int)), SLOT(onItemClicked(QTreeWidgetItem*, int)));
55 }
56 
58 
60 {
61  m_style = style;
62 
63  updateStyleTree(currentRule);
64 }
65 
67 {
68  clear();
69 
70  if(!m_style)
71  return;
72 
73  QTreeWidgetItem* root = new QTreeWidgetItem(this, STYLE);
74  root->setText(0, tr("Style"));
75 
76  std::size_t nRules = m_style->getRules().size();
77 
78  QTreeWidgetItem* currentSymbolItem = nullptr;
79 
80  for(std::size_t i = 0; i < nRules; ++i) // for each rule
81  {
82  const te::se::Rule* rule = m_style->getRule(i);
83  const std::vector<te::se::Symbolizer*>& symbs = rule->getSymbolizers();
84 
85  QTreeWidgetItem* ruleItem = new QTreeWidgetItem(root, RULE);
86 
87  QString ruleTitle = tr("Rule");
88  if (rule->getName())
89  {
90  std::string ruleName = *rule->getName();
91  ruleTitle.append(" " + QString(ruleName.c_str()));
92  }
93 
94  ruleItem->setText(0, ruleTitle);
95  ruleItem->setData(0, Qt::UserRole, (int)i);
96  ruleItem->setIcon(0, QIcon(SymbologyPreview::build(symbs, iconSize())));
97 
98  for(std::size_t j = 0; j < symbs.size(); ++j) // for each symbolizer
99  {
100  QTreeWidgetItem* symbItem = new QTreeWidgetItem(ruleItem, SYMBOLIZER);
101 
102  QString symbTypeName = tr("Unknown Symbol");
103 
104  std::map<QString, QString>::iterator it = m_symbolizerNames.find(symbs[j]->getType().c_str());
105  if(it != m_symbolizerNames.end())
106  symbTypeName = it->second;
107 
108  QString count;
109  count.setNum(j);
110 
111  symbTypeName.append(" " + count);
112 
113  symbItem->setText(0, symbTypeName);
114  symbItem->setData(0, Qt::UserRole, static_cast<int>(j));
115  symbItem->setIcon(0, QIcon(SymbologyPreview::build(symbs[j], iconSize())));
116 
117  if (currentRule)
118  {
119  if (rule == currentRule)
120  {
121  if (j == 0)
122  currentSymbolItem = symbItem;
123  }
124  }
125  else
126  {
127  if (i == 0 && j == 0)
128  currentSymbolItem = symbItem;
129  }
130  }
131  }
132 
133  if (currentSymbolItem)
134  {
135  setCurrentItem(currentSymbolItem);
136  symbolizerClicked(getSymbolizer(currentSymbolItem));
137  }
138 
139  expandAll();
140 }
141 
143 {
144  QTreeWidgetItem* selectedItem = getSelectedItem();
145 
146  if(selectedItem == nullptr)
147  return nullptr;
148 
149  if(selectedItem->type() == RULE)
150  return getRule(selectedItem);
151 
152  if(selectedItem->type() == SYMBOLIZER)
153  return getRule(selectedItem->parent());
154 
155  return nullptr;
156 }
157 
159 {
160  QTreeWidgetItem* selectedItem = getSelectedItem();
161 
162  if(selectedItem != nullptr && selectedItem->type() == SYMBOLIZER)
163  return getSymbolizer(selectedItem);
164 
165  return nullptr;
166 }
167 
169 {
170  QTreeWidgetItem* currentItem = getSelectedItem();
171 
172  if(currentItem == nullptr || currentItem->type() != SYMBOLIZER)
173  return;
174 
175  // Gets the symbolizer index
176  std::size_t index = currentItem->data(0, Qt::UserRole).toUInt();
177 
178  // Checks if the current symbolizer is the first
179  if(index == 0)
180  return;
181 
182  te::se::Rule* rule = getCurrentRule();
183  assert(rule);
184 
185  swapSymbolizers(rule, static_cast<int>(index), static_cast<int>(index - 1));
186 
187  updateStyleTree();
188 }
189 
191 {
192  QTreeWidgetItem* currentItem = getSelectedItem();
193 
194  if(currentItem == nullptr || currentItem->type() != SYMBOLIZER)
195  return;
196 
197  te::se::Rule* rule = getCurrentRule();
198  assert(rule);
199 
200  // Gets the symbolizer index
201  std::size_t index = currentItem->data(0, Qt::UserRole).toUInt();
202 
203  // Checks if the current symbolizer is the last
204  if(index == rule->getSymbolizers().size() - 1)
205  return;
206 
207  swapSymbolizers(rule, static_cast<int>(index), static_cast<int>(index + 1));
208 
209  updateStyleTree();
210 }
211 
213 {
214  setIconSize(QSize(size, size));
215 
216  updateStyleTree();
217 }
218 
220 {
221  emit styleImported(style, isVisual);
222 }
223 
225 {
226  QTreeWidgetItem* symbolizerItem = getSelectedItem();
227 
228  // Updating item
229  symbolizerItem->setIcon(0, QIcon(SymbologyPreview::build(symb, iconSize())));
230 
231  te::se::Rule* rule = getCurrentRule();
232  QTreeWidgetItem* ruleItem = symbolizerItem->parent();
233 
234  if(rule && ruleItem)
235  {
236  const std::vector<te::se::Symbolizer*>& symbs = rule->getSymbolizers();
237  ruleItem->setIcon(0, QIcon(SymbologyPreview::build(symbs, iconSize())));
238  }
239 }
240 
242 {
243  assert(item && item->type() == RULE);
244 
245  // Gets the Rule index
246  std::size_t index = item->data(0, Qt::UserRole).toUInt();
247  assert((index >= 0) && (index < m_style->getRules().size()));
248 
249  return m_style->getRule(index);
250 }
251 
253 {
254  assert(item && item->type() == SYMBOLIZER);
255 
256  // Gets the rule associated with the symbolizer
257  QTreeWidgetItem* parent = item->parent();
258  assert(parent);
259 
260  const te::se::Rule* rule = getRule(parent);
261  assert(rule);
262 
263  // Gets the rule symbolizers
264  const std::vector<te::se::Symbolizer*>& symbs = rule->getSymbolizers();
265 
266  // Gets the Symbolizer index
267  std::size_t index = item->data(0, Qt::UserRole).toUInt();
268  assert(index >= 0 && index < symbs.size());
269 
270  return symbs[index];
271 }
272 
274 {
275  QList<QTreeWidgetItem*> selected = selectedItems();
276 
277  if(selected.empty())
278  return nullptr;
279 
280  return selected.at(0);
281 }
282 
283 void te::qt::widgets::StyleExplorer::swapSymbolizers(te::se::Rule* r, int indexFirst, int indexSecond)
284 {
285  assert(r);
286 
287  // Copy the symbolizers
288  te::se::Symbolizer* first = r->getSymbolizer(indexFirst)->clone();
289  te::se::Symbolizer* second = r->getSymbolizer(indexSecond)->clone();
290 
291  // Swap symbolizers
292  r->setSymbolizer(indexFirst, second);
293  r->setSymbolizer(indexSecond, first);
294 }
295 
297 {
298  switch(item->type())
299  {
300  case STYLE:
301  break;
302 
303  case RULE:
304  emit ruleClicked(getRule(item));
305  break;
306 
307  case SYMBOLIZER:
308  emit symbolizerClicked(getSymbolizer(item));
309  break;
310  }
311 }
void onSymbolizerChanged(te::se::Symbolizer *symb)
The Style defines the styling that is to be applied to a geographic dataset (vector geometries or cov...
Definition: Style.h:65
te::se::Symbolizer * getSymbolizer(QTreeWidgetItem *item)
Auxiliary internal method to retrieve a symbolizer from a QTreeWidgetItem.
void setStyle(te::se::Style *style, te::se::Rule *currentRule=0)
Sets a style element to this widget.
A Symbolizer describes how a feature is to appear on a map.
Definition: Symbolizer.h:80
void importStyle(te::se::Style *style, bool isVisual)
void swapSymbolizers(te::se::Rule *r, int indexFirst, int indexSecond)
void updateStyleTree(te::se::Rule *currentRule=0)
This method updates the Style Explorer.
Static class used to generate preview of Symbology elements.
te::se::Style * m_style
Style element that will be explored by this widget.
QTreeWidgetItem * getSelectedItem() const
Auxiliary internal method to retrieve the selected item on Style Explorer.
Rule * getRule(std::size_t i) const
Definition: Style.cpp:105
const std::vector< Rule * > & getRules() const
Definition: Style.cpp:94
A widget used to explore a style.
te::se::Rule * getRule(QTreeWidgetItem *item)
Auxiliary internal method to retrieve a rule from a QTreeWidgetItem.
std::map< QString, QString > m_symbolizerNames
A map of symbolizers names to user interface names.
void onItemClicked(QTreeWidgetItem *item, int column)
StyleExplorer(QWidget *parent=0)
Constructs a style explorer widget which is a child of parent.
void symbolizerClicked(te::se::Symbolizer *symb)
const std::vector< Symbolizer * > & getSymbolizers() const
Definition: Rule.cpp:158
te::se::Symbolizer * getCurrentSymbolizer()
Gets the current symbolizer.
A Rule is used to attach property/scale conditions to and group the individual symbols used for rende...
Definition: Rule.h:76
te::se::Rule * getCurrentRule()
Gets the current rule.
void ruleClicked(te::se::Rule *rule)
virtual Symbolizer * clone() const =0
It creates a new copy of this object.
void setSymbolizer(std::size_t i, Symbolizer *s)
Definition: Rule.cpp:144
void styleImported(te::se::Style *style, bool isVisual)
const Symbolizer * getSymbolizer(std::size_t i) const
Definition: Rule.cpp:163
static QPixmap build(const te::se::Symbolizer *symb, const QSize &size)
Generates the preview of given symbolizer element.
const std::string * getName() const
Definition: Rule.cpp:64