PLplot  5.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
qt.h
Go to the documentation of this file.
1 //
2 //
3 // This software is provided under the LGPL in March 2009 by the
4 // Cluster Science Centre
5 // QSAS team,
6 // Imperial College, London
7 //
8 // Copyright (C) 2009 Imperial College, London
9 // Copyright (C) 2009 Alan W. Irwin
10 //
11 // This is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Lesser Public License as published
13 // by the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
15 //
16 // This software is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Lesser General Public License for more details.
20 //
21 // To received a copy of the GNU Library General Public License
22 // write to the Free Software Foundation, Inc.,
23 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // History:
26 //
27 //
28 // March 2009: v1.00
29 // Initial release.
30 //
31 //
32 
33 //
34 // Interpretation of the -geometry XSIZExYSIZE option (or the third and fourth
35 // parameters of plspage if those are specified by the user instead) for
36 // the various devices:
37 // - the raster devices (bmpqt, jpgqt, pngqt, ppmqt, tiffqt):
38 // XSIZE and YSIZE define the x and y size in pixels
39 // - qtwidget:
40 // XSIZE and YSIZE define the default x and y size of the widget in
41 // pixels, as well as its aspect ratio, which is kept when the widget is
42 // resized.
43 // - svgqt, epsqt, pdfqt:
44 // XSIZE and YSIZE define the x and y size in points (1/72 of inches).
45 // EPS and PDF files will be drawn in A4 pages for Qt versions before 4.4
46 //
47 // Interpretation of the -dpi DPI option (or the first parameter of
48 // plspage if that is specified by the user instead).
49 // DPI is ignored for all but the raster devices. For those devices
50 // DPI should be set to the DPI value of the monitor being used to view
51 // the results if exact character sizes are desired. Otherwise, DEFAULT_DPI
52 // (set to an average value for modern monitors) is used instead.
53 //
54 
55 #ifndef QT_H
56 #define QT_H
57 
58 #include <iostream>
59 #include <QImage>
60 #include <QPainter>
61 #include <QLinkedList>
62 #include <QPrinter>
63 #include <QApplication>
64 #include <QWidget>
65 #include <QMouseEvent>
66 #include <QTabWidget>
67 #include <QMainWindow>
68 #include <QPicture>
69 #include <QMutex>
70 
71 #include "plDevs.h"
72 #include "plplotP.h"
73 #include "drivers.h"
74 
75 // Used for devices (epsqt, pdfqt, svgqt) with known physical size in points.
76 #define POINTS_PER_INCH 72
77 
78 // Average value of dots per inch assumed for modern monitors if the user
79 // does not specify a value appropriate to their monitor with plspage or
80 // the -dpi option. Used only for devices with size specified in pixels
81 // but not qtwidget since it has independent access to information (e.g.,
82 // delivered by X) about the DPI of the monitor. So this value is only
83 // used for the raster devices (bmpqt, jpgqt, pngqt, ppmqt, tiffqt).
84 #define DEFAULT_DPI 72
85 
86 // These values are in units of pixels (the raster devices and qtwidget)
87 // or points (epsqt, pdfqt, svgqt). In the points case, this corresponds
88 // to the A4 paper size.
89 #define QT_DEFAULT_X 842
90 #define QT_DEFAULT_Y 595
91 
92 class QtPLDriver;
93 
94 // Master Device Handler for multiple streams
95 // Only handles multiple Qt devices
96 class PLDLLIMPEXP_QT MasterHandler : public QObject
97 {
98  Q_OBJECT
99 
100 public:
101  MasterHandler();
102 
103  bool isMasterDevice( QtPLDriver* d );
104  void setMasterDevice( QtPLDriver* d );
105  void DeviceChangedPage( QtPLDriver* d );
106  void DeviceClosed( QtPLDriver* d );
107 
108 signals:
109  void MasterChangedPage();
110  void MasterClosed();
111 
112 protected:
114 };
115 
116 // Basic class, offering the common interface to all Qt plplot devices
118 {
119 public:
120  // Constructor, taking the device size as arguments
121  QtPLDriver( PLINT i_iWidth = QT_DEFAULT_X, PLINT i_iHeight = QT_DEFAULT_Y );
122 
123  virtual ~QtPLDriver(); // does not delete emitter!
124 
125  void setPLStream( PLStream *pls ); // store the related stream
126 
127  virtual void drawArc( short x, short y, short width, short height, PLFLT angle1, PLFLT angle2, PLFLT rotate, bool fill );
128  // Draws a line from (x1, y1) to (x2, y2) in internal plplot coordinates
129  virtual void drawLine( short x1, short y1, short x2, short y2 );
130  virtual void drawPolyline( short * x, short * y, PLINT npts );
131  virtual void drawPolygon( short * x, short * y, PLINT npts );
132  virtual void drawText( EscText* txt );
133  virtual void setColor( int r, int g, int b, double alpha );
134  virtual void setBackgroundColor( int /* r */, int /* g */, int /* b */, double /* alpha */ ){}
135  virtual void setGradient( int x1, int x2, int y1, int y2,
136  unsigned char *r, unsigned char *g,
137  unsigned char *b, PLFLT *alpha, PLINT ncol1 );
138  virtual void setWidthF( PLFLT w );
139  // Set pen to draw solid strokes (called after drawing dashed strokes)
140  virtual void setSolid();
141  // Conversion factor from internal plplot coordinates to device coordinates
142  double downscale;
143  double m_dWidth, m_dHeight;
144  static QMutex mutex; // All-purpose mutex
145 
146 protected:
147  // Returns font with the good size for a QPicture's resolution
148  QFont getFont( PLUNICODE code );
149  // Draws text in a QPicture using a sub-QPicture (!), updates the current xOffset
150  void drawTextInPicture( QPainter*, const QString& );
151  // Gets the QPicture displaying text, with the base chrht char height
152  QPicture getTextPicture( PLUNICODE fci, PLUNICODE* text, int len, PLFLT chrht );
153 
154  // Text-related variables
156  bool overlined;
159  double yOffset;
160  double xOffset;
161 
163 
164  QPainter * m_painterP;
165 };
166 
167 #if defined ( PLD_bmpqt ) || defined ( PLD_jpgqt ) || defined ( PLD_pngqt ) || defined ( PLD_ppmqt ) || defined ( PLD_tiffqt )
168 // Driver painting whatever raster format Qt can save
169 class PLDLLIMPEXP_QT QtRasterDevice : public QtPLDriver, public QImage
170 {
171 public:
172  QtRasterDevice( int i_iWidth = QT_DEFAULT_X,
173  int i_iHeight = QT_DEFAULT_Y );
174  virtual ~QtRasterDevice();
175 
176  virtual void setBackgroundColor( int r, int g, int b, double alpha );
177  void definePlotName( const char* fileName, const char* format );
178  void savePlot();
179  virtual void setResolution( double dotsPerInch )
180  {
181  setDotsPerMeterX( (int) ( ( dotsPerInch / 25.4 ) * 1000. ) );
182  setDotsPerMeterY( (int) ( ( dotsPerInch / 25.4 ) * 1000. ) );
183  }
184  // used by the memqt driver
185  unsigned char *memory;
186 
187 protected:
188  char format[5];
189  QString fileName;
190 };
191 #endif
192 
193 #if defined ( PLD_svgqt ) && QT_VERSION >= 0x040300
194 #include <QSvgGenerator>
195 // Driver painting on an SVG device
196 class PLDLLIMPEXP_QT QtSVGDevice : public QtPLDriver, public QSvgGenerator
197 {
198 public:
199  QtSVGDevice( int i_iWidth = QT_DEFAULT_X,
200  int i_iHeight = QT_DEFAULT_Y );
201 
202  virtual ~QtSVGDevice();
203 
204  virtual void setBackgroundColor( int r, int g, int b, double alpha );
205  void definePlotName( const char* fileName );
206  void savePlot();
207 
208 protected:
209 };
210 #endif
211 
212 #if defined ( PLD_epsqt ) || defined ( PLD_pdfqt )
213 // Driver painting on an EPS or PDF device, uses QPrinter
214 // A (possibly dummy) QApplication must be declared before use
215 class PLDLLIMPEXP_QT QtEPSDevice : public QtPLDriver, public QPrinter
216 {
217 public:
218 #if QT_VERSION < 0x040400
219  QtEPSDevice( int i_iWidth = -1, int i_iHeight = -1 );
220 #else
221  QtEPSDevice( int i_iWidth = QT_DEFAULT_X, int i_iHeight = QT_DEFAULT_Y );
222 #endif
223 
224  virtual ~QtEPSDevice();
225 
226  virtual void setBackgroundColor( int r, int g, int b, double alpha );
227  void definePlotName( const char* fileName, int ifeps );
228  void savePlot();
229 
230 protected:
231 };
232 #endif
233 
234 #if defined ( PLD_qtwidget ) || defined ( PLD_extqt )
235 
236 typedef enum ElementType_
237 {
238  LINE,
239  POLYLINE,
240  POLYGON,
241  RECTANGLE,
242  SET_WIDTH,
243  SET_COLOUR,
244  SET_GRADIENT,
245  SET_SMOOTH,
246  TEXT,
247  SET_BG_COLOUR,
248  ARC
249 } ElementType; // Identifiers for elements of the buffer
250 
251 struct ColourStruct_
252 {
253  PLINT R, G, B, A;
254 };
255 
256 struct TextStruct_
257 {
258  PLFLT x;
259  PLFLT y;
260  PLFLT clipxmin;
261  PLFLT clipymin;
262  PLFLT clipxmax;
263  PLFLT clipymax;
264  PLFLT rotation;
265  PLFLT shear;
266  PLFLT stride;
267  PLFLT just;
268  PLUNICODE * text;
269  PLUNICODE fci;
270  PLINT len;
271  PLFLT chrht;
272 };
273 
274 struct ArcStruct_
275 {
276  QRectF *rect;
277  QPointF *dx;
278  int startAngle;
279  int spanAngle;
280  PLFLT rotate;
281  bool fill;
282 };
283 
284 class BufferElement
285 {
286 public:
287  ElementType Element;
288 
289  union DataType
290  {
291  QLineF * Line;
292  QPolygonF * Polyline;
293  QRectF * Rect;
294  QLinearGradient * LinearGradient;
295  struct ColourStruct_* ColourStruct;
296  struct TextStruct_ * TextStruct;
297  struct ArcStruct_ * ArcStruct;
298  PLINT intParam;
299  PLFLT fltParam;
300  } Data;
301 };
302 
303 // This widget allows to use plplot as a plotting engine in a Qt Application
304 // The aspect ratio of the plotted data is constant, so gray strips are used
305 // to delimit the page when the widget aspect ratio is not the one of the plotted page
306 class PLDLLIMPEXP_QT QtPLWidget : public QWidget, public QtPLDriver
307 {
308  Q_OBJECT
309 
310 public:
311  // Parameters are the actual size of the page, NOT the size of the widget
312  // Call QWidget::resize for that
313  QtPLWidget( int i_iWidth = QT_DEFAULT_X, int i_iHeight = QT_DEFAULT_Y, QWidget * parent = 0 );
314 
315  virtual ~QtPLWidget();
316 
317  void clearWidget();
318  void clearBuffer();
319 
320  int pageNumber;
321 
322  void drawArc( short x, short y, short width, short height, PLFLT angle1, PLFLT angle2, PLFLT rotate, bool fill );
323  void drawLine( short x1, short y1, short x2, short y2 );
324  void drawPolyline( short * x, short * y, PLINT npts );
325  void drawPolygon( short * x, short * y, PLINT npts );
326  void setColor( int r, int g, int b, double alpha );
327  void setBackgroundColor( int r, int g, int b, double alpha );
328  void setGradient( int x1, int x2, int y1, int y2,
329  unsigned char *r, unsigned char *g,
330  unsigned char *b, PLFLT *alpha, PLINT ncol1 );
331  void setWidthF( PLFLT r );
332  void drawText( EscText* txt );
333  void flush();
334  void getCursorCmd( PLGraphicsIn *ptr );
335 
336 protected:
337 
338  void resizeEvent( QResizeEvent* );
339  void paintEvent( QPaintEvent* );
340  void mouseEvent( QMouseEvent * event );
341 
342  void getPlotParameters( double & io_dXFact, double & io_dYFact, double & io_dXOffset, double & io_dYOffset ); // gives the parameters to scale and center the plot on the page
343  void doPlot( QPainter* p, double x_fact, double y_fact, double x_offset, double y_offset ); // Actually draws the plot. Deported in a function for readability
344  void renderText( QPainter* p, struct TextStruct_* s, double x_fact, double x_offset, double y_fact, double y_offset );
345  void lookupButtonEvent( QMouseEvent * event );
346  void locate();
347 
348  void resetPensAndBrushes( QPainter* );
349 
350  double m_dAspectRatio; // Is kept constant during resizes
351  QPixmap * m_pixPixmap; // stores the drawn image as long as it does not have to be regenerated
352 
353  QLinkedList<BufferElement> m_listBuffer; // Buffer holding the draw instructions
354 // bool m_bAwaitingRedraw;
355 // int m_iOldSize; // Holds the size of the buffer. Modified => image has to be redrawn
356  bool redrawFromLastFlush;
357  bool redrawAll;
358 
359  // Pens and brushes required to maintain the status between 2 flushes
360  QPen SolidPen;
361  QPen NoPen;
362  bool hasPen;
363  QBrush SolidBrush;
364  // end parameters
365 
366  QLinkedList<BufferElement>::const_iterator start_iterator;
367 
368  struct
369  {
370  int r;
371  int g;
372  int b;
373  double alpha;
374  } lastColour;
375 
376  struct
377  {
378  int r;
379  int g;
380  int b;
381  double alpha;
382  } bgColour;
383 
384  PLGraphicsIn gin; // Graphics Input Structure
385  int locate_mode; // Set while in locate mode
386 
387 protected slots:
388  void mousePressEvent( QMouseEvent * event );
389  void mouseReleaseEvent( QMouseEvent * event );
390  void mouseMoveEvent( QMouseEvent * event );
391  void keyPressEvent( QKeyEvent* event );
392  void closeEvent( QCloseEvent* event );
393  void nextPage();
394 };
395 
396 #endif
397 
398 #if defined ( PLD_extqt )
399 class PLDLLIMPEXP_QT QtExtWidget : public QtPLWidget
400 {
401  Q_OBJECT
402 
403 public:
404  QtExtWidget( int i_iWidth = QT_DEFAULT_X, int i_iHeight = QT_DEFAULT_Y, QWidget * parent = 0 );
405 
406  virtual ~QtExtWidget();
407 
408  void captureMousePlotCoords( PLFLT* x, PLFLT* y );
409 
410 public slots:
411 
412  void mouseMoveEvent( QMouseEvent* event );
413  void mouseReleaseEvent( QMouseEvent* event );
414  void mousePressEvent( QMouseEvent* event );
415 
416 protected:
417  void paintEvent( QPaintEvent* );
418 
419  struct
420  {
421  bool isTracking;
422  double cursor_x, cursor_y;
423  } cursorParameters;
424 
425  bool killed;
426 };
427 
428 PLDLLIMPEXP_QT void plsetqtdev( QtExtWidget* widget ); // Registers the widget as plot device, as the widget has to be created in the Qt application GUI, prior to any plplot call. Must be called before plinit().
429 
430 PLDLLIMPEXP_QT void plsetqtdev( QtExtWidget* widget, int argc, char** argv ); // Registers the widget as plot device, as the widget has to be created in the Qt application GUI, prior to any plplot call. Must be called before plinit().
431 
432 PLDLLIMPEXP_QT void plfreeqtdev(); // Deletes and unregisters the device.
433 
434 #endif
435 
436 // These variables are declared in plqt.cpp but also needed
437 // by the qt driver.
438 extern PLDLLIMPEXP_QT_DATA( int ) vectorize;
439 extern PLDLLIMPEXP_QT_DATA( int ) lines_aa;
440 extern PLDLLIMPEXP_QT_DATA( MasterHandler ) handler;
441 
442 #if defined ( plplot_pyqt4_EXPORTS )
443 #define initplplot_pyqt4 PLDLLIMPEXP_PYQT4 initplplot_pyqt4
444 #endif
445 
446 #endif