From: <ai...@us...> - 2009-03-05 17:36:00
|
Revision: 9676 http://plplot.svn.sourceforge.net/plplot/?rev=9676&view=rev Author: airwin Date: 2009-03-05 17:35:49 +0000 (Thu, 05 Mar 2009) Log Message: ----------- AWI for Alban Rochel. Properly handle the non-availability of SVG on Qt 4.2. Modified Paths: -------------- trunk/cmake/modules/qt.cmake trunk/drivers/qt.cpp trunk/drivers/qt.h Modified: trunk/cmake/modules/qt.cmake =================================================================== --- trunk/cmake/modules/qt.cmake 2009-03-05 16:07:41 UTC (rev 9675) +++ trunk/cmake/modules/qt.cmake 2009-03-05 17:35:49 UTC (rev 9676) @@ -1,26 +1,10 @@ -# Naive way to (try to?) dissociate the SVG driver (not available on Qt 4.2) from the other drivers. Yet to be tested! - -if(PLD_svgqt) - FIND_PACKAGE(Qt4) - SET(QT_USE_QTSVG 1) +FIND_PACKAGE(Qt4) +if(PLD_rasterqt OR PLD_epspdfqt OR PLD_qtwidget OR PLD_svgqt) +if(PLD_svgqt AND ${QT_VERSION_MINOR} GREATER 2) + SET(QT_USE_QTSVG 1) +endif(PLD_svgqt AND ${QT_VERSION_MINOR} GREATER 2) INCLUDE(${QT_USE_FILE}) if(NOT QT4_FOUND) - set(PLD_svgqt OFF CACHE BOOL "Enable Qt SVG device" FORCE) - else(NOT QT4_FOUND) - set(qt_COMPILE_FLAGS) - foreach(DIR ${QT_INCLUDES}) - set(qt_COMPILE_FLAGS "${qt_COMPILE_FLAGS} -I${DIR}") - endforeach(DIR ${QT_INCLUDES}) - - set(qt_LINK_FLAGS ${QT_LIBRARIES}) - set(DRIVERS_LINK_FLAGS ${DRIVERS_LINK_FLAGS} ${qt_LINK_FLAGS}) - endif(NOT QT4_FOUND) -endif(PLD_svgqt) - -if(PLD_rasterqt OR PLD_epspdfqt OR PLD_qtwidget) - FIND_PACKAGE(Qt4) - INCLUDE(${QT_USE_FILE}) - if(NOT QT4_FOUND) set(PLD_rasterqt OFF CACHE BOOL "Enable Qt raster device" FORCE) set(PLD_epspdfqt OFF CACHE BOOL "Enable Qt EPS/PDF device" FORCE) set(PLD_qtwidget OFF CACHE BOOL "Enable Qt EPS/PDF device" FORCE) @@ -33,4 +17,4 @@ set(qt_LINK_FLAGS ${QT_LIBRARIES}) set(DRIVERS_LINK_FLAGS ${DRIVERS_LINK_FLAGS} ${qt_LINK_FLAGS}) endif(NOT QT4_FOUND) -endif(PLD_rasterqt OR PLD_epspdfqt OR PLD_qtwidget) \ No newline at end of file +endif(PLD_rasterqt OR PLD_epspdfqt OR PLD_qtwidget OR PLD_svgqt) \ No newline at end of file Modified: trunk/drivers/qt.cpp =================================================================== --- trunk/drivers/qt.cpp 2009-03-05 16:07:41 UTC (rev 9675) +++ trunk/drivers/qt.cpp 2009-03-05 17:35:49 UTC (rev 9676) @@ -21,16 +21,22 @@ write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + History: + + + March 2009: v1.00 + Initial release. + */ #include "qt.h" -// #include "moc_qt.cxx" +// Drivers declaration PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_qt = #if defined(PLD_rasterqt) "rasterqt:Qt Raster driver:0:qt:66:rasterqt\n" #endif -#if defined(PLD_svgqt) +#if defined(PLD_svgqt) && QT_VERSION >= 0x040300 "svgqt:Qt SVG driver:0:qt:67:svgqt\n" #endif #if defined(PLD_epspdfqt) @@ -41,13 +47,14 @@ #endif ; +// Declaration of the driver-specific interface functions #if defined(PLD_rasterqt) void plD_dispatch_init_rasterqt(PLDispatchTable *pdt); void plD_init_rasterqt(PLStream *); void plD_eop_rasterqt(PLStream *); #endif -#if defined(PLD_svgqt) +#if defined(PLD_svgqt) && QT_VERSION >= 0x040300 void plD_dispatch_init_svgqt(PLDispatchTable *pdt); void plD_init_svgqt(PLStream *); void plD_eop_svgqt(PLStream *); @@ -65,6 +72,8 @@ void plD_eop_qtwidget(PLStream *); #endif +// Declaration of the generic interface functions + void plD_line_qt(PLStream *, short, short, short, short); void plD_polyline_qt(PLStream *, short*, short*, PLINT); void plD_bop_qt(PLStream *){} @@ -292,6 +301,7 @@ { } +// Draw the content of the buffer void QtPLBufferedDriver::doPlot(QPainter* i_painterP, double x_fact, double y_fact, double x_offset, double y_offset) { QLineF line; @@ -395,15 +405,17 @@ io_dYOffset=0.; } -//////////////////// Generic driver interface /////////////// +// Generic driver interface + void plD_line_qt(PLStream * pls, short x1a, short y1a, short x2a, short y2a) { QtPLDriver * widget=NULL; + // We have to dynamic_cast to make sure the good virtual functions are called #if defined(PLD_rasterqt) if(widget==NULL) widget=dynamic_cast<QtRasterDevice*>((QtPLDriver *) pls->dev); #endif -#if defined(PLD_svgqt) +#if defined(PLD_svgqt) && QT_VERSION >= 0x040300 if(widget==NULL) widget=dynamic_cast<QtSVGDevice*>((QtPLDriver *) pls->dev); #endif #if defined(PLD_epspdfqt) @@ -424,7 +436,7 @@ #if defined(PLD_rasterqt) if(widget==NULL) widget=dynamic_cast<QtRasterDevice*>((QtPLDriver *) pls->dev); #endif -#if defined(PLD_svgqt) +#if defined(PLD_svgqt) && QT_VERSION >= 0x040300 if(widget==NULL) widget=dynamic_cast<QtSVGDevice*>((QtPLDriver *) pls->dev); #endif #if defined(PLD_epspdfqt) @@ -447,7 +459,7 @@ #if defined(PLD_rasterqt) if(widget==NULL) widget=dynamic_cast<QtRasterDevice*>((QtPLDriver *) pls->dev); #endif -#if defined(PLD_svgqt) +#if defined(PLD_svgqt) && QT_VERSION >= 0x040300 if(widget==NULL) widget=dynamic_cast<QtSVGDevice*>((QtPLDriver *) pls->dev); #endif #if defined(PLD_epspdfqt) @@ -483,7 +495,7 @@ delete[] ya; break; - default: break; + default: break; } } @@ -493,7 +505,7 @@ #if defined(PLD_rasterqt) if(widget==NULL) widget=dynamic_cast<QtRasterDevice*>((QtPLDriver *) pls->dev); #endif -#if defined(PLD_svgqt) +#if defined(PLD_svgqt) && QT_VERSION >= 0x040300 if(widget==NULL) widget=dynamic_cast<QtSVGDevice*>((QtPLDriver *) pls->dev); #endif #if defined(PLD_epspdfqt) @@ -523,20 +535,27 @@ } } +////////////////// Raster driver-specific definitions: class and interface functions ///////// + #if defined(PLD_rasterqt) QtRasterDevice::QtRasterDevice(int i_iWidth, int i_iHeight): QtPLDriver(i_iWidth, i_iHeight), QImage(i_iWidth, i_iHeight, QImage::Format_RGB32) { + // Painter initialised in the constructor contrary + // to buffered drivers, which paint only in doPlot(). m_painterP=new QPainter(this); QBrush b=m_painterP->brush(); b.setStyle(Qt::SolidPattern); m_painterP->setBrush(b); m_painterP->setRenderHint(QPainter::Antialiasing, true); + // Let's fill the background m_painterP->fillRect(0, 0, width(), height(), QBrush(Qt::black)); + // For page numbering pageCounter=0; } +// Used to append _page# when multiple pages QString QtRasterDevice::getFileName(char* fileName) { QString fn(fileName); @@ -593,8 +612,10 @@ pls->dev_clear=1; pls->termin=0; + // Initialised with the default (A4) size pls->dev=new QtRasterDevice; + // Shamelessly copied on the Cairo stuff :) if (pls->xlength <= 0 || pls->ylength <= 0) { pls->xlength = ((QtRasterDevice*)(pls->dev))->m_dWidth; @@ -622,7 +643,7 @@ #endif -#if defined(PLD_svgqt) +#if defined(PLD_svgqt) && QT_VERSION >= 0x040300 QtSVGDevice::QtSVGDevice(int i_iWidth, int i_iHeight): QtPLBufferedDriver(i_iWidth, i_iHeight) { @@ -714,6 +735,8 @@ QSize s; ((QtSVGDevice *)pls->dev)->savePlot(pls->FileName); + // Once saved, we have to create a new device with the same properties + // to be able to plot another page. downscale=((QtSVGDevice *)pls->dev)->downscale; pageCounter=((QtSVGDevice *)pls->dev)->pageCounter; s=((QtSVGDevice *)pls->dev)->size(); @@ -810,14 +833,15 @@ int argc=0; char argv[]={'\0'}; + // QPrinter devices won't create if there is no QApplication declared... QApplication * app=new QApplication(argc, (char**)&argv); pls->dev=new QtEPSDevice; delete app; if (pls->xlength <= 0 || pls->ylength <= 0) { - pls->xlength = ((QtSVGDevice*)(pls->dev))->m_dWidth; - pls->ylength = ((QtSVGDevice*)(pls->dev))->m_dHeight; + pls->xlength = ((QtEPSDevice*)(pls->dev))->m_dWidth; + pls->ylength = ((QtEPSDevice*)(pls->dev))->m_dHeight; } if (pls->xlength > pls->ylength) @@ -843,8 +867,10 @@ char argv[]={'\0'}; ((QtEPSDevice *)pls->dev)->savePlot(pls->FileName); - downscale=((QtSVGDevice *)pls->dev)->downscale; - pageCounter=((QtSVGDevice *)pls->dev)->pageCounter; + // Once saved, we have to create a new device with the same properties + // to be able to plot another page. + downscale=((QtEPSDevice *)pls->dev)->downscale; + pageCounter=((QtEPSDevice *)pls->dev)->pageCounter; delete ((QtEPSDevice *)pls->dev); QApplication * app=new QApplication(argc, (char**)&argv); @@ -954,7 +980,7 @@ double x_fact, y_fact, x_offset(0.), y_offset(0.); //Parameters to scale and center the plot on the widget getPlotParameters(x_fact, y_fact, x_offset, y_offset); - // If actual redraw + // If actual redraw, not just adding the cursor acquisition traces if(m_bAwaitingRedraw || m_pixPixmap==NULL || m_listBuffer.size()!=m_iOldSize ) { if(m_pixPixmap!=NULL) delete m_pixPixmap; @@ -1077,14 +1103,14 @@ if(w/h>m_dAspectRatio) //Too wide, h is the limitating factor { io_dYFact=h/m_dHeight; - io_dXFact=h*m_dAspectRatio/m_dWidth;//io_dYFact*m_dAspectRatio; + io_dXFact=h*m_dAspectRatio/m_dWidth; io_dYOffset=0.; io_dXOffset=(w-io_dXFact*m_dWidth)/2.; } else { io_dXFact=w/m_dWidth; - io_dYFact=w/m_dAspectRatio/m_dHeight;//io_dXFact/m_dAspectRatio; + io_dYFact=w/m_dAspectRatio/m_dHeight; io_dXOffset=0.; io_dYOffset=(h-io_dYFact*m_dHeight)/2.; } Modified: trunk/drivers/qt.h =================================================================== --- trunk/drivers/qt.h 2009-03-05 16:07:41 UTC (rev 9675) +++ trunk/drivers/qt.h 2009-03-05 17:35:49 UTC (rev 9676) @@ -21,6 +21,12 @@ write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + History: + + + March 2009: v1.00 + Initial release. + */ #ifndef QT_H @@ -30,7 +36,6 @@ #include <QImage> #include <QPainter> #include <QLinkedList> -#include <QSvgGenerator> #include <QPrinter> #include <QApplication> #include <QWidget> @@ -43,6 +48,7 @@ #define QT_DEFAULT_X 842 #define QT_DEFAULT_Y 598 +// Types of buffer elements for buffered widgets typedef enum ElementType_ { LINE, @@ -55,6 +61,7 @@ SET_SMOOTH } ElementType; +// A buffer element in a buffered widget class BufferElement { public: @@ -88,16 +95,18 @@ } Data; }; - +// Basic class, offering the common interface to all Qt plplot devices class QtPLDriver { public: + // Constructor, taking the device size as arguments QtPLDriver(PLINT i_iWidth=QT_DEFAULT_X, PLINT i_iHeight=QT_DEFAULT_Y); virtual ~QtPLDriver(); - + + // Draws a line from (x1, y1) to (x2, y2) in internal plplot coordinates virtual void drawLine(short x1, short y1, short x2, short y2); - + virtual void drawPolyline(short * x, short * y, PLINT npts); virtual void drawPolygon(short * x, short * y, PLINT npts); @@ -108,10 +117,12 @@ virtual void setDashed(PLINT nms, PLINT* mark, PLINT* space); + // Set pen to draw solid strokes (called after drawing dashed strokes) virtual void setSolid(); virtual void savePlot(char* fileName); + // Conversion factor from internal plplot coordinates to device coordinates double downscale; double m_dWidth, m_dHeight; protected: @@ -119,6 +130,9 @@ QPainter* m_painterP; }; +// This device is used in two situations: +// - if the device can only start plotting when given a destination file (SVG, EPS, PDF), then we have to accumulate the plot commands before printing them when eop() is called +// - If the device may have to redraw (Widget), then the accumulated commands are re-issued, possibly corrected to fit a new device size class QtPLBufferedDriver: public QtPLDriver { public: @@ -126,6 +140,7 @@ virtual ~QtPLBufferedDriver(); + // Accumulates a line command in the end of the buffer virtual void drawLine(short x1, short y1, short x2, short y2); virtual void drawPolyline(short * x, short * y, PLINT npts); @@ -142,18 +157,30 @@ virtual void savePlot(char* fileName); + // Actually plots on the device, using the p QPainter. + // if p is null, then the defaut QPainter m_painterP is used. + // x_fact, y_fact, x_offset and y_offset allow to center the plot + // on the device + // These 5 parameters are actually only used for widgets: + // widgets plot on a pixmap via p, and as the aspect ratio of + // what's drawn is set constant yet taking as much space as possible, + // offsets and factors have to be set + virtual void doPlot(QPainter* p=NULL, double x_fact=1., double y_fact=1., double x_offset=0., double y_offset=0.); + protected: - virtual void doPlot(QPainter* p=NULL, double x_fact=1., double y_fact=1., double x_offset=0., double y_offset=0.); - + // Gets the offsets and factors using the current size of the device virtual void getPlotParameters(double & io_dXFact, double & io_dYFact, double & io_dXOffset, double & io_dYOffset); + // Empties the buffer void clearBuffer(); + // Here is the buffer QLinkedList<BufferElement> m_listBuffer; }; #if defined (PLD_rasterqt) +// Driver painting whatever raster format Qt can save class QtRasterDevice: public QtPLDriver, public QImage { public: @@ -162,17 +189,21 @@ virtual ~QtRasterDevice(){} - QString getFileName(char* fileName); - + // Saves the plot to the fileName file, possibly appending + // _page# to the file name if not the 1st page void savePlot(char* fileName); protected: + // Generates the actual file name, depending on fileName and pageCounter + QString getFileName(char* fileName); int pageCounter; }; #endif -#if defined (PLD_svgqt) +#if defined(PLD_svgqt) && QT_VERSION >= 0x040300 +#include <QSvgGenerator> +// Driver painting on an SVG device class QtSVGDevice: public QtPLBufferedDriver, public QSvgGenerator { public: @@ -180,17 +211,18 @@ int i_iHeight=QT_DEFAULT_Y); virtual ~QtSVGDevice(); - - QString getFileName(char* fileName); void savePlot(char* fileName); - int pageCounter; + int pageCounter; // public because read and written by plD_eop protected: + QString getFileName(char* fileName); }; #endif #if defined (PLD_epspdfqt) +// Driver painting on an EPS or PDF device, uses QPrinter +// A (possibly dummy) QApplication must be declared before use class QtEPSDevice: public QtPLBufferedDriver, public QPrinter { public: @@ -202,14 +234,16 @@ void savePlot(char* fileName); - int pageCounter; + int pageCounter;// public because read and written by plD_eop protected: }; #endif #if defined (PLD_qtwidget) - +// This widget allows to use plplot as a plotting engine in a Qt Application +// The aspect ratio of the plotted data is constant, so gray strips are used +// to delimit the page when the widget aspect ratio is not the one of the plotted page class QtPLWidget: public QWidget, public QtPLBufferedDriver { Q_OBJECT @@ -221,13 +255,29 @@ virtual ~QtPLWidget(); + // This is an addition to plplot drawing routines. + // Calling setSmooth(...) will (de)activate anti-aliasing in plotting + // For example: + // plotWidget->setSmooth(true); + // plbox(...); + // plotWidget->setSmooth(false); + // plline(...) + // will only smooth the axes and their labels. void setSmooth(bool); + // Clears the widget void clearWidget(); public slots: + // This slot can be used to select an x/y range interactively + // xi, yi, xf and yf are the initial and final points coordinates + // in their respective windows, 0 if outside a window void captureMousePlotCoords(double* xi, double* yi, double* xf, double* yf); + + // This slot can be used to select an x/y range interactively + // xi, yi, xf and yf are the initial and final points coordinates + // in the whole page (normalized between 0 and 1) void captureMouseDeviceCoords(double* xi, double* yi, double* xf, double* yf); protected slots: @@ -240,8 +290,10 @@ protected: + // Used to center the plot on the page void getPlotParameters(double & io_dXFact, double & io_dYFact, double & io_dXOffset, double & io_dYOffset); + // Used for cursor tracking (capture[...] slots) struct { bool isTracking; @@ -256,6 +308,15 @@ int m_iOldSize; }; +// This function must be called between plinit to set up the widget +// The widget is created within the Qt Application +// e.g.: +// QtPLWidget*plot=new QtPLWidget(QT_DEFAULT_X, QT_DEFAULT_Y, this); +// plmkstrm(&strm); +// plsqtdev(plot); +// plsdev ("qtwidget"); +// plinit(); +// ... void plsqtdev(QtPLWidget *plotdev); #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |