1
/***************************************************************************
2
qgslabeldialog.cpp - render vector labels
5
copyright : (C) 2004 by Radim Blazek & Tim Sutton
7
***************************************************************************/
8
/***************************************************************************
10
* This program is free software; you can redistribute it and/or modify *
11
* it under the terms of the GNU General Public License as published by *
12
* the Free Software Foundation; either version 2 of the License, or *
13
* (at your option) any later version. *
15
***************************************************************************/
17
#include "qgslabeldialog.h"
20
#include "qgslabelattributes.h"
22
#include <QColorDialog>
23
#include <QFontDialog>
25
#include "qgslogger.h"
28
const int PIXMAP_WIDTH = 200;
29
const int PIXMAP_HEIGHT = 20;
31
QgsLabelDialog::QgsLabelDialog( QgsLabel *label, QWidget *parent )
34
mFontColor( Qt::black ),
35
mBufferColor( Qt::black ),
39
QgsDebugMsg( "entering." );
45
connect( btnDefaultFont, SIGNAL( clicked() ),
46
this, SLOT( changeFont() ) );
47
connect( pbnDefaultBufferColor_2, SIGNAL( clicked() ),
48
this, SLOT( changeBufferColor() ) );
49
connect( pbnDefaultFontColor, SIGNAL( clicked() ),
50
this, SLOT( changeFontColor() ) );
54
void QgsLabelDialog::init( )
56
QgsDebugMsg( "entering." );
58
QgsLabelAttributes * myLabelAttributes = mLabel->labelAttributes();
59
//populate a string list with all the field names which will be used to set up the
61
QgsFieldMap& myFieldsMap = mLabel->fields();
62
QStringList myFieldStringList;
63
myFieldStringList.append( "" );
64
for ( QgsFieldMap::iterator it = myFieldsMap.begin(); it != myFieldsMap.end(); ++it )
66
myFieldStringList.append( it->name() );
69
//now set all the combos that need field lists using the string list
71
cboLabelField->clear();
72
cboLabelField->addItems( myFieldStringList );
73
cboLabelField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Text ), myFieldStringList ) );
75
cboFontField->clear();
76
cboFontField->addItems( myFieldStringList );
77
cboFontField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Family ), myFieldStringList ) );
79
cboBoldField->clear();
80
cboBoldField->addItems( myFieldStringList );
81
cboBoldField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Bold ), myFieldStringList ) );
84
cboItalicField->clear();
85
cboItalicField->addItems( myFieldStringList );
86
cboItalicField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Italic ), myFieldStringList ) );
88
cboUnderlineField->clear();
89
cboUnderlineField->addItems( myFieldStringList );
90
cboUnderlineField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Underline ), myFieldStringList ) );
92
cboFontSizeField->clear();
93
cboFontSizeField->addItems( myFieldStringList );
94
cboFontSizeField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Size ), myFieldStringList ) );
96
cboFontSizeTypeField->clear();
97
cboFontSizeTypeField->addItems( myFieldStringList );
98
cboFontSizeTypeField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::SizeType ), myFieldStringList ) );
101
cboFontTransparencyField->clear();
102
cboFontTransparencyField->addItems( myFieldStringList );
103
cboFontTransparencyField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::FontTransparency ), myFieldStringList ) );
106
cboFontColorField->clear();
107
cboFontColorField->addItems( myFieldStringList );
108
cboFontColorField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Color ), myFieldStringList ) );
111
cboBufferSizeField->clear();
112
cboBufferSizeField->addItems( myFieldStringList );
113
cboBufferSizeField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::BufferSize ), myFieldStringList ) );
115
cboBufferTransparencyField->clear();
116
cboBufferTransparencyField->addItems( myFieldStringList );
117
//cboBufferTransparencyField->setCurrentIndex(itemNoForField(mLabel->labelField(QgsLabel::BufferTransparency),myFieldStringList));
119
cboXCoordinateField->clear();
120
cboXCoordinateField->addItems( myFieldStringList );
121
cboXCoordinateField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::XCoordinate ), myFieldStringList ) );
123
cboYCoordinateField->clear();
124
cboYCoordinateField->addItems( myFieldStringList );
125
cboYCoordinateField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::YCoordinate ), myFieldStringList ) );
127
cboXOffsetField->clear();
128
cboXOffsetField->addItems( myFieldStringList );
129
cboXOffsetField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::XOffset ), myFieldStringList ) );
131
cboYOffsetField->clear();
132
cboYOffsetField->addItems( myFieldStringList );
133
cboYOffsetField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::YOffset ), myFieldStringList ) );
135
cboAlignmentField->clear();
136
cboAlignmentField->addItems( myFieldStringList );
137
cboAlignmentField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Alignment ), myFieldStringList ) );
139
cboAngleField->clear();
140
cboAngleField->addItems( myFieldStringList );
141
cboAngleField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Angle ), myFieldStringList ) );
143
// set up the scale based layer visibility stuff....
144
chkUseScaleDependentRendering->setChecked( mLabel->scaleBasedVisibility() );
145
spinMinimumScale->setValue(( int )mLabel->minScale() );
146
spinMaximumScale->setValue(( int )mLabel->maxScale() );
149
//set the non-databound fields up now
151
leDefaultLabel->setText( myLabelAttributes->text() );
152
mFont.setFamily( myLabelAttributes->family() );
153
if ( myLabelAttributes->sizeIsSet() )
155
mFont.setPointSizeF( myLabelAttributes->size() );
157
int myTypeInt = myLabelAttributes->sizeType();
158
if ( myTypeInt == QgsLabelAttributes::PointUnits )
160
radioFontSizeUnitsPoints->setChecked( true );
162
else //assume map units is checked
164
radioFontSizeUnitsMap->setChecked( true );
167
else //defaults for when no size has been set
169
mFont.setPointSizeF( myLabelAttributes->size() );
170
radioFontSizeUnitsPoints->setChecked( true );
173
spinFontSize->setValue( myLabelAttributes->size() );
175
if ( myLabelAttributes->boldIsSet() )
177
mFont.setBold( myLabelAttributes->bold() );
181
mFont.setBold( false );
183
if ( myLabelAttributes->italicIsSet() )
185
mFont.setItalic( myLabelAttributes->italic() );
189
mFont.setItalic( false );
191
if ( myLabelAttributes->underlineIsSet() )
193
mFont.setUnderline( myLabelAttributes->underline() );
197
mFont.setUnderline( false );
200
mFontColor = myLabelAttributes->color();
202
if ( myLabelAttributes->offsetIsSet() )
204
int myTypeInt = myLabelAttributes->offsetType();
205
if ( myTypeInt == QgsLabelAttributes::PointUnits )
207
radioOffsetUnitsPoints->setChecked( true );
211
radioOffsetUnitsMap->setChecked( true );
213
spinXOffset->setValue( myLabelAttributes->xOffset() );
214
spinYOffset->setValue( myLabelAttributes->yOffset() );
216
else //defaults for when no offset is defined
218
spinXOffset->setValue( 0 );
219
spinYOffset->setValue( 0 );
221
spinAngle->setRange( -1, 360 );
222
spinAngle->setSpecialValueText( tr( "Auto" ) );
223
if ( myLabelAttributes->angleIsAuto() )
225
spinAngle->setValue( -1 );
229
spinAngle->setValue( static_cast<int>( myLabelAttributes->angle() ) );
232
//the values here may seem a bit counterintuitive - basically everything
233
//is the reverse of the way you think it should be...
234
//TODO investigate in QgsLabel why this needs to be the case
235
//TODO add support for corners (e.g. bottom right) to xml serialiser
237
if ( myLabelAttributes->alignment() == ( Qt::AlignRight | Qt::AlignBottom ) ) radioAboveLeft->setChecked( true ) ;
238
if ( myLabelAttributes->alignment() == ( Qt::AlignRight | Qt::AlignTop ) ) radioBelowLeft->setChecked( true ) ;
239
if ( myLabelAttributes->alignment() == ( Qt::AlignLeft | Qt::AlignBottom ) ) radioAboveRight->setChecked( true ) ;
240
if ( myLabelAttributes->alignment() == ( Qt::AlignLeft | Qt::AlignTop ) ) radioBelowRight->setChecked( true ) ;
241
if ( myLabelAttributes->alignment() == ( Qt::AlignRight | Qt::AlignVCenter ) ) radioLeft->setChecked( true ) ;
242
if ( myLabelAttributes->alignment() == ( Qt::AlignLeft | Qt::AlignVCenter ) ) radioRight->setChecked( true ) ;
243
if ( myLabelAttributes->alignment() == ( Qt::AlignBottom | Qt::AlignHCenter ) ) radioAbove->setChecked( true ) ;
244
if ( myLabelAttributes->alignment() == ( Qt::AlignTop | Qt::AlignHCenter ) ) radioBelow->setChecked( true ) ;
245
if ( myLabelAttributes->alignment() == Qt::AlignCenter ) radioOver->setChecked( true ) ;
247
mBufferColor = myLabelAttributes->bufferColor();
248
//note that it could be that buffer properties are set, but the bufer is disabled
249
if ( myLabelAttributes->bufferSizeIsSet() )
251
int myTypeInt = myLabelAttributes->bufferSizeType();
252
if ( myTypeInt == QgsLabelAttributes::PointUnits )
254
radioBufferUnitsPoints->setChecked( true );
258
radioBufferUnitsMap->setChecked( true );
260
spinBufferSize->setValue( myLabelAttributes->bufferSize() );
262
else //defaults for when no offset is defined
264
spinBufferSize->setValue( 1 );
266
//set the state of the multiline enabled checkbox
267
chkUseMultiline->setChecked( myLabelAttributes->multilineEnabled() );
268
//set the state of the buffer enabled checkbox
269
chkUseBuffer->setChecked( myLabelAttributes->bufferEnabled() );
271
//NOTE: do we need this line too? TS
272
spinBufferSize->setValue( myLabelAttributes->bufferSize() );
273
//TODO - transparency attributes for buffers
279
void QgsLabelDialog::changeFont( void )
281
QgsDebugMsg( "entering." );
283
qreal fontSize = mFont.pointSizeF();
285
#if defined(Q_WS_MAC) && QT_VERSION >= 0x040500 && !defined(__LP64__)
286
// Native Mac dialog works only for 64 bit Cocoa (observed in Qt 4.5.2, probably a Qt bug)
287
mFont = QFontDialog::getFont( &resultFlag, mFont, this, QString(), QFontDialog::DontUseNativeDialog );
289
mFont = QFontDialog::getFont( &resultFlag, mFont, this );
293
if ( mFont.pointSizeF() != fontSize )
295
// font is set to the font the user selected
296
spinFontSize->setValue( mFont.pointSizeF() );
301
// the user cancelled the dialog; font is set to the initial
302
// value, in this case Helvetica [Cronyx], 10
304
lblSample->setFont( mFont );
307
void QgsLabelDialog::changeFontColor( void )
309
QgsDebugMsg( "entering." );
311
mFontColor = QColorDialog::getColor( mFontColor );
312
QPalette palette = lblSample->palette();
313
palette.setColor( lblSample->foregroundRole(), mFontColor );
314
lblSample->setPalette( palette );
317
void QgsLabelDialog::changeBufferColor( void )
319
QgsDebugMsg( "entering." );
321
mBufferColor = QColorDialog::getColor( mBufferColor );
322
QPalette palette = lblSample->palette();
323
palette.setColor( lblSample->backgroundRole(), mBufferColor );
324
lblSample->setPalette( palette );
328
int QgsLabelDialog::itemNoForField( QString theFieldName, QStringList theFieldList )
331
for ( QStringList::Iterator it = theFieldList.begin(); it != theFieldList.end(); ++it )
333
if ( theFieldName == *it ) return myItemInt;
336
//if no matches assume first item in list is blank and return that
340
QgsLabelDialog::~QgsLabelDialog()
342
QgsDebugMsg( "entering." );
345
void QgsLabelDialog::apply()
347
QgsDebugMsg( "entering." );
349
//set the label props that are NOT bound to a field in the attributes tbl
350
//All of these are set in the labelAttributes member of the layer
351
QgsLabelAttributes * myLabelAttributes = mLabel->labelAttributes();
352
myLabelAttributes->setText( leDefaultLabel->text() );
353
myLabelAttributes->setFamily( mFont.family() );
355
if ( radioFontSizeUnitsPoints->isChecked() )
357
myTypeInt = QgsLabelAttributes::PointUnits;
359
else //assume map units is checked
361
myTypeInt = QgsLabelAttributes::MapUnits;
363
myLabelAttributes->setSize( mFont.pointSizeF(), myTypeInt );
364
myLabelAttributes->setBold( mFont.bold() );
365
myLabelAttributes->setItalic( mFont.italic() );
366
myLabelAttributes->setUnderline( mFont.underline() );
367
myLabelAttributes->setColor( mFontColor );
369
if ( radioOffsetUnitsPoints->isChecked() )
371
myTypeInt = QgsLabelAttributes::PointUnits;
375
myTypeInt = QgsLabelAttributes::MapUnits;
377
myLabelAttributes->setOffset( spinXOffset->value(), spinYOffset->value(), myTypeInt );
378
myLabelAttributes->setAutoAngle( spinAngle->value() == -1 );
379
myLabelAttributes->setAngle( spinAngle->value() );
381
//the values here may seem a bit counterintuitive - basically everything
382
//is the reverse of the way you think it should be...
383
//TODO investigate in QgsLabel why this needs to be the case
384
if ( radioAboveLeft->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignRight | Qt::AlignBottom );
385
if ( radioBelowLeft->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignRight | Qt::AlignTop );
386
if ( radioAboveRight->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignLeft | Qt::AlignBottom );
387
if ( radioBelowRight->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignLeft | Qt::AlignTop );
388
if ( radioLeft->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
389
if ( radioRight->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
390
if ( radioAbove->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignBottom | Qt::AlignHCenter );
391
if ( radioBelow->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignTop | Qt::AlignHCenter );
392
if ( radioOver->isChecked() ) myLabelAttributes->setAlignment( Qt::AlignCenter );
394
myLabelAttributes->setMultilineEnabled( chkUseMultiline->isChecked() );
395
myLabelAttributes->setBufferEnabled( chkUseBuffer->isChecked() );
396
myLabelAttributes->setBufferColor( mBufferColor );
398
if ( radioBufferUnitsPoints->isChecked() )
400
myTypeInt = QgsLabelAttributes::PointUnits;
404
myTypeInt = QgsLabelAttributes::MapUnits;
406
myLabelAttributes->setBufferSize( spinBufferSize->value(), myTypeInt );
407
//TODO - transparency attributes for buffers
409
//set the label props that are data bound to a field in the attributes tbl
410
mLabel->setLabelField( QgsLabel::Text, fieldIndexFromName( cboLabelField->currentText() ) );
411
mLabel->setLabelField( QgsLabel::Family, fieldIndexFromName( cboFontField->currentText() ) );
412
mLabel->setLabelField( QgsLabel::Bold, fieldIndexFromName( cboBoldField->currentText() ) );
413
mLabel->setLabelField( QgsLabel::Italic, fieldIndexFromName( cboItalicField->currentText() ) );
414
mLabel->setLabelField( QgsLabel::Underline, fieldIndexFromName( cboUnderlineField->currentText() ) );
415
mLabel->setLabelField( QgsLabel::Size, fieldIndexFromName( cboFontSizeField->currentText() ) );
416
mLabel->setLabelField( QgsLabel::SizeType, fieldIndexFromName( cboFontSizeTypeField->currentText() ) );
417
mLabel->setLabelField( QgsLabel::Color, fieldIndexFromName( cboFontColorField->currentText() ) );
418
mLabel->setLabelField( QgsLabel::BufferSize, fieldIndexFromName( cboBufferSizeField->currentText() ) );
419
//mLabel->setLabelField( QgsLabel::BufferTransparency, cboBufferTransparencyField->currentText() );
420
mLabel->setLabelField( QgsLabel::XCoordinate, fieldIndexFromName( cboXCoordinateField->currentText() ) );
421
mLabel->setLabelField( QgsLabel::YCoordinate, fieldIndexFromName( cboYCoordinateField->currentText() ) );
422
mLabel->setLabelField( QgsLabel::XOffset, fieldIndexFromName( cboXOffsetField->currentText() ) );
423
mLabel->setLabelField( QgsLabel::YOffset, fieldIndexFromName( cboYOffsetField->currentText() ) );
424
mLabel->setLabelField( QgsLabel::Alignment, fieldIndexFromName( cboAlignmentField->currentText() ) );
425
mLabel->setLabelField( QgsLabel::Angle, fieldIndexFromName( cboAngleField->currentText() ) );
427
// set up the scale based layer visibility stuff....
428
mLabel->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
429
mLabel->setMinScale( spinMinimumScale->value() );
430
mLabel->setMaxScale( spinMaximumScale->value() );
433
int QgsLabelDialog::fieldIndexFromName( QString name )
435
const QgsFieldMap& fields = mLabel->fields();
436
for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it )
438
if ( it->name() == name )