QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgssymbolslistwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssymbolslist.cpp
3  ---------------------
4  begin : June 2012
5  copyright : (C) 2012 by Arunmozhi
6  email : aruntheguy at gmail.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 
16 
17 #include "qgssymbolslistwidget.h"
18 
20 
21 #include "qgssymbolv2.h"
22 #include "qgsstylev2.h"
23 #include "qgssymbollayerv2utils.h"
24 
25 #include "qgsapplication.h"
26 
27 #include <QString>
28 #include <QStringList>
29 #include <QPainter>
30 #include <QIcon>
31 #include <QStandardItemModel>
32 #include <QColorDialog>
33 #include <QInputDialog>
34 #include <QMessageBox>
35 #include <QMenu>
36 
37 
38 QgsSymbolsListWidget::QgsSymbolsListWidget( QgsSymbolV2* symbol, QgsStyleV2* style, QMenu* menu, QWidget* parent ) : QWidget( parent )
39 {
40  mSymbol = symbol;
41  mStyle = style;
42 
43  setupUi( this );
44 
45  mSymbolUnitWidget->setUnits( QStringList() << tr( "Millimeter" ) << tr( "Map unit" ), 1 );
46 
47  btnAdvanced->hide(); // advanced button is hidden by default
48  if ( menu ) // show it if there is a menu pointer
49  {
50  btnAdvanced->setMenu( menu );
51  btnAdvanced->show();
52  }
53 
54  // populate the groups
55  groupsCombo->addItem( "" );
57  QStringList groups = style->smartgroupNames();
58  foreach ( QString group, groups )
59  {
60  groupsCombo->addItem( group, QVariant( "smart" ) );
61  }
62 
63  QStandardItemModel* model = new QStandardItemModel( viewSymbols );
64  viewSymbols->setModel( model );
65  connect( viewSymbols->selectionModel(), SIGNAL( currentChanged( const QModelIndex &, const QModelIndex & ) ), this, SLOT( setSymbolFromStyle( const QModelIndex & ) ) );
66 
67  connect( mStyle, SIGNAL( symbolSaved( QString, QgsSymbolV2* ) ), this, SLOT( symbolAddedToStyle( QString, QgsSymbolV2* ) ) );
68  connect( openStyleManagerButton, SIGNAL( pressed() ), this, SLOT( openStyleManager() ) );
69 
70  lblSymbolName->setText( "" );
72 
73  if ( mSymbol )
74  {
76  }
77 
78  // select correct page in stacked widget
79  // there's a correspondence between symbol type number and page numbering => exploit it!
80  stackedWidget->setCurrentIndex( symbol->type() );
81  connect( btnColor, SIGNAL( colorChanged( const QColor& ) ), this, SLOT( setSymbolColor( const QColor& ) ) );
82  connect( spinAngle, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerAngle( double ) ) );
83  connect( spinSize, SIGNAL( valueChanged( double ) ), this, SLOT( setMarkerSize( double ) ) );
84  connect( spinWidth, SIGNAL( valueChanged( double ) ), this, SLOT( setLineWidth( double ) ) );
85 
86  // Live color updates are not undoable to child symbol layers
87  btnColor->setAcceptLiveUpdates( false );
88  btnColor->setColorDialogOptions( QColorDialog::ShowAlphaChannel );
89 }
90 
91 void QgsSymbolsListWidget::populateGroups( QString parent, QString prepend )
92 {
93  QgsSymbolGroupMap groups = mStyle->childGroupNames( parent );
94  QgsSymbolGroupMap::const_iterator i = groups.constBegin();
95  while ( i != groups.constEnd() )
96  {
97  QString text;
98  if ( !prepend.isEmpty() )
99  {
100  text = prepend + "/" + i.value();
101  }
102  else
103  {
104  text = i.value();
105  }
106  groupsCombo->addItem( text, QVariant( i.key() ) );
107  populateGroups( i.value(), text );
108  ++i;
109  }
110 }
111 
113 {
115 }
116 
117 void QgsSymbolsListWidget::populateSymbols( QStringList names )
118 {
119  QSize previewSize = viewSymbols->iconSize();
120  QPixmap p( previewSize );
121  QPainter painter;
122 
123  QStandardItemModel* model = qobject_cast<QStandardItemModel*>( viewSymbols->model() );
124  if ( !model )
125  {
126  return;
127  }
128  model->clear();
129 
130  for ( int i = 0; i < names.count(); i++ )
131  {
132  QgsSymbolV2* s = mStyle->symbol( names[i] );
133  if ( s->type() != mSymbol->type() )
134  {
135  delete s;
136  continue;
137  }
138  QStandardItem* item = new QStandardItem( names[i] );
139  item->setData( names[i], Qt::UserRole ); //so we can load symbol with that name
140  item->setText( names[i] );
141  item->setToolTip( names[i] );
142  item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
143  // Set font to 10points to show reasonable text
144  QFont itemFont = item->font();
145  itemFont.setPointSize( 10 );
146  item->setFont( itemFont );
147  // create preview icon
148  QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( s, previewSize );
149  item->setIcon( icon );
150  // add to model
151  model->appendRow( item );
152  delete s;
153  }
154 }
155 
157 {
158  QgsStyleV2ManagerDialog dlg( mStyle, this );
159  dlg.exec();
160 
162 }
163 
164 void QgsSymbolsListWidget::setSymbolColor( const QColor& color )
165 {
166  mSymbol->setColor( color );
167  emit changed();
168 }
169 
171 {
172  QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
173  if ( markerSymbol->angle() == angle )
174  return;
175  markerSymbol->setAngle( angle );
176  emit changed();
177 }
178 
180 {
181  QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
182  if ( markerSymbol->size() == size )
183  return;
184  markerSymbol->setSize( size );
185  emit changed();
186 }
187 
189 {
190  QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol );
191  if ( lineSymbol->width() == width )
192  return;
193  lineSymbol->setWidth( width );
194  emit changed();
195 }
196 
198 {
199  Q_UNUSED( name );
200  Q_UNUSED( symbol );
202 }
203 
205 {
206  bool ok;
207  QString name = QInputDialog::getText( this, tr( "Symbol name" ),
208  tr( "Please enter name for the symbol:" ) , QLineEdit::Normal, tr( "New symbol" ), &ok );
209  if ( !ok || name.isEmpty() )
210  return;
211 
212  // check if there is no symbol with same name
213  if ( mStyle->symbolNames().contains( name ) )
214  {
215  int res = QMessageBox::warning( this, tr( "Save symbol" ),
216  tr( "Symbol with name '%1' already exists. Overwrite?" )
217  .arg( name ),
218  QMessageBox::Yes | QMessageBox::No );
219  if ( res != QMessageBox::Yes )
220  {
221  return;
222  }
223  }
224 
225  // add new symbol to style and re-populate the list
226  mStyle->addSymbol( name, mSymbol->clone() );
227 
228  // make sure the symbol is stored
229  mStyle->saveSymbol( name, mSymbol->clone(), 0, QStringList() );
231 }
232 
234 {
235  if ( mSymbol )
236  {
237  QgsSymbolV2::OutputUnit unit = static_cast<QgsSymbolV2::OutputUnit>( mSymbolUnitWidget->getUnit() );
238  mSymbol->setOutputUnit( unit );
239  mSymbol->setMapUnitScale( mSymbolUnitWidget->getMapUnitScale() );
240 
241  emit changed();
242  }
243 }
244 
246 {
247  if ( mSymbol )
248  {
249  double alpha = 1 - ( value / 255.0 );
250  mSymbol->setAlpha( alpha );
251  displayTransparency( alpha );
252  emit changed();
253  }
254 }
255 
257 {
258  double transparencyPercent = ( 1 - alpha ) * 100;
259  mTransparencyLabel->setText( tr( "Transparency %1%" ).arg(( int ) transparencyPercent ) );
260 }
261 
263 {
264  btnColor->blockSignals( true );
265  btnColor->setColor( mSymbol->color() );
266  btnColor->blockSignals( false );
267 }
268 
270 {
272 
273  if ( mSymbol->type() == QgsSymbolV2::Marker )
274  {
275  QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( mSymbol );
276  spinSize->setValue( markerSymbol->size() );
277  spinAngle->setValue( markerSymbol->angle() );
278  }
279  else if ( mSymbol->type() == QgsSymbolV2::Line )
280  {
281  QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( mSymbol );
282  spinWidth->setValue( lineSymbol->width() );
283  }
284 
285  mSymbolUnitWidget->blockSignals( true );
286  mSymbolUnitWidget->setUnit( mSymbol->outputUnit() );
287  mSymbolUnitWidget->setMapUnitScale( mSymbol->mapUnitScale() );
288  mSymbolUnitWidget->blockSignals( false );
289 
290  mTransparencySlider->blockSignals( true );
291  double transparency = 1 - mSymbol->alpha();
292  mTransparencySlider->setValue( transparency * 255 );
294  mTransparencySlider->blockSignals( false );
295 }
296 
298 {
299  QString symbolName = index.data( Qt::UserRole ).toString();
300  lblSymbolName->setText( symbolName );
301  // get new instance of symbol from style
302  QgsSymbolV2* s = mStyle->symbol( symbolName );
304  // remove all symbol layers from original symbol
305  while ( mSymbol->symbolLayerCount() )
307  // move all symbol layers to our symbol
308  while ( s->symbolLayerCount() )
309  {
310  QgsSymbolLayerV2* sl = s->takeSymbolLayer( 0 );
311  mSymbol->appendSymbolLayer( sl );
312  }
313  mSymbol->setAlpha( s->alpha() );
314  mSymbol->setOutputUnit( unit );
315  // delete the temporary symbol
316  delete s;
317 
319  emit changed();
320 }
321 
323 {
324  QStringList symbols;
325  QString text = groupsCombo->itemText( index );
326  // List all symbols when empty list item is selected
327  if ( text.isEmpty() )
328  {
329  symbols = mStyle->symbolNames();
330  }
331  else
332  {
333  int groupid;
334  if ( groupsCombo->itemData( index ).toString() == "smart" )
335  {
336  groupid = mStyle->smartgroupId( text );
337  symbols = mStyle->symbolsOfSmartgroup( QgsStyleV2::SymbolEntity, groupid );
338  }
339  else
340  {
341  groupid = groupsCombo->itemData( index ).toInt();
342  symbols = mStyle->symbolsOfGroup( QgsStyleV2::SymbolEntity, groupid );
343  }
344  }
345  populateSymbols( symbols );
346 }
347 
349 {
350  QStringList symbols = mStyle->findSymbols( QgsStyleV2::SymbolEntity, text );
351  populateSymbols( symbols );
352 }
void populateSymbols(QStringList symbols)
bool deleteSymbolLayer(int index)
delete symbol layer at specified index
static unsigned index
void symbolAddedToStyle(QString name, QgsSymbolV2 *symbol)
void on_mTransparencySlider_valueChanged(int value)
void setLineWidth(double width)
bool saveSymbol(QString name, QgsSymbolV2 *symbol, int groupid, QStringList tags)
add the symbol to the DB with the tags
Definition: qgsstylev2.cpp:107
void setSymbolFromStyle(const QModelIndex &index)
SymbolType type() const
Definition: qgssymbolv2.h:79
virtual QgsSymbolV2 * clone() const =0
QStringList symbolsOfGroup(StyleEntity type, int groupid)
returns the symbolnames of a given groupid
Definition: qgsstylev2.cpp:515
QgsMapUnitScale mapUnitScale() const
Definition: qgssymbolv2.cpp:84
void populateGroups(QString parent="", QString prepend="")
Recursive function to create the group tree in the widget.
QgsSymbolV2 * symbol(QString name)
return a NEW copy of symbol
Definition: qgsstylev2.cpp:166
void setMarkerSize(double size)
static QIcon icon(QString icon)
void on_groupsCombo_editTextChanged(const QString &text)
void setWidth(double width)
void setMapUnitScale(const QgsMapUnitScale &scale)
QgsSymbolGroupMap childGroupNames(QString parent="")
return a map of groupid and names for the given parent group
Definition: qgsstylev2.cpp:468
bool addSymbol(QString name, QgsSymbolV2 *symbol, bool update=false)
add symbol to style. takes symbol's ownership
Definition: qgsstylev2.cpp:83
void setColor(const QColor &color)
static QIcon symbolPreviewIcon(QgsSymbolV2 *symbol, QSize size)
bool appendSymbolLayer(QgsSymbolLayerV2 *layer)
append symbol layer at the end of the list
qreal alpha() const
Get alpha transparency 1 for opaque, 0 for invisible.
Definition: qgssymbolv2.h:125
void setAngle(double angle)
void setSymbolColor(const QColor &color)
int symbolLayerCount()
Definition: qgssymbolv2.h:85
void setSize(double size)
void setMarkerAngle(double angle)
QStringList symbolsOfSmartgroup(StyleEntity type, int id)
returns the symbols for the smartgroup
QStringList symbolNames()
return a list of names of symbols
Definition: qgsstylev2.cpp:182
QMap< int, QString > QgsSymbolGroupMap
Definition: qgsstylev2.h:35
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
void on_groupsCombo_currentIndexChanged(int index)
void displayTransparency(double alpha)
Displays alpha value as transparency in mTransparencyLabel.
QStringList smartgroupNames()
returns the smart groups list
QgsSymbolV2::OutputUnit outputUnit() const
Definition: qgssymbolv2.cpp:63
QgsSymbolsListWidget(QgsSymbolV2 *symbol, QgsStyleV2 *style, QMenu *menu, QWidget *parent)
QgsSymbolLayerV2 * takeSymbolLayer(int index)
remove symbol layer from the list and return pointer to it
QStringList findSymbols(StyleEntity type, QString qword)
return the names of the symbols which have a matching 'substring' in its defintion ...
Definition: qgsstylev2.cpp:752
double size
Definition: qgssvgcache.cpp:77
int smartgroupId(QString smartgroup)
return the DB id for the given smartgroup name
void setOutputUnit(QgsSymbolV2::OutputUnit u)
void setAlpha(qreal alpha)
Set alpha transparency 1 for opaque, 0 for invisible.
Definition: qgssymbolv2.h:127
QColor color() const
#define tr(sourceText)