QGIS API Documentation  2.9.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
qgsrendererv2widget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrendererv2widget.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 #include "qgsrendererv2widget.h"
16 #include "qgssymbolv2.h"
17 #include "qgsvectorlayer.h"
18 #include "qgscolordialog.h"
21 
22 #include <QMessageBox>
23 #include <QInputDialog>
24 #include <QMenu>
25 
27  : QWidget(), mLayer( layer ), mStyle( style )
28 {
29  contextMenu = new QMenu( "Renderer Options " );
30 
31  mCopyAction = contextMenu->addAction( tr( "Copy" ), this, SLOT( copy() ) );
32  mCopyAction->setShortcut( QKeySequence( QKeySequence::Copy ) );
33  mPasteAction = contextMenu->addAction( tr( "Paste" ), this, SLOT( paste() ) );
34  mPasteAction->setShortcut( QKeySequence( QKeySequence::Paste ) );
35 
36  contextMenu->addSeparator();
37  contextMenu->addAction( tr( "Change color" ), this, SLOT( changeSymbolColor() ) );
38  contextMenu->addAction( tr( "Change transparency" ), this, SLOT( changeSymbolTransparency() ) );
39  contextMenu->addAction( tr( "Change output unit" ), this, SLOT( changeSymbolUnit() ) );
40 
41  if ( mLayer && mLayer->geometryType() == QGis::Line )
42  {
43  contextMenu->addAction( tr( "Change width" ), this, SLOT( changeSymbolWidth() ) );
44  }
45  else if ( mLayer && mLayer->geometryType() == QGis::Point )
46  {
47  contextMenu->addAction( tr( "Change size" ), this, SLOT( changeSymbolSize() ) );
48  }
49 }
50 
52 {
53  contextMenu->exec( QCursor::pos() );
54 }
55 
57 {
58  QList<QgsSymbolV2*> symbolList = selectedSymbols();
59  if ( symbolList.size() < 1 )
60  {
61  return;
62  }
63 
64  QColor color = QgsColorDialogV2::getColor( symbolList.at( 0 )->color(), this, "Change Symbol Color", true );
65  if ( color.isValid() )
66  {
67  QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
68  for ( ; symbolIt != symbolList.end(); ++symbolIt )
69  {
70  ( *symbolIt )->setColor( color );
71  }
73  }
74 }
75 
77 {
78  QList<QgsSymbolV2*> symbolList = selectedSymbols();
79  if ( symbolList.size() < 1 )
80  {
81  return;
82  }
83 
84  bool ok;
85  double oldTransparency = ( 1 - symbolList.at( 0 )->alpha() ) * 100; // convert to percents
86  double transparency = QInputDialog::getDouble( this, tr( "Transparency" ), tr( "Change symbol transparency [%]" ), oldTransparency, 0.0, 100.0, 0, &ok );
87  if ( ok )
88  {
89  QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
90  for ( ; symbolIt != symbolList.end(); ++symbolIt )
91  {
92  ( *symbolIt )->setAlpha( 1 - transparency / 100 );
93  }
95  }
96 }
97 
99 {
100  QList<QgsSymbolV2*> symbolList = selectedSymbols();
101  if ( symbolList.size() < 1 )
102  {
103  return;
104  }
105 
106  bool ok;
107  int currentUnit = ( symbolList.at( 0 )->outputUnit() == QgsSymbolV2::MM ) ? 0 : 1;
108  QString item = QInputDialog::getItem( this, tr( "Symbol unit" ), tr( "Select symbol unit" ), QStringList() << tr( "Millimeter" ) << tr( "Map unit" ), currentUnit, false, &ok );
109  if ( ok )
110  {
111  QgsSymbolV2::OutputUnit unit = ( item.compare( tr( "Millimeter" ) ) == 0 ) ? QgsSymbolV2::MM : QgsSymbolV2::MapUnit;
112 
113  QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
114  for ( ; symbolIt != symbolList.end(); ++symbolIt )
115  {
116  ( *symbolIt )->setOutputUnit( unit );
117  }
119  }
120 }
121 
123 {
124  QList<QgsSymbolV2*> symbolList = selectedSymbols();
125  if ( symbolList.size() < 1 )
126  {
127  return;
128  }
129 
130  bool ok;
131  QgsLineSymbolV2* line = dynamic_cast<QgsLineSymbolV2*>( symbolList.at( 0 ) ) ;
132  double width = QInputDialog::getDouble( this, tr( "Width" ), tr( "Change symbol width" ), line ? line->width() : 0.0 , 0.0, 999999, 1, &ok );
133  if ( ok )
134  {
135  QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
136  for ( ; symbolIt != symbolList.end(); ++symbolIt )
137  {
138  line = dynamic_cast<QgsLineSymbolV2*>( *symbolIt );
139  if ( line )
140  line->setWidth( width );
141  }
143  }
144 }
145 
147 {
148  QList<QgsSymbolV2*> symbolList = selectedSymbols();
149  if ( symbolList.size() < 1 )
150  {
151  return;
152  }
153 
154  bool ok;
155  QgsMarkerSymbolV2* marker = dynamic_cast<QgsMarkerSymbolV2*>( symbolList.at( 0 ) );
156 
157  double size = QInputDialog::getDouble( this, tr( "Size" ), tr( "Change symbol size" ), marker ? marker->size() : 0.0 , 0.0, 999999, 1, &ok );
158  if ( ok )
159  {
160  QList<QgsSymbolV2*>::iterator symbolIt = symbolList.begin();
161  for ( ; symbolIt != symbolList.end(); ++symbolIt )
162  {
163  marker = dynamic_cast<QgsMarkerSymbolV2*>( *symbolIt );
164  if ( marker )
165  marker->setSize( size );
166  }
168  }
169 }
170 
172 {
173  QgsLegendSymbolList symbols = r->legendSymbolItems();
174 
175  QgsSymbolLevelsV2Dialog dlg( symbols, r->usingSymbolLevels(), this );
176 
177  if ( dlg.exec() )
178  {
179  r->setUsingSymbolLevels( dlg.usingLevels() );
180  }
181 }
182 
183 
185 
186 #include "qgsfield.h"
187 
188 QgsRendererV2DataDefinedMenus::QgsRendererV2DataDefinedMenus( QMenu* menu, QgsVectorLayer* layer, QString rotationField, QString sizeScaleField, QgsSymbolV2::ScaleMethod scaleMethod )
189  : QObject( menu ), mLayer( layer )
190 {
191  mRotationMenu = new QMenu( tr( "Rotation field" ) );
192  mSizeScaleMenu = new QMenu( tr( "Size scale field" ) );
193 
194  mRotationAttributeActionGroup = new QActionGroup( mRotationMenu );
195  mSizeAttributeActionGroup = new QActionGroup( mSizeScaleMenu );
196  mSizeMethodActionGroup = new QActionGroup( mSizeScaleMenu );
197 
200 
201  mSizeScaleMenu->addSeparator();
202 
203  QAction* aScaleByArea = new QAction( tr( "Scale area" ), mSizeMethodActionGroup );
204  QAction* aScaleByDiameter = new QAction( tr( "Scale diameter" ), mSizeMethodActionGroup );
205 
206  aScaleByArea->setCheckable( true );
207  aScaleByDiameter->setCheckable( true );
208 
209  if ( scaleMethod == QgsSymbolV2::ScaleDiameter )
210  {
211  aScaleByDiameter->setChecked( true );
212  }
213  else
214  {
215  aScaleByArea->setChecked( true );
216  }
217 
218  mSizeScaleMenu->addActions( mSizeMethodActionGroup->actions() );
219 
220  menu->addMenu( mRotationMenu );
221  menu->addMenu( mSizeScaleMenu );
222 
223  connect( mSizeMethodActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( scaleMethodSelected( QAction* ) ) );
224  connect( mRotationAttributeActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( rotationFieldSelected( QAction* ) ) );
225  connect( mSizeAttributeActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( sizeScaleFieldSelected( QAction* ) ) );
226 }
227 
229 {
230  delete mSizeMethodActionGroup;
233  delete mRotationMenu;
234  delete mSizeScaleMenu;
235 }
236 
237 void QgsRendererV2DataDefinedMenus::populateMenu( QMenu* menu, QString fieldName, QActionGroup *actionGroup )
238 {
239  QAction* aExpr = new QAction( tr( "- expression -" ), actionGroup );
240  aExpr->setCheckable( true );
241  menu->addAction( aExpr );
242  menu->addSeparator();
243  QAction* aNo = new QAction( tr( "- no field -" ), actionGroup );
244  aNo->setCheckable( true );
245  menu->addAction( aNo );
246  menu->addSeparator();
247 
248  bool hasField = false;
249  const QgsFields & flds = mLayer->pendingFields();
250  for ( int idx = 0; idx < flds.count(); ++idx )
251  {
252  const QgsField& fld = flds[idx];
253  if ( fld.type() == QVariant::Int || fld.type() == QVariant::Double )
254  {
255  QAction* a = new QAction( fld.name(), actionGroup );
256  a->setCheckable( true );
257  if ( fieldName == fld.name() )
258  {
259  a->setChecked( true );
260  hasField = true;
261  }
262  menu->addAction( a );
263  }
264  }
265 
266  if ( !hasField )
267  {
268  if ( fieldName.isEmpty() )
269  {
270  aNo->setChecked( true );
271  }
272  else
273  {
274  aExpr->setChecked( true );
275  aExpr->setText( tr( "- expression -" ) + fieldName );
276  }
277  }
278 
279 }
280 
282 {
283  if ( a == NULL )
284  return;
285 
286  QString fldName = a->text();
287 #if 0
288  updateMenu( mRotationAttributeActionGroup, fldName );
289 #endif
290  if ( fldName == tr( "- no field -" ) )
291  {
292  fldName = QString();
293  }
294  else if ( fldName.startsWith( tr( "- expression -" ) ) )
295  {
296  QString expr( fldName );
297  expr.replace( 0, tr( "- expression -" ).length(), "" );
298  QgsExpressionBuilderDialog dialog( mLayer, expr );
299  if ( !dialog.exec() ) return;
300  fldName = dialog.expressionText();
301  Q_ASSERT( !QgsExpression( fldName ).hasParserError() );
302  a->setText( tr( "- expression -" ) + fldName );
303  }
304 
305  emit rotationFieldChanged( fldName );
306 }
307 
309 {
310  if ( a == NULL )
311  return;
312 
313  QString fldName = a->text();
314 #if 0
315  updateMenu( mSizeAttributeActionGroup, fldName );
316 #endif
317  if ( fldName == tr( "- no field -" ) )
318  {
319  fldName = QString();
320  }
321  else if ( fldName.startsWith( tr( "- expression -" ) ) )
322  {
323  QString expr( fldName );
324  expr.replace( 0, tr( "- expression -" ).length(), "" );
325  QgsExpressionBuilderDialog dialog( mLayer, expr );
326  if ( !dialog.exec() ) return;
327  fldName = dialog.expressionText();
328  Q_ASSERT( !QgsExpression( fldName ).hasParserError() );
329  a->setText( tr( "- expression -" ) + fldName );
330  }
331 
332  emit sizeScaleFieldChanged( fldName );
333 }
334 
336 {
337  if ( a == NULL )
338  return;
339 
340  if ( a->text() == tr( "Scale area" ) )
341  {
343  }
344  else if ( a->text() == tr( "Scale diameter" ) )
345  {
347  }
348 }
349 #if 0 // MK: is there any reason for this?
350 void QgsRendererV2DataDefinedMenus::updateMenu( QActionGroup* actionGroup, QString fieldName )
351 {
352  foreach ( QAction* a, actionGroup->actions() )
353  {
354  a->setChecked( a->text() == fieldName );
355  }
356 }
357 #endif
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:86
void showSymbolLevelsDialog(QgsFeatureRendererV2 *r)
show a dialog with renderer's symbol level settings
const QString & name() const
Gets the name of the field.
Definition: qgsfield.cpp:59
virtual QList< QgsSymbolV2 * > selectedSymbols()
Subclasses may provide the capability of changing multiple symbols at once by implementing the follow...
void changeSymbolTransparency()
Change opacity of selected symbols.
void changeSymbolSize()
Change marker sizes of selected symbols.
void contextMenuViewCategories(const QPoint &p)
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
return a list of item text / symbol
Container of fields for a vector layer.
Definition: qgsfield.h:172
void populateMenu(QMenu *menu, QString fieldName, QActionGroup *actionGroup)
void changeSymbolWidth()
Change line widths of selected symbols.
void setWidth(double width)
QgsVectorLayer * mLayer
void changeSymbolUnit()
Change units mm/map units of selected symbols.
void rotationFieldChanged(QString fldName)
void setSize(double size)
void changeSymbolColor()
Change color of selected symbols.
int count() const
Return number of items.
Definition: qgsfield.h:214
QGis::GeometryType geometryType() const
Returns point, line or polygon.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:33
void scaleMethodChanged(QgsSymbolV2::ScaleMethod scaleMethod)
QgsRendererV2Widget(QgsVectorLayer *layer, QgsStyleV2 *style)
void setUsingSymbolLevels(bool usingSymbolLevels)
static QColor getColor(const QColor &initialColor, QWidget *parent, const QString &title=QString(), const bool allowAlpha=false)
Return a color selection from a color dialog.
void sizeScaleFieldChanged(QString fldName)
bool usingSymbolLevels() const
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
virtual void refreshSymbolView()
QgsRendererV2DataDefinedMenus(QMenu *menu, QgsVectorLayer *layer, QString rotationField, QString sizeScaleField, QgsSymbolV2::ScaleMethod scaleMethod)
Represents a vector layer which manages a vector based data sets.
double size
Definition: qgssvgcache.cpp:77
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
Definition: qgsrendererv2.h:43
A generic dialog for building expression strings.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:64
#define tr(sourceText)