1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10 // vim: expandtab
11
12 #include <qmap.h>
13 #include "qwt_plot.h"
14 #include "qwt_plot_grid.h"
15 #include "qwt_plot_curve.h"
16 #include "qwt_plot_marker.h"
17 #include "qwt_symbol.h"
18 #include "qwt_legend.h"
19 #include "qwt_legend_item.h"
20 #include "qwt_scale_widget.h"
21 #include "qwt_text_label.h"
22 #include "qwt_plot_printfilter.h"
23
24 #if QT_VERSION < 0x040000
25 typedef QColorGroup Palette;
26 #else
27 typedef QPalette Palette;
28 #endif
29
30 class QwtPlotPrintFilter::PrivateData
31 {
32 public:
PrivateData()33 PrivateData():
34 options(QwtPlotPrintFilter::PrintAll),
35 cache(NULL)
36 {
37 }
38
~PrivateData()39 ~PrivateData()
40 {
41 delete cache;
42 }
43
44 class Cache
45 {
46 public:
47 QColor titleColor;
48 QFont titleFont;
49
50 QwtText scaleTitle[QwtPlot::axisCnt];
51 QColor scaleColor[QwtPlot::axisCnt];
52 QFont scaleFont[QwtPlot::axisCnt];
53 QColor scaleTitleColor[QwtPlot::axisCnt];
54 QFont scaleTitleFont[QwtPlot::axisCnt];
55
56 QMap<QWidget *, QFont> legendFonts;
57
58 QColor widgetBackground;
59 QColor canvasBackground;
60 QColor gridColors[2];
61
62 QMap<const QwtPlotItem *, QColor> curveColors;
63 QMap<const QwtPlotItem *, QColor> curveSymbolBrushColors;
64 QMap<const QwtPlotItem *, QColor> curveSymbolPenColors;
65
66 QMap<const QwtPlotItem *, QFont> markerFonts;
67 QMap<const QwtPlotItem *, QColor> markerLabelColors;
68 QMap<const QwtPlotItem *, QColor> markerLineColors;
69 QMap<const QwtPlotItem *, QColor> markerSymbolBrushColors;
70 QMap<const QwtPlotItem *, QColor> markerSymbolPenColors;
71 };
72
73 int options;
74 mutable Cache *cache;
75 };
76
77
78 /*!
79 Sets filter options to PrintAll
80 */
81
QwtPlotPrintFilter()82 QwtPlotPrintFilter::QwtPlotPrintFilter()
83 {
84 d_data = new PrivateData;
85 }
86
87 //! Destructor
~QwtPlotPrintFilter()88 QwtPlotPrintFilter::~QwtPlotPrintFilter()
89 {
90 delete d_data;
91 }
92
93 /*!
94 \brief Set plot print options
95 \param options Or'd QwtPlotPrintFilter::Options values
96
97 \sa options()
98 */
setOptions(int options)99 void QwtPlotPrintFilter::setOptions(int options)
100 {
101 d_data->options = options;
102 }
103
104 /*!
105 \brief Get plot print options
106 \sa setOptions()
107 */
options() const108 int QwtPlotPrintFilter::options() const
109 {
110 return d_data->options;
111 }
112
113 /*!
114 \brief Modifies a color for printing
115 \param c Color to be modified
116 \param item Type of item where the color belongs
117 \return Modified color.
118
119 In case of !(QwtPlotPrintFilter::options() & PrintBackground)
120 MajorGrid is modified to Qt::darkGray, MinorGrid to Qt::gray.
121 All other colors are returned unmodified.
122 */
123
color(const QColor & c,Item item) const124 QColor QwtPlotPrintFilter::color(const QColor &c, Item item) const
125 {
126 if ( !(options() & PrintBackground))
127 {
128 switch(item)
129 {
130 case MajorGrid:
131 return Qt::darkGray;
132 case MinorGrid:
133 return Qt::gray;
134 default:;
135 }
136 }
137 return c;
138 }
139
140 /*!
141 \brief Modifies a font for printing
142 \param f Font to be modified
143 \param item Type of item where the font belongs
144
145 All fonts are returned unmodified
146 */
147
font(const QFont & f,Item) const148 QFont QwtPlotPrintFilter::font(const QFont &f, Item) const
149 {
150 return f;
151 }
152
153 /*!
154 Change color and fonts of a plot
155 \sa apply()
156 */
apply(QwtPlot * plot) const157 void QwtPlotPrintFilter::apply(QwtPlot *plot) const
158 {
159 const bool doAutoReplot = plot->autoReplot();
160 plot->setAutoReplot(false);
161
162 delete d_data->cache;
163 d_data->cache = new PrivateData::Cache;
164
165 PrivateData::Cache &cache = *d_data->cache;
166
167 if ( plot->titleLabel() )
168 {
169 QwtTextLabel* title = plot->titleLabel();
170 if ( title->text().testPaintAttribute(QwtText::PaintUsingTextColor) )
171 {
172 QwtText text = title->text();
173 cache.titleColor = text.color();
174 text.setColor(color(cache.titleColor, Title));
175 title->setText(text);
176 }
177 else
178 {
179 QPalette palette = title->palette();
180 cache.titleColor = palette.color(QPalette::Active, Palette::Text);
181 title->setPalette(palette);
182 palette.setColor(QPalette::Active, Palette::Text, color(cache.titleColor, Title));
183 title->setPalette(palette);
184 }
185
186 if ( title->text().testPaintAttribute(QwtText::PaintUsingTextFont) )
187 {
188 QwtText text = title->text();
189 cache.titleFont = text.font();
190 text.setFont(font(cache.titleFont, Title));
191 title->setText(text);
192 }
193 else
194 {
195 cache.titleFont = title->font();
196 title->setFont(font(cache.titleFont, Title));
197 }
198 }
199 if ( plot->legend() )
200 {
201 #if QT_VERSION < 0x040000
202 QValueList<QWidget *> list = plot->legend()->legendItems();
203 for ( QValueListIterator<QWidget *> it = list.begin();
204 it != list.end(); ++it )
205 #else
206 QList<QWidget *> list = plot->legend()->legendItems();
207 for ( QList<QWidget*>::iterator it = list.begin();
208 it != list.end(); ++it )
209 #endif
210 {
211 QWidget *w = *it;
212
213 cache.legendFonts.insert(w, w->font());
214 w->setFont(font(w->font(), Legend));
215
216 if ( w->inherits("QwtLegendItem") )
217 {
218 QwtLegendItem *label = (QwtLegendItem *)w;
219
220 QwtSymbol symbol = label->symbol();
221 QPen pen = symbol.pen();
222 QBrush brush = symbol.brush();
223
224 pen.setColor(color(pen.color(), CurveSymbol));
225 brush.setColor(color(brush.color(), CurveSymbol));
226
227 symbol.setPen(pen);
228 symbol.setBrush(brush);
229 label->setSymbol(symbol);
230
231 pen = label->curvePen();
232 pen.setColor(color(pen.color(), Curve));
233 label->setCurvePen(pen);
234 }
235 }
236 }
237 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
238 {
239 QwtScaleWidget *scaleWidget = plot->axisWidget(axis);
240 if ( scaleWidget )
241 {
242 cache.scaleColor[axis] = scaleWidget->palette().color(
243 QPalette::Active, Palette::Foreground);
244 QPalette palette = scaleWidget->palette();
245 palette.setColor(QPalette::Active, Palette::Foreground,
246 color(cache.scaleColor[axis], AxisScale));
247 scaleWidget->setPalette(palette);
248
249 cache.scaleFont[axis] = scaleWidget->font();
250 scaleWidget->setFont(font(cache.scaleFont[axis], AxisScale));
251
252 cache.scaleTitle[axis] = scaleWidget->title();
253
254 QwtText scaleTitle = scaleWidget->title();
255 if ( scaleTitle.testPaintAttribute(QwtText::PaintUsingTextColor) )
256 {
257 cache.scaleTitleColor[axis] = scaleTitle.color();
258 scaleTitle.setColor(
259 color(cache.scaleTitleColor[axis], AxisTitle));
260 }
261
262 if ( scaleTitle.testPaintAttribute(QwtText::PaintUsingTextFont) )
263 {
264 cache.scaleTitleFont[axis] = scaleTitle.font();
265 scaleTitle.setFont(
266 font(cache.scaleTitleFont[axis], AxisTitle));
267 }
268
269 scaleWidget->setTitle(scaleTitle);
270
271 int startDist, endDist;
272 scaleWidget->getBorderDistHint(startDist, endDist);
273 scaleWidget->setBorderDist(startDist, endDist);
274 }
275 }
276
277
278 QPalette p = plot->palette();
279 cache.widgetBackground = plot->palette().color(
280 QPalette::Active, Palette::Background);
281 p.setColor(QPalette::Active, Palette::Background,
282 color(cache.widgetBackground, WidgetBackground));
283 plot->setPalette(p);
284
285 cache.canvasBackground = plot->canvasBackground();
286 plot->setCanvasBackground(color(cache.canvasBackground, CanvasBackground));
287
288 const QwtPlotItemList& itmList = plot->itemList();
289 for ( QwtPlotItemIterator it = itmList.begin();
290 it != itmList.end(); ++it )
291 {
292 apply(*it);
293 }
294
295 plot->setAutoReplot(doAutoReplot);
296 }
297
apply(QwtPlotItem * item) const298 void QwtPlotPrintFilter::apply(QwtPlotItem *item) const
299 {
300 PrivateData::Cache &cache = *d_data->cache;
301
302 switch(item->rtti())
303 {
304 case QwtPlotItem::Rtti_PlotGrid:
305 {
306 QwtPlotGrid *grid = (QwtPlotGrid *)item;
307
308 QPen pen = grid->majPen();
309 cache.gridColors[0] = pen.color();
310 pen.setColor(color(pen.color(), MajorGrid));
311 grid->setMajPen(pen);
312
313 pen = grid->minPen();
314 cache.gridColors[1] = pen.color();
315 pen.setColor(color(pen.color(), MinorGrid));
316 grid->setMinPen(pen);
317
318 break;
319 }
320 case QwtPlotItem::Rtti_PlotCurve:
321 {
322 QwtPlotCurve *c = (QwtPlotCurve *)item;
323
324 QwtSymbol symbol = c->symbol();
325
326 QPen pen = symbol.pen();
327 cache.curveSymbolPenColors.insert(c, pen.color());
328 pen.setColor(color(pen.color(), CurveSymbol));
329 symbol.setPen(pen);
330
331 QBrush brush = symbol.brush();
332 cache.curveSymbolBrushColors.insert(c, brush.color());
333 brush.setColor(color(brush.color(), CurveSymbol));
334 symbol.setBrush(brush);
335
336 c->setSymbol(symbol);
337
338 pen = c->pen();
339 cache.curveColors.insert(c, pen.color());
340 pen.setColor(color(pen.color(), Curve));
341 c->setPen(pen);
342
343 break;
344 }
345 case QwtPlotItem::Rtti_PlotMarker:
346 {
347 QwtPlotMarker *m = (QwtPlotMarker *)item;
348
349 QwtText label = m->label();
350 cache.markerFonts.insert(m, label.font());
351 label.setFont(font(label.font(), Marker));
352 cache.markerLabelColors.insert(m, label.color());
353 label.setColor(color(label.color(), Marker));
354 m->setLabel(label);
355
356 QPen pen = m->linePen();
357 cache.markerLineColors.insert(m, pen.color());
358 pen.setColor(color(pen.color(), Marker));
359 m->setLinePen(pen);
360
361 QwtSymbol symbol = m->symbol();
362
363 pen = symbol.pen();
364 cache.markerSymbolPenColors.insert(m, pen.color());
365 pen.setColor(color(pen.color(), MarkerSymbol));
366 symbol.setPen(pen);
367
368 QBrush brush = symbol.brush();
369 cache.markerSymbolBrushColors.insert(m, brush.color());
370 brush.setColor(color(brush.color(), MarkerSymbol));
371 symbol.setBrush(brush);
372
373 m->setSymbol(symbol);
374
375 break;
376 }
377 default:
378 break;
379 }
380 }
381
382 /*!
383 Reset color and fonts of a plot
384 \sa apply()
385 */
reset(QwtPlot * plot) const386 void QwtPlotPrintFilter::reset(QwtPlot *plot) const
387 {
388 if ( d_data->cache == 0 )
389 return;
390
391 const bool doAutoReplot = plot->autoReplot();
392 plot->setAutoReplot(false);
393
394 const PrivateData::Cache &cache = *d_data->cache;
395
396 if ( plot->titleLabel() )
397 {
398 QwtTextLabel* title = plot->titleLabel();
399 if ( title->text().testPaintAttribute(QwtText::PaintUsingTextColor) )
400 {
401 QwtText text = title->text();
402 text.setColor(cache.titleColor);
403 title->setText(text);
404 }
405 else
406 {
407 QPalette palette = title->palette();
408 palette.setColor(
409 QPalette::Active, Palette::Text, cache.titleColor);
410 title->setPalette(palette);
411 }
412
413 if ( title->text().testPaintAttribute(QwtText::PaintUsingTextFont) )
414 {
415 QwtText text = title->text();
416 text.setFont(cache.titleFont);
417 title->setText(text);
418 }
419 else
420 {
421 title->setFont(cache.titleFont);
422 }
423 }
424
425 if ( plot->legend() )
426 {
427 #if QT_VERSION < 0x040000
428 QValueList<QWidget *> list = plot->legend()->legendItems();
429 for ( QValueListIterator<QWidget *> it = list.begin();
430 it != list.end(); ++it )
431 #else
432 QList<QWidget *> list = plot->legend()->legendItems();
433 for ( QList<QWidget*>::iterator it = list.begin();
434 it != list.end(); ++it )
435 #endif
436 {
437 QWidget *w = *it;
438
439 if ( cache.legendFonts.contains(w) )
440 w->setFont(cache.legendFonts[w]);
441
442 if ( w->inherits("QwtLegendItem") )
443 {
444 QwtLegendItem *label = (QwtLegendItem *)w;
445 const QwtPlotItem *plotItem =
446 (const QwtPlotItem*)plot->legend()->find(label);
447
448 QwtSymbol symbol = label->symbol();
449 if ( cache.curveSymbolPenColors.contains(plotItem) )
450 {
451 QPen pen = symbol.pen();
452 pen.setColor(cache.curveSymbolPenColors[plotItem]);
453 symbol.setPen(pen);
454 }
455
456 if ( cache.curveSymbolBrushColors.contains(plotItem) )
457 {
458 QBrush brush = symbol.brush();
459 brush.setColor(cache.curveSymbolBrushColors[plotItem]);
460 symbol.setBrush(brush);
461 }
462 label->setSymbol(symbol);
463
464 if ( cache.curveColors.contains(plotItem) )
465 {
466 QPen pen = label->curvePen();
467 pen.setColor(cache.curveColors[plotItem]);
468 label->setCurvePen(pen);
469 }
470 }
471 }
472 }
473 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
474 {
475 QwtScaleWidget *scaleWidget = plot->axisWidget(axis);
476 if ( scaleWidget )
477 {
478 QPalette palette = scaleWidget->palette();
479 palette.setColor(QPalette::Active, Palette::Foreground,
480 cache.scaleColor[axis]);
481 scaleWidget->setPalette(palette);
482
483 scaleWidget->setFont(cache.scaleFont[axis]);
484 scaleWidget->setTitle(cache.scaleTitle[axis]);
485
486 int startDist, endDist;
487 scaleWidget->getBorderDistHint(startDist, endDist);
488 scaleWidget->setBorderDist(startDist, endDist);
489 }
490 }
491
492 QPalette p = plot->palette();
493 p.setColor(QPalette::Active, Palette::Background, cache.widgetBackground);
494 plot->setPalette(p);
495
496 plot->setCanvasBackground(cache.canvasBackground);
497
498 const QwtPlotItemList& itmList = plot->itemList();
499 for ( QwtPlotItemIterator it = itmList.begin();
500 it != itmList.end(); ++it )
501 {
502 reset(*it);
503 }
504
505 delete d_data->cache;
506 d_data->cache = 0;
507
508 plot->setAutoReplot(doAutoReplot);
509 }
510
reset(QwtPlotItem * item) const511 void QwtPlotPrintFilter::reset(QwtPlotItem *item) const
512 {
513 if ( d_data->cache == 0 )
514 return;
515
516 const PrivateData::Cache &cache = *d_data->cache;
517
518 switch(item->rtti())
519 {
520 case QwtPlotItem::Rtti_PlotGrid:
521 {
522 QwtPlotGrid *grid = (QwtPlotGrid *)item;
523
524 QPen pen = grid->majPen();
525 pen.setColor(cache.gridColors[0]);
526 grid->setMajPen(pen);
527
528 pen = grid->minPen();
529 pen.setColor(cache.gridColors[1]);
530 grid->setMinPen(pen);
531
532 break;
533 }
534 case QwtPlotItem::Rtti_PlotCurve:
535 {
536 QwtPlotCurve *c = (QwtPlotCurve *)item;
537
538 QwtSymbol symbol = c->symbol();
539 //commented out by Ion Vasilief since this affects the symbol pen width.
540 //TO DO: report bug to Qwt developper
541 /*if ( cache.curveSymbolPenColors.contains(c) )
542 {
543 symbol.setPen(cache.curveSymbolPenColors[c]);
544 }*/
545
546 if ( cache.curveSymbolBrushColors.contains(c) )
547 {
548 QBrush brush = symbol.brush();
549 brush.setColor(cache.curveSymbolBrushColors[c]);
550 symbol.setBrush(brush);
551 }
552 c->setSymbol(symbol);
553
554 if ( cache.curveColors.contains(c) )
555 {
556 QPen pen = c->pen();
557 pen.setColor(cache.curveColors[c]);
558 c->setPen(pen);
559 }
560
561 break;
562 }
563 case QwtPlotItem::Rtti_PlotMarker:
564 {
565 QwtPlotMarker *m = (QwtPlotMarker *)item;
566
567 if ( cache.markerFonts.contains(m) )
568 {
569 QwtText label = m->label();
570 label.setFont(cache.markerFonts[m]);
571 m->setLabel(label);
572 }
573
574 if ( cache.markerLabelColors.contains(m) )
575 {
576 QwtText label = m->label();
577 label.setColor(cache.markerLabelColors[m]);
578 m->setLabel(label);
579 }
580
581 if ( cache.markerLineColors.contains(m) )
582 {
583 QPen pen = m->linePen();
584 pen.setColor(cache.markerLineColors[m]);
585 m->setLinePen(pen);
586 }
587
588 QwtSymbol symbol = m->symbol();
589
590 if ( cache.markerSymbolPenColors.contains(m) )
591 {
592 QPen pen = symbol.pen();
593 pen.setColor(cache.markerSymbolPenColors[m]);
594 symbol.setPen(pen);
595 }
596
597 if ( cache.markerSymbolBrushColors.contains(m) )
598 {
599 QBrush brush = symbol.brush();
600 brush.setColor(cache.markerSymbolBrushColors[m]);
601 symbol.setBrush(brush);
602 }
603
604 m->setSymbol(symbol);
605
606 break;
607 }
608 default:
609 break;
610 }
611 }
612