casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
QtCanvas.qo.h
Go to the documentation of this file.
00001 //# Copyright (C) 2005
00002 //# Associated Universities, Inc. Washington DC, USA.
00003 //#
00004 //# This library is free software; you can redistribute it and/or modify it
00005 //# under the terms of the GNU Library General Public License as published by
00006 //# the Free Software Foundation; either version 2 of the License, or (at your
00007 //# option) any later version.
00008 //#
00009 //# This library is distributed in the hope that it will be useful, but WITHOUT
00010 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012 //# License for more details.
00013 //#
00014 //# You should have received a copy of the GNU Library General Public License
00015 //# along with this library; if not, write to the Free Software Foundation,
00016 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00017 //#
00018 //# Correspondence concerning AIPS++ should be addressed as follows:
00019 //#        Internet email: aips2-request@nrao.edu.
00020 //#        Postal address: AIPS++ Project Office
00021 //#                        National Radio Astronomy Observatory
00022 //#                        520 Edgemont Road
00023 //#                        Charlottesville, VA 22903-2475 USA
00024 //#
00025 
00026 #ifndef QTCANVAS_H
00027 #define QTCANVAS_H
00028 
00029 #include <casa/aips.h>
00030 #include <casa/BasicSL/String.h>
00031 #include <casa/Containers/Record.h>
00032 #include <casa/Arrays/Array.h>
00033 #include <casa/Arrays/ArrayMath.h>
00034 #include <casa/Arrays/Vector.h>
00035 #include <casa/Arrays/Matrix.h>
00036 #include <casa/Inputs/Input.h>
00037 #include <casa/Arrays/IPosition.h>
00038 
00039 #include <display/QtPlotter/QtPlotSettings.h>
00040 #include <display/QtPlotter/CanvasCurve.h>
00041 #include <display/QtPlotter/WorldCanvasTranslator.h>
00042 #include <display/QtPlotter/ProfileFitMarker.h>
00043 #include <display/QtPlotter/MolecularLine.h>
00044 #include <display/QtPlotter/canvasMode/CanvasMode.h>
00045 
00046 #include <graphics/X11/X_enter.h>
00047 #include <QDir>
00048 #include <QColor>
00049 #include <QHash>
00050 #include <QWidget>
00051 #include <QMouseEvent>
00052 #include <QToolButton>
00053 #include <QDialog>
00054 #include <QPixmap>
00055 #include <QVBoxLayout>
00056 #include <QPainterPath>
00057 #include <QLabel>
00058 #include <QMenu>
00059 #include <map>
00060 #include <vector>
00061 #include <graphics/X11/X_exit.h>
00062 
00063 namespace casa { 
00064 
00065 class Annotation;
00066 
00067 #define QT_DIAMOND_SIZE 5
00068 
00069 class GraphLabel{
00070 public:
00071         QString text;
00072         QString fontName;
00073         int fontSize;
00074         QColor color;
00075         GraphLabel() : text(""), fontName(""), fontSize(12), color(Qt::blue) {}
00076 };
00077 
00078 class QtCanvas : public QWidget, public WorldCanvasTranslator
00079 {
00080         Q_OBJECT
00081 
00082 friend class CanvasModeAnnotation;
00083 friend class CanvasModeRangeSelection;
00084 friend class CanvasModeChannel;
00085 friend class CanvasModeContextMenu;
00086 friend class CanvasModeZoom;
00087 
00088 public:
00089         QtCanvas(QWidget *parent = 0);
00090 
00091         void setPlotSettings(const QtPlotSettings &settings);
00092         void setTopAxisRange(const Vector<Float> &xValues, bool topAxisDescending );
00093         void setFrameMarker( float framePositionX );
00094         void setZoomRectColor( QColor color );
00095         //Returns the spectrum as it is currently displayed in the canvas (with
00096         //possible zooming).
00097         void getCanvasDomain( double* minValue, double* maxValue, QString& units);
00098 
00099         CurveData getCurveData(int);
00100         ErrorData getCurveError(int id);
00101         QString getCurveName(int id);
00102         void setCurveName(int id, const QString& name );
00103         void curveColorsChanged();
00104         QColor getCurveColor( int id );
00105         CanvasCurve getCurve( const QString& curveName );
00106         int getLineCount();
00107         void curveLabelsChanged();
00108         void clearCurve();
00109         void clearFitCurves();
00110         void clearMolecularLines( bool refresh = true );
00111         void setDataRange();
00112         void setImageMode(bool);
00113         QPixmap* graph();
00114         void drawBackBuffer(QPainter *);
00115         //Draws a vertical line indicating the current frame.
00116         void drawFrameMarker( QPainter* );
00117         QString getUnits( QtPlotSettings::AxisIndex axisIndex = QtPlotSettings::xBottom );
00118         QList<MolecularLine*> getMolecularLines() const;
00119 
00120         //Plotting curves
00121         void plotPolyLines(QString);
00122         template<class T> void plotPolyLine(const Vector<T>&, const Vector<T>&);
00123         void plotPolyLine(const Vector<Float> &x, const Vector<Float> &y, const Vector<Float> &e,
00124                         const QString& lb="");
00125         enum ColorCategory { TITLE_COLOR, CURVE_COLOR, CURVE_COLOR_PRIMARY,
00126                 CURVE_COLOR_SECONDARY, WARNING_COLOR, CURVE_TRADITIONAL };
00127         void addPolyLine(const Vector<Float> &x, const Vector<Float> &y,
00128                         const QString& lb="", ColorCategory colorCategory=CURVE_COLOR );
00129         void addMolecularLine(MolecularLine* molecularLine );
00130         QList<QString> getMolecularLineNames() const;
00131 
00132         template<class T> void plotPolyLine(const Matrix<T> &verts);
00133 
00134         QSize minimumSizeHint() const;
00135         QSize sizeHint() const;
00136         ~QtCanvas();
00137 
00138 
00139         void setTitle(const QString &text, int fontSize = 13,const QString &font = FONT_NAME);
00140         QString getTitle(){return title.text;};
00141 
00142         bool isShowChannelLine();
00143         void setShowChannelLine( bool showLine );
00144         void setChannelLineColor( QColor color );
00145 
00146         void setXLabel(const QString &text, int fontSize = 10,
00147                         const QString &font = FONT_NAME, QtPlotSettings::AxisIndex axisIndex=QtPlotSettings::xBottom);
00148         void setWelcome(const QString &text, int fontSize = 14,
00149                         const QString &font = FONT_NAME);
00150         void setAutoScaleX(bool autoScale);
00151         void setAutoScaleY(bool autoScale);
00152         void setShowGrid(int a)   {showGrid = a; refreshPixmap();}
00153         bool getAutoScaleX( ) {return autoScaleX;}
00154         bool getAutoScaleY( ) {return autoScaleY;}
00155         int getShowGrid( )   {return showGrid;}
00156         void setPlotError(int a)  {plotError = a; setDataRange();}
00157 
00158         //Whether or not to show a top axis on the plot.
00159         void setShowTopAxis( bool showAxis );
00160         bool getShowTopAxis() const { return showTopAxis; }
00161 
00162         //Whether or not to show tool tips with the x,y coordinates
00163         //of the points on the plot.
00164         void setShowToolTips( bool toolTipsVisible ){ showToolTips = toolTipsVisible; }
00165         bool getShowToolTips() const { return showToolTips; }
00166 
00167         //Sets the coordinates for the x and y points that are displayed
00168         //as tooltips.
00169         void setToolTipXUnit( const QString& xUnit ){ toolTipXUnit = xUnit; }
00170 
00171         //Stores the location of a (center,peak) point that represents an initial
00172         //Gaussian estimate for spectral line fitting.
00173         void setProfileFitMarkerCenterPeak( int index, double center, double peak);
00174 
00175         //Stores the fwhm and the y value of the fwhm for an initial Gaussian estimate
00176         //for spectral line fitting.
00177         void setProfileFitMarkerFWHM( int index, double fwhm, double fwhmHeight);
00178 
00179         //Whether or not to plot a line graph or instead plot the points as a
00180         //step function.
00181         bool isDisplayStepFunction() const;
00182         void setDisplayStepFunction( bool displayAsStepFunction );
00183 
00184         //Used for customizing the curve colors on the canvas.
00185         void setTraditionalCurveColors( const QList<QString>& colors );
00186         void setMainCurveColors( const QList<QString>& colors );
00187         void setFitCurveColors( const QList<QString>& colors );
00188         void setSummaryCurveColors( const QList<QString>& colors );
00189 
00190         //If this flag is set, only 'traditional' colors will be used.
00191         void setTraditionalColors( bool traditionalColors );
00192         static const QString FONT_NAME;
00193 
00194         //Customization of the curve legend.
00195         void setShowLegend( bool visible );
00196         bool isShowLegend() const;
00197         void setLegendPosition( int position );
00198         int getLegendPosition() const;
00199 
00200         //Set the yaxis units the image is using ( units the data we are getting is in).
00201         void setImageYUnits( const QString& imageUnits );
00202 
00203 
00204         enum TaskMode {/*UNKNOWN_MODE,*/ SPECTRAL_LINE_MODE, LINE_OVERLAY_MODE, MODE_COUNT };
00205 
00206 
00207         //Units we will be displaying the y-axis in which may be different
00208         //from the intrinsic image units.
00209         QString getDisplayYUnits();
00210         void setDisplayYUnits( const QString& displayUnits );
00211 
00212         int getCurZoom();
00213         int getZoomStackSize();
00214 
00215 public slots:
00216         void zoomIn();
00217         void zoomOut();
00218         void zoomNeutral();
00219         void changeTaskMode( int mode );
00220         void createAnnotationText();
00221         void rangeSelectionMode();
00222         void channelPositioningMode();
00223 
00224 signals:
00225         void xRangeChanged(double xmin, double xmax);
00226         void channelSelect(float xvalue);
00227         void specFitEstimateSpecified( double xValue, double yValue, bool centerPeak );
00228         void findRedshiftAt( double center, double peak );
00229         void channelRangeSelect( float startVal, float endVal );
00230         void curvesChanged();
00231         void clearPaletteModes();
00232         void togglePalette( int modeIndex );
00233 
00234 protected:
00235         void paintEvent(QPaintEvent *event);
00236         void resizeEvent(QResizeEvent *event);
00237         void mousePressEvent(QMouseEvent *event);
00238         void mouseMoveEvent(QMouseEvent *event);
00239         void mouseReleaseEvent(QMouseEvent *event);
00240         void keyPressEvent(QKeyEvent *event);
00241         void keyReleaseEvent(QKeyEvent *event);
00242         void wheelEvent(QWheelEvent *event);
00243 
00244         void updateRubberBandRegion();
00245         void updatexRangeBandRegion();
00246         void drawGrid(QPainter *painter);
00247         void drawTicks(QPainter *painter);
00248         void drawLabels(QPainter *painter);
00249         void drawWelcome(QPainter *painter);
00250         void drawCurves(QPainter *painter);
00251         void drawxRange(QPainter *painter);
00252 
00253 
00254 private slots:
00255         void deleteSelectedAnnotation();
00256         void editSelectedAnnotation();
00257         void gaussianCenterPeakSelected();
00258         void gaussianFWHMSelected();
00259         void findRedshift();
00260 
00261 private:
00262 
00263         //Zoom functionality
00264         void zoomYBasedOnX( QtPlotSettings& settings, double zoomFactor, bool zoomIn );
00265         pair<double,double> getRangeFor( double zoomFactor, bool zoomIn, double minX, double maxX );
00266         void increaseCurZoom();
00267         void defaultZoomIn();
00268         void defaultZoomOut();
00269 
00279         void setCurveData(int id, const CurveData &data, const ErrorData &error=ErrorData(),
00280                 const QString& lb="", ColorCategory colorCategory = CURVE_COLOR);
00281         void refreshPixmap();
00282 
00287         void displayToolTip( QMouseEvent* event ) const;
00288 
00293         void adjustExtremes( double* const min, double* const max ) const;
00294 
00300         double getDataY( int pixelPosition ) const;
00301 
00307         double getDataX( int pixelPosition ) const;
00308 
00309         //WorldCanvasTranslator interface methods.
00315         int getPixelX( double dataX ) const;
00316 
00322         int getPixelY ( double dataY ) const;
00323 
00334         QString findCoords( double x, double y ) const;
00335 
00339         int getRectHeight() const;
00340 
00344         int getRectWidth() const;
00345 
00349         int getRectBottom() const;
00350 
00354         int getRectLeft() const;
00355 
00364         QString getXTickLabel( int index, int tickCount, QtPlotSettings::AxisIndex axisIndex ) const;
00365 
00371         void initContextMenu();
00372         void addDiamond( int x, int y, int diamondSize, QPainterPath& points ) const;
00373         bool storeClickPosition( QMouseEvent* event );
00374         int getLastAxis() const;
00375         void stripCurveTitleNumbers( QString& curveName ) const;
00376         bool duplicateCurve( QString& targetLabel );
00377         void setYLabel(const QString &text, int fontSize = 10, const QString &font = FONT_NAME);
00378 
00379         //Annotation methods
00380         void selectAnnotation( QMouseEvent* event, bool select = true );
00381         bool isAnnotation( QMouseEvent* event ) const;
00382         Annotation* getSelectedAnnotation() const;
00383 
00384         //Mouse Events
00385         void storeActiveAnnotation( QMouseEvent* event );
00386         void selectChannel( QMouseEvent* event );
00387         void updateChannel( QMouseEvent* event );
00388         void moveChannel( QMouseEvent* event );
00389         void startRangeX( QMouseEvent* event );
00390         void updateRangeX( QMouseEvent* event );
00391         void endRangeX( QMouseEvent* event );
00392         void startZoomRect( QMouseEvent* event );
00393         void updateZoomRect( QMouseEvent* event );
00394         void endZoomRect( QMouseEvent* event );
00395         void resetSelectedAnnotation( QMouseEvent* event );
00396         void drawMolecularLines( QPainter& painter );
00397 
00398         //Plot Margins
00399         const int MARGIN_LEFT;
00400         const int MARGIN_BOTTOM;
00401         const int MARGIN_TOP;
00402         const int MARGIN_RIGHT;
00403         const int FRACZOOM;
00404         const double ZERO_LIMIT;
00405 
00406         GraphLabel title;
00407         GraphLabel xLabel[2];
00408         GraphLabel yLabel;
00409         GraphLabel welcome;
00410 
00411         std::map<int, CanvasCurve> curveMap;
00412         std::vector<QtPlotSettings> zoomStack;
00413         QList<MolecularLine*> molecularLineStack;
00414         std::pair<double,double> topAxisRange;
00415 
00416         int curZoom;
00417         int curMarker;
00418         bool rubberBandIsShown;
00419         bool xRangeIsShown;
00420         bool imageMode;
00421         bool xRangeMode;
00422         double xRangeStart;
00423         double xRangeEnd;
00424         QRect rubberBandRect;
00425         QRect xRangeRect;
00426         QPixmap pixmap;
00427         QPixmap backBuffer;
00428         Matrix<uInt> *pMask;
00429 
00430         QPoint currentCursorPosition;
00431         QColor xcursor;
00432 
00433         bool autoScaleX;
00434         bool autoScaleY;
00435         int plotError;
00436         int showGrid;
00437 
00438         int xRectStart;
00439         int xRectEnd;
00440 
00441         bool showTopAxis;
00442         bool showToolTips;
00443         bool showFrameMarker;
00444         bool displayStepFunction;
00445         QString toolTipXUnit;
00446         QString yUnitImage;
00447         QString yUnitDisplay;
00448 
00449         //Context Menu
00450         QMenu contextMenu;
00451         QAction* centerPeakAction;
00452         QAction* fwhmAction;
00453         QAction* findRedshiftAction;
00454         QAction* createAnnotationAction;
00455         QAction* editAnnotationAction;
00456         QAction* deleteAnnotationAction;
00457         void showContextMenu( QMouseEvent* event );
00458 
00459         //Profile Fitting Gaussian Estimation
00460         double gaussianEstimateX;
00461         double gaussianEstimateY;
00462         QList<ProfileFitMarker> profileFitMarkers;
00463 
00464         ProfileFitMarker getMarker( int index ) const;
00465         void setMarker( int index, ProfileFitMarker& marker );
00466 
00467 
00475         QColor getDiscreteColor(ColorCategory colorCategory, int id=0);
00476         QColor frameMarkerColor;
00477         QColor zoomColor;
00478         QList<QString> mainCurveColorList;
00479         QList<QString> fitCurveColorList;
00480         QList<QString> fitSummaryCurveColorList;
00481         QList<QString>  traditionalCurveColorList;
00482 
00483         int curveCount;
00484         int curveCountPrimary;
00485         int curveCountSecondary;
00486 
00487         //The optical spectral line fitting curve needs to use
00488         //the traditional color list rather than a customizable one.
00489         //That is the purpose of this flag.
00490         bool traditionalColors;
00491 
00492         //Whether the pixel canvas should show a legend with the curves.
00493         bool showLegend;
00494 
00495         //Where the curve legend should appear relative to this
00496         //canvas.
00497         int legendPosition;
00498 
00499         //The x location for the vertical line representing the
00500         //current frame position.
00501         float framePositionX;
00502 
00503         //Indicates the current work focus of the profiler
00504         TaskMode taskMode;
00505 
00506         float channelSelectValue;
00507 
00508         Annotation* selectedAnnotation;
00509         vector<Annotation*> annotations;
00510 
00511         //Returns true if the user is in the process of drawing an
00512         //annotation.
00513         bool isAnnotationActive() const;
00514 
00515         Annotation* getActiveAnnotation() const;
00516         CanvasMode* currentMode;
00517 };
00518 
00519 }
00520 #endif
00521