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