PLplot  5.15.0
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-2016 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 ) || defined ( PLD_memqt )
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
304 // Application. The aspect ratio of the plotted data is constant, so
305 // gray strips are used to delimit the page when the widget aspect
306 // ratio is not the one of the plotted page.
307 
308 // N.B. The moc application assumes that the first inherited class and
309 // only that inherited class is a subclass of QObject. Therefore,
310 // Qwidget (a subclass of QObject) must be first.
311 class PLDLLIMPEXP_QT QtPLWidget : public QWidget, public QtPLDriver
312 {
313  Q_OBJECT
314 
315 public:
316  // Parameters are the actual size of the page, NOT the size of the widget
317  // Call QWidget::resize for that
318  QtPLWidget( int i_iWidth = QT_DEFAULT_X, int i_iHeight = QT_DEFAULT_Y, QWidget * parent = 0 );
319 
320  virtual ~QtPLWidget();
321 
322  void clearWidget();
323  void clearBuffer();
324 
325  int pageNumber;
326 
327  void drawArc( short x, short y, short width, short height, PLFLT angle1, PLFLT angle2, PLFLT rotate, bool fill );
328  void drawLine( short x1, short y1, short x2, short y2 );
329  void drawPolyline( short * x, short * y, PLINT npts );
330  void drawPolygon( short * x, short * y, PLINT npts );
331  void setColor( int r, int g, int b, double alpha );
332  void setBackgroundColor( int r, int g, int b, double alpha );
333  void setGradient( int x1, int x2, int y1, int y2,
334  unsigned char *r, unsigned char *g,
335  unsigned char *b, PLFLT *alpha, PLINT ncol1 );
336  void setWidthF( PLFLT r );
337  void drawText( EscText* txt );
338  void flush();
339  void getCursorCmd( PLGraphicsIn *ptr );
340 
341 protected:
342 
343  void resizeEvent( QResizeEvent* );
344  void paintEvent( QPaintEvent* );
345  void mouseEvent( QMouseEvent * event );
346 
347  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
348  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
349  void renderText( QPainter* p, struct TextStruct_* s, double x_fact, double x_offset, double y_fact, double y_offset );
350  void lookupButtonEvent( QMouseEvent * event );
351  void locate();
352 
353  void resetPensAndBrushes( QPainter* );
354 
355  double m_dAspectRatio; // Is kept constant during resizes
356  QPixmap * m_pixPixmap; // stores the drawn image as long as it does not have to be regenerated
357 
358  QLinkedList<BufferElement> m_listBuffer; // Buffer holding the draw instructions
359 // bool m_bAwaitingRedraw;
360 // int m_iOldSize; // Holds the size of the buffer. Modified => image has to be redrawn
361  bool redrawFromLastFlush;
362  bool redrawAll;
363 
364  // Pens and brushes required to maintain the status between 2 flushes
365  QPen SolidPen;
366  QPen NoPen;
367  bool hasPen;
368  QBrush SolidBrush;
369  // end parameters
370 
371  QLinkedList<BufferElement>::const_iterator start_iterator;
372 
373  struct
374  {
375  int r;
376  int g;
377  int b;
378  double alpha;
379  } lastColour;
380 
381  struct
382  {
383  int r;
384  int g;
385  int b;
386  double alpha;
387  } bgColour;
388 
389  PLGraphicsIn gin; // Graphics Input Structure
390  int locate_mode; // Set while in locate mode
391 
392 protected slots:
393  void mousePressEvent( QMouseEvent * event );
394  void mouseReleaseEvent( QMouseEvent * event );
395  void mouseMoveEvent( QMouseEvent * event );
396  void keyPressEvent( QKeyEvent* event );
397  void closeEvent( QCloseEvent* event );
398  void nextPage();
399 };
400 
401 #endif
402 
403 #if defined ( PLD_extqt )
404 class PLDLLIMPEXP_QT QtExtWidget : public QtPLWidget
405 {
406  Q_OBJECT
407 
408 public:
409  QtExtWidget( int i_iWidth = QT_DEFAULT_X, int i_iHeight = QT_DEFAULT_Y, QWidget * parent = 0 );
410 
411  virtual ~QtExtWidget();
412 
413  void captureMousePlotCoords( PLFLT* x, PLFLT* y );
414 
415 public slots:
416 
417  void mouseMoveEvent( QMouseEvent* event );
418  void mouseReleaseEvent( QMouseEvent* event );
419  void mousePressEvent( QMouseEvent* event );
420 
421 protected:
422  void paintEvent( QPaintEvent* );
423 
424  struct
425  {
426  bool isTracking;
427  double cursor_x, cursor_y;
428  } cursorParameters;
429 
430  bool killed;
431 };
432 
433 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().
434 
435 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().
436 
437 PLDLLIMPEXP_QT void plfreeqtdev(); // Deletes and unregisters the device.
438 
439 #endif
440 
441 // These variables are declared in plqt.cpp but also needed
442 // by the qt driver.
443 extern PLDLLIMPEXP_QT_DATA( int ) vectorize;
444 extern PLDLLIMPEXP_QT_DATA( int ) lines_aa;
445 extern PLDLLIMPEXP_QT_DATA( MasterHandler ) handler;
446 
447 #if defined ( plplot_pyqt4_EXPORTS )
448 #define initplplot_pyqt4 PLDLLIMPEXP_PYQT4 initplplot_pyqt4
449 #endif
450 
451 #if defined ( plplot_pyqt5_EXPORTS )
452 #define initplplot_pyqt5 PLDLLIMPEXP_PYQT5 initplplot_pyqt5
453 #endif
454 
455 #endif
static char ** argv
Definition: qt.cpp:49
double downscale
Definition: qt.h:142
double currentFontSize
Definition: qt.h:158
PLUINT PLUNICODE
Definition: plplot.h:201
static int argc
Definition: qt.cpp:48
double yOffset
Definition: qt.h:159
double currentFontScale
Definition: qt.h:157
PLDLLIMPEXP_QT_DATA(int) vectorize
QPainter * m_painterP
Definition: qt.h:164
int PLINT
Definition: plplot.h:181
double m_dWidth
Definition: qt.h:143
static QMutex mutex
Definition: qt.h:144
QtPLDriver * masterDevice
Definition: qt.h:113
static const char * fileName
Definition: tkMain.c:134
bool overlined
Definition: qt.h:156
virtual void setBackgroundColor(int, int, int, double)
Definition: qt.h:134
bool underlined
Definition: qt.h:155
double xOffset
Definition: qt.h:160
static PLStream * pls[PL_NSTREAMS]
Definition: plcore.h:88
#define LINE
Definition: metadefs.h:61
Definition: qt.h:117
PLStream * pls
Definition: qt.h:162
static int text
Definition: ps.c:77
float PLFLT
Definition: plplot.h:163
#define PLDLLIMPEXP_QT
Definition: pldll.h:146
#define POLYLINE
Definition: metadefs.h:65
#define QT_DEFAULT_X
Definition: qt.h:89
#define QT_DEFAULT_Y
Definition: qt.h:90
PLDLLIMPEXP_CXX void fill(PLINT n, const PLFLT *x, const PLFLT *y)
Definition: plstream.cc:246