RSUtils.qo.h

Go to the documentation of this file.
00001 //# RSUtils.qo.h: Common utilities/constants for region shapes.
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 RSUTILS_QO_H_
00028 #define RSUTILS_QO_H_
00029 
00030 #include <QtGui>
00031 
00032 #include <casa/BasicSL/String.h>
00033 #include <display/Display/WorldCanvasHolder.h>
00034 #include <display/Display/WorldCanvas.h>
00035 #include <measures/Measures/MCDirection.h>
00036 #include <measures/Measures/MDirection.h>
00037 
00038 #include <casa/namespace.h>
00039 
00040 namespace casa {
00041 
00042         class QtColorWidget;
00043 
00044 // Common utilities/constants for region shapes.
00045         class RSUtils {
00046         public:
00047                 // Returns a new layout with the given parent, and calls setupLayout
00048                 // on it;
00049                 // <group>
00050                 static QHBoxLayout* hlayout(QWidget* parent = NULL);
00051                 static QVBoxLayout* vlayout(QWidget* parent = NULL);
00052                 // </group>
00053 
00054                 // Sets up the given layout by setting:
00055                 // 1) margins to 0,
00056                 // 2) spacing to 3.
00057                 static void setupLayout(QLayout* layout);
00058 
00059                 // Returns a horizontal or vertical line (QFrame).
00060                 // <group>
00061                 static QWidget* hline();
00062                 static QWidget* vline();
00063                 // </group>
00064 
00065                 // Returns a new color widget.  If margins and spacing are given, they are
00066                 // applied to the widget.  If a frame is given, the widget is inserted into
00067                 // the frame.
00068                 static QtColorWidget* colorWidget(bool showButton = false,
00069                                                   String setColor = "",
00070                                                   QWidget* parent = NULL);
00071 
00072 
00073                 // Pixel coordinate system.  Used for converting between different
00074                 // systems, etc.
00075                 static const String PIXEL;
00076 
00077 
00078                 // Returns whether or not the given coordinate system has a direction
00079                 // coordinate or not.
00080                 // <group>
00081                 static bool hasDirectionCoordinate(const DisplayCoordinateSystem& cs);
00082                 static bool hasDirectionCoordinate(const WorldCanvas* wc) {
00083                         return wc != NULL && hasDirectionCoordinate(wc->coordinateSystem());
00084                 }
00085                 static bool hasDirectionCoordinate(const WorldCanvasHolder& wch) {
00086                         return hasDirectionCoordinate(wch.worldCanvas()->coordinateSystem());
00087                 }
00088                 // </group>
00089 
00090                 // Returns the world system type for the given coordinate system.
00091                 static MDirection::Types worldSystem(const DisplayCoordinateSystem& cs);
00092 
00093                 // Returns the world system type for the given WorldCanvas.
00094                 static MDirection::Types worldSystem(const WorldCanvas* wc) {
00095                         return worldSystem(wc->coordinateSystem());
00096                 }
00097 
00098                 // Returns the world system type for the given WorldCanvasHolder.
00099                 static MDirection::Types worldSystem(const WorldCanvasHolder& wch) {
00100                         return worldSystem(wch.worldCanvas()->coordinateSystem());
00101                 }
00102 
00103                 // Converts between coordinate systems.  The result has unit
00104                 // RegionShape::UNIT.
00105                 static bool convertWCS(const Quantum<Vector<Double> >& from,
00106                                        MDirection::Types fromSys,
00107                                        Quantum<Vector<Double> >& to,
00108                                        MDirection::Types toSys);
00109 
00110                 // Converts the given coordinates between different systems, using the
00111                 // given WorldCanvas and world system (if applicable).  Input world values
00112                 // are expected to have unit RegionShape::UNIT; output world values always
00113                 // have unit RegionShape::UNIT.  Methods that have a "wrap" flag will check
00114                 // the sign of the values when converting between different world
00115                 // coordinate systems, and wrap the values to have the same sign.  If
00116                 // a String is given, it will be used to record errors when the method
00117                 // returns false.
00118                 // <group>
00119                 static bool worldToPixel(const Quantum<Vector<double> >& worldX,
00120                                          const Quantum<Vector<double> >& worldY,
00121                                          Vector<double>& pixelX, Vector<double>& pixelY,
00122                                          WorldCanvasHolder& wch, MDirection::Types fromSys,
00123                                          bool wrap = true, String* error = NULL);
00124 
00125                 static bool pixelToWorld(const Vector<double>& pixelX,
00126                                          const Vector<double>& pixelY,
00127                                          Quantum<Vector<double> >& worldX,
00128                                          Quantum<Vector<double> >& worldY,
00129                                          WorldCanvasHolder& wch, MDirection::Types toSys,
00130                                          bool wrap = true, String* error = NULL);
00131 
00132                 static bool worldToLinear(const Quantum<Vector<double> >& worldX,
00133                                           const Quantum<Vector<double> >& worldY,
00134                                           Vector<double>& linearX, Vector<double>& linearY,
00135                                           WorldCanvasHolder& wch, MDirection::Types fromSys,
00136                                           bool wrap = true, String* error = NULL);
00137 
00138                 static bool pixelToLinear(const Vector<double>& pixelX,
00139                                           const Vector<double>& pixelY,
00140                                           Vector<double>& linearX, Vector<double>& linearY,
00141                                           WorldCanvasHolder& wch, String* error = NULL);
00142 
00143                 static bool linearToScreen(const Vector<double>& linearX,
00144                                            const Vector<double>& linearY,
00145                                            Vector<double>& screenX, Vector<double>& screenY,
00146                                            WorldCanvasHolder& wch, String* error = NULL);
00147 
00148                 static bool worldToScreen(const Quantum<Vector<double> >& worldX,
00149                                           const Quantum<Vector<double> >& worldY,
00150                                           Vector<double>& screenX, Vector<double>& screenY,
00151                                           WorldCanvasHolder& wch, MDirection::Types fromSys,
00152                                           bool wrap = true, String* error = NULL) {
00153                         Vector<double> linX(worldX.getValue().size()),
00154                                linY(worldY.getValue().size());
00155                         return worldToLinear(worldX, worldY, linX, linY, wch, fromSys, wrap,
00156                                              error) && linearToScreen(linX,linY,screenX,screenY,wch,error);
00157                 }
00158 
00159                 static bool pixelToScreen(const Vector<double>& pixelX,
00160                                           const Vector<double>& pixelY,
00161                                           Vector<double>& screenX, Vector<double>& screenY,
00162                                           WorldCanvasHolder& wch, String* error = NULL) {
00163                         Vector<double> linX(pixelX.size()), linY(pixelY.size());
00164                         return pixelToLinear(pixelX, pixelY, linX, linY, wch, error) &&
00165                                linearToScreen(linX, linY, screenX, screenY, wch, error);
00166                 }
00167 
00168                 static bool screenToLinear(const Vector<double>& screenX,
00169                                            const Vector<double>& screenY,
00170                                            Vector<double>& linearX, Vector<double>& linearY,
00171                                            WorldCanvasHolder& wch, String* error = NULL);
00172 
00173                 static bool linearToWorld(const Vector<double>& linearX,
00174                                           const Vector<double>& linearY,
00175                                           Quantum<Vector<double> >& worldX,
00176                                           Quantum<Vector<double> >& worldY,
00177                                           WorldCanvasHolder& wch, MDirection::Types toSys,
00178                                           const vector<int>& xSign,const vector<int>& ySign,
00179                                           bool wrap = true, String* error = NULL);
00180 
00181                 static bool linearToWorld(const Vector<double>& linearX,
00182                                           const Vector<double>& linearY,
00183                                           Quantum<Vector<double> >& worldX,
00184                                           Quantum<Vector<double> >& worldY,
00185                                           WorldCanvasHolder& wch, MDirection::Types toSys,
00186                                           String* error = NULL) {
00187                         return linearToWorld(linearX, linearY, worldX, worldY, wch, toSys,
00188                                              vector<int>(), vector<int>(), false, error);
00189                 }
00190 
00191                 static bool linearToPixel(const Vector<double>& linearX,
00192                                           const Vector<double>& linearY,
00193                                           Vector<double>& pixelX, Vector<double>& pixelY,
00194                                           WorldCanvasHolder& wch, String* error = NULL);
00195 
00196                 static bool screenToWorld(const Vector<double>& screenX,
00197                                           const Vector<double>& screenY,
00198                                           Quantum<Vector<double> >& worldX,
00199                                           Quantum<Vector<double> >& worldY,
00200                                           WorldCanvasHolder& wch, MDirection::Types toSys,
00201                                           String* error = NULL) {
00202                         Vector<double> linX(screenX.size()), linY(screenY.size());
00203                         return screenToLinear(screenX, screenY, linX, linY, wch) &&
00204                                linearToWorld(linX, linY, worldX, worldY, wch, toSys,
00205                                              vector<int>(), vector<int>(), false, error);
00206                 }
00207 
00208                 static bool screenToWorld(const Vector<double>& screenX,
00209                                           const Vector<double>& screenY,
00210                                           Quantum<Vector<double> >& worldX,
00211                                           Quantum<Vector<double> >& worldY,
00212                                           WorldCanvasHolder& wch, MDirection::Types toSys,
00213                                           const vector<int>& xSign, const vector<int>& ySign,
00214                                           String* error = NULL) {
00215                         Vector<double> linX(screenX.size()), linY(screenY.size());
00216                         return screenToLinear(screenX, screenY, linX, linY, wch) &&
00217                                linearToWorld(linX, linY, worldX, worldY, wch, toSys,
00218                                              xSign, ySign, true, error);
00219                 }
00220 
00221                 static bool screenToPixel(const Vector<double>& screenX,
00222                                           const Vector<double>& screenY,
00223                                           Vector<double>& pixelX, Vector<double>& pixelY,
00224                                           WorldCanvasHolder& wch, String* error = NULL) {
00225                         Vector<double> linX(screenX.size()), linY(screenY.size());
00226                         return screenToLinear(screenX, screenY, linX, linY, wch, error) &&
00227                                linearToPixel(linX, linY, pixelX, pixelY, wch, error);
00228                 }
00229                 // </group>
00230 
00231 
00232                 // Appends the given message to the given stream, if the stream does not
00233                 // already contain an identical message.  Messages are newline-separated.
00234                 // <group>
00235                 static void appendUniqueMessage(stringstream& ss, const String& message);
00236                 static void appendUniqueMessage(stringstream* ss, const String& message) {
00237                         if(ss != NULL) appendUniqueMessage(*ss, message);
00238                 }
00239                 static void appendUniqueMessage(String& ss, const String& message);
00240                 static void appendUniqueMessage(String* ss, const String& message) {
00241                         if(ss != NULL) appendUniqueMessage(*ss, message);
00242                 }
00243                 // </group>
00244         };
00245 
00246 
00247 // A widget that lets the user select a color: either one from a list, or a
00248 // custom color.
00249         class QtColorWidget : public QHBoxLayout {
00250                 Q_OBJECT
00251 
00252         public:
00253                 // Constructor that uses default colors.  If setText is nonempty, the
00254                 // chooser is set to the given.  If showButton is true, a "pick" button
00255                 // is shown for picking colors.
00256                 QtColorWidget(bool showButton = false, String setText = "",
00257                               QWidget* parent = NULL);
00258 
00259                 // Constructor that uses the given colors.  If setText is nonempty, the
00260                 // chooser is set to the given.  If showButton is true, a "pick" button
00261                 // is shown for picking colors.
00262                 QtColorWidget(const vector<String>& colors, bool showButton = false,
00263                               String setText = "", QWidget* parent = NULL);
00264 
00265                 // Destructor.
00266                 ~QtColorWidget();
00267 
00268                 // Returns the color that the user has chosen.  This will either be from
00269                 // the initial list, or in "#000000" form (see QColor::name()).
00270                 String getColor() const;
00271 
00272                 // Sets the displayed color to the given.  If the color is in the colors
00273                 // list, that index will be selected -- otherwise it will be entered in
00274                 // the custom color box.
00275                 void setColor(const String& color);
00276 
00277 
00278                 // Returns default colors.
00279                 static vector<String> defaultColors() {
00280                         static vector<String> v(9);
00281                         v[0] = "white";
00282                         v[1] = "black";
00283                         v[2] = "red";
00284                         v[3] = "green";
00285                         v[4] = "blue";
00286                         v[5] = "cyan";
00287                         v[6] = "magenta";
00288                         v[7] = "yellow";
00289                         v[8] = "gray";
00290                         return v;
00291                 }
00292 
00293         private:
00294                 // Color chooser.
00295                 QComboBox* m_chooser;
00296 
00297                 // Custom color.
00298                 QLineEdit* m_edit;
00299 
00300                 // Picker button.
00301                 QPushButton* m_button;
00302 
00303                 // Initializes GUI members.
00304                 void init(const vector<String>& colors, const String& setText,
00305                           bool showButton);
00306 
00307         private slots:
00308                 // For when the user picks a different color in the chooser.
00309                 void colorChanged(int index);
00310 
00311                 // For when the user clicks the "pick" button.
00312                 void colorPick();
00313         };
00314 
00315 
00316 // Convenience class for the different units available for coordinates/sizes.
00317 // Two modes: quantum and HMS/DMS (distinguished by the "isQuantum" flag).
00318 // <ol><li>Quantum: consists of a value and a unit, stored in "val".</li>
00319 //     <li>HMS/DMS: consists of three values and two flags.  Hours/degrees
00320 //         are stored in "hOrD", minutes are stored in "min", and seconds are
00321 //         stored in "sec".  The "isHMS" flag distinguishes between HMS and
00322 //         DMS.  The "isMinusZero" flag is used when "hOrD" is zero, but the
00323 //         whole value is negative.</li></ol>
00324         class RSValue {
00325         public:
00326                 RSValue(double d = 0) : isQuantum(true), isHMS(false), isMinusZero(false),
00327                         val(d, DEG), hOrD(0), min(0), sec(0) { }
00328 
00329                 RSValue(double d, Unit u) : isQuantum(true), isHMS(false),
00330                         isMinusZero(false), val(d, u), hOrD(0), min(0), sec(0) { }
00331 
00332                 RSValue(bool hms, long hd, long m, double s, bool minus = false) :
00333                         isQuantum(false), isHMS(hms), isMinusZero(minus), val(0, "_"),
00334                         hOrD(hd), min(m), sec(s) { }
00335 
00336                 ~RSValue() { }
00337 
00338                 bool isQuantum;
00339                 bool isHMS;
00340                 bool isMinusZero;
00341 
00342                 Quantum<double> val;
00343                 long hOrD;
00344                 long min;
00345                 double sec;
00346 
00347 
00348                 // Conversion methods/constants //
00349 
00350                 // Units constants.
00351                 // <group>
00352                 static const String DEG;
00353                 static const String RAD;
00354                 static const String ARCSEC;
00355                 static const String ARCMIN;
00356                 static const String HMS;
00357                 static const String DMS;
00358                 // </group>
00359 
00360                 // Converts the value in the given QString in the given units to the given
00361                 // RSValue.  The output RSValue is in degrees.  fromUnits should either be:
00362                 // 1) HMS or DMS constants,
00363                 // 2) a relevant Unit.
00364                 static bool convertBetween(const QString& from, const String& fromUnits,
00365                                            RSValue& to);
00366 
00367                 // Converts the value in the given RSValue to the given QString, using the
00368                 // given precision for the doubles.
00369                 static bool convertBetween(const RSValue& from, QString& to,
00370                                            int precision = -1);
00371 
00372                 // Converts the value in the given RSValue to the give RSValue which uses
00373                 // the given units.  toUnits should either be:
00374                 // 1) HMS or DMS constants,
00375                 // 2) a relevant Unit.
00376                 static bool convertBetween(const RSValue& from, RSValue& to,
00377                                            const String& toUnits);
00378         };
00379 
00380 
00381 // Convenience class for a String, bool, or double.
00382         class RSOption {
00383         public:
00384                 // String constructor.
00385                 RSOption(const String& str);
00386 
00387                 // Bool constructor.
00388                 RSOption(bool b = false);
00389 
00390                 // Double constructor.
00391                 RSOption(double d);
00392 
00393                 // String vector constructor.
00394                 RSOption(const vector<String>& v);
00395 
00396                 // Destructor.
00397                 ~RSOption();
00398 
00399                 // Type methods.
00400                 // <group>
00401                 bool isString() const;
00402                 bool isBool() const;
00403                 bool isDouble() const;
00404                 bool isStringArray() const;
00405                 // </group>
00406 
00407                 // Value methods.
00408                 // <group>
00409                 const String& asString() const;
00410                 bool asBool() const;
00411                 double asDouble() const;
00412                 const vector<String>& asStringArray() const;
00413                 // </group>
00414 
00415                 // Operators.
00416                 // <group>
00417                 bool operator==(const RSOption& other);
00418                 bool operator!=(const RSOption& other);
00419                 RSOption& operator=(const String& str);
00420                 RSOption& operator=(bool b);
00421                 RSOption& operator=(double d);
00422                 RSOption& operator=(const vector<String>& v);
00423                 // </group>
00424 
00425         private:
00426                 bool m_isString;
00427                 String m_string;
00428                 bool m_isBool;
00429                 bool m_bool;
00430                 bool m_isDouble;
00431                 double m_double;
00432                 bool m_isStringArray;
00433                 vector<String> m_stringArray;
00434         };
00435 
00436 
00437 // A "handle" is a four-point structure (usually a rectangle) that describes
00438 // the boundaries in screen pixels that a RegionShape takes on a canvas.  In
00439 // the future, this will be used for selecting/editing/moving/resizing shapes
00440 // on the canvas using the mouse.
00441         class RSHandle {
00442         public:
00443                 // Defaults.
00444                 // <group>
00445                 static const int DEFAULT_MARKER_HEIGHT;
00446                 static const String DEFAULT_MARKER_COLOR;
00447                 static const Display::Marker DEFAULT_MARKER_TYPE;
00448                 // </group>
00449 
00450                 // Constructor which makes an invalid handle.
00451                 RSHandle();
00452 
00453                 // Constructor which takes x and y vectors.  x and y MUST be length 4 or
00454                 // the handle is invalid.
00455                 RSHandle(const vector<double>& x, const vector<double>& y,
00456                          int markerHeight = DEFAULT_MARKER_HEIGHT,
00457                          const String& markerColor = DEFAULT_MARKER_COLOR,
00458                          Display::Marker markerType = DEFAULT_MARKER_TYPE);
00459 
00460                 // Constructor which takes x and y Vectors.  x and y MUST be length 4 or
00461                 // the handle is invalid.
00462                 RSHandle(const Vector<double>& x, const Vector<double>& y,
00463                          int markerHeight = DEFAULT_MARKER_HEIGHT,
00464                          const String& markerColor = DEFAULT_MARKER_COLOR,
00465                          Display::Marker markerType = DEFAULT_MARKER_TYPE);
00466 
00467                 // Destructor.
00468                 ~RSHandle();
00469 
00470                 // Gets/sets the marker height/color/type.
00471                 // <group>
00472                 int getMarkerHeight() const {
00473                         return m_markerHeight;
00474                 }
00475                 void setMarkerHeight(int height);
00476                 String getMarkerColor() const {
00477                         return m_markerColor;
00478                 }
00479                 void setMarkerColor(const String& color);
00480                 Display::Marker getMarkerType() const {
00481                         return m_markerType;
00482                 }
00483                 void setMarkerType(Display::Marker type);
00484                 // </group>
00485 
00486                 // Returns whether the handle is valid (has four valid points) or not.
00487                 bool isValid() const {
00488                         return m_isValid;
00489                 }
00490 
00491                 // Returns true if the handle is valid and the given point is inside.
00492                 bool containsPoint(double x, double y) const;
00493 
00494                 // Gets the handle vertices coordinates and returns whether the operation
00495                 // succeeded or not (i.e. if the handle is valid).  If it succeeded, x and
00496                 // y will be resize to be size 4 if necessary.
00497                 bool getVertices(vector<double>& x, vector<double>& y) const;
00498 
00499                 // Draws the handles on the given canvas and returns whether the operation
00500                 // succeeded or not (i.e. if the handle is valid).  If valid, each of the
00501                 // four points is drawn as a marker.
00502                 bool draw(PixelCanvas* canvas) const;
00503 
00504         private:
00505                 bool m_isValid;
00506                 vector<double> m_x, m_y;
00507                 int m_markerHeight;
00508                 String m_markerColor;
00509                 Display::Marker m_markerType;
00510         };
00511 
00512 }
00513 
00514 #endif /* RSUTILS_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1