1 /*************************************************************************** 2 qgslegendsettings.h 3 -------------------------------------- 4 Date : July 2014 5 Copyright : (C) 2014 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 16 #ifndef QGSLEGENDSETTINGS_H 17 #define QGSLEGENDSETTINGS_H 18 19 #include "qgis_core.h" 20 #include "qgis_sip.h" 21 #include <QColor> 22 #include <QSizeF> 23 24 class QRectF; 25 26 #include "qgslegendstyle.h" 27 28 class QgsExpressionContext; 29 30 /** 31 * \ingroup core 32 * \brief The QgsLegendSettings class stores the appearance and layout settings 33 * for legend drawing with QgsLegendRenderer. The content of the legend is given 34 * in QgsLegendModel class. 35 * 36 * \since QGIS 2.6 37 */ 38 class CORE_EXPORT QgsLegendSettings 39 { 40 public: 41 QgsLegendSettings(); 42 43 /** 44 * Sets the title for the legend, which will be rendered above all legend items. 45 * 46 * \see title() 47 */ setTitle(const QString & t)48 void setTitle( const QString &t ) { mTitle = t; } 49 50 /** 51 * Returns the title for the legend, which will be rendered above all legend items. 52 * 53 * \see setTitle() 54 */ title()55 QString title() const { return mTitle; } 56 57 /** 58 * Returns the alignment of the legend title. 59 * \see setTitleAlignment() 60 */ titleAlignment()61 Qt::AlignmentFlag titleAlignment() const { return mTitleAlignment; } 62 63 /** 64 * Sets the \a alignment of the legend title. 65 * \see titleAlignment() 66 */ setTitleAlignment(Qt::AlignmentFlag alignment)67 void setTitleAlignment( Qt::AlignmentFlag alignment ) { mTitleAlignment = alignment; } 68 69 /** 70 * Returns modifiable reference to the style for a legend component. 71 * 72 * \note Not available in Python bindings. 73 */ rstyle(QgsLegendStyle::Style s)74 SIP_SKIP QgsLegendStyle &rstyle( QgsLegendStyle::Style s ) { return mStyleMap[s]; } SIP_SKIP 75 76 /** 77 * Returns the style for a legend component. 78 * 79 * \see setStyle() 80 */ style(QgsLegendStyle::Style s)81 QgsLegendStyle style( QgsLegendStyle::Style s ) const { return mStyleMap.value( s ); } 82 83 /** 84 * Sets the \a style for a legend component. 85 * 86 * \see style() 87 */ setStyle(QgsLegendStyle::Style s,const QgsLegendStyle & style)88 void setStyle( QgsLegendStyle::Style s, const QgsLegendStyle &style ) { mStyleMap[s] = style; } 89 90 /** 91 * Returns the legend box space (in millimeters), which is the empty margin around the inside of the legend's 92 * rectangle. 93 * 94 * \see setBoxSpace() 95 */ boxSpace()96 double boxSpace() const {return mBoxSpace;} 97 98 /** 99 * Sets the legend box space (in millimeters), which is the empty margin around the inside of the legend's 100 * rectangle. 101 * 102 * \see boxSpace() 103 */ setBoxSpace(double s)104 void setBoxSpace( double s ) {mBoxSpace = s;} 105 106 /** 107 * Sets a string to use as a wrapping character. 108 * 109 * Whenever this string is encountered inside legend component text it will be automatically replaced with a new 110 * line character. 111 * 112 * \see wrapChar() 113 */ setWrapChar(const QString & t)114 void setWrapChar( const QString &t ) {mWrapChar = t;} 115 116 /** 117 * Returns the string used as a wrapping character. 118 * 119 * Whenever this string is encountered inside legend component text it will be automatically replaced with a new 120 * line character. 121 * 122 * \see setWrapChar() 123 */ wrapChar()124 QString wrapChar() const {return mWrapChar;} 125 126 /** 127 * Returns the margin space between adjacent columns (in millimeters). 128 * 129 * \see setColumnSpace() 130 */ columnSpace()131 double columnSpace() const {return mColumnSpace;} 132 133 /** 134 * Sets the margin space between adjacent columns (in millimeters). 135 * 136 * \see columnSpace() 137 */ setColumnSpace(double s)138 void setColumnSpace( double s ) { mColumnSpace = s;} 139 140 /** 141 * Returns the desired minimum number of columns to show in the legend. 142 * 143 * If legend components have forced column breaks then the actual number of columns in the rendered 144 * legend may be larger than this value. 145 * 146 * \see setColumnCount() 147 */ columnCount()148 int columnCount() const { return mColumnCount; } 149 150 /** 151 * Sets the desired minimum number of columns to show in the legend. 152 * 153 * If legend components have forced column breaks then the actual number of columns in the rendered 154 * legend may be larger than this value. 155 * 156 * \see columnCount() 157 */ setColumnCount(int c)158 void setColumnCount( int c ) { mColumnCount = c;} 159 160 /** 161 * Returns TRUE if layer components can be split over multiple columns. 162 * 163 * \see setSplitLayer() 164 */ splitLayer()165 bool splitLayer() const { return mSplitLayer; } 166 167 /** 168 * Sets whether layer components can be split over multiple columns. 169 * 170 * \see splitLayer() 171 */ setSplitLayer(bool s)172 void setSplitLayer( bool s ) { mSplitLayer = s;} 173 174 /** 175 * Returns TRUE if all columns should have equal widths. 176 * 177 * If FALSE is returned then columns will be individually resized to their minimum possible width. 178 * 179 * \see setEqualColumnWidth() 180 */ equalColumnWidth()181 bool equalColumnWidth() const { return mEqualColumnWidth; } 182 183 /** 184 * Sets whether all columns should have equal widths. 185 * 186 * If FALSE, then then columns will be individually resized to their minimum possible width. 187 * 188 * \see equalColumnWidth() 189 */ setEqualColumnWidth(bool s)190 void setEqualColumnWidth( bool s ) { mEqualColumnWidth = s;} 191 192 /** 193 * Returns the font color used for legend items. 194 * 195 * \see setFontColor() 196 */ fontColor()197 QColor fontColor() const {return mFontColor;} 198 199 /** 200 * Sets the font color used for legend items. 201 * 202 * \see fontColor() 203 */ setFontColor(const QColor & c)204 void setFontColor( const QColor &c ) {mFontColor = c;} 205 206 /** 207 * Returns layer font color, defaults to fontColor() 208 * \see setLayerFontColor() 209 * \see fontColor() 210 * \since QGIS 3.4.7 211 */ layerFontColor()212 QColor layerFontColor() const {return mLayerFontColor.isValid() ? mLayerFontColor : fontColor() ;} 213 214 /** 215 * Sets layer font color to \a fontColor 216 * Overrides fontColor() 217 * \see layerFontColor() 218 * \see fontColor() 219 * \since QGIS 3.4.7 220 */ setLayerFontColor(const QColor & fontColor)221 void setLayerFontColor( const QColor &fontColor ) {mLayerFontColor = fontColor;} 222 223 /** 224 * Returns the default symbol size (in millimeters) used for legend items. 225 * 226 * \see setSymbolSize() 227 */ symbolSize()228 QSizeF symbolSize() const {return mSymbolSize;} 229 230 /** 231 * Sets the default symbol size (in millimeters) used for legend items. 232 * 233 * \see symbolSize() 234 */ setSymbolSize(QSizeF s)235 void setSymbolSize( QSizeF s ) {mSymbolSize = s;} 236 237 /** 238 * Returns the maximum symbol size (in mm). 0.0 means there is no maximum set. 239 * 240 * \see setMaximumSymbolSize() 241 * \since QGIS 3.16 242 */ maximumSymbolSize()243 double maximumSymbolSize() const {return mMaxSymbolSize; } 244 245 /** 246 * Set the maximum symbol \a size for symbol (in millimeters). 247 * 248 * A symbol size of 0.0 indicates no maximum is set. 249 * 250 * \see maximumSymbolSize() 251 * \since QGIS 3.16 252 */ setMaximumSymbolSize(double size)253 void setMaximumSymbolSize( double size ) { mMaxSymbolSize = size;} 254 255 /** 256 * Returns the minimum symbol size (in mm). A value 0.0 means there is no minimum set. 257 * 258 * \see setMinimumSymbolSize 259 * \since QGIS 3.16 260 */ minimumSymbolSize()261 double minimumSymbolSize() const {return mMinSymbolSize; } 262 263 /** 264 * Set the minimum symbol \a size for symbol (in millimeters). 265 * 266 * A symbol size of 0.0 indicates no minimum is set. 267 * 268 * \see minimumSymbolSize() 269 * \since QGIS 3.16 270 */ setMinimumSymbolSize(double size)271 void setMinimumSymbolSize( double size ) { mMinSymbolSize = size;} 272 273 /** 274 * Sets the \a alignment for placement of legend symbols. 275 * 276 * Only Qt::AlignLeft or Qt::AlignRight are supported values. 277 * 278 * \see symbolAlignment() 279 * \since QGIS 3.10 280 */ setSymbolAlignment(Qt::AlignmentFlag alignment)281 void setSymbolAlignment( Qt::AlignmentFlag alignment ) { mSymbolAlignment = alignment; } 282 283 /** 284 * Returns the alignment for placement of legend symbols. 285 * 286 * Only Qt::AlignLeft or Qt::AlignRight are supported values. 287 * 288 * \see setSymbolAlignment() 289 * \since QGIS 3.10 290 */ symbolAlignment()291 Qt::AlignmentFlag symbolAlignment() const { return mSymbolAlignment; } 292 293 /** 294 * Returns whether a stroke will be drawn around raster symbol items. 295 * \see setDrawRasterStroke() 296 * \see rasterStrokeColor() 297 * \see rasterStrokeWidth() 298 * \since QGIS 2.12 299 */ drawRasterStroke()300 bool drawRasterStroke() const { return mRasterSymbolStroke; } 301 302 /** 303 * Sets whether a stroke will be drawn around raster symbol items. 304 * \param enabled set to TRUE to draw borders 305 * \see drawRasterStroke() 306 * \see setRasterStrokeColor() 307 * \see setRasterStrokeWidth() 308 * \since QGIS 2.12 309 */ setDrawRasterStroke(bool enabled)310 void setDrawRasterStroke( bool enabled ) { mRasterSymbolStroke = enabled; } 311 312 /** 313 * Returns the stroke color for the stroke drawn around raster symbol items. The stroke is 314 * only drawn if drawRasterStroke() is TRUE. 315 * \see setRasterStrokeColor() 316 * \see drawRasterStroke() 317 * \see rasterStrokeWidth() 318 * \since QGIS 2.12 319 */ rasterStrokeColor()320 QColor rasterStrokeColor() const { return mRasterStrokeColor; } 321 322 /** 323 * Sets the stroke color for the stroke drawn around raster symbol items. The stroke is 324 * only drawn if drawRasterStroke() is TRUE. 325 * \param color stroke color 326 * \see rasterStrokeColor() 327 * \see setDrawRasterStroke() 328 * \see setRasterStrokeWidth() 329 * \since QGIS 2.12 330 */ setRasterStrokeColor(const QColor & color)331 void setRasterStrokeColor( const QColor &color ) { mRasterStrokeColor = color; } 332 333 /** 334 * Returns the stroke width (in millimeters) for the stroke drawn around raster symbol items. The stroke is 335 * only drawn if drawRasterStroke() is TRUE. 336 * \see setRasterStrokeWidth() 337 * \see drawRasterStroke() 338 * \see rasterStrokeColor() 339 * \since QGIS 2.12 340 */ rasterStrokeWidth()341 double rasterStrokeWidth() const { return mRasterStrokeWidth; } 342 343 /** 344 * Sets the stroke width for the stroke drawn around raster symbol items. The stroke is 345 * only drawn if drawRasterStroke() is TRUE. 346 * \param width stroke width in millimeters 347 * \see rasterStrokeWidth() 348 * \see setDrawRasterStroke() 349 * \see setRasterStrokeColor() 350 * \since QGIS 2.12 351 */ setRasterStrokeWidth(double width)352 void setRasterStrokeWidth( double width ) { mRasterStrokeWidth = width; } 353 354 /** 355 * Returns the size (in millimeters) of WMS legend graphics shown in the legend. 356 * 357 * \see setWmsLegendSize() 358 */ wmsLegendSize()359 QSizeF wmsLegendSize() const {return mWmsLegendSize;} 360 361 /** 362 * Sets the desired size (in millimeters) of WMS legend graphics shown in the legend. 363 * 364 * \see wmsLegendSize() 365 */ setWmsLegendSize(QSizeF s)366 void setWmsLegendSize( QSizeF s ) {mWmsLegendSize = s;} 367 368 /** 369 * Returns the line spacing to use between lines of legend text. 370 * 371 * \see setLineSpacing() 372 */ lineSpacing()373 double lineSpacing() const { return mLineSpacing; } 374 375 /** 376 * Sets the line spacing to use between lines of legend text. 377 * 378 * \see lineSpacing() 379 */ setLineSpacing(double s)380 void setLineSpacing( double s ) { mLineSpacing = s; } 381 382 /** 383 * \deprecated Use scale factor from render contexts instead. 384 */ 385 Q_DECL_DEPRECATED double mmPerMapUnit() const SIP_DEPRECATED; 386 387 /** 388 * \deprecated Set scale factor on render contexts instead. 389 */ 390 Q_DECL_DEPRECATED void setMmPerMapUnit( double mmPerMapUnit ) SIP_DEPRECATED; 391 392 /** 393 * \deprecated Use flags from render contexts instead. 394 */ 395 Q_DECL_DEPRECATED bool useAdvancedEffects() const SIP_DEPRECATED; 396 397 /** 398 * \deprecated Set flag on render contexts instead. 399 */ 400 Q_DECL_DEPRECATED void setUseAdvancedEffects( bool use ) SIP_DEPRECATED; 401 402 /** 403 * Returns the legend map scale. 404 * The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map. 405 * \see setMapScale() 406 * \deprecated take this property from the render context instead 407 */ 408 Q_DECL_DEPRECATED double mapScale() const SIP_DEPRECATED; 409 410 /** 411 * Sets the legend map \a scale. 412 * The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map. 413 * \see mapScale() 414 * \deprecated set this property on the render context instead 415 */ 416 Q_DECL_DEPRECATED void setMapScale( double scale ) SIP_DEPRECATED; 417 418 /** 419 * Returns the factor of map units per pixel for symbols with size given in map units calculated by dpi and mmPerMapUnit 420 * \see setMapUnitsPerPixel() 421 * \deprecated take these properties on render contexts instead 422 */ 423 Q_DECL_DEPRECATED double mapUnitsPerPixel() const SIP_DEPRECATED; 424 425 /** 426 * Sets the mmPerMapUnit calculated by \a mapUnitsPerPixel mostly taken from the map settings. 427 * \see mapUnitsPerPixel() 428 * \deprecated set these properties on render contexts instead 429 */ 430 Q_DECL_DEPRECATED void setMapUnitsPerPixel( double mapUnitsPerPixel ) SIP_DEPRECATED; 431 432 /** 433 * \deprecated Take dpi from render contexts instead. 434 */ 435 Q_DECL_DEPRECATED int dpi() const SIP_DEPRECATED; 436 437 /** 438 * \deprecated Set dpi on render contexts instead. 439 */ 440 Q_DECL_DEPRECATED void setDpi( int dpi ) SIP_DEPRECATED; 441 442 // utility functions 443 444 /** 445 * Splits a string using the wrap char taking into account handling empty 446 * wrap char which means no wrapping 447 */ 448 449 /** 450 * Returns the actual text to render for a legend item, split into separate lines. 451 * 452 * The expression \a context argument is used to correctly evaluated expressions contained 453 * within legend item text. 454 * 455 * \since QGIS 3.6 456 */ 457 QStringList evaluateItemText( const QString &text, const QgsExpressionContext &context ) const; 458 459 /** 460 * Splits a string using the wrap char taking into account handling empty 461 * wrap char which means no wrapping 462 */ 463 QStringList splitStringForWrapping( const QString &stringToSplt ) const; 464 465 /** 466 * Draws Text. Takes care about all the composer specific issues (calculation to 467 * pixel, scaling of font and painter to work around the Qt font bug) 468 */ 469 void drawText( QPainter *p, double x, double y, const QString &text, const QFont &font ) const; 470 471 /** 472 * Like the above, but with a rectangle for multiline text 473 * \param p painter to use 474 * \param rect rectangle to draw into 475 * \param text text to draw 476 * \param font font to use 477 * \param halignment optional horizontal alignment 478 * \param valignment optional vertical alignment 479 * \param flags allows for passing Qt::TextFlags to control appearance of rendered text 480 */ 481 void drawText( QPainter *p, const QRectF &rect, const QString &text, const QFont &font, Qt::AlignmentFlag halignment = Qt::AlignLeft, Qt::AlignmentFlag valignment = Qt::AlignTop, int flags = Qt::TextWordWrap ) const; 482 483 //! Returns a font where size is in pixel and font size is upscaled with FONT_WORKAROUND_SCALE 484 QFont scaledFontPixelSize( const QFont &font ) const; 485 486 //! Calculates font to from point size to pixel size 487 double pixelFontSize( double pointSize ) const; 488 489 //! Returns the font width in millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCALE 490 double textWidthMillimeters( const QFont &font, const QString &text ) const; 491 492 //! Returns the font height of a character in millimeters 493 double fontHeightCharacterMM( const QFont &font, QChar c ) const; 494 495 //! Returns the font ascent in Millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCALE 496 double fontAscentMillimeters( const QFont &font ) const; 497 498 //! Returns the font descent in Millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCALE 499 double fontDescentMillimeters( const QFont &font ) const; 500 501 private: 502 503 QString mTitle; 504 505 //! Title alignment, one of Qt::AlignLeft, Qt::AlignHCenter, Qt::AlignRight) 506 Qt::AlignmentFlag mTitleAlignment = Qt::AlignLeft; 507 508 QString mWrapChar; 509 510 QColor mFontColor; 511 512 //! Space between item box and contents 513 qreal mBoxSpace = 2; 514 515 //! Width and height of symbol icon 516 QSizeF mSymbolSize; 517 518 //! Maximum marker symbol size (in mm) 519 double mMaxSymbolSize = 0.0; 520 521 //! Minimum marker symbol size (in mm) 522 double mMinSymbolSize = 0.0; 523 524 //! Width and height of WMS legendGraphic pixmap 525 QSizeF mWmsLegendSize; 526 527 //! Spacing between lines when wrapped 528 double mLineSpacing = 1; 529 530 //! Space between columns 531 double mColumnSpace = 2; 532 533 //! Number of legend columns 534 int mColumnCount = 1; 535 536 //! Allow splitting layers into multiple columns 537 bool mSplitLayer = false; 538 539 //! Use the same width (maximum) for all columns 540 bool mEqualColumnWidth = false; 541 542 bool mRasterSymbolStroke = true; 543 QColor mRasterStrokeColor; 544 double mRasterStrokeWidth = 0.0; 545 546 QMap<QgsLegendStyle::Style, QgsLegendStyle> mStyleMap; 547 548 //! Conversion ratio between millimeters and map units - for symbols with size given in map units 549 double mMmPerMapUnit = 1; 550 551 //! Whether to use advanced effects like opacity for symbols - may require their rasterization 552 bool mUseAdvancedEffects = true; 553 554 //! Denominator of map's scale 555 double mMapScale = 1; 556 557 //! DPI to be used when rendering legend 558 int mDpi = 96; 559 560 //! Font color for layers, overrides font color 561 QColor mLayerFontColor; 562 563 //! Symbol alignment 564 Qt::AlignmentFlag mSymbolAlignment = Qt::AlignLeft; 565 }; 566 567 568 569 #endif // QGSLEGENDSETTINGS_H 570