casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
QPPlotItem.qo.h
Go to the documentation of this file.
00001 //# QPPlotItem.qo.h: Superclass for all plot items in qwt plotter.
00002 //# Copyright (C) 2008
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: $
00027 #ifndef QPPLOTITEM_H_
00028 #define QPPLOTITEM_H_
00029 
00030 #ifdef AIPS_HAS_QWT
00031 
00032 #include <graphics/GenericPlotter/PlotItem.h>
00033 
00034 #include <casaqt/QwtPlotter/QPImageCache.h>
00035 #include <graphics/GenericPlotter/PlotLogger.h>
00036 #include <graphics/GenericPlotter/PlotOperation.h>
00037 
00038 #include <QHash>
00039 #include <QPainter>
00040 #include <QThread>
00041 
00042 #include <qwt_plot.h>
00043 
00044 #include <casa/namespace.h>
00045 
00046 namespace casa {
00047 
00048 //# Forward Declarations
00049 class QPCanvas;
00050 
00051 
00052 // Abstract superclass for any layered item that will be drawn on a
00053 // QPLayeredCanvas.
00054 class QPLayerItem : public virtual QwtPlotItem {
00055     friend class QPCanvas;
00056     friend class QPLayeredCanvas;
00057     friend class QPDrawThread;
00058     
00059 public:
00060     // Constructor.
00061     QPLayerItem();
00062     
00063     // Destructor.
00064     virtual ~QPLayerItem();
00065     
00066     
00067     // Implements QwtPlotItem::draw().
00068     virtual void draw(QPainter* p, const QwtScaleMap& xMap,
00069             const QwtScaleMap& yMap, const QRect& canvasRect) const;
00070     
00071     // See PlotItem::drawSegments().
00072     virtual unsigned int itemDrawSegments(unsigned int segmentThreshold) const;
00073     
00074     
00075     // ABSTRACT METHODS //
00076     
00077     // Forces subclasses to override QwtPlotItem::itemChanged() to redraw only
00078     // the necessary layer.
00079     virtual void itemChanged() = 0;
00080     
00081     // Returns true if this item should be drawn, false otherwise.  This is
00082     // used to avoid drawing attached items that are empty or otherwise have
00083     // nothing to draw.
00084     virtual bool shouldDraw() const = 0;
00085     
00086     // See PlotItem::drawCount().
00087     virtual unsigned int itemDrawCount() const = 0;
00088     
00089     // See PlotItem::title().
00090     virtual String itemTitle() const = 0;
00091     
00092 protected:
00093     // Like QwtPlotItem::draw() except that the child item should only draw
00094     // drawCount items starting at drawIndex.  The indexing may not be
00095     // applicable to all layer items (i.e., some items may draw everything in
00096     // this call rather than segmenting).
00097     virtual void draw_(QPainter* p, const QwtScaleMap& xMap,
00098             const QwtScaleMap& yMap, const QRect& drawRect,
00099             unsigned int drawIndex, unsigned int drawCount) const = 0;
00100 };
00101 
00102 
00103 // Subclass of PlotItem to take care of common functionality that is provided
00104 // by QwtPlotItem.
00105 class QPPlotItem : public virtual PlotItem, public QPLayerItem {
00106     friend class QPCanvas;
00107     friend class QPDrawThread;
00108     
00109 public:
00110     // Static //
00111     
00112     // Convenient access to "origin" name for draw method for logging.
00113     static const String DRAW_NAME;
00114     
00115     
00116     // Returns true if the given pointer is a Qwt plotter implementation,
00117     // false otherwise.
00118     static bool isQPPlotItem(const PlotItemPtr item);
00119     
00120     // If the given item is not a Qwt plotter implementation, returns a copy
00121     // of the proper class.  Otherwise, returns the item.  If wasCloned is
00122     // given, it will be set to true if the returned item is new, false
00123     // otherwise.
00124     static QPPlotItem* cloneItem(const PlotItemPtr item, bool* wasCloned=NULL);
00125     
00126     // Returns true if the two items are the same type (class), false
00127     // otherwise.
00128     static bool sameType(QPPlotItem* item1, QPPlotItem* item2);
00129     
00130     // Returns true if the given item is a Plot type (QPBarPlot, QPHistogram,
00131     // QPRasterPlot, or QPScatterPlot) or not.
00132     static bool isPlot(QPPlotItem* item);
00133     
00134     
00135     // Non-Static //
00136     
00137     // Constructor.
00138     QPPlotItem();
00139     
00140     // Destructor.
00141     virtual ~QPPlotItem();
00142     
00143     
00144     // PlotItem methods //
00145     
00146     // Implements PlotItem::canvas().
00147     PlotCanvas* canvas() const;
00148     
00149     // Implements PlotItem::title().
00150     String title() const;
00151     
00152     // Implements PlotItem::setTitle().
00153     void setTitle(const String& newTitle);
00154     
00155     // Implements PlotItem::isQWidget().
00156     virtual bool isQWidget() const { return false; }
00157     
00158     // Implements PlotItem::xAxis().
00159     PlotAxis xAxis() const;
00160     
00161     // Implements PlotItem::yAxis().
00162     PlotAxis yAxis() const;
00163     
00164     // Implements PlotItem::setXAxis().
00165     void setXAxis(PlotAxis x);
00166     
00167     // Implements PlotItem::setYAxis().
00168     void setYAxis(PlotAxis y);
00169     
00170     
00171     // QPLayerItem methods //
00172     
00173     // Implements QPLayerItem::itemChanged() to only redraw the canvas layer
00174     // this item is in.
00175     virtual void itemChanged();
00176     
00177     // Implements QPLayerItem::shouldDraw().
00178     virtual bool shouldDraw() const { return isValid(); }
00179     
00180     // Implements QPLayerItem::itemDrawCount().
00181     unsigned int itemDrawCount() const{ return shouldDraw()? drawCount() : 0; }
00182     
00183     // Implements QPLayerItem::itemTitle().
00184     String itemTitle() const { return title(); }
00185     
00186     
00187     // QPPlotItem methods //
00188     
00189     // Returns the layer this item is attached to.
00190     PlotCanvasLayer canvasLayer() const { return m_layer; }
00191     
00192     // Provides access to QwtPlotItem methods that have been overloaded.
00193     // <group>
00194     const QwtText& qwtTitle() const { return QwtPlotItem::title(); }
00195     void setQwtTitle(const QwtText& text) { QwtPlotItem::setTitle(text); }
00196     QwtPlot::Axis qwtXAxis() const{return QwtPlot::Axis(QwtPlotItem::xAxis());}
00197     QwtPlot::Axis qwtYAxis() const{return QwtPlot::Axis(QwtPlotItem::yAxis());}    
00198     void qwtAttach(QwtPlot* plot) { QwtPlotItem::attach(plot); }
00199     void qwtDetach() { QwtPlotItem::detach(); }
00200     // </group>
00201 
00202     
00203     // ABSTRACT METHODS //
00204     
00205     // Forces children to override QwtPlotItem::boundingRect().
00206     virtual QwtDoubleRect boundingRect() const = 0;
00207     
00208     // Forces children to override QwtPlotItem::legendItem().
00209     virtual QWidget* legendItem() const = 0;
00210     
00211 protected:    
00212     // Attached canvas (or NULL for none).
00213     QPCanvas* m_canvas;
00214     
00215     // Flag for whether this object's creation has been logged or not.  This
00216     // happens the first time the item is attached to a canvas.
00217     bool m_loggedCreation;
00218     
00219     // Which layer this item is in.
00220     PlotCanvasLayer m_layer;
00221     
00222     
00223     // Provides access to QwtPlotItem's attach and detach methods for QPCanvas.
00224     // <group>
00225     void attach(QPCanvas* canvas, PlotCanvasLayer layer);
00226     void detach();
00227     // </group>
00228     
00229     // Provides access to the plotter's logger for children.
00230     PlotLoggerPtr logger() const;
00231     
00232     // Provides access to logging destruction, for children.  Should be called
00233     // in children's destructor.
00234     void logDestruction();
00235     
00236     // Provides access to log method enter/exit, for children.
00237     void logMethod(const String& methodName, bool entering,
00238             const String& message = String()) const;
00239     
00240     // Provides access to QPCanvas's draw operation for children.
00241     PlotOperationPtr drawOperation() const;
00242     
00243     
00244     // ABSTRACT METHODS //
00245     
00246     // Returns the class name for the child, for logging purposes.
00247     virtual const String& className() const = 0;
00248 };
00249 
00250 
00251 // Thread for drawing multiple QPPlotItems into QPImageCaches based on its
00252 // canvas layer.  Once the thread is finished, the QPImageCaches can be copied
00253 // to the canvas caches and shown on the GUI widget as needed.  The thread will
00254 // emit a signal after each "segment" is drawn, either the whole item for small
00255 // items or part of a large item.
00256 class QPDrawThread : public QThread {
00257     Q_OBJECT
00258     
00259 public:
00260     // Static //
00261     
00262     // Convenient access to class name.
00263     static const String CLASS_NAME;
00264     
00265     // Returns the default segment threshold.
00266     static const unsigned int DEFAULT_SEGMENT_THRESHOLD;
00267     
00268     // Returns item1->z() < item2->z().
00269     // <group>
00270     static bool itemSortByZ(const QPLayerItem* item1,const QPLayerItem* item2);
00271     // </group>
00272     
00273     // Draws the given items, sorted by z-order, using the given painter, rect,
00274     // and maps.  If PlotOperation parameters are given, they are updated as
00275     // needed.
00276     // <group>
00277     static void drawItem(const QPLayerItem* item, QPainter* painter,
00278             const QRect& rect, const QwtScaleMap maps[QwtPlot::axisCnt]);
00279     static void drawItem(const QPLayerItem* item, QPainter* painter,
00280             const QRect& rect, const QwtScaleMap maps[QwtPlot::axisCnt],
00281             unsigned int drawIndex, unsigned int drawCount);
00282     static void drawItems(const QList<const QPLayerItem*>& items,
00283             QPainter* painter, const QRect& rect,
00284             const QwtScaleMap maps[QwtPlot::axisCnt],
00285             PlotOperationPtr op = PlotOperationPtr(),
00286             unsigned int currentSegment = 0, unsigned int totalSegments = 0,
00287             unsigned int segmentThreshold =
00288                 QPDrawThread::DEFAULT_SEGMENT_THRESHOLD);
00289     static void drawItems(const QList<const QPPlotItem*>& items,
00290             QPainter* painter, const QRect& rect,
00291             const QwtScaleMap maps[QwtPlot::axisCnt],
00292             PlotOperationPtr op = PlotOperationPtr(),
00293             unsigned int currentSegment = 0, unsigned int totalSegments = 0,
00294             unsigned int segmentThreshold =
00295                 QPDrawThread::DEFAULT_SEGMENT_THRESHOLD);
00296     // </group>
00297     
00298     
00299     // Non-Static //
00300     
00301     // Constructor which takes a list of items to draw, axes maps, the drawing
00302     // rectangle, an optional fixed image size, and an optional segment
00303     // threshold.
00304     QPDrawThread(const QList<const QPPlotItem*>& items,
00305             const QwtScaleMap maps[QwtPlot::axisCnt], QSize imageSize,
00306             unsigned int segmentTreshold = DEFAULT_SEGMENT_THRESHOLD);
00307     
00308     // Destructor.
00309     ~QPDrawThread();
00310     
00311     // Returns the total segments that will be drawn.  This is AT LEAST the
00312     // number of items to be drawn.
00313     unsigned int totalSegments() const;
00314     
00315     // Implements QThread::run().  Draws the items into one of the two images
00316     // depending on their layers.  Emits segmentDrawn() after each segment is
00317     // finished.
00318     void run();
00319     
00320     // Returns the image result for the given layer.  Should only be done AFTER
00321     // the thread is finished.  If clearResult is true, then the resulting
00322     // image is removed from the thread's images.
00323     QPImageCache drawResult(PlotCanvasLayer layer, bool clearResult = true);
00324     
00325 public slots:
00326     // Cancels this thread.  If the thread is currently running, it will finish
00327     // the segment it is on and then stop.
00328     void cancel();
00329     
00330 private:
00331     // Items to draw.
00332     QList<const QPPlotItem*> m_items;
00333     
00334     // Axes maps.
00335     QwtScaleMap m_axesMaps[QwtPlot::axisCnt];
00336     
00337     // Images to draw into.
00338     QHash<PlotCanvasLayer, QPImageCache*> m_images;
00339     
00340     // Maximum number of draw items per segment.
00341     unsigned int m_segmentThreshold;
00342     
00343     // Flag that thread checks while running, to cancel rest of draw.
00344     bool m_cancelFlag;
00345 };
00346 
00347 }
00348 
00349 #endif
00350 
00351 #endif /* QPPLOTITEM_H_ */