1
/***************************************************************************
2
qgsgramadialog.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
***************************************************************************/
19
#include "qgsgramadialog.h"
20
#include "qgsgramaextensionwidget.h"
21
#include "qgsmarkersymbol.h"
22
#include "qgsvectorlayer.h"
23
#include "qgsvectordataprovider.h"
24
#include "qgsgraduatedmarenderer.h"
25
#include "qgsdlgvectorlayerproperties.h"
26
#include "qgslegenditem.h"
27
#include "qgssvgcache.h"
28
#include <qcombobox.h>
31
#include <qpushbutton.h>
34
QgsGraMaDialog::QgsGraMaDialog(QgsVectorLayer* layer): QgsGraMaDialogBase(), ext(0), mVectorLayer(layer)
37
qWarning("constructor QgsGraSyDialog");
40
setOrientation(Qt::Vertical);
41
setSizeGripEnabled(true);
43
//find out the numerical fields of mVectorLayer
44
QgsVectorDataProvider *provider;
45
if (provider = dynamic_cast<QgsVectorDataProvider *>(mVectorLayer->getDataProvider()))
47
std::vector < QgsField > &fields = provider->fields();
51
for (std::vector < QgsField >::iterator it = fields.begin(); it != fields.end(); ++it)
53
QString type = (*it).type();
54
if (type != "String" && type != "varchar" && type != "geometry")
57
str = str.left(1).upper() + str.right(str.length() - 1); //make the first letter uppercase
58
mClassificationComboBox->insertItem(str);
59
mFieldMap.insert(std::make_pair(str, fieldnumber));
66
qWarning("Warning, data provider is null in QgsGraSyDialog::QgsGraSyDialog(...)");
70
mModeComboBox->insertItem("Empty");
71
mModeComboBox->insertItem("Equal Interval");
73
//restore the correct settings
74
QgsGraduatedMaRenderer *renderer;
76
//initial settings, use the buffer of the propertiesDialog if possible. If this is not possible, use the renderer of the vectorlayer directly
77
if (mVectorLayer->propertiesDialog())
79
renderer = dynamic_cast < QgsGraduatedMaRenderer * >(layer->propertiesDialog()->getBufferRenderer());
83
renderer = dynamic_cast < QgsGraduatedMaRenderer * >(layer->renderer());
86
std::list < QgsRangeRenderItem * >list;
90
list = renderer->items();
91
ext = new QgsGraMaExtensionWidget(this, renderer->classificationField(), QgsGraSyDialog::EMPTY, list.size(), mVectorLayer);
94
mClassificationComboBox->setCurrentItem(renderer->classificationField());
96
//set the right colors and texts to the widgets
98
for (std::list < QgsRangeRenderItem * >::iterator it = list.begin(); it != list.end(); ++it)
100
((QLineEdit *) (ext->getWidget(0, number)))->setText((*it)->value());
101
((QLineEdit *) ext->getWidget(1, number))->setText((*it)->upper_value());
102
((QLineEdit *) ext->getWidget(2, number))->setText((*it)->label());
103
((QPushButton *) ext->getWidget(3, number))->setName(((QgsMarkerSymbol*)((*it)->getSymbol()))->picture());
104
((QLineEdit *) ext->getWidget(4, number))->setText(QString::number(((QgsMarkerSymbol*)((*it)->getSymbol()))->scaleFactor(),'f',2));
109
mNumberOfClassesSpinbox->setValue(list.size());
110
QgsGraMaDialogBaseLayout->addMultiCellWidget(ext, 5, 5, 0, 3);
113
//do the necessary signal/slot connections
114
QObject::connect(mNumberOfClassesSpinbox, SIGNAL(valueChanged(int)), this, SLOT(adjustNumberOfClasses()));
115
QObject::connect(mClassificationComboBox, SIGNAL(activated(int)), this, SLOT(adjustClassification()));
116
QObject::connect(mModeComboBox, SIGNAL(activated(int)), this, SLOT(adjustClassification()));
119
QgsGraMaDialog::QgsGraMaDialog()
122
qWarning("constructor QgsGraSyDialog");
126
QgsGraMaDialog::~QgsGraMaDialog()
134
qWarning("destructor QgsGraSyDialog");
138
void QgsGraMaDialog::apply()
142
ext->adjustMarkers();
144
if (mClassificationComboBox->currentText().isEmpty()) //don't do anything, it there is no classification field
149
//font tor the legend text
150
QFont f("arial", 10, QFont::Normal);
156
int leftspace = 10; //space between left side of the pixmap and the text/graphics
157
int rightspace = 5; //space between text/graphics and right side of the pixmap
158
int wordspace = 5; //space between graphics/word
159
int markerheight; //height of a marker (is different for every row)
160
int markerwidth; //width of the broadest marker
161
int lowerupperwidth; // widht of the broadest lower-upper pair
162
int rowspace = 5; //spaces between rows of symbols
163
int rowheight = fm.height(); //height of a text row
164
int classesheight; //height of the classes section
166
//find out the width of the widest label and the widest lower - upper pair
170
for (int i = 0; i < mNumberOfClassesSpinbox->value(); i++)
172
int currentlabelwidth=fm.width(((QLineEdit *) (ext->getWidget(2, i)))->text());
173
if(currentlabelwidth>labelwidth)
175
labelwidth=currentlabelwidth;
178
int currentluwidth=fm.width(((QLineEdit *) (ext->getWidget(0, i)))->text() + " - " + ((QLineEdit *) (ext->getWidget(1, i)))->text());
179
if(currentluwidth>lowerupperwidth)
181
lowerupperwidth=currentluwidth;
185
//find out the width of the broadest marker and the total height of the class section
187
classesheight=rowspace*(mNumberOfClassesSpinbox->value()-1);
188
for (int i = 0; i < mNumberOfClassesSpinbox->value(); i++)
190
QPixmap p = QgsSVGCache::instance().
191
getPixmap(((QPushButton*)(ext->getWidget(3,i)))->name(),
192
((QLineEdit*)(ext->getWidget(4,i)))->text().toDouble());
193
int width = p.width();
194
if(width>markerwidth) {
196
qWarning("markerwidth: "+QString::number(markerwidth));
198
int height = p.height();
199
height = (height>rowheight) ? height : rowheight;
200
qWarning("height: " + QString::number(height));
201
classesheight+=height;
204
//create the pixmap for the render item
205
QPixmap *pix = mVectorLayer->legendPixmap();
207
if (mVectorLayer->propertiesDialog())
209
name = mVectorLayer->propertiesDialog()->displayName();
216
//query the name and the maximum upper value to estimate the necessary width of the pixmap
217
int pixwidth = leftspace + rightspace + markerwidth + 2 * wordspace + labelwidth + lowerupperwidth; //width of the pixmap with symbol and values
218
//consider 240 pixel for labels
219
int namewidth = leftspace + fm.width(name) + rightspace;
220
int width = (pixwidth > namewidth) ? pixwidth : namewidth;
221
pix->resize(width, topspace + 2 * fm.height() + bottomspace + classesheight);
226
//draw the layer name and the name of the classification field into the pixmap
227
p.drawText(leftspace, topspace + fm.height(), name);
228
p.drawText(leftspace, topspace + 2 * fm.height(), mClassificationComboBox->currentText());
230
QgsGraduatedMaRenderer *renderer = dynamic_cast < QgsGraduatedMaRenderer * >(mVectorLayer->renderer());
234
qWarning("Warning, typecast failed in QgsGraSyDialog::apply()");
238
renderer->removeItems();
240
int offset = topspace + 2 * fm.height();
241
for (int i = 0; i < mNumberOfClassesSpinbox->value(); i++)
243
QgsMarkerSymbol* sy = new QgsMarkerSymbol();
244
sy->setPicture(((QPushButton*)(ext->getWidget(3,i)))->name());
245
qWarning("SVG file: " + QString::fromAscii(((QPushButton*)(ext->getWidget(3,i)))->name()));
246
sy->setScaleFactor(((QLineEdit*)(ext->getWidget(4,i)))->text().toDouble());
248
QString lower_bound = ((QLineEdit *) (ext->getWidget(0, i)))->text();
249
QString upper_bound = ((QLineEdit *) (ext->getWidget(1, i)))->text();
250
QString label = ((QLineEdit *) (ext->getWidget(2, i)))->text();
252
//test, if lower_bound is numeric or not (making a subclass of QString would be the proper solution)
253
bool lbcontainsletter = false;
254
for (uint j = 0; j < lower_bound.length(); j++)
256
if (lower_bound.ref(j).isLetter())
258
lbcontainsletter = true;
262
//test, if upper_bound is numeric or not (making a subclass of QString would be the proper solution)
263
bool ubcontainsletter = false;
264
for (uint j = 0; j < upper_bound.length(); j++)
266
if (upper_bound.ref(j).isLetter())
268
ubcontainsletter = true;
272
if (lbcontainsletter == false && ubcontainsletter == false && lower_bound.length() > 0 && upper_bound.length() > 0) //only add the item if the value bounds do not contain letters and are not null strings
274
QgsRangeRenderItem *item = new QgsRangeRenderItem(sy, lower_bound, upper_bound, label);
275
qWarning("lower_bound: " +lower_bound);
276
qWarning("upper_bound: " +upper_bound);
277
qWarning("label: " +label);
278
renderer->addItem(item);
280
//add the symbol to the picture
281
QString legendstring = lower_bound + " - " + upper_bound;
282
//todo: paint the picture
283
double scalefactor=((QLineEdit*)(ext->getWidget(4,i)))->text().
285
QPixmap pix = QgsSVGCache::instance().
286
getPixmap(((QPushButton*)(ext->getWidget(3,i)))->name(),
288
int actrowheight=(int)(pix.height() * scalefactor);
289
actrowheight = (actrowheight > rowheight ?
290
actrowheight : rowheight);
291
p.drawPixmap(leftspace, offset, pix);
293
p.drawText(leftspace+markerwidth + wordspace, offset + actrowheight, legendstring);
294
p.drawText(leftspace+markerwidth+2*wordspace+lowerupperwidth, offset + actrowheight, label);
295
offset+=(rowspace+actrowheight);
299
renderer->setClassificationField(ext->classfield());
301
mVectorLayer->updateItemPixmap();
303
if (mVectorLayer->propertiesDialog())
305
mVectorLayer->propertiesDialog()->setRendererDirty(false);
307
mVectorLayer->triggerRepaint();
310
else //number of classes is 0
312
std::cout << "warning, number of classes is zero" << std::endl << std::flush;
316
void QgsGraMaDialog::adjustNumberOfClasses()
318
//find out the number of the classification field
319
QString fieldstring = mClassificationComboBox->currentText();
320
if (fieldstring.isEmpty()) //don't do anything, it there is no classification field
326
std::map < QString, int >::iterator iter = mFieldMap.find(fieldstring);
327
int field = iter->second;
331
QgsGraMaDialogBaseLayout->remove(ext);
335
//create a new extension dialog
336
if (mModeComboBox->currentText() == "Empty")
338
ext = new QgsGraMaExtensionWidget(this, field, QgsGraSyDialog::EMPTY, mNumberOfClassesSpinbox->value(), mVectorLayer);
340
else if (mModeComboBox->currentText() == "Equal Interval")
342
ext = new QgsGraMaExtensionWidget(this, field, QgsGraSyDialog::EQUAL_INTERVAL, mNumberOfClassesSpinbox->value(), mVectorLayer);
345
if (mNumberOfClassesSpinbox->value() == 0)
351
QgsGraMaDialogBaseLayout->addMultiCellWidget(ext, 5, 5, 0, 3);
355
void QgsGraMaDialog::adjustClassification()
357
//find out the number of the classification field
358
QString fieldstring = mClassificationComboBox->currentText();
359
if (fieldstring.isEmpty()) //don't do anything, it there is no classification field
365
std::map < QString, int >::iterator iter = mFieldMap.find(fieldstring);
366
int field = iter->second;
370
if (mModeComboBox->currentText() == "Empty")
372
ext->setClassification(QgsGraSyDialog::EMPTY,field);
374
else if(mModeComboBox->currentText() == "Equal Interval")
376
ext->setClassification(QgsGraSyDialog::EQUAL_INTERVAL,field);