1
/***************************************************************************
2
qgsuvaldialog.cpp - description
5
copyright : (C) 2004 by Marco Hugentobler
6
email : marco.hugentobler@autoform.ch
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
17
/* $Id: qgsuvaldialog.cpp,v 1.16.2.3 2004/12/12 23:28:23 mhugent Exp $ */
18
#include "qgsuvaldialog.h"
19
#include "qgsvectordataprovider.h"
20
#include "qgsvectorlayer.h"
21
#include "qgsdlgvectorlayerproperties.h"
22
#include "qgsfeature.h"
23
#include "qgsfeatureattribute.h"
24
#include "qgsuniquevalrenderer.h"
25
#include "qgssisydialog.h"
26
#include "qgssymbol.h"
27
#include "qgsrenderitem.h"
28
#include "qgsuniquevalrenderer.h"
29
#include <qwidgetstack.h>
31
#include <qcombobox.h>
35
QgsUValDialog::QgsUValDialog(QgsVectorLayer* vl): QgsUValDialogBase(), mVectorLayer(vl), sydialog(vl)
37
setSizeGripEnabled(true);
39
//find out the fields of mVectorLayer
40
QgsVectorDataProvider *provider;
41
if (provider = dynamic_cast<QgsVectorDataProvider *>(mVectorLayer->getDataProvider()))
43
std::vector < QgsField > &fields = provider->fields();
46
for (std::vector < QgsField >::iterator it = fields.begin(); it != fields.end(); ++it)
49
str = str.left(1).upper() + str.right(str.length() - 1); //make the first letter uppercase
50
mClassificationComboBox->insertItem(str);
55
qWarning("Warning, data provider is null in QgsUValDialog::QgsUValDialog");
59
QObject::connect(mClassificationComboBox, SIGNAL(activated(int)), this, SLOT(changeClassificationAttribute(int)));
60
QObject::connect(mClassBreakBox, SIGNAL(selectionChanged()), this, SLOT(changeCurrentValue()));
61
QObject::connect(&sydialog, SIGNAL(settingsChanged()), this, SLOT(applySymbologyChanges()));
62
mSymbolWidgetStack->addWidget(&sydialog);
63
mSymbolWidgetStack->raiseWidget(&sydialog);
65
//restore settings if unique value renderer was read from a project file
66
QgsUniqueValRenderer *renderer;
67
//initial settings, use the buffer of the propertiesDialog if possible. If this is not possible, use the renderer of the vectorlayer directly
68
if (mVectorLayer->propertiesDialog())
70
renderer = dynamic_cast < QgsUniqueValRenderer * >(mVectorLayer->propertiesDialog()->getBufferRenderer());
74
renderer = dynamic_cast < QgsUniqueValRenderer * >(mVectorLayer->renderer());
80
mClassBreakBox->clear();
81
std::list<int>::iterator iter=renderer->classificationAttributes().begin();
83
mClassificationComboBox->setCurrentItem(classattr);
85
if(renderer->items().size()==0)
87
changeClassificationAttribute(classattr);
90
//fill the items of the renderer into mValues
91
for(std::map<QString,QgsRenderItem*>::iterator iter=renderer->items().begin();iter!=renderer->items().end();++iter)
93
QgsRenderItem* item=(*iter).second;
94
QString itemvalue=item->value();
95
QgsSymbol* sym=new QgsSymbol();
96
sym->setPen(item->getSymbol()->pen());
97
sym->setBrush(item->getSymbol()->brush());
98
QgsRenderItem* ritem=new QgsRenderItem(sym,item->value(),item->label());
99
mValues.insert(std::make_pair(itemvalue,ritem));
100
mClassBreakBox->insertItem(itemvalue);
103
mClassBreakBox->setCurrentItem(0);
106
QgsUValDialog::~QgsUValDialog()
108
std::map<QString, QgsRenderItem *>::iterator myValueIterator = mValues.begin();
109
while ( myValueIterator != mValues.end() )
111
delete myValueIterator->second;
113
mValues.erase( myValueIterator );
115
myValueIterator = mValues.begin(); // since iterator invalidated due to
116
// erase(), reset to new first element
118
mClassBreakBox->setCurrentItem(0);
121
void QgsUValDialog::apply()
123
//font tor the legend text
124
QFont f("arial", 10, QFont::Normal);
127
int symbolheight = 15; //height of an area where a symbol is painted
128
int symbolwidth = 15; //width of an area where a symbol is painted
129
int rowheight = (fm.height() > symbolheight) ? fm.height() : symbolheight; //height of a row in the symbology part
135
int wordspace = 5; //space between graphics/word
139
//find out the width of the widest label and of the broadest value string
143
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
145
int currentlabelwidth=fm.width(it->second->label());
146
if(currentlabelwidth>maxlabelwidth)
148
maxlabelwidth=currentlabelwidth;
150
int currentvwidth=fm.width(it->second->value());
151
if(currentvwidth>maxvaluewidth)
153
//widestlu = string2;
154
maxvaluewidth=currentvwidth;
158
QgsUniqueValRenderer *renderer = dynamic_cast < QgsUniqueValRenderer * >(mVectorLayer->renderer());
160
//go through mValues and add the entries to the renderer
163
renderer->clearValues();
164
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
166
QgsSymbol* symbol=it->second->getSymbol();
167
QgsSymbol* newsymbol=new QgsSymbol();
168
newsymbol->setPen(symbol->pen());
169
newsymbol->setBrush(symbol->brush());
170
QgsRenderItem* ritem=new QgsRenderItem(newsymbol,it->first,it->second->label());
171
renderer->insertValue(it->first,ritem);
172
//find out the width of the string
173
valuewidth=fm.width(it->first);
174
if(valuewidth>widestvalue)
176
widestvalue=valuewidth;
179
renderer->setClassificationField(mClassificationComboBox->currentItem());
184
qWarning("Warning, typecast failed in qgsuvaldialog.cpp, l. 61");
188
//render the legend item
189
QPixmap *pix = mVectorLayer->legendPixmap();
191
QString field=mClassificationComboBox->currentText();
192
int fieldwidth=fm.width(field);
193
if(fieldwidth>widestvalue)
195
widestvalue=fieldwidth;
197
if (mVectorLayer->propertiesDialog())
199
name = mVectorLayer->propertiesDialog()->displayName();
205
int namewidth=fm.width(name);
207
if(namewidth>widestvalue)
209
if(namewidth>(symbolwidth+wordspace+widestvalue+maxlabelwidth))
211
pixwidth = leftspace+wordspace+namewidth+rightspace;
215
pixwidth = leftspace+2*wordspace+symbolwidth+maxlabelwidth+widestvalue+rightspace;
220
pixwidth = leftspace+2*wordspace+symbolwidth+widestvalue+maxlabelwidth+rightspace;
223
int pixheight = topspace+2*fm.height()+rowspace+(rowheight+rowspace)*mValues.size()+bottomspace;
225
pix->resize(pixwidth,pixheight);
230
//draw the layer name and the name of the classification field into the pixmap
231
p.drawText(leftspace, topspace + fm.height(), name);
232
p.drawText(leftspace, topspace + 2 * fm.height(), field);
233
int intermheight=topspace+2*fm.height()+rowspace;
236
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
238
QgsSymbol* sym=it->second->getSymbol();
239
p.setPen(sym->pen());
240
p.setBrush(sym->brush());
242
if (mVectorLayer->vectorType() == QGis::Polygon)
244
p.drawRect(leftspace,intermheight+row*(rowheight+rowspace)+rowheight-symbolheight,symbolwidth,symbolheight);
246
else if (mVectorLayer->vectorType() == QGis::Line)
248
p.drawLine(leftspace,intermheight+row*(rowheight+rowspace)+rowheight-symbolheight,leftspace+symbolwidth,intermheight+row*(rowheight+rowspace)+rowheight);
250
else if (mVectorLayer->vectorType() == QGis::Point)
252
p.drawRect(leftspace + symbolwidth / 2, intermheight + (int) ((rowheight+rowspace) * (row + 0.5)),5,5);
255
p.drawText(leftspace+symbolwidth+wordspace, intermheight+row*(rowheight+rowspace)+rowheight, it->first);
256
p.drawText(leftspace+symbolwidth+2*wordspace+widestvalue, intermheight+row*(rowheight+rowspace)+rowheight, it->second->label());
262
mVectorLayer->updateItemPixmap();
263
mVectorLayer->triggerRepaint();
266
void QgsUValDialog::changeClassificationAttribute(int nr)
269
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
275
QgsVectorDataProvider *provider = dynamic_cast<QgsVectorDataProvider *>(mVectorLayer->getDataProvider());
279
std::list<int> attlist;
280
attlist.push_back(nr);
281
std::vector < QgsFeatureAttribute > vec;
283
QgsRenderItem* ritemptr;
288
//go through all the features and insert their value into the map and into mClassBreakBox
289
mClassBreakBox->clear();
290
while((f=provider->getNextFeature(attlist)))
292
vec = f->attributeMap();
293
value=vec[0].fieldValue();
295
if(mValues.find(value)==mValues.end())
297
symbol=new QgsSymbol();
298
ritemptr=new QgsRenderItem(symbol,"","");
299
mValues.insert(std::make_pair(value,ritemptr));
304
//set symbology for all QgsSiSyDialogs
309
for(std::map<QString,QgsRenderItem*>::iterator it=mValues.begin();it!=mValues.end();++it)
312
//color range from blue to red
313
frac=number/mValues.size();
314
thecolor.setRgb(int(255*frac),0,int(255-(255*frac)));
315
mClassBreakBox->insertItem(it->first);
316
QgsSymbol* sym=it->second->getSymbol();
319
if(mVectorLayer->vectorType() == QGis::Line)
321
pen.setColor(thecolor);
322
pen.setStyle(Qt::SolidLine);
327
brush.setColor(thecolor);
328
brush.setStyle(Qt::SolidPattern);
329
pen.setColor(Qt::black);
330
pen.setStyle(Qt::SolidLine);
334
sym->setBrush(brush);
337
mClassBreakBox->setCurrentItem(0);
340
void QgsUValDialog::changeCurrentValue()
342
sydialog.blockSignals(true);//block signal to prevent sydialog from changing the current QgsRenderItem
343
QListBoxItem* item=mClassBreakBox->selectedItem();
344
QString value=item->text();
345
std::map<QString,QgsRenderItem*>::iterator it=mValues.find(value);
346
if(it!=mValues.end())
348
QPen& pen=it->second->getSymbol()->pen();
349
QBrush& brush=it->second->getSymbol()->brush();
350
QColor fcolor(brush.color().red(),brush.color().green(),brush.color().blue());
351
QColor ocolor(pen.color().red(),pen.color().green(),pen.color().blue());
352
sydialog.setFillColor(fcolor);
353
sydialog.setFillStyle(brush.style());
354
sydialog.setOutlineColor(ocolor);
355
sydialog.setOutlineStyle(pen.style());
356
sydialog.setOutlineWidth(pen.width());
357
sydialog.setLabel(it->second->label());
363
sydialog.blockSignals(false);
366
void QgsUValDialog::applySymbologyChanges()
368
QListBoxItem* item=mClassBreakBox->selectedItem();
369
QString value=item->text();
370
std::map<QString,QgsRenderItem*>::iterator it=mValues.find(value);
371
if(it!=mValues.end())
373
QPen& pen=it->second->getSymbol()->pen();
374
QBrush& brush=it->second->getSymbol()->brush();
375
pen.setWidth(sydialog.getOutlineWidth());
376
pen.setColor(sydialog.getOutlineColor());
377
pen.setStyle(sydialog.getOutlineStyle());
378
brush.setColor(sydialog.getFillColor());
379
brush.setStyle(sydialog.getFillStyle());
380
it->second->setLabel(sydialog.label());