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