00001 //# QtDisplayData.qo.h: Qt DisplayData wrapper. 00002 //# Copyright (C) 2005 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 00028 #ifndef QTDISPLAYDATA_H 00029 #define QTDISPLAYDATA_H 00030 00031 #include <casa/aips.h> 00032 #include <casa/BasicSL/String.h> 00033 #include <casa/Containers/Record.h> 00034 #include <display/Display/DisplayCoordinateSystem.h> 00035 #include <display/Display/DParameterChoice.h> 00036 #include <display/Display/DParameterRange.h> 00037 #include <casa/BasicMath/Math.h> 00038 #include <display/Display/DisplayEnums.h> 00039 #include <display/DisplayDatas/DisplayData.h> 00040 #include <display/DisplayDatas/DisplayDataOptions.h> 00041 #include <display/Utilities/ImageProperties.h> 00042 #include <vector> 00043 00044 00045 #include <graphics/X11/X_enter.h> 00046 #include <QtCore> 00047 #include <QObject> 00048 #include <graphics/X11/X_exit.h> 00049 00050 00051 namespace casa { //# NAMESPACE CASA - BEGIN 00052 00053 class String; 00054 class Record; 00055 class DisplayData; 00056 class WCMotionEvent; 00057 template <class T> class ImageInterface; 00058 class QtDisplayPanel; 00059 class ImageRegion; 00060 class WorldCanvasHolder; 00061 class Colormap; 00062 class QtDisplayPanelGui; 00063 class WedgeDD; 00064 00065 class QtDisplayData : public QObject { 00066 00067 Q_OBJECT //# Allows slot/signal definition. Must only occur in 00068 //# implement/.../*.h files; also, makefile must include 00069 //# name of this file in 'mocs' section. 00070 00071 public: 00072 00073 static std::string path(const DisplayData *); 00074 00075 QtDisplayData( QtDisplayPanelGui *panel, String path, String dataType, String displayType, 00076 const viewer::DisplayDataOptions &ddo = viewer::DisplayDataOptions( ), 00077 const viewer::ImageProperties &props = viewer::ImageProperties( ) ); 00078 ~QtDisplayData(); 00079 String getPositionInformation( const Vector<double> world); 00080 virtual std::string name() { 00081 return name_; 00082 } 00083 virtual const char* nameChrs() { 00084 return name_.c_str(); 00085 } 00086 virtual void setName(const std::string& name) { 00087 name_ = name; 00088 } 00089 const std::string DISPLAY_RASTER; 00090 const std::string DISPLAY_CONTOUR; 00091 const std::string DISPLAY_VECTOR; 00092 const std::string DISPLAY_MARKER; 00093 virtual std::string dataType() const { 00094 return dataType_; 00095 } 00096 virtual std::string displayType() { 00097 return displayType_; 00098 } 00099 00100 //Display Type 00101 Bool isRaster() const; 00102 Bool isContour() const; 00103 Bool isVector() const; 00104 Bool isMarker() const; 00105 Bool isImage() const; 00106 00107 //virtual Bool delTmpData() const; 00108 virtual void delTmpData() const; 00109 virtual void setDelTmpData(Bool delTmpData); 00110 00111 std::string description( ) const; 00112 std::string path( ) const { 00113 return path_; 00114 } 00115 00116 virtual String errMsg() { 00117 return errMsg_; 00118 } 00119 00120 // retrieve the Record of options. This is similar to a 'Parameter Set', 00121 // containing option types, default values, and meta-information, 00122 // suitable for building a user interface for controlling the DD. 00123 virtual Record getOptions(); 00124 00125 // retrieve wrapped DisplayData. 00126 //# (should probably be private, and 'friend'ed only to QtDP, which 00127 //# needs it for purposes like registration...). 00128 virtual DisplayData* dd() { 00129 return dd_; 00130 } 00131 00132 // Did creation of wrapped DD fail? 00133 virtual Bool isEmpty() { 00134 return dd_==0; 00135 } 00136 00137 00138 00139 // Possible valuse: Raster, Vector, Annotation, CanvasAnnotation 00140 virtual Display::DisplayDataType ddType(); 00141 bool isSkyCatalog() const; 00142 bool isMS() const; 00143 00144 00145 // Can the QDD display tracking information? 00146 virtual Bool usesTracking() { 00147 return !isEmpty() && 00148 ddType()!=Display::Annotation && 00149 ddType()!=Display::CanvasAnnotation; 00150 } 00151 00152 // Returns a String with value and position information, 00153 // suitable for a cursor tracking display. 00154 virtual pair<String,String> trackingInfo(const WCMotionEvent& ev); 00155 00156 00157 // Convert 2-D 'pseudoregion' (or 'mouse region' Record, from the region 00158 // mouse tools) to a full Image Region, with same number of axes as the 00159 // DD's Lattice (and relative to its DisplayCoordinateSystem). 00160 // Return value is 0 if the conversion can't be made or does not apply 00161 // to this DD for any reason (ignored by non-Lattice DDs, e.g.). 00162 // 00163 // If allChannels==True, the region is extended along spectral axis, if 00164 // it exists (but ONLY if the spectral axis is not also on display; the 00165 // visible mouse region always defines region shape on the display axes). 00166 // 00167 // If allAxes is True, the region is extended over all (non-display) 00168 // axes (including any spectral axis; allAxes=True makes the allChannels 00169 // setting irrelevant). 00170 // 00171 // If both allchannels and allAxes are False (the default), the region 00172 // will be confined to the currently-displayed plane. 00173 // 00174 // -->If the returned ImageRegion* is non-zero, the caller 00175 // -->is responsible for deleting it. 00176 virtual ImageRegion* mouseToImageRegion(Record mouseRegion, 00177 WorldCanvasHolder* wch, 00178 Bool allChannels=False, 00179 Bool allPols=False, 00180 Bool allRAs=False, 00181 Bool allDECs=False, 00182 Bool allAxes=False); 00183 virtual ImageRegion* mouseToImageRegion( 00184 Record mouseRegion, WorldCanvasHolder* wch, 00185 String& extChan, String& extPol); 00186 00187 // Print statistics on image for given region. 00188 // Returns False if unable to do so. 00189 virtual Bool printRegionStats(ImageRegion& imgReg); 00190 virtual Bool printLayerStats(ImageRegion& imgReg); 00191 00192 00193 // Return the number of the spectral axis within the DD's original 00194 // image lattice and coordinate system (-1 if none). 00195 //virtual Int spectralAxis(); 00196 virtual Int getAxisIndex(String axtype=String("Spectral")); 00197 00198 //# colorbar methods 00199 00200 00201 // Would this QDD want to display a color bar if registered and 00202 // conformant for drawing? 00203 virtual Bool wouldDisplayColorBar() { 00204 bool displayColorBar = false; 00205 bool wouldDisplayColorBar = false; 00206 if ( colorBarDisplayOpt_ != NULL ) { 00207 if (colorBarDisplayOpt_->value() == WEDGE_YES) { 00208 displayColorBar = true; 00209 } 00210 wouldDisplayColorBar = hasColorBar() && displayColorBar; 00211 } 00212 return wouldDisplayColorBar; 00213 } 00214 00215 00216 // Is a color bar WDD defined for this QDD? 00217 virtual Bool hasColorBar() { 00218 bool colorBarExists = false; 00219 if ( colorBar_!= 0 ) { 00220 colorBarExists = true; 00221 } 00222 return colorBarExists; 00223 } 00224 00225 00226 // User-requested adjustment to colorbar thickness (will probably 00227 // remain at the default value of 1). Used by QtDisplayPanel to 00228 // aid in sizing colorbar panels. 00229 virtual Float colorBarSizeAdj() { 00230 if(!wouldDisplayColorBar()) return 0.; 00231 return max(colorBarThicknessOpt_->minimum(), 00232 min(colorBarThicknessOpt_->maximum(), 00233 colorBarThicknessOpt_->value())); 00234 } 00235 00236 00237 // Used (by QtDisplayPanel) to compute margin space for colorbar labels. 00238 // It is the (pgplot) character size for colorbar labels (default 1.2) 00239 // times a label space 'adjustment' user option (default 1.). 00240 virtual Float colorBarLabelSpaceAdj(); 00241 00242 00243 // Retrieve color bar ('wedge') DD. (0 if none. It will exist if 00244 // hasColorBar() is True). (Not for general use). 00245 //# (should probably be private, and 'friend'ed only to QtDP, which 00246 //# which manages its registration and other aspects). 00247 virtual WedgeDD* colorBar() { 00248 return colorBar_; 00249 } 00250 00251 Colormap* getColorMap() const; 00252 00253 00254 // Does this DD currently own a colormap? 00255 virtual Bool hasColormap() const { 00256 return clrMap_!=0; 00257 } 00258 // Different DisplayDatas *could* have different colormap palettes 00259 // thus this is non-static and specific to a display data 00260 virtual bool isValidColormap( const QString &name ) const; 00261 void setColorMap( Colormap* colorMap ); 00262 //Set the transparence of the color map for overlaying images. 00263 Bool setColormapAlpha( uInt alpha ); 00264 void removeColorMap( const String& name ); 00265 00266 // Get/set colormap shift/slope ('fiddle') and brightness/contrast 00267 // settings. (At present this is usually set for the PC's current 00268 // colormap via mouse tools. These may want to to into get/setOptions 00269 // (thus into guis) eventually...). Return value will be False if 00270 // DD has no colormap [at present]. 00271 //<group> 00272 virtual Bool getCMShiftSlope(Vector<Float>& params) const; 00273 virtual Bool getCMBrtCont(Vector<Float>& params) const; 00274 virtual Bool setCMShiftSlope(const Vector<Float>& params); 00275 virtual Bool setCMBrtCont(const Vector<Float>& params); 00276 //</group> 00277 00278 //Return the name of the z-axis. 00279 String getZAxisName(); 00280 00281 //# (dk note: If you use this, you must assure you do not change it in ways 00282 //# that will crash QDD. Do not assume it is non-zero -- im_ may be zero if 00283 //# the QDD's image is complex. However, if it _is_ non-zero, you should 00284 //# be able to assume it will exist for the life of the QDD). 00285 SHARED_PTR<ImageInterface<Float> > imageInterface() { 00286 return im_; 00287 } 00288 const viewer::ImageProperties &imageProperties( ); 00289 00290 // force unlocking of paged images 00291 void unlock( ); 00292 static const String WEDGE_LABEL_CHAR_SIZE; 00293 static const String WEDGE_YES; 00294 00295 00296 void init(); 00297 void initImage(); 00298 void setImage(SHARED_PTR< ImageInterface<Float> > img); 00299 static void setGlobalColorOptions( bool global ); 00300 void setHistogramColorProperties( bool invert, int logScale ); 00301 00302 public slots: 00303 00304 // (Should only be used by QtDisplayPanels to notify the QDD that it 00305 // has been registered, or is about to be unregistered, on the QDP). 00306 //<group> 00307 virtual void registerNotice(QtDisplayPanel*); 00308 virtual void unregisterNotice(QtDisplayPanel*); 00309 //</group> 00310 00311 // Apply option values to the DisplayData. Method will 00312 // emit optionsChanged() if other option values, limits, etc. 00313 // should also change as a result. 00314 // Set emitAll = True if the call was not initiated by the options gui 00315 // itself (e.g. via scripting or save-restore); that will assure that 00316 // the options gui does receive all option updates (via the optionsChanged 00317 // signal) and updates its user interface accordingly. 00318 00319 virtual void setOptions(Record opts, Bool emitAll=False); 00320 void emitOptionsChanged( Record changedOpts ); 00321 void setPlotTitle(); 00322 00323 00324 00325 00326 virtual void checkAxis( bool changeSpectrum = true); 00327 00328 00329 const String &getColormap( ) { 00330 return clrMapName_; 00331 } 00332 void setColormap(const String& clrMapName) { 00333 setColormap_(clrMapName); 00334 } 00335 void setHistogramColorMapping( float minValue, float maxValue, float powerScale ); 00336 // This is used to get the display data to set a saturation range 00337 // from another image. 00338 void setSaturationRange( double min, double max ); 00339 00340 signals: 00341 00342 // Signals changes the DD has made internally to option values, limits, 00343 // etc., that ui (if any) will want to reflect. Calling setOptions() 00344 // to change one option value may cause this to be emitted with any other 00345 // options which have changed as a result. 00346 void optionsChanged(Record changedOptions); 00347 00348 // Emitted when problems encountered (in setOptions, e.g.) 00349 void qddError(String errmsg); 00350 00351 // Emitted when options successfully set without error. 00352 //# (same purpose as above -- clean this up). 00353 void optionsSet(); 00354 00355 // Emitted when color bars may need rearrangement on panels where 00356 // this QDD is registered. QDP connects this to its checkColorBars_() 00357 // slot. 00358 void colorBarChange(); 00359 00360 // Emitted when something in the DD (besides mouse movement) means 00361 // that tracking data for this QDD could be usefully recomputed 00362 // and redisplayed. Underlying DDs can indicate this in setOptions 00363 // by defining the "trackingchange" field in chgdOpts (recOut). 00364 void trackingChange(QtDisplayData*); 00365 00366 00367 //# Emitted when an operation is successfully completed. It is intended 00368 //# that, e.g., a gui that responds to qddError signals by setting 00369 //# an error message onto a status line vould clear the status line 00370 //# when this signal occurs. 00371 //# (let qdpg clear status line itself b4 QDP calls instead?...) 00372 //#void qddOK(); 00373 00374 //# This object will be destroyed after this signal is processed. 00375 //# (Note: if this DD is managed in QtViewer's list, it is preferable 00376 //# to connect to QtViewerBase::ddRemoved() instead). 00377 //# void dying(QtDisplayData*); 00378 00379 // (mkApr2012) axisChanged and axisChangedProfile have the identical 00380 // functionality, to send out the names of the current x/y/z axes. 00381 // The profiler needs to be notified first such subsequent plot 00382 // request from regions are accepted. For that reason there is the 00383 // signal axisChangedProfile which connects to the profiler and is 00384 // emitted prior to axisChanged (in QtDisplayData::checkAxis()) 00385 void axisChanged(String, String, String, std::vector<int> ); 00386 void axisChangedProfile(String, String, String, std::vector<int> ); 00387 00388 void spectrumChanged(String spcTypeUnit, String spcRval, String spcSys); 00389 00390 void statsReady(const String&); 00391 void showColorHistogram( QtDisplayData* ); 00392 00393 void globalOptionsChanged( QtDisplayData*, Record); 00394 00395 protected slots: 00396 00397 // Set the color bar orientation option according to the master 00398 // value stored in the QtViewerBase (panel_->viewer()->colorBarsVertical_). 00399 // Connected to QtViewerBase's colorBarOrientationChange() signal; 00400 // also called during initialization. 00401 virtual void setColorBarOrientation_(); 00402 00403 00404 protected: 00405 00406 // Heuristic used internally to set initial axes to display on X, Y and Z, 00407 // for PADDs. shape should be that of Image/Array, and have same nelements 00408 // as axs. On return, axs[0], axs[1] and (if it exists) axs[2] will be axes 00409 // to display initially on X, Y, and animator, respectively. 00410 // If you pass a CS for the image, it will give special consideration to 00411 // Spectral [/ Direction] axes (users expect their spectral axes on Z, e.g.) 00412 //# (Lifted bodily from GTkDD). 00413 virtual void getInitialAxes_(Block<uInt>& axs, const IPosition& shape, 00414 const DisplayCoordinateSystem &cs); 00415 00416 // Set named colormap onto underlying dd (called from public setOptions()). 00417 // Pass "" to remove/delete any existing colormap for the QDD. 00418 // In the case that no colormap is set on a dd that needs one (raster dds, 00419 // mostly), the drawing canvas will provide a default. 00420 // See ColormapDefinition.h, and the Table gui/colormaps/default.tbl (in the 00421 // data repository) for the list of valid default colormap names (and 00422 // information on creating/installing custom ones). If an invalid name is 00423 // passed, an (ignorable) error message is signalled, and the dd's colormap 00424 // will remain unchanged. 00425 virtual void setColormap_(const String& clrMapName, bool invertChanged = false); 00426 virtual void removeColormap_() { 00427 setColormap_(""); 00428 } 00429 00430 00431 00432 //# (could be exposed publicly, if useful). 00433 // Does this DD use/need a public colormap? 00434 virtual Bool usesClrMap_() { 00435 return (isRaster() || displayType_=="pksmultibeam"); 00436 } 00437 //# These are the only DD types currently needing a colormap and 00438 //# supporting the selection option; add more if/when needed.... 00439 00440 // Can this QDD use a color bar? 00441 virtual Bool usesColorBar_() { 00442 return isRaster(); 00443 } 00444 00445 typedef std::map<const DisplayData*,QtDisplayData*> data_to_qtdata_map_type; 00446 static data_to_qtdata_map_type dd_source_map; 00447 00448 private: 00449 // Not intended for use. 00450 QtDisplayData() : panel_(0), im_(), cim_(), dd_(0) { } 00451 static bool globalColorSettings; 00452 bool setColorBarOptions( Record& opts, Record& chgdOpts ); 00453 void checkGlobalChange( Record& chgdOpts ); 00454 void done(); 00455 //If global color settings is checked and a new QtDisplayData is added, 00456 //it should pick up the global color settings already in place. 00457 void initGlobalColorSettings(); 00458 void initColorSettings(); 00459 Record getGlobalColorChangeRecord( Record& opts ) const; 00460 //# data 00461 00462 QtDisplayPanelGui *panel_; 00463 std::string path_, dataType_, displayType_; 00464 00465 const std::string TYPE_IMAGE; 00466 const std::string SKY_CATALOG; 00467 const std::string MS; 00468 SHARED_PTR<ImageInterface<Float> > im_; 00469 SHARED_PTR<ImageInterface<Complex> > cim_; 00470 DisplayData* dd_; 00471 00472 std::string name_; 00473 00474 bool invertColorMap; 00475 int logScaleColorMap; 00476 00477 // Name of colormap used by dd_ ("" if none) 00478 String clrMapName_; 00479 // Color maps can be removed. In such a case, the restoreColorMapName 00480 //holds the previous one so we can reset to that in case the one we 00481 //are using is removed. 00482 String restoreColorMapName; 00483 00484 // Will be set onto underlying dd_ if needed (0 if none) 00485 Colormap* clrMap_; 00486 00487 // Parses colormap choice out of a setOptions record. 00488 DParameterChoice* clrMapOpt_; 00489 00490 // All the valid ('primary') colormap names. 00491 // (This interface doesn't support use of 'synonym' names). 00492 typedef ColormapDefinition::colormapnamemap colormapnamemap; 00493 colormapnamemap clrMapNames_; 00494 00495 // Set of colormaps currently or previously used by this DD. Once 00496 // a Colormap is created, it is retained for the life of the DD. 00497 //# (A main reason for this is to remember the colormap's 00498 //# 'transfer function' state (brightness/contrast/shift/slope) in case 00499 //# it is reused -- see PCITFiddler.h (colormap mouse tools)). 00500 typedef std::map<String, Colormap*> colormapmap; 00501 colormapmap clrMaps_; 00502 const static String COLOR_MAP; 00503 00504 00505 // Latest error message, retrievable via errMsg(). (Where possible, errors 00506 // are indicated via the qddError signal rather than a throw, and the code 00507 // attempts something sensible in case the caller chooses to ignore it). 00508 String errMsg_; 00509 00510 00511 // The DD that draws the color bar key for the main DD -- 0 if N/A. 00512 WedgeDD* colorBar_; 00513 00514 //# User interface parsing objects for some color bar parameters that are 00515 //# controlled externally to the WedgeDD (colorBar_): whether to display 00516 //# the color bar, its thickness, label (margin) space, orientation, 00517 //# and character size. 00518 //# Changes to any of these DisplayParameters means that the arrangement 00519 //# of colorbars must be checked on all QtDisplayPanels where this QDD 00520 //# is registered (orientation change is sent to base viewer class and 00521 //# handled there). 00522 00523 // Is color bar display turned on? ("Yes" / "No") 00524 DParameterChoice* colorBarDisplayOpt_; 00525 00526 // Manual user adjustment factor for color bar thickness. Hopefully 00527 // the automatic choice (by QtDisplayPanel) will be adequate in most 00528 // cases, and this can remain at the default value of 1. 00529 DParameterRange<Float>* colorBarThicknessOpt_; 00530 00531 // Manual user adjustment factor for color bar label space. Hopefully 00532 // the automatic choice (by QtDisplayPanel) will be adequate in most 00533 // cases, and this can remain at the default value of 1. 00534 DParameterRange<Float>* colorBarLabelSpaceOpt_; 00535 00536 // "horizontal" / "vertical" 00537 DParameterChoice* colorBarOrientationOpt_; 00538 00539 // Size of label characters on color bar (affects margins only). 00540 //# (WedgeDD reacts to this option, but it is also monitored on this level). 00541 DParameterRange<Float>* colorBarCharSizeOpt_; 00542 00543 viewer::ImageProperties image_properties; 00544 00545 }; 00546 00547 00548 } //# NAMESPACE CASA - END 00549 00550 00551 //# Allows QtDisplayData* to be stored in a QVariant; e.g., to be 00552 //# the data associated with a QAction.... See QMetaType and 00553 //# QVariant class doc. QVariants are rather well-designed 00554 //# generic value holders. 00555 //# Note: this declaration cannot be placed within the casa namespace. 00556 Q_DECLARE_METATYPE(casa::QtDisplayData*) 00557 00558 00559 #endif