CanvasView.cxx

Go to the documentation of this file.
00001 
00013 // for MEMFUN1 and others
00014 #ifdef HAVE_CONFIG_H
00015 // for wcslib also
00016 #include "config.h"
00017 #endif
00018 
00019 #if QT_VERSION < 0x040000
00020 #else
00021 //Added by the Qt porting tool:
00022 #include <QMouseEvent>
00023 #endif
00024 
00025 #ifdef _MSC_VER
00026 #include "msdevstudio/MSconfig.h"
00027 #endif
00028 
00029 #include "CanvasView.h"
00030 
00031 #include "CanvasSelectionEvent.h"
00032 #include "CanvasSettings.h"
00033 #include "CanvasWindow.h"
00034 #include "Inspector.h"
00035 #include "PlotterEvent.h"
00036 #include "QtViewFactory.h"
00037 #include "PickTable.h"
00038 #include "WindowController.h"
00039 #include "CreateNTuple.h"
00040 #include "QtGroupView.h"
00041 
00042 #include "controllers/DisplayController.h"
00043 #include "controllers/FunctionController.h"
00044 #include "datareps/ScatterPlot.h"
00045 #include "datasrcs/DataSourceController.h"
00046 #include "datasrcs/NTupleController.h"
00047 #include "graphics/EpsView.h"
00048 #include "plotters/PlotterBase.h"
00049 #include "plotters/Cut1DPlotter.h"
00050 #include "plotters/Cut2DPlotter.h"
00051 #include "qtxml/QtXMLController.h"
00052 #include "transforms/BinaryTransform.h"
00053 
00054 #ifdef HAVE_CFITSIO
00055 #include "fits/FitsController.h"
00056 #endif
00057 
00058 #ifdef HAVE_ROOT
00059 #include "root/RootController.h"
00060 #endif
00061 
00062 #ifdef HAVE_WCSLIB
00063 /* The following were defined in generated ../config.h. */
00064 #undef PACKAGE_BUGREPORT
00065 #undef PACKAGE_NAME
00066 #undef PACKAGE_STRING
00067 #undef PACKAGE_TARNAME
00068 #undef PACKAGE_VERSION
00069 #ifdef _WIN32
00070 #include "wcslib/C/config.h"
00071 #else
00072 #include "wcslib/config.h"
00073 #endif
00074 #endif
00075 
00076 #include <qapplication.h>
00077 #include <qaction.h>
00078 
00079 #if QT_VERSION < 0x040000
00080 #include <qfiledialog.h>
00081 #include <qimage.h>
00082 #else
00083 #include <q3action.h>
00084 #include <q3filedialog.h>
00085 #include <QtGui/QImageWriter>
00086 #endif
00087 
00088 #include <qcursor.h>
00089 #include <qiconset.h>
00090 #include <qmessagebox.h>
00091 #include <qpainter.h>
00092 #include <qsettings.h>
00093 #include <qstatusbar.h>
00094 #include <qwaitcondition.h>
00095 #include <qfont.h>
00096 
00097 #include <algorithm>
00098 #include <exception>
00099 
00100 #include <cctype>
00101 #include <cmath>
00102 
00103 #include <cassert>
00104 
00105 using std::bind2nd;
00106 using std::for_each;
00107 using std::map;
00108 using std::mem_fun;
00109 using std::list;
00110 using std::string;
00111 using std::tolower;
00112 using std::vector;
00113 
00114 namespace {
00115    QWaitCondition mouseEvent;
00116 }
00117 
00118 using namespace hippodraw;
00119 
00120 /* Use `=' syntax so that Doxygen picks it up. */
00121 const string CanvasView::s_app_name = "HippoDraw";
00122 string CanvasView::s_image_filters;
00123 
00124 XmlController * CanvasView::s_xml_controller = 0;
00125 
00126 #if QT_VERSION < 0x040000
00127 CanvasView::CanvasView ( QCanvas * c, QWidget * parent,
00128                          const char * name, Qt::WFlags f )
00129 #else
00130 CanvasView::CanvasView ( Q3Canvas * c, QWidget * parent,
00131                          const char * name, Qt::WFlags f )
00132 #endif
00133   :  FigureEditor ( c, parent, name, f ),
00134      m_inspector ( 0 ),
00135      m_image_dialog ( 0 ),
00136      m_num_width ( 2 ),
00137      m_num_height ( 3 ),
00138      m_cut_mode ( 1 ),
00139      m_edge ( 0 ),
00140      m_clicked( false )
00141 
00142 {
00143   s_xml_controller = QtXMLController::instance ();
00144   m_table_map.clear();
00145   m_drag_rect = 0;
00146 
00147   initSettings ();
00148 }
00149 
00150 void
00151 CanvasView::
00152 initSettings ()
00153 {
00154   QSettings settings;
00155   settings.insertSearchPath ( QSettings::Windows, s_registry );
00156 
00157   m_num_width
00158     = settings.readNumEntry ( s_app_key + "Canvas/Number/Width", 2 );
00159   m_num_height
00160     = settings.readNumEntry ( s_app_key + "Canvas/Number/Height", 3 );
00161   m_add_selected
00162     = settings.readBoolEntry ( s_app_key + "Canvas/AddSelected" );
00163   m_ignore_margin
00164     = settings.readBoolEntry ( s_app_key + "Canvas/IgnoreMargin" );
00165 }
00166 
00167 void
00168 CanvasView::
00169 #if QT_VERSION < 0x040000
00170 initDockWindows ( QMainWindow * mw )
00171 #else
00172 initDockWindows ( Q3MainWindow * mw )
00173 #endif
00174 {
00175   QSettings settings;
00176   settings.insertSearchPath ( QSettings::Windows, s_registry );
00177   bool ok = false;
00178   QString dockSetting = settings.readEntry ( s_app_key + "DockWindow/Position",
00179                                              QString::null, &ok );
00180 
00181   if ( ok == false ) return;
00182   QTextStream stream( &dockSetting, IO_ReadOnly );
00183   stream >> *mw;
00184 }
00185 
00186 void
00187 CanvasView::
00188 initRecentFiles ( QActionGroup * ag )
00189 {
00190 #if QT_VERSION < 0x040000
00191 #else
00192   QObject * parent = ag -> parent ();
00193 #endif  
00194   QSettings settings;
00195   settings.insertSearchPath ( QSettings::Windows, s_registry );
00196   bool ok = false;
00197 
00198   // Read every entries from the settings.
00199   for (unsigned int i = 0; i<5; i++){
00200     QString number=QString::number(i);
00201     QString entry = settings.readEntry ( s_app_key + "Files/File"+number,
00202                                          QString::null, &ok );
00203     
00204     // No entry or empty entry.
00205     if ((ok==false) || ( entry == "" )) return;
00206     
00207     
00208 #if QT_VERSION < 0x040000
00209     QAction * action = new QAction ( "", // text
00210                                      QIconSet(),
00211                                      entry, // menu test
00212                                      0, // accel
00213                                      ag ); // parent
00214 #else
00215     QAction * action = new QAction ( entry, parent );
00216     ag -> addAction ( action );
00217 #endif
00218     m_recent_list.push_back( action );
00219     action -> setToggleAction ( true );
00220   }
00221 }
00222 
00223 
00224 void
00225 CanvasView::
00226 initFitterDefault ()
00227 {
00228   QSettings settings;
00229   settings.insertSearchPath ( QSettings::Windows, s_registry );
00230   bool ok = false;
00231   QString entry = settings.readEntry ( s_app_key + "Fitter/Name",
00232                                        QString::null, &ok );
00233   if ( ok == true ) {
00234     const string name ( entry.latin1() );
00235     try { // might not be available
00236       setFitterDefault ( name );
00237       if ( m_inspector != 0 ) {
00238         m_inspector -> setSelectedFitter ( name );
00239       }
00240     }
00241     catch ( ... ) { // not available in this build
00242       // could raise error dialog, but not nice on initialization
00243     }
00244   }
00245 }
00246 
00247 void
00248 CanvasView::
00249 setFitterDefault ( const QString & name )
00250 {
00251   QSettings settings;
00252   settings.insertSearchPath ( QSettings::Windows, s_registry );
00253   settings.writeEntry ( s_app_key + "Fitter/Name", name );
00254 
00255   const string fitter ( name.latin1() );
00256   setFitterDefault ( fitter );
00257 }
00258 void
00259 CanvasView::
00260 setFitterDefault ( const std::string & name )
00261 {
00262   FunctionController * controller = FunctionController::instance ();
00263   controller -> setDefaultFitter ( name );
00264 }
00265 
00266 void
00267 CanvasView::
00268 initFitterSettings ( QActionGroup * ag )
00269 {
00270   initFitterDefault ();
00271   initFitterMenu ( ag );
00272 }
00273 
00274 void
00275 CanvasView::
00276 initFitterMenu ( QActionGroup * ag )
00277 {
00278   FunctionController * controller = FunctionController::instance();
00279   const vector < string > & fitters = controller -> getFitterNames ();
00280   const string & def_fitter = controller -> getDefaultFitter ();
00281 #if QT_VERSION < 0x040000
00282 #else
00283   QObject * parent = ag -> parent ();
00284 #endif
00285   for ( unsigned int i = 0; i < fitters.size(); i++ ) {
00286 #if QT_VERSION < 0x040000
00287     const QString name ( fitters[i].c_str() );
00288     QAction * action = new QAction ( "", // text
00289                                      QIconSet(),
00290                                      name, // menu test
00291                                      0, // accel
00292                                      ag ); // parent
00293 #else
00294     const QString name ( fitters[i].c_str() );
00295     QAction * action = new QAction ( name, parent );
00296     ag -> addAction ( action );
00297 #endif
00298     action -> setToggleAction ( true );
00299     if ( def_fitter == fitters[i] ) {
00300       action -> setOn ( true );
00301     }
00302   }
00303 }
00304 
00305 
00306 void
00307 CanvasView::
00308 saveSettings () const
00309 {
00310   QSettings settings;
00311   settings.insertSearchPath ( QSettings::Windows, s_registry );
00312 
00313   int orientation;
00314   if( s_printer -> orientation() == QPrinter::Portrait )
00315     orientation = 0;
00316   else
00317     orientation = 1;
00318 
00319   settings.writeEntry ( s_app_key + "Printer/Orientation", orientation );
00320   settings.writeEntry ( s_app_key + "Canvas/Number/Width",  m_num_width );
00321   settings.writeEntry ( s_app_key + "Canvas/Number/Height", m_num_height );
00322   settings.writeEntry ( s_app_key + "Canvas/AddSelected", m_add_selected );
00323   settings.writeEntry ( s_app_key + "Canvas/IgnoreMargin", m_ignore_margin );
00324 
00325   if( m_printer_bounds == false )
00326     settings.writeEntry ( s_app_key + "Canvas/Margin", 0 );
00327   else
00328     settings.writeEntry ( s_app_key + "Canvas/Margin", 1 );
00329 }
00330 
00331 void
00332 CanvasView::
00333 setAddedSelected ( bool yes )
00334 {
00335   m_add_selected = yes;
00336 }
00337 
00338 void CanvasView::initFrom ( const std::list < ViewBase * > & views )
00339 {
00340   std::list < ViewBase * > ::const_iterator first = views.begin();
00341   for ( ; first != views.end(); ++first ) {
00342     QtView * view = dynamic_cast < QtView * > ( *first );
00343     if ( view -> height () < 0 ||
00344          view -> width () < 0 ) {
00345       sizeAndPlace ( view );
00346     }
00347     add ( view ); // ignore the rest
00348   }
00349 
00350 #if QT_VERSION < 0x040000
00351   QCanvasView::ensureVisible ( 0, 0 );
00352 #else
00353   Q3CanvasView::ensureVisible ( 0, 0 );
00354 #endif
00355 }
00356 
00357 void
00358 CanvasView::
00359 initFromFile ( const std::string & filename )
00360 {
00361   XmlController::Status status = s_xml_controller->openFile ( filename );
00362 
00363   // If file not found, change the directory and try again.
00364   if ( status == XmlController::NTupleError ) {
00365 
00366     std::list < std::string > & missing_tuples = 
00367       s_xml_controller -> getMissingTuples ();
00368     std::list< std::string>::iterator it;
00369 
00370     for ( it=missing_tuples.begin(); it!=missing_tuples.end(); ++it )
00371       {
00372         string shortFileName;
00373         string::size_type pos1 = (*it).find_last_of ("/");
00374         string::size_type pos2 = (*it).find_last_of (":");
00375         shortFileName = (*it).substr(pos1+1); // get the short filename
00376         
00377         QString cap ( "Select the DataSource:  " );
00378         cap += shortFileName.c_str(); // Caption of the open file dialog
00379         QString filter ( "All files(*.*);;Text NTuple(*.tnt);;FITS file(*.fits);;Compressed FITS file(*.fits.gz);;ROOT file(*.root)");
00380         
00381         QString filename =
00382 #if QT_VERSION < 0x040000
00383           QFileDialog::getOpenFileName ( QString::null, // starting directory
00384                                          filter, // filter
00385                                          this,
00386                                          "Open file dialog",
00387                                          cap ); // caption
00388 #else
00389         Q3FileDialog::getOpenFileName ( QString::null, // starting directory
00390                                         filter, // filter
00391                                         this,
00392                                         "Open file dialog",
00393                                         cap ); // caption
00394 #endif
00395 
00396         string newFileName = filename.latin1();
00397 
00398 
00399         if ( ( pos2!= string::npos)  && (pos2 != 1) ) {
00400           ( *it ).replace (0, pos2, newFileName); // keep the name
00401                                                   // after ":"
00402                                                   // unchanged
00403         }
00404         else {
00405           ( *it )=newFileName; // with no name
00406         }
00407 
00408       }
00409 
00410     status = s_xml_controller->openUpdatedNTuples (  );    
00411   }
00412 
00413 
00414   // Second try failed, show failed message.
00415   if ( status != XmlController::Success ) {
00416     const string & app_name = applicationName ();
00417 
00418     QString fn = filename.c_str ();
00419     QString message;
00420     message = QString("Unable to open document file:\n%1\n").arg ( fn );
00421     if ( status == XmlController::OpenError ) {
00422       message += "\nFile could not be read\n";
00423     } else
00424       if ( status == XmlController::ParseError ) {
00425         message += "\nThere was a XML parsing error\n";
00426       } else {
00427         message += "\nThere were one or more referenced\n";
00428         message += "NTuple files that could not be found.";
00429       }
00430     QMessageBox::critical ( this, // parent
00431                             app_name.c_str(), // caption
00432                             message,
00433                             QMessageBox::Ok,
00434                             Qt::NoButton,
00435                             Qt::NoButton );
00436     show ();
00437     return;
00438   }
00439 
00440   ViewFactory * factory = QtViewFactory::instance ();
00441   const list < ViewBase * > & view_list
00442     = s_xml_controller->getViews ( factory );
00443 
00444   initFrom ( view_list );
00445 
00446   notifyObservers ();
00447 }
00448 
00449 void
00450 CanvasView::
00451 invalidImageFormatError ( const std::string & filename )
00452 {
00453   if ( s_image_filters.empty () ) createImageFilters ();
00454 
00455   string types;
00456   string::size_type size = s_image_filters.size ();
00457   for ( string::size_type i = 0; i < size; i++ ) {
00458     string::value_type c = s_image_filters[i];
00459     if ( c != '(' &&
00460          c != ')' &&
00461          c != ';' ) types += c;
00462   }
00463 
00464   string message ( "Attempt to save image to file:\n" );
00465   message += filename;
00466   message += "\nwhose suffix indicates unsupported image format.\n\n";
00467   message += "Supported image formats are:\n";
00468   message += types;
00469 
00470   QMessageBox::critical ( this, // parent
00471                           "Image format error", // caption
00472                           message.c_str() );
00473 
00474 }
00475 
00476 bool
00477 CanvasView::
00478 existingFileWarning ( const std::string & filename )
00479 {
00480   string message ( "The file:\n" );
00481   message += filename;
00482   message += "\nalready exists.\n\n";
00483   message += "Over-write existing file?";
00484 
00485   int yes = QMessageBox::warning ( this, //parent
00486                                    "Existing file warning", // caption
00487                                    message.c_str(),
00488                                    QMessageBox::Yes,
00489                                    QMessageBox::No,
00490                                    Qt::NoButton );
00491 
00492   return yes == QMessageBox::Yes;
00493 }
00494 
00498 void
00499 CanvasView::
00500 copySelectedToPasteboard ()
00501 {
00502   const vector < const ViewBase * > & selViews = selectedViews();
00503   if ( selViews.empty () ) return;
00504 
00505   vector < const ViewBase * > view_list;
00506   fillSelectedWithObservers ( view_list );
00507   s_xml_controller->saveToPasteboard ( view_list );
00508 
00509   copySelectedToClipboard ();
00510 }
00511 
00512 void
00513 CanvasView::
00514 copyFromPasteboard ()
00515 {
00516   const vector < const ViewBase * > & targets = views ();
00517   ViewFactory * factory = QtViewFactory::instance ();
00518 
00519   const list < ViewBase * > & pb_views
00520     = s_xml_controller->getFromPasteboard ( factory, targets );
00521   pasteViews ( pb_views );
00522 }
00523 
00524 void
00525 CanvasView::
00526 addFromPasteboard ()
00527 {
00528   const vector < const ViewBase * > & targets = views ();
00529   ViewFactory * factory = QtViewFactory::instance ();
00530 
00531   const list < ViewBase * > & pb_views
00532     = s_xml_controller->getFromPasteboard ( factory, targets );
00533   list < ViewBase * >::const_iterator first = pb_views.begin ();
00534   while ( first != pb_views.end () ) {
00535     ViewBase * view = *first++;
00536     QtView * qtview = dynamic_cast < QtView * > ( view );
00537     placeGraph ( qtview );
00538     addView ( qtview, true );
00539   }
00540 }
00541 
00542 void
00543 CanvasView::
00544 deleteSelected ( bool pasteboard )
00545 {
00546   const vector < const ViewBase * > & selViews = selectedViews();
00547   if ( selViews.empty () ) return;
00548 
00549   vector < const ViewBase * > view_list;
00550   fillSelectedWithObservers ( view_list );
00551   if ( pasteboard ) {
00552     s_xml_controller->saveToPasteboard ( view_list );
00553   }
00554 
00555   DisplayController * controller = DisplayController::instance ();
00556   controller->removeTextObservers ( view_list );
00557 
00558   // Remove views from the canvas.
00559 
00560 #ifdef ITERATOR_MEMBER_DEFECT
00561   std::
00562 #endif
00563   vector < const ViewBase * > ::const_iterator iter = view_list.begin();
00564 
00565   // Remove views or group views.
00566   while ( iter != view_list.end() ) {
00567     const ViewBase * curview = ( * iter++ );
00568     const QtView * view = dynamic_cast < const QtView * > ( curview );
00569     QtView * v = 0;
00570     if (view) v = const_cast < QtView * > ( view );
00571     const QtGroupView * groupview = 
00572       dynamic_cast < const QtGroupView * > ( curview );
00573     QtGroupView * gv =  0;
00574     if (groupview) gv = const_cast < QtGroupView * > (groupview);
00575     if (v) remove ( v );
00576     if (gv) remove (gv);
00577   }
00578 
00579   notifyObservers ();
00580 }
00581 
00582 void
00583 CanvasView::
00584 clear ()
00585 {
00586   FigureEditor::clear ();
00587 
00588   notifyObservers ();
00589 }
00590 
00595 void CanvasView::removeSelected ( )
00596 {
00597   const vector < const ViewBase * > & views = selectedViews ();
00598 #ifdef ITERATOR_MEMBER_DEFECT
00599   std::
00600 #endif
00601   vector < const ViewBase * > ::const_iterator first = views.begin();
00602   while ( first != views.end() ) {
00603     const QtView * view = dynamic_cast < const QtView * > ( *first++ );
00604     QtView * v = const_cast < QtView * > ( view );
00605     remove ( v );
00606   }
00607 }
00608 
00612 void CanvasView::pasteViews ( const std::list < ViewBase * > & views )
00613 {
00614   clearSelectedList ();
00615   std::list < ViewBase * > ::const_iterator first = views.begin();
00616   for ( ; first != views.end(); ++first ) {
00617     QtView * view = dynamic_cast < QtView * > ( *first );
00618     paste ( view );
00619     addSelectedItem ( view );
00620   }
00621 
00622   setChanged ( true );
00623 }
00624 
00625 void CanvasView::setInspector ( Inspector * inspector )
00626 {
00627   m_inspector = inspector;
00628   m_inspector->enableNewPlotBox ( );
00629 }
00630 
00631 Inspector * CanvasView::getInspector ()
00632 {
00633   return m_inspector;
00634 }
00635 
00636 void CanvasView::setChanged ( bool flag )
00637 {
00638   QWidget * parent = parentWidget ();
00639   if ( parent != 0 ) {
00640     PlotterEvent * event = new PlotterEvent ( 0 );
00641     QApplication::postEvent ( parent, event );
00642   }
00643 }
00644 
00645 void CanvasView::notifyObservers ()
00646 {
00647   setChanged ( true );
00648   if ( m_inspector != 0 ) {
00649     vector < PlotterBase * > plotters = getSelectedPlotters ();
00650 
00651     CanvasSelectionEvent * event = new CanvasSelectionEvent ( plotters );
00652     QApplication::postEvent ( m_inspector, event );
00653   }
00654 
00655   WindowController * controller = WindowController::instance ();
00656   controller -> updateActions ();
00657 }
00658 
00659 vector < PlotterBase * >
00660 CanvasView::
00661 getSelectedPlotters () const
00662 {
00663   vector < PlotterBase * > plotters;
00664 
00665   const vector < const ViewBase * > & viewList = selectedViews ();
00666   unsigned int size = viewList.size ();
00667   for ( unsigned int i = 0; i < size; i++ ) {
00668     const ViewBase * view = viewList [ i ];
00669 
00670     const QtGroupView * groupView = dynamic_cast <const QtGroupView *> (view);
00671 
00672     if (groupView) {
00673       const vector <PlotterBase *> groupPlotters = groupView -> getPlotters ();
00674       plotters.insert ( plotters.end(), 
00675                         groupPlotters.begin(), groupPlotters.end() );
00676       break;
00677     } 
00678 
00679     //else
00680     PlotterBase * plotter = view -> getPlotter ();
00681     if ( plotter != 0 ) {
00682       plotters.push_back ( plotter );
00683     }
00684   }
00685 
00686   return plotters;
00687 }
00688 
00689 PlotterBase * CanvasView::selectedPlotter () const
00690 {
00691   const vector < const ViewBase * > & viewList = selectedViews ();
00692 
00693   if ( viewList.size() != 1 )
00694     {
00695       return 0;
00696     }
00697 
00698   PlotterBase * plotter = viewList[0]->getPlotter ();
00699   //assert ( plotter );      // Can return 0, handle by caller.
00700 
00701   return plotter;
00702 }
00703 
00704 void
00705 CanvasView::
00706 addView ( QtView * view, bool select )
00707 {
00708   add ( view ); // in FigureEditor
00709   if ( select ) {
00710     ensureVisible ( view );
00711     setSelectedItem ( view );
00712     vector < const ViewBase * > view_list;
00713     fillSelectedWithObservers ( view_list );
00714     s_xml_controller -> saveToSelectionCopy ( view_list );
00715   }
00716   notifyObservers ();
00717 }
00718 
00719 void
00720 CanvasView::
00721 setPlotMatrix ( unsigned int columns, unsigned int rows )
00722 {
00723   m_num_width = columns;
00724   m_num_height = rows;
00725 }
00726 
00727 void
00728 CanvasView::
00729 swapOrientation ()
00730 {
00731 #if QT_VERSION < 0x040000
00732   QCanvas * can = canvas();
00733 #else
00734   Q3Canvas * can = canvas();
00735 #endif
00736   int numpages = static_cast<int> ( can -> height()
00737                                    / (double) m_apage_h );
00738   std::swap( m_upage_w, m_upage_h );
00739   std::swap( m_apage_w, m_apage_h );
00740 
00741   can -> resize ( static_cast<int> ( 1.2 * m_upage_w ),
00742                   numpages * m_apage_h );
00743 
00744   showPrinterMargins ( false ); // Delete old ones ( if any    )
00745   showPrinterMargins ( true );  // Redraw new ones ( if needed )
00746 }
00747 
00748 void
00749 CanvasView::
00750 setup ()
00751 {
00752   CanvasSettings * cs = new CanvasSettings ( this );
00753   cs -> setOrientation ( s_printer -> orientation() );
00754   cs -> setWidthNumber ( m_num_width );
00755   cs -> setHeightNumber ( m_num_height );
00756   cs -> setAddSelected ( m_add_selected );
00757   cs -> setPrinterBounds ( m_printer_bounds );
00758   cs -> setIgnorePrinterMargin ( m_ignore_margin );
00759 
00760   int retval = cs -> exec ();
00761 
00762   if (  retval == CanvasSettings::AcceptedAndRetile ||
00763         retval == CanvasSettings::Retile )
00764     {
00765       m_add_selected = cs -> getAddSelected ();
00766 
00767 
00768       if ( cs -> orientation() != s_printer -> orientation() ) {
00769         s_printer -> setOrientation( cs -> orientation() );
00770         swapOrientation ();
00771       }
00772 
00773       if( cs -> printerBounds() == false )
00774         showPrinterMargins ( false ); // Delete old ones ( if any    )
00775       else
00776         {
00777           showPrinterMargins ( false ); // Delete old ones ( if any    )
00778           showPrinterMargins ( true );  // Redraw new ones ( if needed )
00779         }
00780 
00781       m_ignore_margin = cs -> ignorePrinterMargin ();
00782     }
00783 
00784   if ( retval == CanvasSettings::AcceptedAndRetile ||
00785        retval == CanvasSettings::Retile ) {
00786     unsigned int columns = cs -> getWidthNumber ();
00787     unsigned int rows    = cs -> getHeightNumber ();
00788     setPlotMatrix ( columns, rows );
00789     reTile ();
00790   }
00791 
00792   if ( retval == CanvasSettings::AcceptedAndRetile ) {
00793     saveSettings ();
00794   }
00795 
00796   delete cs;
00797 }
00798 
00799 
00800 void
00801 CanvasView::
00802 setFonts( const QFont & font )
00803 {
00804   const vector < const ViewBase * > & allviews = views();
00805 
00806   for( unsigned int i = 0; i < allviews.size(); i++ )
00807     {
00808       const ViewBase * curview = allviews[ i ];
00809       const QtView * view = dynamic_cast < const QtView * > ( curview );
00810       QtView * v = const_cast < QtView * > ( view );
00811       v -> setDefaultFont( font );
00812       v -> getPlotter() -> update();
00813     }
00814 }
00815 
00816 void
00817 CanvasView::
00818 calcDefaultSize ( QtView * view, double transform_aspect_ratio )
00819 {
00820   double width = ( 0.95 * m_upage_w ) / m_num_width;
00821   double height = ( 0.95 * m_upage_h ) / m_num_height;
00822 
00823   if ( transform_aspect_ratio > 0.0 )
00824     {
00825       width = height * transform_aspect_ratio;
00826     }
00827 
00828   view -> setDrawRect ( 0.0, 0.0, width, height );
00829 }
00830 
00831 
00832 void
00833 CanvasView::
00834 addPlotDisplay ( PlotterBase * plotter )
00835 {
00836   addPlotDisplay ( plotter, m_add_selected );
00837 }
00838 
00839 QtView *
00840 CanvasView::
00841 wrapPlotter ( PlotterBase * plotter )
00842 {
00843   ViewFactory * factory = QtViewFactory::instance ();
00844   ViewBase * view = factory -> createView ( plotter );
00845   QtView * qtview = dynamic_cast< QtView * > ( view );
00846   qtview -> setSize ( -1, -1 );
00847 
00848   return qtview;
00849 }
00850 
00851 void CanvasView::addPlotDisplay ( PlotterBase * plotter, bool select )
00852 {
00853   QtView * qtview = wrapPlotter ( plotter );
00854   qtview -> setPageWidth( m_upage_w );
00855   qtview -> setInspector( m_inspector );
00856   sizeAndPlace ( qtview  );
00857 
00858   addView ( qtview, select );
00859 }
00860 
00861 void
00862 CanvasView::
00863 sizeAndPlace ( QtView * view )
00864 {
00865   PlotterBase * plotter = view -> getPlotter ();
00866   double transform_aspect_ratio = plotter -> getAspectRatio();
00867   calcDefaultSize ( view, transform_aspect_ratio );
00868   placeGraph ( view );
00869 }
00870 
00871 static bool
00872 #if QT_VERSION < 0x040000
00873 sortViews ( QCanvasItem * first, QCanvasItem * second )
00874 #else
00875 sortViews ( Q3CanvasItem * first, Q3CanvasItem * second )
00876 #endif
00877 {
00878   bool yes = false;
00879 
00880   QRect frect = first -> boundingRect ();
00881   QRect srect = second -> boundingRect ();
00882 
00883   if ( frect.left () < srect.left () ) {
00884     if ( frect.top() < srect.bottom () ) {
00885       yes = true;
00886     }
00887   }
00888   if ( frect.right () > srect.right () ) {
00889     if ( frect.bottom () <  srect.top () ) {
00890       yes = true;
00891     }
00892   }
00893   else {
00894     yes = frect.top () < srect.top ();
00895   }
00896 
00897   return yes;
00898 }
00899 
00900 void
00901 CanvasView::
00902 reTile ()
00903 {
00904 #if QT_VERSION < 0x040000
00905   QCanvas temp_canvas;
00906 #else
00907   Q3Canvas temp_canvas;
00908 #endif
00909 #ifdef MEMFUN1_DEFECT
00910   for_each ( m_items.begin(), m_items.end(),
00911 #if QT_VERSION < 0x040000
00912              bind2nd ( mem_fun1 ( & QCanvasItem::setCanvas ), &temp_canvas ) );
00913 #else
00914              bind2nd ( mem_fun1 ( & Q3CanvasItem::setCanvas ),
00915                        &temp_canvas ) );
00916 #endif
00917 #else
00918   for_each ( m_items.begin(), m_items.end(),
00919 #if QT_VERSION < 0x040000
00920              bind2nd ( mem_fun ( & QCanvasItem::setCanvas ), &temp_canvas ) );
00921 #else
00922              bind2nd ( mem_fun ( & Q3CanvasItem::setCanvas ), &temp_canvas ) );
00923 #endif
00924 #endif
00925 
00926 #if QT_VERSION < 0x040000
00927   vector < QCanvasItem * > items ( m_items );
00928 #else
00929   vector < Q3CanvasItem * > items ( m_items );
00930 #endif
00931   m_items.clear();
00932 
00933   sort ( items.begin(), items.end(), sortViews );
00934 
00935   placeItems ( items );
00936 }
00937 
00938 void
00939 CanvasView::
00940 #if QT_VERSION < 0x040000
00941 placeItems ( const std::vector < QCanvasItem * > & items )
00942 {
00943   vector < QCanvasItem * >:: const_iterator first = items.begin();
00944 #else
00945 placeItems ( const std::vector < Q3CanvasItem * > & items )
00946 {
00947   vector < Q3CanvasItem * >:: const_iterator first = items.begin();
00948 #endif
00949 
00950   // Place xy plotters before text plotters.
00951   vector <QtView *> textViews;
00952   
00953   while ( first != items.end() )
00954     {
00955       QtView * view = dynamic_cast < QtView * > ( *first++ );
00956 
00957       PlotterBase * plotter = view->getPlotter();
00958       if (plotter->isTextPlotter()) {
00959         // Move back to (0,0) and add to textView list.
00960         double x = view -> x ();
00961         double y = view -> y ();
00962         view->moveBy(-x, -y);
00963         textViews.push_back(view);
00964         continue;
00965       }
00966       calcDefaultSize ( view, view -> getAspectRatio() );
00967       placeGraph ( view );
00968       add ( view );
00969     }
00970 
00971   // Add text plotters to their parent plotters
00972   vector <QtView *>::const_iterator it = textViews.begin();
00973   while ( it != textViews.end() )
00974     {
00975       QtView * view = *it++;
00976       moveToPlotter(view->getPlotter()->getParentPlotter(), view );
00977       add ( view );
00978     }
00979 }
00980 
00981 void
00982 CanvasView::
00983 reTilePage ()
00984 {
00985   int y = contentsY ();
00986   int page = y / m_apage_h;
00987   QRect rect ( 0, page * m_apage_h, m_apage_w, m_apage_h );
00988 #if QT_VERSION < 0x040000
00989   QCanvasItemList c_items = m_canvas -> collisions ( rect );
00990 
00991   // copy to STL vector and remove from item list.
00992   vector < QCanvasItem * > v_items;
00993   QCanvasItemList:: const_iterator first = c_items.begin();
00994   while ( first != c_items.end() ) {
00995     QCanvasItem * item = *first++;
00996 #else
00997   Q3CanvasItemList c_items = m_canvas -> collisions ( rect );
00998 
00999   // copy to STL vector and remove from item list.
01000   vector < Q3CanvasItem * > v_items;
01001   Q3CanvasItemList:: const_iterator first = c_items.begin();
01002   while ( first != c_items.end() ) {
01003     Q3CanvasItem * item = *first++;
01004 #endif
01005     QtView * view = dynamic_cast < QtView * > ( item );
01006 
01007     if ( view != 0 ) { // avoid page margin rect
01008       v_items.push_back ( item );
01009       removeFromItemList ( item );
01010     }
01011   }
01012 
01013   placeItems ( v_items );
01014 }
01015 
01016 void CanvasView::moveToPlotter ( const PlotterBase * plotter, QtView * view )
01017 {
01018   QtView * target = getViewFor ( plotter );
01019   QRect rect = target -> boundingRect ();
01020   double x = target -> x ();
01021   double y = target -> y ();
01022   x += 0.25 * rect.width();
01023   y += 0.25 * rect.height();
01024 
01025   view->moveBy ( x, y );
01026 }
01027 
01028 std::pair<double, double>
01029 CanvasView::
01030 moveToPlotterAt ( const PlotterBase * plotter,
01031                   QtView * view,
01032                   double xrel, double yrel )
01033 {
01034    QtView * sel_item = getViewFor ( plotter );
01035    QRect rect = sel_item->boundingRect ();
01036    double x = sel_item->x();
01037    double y = sel_item->y();
01038    x += xrel * rect.width();
01039    y += yrel * rect.height();
01040 
01041    view->moveBy ( x, y );
01042 
01043 // Find the lower left corner of the view.
01044    QRect viewRect = view->boundingRect();
01045    double xLowerLeft = view->x();
01046    double yLowerLeft = view->y() + viewRect.height();
01047 
01048 // Normalize to selectedItem coordinate system.
01049    xLowerLeft = ( xLowerLeft - sel_item->x() ) / rect.width();
01050    yLowerLeft = ( yLowerLeft - sel_item->y() ) / rect.height();
01051 
01052    return std::make_pair<double, double>(xLowerLeft, yLowerLeft);
01053 }
01054 
01055 void
01056 CanvasView::
01057 addTextDisplay ( PlotterBase * plotter,
01058                  const std::string & s,
01059                  const std::string & text )
01060 {
01061   DisplayController * display_controller = DisplayController::instance ();
01062   ViewFactory * factory = QtViewFactory::instance ();
01063 
01064   ViewBase * view
01065     = display_controller->createTextView ( factory, plotter, s, text );
01066   assert ( view != 0 );
01067 
01068   QtView * qtview = dynamic_cast < QtView * > ( view );
01069   assert ( qtview != 0 );
01070 
01071   moveToPlotter ( plotter, qtview );
01072 
01073   addView ( qtview, false );
01074 
01075   // Make sure new view on top of others
01076   double z = maximumZ ();
01077   
01078   // Make sure the new text plotter on top all other text plotters
01079   qtview->setZ(z+101.0);
01080 }
01081 
01082 std::pair<double, double>
01083 CanvasView::
01084 addTextDisplayAt ( PlotterBase * plotter,
01085                    const std::string & type,
01086                    const std::string & text,
01087                    double x, double y )
01088 {
01089   DisplayController * display_controller = DisplayController::instance ();
01090   ViewFactory * factory = QtViewFactory::instance ();
01091 
01092   ViewBase * view
01093     = display_controller->createTextView ( factory, plotter, type, text );
01094 
01095   QtView * qtview = dynamic_cast < QtView * > ( view );
01096 
01097   std::pair<double, double> lowerLeftCorner
01098      = moveToPlotterAt ( plotter, qtview, x, y );
01099 
01100   addView ( qtview, false );
01101 
01102   return lowerLeftCorner;
01103 }
01104 
01105 void
01106 CanvasView::
01107 addFuncDisplay ( PlotterBase * plotter, const std::string & s)
01108 {
01109   FunctionController * controller = FunctionController::instance ();
01110   const ViewFactory * factory = QtViewFactory::instance ();
01111 
01112   ViewBase * view
01113     = controller->createFuncView ( factory, plotter, s );
01114 
01115   QtView * qtview = dynamic_cast < QtView * > ( view );
01116   moveToPlotter ( plotter, qtview );
01117 
01118   addView (qtview, false );
01119 }
01120 
01123 void
01124 CanvasView::
01125 removeDisplay ( PlotterBase * plotter )
01126 {
01127  QtView * view = getViewFor ( plotter );
01128 
01129  if ( view != 0 ) remove ( view );
01130 }
01131 
01132 void
01133 CanvasView::
01134 setVisibleNonViews ( bool yes )
01135 {
01136 #if QT_VERSION < 0x040000
01137   QCanvasItemList items = m_canvas->allItems ();
01138   QCanvasItemList::Iterator first = items.begin();
01139   while ( first != items.end() ) {
01140     QCanvasItem * item = *first++;
01141 #else
01142   Q3CanvasItemList items = m_canvas->allItems ();
01143   Q3CanvasItemList::Iterator first = items.begin();
01144   while ( first != items.end() ) {
01145     Q3CanvasItem * item = *first++;
01146 #endif
01147     QtView * view = dynamic_cast < QtView * > ( item );
01148       if ( view == 0 ) {
01149         item -> setVisible ( yes );
01150       }
01151   }
01152 }
01153 
01154 void
01155 CanvasView::
01156 print ()
01157 {
01158   setVisibleNonViews ( false );
01159   FigureEditor::print ();
01160   setVisibleNonViews ( true );
01161 }
01162 
01163 void
01164 CanvasView::
01165 print ( const std::string & filename )
01166 {
01167   setVisibleNonViews ( false );
01168   FigureEditor::print ( filename );
01169   setVisibleNonViews ( true );
01170 }
01171 
01172 
01173 const vector < const ViewBase * > &
01174 CanvasView::
01175 selectedViews () const
01176 {
01177   m_sel_views.clear ();
01178 
01179 #if QT_VERSION < 0x040000
01180   vector < QCanvasItem * > :: const_iterator first = m_selected_list.begin();
01181   while ( first != m_selected_list.end() ) {
01182     QCanvasItem * item = *first++;
01183 #else
01184   vector < Q3CanvasItem * > :: const_iterator first = m_selected_list.begin();
01185   while ( first != m_selected_list.end() ) {
01186     Q3CanvasItem * item = *first++;
01187 #endif
01188     QtView * view = dynamic_cast < QtView * > ( item );
01189     if ( view != 0 ) { // may be printer page border
01190       m_sel_views.push_back ( view );
01191     }
01192     QtGroupView * groupview = dynamic_cast < QtGroupView * > ( item );
01193     if ( groupview != 0 ){
01194       m_sel_views.push_back ( groupview );
01195     }
01196   }
01197 
01198   return m_sel_views;
01199 }
01200 
01201 const vector < const ViewBase * > & CanvasView::views () const
01202 {
01203   m_views.clear();
01204 
01205 #if QT_VERSION < 0x040000
01206   QCanvasItemList item_list = m_canvas->allItems();
01207   QCanvasItemList::Iterator it = item_list.begin();
01208 #else
01209   Q3CanvasItemList item_list = m_canvas->allItems();
01210   Q3CanvasItemList::Iterator it = item_list.begin();
01211 #endif
01212   for ( ; it != item_list.end(); ++ it ) {
01213     const QtView * view = dynamic_cast < const QtView * > ( *it );
01214     if ( view != 0 ) {
01215       m_views.push_back ( view );
01216     }
01217   }
01218 
01219   return m_views;
01220 }
01221 
01222 void
01223 CanvasView::
01224 fillPlotterList ( std::vector < PlotterBase * > & plotterlist )
01225 {
01226   plotterlist.clear();
01227 
01228   const vector < const ViewBase * > & view_list = views ();
01229 #ifdef ITERATOR_MEMBER_DEFECT
01230   std::
01231 #endif
01232   vector < const ViewBase * >::const_iterator first = view_list.begin ();
01233   for ( ; first != view_list.end(); ++first ) {
01234     const QtView * qtview = dynamic_cast < const QtView * > ( *first );
01235     plotterlist.push_back ( qtview->getPlotter () );
01236   }
01237 }
01238 
01239 
01240 QtView *
01241 CanvasView::
01242 getViewFor ( const PlotterBase * target ) const
01243 {
01244   QtView * view = 0;
01245   const vector < const ViewBase * > & all_views = views ();
01246   vector < const ViewBase * > :: const_iterator  first = all_views.begin();
01247 
01248   while ( first != all_views.end() ) {
01249     const ViewBase * vb = *first++;
01250     const PlotterBase * plotter = vb->getPlotter();
01251     if ( plotter == target ) {
01252       const QtView * v = dynamic_cast < const QtView * > ( vb );
01253       view = const_cast < QtView * > ( v );
01254       break;
01255     }
01256   }
01257 
01258   return view;
01259 }
01260 
01261 void
01262 CanvasView::
01263 createImageFilters ()
01264 {
01265 #ifdef STRING_CLEAR_DEFECT
01266   s_image_filters.erase();
01267 #else
01268   s_image_filters.clear();
01269 #endif
01270 
01271   const string eps ( "eps" );
01272   bool eps_inserted = false;
01273 
01274 #if QT_VERSION < 0x040000
01275   QStringList slist = QImage::outputFormatList ();
01276   QStringList::Iterator it = slist.begin();
01277 #else
01278   QList < QByteArray >  slist = QImageWriter::supportedImageFormats ();
01279   QList < QByteArray > ::const_iterator it = slist.begin();
01280 #endif
01281 
01282   while ( it != slist.end() ) {
01283     QString upper = *it++;
01284     QString lower = upper.lower();
01285 #if QT_VERSION < 0x030100
01286     string low ( lower );
01287 #else
01288     string low = lower.latin1();
01289 #endif
01290 #ifdef Q_OS_MACX
01291 #else // not mac os x
01292   if ( low == "jpeg" ) low = "jpg";
01293 #endif
01294     if ( eps >= low ) {
01295 
01296 #if QT_VERSION < 0x040000
01297       s_image_filters += low +"(*." + low + ");;";
01298 #else
01299       s_image_filters += " (*." + low + ");;";
01300 #endif
01301     }
01302     else {
01303       if ( eps_inserted == false ) {
01304 #if QT_VERSION < 0x040000
01305         s_image_filters += eps + "(*." + eps + ");;";
01306 #else
01307         s_image_filters += "(*." + eps + ");;";
01308 #endif
01309         eps_inserted = true;
01310       }
01311 #if QT_VERSION < 0x040000
01312       s_image_filters += low + "(*." + low + ");;";
01313 #else
01314       s_image_filters += "(*." + low + ");;";
01315 #endif
01316     }
01317   }
01318   // Add FITS file.
01319 #if QT_VERSION < 0x040000
01320   s_image_filters += "FITS(*.fits);;";
01321 #else
01322   s_image_filters += "(*.fits);;";
01323 #endif
01324 
01325 #if QT_VERSION < 0x040000
01326   s_image_filters += "Compressed FITS(*.fits.gz)";
01327 #else
01328   s_image_filters += "(*.fits.gz)";
01329 #endif
01330 }
01331 
01332 #if QT_VERSION < 0x040000
01333 QFileDialog *
01334 #else
01335 Q3FileDialog *
01336 #endif
01337 CanvasView::
01338 createImageDialog ()
01339 {
01340   if ( s_image_filters.empty () ) createImageFilters ();
01341 
01342   QString filters = s_image_filters.c_str();
01343 
01344 #if QT_VERSION < 0x040000
01345   QFileDialog * dialog = new QFileDialog ( this );
01346   dialog->setFilters ( filters );
01347   dialog->setMode ( QFileDialog::AnyFile );
01348 #else
01349   Q3FileDialog * dialog = new Q3FileDialog ( this );
01350   dialog->setFilters ( filters );
01351   dialog->setMode ( Q3FileDialog::AnyFile );
01352 #endif
01353 
01354   return dialog;
01355 }
01356 
01357 /* The menu item calling this method is disabled when no plot is
01358    selected so there's no need to see if any plots are selected
01359    here.
01360 */
01361 void
01362 CanvasView::
01363 saveSelectedImages ()
01364 {
01365   setVisibleNonViews ( false );
01366 
01367 #if QT_VERSION < 0x040000
01368   const vector < QCanvasItem * > views = getSelectedItems (); // make copy
01369 #else
01370   const vector < Q3CanvasItem * > views = getSelectedItems (); // make copy
01371 #endif
01372   assert ( views.empty () == false );
01373 
01374   for ( unsigned int i = 0; i < views.size (); i++ ) {
01375     setCollidingSelected ( views[i] );
01376   }
01377 
01378   if ( s_image_filters.empty () ) createImageFilters ();
01379   QString sel_filt;
01380 #if QT_VERSION < 0x040000
01381   QString filename 
01382     = QFileDialog::getSaveFileName ( QString::null, // working dir
01383                                      s_image_filters.c_str(),
01384                                      this, // parent
01385                                      0, // name
01386                                      "Save image as", // caption
01387                                      & sel_filt ); // selected filter
01388 #else
01389   QString filename 
01390     = Q3FileDialog::getSaveFileName ( QString::null, // working dir
01391                                       s_image_filters.c_str(),
01392                                       this, // parent
01393                                       0, // name
01394                                       "Save image as", // caption
01395                                       & sel_filt ); // selected filter
01396 #endif
01397 
01398   if ( filename.isEmpty () ) return;
01399 
01400   filename.stripWhiteSpace ();
01401 
01402 #if QT_VERSION < 0x030100
01403   string fn ( filename );
01404 #else
01405   string fn = filename.latin1();
01406 #endif
01407 
01408   int pos = filename.findRev ( '.' );
01409   if ( pos < 0 ) {
01410     string sf = sel_filt.latin1();
01411     string::size_type pos1 = sf.find ( '(' );
01412     string::size_type pos2 = sf.find_last_of ( ')' );
01413     string::size_type len = ( pos2 ) - ( pos1 + 2 );
01414     string suffix = sf.substr ( pos1 + 2, len );
01415     fn += suffix;
01416   }
01417 
01418   saveSelectedImages ( fn, true );
01419 
01420   // Restore original selection flags.
01421   m_selected_list.clear();
01422   for ( unsigned int i = 0; i < views.size(); i++ ) {
01423     m_selected_list.push_back ( views[i] );
01424   }
01425   setSelectedFlags ();
01426   setVisibleNonViews ( true );
01427 }
01428 
01429 void
01430 CanvasView::
01431 saveSelectedImages (const std::string & filename)
01432 {
01433   setVisibleNonViews ( false );
01434 
01435 #if QT_VERSION < 0x040000
01436   const vector < QCanvasItem * > views = getSelectedItems (); // make copy
01437 #else
01438   const vector < Q3CanvasItem * > views = getSelectedItems (); // make copy
01439 #endif
01440   if (views.empty()) {
01441      return;
01442   }
01443 
01444   for ( unsigned int i = 0; i < views.size (); i++ ) {
01445     setCollidingSelected ( views[i] );
01446   }
01447 
01448   saveSelectedImages ( filename, false );
01449 
01450   // Restore original selection flags.
01451   m_selected_list.clear();
01452   for ( unsigned int i = 0; i < views.size(); i++ ) {
01453     m_selected_list.push_back ( views[i] );
01454   }
01455   setSelectedFlags ();
01456   setVisibleNonViews ( true );
01457 }
01458 
01462 void CanvasView::setIntervalEnabled ( bool yes )
01463 {
01464   DisplayController * controller = DisplayController::instance ();
01465   const vector < const ViewBase * > & view_list = views ();
01466   vector < const ViewBase * > ::const_iterator first = view_list.begin ();
01467 
01468   while ( first != view_list.end() ) {
01469     const ViewBase * view = *first++;
01470     PlotterBase * plotter = view->getPlotter();
01471     controller -> setAllIntervalEnabled ( plotter, yes );
01472   }
01473 }
01474 
01475 void
01476 CanvasView::
01477 restoreFromSelectCopy ()
01478 {
01479 
01480   ViewFactory * factory = QtViewFactory::instance ();
01481   const vector < const ViewBase * > & targets = views ();
01482 
01483   const list < ViewBase * > & views
01484     = s_xml_controller->getFromSelectionCopy ( factory, targets );
01485 
01486   if ( views.empty() == false ) {
01487     removeSelected ();
01488     pasteViews ( views );
01489 
01490     notifyObservers ();
01491   }
01492 }
01493 
01494 void CanvasView::controlMousePressEvent ( )
01495 {
01496 #if QT_VERSION < 0x040000
01497   QCanvasItem * selItem = m_selected_list.front ();
01498 #else
01499   Q3CanvasItem * selItem = m_selected_list.front ();
01500 #endif
01501   QtView * qtview = dynamic_cast < QtView * > ( selItem );
01502   assert ( qtview );
01503 
01504   PlotterBase * plotter = qtview->getPlotter ();
01505   assert ( plotter );
01506 
01507   plotter -> toggleActivePlot ();
01508 }
01509 
01510 void
01511 CanvasView::
01512 fillSelectedWithObservers ( std::vector < const ViewBase * > & view_list )
01513 {
01514   const vector < const ViewBase * > & sel_views = selectedViews ();
01515 
01516   view_list.resize ( sel_views.size() );
01517   copy ( sel_views.begin(), sel_views.end(), view_list.begin() );
01518 
01519   DisplayController * controller = DisplayController::instance ();
01520   const vector < const ViewBase * > & all_views = views ();
01521 
01522   controller->addTextViewToList ( view_list, all_views );
01523 }
01524 
01525 void CanvasView::contentsMousePressEvent ( QMouseEvent* e )
01526 {
01527   FigureEditor::contentsMousePressEvent ( e );
01528   if ( (e->button() == Qt::RightButton) ||( e->state() == Qt::RightButton)) {
01529     contentsMouseMoveEvent ( e );
01530   }
01531 
01532   const vector < const ViewBase * > & sel_views = selectedViews ();
01533 
01534   if ( ! sel_views.empty () ) {
01535     vector < const ViewBase * > view_list;
01536     fillSelectedWithObservers ( view_list );
01537     s_xml_controller->saveToSelectionCopy ( view_list );
01538   }
01539 
01540   notifyObservers();
01541 }
01542 
01543 
01547 void CanvasView::contentsMouseMoveEvent ( QMouseEvent * e )
01548 {
01549 //If right button pressed, get the position and show on the status bar.
01550   if ( (e->button() == Qt::RightButton) ||( e->state() & Qt::RightButton)) {
01551 #if QT_VERSION < 0x040000
01552     QCanvasItem * right_item=FigureEditor::getRightItem ();
01553 #else
01554     Q3CanvasItem * right_item=FigureEditor::getRightItem ();
01555 #endif
01556     if ( right_item == 0 ) return;
01557 
01558 #if QT_VERSION < 0x040000
01559     QCanvasRectangle * rect
01560     = dynamic_cast <QCanvasRectangle *> ( right_item );
01561 #else
01562     Q3CanvasRectangle * rect
01563     = dynamic_cast <Q3CanvasRectangle *> ( right_item );
01564 #endif
01565 
01566 
01567     QPoint p = inverseWorldMatrix().map(e->pos());
01568 
01569     if ( ( p.x() >= rect->x() ) &&
01570        ( p.x() <= rect->x() + rect->width() ) &&
01571        ( p.y() >= rect->y() ) &&
01572        ( p.y() <= rect->y() + rect->height() ) ) {
01573 
01574       QtView * qtview = dynamic_cast < QtView * > ( right_item );
01575       if ( qtview == 0 ) //return;
01576         {
01577           QtGroupView * gv = dynamic_cast <QtGroupView *> (right_item);
01578           const vector <ViewBase * > & views = gv->getViews();
01579           vector < ViewBase * >::const_iterator first = views.begin();
01580           for ( ; first != views.end(); ++first ) {
01581             QtView * v = dynamic_cast < QtView * > ( *first );
01582             if ( ( p.x() >= v->x() ) &&
01583                  ( p.x() <= v->x() + v->width() ) &&
01584                  ( p.y() >= v->y() ) &&
01585                  ( p.y() <= v->y() + v->height() ) ) {
01586               qtview = v;
01587               break;
01588             }
01589           }
01590           if ( qtview == 0 ) return;     // click between views
01591         }
01592 
01593 
01594       vector < double > picked;
01595       qtview -> fillPickedPoint ( p.x(), p.y(), picked );
01596       if ( picked.empty () ) return;
01597 
01598       unsigned int size = picked.size();
01599       double datax = picked[1];
01600       double datay = picked[2]; // scaled if needed
01601       double dataz = 0.0;
01602       if ( size >= 4 ) {
01603         dataz = picked[3];
01604       }
01605 
01606       double unscaledDataX = picked[1];
01607       double unscaledDataY = picked[2];
01608       if ( std::abs ( picked[0] - 1.0 ) < 0.5 )  unscaledDataY = picked[3];
01609 
01610       // Set cross cursor for fits image with transfom.
01611       BinaryTransform * tf_fits
01612         = dynamic_cast < BinaryTransform * >  
01613         ( qtview->getPlotter()->getFitsTransform() );
01614 
01615       // tf_fits = 0 if the plot is not fits image with transform.
01616       if ( tf_fits ){
01617         tf_fits -> transform ( unscaledDataX, unscaledDataY );
01618       }
01619 
01620       qtview->setCrossX ( unscaledDataX );
01621       qtview->setCrossY ( unscaledDataY );
01622       qtview->setShowCrossHairs ( true );
01623       const QCursor cursor ( Qt::CrossCursor );
01624       QApplication::setOverrideCursor ( cursor, true );
01625       qtview->update(0);
01626 
01627       QString qstr = QString
01628         ( "Coordinates are : ( %1, %2, %3 )" )
01629         .arg ( datax )
01630         .arg ( datay )
01631         .arg ( dataz );
01632 
01633       CanvasWindow * cw = dynamic_cast < CanvasWindow * > ( parentWidget() );
01634       QStatusBar * sb = cw->statusBar();
01635       sb->message ( qstr );
01636 
01637 
01638       // Skip cut setting if in pick mode.
01639       // Add pick table if needed.
01640       if (m_cut_mode == 0 ){
01641         PickTable * table = 0;
01642         map < const QtView*, PickTable * > ::iterator first
01643           = m_table_map.find ( qtview );
01644         if ( first != m_table_map.end () ) {
01645           table = m_table_map [ qtview ];
01646         }
01647         else {
01648           PlotterBase * plotter = qtview->getPlotter ();
01649           
01650           table = new PickTable ( plotter );
01651           m_table_map [ qtview ] = table;
01652         }
01653         return;
01654       }
01655 
01656       // Set the cut range if the current plotter is a cut.
01657       PlotterBase * plotter = qtview->getPlotter();
01658       if ( plotter == 0 ) return;
01659       Cut1DPlotter * cut1d = dynamic_cast < Cut1DPlotter * > (plotter);
01660       Cut2DPlotter * cut2d = dynamic_cast < Cut2DPlotter * > ( plotter );
01661 
01662       
01663       // Set the cut range to be within the plotter range.
01664       // Cut1D plotter
01665       if ( cut1d ) {
01666         double cut_low = cut1d->getCutRange().low();
01667         double cut_high = cut1d->getCutRange().high();
01668         double plotter_low = cut1d->getRange( Axes::X, true ).low();
01669         double plotter_high = cut1d->getRange( Axes::X, true ).high();
01670 
01671         if (m_cut_mode == 1){
01672 
01673           if ( cut_low < plotter_low )
01674             {
01675               Range currentRange = Range::Range ( plotter_low, cut_high );
01676               cut1d -> setCutRangeAt ( currentRange , 0 );
01677             }
01678           if ( cut_high > plotter_high )
01679             {
01680               Range currentRange = Range::Range ( cut_low , plotter_high );
01681               cut1d -> setCutRangeAt ( currentRange , 0 );
01682             }
01683         }
01684 
01685       }
01686 
01687       // Cut2D plotter
01688       else if ( cut2d ) {
01689         double cut_low_x = cut2d->getCutRange().low();
01690         double cut_high_x = cut2d->getCutRange().high();
01691         double plotter_low_x = cut2d->getRange( Axes::X, true ).low();
01692         double plotter_high_x = cut2d->getRange( Axes::X, true ).high();
01693         double cut_low_y = cut2d->getCutRangeY().low();
01694         double cut_high_y = cut2d->getCutRangeY().high();
01695         double plotter_low_y = cut2d->getRange( Axes::Y, true ).low();
01696         double plotter_high_y = cut2d->getRange( Axes::Y, true ).high();
01697 
01698         if ( m_cut_mode == 1 ) {
01699 
01700           if ( cut_low_x < plotter_low_x )
01701             {
01702               Range currentRange = Range::Range ( plotter_low_x, cut_high_x );
01703               cut2d -> setCutRangeAt ( currentRange , 0 );
01704             }
01705           if ( cut_high_x > plotter_high_x )
01706             {
01707               Range currentRange = Range::Range ( cut_low_x , plotter_high_x );
01708               cut2d -> setCutRangeAt ( currentRange , 0 );
01709             }
01710           
01711           if ( cut_low_y < plotter_low_y )
01712             {
01713               Range currentRange = Range::Range ( plotter_low_y, cut_high_y );
01714               cut2d -> setCutRangeAt ( currentRange , 1 );
01715             }
01716           if ( cut_high_y > plotter_high_y )
01717             {
01718               Range currentRange = Range::Range ( cut_low_y , plotter_high_y );
01719               cut2d -> setCutRangeAt ( currentRange , 1 );
01720             }
01721         }
01722       }
01723         
01724 
01725 
01726       // Set cut according to the cut mode.
01727       switch ( m_cut_mode ){
01728       case 1:
01729         if ( cut1d ) {
01730           Range oldRange = cut1d -> getCutRange ();
01731           double old_low = oldRange.low();
01732           double old_high = oldRange.high();
01733 
01734           if ( datax < ( old_low + old_high ) / 2 ) {
01735             Range currentRange = Range::Range ( datax , old_high );
01736             cut1d -> setCutRangeAt ( currentRange , 0 );
01737           }
01738           
01739           else
01740             {
01741               Range currentRange = Range::Range ( old_low , datax );
01742               cut1d -> setCutRangeAt ( currentRange , 0 );
01743             }
01744           notifyObservers();
01745         }
01746 
01747         // Cut2D plotter
01748         else if ( cut2d ) {
01749           Range oldRangeX = cut2d -> getCutRange ();
01750           Range oldRangeY = cut2d -> getCutRangeY ();
01751           double old_low_x = oldRangeX.low();
01752           double old_high_x = oldRangeX.high();
01753           double old_low_y = oldRangeY.low();
01754           double old_high_y = oldRangeY.high();
01755         
01756           // Distances to each edge.
01757           double dis_low_x = std::abs ( datax - old_low_x );
01758           double dis_high_x = std::abs ( datax - old_high_x );
01759           double dis_low_y = std::abs ( datay - old_low_y );
01760           double dis_high_y = std::abs ( datay - old_high_y );
01761 
01762           // Left-bottom
01763           if ( ( dis_low_x <= 0.1 * (old_high_x - old_low_x)) &&
01764                ( dis_low_y <= 0.1 * (old_high_y - old_low_y)) &&
01765                ( m_edge == 0 ) || ( m_edge == 1 ) ) {
01766             Range currentRange = Range::Range ( datax, old_high_x );
01767             cut2d -> setCutRangeAt ( currentRange, 0 );
01768 
01769             // Handle shift drag.
01770             if ( e->state() & Qt::ShiftButton) {
01771               int view_top = qtview->toViewY(old_high_y);
01772               int view_left = qtview->toViewX(datax);
01773               int view_right = qtview->toViewX(old_high_x);
01774               int view_bottom = view_top + view_right - view_left;
01775 
01776               // Not effecient to call fillPickedPoint(), but marginToUser() 
01777               // is protected.
01778               vector <double> adjusted;
01779               qtview->fillPickedPoint(view_left, view_bottom, adjusted);
01780               currentRange = Range::Range ( adjusted[2], old_high_y );
01781             }
01782             else
01783               currentRange = Range::Range ( datay, old_high_y );
01784             cut2d -> setCutRangeAt ( currentRange, 1 );
01785             m_edge = 1;
01786           }
01787 
01788           // Left-top
01789           else if ( ( dis_low_x <= 0.1 * (old_high_x - old_low_x)) &&
01790                     ( dis_high_y <= 0.1 * (old_high_y - old_low_y)) &&
01791                     ( m_edge == 0 ) || ( m_edge == 2 ) ) {
01792             Range currentRange = Range::Range ( datax, old_high_x );
01793             cut2d -> setCutRangeAt ( currentRange, 0 );
01794 
01795             // Handle shift drag
01796             if ( e->state() & Qt::ShiftButton) {
01797               int view_bottom = qtview->toViewY(old_low_y);
01798               int view_left = qtview->toViewX(datax);
01799               int view_right = qtview->toViewX(old_high_x);
01800               int view_top = view_bottom - view_right + view_left;
01801 
01802               // Not effecient to call fillPickedPoint(), but marginToUser() 
01803               // is protected.
01804               vector <double> adjusted;
01805               qtview->fillPickedPoint(view_left, view_top, adjusted);
01806               currentRange = Range::Range ( old_low_y, adjusted[2]);
01807             }
01808             else
01809               currentRange = Range::Range ( old_low_y, datay );
01810             cut2d -> setCutRangeAt ( currentRange, 1 );
01811             m_edge = 2;
01812           }
01813           
01814           // Right-bottom
01815           else if ( ( dis_high_x <= 0.1 * (old_high_x - old_low_x)) &&
01816                     ( dis_low_y <= 0.1 * (old_high_y - old_low_y)) &&
01817                     ( m_edge == 0 ) || ( m_edge == 3 ) ) {
01818             Range currentRange = Range::Range ( old_low_x, datax );
01819             cut2d -> setCutRangeAt ( currentRange, 0 );
01820 
01821             // Handle shift drag.
01822             if ( e->state() & Qt::ShiftButton) {
01823               int view_top = qtview->toViewY(old_high_y);
01824               int view_left = qtview->toViewX(old_low_x);
01825               int view_right = qtview->toViewX(datax);
01826               int view_bottom = view_top + view_right - view_left;
01827 
01828               // Not effecient to call fillPickedPoint(), but marginToUser() 
01829               // is protected.
01830               vector <double> adjusted;
01831               qtview->fillPickedPoint(view_right, view_bottom, adjusted);
01832               currentRange = Range::Range ( adjusted[2], old_high_y );
01833             }
01834             else
01835               currentRange = Range::Range ( datay, old_high_y );
01836             cut2d -> setCutRangeAt ( currentRange, 1 );
01837             m_edge = 3;
01838           }
01839           
01840           // Right-top
01841           else if ( ( dis_high_x <= 0.1 * (old_high_x - old_low_x)) &&
01842                     ( dis_high_y <= 0.1 * (old_high_y - old_low_y)) &&
01843                     ( m_edge == 0) || ( m_edge == 4 ) ) {
01844             Range currentRange = Range::Range ( old_low_x, datax );
01845             cut2d -> setCutRangeAt ( currentRange, 0 );
01846 
01847             // Handle shift drag.
01848             if ( e->state() & Qt::ShiftButton) {
01849               int view_bottom = qtview->toViewY(old_low_y);
01850               int view_left = qtview->toViewX(old_low_x);
01851               int view_right = qtview->toViewX(datax);
01852               int view_top = view_bottom - view_right + view_left;
01853 
01854               // Not effecient to call fillPickedPoint(), but marginToUser() 
01855               // is protected.
01856               vector <double> adjusted;
01857               qtview->fillPickedPoint(view_right, view_top, adjusted);
01858               currentRange = Range::Range ( old_low_y, adjusted[2] );
01859             }
01860             else
01861               currentRange = Range::Range ( old_low_y, datay );
01862             cut2d -> setCutRangeAt ( currentRange, 1 );
01863             m_edge = 4;
01864           }
01865 
01866           // Left
01867           else if ( ( dis_low_x <= dis_high_x ) &&
01868                     ( dis_low_x <= dis_low_y ) &&
01869                     ( dis_low_x <= dis_high_y ) && 
01870                     ( m_edge == 0 ) || ( m_edge == 5 ) ) {
01871             Range currentRange = Range::Range ( datax, old_high_x );
01872             cut2d -> setCutRangeAt ( currentRange, 0 );
01873             m_edge = 5;
01874           }
01875           
01876           // Right
01877           else if ( ( dis_high_x <= dis_low_x ) &&
01878                     ( dis_high_x <= dis_low_y ) &&
01879                     ( dis_high_x <= dis_high_y ) &&
01880                     ( m_edge == 0 ) || ( m_edge == 6 ) ) {
01881             Range currentRange = Range::Range ( old_low_x, datax );
01882             cut2d -> setCutRangeAt ( currentRange, 0 );
01883             m_edge = 6;
01884           } 
01885 
01886           // Bottom
01887           else if ( ( dis_low_y <= dis_high_x ) &&
01888                     ( dis_low_y <= dis_low_x ) &&
01889                     ( dis_low_y <= dis_high_y ) &&
01890                     ( m_edge == 0 ) || ( m_edge == 7 ) ) {
01891             Range currentRange = Range::Range ( datay, old_high_y );
01892             cut2d -> setCutRangeAt ( currentRange, 1 );
01893             m_edge = 7;
01894           }
01895 
01896           // Top
01897           else 
01898             {
01899               Range currentRange = Range::Range ( old_low_y, datay );
01900               cut2d -> setCutRangeAt ( currentRange, 1 );
01901               m_edge = 8;
01902             }
01903           notifyObservers();
01904         }
01905                                          
01906         break;
01907 
01908 
01909       case 2:
01910         if ( cut1d ) {
01911           
01912           if ( !m_clicked ){
01913             old_pos = datax;
01914           }
01915 
01916           else {
01917             double low, high;
01918 
01919             if ( datax > old_pos ) {
01920               low = old_pos;
01921               high = datax;
01922             }
01923 
01924             else  {
01925               low = datax;
01926               high= old_pos;
01927             }
01928 
01929             Range currentRange = Range::Range ( low, high );
01930             cut1d -> setCutRangeAt ( currentRange , 0 );
01931           }
01932           notifyObservers();
01933         }
01934 
01935         // Cut2D plotter.
01936         else if ( cut2d ) {
01937           if ( !m_clicked ){
01938             old_pos_x = datax;
01939             old_pos_y = datay;
01940           }
01941 
01942           else {
01943             double low, high;
01944             if ( datax > old_pos_x ) {
01945               low = old_pos_x;
01946               high = datax;
01947             }
01948             else {
01949               low = datax;
01950               high = old_pos_x;
01951             }
01952             Range currentRange = Range::Range ( low, high );
01953             cut2d -> setCutRangeAt ( currentRange, 0 );
01954 
01955             if ( datay > old_pos_y ) {
01956               low = old_pos_y;
01957               high = datay;
01958             }
01959             else {
01960               low = datay;
01961               high = old_pos_y;
01962             }
01963             currentRange = Range::Range ( low, high );
01964             cut2d -> setCutRangeAt ( currentRange, 1 );
01965           }
01966           notifyObservers();
01967         }
01968 
01969         break;
01970 
01971 
01972       case 3:
01973         if ( cut1d ) {
01974 
01975           DisplayController * controller = DisplayController::instance ();
01976           Range oldRange = cut1d -> getCutRange ();
01977           double width, low, high;
01978           
01979           // Log X axis.
01980           if ( (controller -> getLog ( plotter, Axes::X )) == true )
01981             {
01982               width = log10(oldRange.high())-log10(oldRange.low());
01983               low = pow ( 10., log10(datax) - ( width/2 ) );
01984               high = pow ( 10., log10(datax) + ( width/2 ) );         
01985             }
01986 
01987           // Linear X axis.
01988           else 
01989             {
01990               width = oldRange.high() - oldRange.low();
01991               low = datax - width/2;
01992               high = datax + width/2;
01993             }
01994           Range currentRange = Range::Range ( low, high );
01995           cut1d -> setCutRangeAt (currentRange, 0 );
01996           notifyObservers();
01997         }
01998         
01999         // Cut2D plotter.
02000         if ( cut2d ) {
02001           DisplayController * controller = DisplayController::instance ();
02002           Range oldRangeX = cut2d -> getCutRange ();
02003           Range oldRangeY = cut2d -> getCutRangeY ();
02004           double width_x, width_y, low_x, high_x, low_y, high_y;
02005           
02006           // Log X axis.
02007           if ( (controller -> getLog ( plotter, Axes::X )) == true )
02008             {
02009               width_x = log10(oldRangeX.high())-log10(oldRangeX.low());
02010               low_x = pow ( 10., log10(datax) - ( width_x/2 ) );
02011               high_x = pow ( 10., log10(datax) + ( width_x/2 ) );             
02012             }
02013 
02014           // Linear X axis.
02015           else 
02016             {
02017               width_x = oldRangeX.high() - oldRangeX.low();
02018               low_x = datax - width_x/2;
02019               high_x = datax + width_x/2;
02020             }
02021 
02022           // Log Y axis.
02023           if ( (controller -> getLog ( plotter, Axes::Y )) == true )
02024             {
02025               width_y = log10(oldRangeY.high())-log10(oldRangeY.low());
02026               low_y = pow ( 10., log10(datay) - ( width_y/2 ) );
02027               high_y = pow ( 10., log10(datay) + ( width_y/2 ) );             
02028             }
02029 
02030           // Linear Y axis.
02031           else 
02032             {
02033               width_y = oldRangeY.high() - oldRangeY.low();
02034               low_y = datay - width_y/2;
02035               high_y = datay + width_y/2;
02036             }
02037 
02038           Range currentRange = Range::Range ( low_x, high_x );
02039           cut2d -> setCutRangeAt (currentRange, 0 );
02040           currentRange = Range::Range ( low_y, high_y );
02041           cut2d -> setCutRangeAt (currentRange, 1 );
02042           notifyObservers();
02043         }
02044           
02045         break;
02046 
02047       default:
02048         break;
02049       }
02050 
02051 
02052 
02053 
02054     }
02055   }
02056 
02057 
02058   // Left button pressed, do zoom in if in zoom mode.
02059   else{
02060 
02061     if ( isSingleItemSelected () == false )
02062       {
02063         FigureEditor::mouseMoveMultiItem(e);
02064         return;
02065       }
02066 
02067 #if QT_VERSION < 0x040000
02068     QCanvasItem * item = selectedItem ();
02069 #else
02070     Q3CanvasItem * item = selectedItem ();
02071 #endif
02072 
02073     if ( item->isActive () ) return;
02074 
02075     QtView * qtview = dynamic_cast < QtView * > ( selectedItem() );
02076 
02077     if (qtview) {
02078       double aspect = qtview->getAspectRatio();
02079       FigureEditor::contentsMouseMoveEvent ( e, aspect );
02080     }
02081     else {
02082       QtGroupView * qtgroupview = 
02083         dynamic_cast < QtGroupView * > ( selectedItem());
02084       if (qtgroupview) {
02085         FigureEditor::contentsMouseMoveEvent (e, 0);
02086       }
02087     }
02088 
02089 #if QT_VERSION < 0x040000
02090     QCanvasRectangle * rect
02091        = dynamic_cast <QCanvasRectangle *> ( item );
02092 #else
02093     Q3CanvasRectangle * rect
02094       = dynamic_cast <Q3CanvasRectangle *> ( item );
02095 #endif
02096 
02097     if ( getZoomMode() ){
02098       if ( (e->button() == Qt::LeftButton) ||
02099            ( e->state() & Qt::LeftButton) ) {
02100 
02101         QPoint p = inverseWorldMatrix().map ( e -> pos() );
02102         if ( ( p.x() >= rect->x() ) &&
02103            ( p.x() <= rect->x() + rect->width() ) &&
02104            ( p.y() >= rect->y() ) &&
02105            ( p.y() <= rect->y() + rect->height() ) ) {
02106 
02107 
02108            if (m_drag_rect != 0 ) {
02109               delete m_drag_rect;
02110            }
02111 
02112           QPoint top_left ( std::min ( p.x(), m_zoom_start.x() ),
02113                             std::max ( p.y(), m_zoom_start.y() ) );
02114           QPoint bo_right ( std::max ( p.x(), m_zoom_start.x() ),
02115                             std::min ( p.y(), m_zoom_start.y() ) );
02116 
02117           // Use square to zoom in
02118           if (e->state() & Qt::ShiftButton) {
02119             if (top_left.y() == m_zoom_start.y()) { 
02120               bo_right.setY( top_left.y() - bo_right.x() + top_left.x() );
02121             }
02122             
02123             else { // if (bo_right.y() == m_zoom_start.y()){ 
02124               top_left.setY( bo_right.y() + bo_right.x() - top_left.x() ); 
02125             }
02126           }
02127 
02128 #if QT_VERSION < 0x040000
02129           m_drag_rect = new QCanvasRectangle ( QRect( top_left,bo_right ),
02130                                            canvas ());
02131 #else
02132           m_drag_rect = new Q3CanvasRectangle ( QRect( top_left,bo_right ),
02133                                            canvas ());
02134 #endif
02135           QColor color ( "black" );
02136           QPen pen ( color, 1, Qt::DotLine );
02137           m_drag_rect->setPen(pen);
02138           
02139           if ( selectedPlotter() == 0 ) {
02140             QString message ( "Can not do range zoom in a group view.\n" );
02141             message += "Please select a single plotter view.";
02142             QMessageBox::information ( this,
02143                                        s_app_name.c_str(),
02144                                        message );
02145             return;
02146           }
02147             
02148 
02149           if ( selectedPlotter()->hasAxis(Axes::Z) ){
02150             double z = selectedPlotter()->getRange(Axes::Z,true).high() ;
02151             m_drag_rect -> setZ( z );  // Why setZ? Any thing to do with text plotter?
02152           }
02153           m_drag_rect -> setVisible ( true );
02154           //canvas () -> update ();
02155         }
02156       }
02157     }
02158   }
02159 }
02160 
02161 void
02162 CanvasView::
02163 savePlotAsImage ( const PlotterBase * plotter,
02164                   const std::string & filename )
02165 {
02166   if ( plotter == 0 ) return;
02167 
02168   string::size_type i = filename.find_last_of ( '.');
02169   if ( i != string::npos ) {
02170     string suffix ( filename.substr ( i + 1 ) );
02171     if ( suffix == "eps" ||
02172          suffix == "EPS" ) {
02173       savePlotAsEps ( plotter, filename );
02174     }
02175     else {
02176       QtView * view = getViewFor ( plotter );
02177       assert ( view != 0 );
02178 
02179       QRect rect = view -> rect ();
02180       saveAreaAsPixmap ( rect, filename );
02181     }
02182   }
02183 }
02184 
02185 void
02186 CanvasView::
02187 toLower ( std::string & upper )
02188 {
02189   string::size_type size = upper.size();
02190   for ( string::size_type i = 0; i < size; i++ ) {
02191     upper[i] = std::tolower ( upper[i] );
02192   }
02193 }
02194 
02195 bool
02196 CanvasView::
02197 isValidImageFormat ( const std::string & suffix )
02198 {
02199   // Handle gzipped suffix
02200   if (suffix=="gz" || suffix=="GZ") return true;
02201 
02202   if ( s_image_filters.empty () ) createImageFilters ();
02203 
02204   string star ( "*." + suffix );
02205   toLower ( star );
02206 
02207   // following could be 64 bit unsigned int
02208   string::size_type i = s_image_filters.find ( star );
02209 
02210   return i != string::npos;
02211 }
02212 
02213 void
02214 CanvasView::
02215 showFitsError () const
02216 {
02217   QString message ( "Sorry, this installation of " );
02218   message += s_app_name.c_str();
02219   message += " was not\n"
02220     "built with the optional FITS support.";
02221   QMessageBox::information ( const_cast < CanvasView * > ( this ),
02222                              s_app_name.c_str(),
02223                              message );
02224 }
02225 
02226 void
02227 CanvasView::
02228 saveSelectedImages ( const std::string & fn, bool check_existing )
02229 {
02230   string filename = fn;
02231   string::size_type i = filename.find_last_of ( '.' );
02232 
02233   if ( i == string::npos ) { // no suffix given
02234     if ( m_image_dialog != 0 ) {
02235       QString s = m_image_dialog->selectedFilter ();
02236       string filt = s.latin1();
02237       string::size_type ipos = filt.find ( "*." ) + 1;
02238       string::size_type epos = filt.find ( ")" );
02239       string suffix ( filt.substr ( ipos, epos - ipos ) );
02240       filename += suffix;
02241     }
02242     else {
02243       filename += ".jpg";
02244     }
02245     i = filename.find_last_of ( '.' );
02246   }
02247 
02248   string suffix ( filename.substr ( i + 1 ) );
02249   if ( isValidImageFormat ( suffix ) ) {
02250     string base ( filename.substr ( 0, i - 1 ) ); //basename
02251     if ( base.empty () ) filename = "image." + suffix;
02252 
02253     if ( check_existing ) {
02254       QString fn ( filename.c_str() );
02255       bool yes = QFile::exists ( fn );
02256 
02257       if ( yes ) {
02258         yes = existingFileWarning ( filename );
02259         if ( yes == false ) return;
02260       }
02261     }
02262 
02263     setVisibleNonViews ( false );
02264     if ( suffix == "eps" ||
02265          suffix == "EPS" ) 
02266       {
02267         saveSelectedAsEps ( filename );
02268       } 
02269     else if (suffix == "fits" ||
02270              suffix == "FITS" ||
02271              suffix == "gz"   ||
02272              suffix == "GZ")
02273       {
02274 #ifdef HAVE_CFITSIO
02275         saveSelectedAsFits ( filename );
02276 #else
02277         showFitsError ();
02278 #endif  
02279       }
02280     else
02281       {
02282         setUnselectedVisible ( false );
02283         saveSelectedAsPixmap ( filename );
02284         setUnselectedVisible ( true );
02285       }
02286     setVisibleNonViews ( true );
02287   }
02288   else {
02289     invalidImageFormatError ( filename );
02290   }
02291 }
02292 
02293 void
02294 CanvasView::
02295 savePlotAsFits ( const PlotterBase * plotter,
02296                  const std::string & filename ) const
02297 {
02298 #ifdef HAVE_CFITSIO
02299   if ( plotter -> isImageConvertable () == false ) {
02300     QString message ( "The contents of this plotter is not\n"
02301                       "onvertable to a FITS image." );
02302     QMessageBox::information ( const_cast < CanvasView * > ( this ),
02303                                s_app_name.c_str(),
02304                                message );
02305     return;
02306   }
02307 
02308   PlotterBase * p = const_cast < PlotterBase * > ( plotter );
02309 
02310   const std::vector <unsigned int> & fitsshape = p->getShape();
02311   const std::vector <double> & fitsdata = p->getZValues();
02312   
02313   FitsController::instance ()
02314     ->writeImageToFile ( fitsshape[0], fitsshape[1], fitsdata, filename );
02315 
02316 #else
02317   showFitsError ();
02318 #endif
02319 }
02320 
02321 #ifdef HAVE_CFITSIO
02322 void
02323 CanvasView::
02324 saveSelectedAsFits ( const std::string & filename )
02325 {
02326   PlotterBase * plotter = selectedPlotter ();
02327 
02328   if ( !plotter ) {
02329     QString message ( "No plot or more than one plot selected." );
02330     QMessageBox::information ( this,
02331                                s_app_name.c_str(),
02332                                message );
02333     return;
02334   }
02335 
02336   else {
02337     savePlotAsFits ( plotter, filename );
02338   }
02339 }
02340 #endif
02341   
02342 
02343 void
02344 CanvasView::
02345 savePlotAsEps ( const PlotterBase * plotter,
02346                 const std::string & filename ) const
02347 {
02348   if ( plotter != 0 ) {
02349     QtView * view = getViewFor ( plotter );
02350     assert ( view != 0 );
02351 
02352     QRect rect = view -> rect ();
02353     EpsView * eps = new EpsView ( filename,
02354                                   rect.x(), rect.y (),
02355                                   rect.width(), rect.height() );
02356     const Rect & marg_rect = view -> getMarginRect ();
02357     eps -> setMarginRect ( marg_rect );
02358 
02359     PlotterBase * p = const_cast < PlotterBase * > ( plotter );
02360     eps -> setPlotter ( p );
02361     eps -> setDrawRect ( rect.x(), rect.y(),
02362                          rect.width(), rect.height() );
02363     eps -> drawSelf ();
02364     eps -> closeFile ();
02365     delete eps;
02366   }
02367 }
02368 
02369 void
02370 CanvasView::
02371 saveSelectedAsEps ( const std::string & filename )
02372 {
02373   QRect rect = getSelectedBounds ();
02374 
02375   EpsView * eps_view
02376     = new EpsView ( filename,
02377                     rect.x(), rect.y(), rect.width(), rect.height() );
02378 
02379   const vector < const ViewBase * > & viewList = selectedViews ();
02380 #ifdef ITERATOR_MEMBER_DEFECT
02381   std::
02382 #endif
02383   vector < const ViewBase * > :: const_iterator first = viewList.begin();
02384   while ( first != viewList.end() ) {
02385     const ViewBase * vb = *first++;
02386     const QtView * view = dynamic_cast < const QtView * > ( vb );
02387     PlotterBase * plotter = view->getPlotter ();
02388     QRect rect = view->rect();
02389 
02390     eps_view -> setPlotter ( plotter );
02391     eps_view -> setDrawRect ( rect.x(), rect.y(),
02392                               rect.width(), rect.height() );
02393     const Rect & marg_rect = view -> getMarginRect ();
02394     eps_view -> setMarginRect ( marg_rect );
02395 
02396     eps_view -> drawSelf ();
02397   }
02398 
02399   eps_view -> closeFile ();
02400 
02401   delete eps_view;
02402 }
02403 
02406 void
02407 CanvasView::
02408 saveAs ( const std::string & filename ) const
02409 {
02410   const vector < const ViewBase * > & view_list = views ();
02411   saveAs ( view_list, filename );
02412 }
02413 
02414 void
02415 CanvasView::
02416 saveAs ( const std::vector < PlotterBase * > & plotters,
02417          const std::string & filename )
02418 {
02419   vector < const ViewBase * > views;
02420 
02421   unsigned int size = plotters.size ();
02422   for ( unsigned int i = 0; i < size; i++ ) {
02423     PlotterBase * plotter = plotters [i];
02424     QtView * view = wrapPlotter ( plotter );
02425     views.push_back ( view );
02426   }
02427   saveAs ( views, filename );
02428 }
02429 
02430 void
02431 CanvasView::
02432 saveAs ( const std::vector < const ViewBase * > & views,
02433          const std::string & filename )
02434 {
02435   if ( s_xml_controller == 0 ) {
02436     s_xml_controller = QtXMLController::instance ();
02437   }
02438 
02439   XmlController::Status status
02440     =  s_xml_controller->saveToFile ( views, filename );
02441   if ( status != XmlController::Success ) {
02442     return;
02443   }
02444 }
02445 
02449 void
02450 CanvasView::
02451 exportTextTuple ( const std::string & data_suffix )
02452 {
02453  DataSourceController * controller = DataSourceController::instance ();
02454 
02455   const vector < string > & tuples = controller->getNTupleNames();
02456 
02457   if ( tuples.empty () ) {
02458     QString message ( "There are no NTuples to be exported" );
02459     QMessageBox::information ( this,
02460                                s_app_name.c_str(),
02461                                message );
02462     return;
02463   }
02464 
02465   QString filename =
02466 #if QT_VERSION < 0x040000
02467     QFileDialog::getSaveFileName ( QString::null, // starting directory
02468                                    QString::null, // filter
02469                                    this,
02470                                    "save file dialog",
02471                                    "Save data source as ..." ); // caption
02472 #else
02473     Q3FileDialog::getSaveFileName ( QString::null, // starting directory
02474                                     QString::null, // filter
02475                                     this,
02476                                     "save file dialog",
02477                                     "Save data source as ..." ); // caption
02478 #endif
02479 
02480   if ( filename == QString::null ) return;
02481 
02482   QString suffix ( data_suffix.c_str() );
02483 #if QT_VERSION < 0x030300
02484   QString suffix2 ( suffix );
02485   suffix2.upper ();
02486   if ( filename.endsWith ( suffix )  == false &&
02487        filename.endsWith ( suffix2 ) == false ) {
02488     filename += data_suffix;
02489   }
02490 #else
02491   if ( filename.endsWith ( suffix, false ) == false ) {
02492     filename += data_suffix.c_str();
02493   }
02494 #endif
02495 
02496   const string tuple_name = m_inspector -> getSelectedDataSourceName ();
02497 
02498 #if defined(QT_NO_STL) || QT_VERSION < 0x030100
02499   string tuple_file( filename );
02500 #else
02501   string tuple_file ( filename.latin1() );
02502 #endif
02503 
02504   try {
02505     NTupleController::instance ()
02506       ->writeNTupleToFile ( tuple_name, tuple_file );
02507     controller -> changeName ( tuple_name, tuple_file );
02508   }
02509   catch ( const std::exception & e ) {
02510     QString message ( "An error occurred in writing file.\n\n" );
02511     message += e.what();
02512     QMessageBox::critical ( this, // parent
02513                             QString ( "Write error" ), // caption
02514                             message,
02515                             QMessageBox::Ok,
02516                             QMessageBox::NoButton,
02517                             QMessageBox::NoButton );
02518   }
02519 
02520   notifyObservers ();
02521 }
02522  
02523 void
02524 CanvasView::
02525 contentsMouseReleaseEvent(QMouseEvent * e) {
02526   
02527   FigureEditor::contentsMouseReleaseEvent(e);
02528   
02529   std::vector<double> picked;
02530   fillPickedPoint(e, picked);
02531 
02532   QPoint p = inverseWorldMatrix().map(e->pos());
02533   
02534   QtView * qtview(0);
02535   
02536   // For right button, just fill m_mouseData and return...
02537   // Behave differently in different cut modes. 
02538   if (e->button() == Qt::RightButton || e->state() == Qt::RightButton) {
02539 
02540 #if QT_VERSION < 0x040000
02541     QCanvasItem * right_item=FigureEditor::getRightItem ();
02542 #else
02543     Q3CanvasItem * right_item=FigureEditor::getRightItem ();
02544 #endif
02545 
02546     if ( right_item == 0 ) {
02547       return;
02548     }
02549 
02550     qtview = dynamic_cast < QtView * > ( right_item );
02551 
02552     // Select a view if a group view is selected.
02553     if ( qtview == 0 )
02554       {
02555         QtGroupView * gv = dynamic_cast <QtGroupView *> (right_item);
02556         const vector <ViewBase * > & views = gv->getViews();
02557         vector < ViewBase * >::const_iterator first = views.begin();
02558         for ( ; first != views.end(); ++first ) {
02559           QtView * v = dynamic_cast < QtView * > ( *first );
02560           if ( ( p.x() >= v->x() ) &&
02561                ( p.x() <= v->x() + v->width() ) &&
02562                ( p.y() >= v->y() ) &&
02563                ( p.y() <= v->y() + v->height() ) ) {
02564               qtview = v;
02565               break;
02566           }
02567         }
02568         if ( qtview == 0 ) return;     // click between views
02569       }
02570 
02571 
02572 
02573     fillMouseData(picked);
02574     
02575     // In pick mode, update the pick table.
02576     if ( qtview && ( m_cut_mode == 0 ) ) {
02577         
02578 #if QT_VERSION < 0x040000
02579       QCanvasRectangle * rect
02580         = dynamic_cast <QCanvasRectangle *> ( qtview );
02581 #else
02582       Q3CanvasRectangle * rect
02583         = dynamic_cast <Q3CanvasRectangle *> ( qtview );
02584 #endif
02585       
02586       
02587       if ( ( p.x() >= rect->x() ) &&
02588            ( p.x() <= rect->x() + rect->width() ) &&
02589            ( p.y() >= rect->y() ) &&
02590            ( p.y() <= rect->y() + rect->height() ) ) {
02591         
02592         vector < double > picked2;
02593         qtview -> fillPickedPoint ( p.x(), p.y(), picked2 );
02594         updatePickTable ( qtview, picked2 );
02595       }
02596     }
02597         
02598     // In cut mode 2, up date m_clicked to identify first and second click.
02599     if ( qtview && ( m_cut_mode == 2 ) ) m_clicked=!m_clicked;
02600     if ( qtview && ( m_cut_mode == 1 ) ) m_edge = 0;
02601   
02602   } 
02603   
02604   else {  // zoom in
02605     qtview = dynamic_cast < QtView * > ( selectedItem() );
02606     if (qtview && !picked.empty() && m_whereClicked != invalid &&
02607         m_drag_rect != 0 ) { // We have a rectangle selected.
02608 
02609       std::vector <double> zoom_top_left;
02610       std::vector <double> zoom_bo_right;
02611 
02612       // Zoom in use the rect instead of the release point.
02613       qtview->fillPickedPoint(m_drag_rect->x(), 
02614                               m_drag_rect->y(), 
02615                               zoom_top_left);
02616       qtview->fillPickedPoint(m_drag_rect->x()+m_drag_rect->width(), 
02617                               m_drag_rect->y()+m_drag_rect->height(), 
02618                               zoom_bo_right);
02619       setPlotZoom(zoom_top_left, zoom_bo_right);
02620 
02621       delete m_drag_rect;   // Erase the rectangle.
02622       m_drag_rect = 0;
02623       canvas()->update();
02624     } else {
02625       m_mouseData.clear();
02626     }
02627   }
02628   
02629   QApplication::restoreOverrideCursor ();
02630   
02631   CanvasWindow * cw = dynamic_cast < CanvasWindow * > ( parentWidget() );
02632   QStatusBar * sb = cw->statusBar();
02633   sb->clear();
02634   
02635   if (qtview) {
02636     qtview->setShowCrossHairs ( false );
02637     qtview->update(0);
02638   }
02639   
02640   ::mouseEvent.wakeAll();
02641   notifyObservers ();
02642 }
02643 
02644 bool
02645 CanvasView::
02646 fillPickedPoint(QMouseEvent * e, std::vector<double> & picked) {
02647    QPoint p = inverseWorldMatrix().map(e->pos());
02648 
02649 #if QT_VERSION < 0x040000
02650    QCanvasItem * selItem = FigureEditor::selectedItem();
02651    QCanvasRectangle * rect = dynamic_cast<QCanvasRectangle *>(selItem);
02652 #else
02653    Q3CanvasItem * selItem = FigureEditor::selectedItem();
02654    Q3CanvasRectangle * rect = dynamic_cast<Q3CanvasRectangle *>(selItem);
02655 #endif
02656    if (selItem) {
02657       QtView * qtview = dynamic_cast<QtView *>(selItem);
02658       if (!qtview) return false;
02659       picked.clear();
02660       if ( ( p.x() >= rect->x() ) &&
02661            ( p.x() <= rect->x() + rect->width() ) &&
02662            ( p.y() >= rect->y() ) &&
02663            ( p.y() <= rect->y() + rect->height() ) ) {
02664          qtview -> fillPickedPoint ( p.x(), p.y(), picked );
02665          if (!picked.empty()) {
02666             return true;
02667          }
02668       }
02669    }
02670    return false;
02671 }
02672 
02673 void
02674 CanvasView::
02675 fillMouseData(const std::vector<double> & picked) {
02676    if (!picked.empty()) {
02677       m_mouseData.clear();
02678       m_mouseData.reserve(3);
02679       m_mouseData.push_back(picked[1]);
02680       m_mouseData.push_back(picked[2]);
02681       if (picked.size() == 4) {
02682          m_mouseData.push_back(picked[3]);
02683       } else {
02684          m_mouseData.push_back(0);
02685       }
02686    }
02687 }
02688 
02689 void
02690 CanvasView::
02691 updatePickTable(QtView * qtview, std::vector<double> & picked) {
02692   if (!picked.empty()){
02693     PickTable * table = 0;
02694     map < const QtView *, PickTable * > ::iterator first
02695       = m_table_map.find ( qtview );
02696     if ( first != m_table_map.end () ) {
02697       table = m_table_map [ qtview ];
02698     }
02699     if ( m_cut_mode == 0 ) {
02700       table -> addItem ( picked );
02701     }
02702   }
02703 }
02704 
02705 /* Note: indexing into the picked vector offset by one because the
02706    first entry is the type.   See XyPlotter::fillPickedPointFrom().
02707  */
02708 void
02709 CanvasView::
02710 setPlotZoom(const std::vector<double> & start_picked,
02711             const std::vector<double> & picked) {
02712    if (getZoomMode()) {
02713       if ( !(selectedPlotter()->getCurrentRangeSaved()) ) {
02714          setCurrentRange();
02715       }
02716       PlotterBase * plotter = selectedPlotter();
02717       plotter->setRange( "x",
02718                          std::min(picked[1], start_picked[1]),
02719                          std::max(picked[1], start_picked[1]) );
02720       if (plotter->hasAxis(Axes::Z) || plotter->hasZoomY()) {
02721          plotter->setRange( "y",
02722                             std::min(picked[2], start_picked[2]),
02723                             std::max(picked[2], start_picked[2]) );
02724       }
02725       plotter -> setCurrentRangeSaved ( false );
02726    }
02727 }
02728 
02729 void
02730 CanvasView::
02731 setCurrentRange()
02732 {
02733   if ( ! m_current_range.empty () ){
02734     m_current_range.clear ();
02735   }
02736   PlotterBase * plotter = selectedPlotter ();
02737 
02738     m_current_range.push_back( plotter -> getRange(Axes::X,true).low());
02739     m_current_range.push_back( plotter -> getRange(Axes::X,true).high());
02740     m_current_range.push_back( plotter -> getRange(Axes::Y,true).low());
02741     m_current_range.push_back( plotter -> getRange(Axes::Y,true).high());
02742 
02743     int i = plotter  -> currentView();
02744     plotter -> saveViewAtIndex( m_current_range , i + 1 );
02745     plotter -> setCurrentRangeSaved( true );
02746 }
02747 
02748 std::vector<double>&
02749 CanvasView::
02750 getCurrentRange()
02751 {
02752   return m_current_range;
02753 }
02754 
02755 void
02756 CanvasView::
02757 showInspector ()
02758 {
02759   m_inspector -> show ();
02760 }
02761 
02762 void
02763 CanvasView::
02764 viewShowPickTable()
02765 {
02766 //   if ( !isSingleItemSelected() ) return;
02767   if ( isSingleItemSelected () == false ) {
02768     QString message ( "One must select a single plot before showing\n"
02769                       "the pick table." );
02770     QMessageBox::information ( this,
02771                                s_app_name.c_str(),
02772                                message );
02773     return;
02774   }
02775 
02776 #if QT_VERSION < 0x040000
02777   QCanvasItem * selItem = selectedItem();
02778 #else
02779   Q3CanvasItem * selItem = selectedItem();
02780 #endif
02781   QtView * qtview = dynamic_cast < QtView * > ( selItem );
02782   if ( qtview == 0 ) {
02783     QString message ( "Can not show pick table of a group view.\n" );
02784     message += "Please select a single plotter view.";
02785     QMessageBox::information ( this,
02786                                s_app_name.c_str(),
02787                                message );
02788     return;
02789   }
02790   map < const QtView *, PickTable * > ::iterator first
02791     = m_table_map.find ( qtview );
02792 
02793   if ( first == m_table_map.end() ) {
02794     PlotterBase * plotter = qtview->getPlotter ();
02795 
02796     PickTable * table = new PickTable ( plotter );
02797     m_table_map [ qtview ] = table;
02798     table->show();
02799   }
02800   else {
02801     // Show existing pick table.
02802     m_table_map[qtview]->show();
02803   }
02804 }
02805 
02806 
02807 
02808 const std::vector<double> &
02809 CanvasView::
02810 mouseEventData()
02811 {
02812 #if QT_VERSION < 0x040000
02813   ::mouseEvent.wait();
02814 #else
02815   // need to learn about equivalent
02816   //  ::mouseEvent.wait( mutex, time );
02817 #endif
02818    return m_mouseData;
02819 }
02820 
02821 void
02822 CanvasView::helpAbout()
02823 {
02824   const std::string & version = WindowController::version ();
02825   std::string about = "<h2>HippoDraw version: ";
02826   about += version;
02827   about += "<h3> Built on ";
02828   about += "<ul>";
02829   about += "<li> Qt ";
02830   about += QT_VERSION_STR;
02831 #ifdef HAVE_CFITSIO
02832   about += "<li> CFITSIO ";
02833   const string & fits_version = FitsController::instance () -> version ();
02834   about += fits_version.c_str();
02835 #endif
02836 
02837 #ifdef HAVE_MINUIT
02838   about += "<li> C++ Minuit";
02839 #endif
02840 
02841 #ifdef HAVE_MINUIT2
02842   about += "<li> Minuit2";
02843 #endif
02844 
02845 #ifdef HAVE_ROOT
02846   about += "<li> ROOT ";
02847   const string & root_version = RootController::instance() -> version ();
02848   about += root_version.c_str();
02849 #endif
02850 
02851 #ifdef HAVE_WCSLIB
02852   about += "<li> WCSlib ";
02853   about += PACKAGE_VERSION;
02854 #endif
02855   about += "</ul>";
02856 
02857   about += "<h3>Contributors...";
02858   about += "<ul>";
02859   about += "<li> Stephane Bonneaud";
02860   about += "<li> James Chiang";
02861   about += "<li> Johann Cohen-Tanugi";
02862   about += "<li> Xie Fang";
02863   about += "<li> Kaustuv";
02864   about += "<li> Paul F. Kunz";
02865   about += "<li> Sanket B. Malde";
02866   about += "<li> Matthew D. Langston";
02867   about += "<li> Joy Rajiv";
02868   about += "<li> Matan Shacham";
02869   about += "<li> Oded Wurman";
02870   about += "</ul>";
02871 
02872   static QMessageBox* mbox
02873     = new QMessageBox ( "HippoDraw",
02874                         about.c_str(),
02875                         QMessageBox::Information, 1, 0, 0, this, 0, false );
02876   mbox->setButtonText ( 1, "OK" );
02877 
02878   mbox -> exec (); // run modal
02879 }
02880 
02881 const std::string &
02882 CanvasView::
02883 applicationName () const
02884 {
02885   return s_app_name;
02886 }
02887 
02888 
02889 PlotterBase *
02890 CanvasView::
02891 getRightClickedPlotter()
02892 {
02893 
02894 #if QT_VERSION < 0x040000
02895   QCanvasItem * right_item=FigureEditor::getRightItem ();
02896 #else
02897   Q3CanvasItem * right_item=FigureEditor::getRightItem ();
02898 #endif
02899 
02900   QtView * view = dynamic_cast <QtView *> (right_item);
02901   
02902   if ( view == 0 ) return 0;
02903   PlotterBase * plotter = view -> getPlotter ();
02904   return plotter;
02905 }
02906 
02907 void
02908 CanvasView::
02909 setCutMode ( int mode )
02910 {
02911   m_cut_mode=mode;
02912 }
02913 
02914 void
02915 CanvasView::
02916 createNTuple ()
02917 {
02918   DataSourceController * controller = DataSourceController::instance ();
02919 
02920   const vector < string > & tuples = controller->getNTupleNames();
02921 
02922   if ( tuples.empty () ) {
02923     QString message ( "There are no NTuples to be used as source" );
02924     QMessageBox::information ( this,
02925                                s_app_name.c_str(),
02926                                message );
02927     return;
02928   }
02929 
02930   CreateNTuple * cnt = new CreateNTuple ();
02931   cnt-> show ();
02932 }
02933 
02934 NTuple *
02935 CanvasView::
02936 getPickTable ()
02937 {
02938 
02939   const ViewBase * selview;
02940   if (m_sel_views.size()==1) selview = m_sel_views[0];
02941   else return NULL;
02942 
02943   const QtView * view = dynamic_cast < const QtView * > ( selview );
02944 
02945   PickTable * table=0;
02946   map < const QtView *, PickTable * > ::iterator first
02947     = m_table_map.find ( view );
02948   if ( first != m_table_map.end () ) {
02949     table = m_table_map [ view ];
02950   }
02951   if ( table ) {
02952     return table->getPickTable();
02953   }
02954   
02955   return NULL;
02956 
02957 }
02958 
02959 NTuple *
02960 CanvasView::
02961 getPickTable ( const PlotterBase * plotter )
02962 {
02963 
02964   const QtView * view = getViewFor ( plotter );
02965   
02966   PickTable * table = 0;
02967   map < const QtView *, PickTable * > :: iterator first
02968     = m_table_map.find (view);
02969   if ( first !=m_table_map.end() ) {
02970     table = m_table_map [view];
02971   }
02972   if ( table ) {
02973     return table->getPickTable();
02974   }
02975   
02976   return NULL;
02977 }
02978 
02979 void
02980 CanvasView::
02981 groupView ()
02982 {
02983   const vector < const ViewBase * > & selViews = selectedViews();
02984   if ( selViews.empty () ) return;
02985 
02986   QRect groupRect = QRect(0,0,0,0);
02987 
02988   QtGroupView * groupView = new QtGroupView ();
02989 
02990   vector < const ViewBase * >::const_iterator it = selViews.begin();
02991   for ( ; it != selViews.end(); ++it ) {
02992     ViewBase * view = const_cast < ViewBase * > ( *it );
02993 
02994     QtView * qtview = dynamic_cast < QtView * > ( view );
02995     if (!qtview) continue;  // don't include groupview in groupview
02996 
02997     groupView->addView (view);
02998     removeFromItemList (qtview);
02999     QRect temp = qtview->boundingRect();
03000     groupRect|=temp;   // get a rect to contain all QtViews
03001   }
03002   
03003   groupView->setDrawRect(groupRect);
03004   groupView->setPositions();  // set relative position
03005   add(groupView);
03006   clearSelectedList();
03007   addSelectedItem ( groupView );
03008 }
03009 
03010 void
03011 CanvasView::
03012 ungroupView ()
03013 {
03014   const vector < const ViewBase * > & selViews = selectedViews();
03015   if ( selViews.size() != 1 ) return;
03016 
03017   const QtGroupView * groupView = 
03018     dynamic_cast < const QtGroupView * > ( selViews[0] );
03019   if (!groupView) return;
03020 
03021   QtGroupView * gv = const_cast < QtGroupView * > ( groupView );
03022   clearSelectedList ();
03023   const vector < ViewBase * > & views = gv->getViews();
03024 
03025   vector < ViewBase * >::const_iterator first = views.begin();
03026   for ( ; first != views.end(); ++first ) {
03027     QtView * qtview = dynamic_cast < QtView * > ( *first );
03028     add (qtview);
03029     gv->removeView(*first);
03030     --first;     // a view is removed, decrease the iterator
03031     addSelectedItem (qtview );
03032   }
03033   remove ( gv );
03034 }
03035 
03036 void CanvasView::hideSelected ( )
03037 {
03038   const vector < const ViewBase * > & views = selectedViews ();
03039 #ifdef ITERATOR_MEMBER_DEFECT
03040   std::
03041 #endif
03042   vector < const ViewBase * > ::const_iterator first = views.begin();
03043   while ( first != views.end() ) {
03044     const QtView * view = dynamic_cast < const QtView * > ( *first++ );
03045     QtView * v = const_cast < QtView * > ( view );
03046     hide(v);
03047   }
03048 }
03049 
03050 void
03051 CanvasView::
03052 addRecentFile (const QString & filename, QActionGroup * ag )
03053 {
03054   #if QT_VERSION < 0x040000
03055 #else
03056   QObject * parent = ag -> parent ();
03057 #endif  
03058     
03059   // Avoid duplicate recently opened files. 
03060   // Remove old item with same name if needed.
03061   std::list<QAction *>::iterator it=m_recent_list.begin();
03062 
03063   for (; it!=m_recent_list.end(); ++it){
03064     if (((*it)->menuText())==filename){
03065       delete *it;    // need removeFrom(ag) ?
03066       it=m_recent_list.erase(it);
03067       break;
03068     }
03069   }
03070 
03071   // Add new item.
03072 #if QT_VERSION < 0x040000
03073   QAction * action = new QAction ( "", // text
03074                                    QIconSet(),
03075                                    filename, // menu test
03076                                    0, // accel
03077                                    ag ); // parent
03078 #else
03079   QAction * action = new QAction ( filename, parent );
03080   ag -> addAction ( action );
03081 #endif
03082   action -> setToggleAction ( true );
03083   m_recent_list.push_back(action);
03084 
03085   // Remove the first element if size is more than 5.
03086   if (m_recent_list.size() > 5) {
03087     it=m_recent_list.begin();
03088     delete *it;    //need removeFrom(ag) ?
03089     m_recent_list.pop_front();
03090   }
03091 }
03092 
03093 void
03094 CanvasView::
03095 #if QT_VERSION < 0x040000
03096 autosaveSettings (QMainWindow * mw)
03097 #else
03098 autosaveSettings (Q3MainWindow * mw)
03099 #endif
03100 {
03101   QSettings settings;
03102   settings.insertSearchPath ( QSettings::Windows, s_registry );
03103   QString fn;
03104   list<QAction *>::iterator it;
03105   unsigned int i=0;
03106 
03107 
03108   // Save recently opened files
03109   for ( it=m_recent_list.begin(); 
03110         it!=m_recent_list.end(); i++, it++ )
03111     {
03112       fn = (*it)->menuText();
03113       QString number=QString::number(i);
03114       settings.writeEntry ( s_app_key + "Files/File"+number, fn );
03115     }
03116 
03117   // Save dock window positions.
03118   QString dockSetting;
03119   QTextStream stream( &dockSetting, IO_WriteOnly );
03120   stream << *mw;
03121   settings.writeEntry(s_app_key+"DockWindow/Position", dockSetting);
03122 }
03123 
03124 void
03125 CanvasWindow::
03126 defaultToolbar()
03127 {
03128   moveDockWindow(toolBar);
03129   moveDockWindow(Toolbar_2);
03130   moveDockWindow(Toolbar);
03131   moveDockWindow(Toolbar_4);
03132 
03133   lineUpDockWindows();
03134 }

Generated for HippoDraw Class Library by doxygen