Inspector.cxx

Go to the documentation of this file.
00001 
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #endif
00015 
00016 #ifdef _MSC_VER
00017 #include "msdevstudio/MSconfig.h"
00018 #endif
00019 
00020 #include "Inspector.h"
00021 
00022 #include "CanvasSelectionEvent.h"
00023 #include "CanvasWindow.h"
00024 #include "PlotterEvent.h"
00025 #include "WindowController.h"
00026 #include "AxisWidget.h"
00027 #include "QtFont.h"
00028 
00029 #include <qapplication.h>
00030 
00031 #if QT_VERSION < 0x040000
00032 #include "qlistview.h"
00033 #include "qbuttongroup.h"
00034 #include "qgroupbox.h"
00035 #include "qwidgetstack.h"
00036 #include "qlayout.h"
00037 #else
00038 #include <QtCore/QCustomEvent>
00039 #include <QtGui/QHBoxLayout>
00040 #include <QtGui/QVBoxLayout>
00041 #include "q3button.h"
00042 #include "q3listview.h"
00043 #include "q3buttongroup.h"
00044 #include "q3groupbox.h"
00045 #include "q3widgetstack.h"
00046 #endif
00047 
00048 #include "qtooltip.h"
00049 #include "qcheckbox.h"
00050 #include "qcolordialog.h"
00051 #include "qcombobox.h"
00052 #include "qlineedit.h"
00053 #include "qmessagebox.h"
00054 #include "qpushbutton.h"
00055 #include "qradiobutton.h"
00056 #include "qslider.h"
00057 #include "qlabel.h"
00058 #include "qinputdialog.h"
00059 #include "qfontdialog.h"
00060 #include "qtabwidget.h"
00061 #include "qsettings.h"
00062 #include "qstringlist.h"
00063 #include "qtextstream.h"
00064 
00065 
00066 #include "colorreps/BinToColor.h"
00067 #include "controllers/CutController.h"
00068 #include "controllers/DataRepController.h"
00069 #include "controllers/DisplayController.h"
00070 #include "controllers/FunctionController.h"
00071 
00072 #include "datareps/FunctionParameter.h"
00073 #include "datareps/CompositeFunctionRep.h"
00074 
00075 #include "datasrcs/DataSourceController.h"
00076 #include "datasrcs/NTuple.h"
00077 #include "datasrcs/TupleCut.h"
00078 
00079 #include "plotters/CutPlotter.h"
00080 #include "plotters/TextPlotter.h"
00081 
00082 #include "projectors/NTupleProjector.h"
00083 
00084 #include "reps/ContourPointRep.h"
00085 #include "transforms/PeriodicBinaryTransform.h"
00086 
00087 #ifdef HAVE_ROOT
00088 #include "root/RootController.h"
00089 #include "boost/tokenizer.hpp"
00090 #include "boost/lexical_cast.hpp"
00091 #endif
00092 
00093 #include "pattern/string_convert.h"
00094 
00095 #include <algorithm>
00096 #include <iostream>
00097 #include <stdexcept>
00098 
00099 using std::cout;
00100 using std::endl;
00101 
00102 #include <cmath>
00103 #include <cassert>
00104 
00105 using std::map;
00106 using std::runtime_error;
00107 using std::string;
00108 using std::vector;
00109 
00110 using namespace hippodraw;
00111 
00112 
00113 void
00114 Inspector::
00115 stringTokenize ( std::string input, const std::string & delimiters,
00116                  std::vector<std::string> & tokens, bool clear )
00117 {
00118       if (clear) {
00119          tokens.clear();
00120       }
00121       std::string::size_type j;
00122       while ( (j = input.find_first_of(delimiters)) != std::string::npos ) {
00123          if (j != 0) {
00124             tokens.push_back(input.substr(0, j));
00125          }
00126          input = input.substr(j+1);
00127       }
00128       tokens.push_back(input);
00129       if (tokens.back() == "") {
00130          tokens.pop_back();
00131       }
00132 }
00133 
00134 
00135 QString    Inspector::s_registry ( "/Trolltech" );
00136 
00137 
00138 Inspector::
00139 Inspector ( QWidget * parent, const char * name, bool modal, Qt::WFlags flags )
00140   : InspectorBase ( parent, name, modal, flags ),
00141     m_plotter ( 0 ),
00142     m_is_updating ( false ),
00143     m_user_models_loaded ( false )
00144 {
00145   init ();
00146   FunctionController * controller = FunctionController::instance();
00147   const vector < string > & names = controller -> getFitterNames ();
00148     for ( unsigned int i = 0; i < names.size(); i++ ) {
00149     QString name ( names[i].c_str() );
00150     m_fitter_names -> insertItem ( name );
00151   }
00152 #if QT_VERSION < 0x040000
00153 #else // correct code generated by uic3 with release 4.1.1
00154 //     for ( int i = 0; i < 3; i++ ) {
00155 // o      QAbstractButton * b = axis_button_group -> find ( i );
00156 //       axis_button_group -> remove ( b );
00157 //     }
00158 //     radioButton38 = new QRadioButton(axis_button_group);
00159 //     radioButton38->setObjectName(QString::fromUtf8("radioButton38"));
00160 //     radioButton38->setEnabled(true);
00161 //     radioButton38->setGeometry(QRect(10, 0, 65, 30));
00162 //     radioButton38->setMinimumSize(QSize(60, 0));
00163 //     radioButton38->setChecked(true);
00164 
00165 //     radioButton39 = new QRadioButton(axis_button_group);
00166 //     radioButton39->setObjectName(QString::fromUtf8("radioButton39"));
00167 //     radioButton39->setEnabled(true);
00168 //     radioButton39->setGeometry(QRect(80, 0, 65, 30));
00169 //     radioButton39->setMinimumSize(QSize(65, 0));
00170 //     radioButton39->setChecked(false);
00171 
00172 //     radioButton40 = new QRadioButton(axis_button_group);
00173 //     radioButton40->setObjectName(QString::fromUtf8("radioButton40"));
00174 //     radioButton40->setEnabled(true);
00175 //     radioButton40->setGeometry(QRect(150, 0, 65, 30));
00176 //     radioButton40->setMinimumSize(QSize(65, 0));
00177 //     radioButton40->setChecked(false);
00178 
00179     // add index change for Qt 4
00180     connect ( m_all_ntuples, SIGNAL ( currentIndexChanged ( int ) ),
00181               this, SLOT ( dataNTupleSelChanged ( int ) ) );
00182 #endif
00183 
00184 
00185   connect ( axisWidget1, SIGNAL ( lowTextReturnPressed() ),
00186             this, SLOT ( setLowText() ) );
00187 
00188   connect ( axisWidget2, SIGNAL ( lowTextReturnPressed() ),
00189             this, SLOT ( cutText_returnPressed() ) );
00190 
00191   connect ( axisWidget1, SIGNAL ( highTextReturnPressed() ),
00192             this, SLOT ( setHighText() ) );
00193 
00194   connect ( axisWidget2, SIGNAL ( highTextReturnPressed() ),
00195             this, SLOT ( cutText_returnPressed() ) );
00196 
00197   connect ( axisWidget1, SIGNAL ( lowSliderReleased() ),
00198             this, SLOT ( lowRangeDrag() ) );
00199 
00200   connect ( axisWidget2, SIGNAL ( lowSliderReleased() ),
00201             this, SLOT ( cutLowSlider_sliderReleased() ) );
00202 
00203   connect ( axisWidget1, SIGNAL ( lowSliderPressed() ),
00204             this, SLOT ( setDragOn() ) );
00205 
00206   connect ( axisWidget1, SIGNAL ( highSliderPressed() ),
00207             this, SLOT ( setDragOn() ) );
00208 
00209   connect ( axisWidget1, SIGNAL ( lowSliderValueChanged ( int ) ),
00210             this, SLOT ( setLowRange ( int ) ) );
00211 
00212   connect ( axisWidget2, SIGNAL ( lowSliderValueChanged ( int ) ),
00213             this, SLOT ( cutLowSlider_sliderMoved ( int ) ) );
00214 
00215   connect ( axisWidget1, SIGNAL ( highSliderReleased() ),
00216             this, SLOT ( highRangeDrag() ) );
00217 
00218   connect ( axisWidget2, SIGNAL ( highSliderReleased() ),
00219             this, SLOT ( cutHighSlider_sliderReleased() ) );
00220 
00221   connect ( axisWidget1, SIGNAL ( highSliderValueChanged ( int ) ),
00222             this, SLOT ( setHighRange ( int ) ) );
00223 
00224   connect ( axisWidget2, SIGNAL ( highSliderValueChanged ( int ) ),
00225             this, SLOT ( cutHighSlider_sliderMoved ( int ) ) );
00226 
00227   connect ( axisWidget1, SIGNAL ( zoomPanCheckBoxClicked () ),
00228             this, SLOT ( axisZoomPanCheckBox_clicked () ) );
00229 
00230   connect ( axisWidget2, SIGNAL ( zoomPanCheckBoxClicked () ),
00231             this, SLOT ( cutZoomPanCheckBox_clicked () ) );
00232 
00233   axisWidget2 -> setCut ( true );
00234   // Default position of the sliders is center which corrosponds to
00235   // a value of 50. So initialization takes place as 50.
00236   m_lowslider1_last_val  = 50;
00237   m_highslider1_last_val = 50;
00238 
00239   updatePlotTypes ();
00240 
00241 }
00242 
00243 Inspector::
00244 ~Inspector ()
00245 {
00246   DisplayController * controller = DisplayController::instance ();
00247   delete controller;
00248 
00249 }
00250 
00251 void
00252 Inspector::
00253 init()
00254 {
00255 
00256   unsigned int n = 5;
00257   m_new_labels.reserve ( n );
00258   m_new_labels.push_back ( new_binding_0 );
00259   m_new_labels.push_back ( new_binding_1 );
00260   m_new_labels.push_back ( new_binding_2 );
00261   m_new_labels.push_back ( new_binding_3 );
00262   m_new_labels.push_back ( new_binding_4 );
00263 
00264   m_new_combos.reserve ( n );
00265   m_new_combos.push_back ( new_combo_0 );
00266   m_new_combos.push_back ( new_combo_1 );
00267   m_new_combos.push_back ( new_combo_2 );
00268   m_new_combos.push_back ( new_combo_3 );
00269   m_new_combos.push_back ( new_combo_4 );
00270 
00271   m_sel_labels.reserve ( n );
00272   m_sel_labels.push_back ( sel_binding_0 );
00273   m_sel_labels.push_back ( sel_binding_1 );
00274   m_sel_labels.push_back ( sel_binding_2 );
00275   m_sel_labels.push_back ( sel_binding_3 );
00276   m_sel_labels.push_back ( sel_binding_4 );
00277 
00278   m_sel_combos.reserve ( n );
00279   m_sel_combos.push_back ( sel_combo_0 );
00280   m_sel_combos.push_back ( sel_combo_1 );
00281   m_sel_combos.push_back ( sel_combo_2 );
00282   m_sel_combos.push_back ( sel_combo_3 );
00283   m_sel_combos.push_back ( sel_combo_4 );
00284 
00285   QSize cur_size = size();
00286   setFixedSize ( cur_size );
00287 
00288   m_min_entries = 0;
00289   m_rotate_enable = true;
00290   m_dragging = false;
00291   m_axis = Axes::X;
00292   m_layoutWidget = new QWidget( currentPlot, "m_Layout" );
00293   m_layoutWidget->setGeometry( QRect ( 7, 75, 360, 0 ) );
00294   m_vLayout = new QVBoxLayout( m_layoutWidget, 0, 6, "m_vLayout");
00295 
00296   newPlotButton->setEnabled( false );
00297 
00298   m_newLayoutWidget = new QWidget ( m_new_plot_box, "m_newLayout" );
00299   m_newLayoutWidget->setGeometry( QRect ( 7, 75, 360, 0 ) );
00300   m_newVLayout = new QVBoxLayout( m_newLayoutWidget, 0, 6,
00301                                   "m_newVLayout");
00302 
00303   updateValueCombo ();
00304 
00305   m_interval_le->setDisabled ( true );
00306 
00307   // Add fixed sized column headers to the function params group box
00308   // This we could not do using the designer.
00309   m_FunctionParamsListView -> addColumn( QString( "Function" ),40 );
00310   m_FunctionParamsListView -> addColumn( QString( "Params" ),  20 );
00311   m_FunctionParamsListView -> addColumn( QString( "Value" ),   20 );
00312   m_FunctionParamsListView -> addColumn( QString( "Error" ),   20 );
00313   m_FunctionParamsListView -> addColumn( QString( "Fixed"  ),   3 );
00314   m_FunctionParamsListView -> setSorting ( -1 );
00315 
00316   // vector of QRadioButtons on transform tabbed panel.  Needed for
00317   // workaround of faulty code generation of Qt 4.1.1
00318   m_transform_buttons.push_back ( m_linear );
00319   m_transform_buttons.push_back ( m_logy );
00320   m_transform_buttons.push_back ( m_logx );
00321   m_transform_buttons.push_back ( m_logxy );
00322   m_transform_buttons.push_back ( m_hammer );
00323   m_transform_buttons.push_back ( m_lambert );
00324   m_transform_buttons.push_back ( m_Car );
00325   m_transform_buttons.push_back ( m_Mer );
00326   m_transform_buttons.push_back ( m_Gls );
00327   m_transform_buttons.push_back ( m_Arc );
00328   m_transform_buttons.push_back ( m_Tan );
00329   m_transform_buttons.push_back ( m_Sin );
00330   m_transform_buttons.push_back ( m_Stg );
00331   m_transform_buttons.push_back ( m_Air );
00332 }
00333 
00334 void
00335 Inspector::
00336 updateValueCombo ()
00337 {
00338   DisplayController * controller = DisplayController::instance ();
00339   const vector < string > & names = controller -> getValueTransformTypes ();
00340   m_value_combo -> clear ();
00341   unsigned int size = names.size ();
00342   for ( unsigned int i = 0; i < size; i++ ) {
00343     m_value_combo -> insertItem ( names[i].c_str() );
00344   }
00345 }
00346 
00347 void
00348 Inspector::
00349 enableNewPlotBox ( bool yes )
00350 {
00351   m_new_plot_box->setEnabled ( yes );
00352   m_summary->setEnabled ( yes );
00353 }
00354 
00355 #if QT_VERSION < 0x040000
00356 void Inspector::customEvent ( QCustomEvent * event )
00357 #else
00358 void Inspector::customEvent ( QEvent * event )
00359 #endif
00360 {
00361   PlotterEvent * pev = dynamic_cast < PlotterEvent * > ( event );
00362   if ( pev != 0 ) {
00363     m_plotter = pev -> plotter ();
00364     update ();
00365   }
00366 
00367   CanvasSelectionEvent * ev
00368     = dynamic_cast < CanvasSelectionEvent * > ( event );
00369   if ( ev != 0  ) {
00370     m_plotter_list = ev -> getPlotters ();
00371     if ( m_plotter_list.size () == 1 ) {
00372       m_plotter = m_plotter_list.front ();
00373     }
00374     else {
00375       m_plotter = 0;
00376     }
00377     update ();
00378   }
00379 }
00380 
00381 PlotterBase *
00382 Inspector::
00383 getPlotter ()
00384 {
00385   return m_plotter;
00386 }
00387 
00388 void
00389 Inspector::
00390 setZRadioButton ( bool enabled )
00391 {
00392   if (!enabled && m_axis == Axes::Z )
00393     {
00394 #if QT_VERSION < 0x040000
00395       QButton * b = axis_button_group -> find ( 0 );
00396 #else
00397       QAbstractButton * b = axis_button_group -> find ( 2 );
00398 #endif
00399       QRadioButton * button = dynamic_cast< QRadioButton * > ( b );
00400       button -> setChecked ( true );
00401       m_axis = Axes::X;
00402       updateAxisTab ();
00403     }
00404 
00405 #if QT_VERSION < 0x040000
00406   QButton * button = axis_button_group -> find ( 2 );
00407 #else
00408   QAbstractButton * button = axis_button_group -> find ( 2 );
00409 #endif
00410 
00411   button -> setEnabled ( enabled );
00412 }
00413 
00414 void
00415 Inspector::
00416 tabChanged ()
00417 {
00418   update ();
00419 }
00420 
00421 void
00422 Inspector::
00423 update ()
00424 { 
00425   if ( isHidden() == true ) return;
00426   m_is_updating = true;
00427   int index = m_plot_tab -> currentPageIndex ();
00428 
00429   switch ( index )
00430     {
00431     case ( 0 ) :
00432       updateDataTab();
00433       break;
00434     case ( 1 ) :
00435       updatePlotTab();
00436       break;
00437     case ( 2 ) :
00438       updateAxisTab();
00439       break;
00440     case ( 3 ) :
00441       updateCutsTab();
00442       break;
00443     case ( 4 ) :
00444       updateFunctionsTab();
00445       break;
00446     case ( 5 ) :
00447       updateSummaryTab ();
00448       break;
00449     case ( 6 ) :
00450       updateTransformTab ();
00451       break;
00452     default :
00453       assert ( false );
00454       break;
00455     }
00456   
00457 //   if ( m_plotter != 0 ) {
00458 //     bool hasZ = m_plotter -> hasAxis ( Axes::Z );
00459 //     setZRadioButton ( hasZ );
00460         
00461 //   }
00462 
00463   m_is_updating = false;
00464   updateCutsActive ();
00465   
00466 }
00467 
00468 void
00469 Inspector::
00470 updateCutsActive ()
00471 {
00472   PlotterBase * plotter = getPlotter ();
00473   if ( plotter == 0 ) {
00474     setAllCutsActive ( true );
00475   }
00476   else {
00477     vector < PlotterBase * > cutlist;
00478     CutController * controller = CutController::instance ();
00479     controller -> fillCutList ( plotter, cutlist );
00480 
00481     if ( cutlist.empty () ) {
00482       setAllCutsActive ( false );
00483       return;
00484     }
00485     else {
00486       setAllCutsActive ( false );
00487       vector < PlotterBase * >::iterator first = cutlist.begin();
00488       while ( first != cutlist.end () ) {
00489         PlotterBase * pb = *first++;
00490         CutPlotter * cutter = dynamic_cast < CutPlotter * > ( pb );
00491         assert ( cutter );
00492         cutter -> setActive ( true );
00493       }
00494     }
00495   }
00496 }
00497 
00498 std::string
00499 Inspector::
00500 getSelectedDataSourceName () const
00501 {
00502   string s;
00503   const vector < string > & names
00504     = DataSourceController::instance () -> getNTupleNames ();
00505   int index = m_all_ntuples -> count () == 0 ? -1 : m_all_ntuples -> currentItem ();
00506   if ( index >= 0 &&
00507        names.empty () == false ) {
00508     s = names [ index ];
00509   }
00510 
00511   return s;
00512 }
00513 
00514 void
00515 Inspector::
00516 updateNewPlotControls ()
00517 {
00518   const vector < string > & nt_vector
00519     = DataSourceController::instance() -> getNTupleNames ();
00520 
00521   
00522   if ( nt_vector.empty () ) {
00523    
00524     m_all_ntuples -> clear ();
00525     return;
00526   }
00527 
00528   unsigned int count = m_all_ntuples -> count ();
00529   if ( count == nt_vector.size () ) return;
00530 
00531 #ifdef ITERATOR_MEMBER_DEFECT
00532   //std::
00533 #endif
00534 
00535   m_all_ntuples -> clear();
00536   vector < string > ::const_iterator first = nt_vector.begin();
00537   while ( first != nt_vector.end() ) {
00538     const string & name = *first++;
00539     m_all_ntuples->insertItem ( name.c_str() );
00540   }
00541 
00542   if ( m_all_ntuples -> count () != 0 ) {
00543     const string & name = nt_vector.back ();
00544 
00545     setNewPlotNTuple ( name );
00546     
00547 
00548     availPlotTypesActivated ( name.c_str() );
00549         
00550   }
00551   else {
00552     availPlotTypesActivated ( QString::null );
00553         
00554   }
00555 }
00556 
00557 void
00558 Inspector::
00559 setNewPlotNTuple ( const std::string & name )
00560 {
00561   const vector < string > & nt_vector
00562     = DataSourceController::instance() -> getNTupleNames ();
00563 
00564   for ( unsigned int i = 0; i < nt_vector.size(); i++ ) {
00565     if ( nt_vector[i] == name ) {
00566       unsigned int current = m_all_ntuples -> currentItem ();
00567       if ( current != i ) {
00568         m_all_ntuples -> setCurrentItem ( i );
00569       }
00570       break;
00571     }
00572   }
00573 
00574   // Update tip tool.
00575   QToolTip::remove(m_all_ntuples);
00576   const QString tip=getSelectedDataSourceName().c_str();
00577   QToolTip::add( m_all_ntuples, tip );
00578 
00579 }
00580 
00581 void
00582 Inspector::
00583 dataTupleNameChanged ( const QString & )
00584 {
00585   m_last_ntuple_edited = m_all_ntuples -> currentItem ();
00586 
00587 }
00588 
00589 void
00590 Inspector::
00591 changeNTupleName ( const QString & text )
00592 {
00593   DataSourceController * controller = DataSourceController::instance ();
00594   vector < DataSource * > nt_vector;
00595   controller -> getDataSources ( nt_vector ); // get all
00596   DataSource * ds = nt_vector [ m_last_ntuple_edited ];
00597   if ( ds == 0 ) return;
00598 
00599   const string new_name = text.latin1();
00600 
00601   ds -> setName ( new_name );
00602 }
00603 
00604 void
00605 Inspector::
00606 dataNTupleSelChanged ( int item )
00607 {
00608   DataSourceController * controller = DataSourceController::instance ();
00609   controller -> setCurrentIndex ( item );
00610 
00611   m_all_ntuples -> setCurrentItem ( item );
00612   QString text ( "" );
00613 
00614   availPlotTypesActivated ( text );
00615 
00616   // Update tip tool.
00617   QToolTip::remove(m_all_ntuples);
00618   const QString tip=getSelectedDataSourceName().c_str();
00619   QToolTip::add( m_all_ntuples, tip );
00620 
00621 }
00622 
00623 void
00624 Inspector::
00625 allNtupleComboActivated ( const QString & text )
00626 {
00627   // Change the number and type of axes depending on what is selected
00628   // inside m_availPlotTypes. Then insert the axis labels based on the
00629   // selection of nTupleNameComboBox.
00630 
00631   changeNTupleName ( text );
00632   m_all_ntuples -> setCurrentItem ( m_last_ntuple_edited );
00633   m_all_ntuples -> changeItem ( text, m_last_ntuple_edited );
00634 
00635   DataSourceController * controller = DataSourceController::instance ();
00636   int index = m_all_ntuples -> currentItem ();
00637   controller -> setCurrentIndex( index );
00638 
00639   availPlotTypesActivated ( text );
00640 }
00641 
00642 void
00643 Inspector::
00644 sel_combo_0_activated ( const QString & label )
00645 {
00646   axisLabelChanged ( 0, label );
00647 }
00648 
00649 void
00650 Inspector::
00651 sel_combo_1_activated ( const QString & label )
00652 {
00653   axisLabelChanged ( 1, label );
00654 }
00655 
00656 void
00657 Inspector::
00658 sel_combo_2_activated ( const QString & label )
00659 {
00660   axisLabelChanged ( 2, label );
00661 }
00662 
00663 void
00664 Inspector::
00665 sel_combo_3_activated ( const QString & label )
00666 {
00667   axisLabelChanged ( 3, label );
00668 }
00669 
00670 void
00671 Inspector::
00672 axisLabelChanged ( int index, const QString & label )
00673 {
00674   if ( m_plotter_list.size () > 1 ) {
00675     multiplePlotError ();
00676     return;
00677   }
00678 
00679   PlotterBase * plotter = getPlotter ();
00680   if ( !plotter ) return ;
00681 
00682   QString axisName = m_sel_labels [index] -> text();
00683   const std::string strAxisName ( axisName.latin1() );
00684   const std::string strLabel( label.latin1() );
00685 
00686   DisplayController * controller = DisplayController::instance();
00687   controller -> setAxisBinding ( plotter, strAxisName, strLabel );
00688 
00689   bool valid = controller -> isDataValid ( plotter );
00690   if ( valid == false ) {
00691     invalidDataWarning ();
00692   }
00693 }
00694 
00695 void
00696 Inspector::
00697 updatePlotTypes ()
00698 {
00699   const vector < string > & dataRepNames
00700     = DisplayController::instance() -> getDisplayTypes ();
00701   if ( dataRepNames.empty () ) return;
00702   unsigned int size = m_availPlotTypes -> count ();
00703 
00704   if ( dataRepNames.size() != size ) {
00705     m_availPlotTypes->clear();
00706 
00707     vector < string > ::const_iterator first = dataRepNames.begin ();
00708     while ( first != dataRepNames.end() ) {
00709       const string & name = *first++;
00710       if ( name.find ( "Static" ) != string::npos ) continue;
00711       m_availPlotTypes->insertItem ( name.c_str() );
00712         }
00713      m_availPlotTypes->setCurrentItem ( 2 ); //Histogram
00714   }
00715 
00716   newPlotButton->setEnabled( true );
00717 }
00718 
00719 void
00720 Inspector::
00721 clear ( std::vector < QLabel * > & labels,
00722         std::vector < QComboBox * > & combos )
00723 {
00724   unsigned int size = combos.size ();
00725   for ( unsigned int i = 0; i < size; i++ ) {
00726     QComboBox * box = combos [ i ];
00727     box -> clear ();
00728     box -> setEnabled ( false );
00729     QLabel * label = labels [ i ];
00730     label -> setEnabled ( false );
00731   }
00732 }
00733 
00734 void
00735 Inspector::
00736 availPlotTypesActivated ( const QString & )
00737 {
00738   int index = m_all_ntuples -> count () == 0 ? -1 : m_all_ntuples -> currentItem ();
00739   vector < DataSource * > nt_vector;
00740   DataSourceController::instance() -> getDataSources ( nt_vector );
00741 
00742 
00743   int size = static_cast < int > ( nt_vector.size() );
00744   if ( size == 0 ) {
00745     clear ( m_new_labels, m_new_combos );
00746     return;
00747   }
00748  
00749 
00750   if ( ! (index < size ) ) {
00751     index = 0;
00752   }
00753   std::string plotTypeStr( (m_availPlotTypes->currentText()).latin1() );
00754 
00755   DisplayController * controller = DisplayController::instance ();
00756 
00757   const vector < string > & bindingOptions
00758     = controller -> bindingOptions ( plotTypeStr );
00759 
00760   if ( bindingOptions.empty () ) return;
00761 
00762   //Layout the stuff.
00763 
00764   m_newLayoutWidget->hide();
00765 
00766   vector < int > indices;
00767   unsigned int s = m_new_combos.size ();
00768   for ( unsigned int i = 0; i < s; i++ ) {
00769     indices.push_back ( m_new_combos[i] -> currentItem () );
00770   }
00771   clear ( m_new_labels, m_new_combos );
00772   QString qs1;
00773 
00774   if ( index >= 0 ) {
00775     DataSource * nt = nt_vector[index];
00776     const vector < string > & cols = nt->getLabels();
00777 
00778     for ( unsigned int i = 0; i < m_new_combos.size (); i++ ) {
00779       if ( i < bindingOptions.size () ) {
00780         const string & axisName = bindingOptions[i];
00781         
00782         qs1 = ( axisName.c_str() );
00783         m_new_labels [i] -> setEnabled ( true );
00784         m_new_labels [i] -> setText ( qs1 );
00785         m_new_combos [i] -> setEnabled ( true );
00786         for (std::vector<string>::size_type j = 0; j < cols.size(); j++){
00787           m_new_combos [i] -> insertItem ( cols [j].c_str() );
00788         }
00789         
00790         if ( axisName.find ( "optional" ) != string::npos ) {
00791           m_new_combos [i] -> insertItem ( "nil" );
00792           m_new_combos [i] -> setCurrentText ( "nil" );
00793           indices[i] = -1;
00794         }
00795       }
00796     }
00797   }
00798   
00799 
00800   for ( unsigned int i = 0; i < m_new_combos.size(); i++ ) {
00801           
00802 
00803     if ( indices[i] >= 0 &&
00804          indices[i] < m_new_combos[i] -> count () ) {
00805       m_new_combos[i] ->setCurrentItem ( indices[i] );
00806     }
00807   }
00808   
00809 }
00810 
00811 void
00812 Inspector::
00813 updateDataTab()
00814 {
00815 
00816   
00817   updateNewPlotControls ();
00818   
00819 
00820   dataClearSelectedControls ();
00821   
00822 
00823   PlotterBase * plotter = getPlotter ();
00824   updateSelectedPlotType ( plotter );
00825 
00826   
00827 
00828   if ( plotter != 0 ) {
00829           
00830     currentPlot->setEnabled ( true );
00831     bool yes = plotter -> isTargetable ();
00832     if ( yes == false ) return;
00833   }
00834   else {
00835           
00836     if ( m_plotter_list.empty () == true ) {
00837                 
00838       currentPlot -> setDisabled ( true );
00839     }
00840     else {
00841 
00842           currentPlot -> setDisabled ( false );
00843     }
00844         
00845     return;
00846   }
00847   
00848   
00849 
00850   updateSelectedPlotData ( plotter );
00851   
00852 
00853   
00854 
00855 }
00856 
00857 void
00858 Inspector::
00859 updateSelectedPlotDataSource ( const std::string & name )
00860 {
00861   const vector < string > & nt_vector
00862     = DataSourceController::instance () -> getNTupleNames ();
00863 
00864   unsigned int size = nt_vector.size ();
00865   unsigned int count = m_sel_ntuple_name -> count ();
00866   bool refresh = count != size;
00867   if ( refresh ) m_sel_ntuple_name -> clear ();
00868   int jndex = -1;
00869   for ( std::size_t i = 0; i < size; i++ ) {
00870     const string & ntname = nt_vector[i];
00871     if ( ntname == name ) jndex = i;
00872     if ( refresh ) m_sel_ntuple_name -> insertItem ( ntname.c_str () );
00873   }
00874 
00875   if ( jndex < 0 ) { // not bound to ntuple
00876     m_sel_ntuple_name -> setEnabled ( false );
00877   }
00878   else {
00879     m_sel_ntuple_name -> setEnabled ( true );
00880     m_sel_ntuple_name -> setCurrentItem ( jndex );
00881   }
00882   // Update tip tool.
00883   QToolTip::remove(m_sel_ntuple_name );
00884   const QString tip = m_sel_ntuple_name -> currentText ();
00885   QToolTip::add( m_sel_ntuple_name, tip );
00886 
00887 
00888 }
00889 
00890 void
00891 Inspector::
00892 updateSelectedPlotType ( const PlotterBase * plotter )
00893 {
00894   bool yes = plotter != 0;
00895   if ( yes ) {
00896     yes = plotter -> isTargetable ();
00897     if ( yes ) {
00898       DataRep * datarep = plotter -> getTarget ();
00899       yes = datarep != 0;
00900       if ( yes ) {
00901         int index = plotter -> indexOf ( datarep );
00902         DisplayController * controller = DisplayController::instance ();
00903         const string & dataRepName
00904           = controller -> getType ( plotter, index );
00905         QString qst2 ( dataRepName.c_str() );
00906         m_dataRepNameText->setText ( qst2 );
00907       }
00908     }
00909   }
00910 
00911   m_dataRepNameText -> setEnabled ( yes );
00912 }
00913 
00914 void
00915 Inspector::
00916 dataClearSelectedControls ()
00917 {
00918   QLayoutIterator it = m_vLayout->iterator();
00919   while ( it.current() != 0 )
00920     {
00921       QLayoutItem * ptr = it.current();
00922       QHBoxLayout * hbox = static_cast <QHBoxLayout *> (ptr);
00923 
00924       QLayoutIterator hit = hbox->iterator();
00925       while ( hit.current() != 0 )
00926         {
00927           QLayoutItem * hptr = hit.current();
00928           QWidget * hwidget = hptr->widget();
00929           hit.deleteCurrent();
00930           if ( hwidget ) delete ( hwidget );
00931         }
00932 
00933       it.deleteCurrent();
00934 
00935     }
00936 }
00937 
00938 void
00939 Inspector::
00940 updateSelectedPlotData ( const PlotterBase * plotter )
00941 {
00942   DisplayController * controller = DisplayController::instance ();
00943   DataRep * datarep = plotter -> getTarget ();
00944   int index = plotter -> indexOf ( datarep );
00945   assert ( datarep != 0 );
00946 
00947   bool ntuple_bindings = datarep -> hasNTupleBindings ( );
00948   string name;
00949 
00950   if ( ntuple_bindings ) {
00951      name  = controller -> getDataSourceName ( plotter, index );
00952     setNewPlotNTuple ( name );
00953   }
00954   else {
00955     name = "<none>";
00956   }
00957   updateSelectedPlotDataSource ( name );
00958 
00959   //Layout the stuff.
00960 
00961   m_layoutWidget->hide();
00962 
00963   const vector < string > & bindings
00964     = controller -> axisBindings ( plotter, index );
00965   const vector < string > & bindingOptions
00966     = controller -> bindingOptions ( plotter, index );
00967   unsigned int listSize;
00968 
00969   if ( bindings.size() < bindingOptions.size() )
00970     {
00971       listSize = bindings.size();
00972     }
00973   else
00974     {
00975       listSize = bindingOptions.size();
00976     }
00977 
00978   bool yes = plotter -> isTargetable ();
00979   if ( ntuple_bindings == false ||
00980        yes == false ) return;
00981 
00982   // Now add the new hlayouts.
00983 
00984   QString qs1, qs2;
00985 
00986   const vector < string > & cols
00987     = controller -> getDataSourceLabels ( plotter, index );
00988 
00989   if ( cols.empty () ) return;
00990 
00991   clear ( m_sel_labels, m_sel_combos );
00992 
00993   for ( unsigned int i = 0; i < m_sel_combos.size (); i++ )
00994     {
00995       if ( i == listSize ) break;
00996       const string & axisLabel = bindings[i];
00997       const string & axisName = bindingOptions[i];
00998 
00999       qs1 = ( axisName.c_str() );
01000       m_sel_labels [i] -> setEnabled ( true );
01001       m_sel_labels [i] -> setText ( qs1 );
01002 
01003       qs2 = ( axisLabel.c_str() );
01004 
01005       // Insert all column labels from the vector cols, and make qs2
01006       // the current text.
01007 
01008       m_sel_combos [i] -> setEnabled ( true );
01009       for (std::vector<string>::size_type j = 0; j < cols.size(); j++ )
01010         {
01011           m_sel_combos [i] -> insertItem ( cols [j].c_str() );
01012         }
01013       if ( axisName.find ( "optional" ) != string::npos )
01014         {
01015           m_sel_combos [i] -> insertItem ( "nil" );
01016         }
01017       m_sel_combos [i] -> setCurrentText ( qs2 );
01018     }
01019 }
01020 
01021 void
01022 Inspector::
01023 invalidDataWarning ()
01024 {
01025   const QString message = 
01026     "One or more columns of the bound data source\n"
01027     "contains invalid data.";
01028  QMessageBox::warning ( this, // parent
01029                         "Invalid data", // caption
01030                         message,
01031                         QMessageBox::Ok,
01032                         Qt::NoButton,
01033                         Qt::NoButton );
01034 }
01035 
01036 void
01037 Inspector::
01038 noNTupleSelectedError ()
01039 {
01040   const QString message =
01041     "No n-tuple selected error\n"
01042     "Need to load n-tuple to create a plot";
01043   QMessageBox::critical ( this, // parent
01044                           "No n-tuple selected error", // cpation
01045                           message,
01046                           QMessageBox::Ok,
01047                           Qt::NoButton,
01048                           Qt::NoButton );
01049 }
01050 
01051 void
01052 Inspector::
01053 incompatibleDataRepError ( const std::string & type )
01054 {
01055   QString message ("Plot of type " );
01056   message += type.c_str();
01057   message += " can not be added\n"
01058     "to selected plot\n\n"
01059     "It might be incompatible.   For example, \n"
01060     "requiring a Z axis display while selected\n"
01061     "does not have one.";
01062   QMessageBox::critical ( this, // parent
01063                           "Add to plot error", // caption
01064                           message,
01065                           QMessageBox::Ok,
01066                           Qt::NoButton,
01067                           Qt::NoButton );
01068 }
01069 void
01070 Inspector::
01071 incompatibleFitterError ( const std::string & type )
01072 {
01073   QString message ( "Fitter of type " );
01074   message += type.c_str();
01075   message += " can not be used\n"
01076     "with selected plot\n\n"
01077     "It might be incompatible.   For example, \n"
01078     "Maximum Likelihood fitting requires binned\n"
01079     "data representation.";
01080   QMessageBox::critical ( this, // parent
01081                           "Set fitter error", // caption
01082                           message,
01083                           QMessageBox::Ok,
01084                           Qt::NoButton,
01085                           Qt::NoButton );
01086 }
01087 
01088 void
01089 Inspector::
01090 badFunctionError ( const std::string & name, const char * what )
01091 {
01092   QString message = "Function`";
01093   message += name.c_str();
01094   message += "' could not be used because ...\n";
01095   message += what;
01096   message +="\nMaybe the copy constructor or clone function is bad.";
01097 
01098   QMessageBox::critical ( this, // parent
01099                           "Function error", // caption
01100                           message,
01101                           QMessageBox::Ok,
01102                           Qt::NoButton,
01103                           Qt::NoButton );
01104 }
01105 
01106 void
01107 Inspector::
01108 incompatibleFunctionError ( const std::string & type )
01109 {
01110   QString message ( "Funtion of type " );
01111   message += type.c_str();
01112   message  += " can not be used\n"
01113     "with selected fitter\n\n"
01114     "It might be incompatible.   For example, \n"
01115     "the fitter requires derivatives\n"
01116     "that the function can not supply.";
01117   QMessageBox::critical ( this, // parent
01118                           "Set fitter error", // caption
01119                           message,
01120                           QMessageBox::Ok,
01121                           Qt::NoButton,
01122                           Qt::NoButton );
01123 }
01124 
01125 void
01126 Inspector::
01127 invalidRangeError ( const std::string & bad )
01128 {
01129   QString message ( "Attempt to apply invalid range:\n\n" );
01130   message += bad.c_str();
01131   message  += "\n\n Low end of range must be less than high end.";
01132 
01133   QMessageBox::critical ( this, // parent
01134                           "Range error", // caption
01135                           message,
01136                           QMessageBox::Ok,
01137                           Qt::NoButton,
01138                           Qt::NoButton );
01139 }
01140                         
01141 void
01142 Inspector::
01143 multipleDataRepError ( const std::string & type )
01144 {
01145   QString message ( "Multiple data representations are active.\n"
01146                     "Can not apply a " );
01147   message += type.c_str();
01148 #ifdef Q_OS_MACX
01149   message  += ".\n\n"
01150     "Use Command-click to select only one data representation.";
01151 #else
01152   message  += ".\n\n"
01153     "Use Control-click to select only one data representation.";
01154 #endif
01155   QMessageBox::information ( this, // parent
01156                              "Multiple data representation error", // caption
01157                              message,
01158                              QMessageBox::Ok,
01159                              Qt::NoButton,
01160                              Qt::NoButton );
01161 }
01162 
01163 bool
01164 Inspector::
01165 multipleDataRepInfo ( const std::string & type )
01166 {
01167   bool ok = false;
01168   QString message ( "Multiple data representations are active.\n"
01169                     "Apply " );
01170   message += type.c_str();
01171   message += " to each?\n\n";
01172 
01173 #ifdef Q_OS_MACX
01174   message += "One can use Control-click to apply a ";
01175 #else
01176   message += "One can use Command-click to apply a ";
01177 #endif
01178   message += type.c_str();
01179   message +=" to a selected data representation.";
01180 
01181   int result = QMessageBox::
01182     information ( this, // parent
01183                   "Multiple data representation error", // caption
01184                   message,
01185                   QMessageBox::Yes,
01186                   QMessageBox::No,
01187                   QMessageBox::NoButton );
01188 
01189   ok = result == QMessageBox::Ok;
01190 
01191   return ok;
01192 }
01193 
01194 void
01195 Inspector::
01196 cutOnCutError ()
01197 {
01198   const QString message ( "Attempt to add cut to itself\n"
01199                           "The request was ignorned" );
01200   QMessageBox::information ( this, // parent
01201                              "Applying cut error", // caption
01202                              message,
01203                              QMessageBox::Ok,
01204                              Qt::NoButton,
01205                              Qt::NoButton );
01206 }
01207 
01208 void
01209 Inspector::
01210 multiplePlotError ( )
01211 {
01212   const QString  message (
01213     "Multiple plots are selected.\n"
01214     "Can not apply change until only one is selected\n\n"
01215     "Use shift-click to deselect a selected plot" );
01216   QMessageBox::information ( this, // parent
01217                              "Multiple plot error", // caption
01218                              message, // .c_str(),
01219                              QMessageBox::Ok,
01220                              Qt::NoButton,
01221                              Qt::NoButton );
01222 }
01223 
01224 void Inspector::functionAddError ()
01225 {
01226   const QString message =
01227     "Functions are not supported on the selected data reaxisWitation.";
01228 
01229   QMessageBox::critical ( this, "Function Add Error",
01230                           message,
01231                           QMessageBox::Ok,
01232                           Qt::NoButton,
01233                           Qt::NoButton );
01234 }
01235 
01239 void
01240 Inspector::
01241 newPlotError ( const std::exception & e )
01242 {
01243   QString message ( "New plot could not be created because:\n" );
01244   message += e.what ();
01245   QMessageBox::critical ( this, // parent
01246                           "New plot error", // caption
01247                           message,
01248                           QMessageBox::Ok,
01249                           Qt::NoButton,
01250                           Qt::NoButton );
01251 }
01252 
01253 std::string
01254 Inspector::
01255 getArrayTupleLabel( const DataSource * rtuple, const std::string & column )
01256 {
01257 #ifdef HAVE_ROOT
01258   RootController * controller = RootController::instance ();
01259   vector < int > dimSize;
01260   controller -> fillDimSize ( dimSize, rtuple, column );
01261 
01262   // Set the caption
01263   QString caption( "MultiDimensional data in rows of the column ");
01264   caption.append( QString( column.c_str() ) );
01265 
01266   // Set the label
01267   std::ostringstream ost;
01268   ost << " Rows of this column are of size ";
01269 
01270   unsigned int i;
01271   for( i = 0; i < dimSize.size() - 1; i++ )
01272     ost << dimSize[i] << " x ";
01273   ost << dimSize[i];
01274 
01275   ost << "\n Enter C-style index of a single element of this";
01276   ost << "\n multidimentional data which you wish to analyse.";
01277   ost << "\n Index should be a comma separated list of ";
01278   ost << dimSize.size() << " integers.";
01279 
01280   ost << "\n For e.g. ";
01281   for( i = 0; i < dimSize.size() - 1; i++ )
01282     ost << "0, ";
01283   ost << "0 \n";
01284 
01285   string label( ost.str() );
01286 
01287   bool ok;
01288   QString text = QInputDialog::getText( caption, QString( label.c_str() ),
01289                                         QLineEdit::Normal,
01290                                         QString::null, &ok, this );
01291 
01292   // Also create the array tuple label
01293   std::ostringstream labelstream;
01294   labelstream << column;
01295 
01296   if ( ok && !text.isEmpty() )
01297     {
01298       vector< unsigned int > index;
01299       string s( text.ascii() );
01300 
01301       // User entered something and pressed OK
01302       // Creating the list of dropped delimiters.
01303       boost::char_separator< char > sep( "," );
01304 
01305       // A tokenizer with above dropped delimiters.
01306       typedef boost::tokenizer< boost::char_separator< char > >  tokenizer;
01307       tokenizer tok( s, sep );
01308 
01309       // Start extracting the dimension sizes.
01310       for( tokenizer::iterator tok_iter = tok.begin();
01311            tok_iter != tok.end();
01312            ++tok_iter )
01313         {
01314           unsigned int idx = boost::lexical_cast< unsigned int >( *tok_iter );
01315           index.push_back( idx );
01316           labelstream << "[" << idx << "]";
01317         }
01318     }
01319 
01320   return labelstream.str();
01321 #else
01322   return string(); // will not be used.
01323 #endif
01324 }
01325 
01326 void
01327 Inspector::
01328 newPlotButton_clicked()
01329 {
01330   vector < DataSource * > nt_vector;
01331   DataSourceController::instance() -> getDataSources ( nt_vector );
01332 
01333   if ( nt_vector.empty() )
01334     {
01335       noNTupleSelectedError ();
01336       return;
01337     }
01338 
01339   // See all comboboxes and create a new plotter.
01340   int current = m_all_ntuples->currentItem ();
01341   DataSource * ds = nt_vector[current];
01342 
01343   // Find the datarep.
01344   std::string plotTypeStr( (m_availPlotTypes -> currentText()).latin1() );
01345 
01346   // Find the axis bindings.
01347   vector < string > bindings;
01348   for ( unsigned int i = 0; i < m_new_combos.size(); i++ )
01349     {
01350       if ( m_new_combos [i] -> count () == 0 ) break;
01351 
01352       QString qstring = m_new_combos [ i ] -> currentText();
01353       string column ( qstring.latin1() );
01354       string label = column;
01355 
01356 #ifdef HAVE_ROOT
01357       if( column != "nil" && ds -> isMultiDimensional( column ) ) {
01358         bool yes = ds -> isUseable ( column );
01359         if ( yes == false ) {
01360           const QString
01361             message ( "This column is not useable because it contains\n"
01362                       "a multidimension array that varies is size or is\n"
01363                       "an unsupported data type." );
01364           QMessageBox::critical ( this, // parent
01365                                   "DataSource error",
01366                                   message,
01367                                   QMessageBox::Ok,
01368                                   QMessageBox::NoButton,
01369                                   QMessageBox::NoButton );
01370           return;
01371         }
01372 
01373         label = getArrayTupleLabel ( ds, column );
01374         RootController * rcontroller = RootController::instance();
01375         rcontroller -> smartExpandRootNTuple ( ds, column );
01376       }
01377 #endif
01378       bindings.push_back ( label );
01379     }
01380 
01381   // Create the plotter.
01382   try {
01383     DisplayController * controller =  DisplayController::instance();
01384     PlotterBase * newDisplay =
01385       controller -> createDisplay ( plotTypeStr, * ds, bindings );
01386     CanvasWindow * canvas = WindowController::instance() -> currentCanvas();
01387     canvas->addPlotDisplay ( newDisplay, true );
01388 
01389     bool valid = controller -> isDataValid ( newDisplay );
01390     if ( valid == false ) {
01391       invalidDataWarning ();
01392     }
01393   }
01394 //   catch ( const DataSourceException & e ) {
01395   catch ( const std::exception & e ) {
01396     newPlotError ( e );
01397   }
01398 }
01399 
01400 
01401 void
01402 Inspector::
01403 addDataRepButton_clicked()
01404 {
01405   // Find the display.
01406 
01407   PlotterBase * plotter = getPlotter ();
01408   if ( !plotter ) return;
01409 
01410   // Find the datarep.
01411   std::string plotTypeStr( (m_availPlotTypes->currentText()).latin1() );
01412 
01413   vector < DataSource * > nt_vector;
01414   DataSourceController::instance() -> getDataSources ( nt_vector );
01415 
01416   int current = m_all_ntuples->currentItem ();
01417   DataSource * ds = nt_vector[current];
01418 
01419   // Find the axis bindings.
01420 
01421   vector < string > bindings;
01422   for ( unsigned int i = 0; i < m_new_combos.size(); i++ )
01423     {
01424       if ( m_new_combos [i] -> count () == 0 ) break;
01425 
01426       QString qstring = m_new_combos [ i ] -> currentText();
01427       string column ( qstring.latin1() );
01428       string label = column;
01429 #ifdef HAVE_ROOT
01430       if ( column != "nil" && ds -> isMultiDimensional ( column ) ) {
01431         label = getArrayTupleLabel ( ds, column );
01432         RootController * rcontroller = RootController::instance ();
01433         rcontroller -> smartExpandRootNTuple ( ds, column );
01434       }
01435 #endif
01436       bindings.push_back ( label );
01437     }
01438 
01439   // Add the data rep.
01440 
01441   DisplayController * controller = DisplayController::instance();
01442   DataRep * rep = controller -> addDataRep ( plotter, plotTypeStr, ds,
01443                                              bindings );
01444 
01445   // If incompatible, do nothing.
01446   if ( rep == 0 ) 
01447     {
01448       incompatibleDataRepError ( plotTypeStr );
01449       return;
01450     }
01451 
01452   rep->set(Color::getColor());
01453 
01454   plotter -> autoScale ();
01455   bool valid = controller -> isDataValid ( rep );
01456   if ( valid == false ) {
01457     invalidDataWarning ();
01458   }
01459 
01460   update ();
01461 }
01462 
01463 void
01464 Inspector::
01465 removeDataRepButton_clicked()
01466 {
01467   PlotterBase * plotter = getPlotter ();
01468   if ( !plotter ) return;
01469 
01470   int num_active = plotter->activePlotIndex();
01471   int num_rep = plotter -> getNumDataReps();
01472 
01473   // If more than one active datarep or only one datarep 
01474   // in the plot, show warning message and do nothing.
01475   if (( num_active < 0) || ( num_rep <= 1 ))
01476     {
01477       const QString message=
01478         "You must have more than one DataReps \n"
01479         "in this view AND only one DataRep \n"
01480         "selected to be removed.";
01481 
01482       QMessageBox::warning ( this, // parent
01483                              "Unable to remove DataRep", // caption
01484                              message,
01485                              QMessageBox::Ok,
01486                              Qt::NoButton,
01487                              Qt::NoButton );
01488       return;
01489     }
01490 
01491   DataRep * rep = plotter -> getDataRep( num_active );
01492   //Reset index before remove the datarep.
01493   plotter->setActivePlot(-1,false);
01494   plotter -> removeDataRep ( rep );
01495   plotter -> autoScale ();
01496   delete rep;
01497 
01498   update();
01499 }
01500 
01501 
01502 void
01503 Inspector::
01504 dataCreateNTuple ()
01505 {
01506   const PlotterBase * plotter = getPlotter ();
01507   if ( plotter == 0 ) return;
01508   FunctionController * fc = FunctionController::instance ();
01509   NTuple * ntuple = fc -> createNTuple ( plotter, 0 );
01510   DataSourceController::instance () -> registerNTuple ( ntuple );
01511 
01512   update ();
01513 }
01514 
01515 
01516 void
01517 Inspector::
01518 fillPlotterList ( std::vector < PlotterBase * > & plotterlist )
01519 {
01520   plotterlist.clear();
01521   CanvasWindow * canvaz = WindowController::instance () ->currentCanvas();
01522 
01523   if ( canvaz != 0 ) {
01524     canvaz -> fillPlotterList ( plotterlist );
01525   }
01526 }
01527 
01528 void
01529 Inspector::
01530 ntupleChanged ( int index )
01531 {
01532   // Update tip tool.
01533   QToolTip::remove ( m_sel_ntuple_name );
01534   const QString tip = m_sel_ntuple_name -> currentText ();
01535   QToolTip::add ( m_sel_ntuple_name, tip );
01536 
01537   unsigned int size = m_plotter_list.size ();
01538   if ( size == 0 ) return;
01539 
01540   CutController * controller = CutController::instance ();
01541   vector < PlotterBase * > web;
01542   controller -> fillCutWeb ( m_plotter_list, web );
01543   size = web.size ();
01544 
01545   for ( unsigned int i = 0; i < size; i++ ) {
01546     PlotterBase * plotter = web [ i ];
01547     bool yes = plotter != 0;
01548     if ( yes ) yes = plotter -> isTargetable ();
01549     if ( yes == false ) continue;
01550 
01551     DataRep * rep = plotter -> getTarget ();
01552     yes = rep -> hasNTupleBindings ();
01553     if ( yes == false ) continue;
01554 
01555     DataSourceController * ds_controller = DataSourceController::instance ();
01556     const vector < string > & names = ds_controller -> getNTupleNames ();
01557     const string & ds_name = names [ index ];
01558     const DataSource * source = ds_controller -> getDataSource ( ds_name );
01559     DataRepController * dr_controller = DataRepController::instance ();
01560 
01561     try {
01562       dr_controller -> changeDataSource ( rep, source );
01563     }
01564     catch ( const runtime_error & e ) {
01565       QString message ( "Could not change binding because\n" );
01566       message += e.what ();
01567       QMessageBox::critical ( this, // parent
01568                               "Data source error",
01569                               message,
01570                               QMessageBox::Ok,
01571                               Qt::NoButton,
01572                               Qt::NoButton );
01573     }
01574   }
01575 }
01576 
01577 void
01578 Inspector::
01579 updateColorMapCtrls (const PlotterBase * plotter )
01580 {
01581   DisplayController * controller = DisplayController::instance ();
01582 
01583   const vector < double > & sv =
01584     controller -> getValueCtrlPts ( plotter );
01585   unsigned int size = sv.size ();
01586   if ( size > 0 ) {
01587     brk_pt -> setEnabled ( true );
01588     brk_label -> setEnabled ( true );
01589     brk_pt -> setValue ( static_cast <int> ( sv[0] * brk_pt -> maxValue() ));
01590   }
01591   if ( size > 1 ) {
01592     flat_width -> setEnabled ( true );
01593     flatlabel -> setEnabled ( true );
01594     flat_width->setValue(static_cast <int>( sv[1] * flat_width->maxValue()));
01595   }
01596   if ( size > 2 ) {
01597     color_scale -> setEnabled ( true );
01598     colorlabel -> setEnabled ( true);
01599     color_scale->setValue(static_cast<int>( sv[2] * color_scale->maxValue()));
01600   }
01601   if ( size < 3 ) {
01602     color_scale -> setEnabled ( false );
01603     colorlabel -> setEnabled ( false);
01604   }
01605   if ( size < 2 ) {
01606     flat_width -> setEnabled ( false );
01607     flatlabel -> setEnabled ( false );
01608   }
01609   if ( size < 1 ) {
01610     brk_pt -> setEnabled ( false );
01611     brk_label -> setEnabled ( false );
01612   }
01613 }
01614 
01618 void
01619 Inspector::
01620 updatePlotTab()
01621 { 
01622   
01623   loadAllUserModels ();
01624 
01625   bool yes = m_plotter_list.empty();
01626 
01627   m_plot_title -> setDisabled ( yes );
01628 
01629   PlotterBase * plotter = getPlotter ();
01630 
01631   yes = plotter != 0;
01632   if ( yes ) {
01633     int number = plotter -> getNumDataReps ();
01634     int index = plotter -> activePlotIndex ();
01635     yes = ( number < 2 ) || index >= 0;
01636   }
01637 
01638   m_plot_symbols->setEnabled ( yes );
01639 //   m_plot_color->setEnabled ( yes );
01640 //   m_selectedColor -> setEnabled ( yes );
01641   m_interval_le->setEnabled ( yes );
01642   m_interval_cb->setEnabled ( yes );
01643   m_errorBars ->setEnabled ( yes );
01644   m_grid -> setEnabled ( yes );
01645   m_boxedge->setEnabled ( yes );
01646   m_pointRepComboBox->setEnabled ( yes );
01647   if ( yes == false ) {
01648     m_selectedColor->setPaletteBackgroundColor ( "black" );
01649     return;
01650   }
01651 
01652 
01653   // Point Reps stuff.
01654 
01655   m_pointRepComboBox->clear();
01656 
01657   DisplayController * controller = DisplayController::instance ();
01658 
01659   DataRep * datarep = controller -> activeDataRep ( plotter );
01660 
01661   assert ( datarep != 0 );
01662 
01663   yes = datarep -> hasErrorDisplay ();
01664   m_errorBars -> setEnabled ( yes );
01665 
01666   ProjectorBase * proj = datarep -> getProjector();
01667 
01668   if ( proj != 0 ) {
01669     const vector <string> & pointreps = proj -> getPointReps();
01670         
01671 
01672     if ( pointreps.empty () == false ) {
01673       for (std::vector<string>::size_type i = 0; i < pointreps.size(); i++ ) {
01674                   
01675 
01676         m_pointRepComboBox->insertItem ( pointreps[i].c_str() );
01677       }
01678     }
01679     RepBase * rep = datarep->getRepresentation();
01680         
01681     const string & curRep = rep->name();
01682     m_pointRepComboBox->setCurrentText ( curRep.c_str() );
01683   }
01684 
01685   if ( plotter -> hasAxis ( Axes::Z ) == false ) { // no Z axis (colormap)
01686     m_value_combo -> setDisabled ( true );
01687     m_slider_control -> setDisabled ( true );
01688   }
01689   else { // has z axis (colormap)
01690 
01691     int jndex = controller -> getValueTransformIndex ( plotter ); // return the index to the list
01692 
01693         
01694         // of value to color transform names of the plotter. from 0 to size-1
01695     if ( jndex < 0 ) {  // no value available, jndex=-1
01696       m_value_combo -> setDisabled ( true );
01697     }
01698     else {
01699       m_value_combo -> setEnabled ( true );
01700       m_value_combo -> setCurrentItem ( jndex );
01701      
01702           // ***************************
01703          const BinToColor * repp=plotter -> getValueRep ();
01704          
01705          if (repp != 0) {
01706          bool yess = repp -> acceptChangeColor ();
01707          m_plot_color -> setEnabled (yess);
01708          m_selectedColor -> setEnabled (yess);
01709          }
01710          // *****************************
01711 
01712           bool yes = controller -> hasControlPoints ( plotter ); //return true if the value to color transform has control points
01713       m_slider_control -> setEnabled ( yes );
01714       yes = controller -> isUserDefinedValueTransform ( plotter );
01715       edit_model -> setEnabled ( yes );
01716       updateColorMapCtrls ( plotter );
01717     }// end of jndex<0
01718   }// end of plotter -> hasAxis ( Axes::Z ) == false
01719 
01720   // data source
01721   const DataSource * nt = controller -> getDataSource ( plotter, 0 );
01722 
01723   if ( nt && nt -> empty () ) {
01724     m_plot_symbols->setDisabled ( true );
01725     m_plot_title->setDisabled ( true );
01726     m_plot_color->setDisabled ( true );
01727     m_selectedColor -> setDisabled ( true );
01728     return;
01729   }
01730 
01731   //title
01732   const std::string & st = plotter->getTitle();
01733   QString qst ( st.c_str() );
01734   m_titleText->setText ( qst );
01735 
01736   // error bar and show grid checkbox
01737   m_errorBars->setChecked ( plotter->errorDisplay ( Axes::Y ) );
01738   m_grid->setChecked ( plotter->getShowGrid () );
01739   m_boxedge->setChecked (plotter->getBoxEdge ());
01740 
01741   // whether use symbols(triangle,plus,circle...) to represent data
01742   yes = controller -> hasSymbolRep ( plotter );
01743   m_symbol_group -> setEnabled ( yes );
01744 
01745   if ( yes  ) {
01746     m_point_stack -> raiseWidget ( 0 );
01747     unsigned int index = controller ->getRepStyle ( plotter );
01748     m_symbol_group -> setButton ( index );
01749   }
01750 
01751   // whether use line(solid, dash...)to represent data
01752   yes = controller -> hasLineRep ( plotter );
01753   m_line_group -> setEnabled ( yes );
01754   if ( yes ) {
01755     m_point_stack -> raiseWidget ( 1 );
01756     unsigned int style = controller -> getRepStyle ( plotter );
01757 #if QT_VERSION < 0x040000
01758     QButton * button = m_line_group -> find ( style );
01759 #else
01760    QAbstractButton * button = m_line_group -> find ( style );
01761 #endif
01762     QRadioButton * rb = dynamic_cast < QRadioButton * > ( button );
01763     rb -> setChecked ( true );
01764   }
01765   // set the point size
01766   float ptsize =  controller -> pointSize ( plotter );
01767   m_symbolPointSize -> setText ( QString ("%1").arg (ptsize) );
01768 
01769   // set color the user choose by RGB
01770   const Color & color = plotter->repColor ();
01771   QColor qcolor ( color.getRed(), color.getGreen(), color.getBlue () ); // constructor
01772   m_selectedColor->setPaletteBackgroundColor ( qcolor );
01773 
01774   // display interval
01775   if ( nt == 0 ) {
01776     m_interval_cb -> setEnabled ( false );
01777     m_interval_le -> setEnabled ( false );
01778     return;
01779   }
01780   const NTuple * ntuple = dynamic_cast < const NTuple * > ( nt );
01781   yes = ntuple != 0 && ntuple -> isIntervalEnabled ();
01782   m_interval_cb->setChecked ( yes );
01783   m_interval_le->setEnabled ( yes );
01784 
01785   if ( yes ) {
01786     unsigned int count = ntuple->getIntervalCount ();
01787     m_interval_le->setText ( QString ("%1").arg ( count ) );
01788   }
01789 }
01790 
01791 void
01792 Inspector::
01793 valueChanged ( int index )
01794 {
01795   PlotterBase * plotter = getPlotter ();
01796   if ( plotter != 0 ) {
01797 
01798     DisplayController * controller = DisplayController::instance ();
01799     controller -> setValueTransform ( plotter, index );
01800 
01801     const BinToColor * rep = plotter -> getValueRep();
01802     bool yes = false;
01803     if ( rep != 0 ) {
01804       yes = rep -> acceptChangeColor ();
01805     }
01806     m_plot_color -> setEnabled ( yes );
01807     m_selectedColor -> setEnabled ( yes );
01808 
01809      yes = controller -> hasControlPoints ( plotter );
01810      m_slider_control -> setEnabled ( yes );
01811      bool y = rep -> isUserDefined ();
01812      edit_model -> setEnabled ( y );
01813      if ( yes ) {
01814        m_is_updating = true;
01815          updateColorMapCtrls ( plotter );
01816            m_is_updating = false;
01817      }
01818   }
01819 }
01820 
01821 void
01822 Inspector::
01823 setAppKey ()
01824 {
01825   CanvasWindow * canvas = WindowController::instance () ->currentCanvas();
01826   if ( canvas != 0 ) {
01827     m_app_key = canvas -> getAppKey ();
01828     m_model_name  = m_app_key + "/Model Name/";
01829     m_break_point = m_app_key + "/break point/";
01830     m_flat_width  = m_app_key + "/flat width/";
01831     m_color_scale = m_app_key + "/color scale/";
01832   }
01833 }
01834 
01835 void
01836 Inspector::
01837 loadAllUserModels ()
01838 {
01839   if ( m_user_models_loaded == false ) {    
01840     setAppKey ();
01841 
01842     QSettings settings;
01843     settings.insertSearchPath ( QSettings::Windows, s_registry );
01844 
01845     QString model_name_key ( m_model_name );
01846     QStringList model_list 
01847         = settings.entryList ( model_name_key );
01848 
01849     QStringList::size_type size = model_list.size ();
01850     for ( QStringList::size_type i = 0; i < size ; i++ )
01851       {
01852         QString number = model_list [ i ];
01853         QString name 
01854           = settings.readEntry ( model_name_key + number );
01855         
01856         double brk_pt 
01857           = settings.readDoubleEntry ( m_break_point + number );
01858         double flat_width 
01859           = settings.readDoubleEntry ( m_flat_width + number );
01860         double color_scale 
01861           = settings.readDoubleEntry ( m_color_scale + number );
01862 
01863         string mname ( name.latin1() );
01864         vector < double > cpts;
01865         cpts.push_back ( brk_pt );
01866         cpts.push_back ( flat_width );
01867         cpts.push_back ( color_scale );
01868 
01869         DisplayController * controller = DisplayController::instance ();
01870         controller -> addValueTransform ( mname, cpts );
01871       }
01872 
01873     updateValueCombo ();
01874     m_user_models_loaded = true;
01875   }
01876 }
01877 
01878 void
01879 Inspector::
01880 sliderChanged ( int )
01881 {
01882   if ( m_is_updating == false ) {
01883     vector < double > sv;
01884 
01885     double m = brk_pt -> maxValue ();
01886     assert(m != 0);
01887     sv.push_back ( (brk_pt -> value()) / m + 0.001);
01888 
01889     double w = flat_width -> maxValue();
01890     assert(w != 0);
01891     sv.push_back ( (flat_width -> value()) / w + 0.001);
01892 
01893     double c = color_scale -> maxValue ();
01894     assert( c!= 0 );
01895     sv.push_back ( ( ( (color_scale -> value()) / c ) ) * 1.5 );
01896 
01897     PlotterBase * plotter = getPlotter ();
01898     if ( plotter != 0 ) {
01899       DisplayController * controller = DisplayController::instance ();
01900       controller -> setValueCtrlPts (plotter,sv );
01901     }
01902   }
01903 }
01904 
01905 void
01906 Inspector::
01907 resetSlider ( )
01908 {
01909   if ( m_slider_control -> isEnabled () )
01910     {
01911       brk_pt -> setValue ( 50 );
01912       flat_width -> setValue ( 50 );
01913       color_scale -> setValue ( 0 );
01914     }
01915 }
01916 
01917 
01918 void
01919 Inspector::
01920 convertCtrlPts ( std::vector < double > & sv )
01921 {
01922   sv.clear();
01923 
01924   int ibp = brk_pt -> value ();
01925   int ifw = flat_width -> value ();
01926   int ics = color_scale -> value ();
01927 
01928   double bp = static_cast < double > ( ibp) /
01929     static_cast <double>( brk_pt -> maxValue () );
01930 
01931   double fw = static_cast < double > ( ifw ) /
01932     static_cast <double>( flat_width -> maxValue () );
01933 
01934   double cs = static_cast < double > ( ics ) /
01935     static_cast <double>(color_scale -> maxValue () );
01936 
01937   sv.push_back ( bp );
01938   sv.push_back ( fw );
01939   sv.push_back ( cs );
01940 }
01941 
01942 void
01943 Inspector::
01944 newColorModel ( )
01945 {
01946   setAppKey ();
01947 
01948   bool ok = false;
01949   QString text =  QInputDialog::getText ( "Save color model", // caption
01950                                           "Enter name", // label
01951                                           QLineEdit::Normal,
01952                                           QString::null, // default text
01953                                           & ok, this );
01954 
01955   if ( ok )
01956     {
01957       const string name ( text.latin1() );
01958       vector < double > sv;
01959       convertCtrlPts ( sv );
01960       DisplayController * controller = DisplayController::instance ();
01961       controller -> addValueTransform ( name, sv );
01962 
01963       updateValueCombo ();
01964 
01965       PlotterBase * plotter = getPlotter ();
01966       controller -> setValueTransform ( plotter, name );
01967       int index = controller -> getValueTransformIndex ( plotter );
01968       m_value_combo -> setCurrentItem ( index );
01969 
01970       QSettings settings;
01971       settings.insertSearchPath ( QSettings::Windows, s_registry );
01972       QString model_name_key ( m_model_name );
01973 
01974       QStringList model_list 
01975         = settings.entryList ( model_name_key );
01976       
01977       int iat = 0;
01978       while ( true ) {
01979         int index = model_list.findIndex ( QString::number ( iat )) ;
01980         if ( index == -1 ) break;
01981         iat++;
01982       }
01983 
01984       QString at ( QString::number ( iat ) );
01985       settings.writeEntry ( m_model_name + at, text );
01986       settings.writeEntry ( m_break_point + at, sv[0] );
01987       settings.writeEntry ( m_flat_width + at, sv[1] );
01988       settings.writeEntry ( m_color_scale + at, sv[2] );
01989     }
01990 }
01991 
01992 void
01993 Inspector::
01994 editColorModel ( )
01995 {
01996   // If it's the first time to save the variable rainbow color scale,
01997   // we will need special handling. 
01998   bool isFirstVR = true;
01999   
02000   QString item = m_value_combo -> currentText ();
02001   vector < double > sv;
02002   convertCtrlPts ( sv );
02003 
02004   PlotterBase * plotter = getPlotter ();
02005   DisplayController * controller = DisplayController::instance ();
02006   // Use saveValueCtrlPts instead of setValueCtrlPts to make the 
02007   // changes effective in this session.
02008   controller -> saveValueCtrlPts ( plotter, sv );
02009       
02010   QSettings settings;
02011   settings.insertSearchPath ( QSettings::Windows, s_registry );
02012 
02013   QString model_name_key ( m_model_name );
02014   QStringList model_list 
02015     = settings.entryList ( model_name_key );
02016 
02017 #if QT_VERSION < 0x040000
02018   for ( unsigned int i = 0; i < model_list.size(); i++ ) {
02019 #else
02020   for ( int i = 0; i < model_list.size(); i++ ) {
02021 #endif
02022     QString at ( QString::number ( i ) );
02023     QString name_key ( model_name_key + at );
02024     QString name = settings.readEntry ( name_key );
02025     if ( name == item ) {
02026       settings.writeEntry ( m_break_point + at, sv[0] );
02027       settings.writeEntry ( m_flat_width + at, sv[1] );
02028       settings.writeEntry ( m_color_scale + at, sv[2] );
02029       isFirstVR = false;
02030       break;
02031     }
02032   }
02033 
02034   // For the first time, save the variable rainbow color scale.
02035   if ( isFirstVR ) {
02036     // Find the end of the settings.
02037     int iat = 0;
02038     while ( true ) {
02039       int index = model_list.findIndex ( QString::number ( iat )) ;
02040       if ( index == -1 ) break;
02041       iat++;
02042     }
02043     
02044     QString at ( QString::number ( iat ) );
02045     settings.writeEntry ( m_model_name + at, item );
02046     settings.writeEntry ( m_break_point + at, sv[0] );
02047     settings.writeEntry ( m_flat_width + at, sv[1] );
02048     settings.writeEntry ( m_color_scale + at, sv[2] );
02049   }
02050 }
02051 
02052 void
02053 Inspector::
02054 deleteColorModel ( )
02055 {
02056   QString item = m_value_combo -> currentText ();
02057   const string name ( item.latin1() );
02058 
02059   DisplayController * controller = DisplayController::instance ();
02060   bool yes =  controller -> removeValueTransform ( name );  
02061 
02062   if ( yes ) {
02063     PlotterBase * plotter = getPlotter ();
02064     controller -> setValueTransform ( plotter, "Rainbow" );
02065 
02066     QSettings settings;
02067     settings.insertSearchPath ( QSettings::Windows, s_registry );
02068     QString model_name_key ( m_model_name );
02069     QStringList model_list 
02070       = settings.entryList ( model_name_key );
02071     QStringList::size_type size = model_list.size ();
02072 
02073     for (QStringList::size_type i = 0; i < size; i++ ) {
02074       QString at ( model_list [ i ] );
02075       QString name_key ( model_name_key + at );
02076       QString name = settings.readEntry ( name_key );
02077       if ( name == item ) {
02078         settings.removeEntry ( name_key );
02079         settings.removeEntry ( m_break_point + at );
02080         settings.removeEntry ( m_flat_width + at );
02081         settings.removeEntry ( m_color_scale + at );
02082         break;
02083       }
02084     }
02085     updateValueCombo ();
02086   }
02087 }
02088 
02089 void
02090 Inspector::
02091 errorBars_toggled( bool )
02092 {
02093   PlotterBase * plotter = getPlotter ();
02094   if ( !plotter ) return;
02095 
02096   bool checked = m_errorBars->isChecked();
02097   DisplayController * controller = DisplayController::instance ();
02098 
02099   controller -> setErrorDisplayed ( plotter, Axes::Y, checked );
02100 }
02101 void
02102 Inspector::warningTex ()
02103 {
02104     const QString message ( "HippoDraw was not built with TeX support on "
02105                             "this platfrom." );
02106     QMessageBox::information ( this, /* parent */
02107                                "Input error",
02108                                message,
02109                                QMessageBox::Ok,
02110                                Qt::NoButton,
02111                                Qt::NoButton );
02112 }
02113 
02114 void
02115 Inspector::
02116 titleText_returnPressed()
02117 {
02118   std::string s( (m_titleText->text()).latin1() );
02119   unsigned int size = m_plotter_list.size();
02120 
02121   for ( unsigned int i = 0; i < size; i++ ) {
02122     PlotterBase * plotter = m_plotter_list [ i ];
02123 
02124     /* The size of drawrect, marginrect, need to be updated
02125        according to title text format. LaTeX format starts with
02126        "tex:" (case insensitive).
02127     */
02128     bool needMargin = String::ci_find(s, "tex:")==0;  
02129     if ( needMargin ) {
02130 #ifdef HAVE_TEX_UTILS
02131     plotter -> setTopMargin ( needMargin?10.0:0.0 );
02132     plotter -> setNeedUpdate(true);
02133     plotter -> notifyObservers ();
02134 #else
02135     warningTex ();
02136     s.erase ( 0, 4 );
02137 
02138 #endif
02139     }
02140     plotter->setTitle ( s );
02141   }
02142   
02143 
02144 }
02145 
02146 void Inspector::symbolTypeButtonGroup_clicked ( int id )
02147 {
02148   m_symbol_group -> setButton ( id );
02149   PlotterBase * plotter = getPlotter ();
02150   if ( !plotter ) return ;
02151 
02152   DisplayController * controller = DisplayController::instance ();
02153   DataRep * rep = controller -> activeDataRep ( plotter );
02154   if ( rep == 0 ) {
02155     multipleDataRepError ( "plot symbol change" );
02156     return;
02157   }
02158 
02159   rep -> setRepStyle ( id );
02160 }
02161 
02162 void Inspector::lineStyleButtonGroup_clicked ( int id )
02163 {
02164 
02165   m_line_group -> setButton ( id );
02166   PlotterBase * plotter = getPlotter ();
02167   if ( !plotter ) return ;
02168 
02169   DisplayController * controller = DisplayController::instance ();
02170   DataRep * rep = controller -> activeDataRep ( plotter );
02171   if ( rep == 0 ) {
02172     multipleDataRepError ( "plot symbol change" );
02173     return;
02174   }
02175 
02176   rep -> setRepStyle ( id );
02177 }
02178 
02179 void Inspector::symbolPointSize_returnPressed()
02180 {
02181 
02182   PlotterBase * plotter = getPlotter ();
02183   if ( !plotter ) return;
02184 
02185   DisplayController * controller = DisplayController::instance ();
02186   DataRep * rep = controller -> activeDataRep ( plotter );
02187   if ( rep == 0 ) {
02188     multipleDataRepError ( "plot symbol size change" );
02189     return;
02190   }
02191 
02192   QString text = m_symbolPointSize->text();
02193   float size = text.toFloat();
02194 
02195   rep->setRepSize ( size );
02196 
02197 }
02198 
02199 void Inspector::intervalStateChanged ( bool state )
02200 {
02201   PlotterBase * plotter = getPlotter ();
02202   if ( plotter == 0 ) return;
02203 
02204   DisplayController * controller = DisplayController::instance ();
02205   controller->setIntervalEnabled ( plotter, state );
02206   m_interval_le->setEnabled ( state );
02207 }
02208 
02209 void
02210 Inspector::
02211 intervalTextChanged ( const QString & text )
02212 {
02213   PlotterBase * plotter = getPlotter ();
02214   if ( plotter == 0 ) return;
02215 
02216   DisplayController * controller = DisplayController::instance ();
02217 
02218   unsigned int interval = text.toUInt ();
02219   controller->setIntervalCount ( plotter, interval );
02220 }
02221 
02222 void
02223 Inspector::
02224 colorSelect_clicked()
02225 {
02226   PlotterBase * plotter = getPlotter ();
02227   if ( !plotter ) return;
02228 
02229   int index = plotter->activePlotIndex ();
02230 
02231   if ( index < 0 ) {
02232     multipleDataRepError ( "color change" );
02233     return;
02234   }
02235 
02236   const Color & rep_color = plotter->repColor();
02237   QColor color ( rep_color.getRed(),
02238                  rep_color.getGreen(),
02239                  rep_color.getBlue() );
02240   color = QColorDialog::getColor ( color );
02241   if ( color.isValid() == false ) return;
02242 
02243   m_selectedColor->setPaletteBackgroundColor ( color );
02244 
02245   Color c ( color.red(), color.green(), color.blue() );
02246   plotter->setRepColor ( c );
02247 }
02248 
02249 void
02250 Inspector::
02251 pointRepComboBox_activated ( const QString & qstr )
02252 {
02253   PlotterBase * plotter = getPlotter ();
02254 
02255   if ( plotter != 0 ) {
02256     DisplayController * controller = DisplayController::instance ();
02257     const string rep ( qstr.latin1() );
02258 
02259     controller -> setPointRep ( plotter, rep );
02260 
02261     if ( plotter -> hasAxis ( Axes::Z ) == true ) {
02262 
02263       int index = m_value_combo -> currentItem ();
02264       controller -> setValueTransform ( plotter, index );
02265     }
02266 
02267     updatePlotTab (); // to update the m_point_stack and size.
02268   }
02269 }
02270 
02271 void
02272 Inspector::
02273 axis_button_group_clicked ( int id )
02274 {
02275 // #if QT_VERSION < 0x040000
02276 // #else
02277 //   id -= 3; // The re-inserted ones have wrong id
02278 // #endif
02279   m_axis = hippodraw::Axes::convert ( id );
02280   updateAxisTab ();
02281 }
02282 
02283 void
02284 Inspector::
02285 axisZoomPanCheckBox_clicked()
02286 {
02287   PlotterBase * plotter = getPlotter ();
02288   if ( !plotter ) return;
02289 
02290   plotter->setAutoRanging ( m_axis, false );
02291   const Range & r = plotter->getRange ( m_axis, true );
02292 
02293   m_autoScale->setChecked ( false );
02294 
02295   if ( axisWidget1->isZoomPanChecked() ) {
02296     m_zoompan[plotter] = true;
02297   }
02298 
02299   else {
02300 
02301     std::map < const PlotterBase *, bool >::const_iterator it
02302       = m_zoompan.find ( plotter );
02303     if ( it != m_zoompan.end () ) {
02304       m_zoompan[plotter] = false;
02305     }
02306 
02307   }
02308 
02309   axisWidget1->processZoomPanCheckBoxClicked ( r, r );
02310 }
02311 
02312 void
02313 Inspector::
02314 highRangeDrag()
02315 {
02316   int value = axisWidget1->getHighSliderValue ();
02317   setHighRange ( value, false );
02318 
02319   axisWidget1->setHighSliderValue ( 50 );
02320 }
02321 
02322 void
02323 Inspector::
02324 lowRangeDrag()
02325 {
02326   int value = axisWidget1->getLowSliderValue ();
02327   setLowRange ( value, false  );
02328 
02329   axisWidget1->setLowSliderValue ( 50 );
02330 }
02331 
02332 void
02333 Inspector::
02334 offsetDrag()
02335 {
02336   int value = m_offset_range->value ();
02337   setOffset ( value, false );
02338   m_offset_range->setValue ( 50 );
02339 }
02340 
02341 void
02342 Inspector::
02343 widthDrag ()
02344 {
02345   int value = m_width_range->value ();
02346   setBinWidth ( value, false );
02347 
02348   m_width_range->setValue ( 50 );
02349 }
02350 
02351 void
02352 Inspector::
02353 entriesDrag ()
02354 {
02355   int value = min_entries_slider->value ();
02356   m_dragging = false;
02357   setMinEntries(value);
02358 
02359   //  min_entries_slider->setValue ( 50 );
02360 }
02361 
02362 void
02363 Inspector::
02364 setWidthText()
02365 {
02366   PlotterBase * plotter = getPlotter ();
02367   if ( !plotter ) return;
02368 
02369   DisplayController * controller = DisplayController::instance ();
02370   int index = controller -> activeDataRepIndex ( plotter );
02371   bool yes = controller -> hasNTupleBindings ( plotter, index );
02372   if ( yes ) {
02373     //Get the string and convert it to double.
02374     QString text = m_width_text->text();
02375     double width = text.toDouble();
02376 
02377     if ( width == 0 ) return;    // To prevent it from crashing.
02378     plotter -> setBinWidth ( m_axis, width );
02379   }
02380 
02381   updateAxisTab();
02382 }
02383 
02384 void
02385 Inspector::
02386 setDragOn ()
02387 {
02388   m_dragging = true;
02389   m_min_entries = getMinEntries();
02390 
02391   if ( ! axisWidget1->isZoomPanChecked() )
02392     {
02393       m_autoScale->setChecked ( false );
02394       autoScale_clicked ();
02395     }
02396   else
02397     {
02398       // Save current width and position.
02399       m_autoScale->setChecked ( false );
02400       autoScale_clicked ();
02401 
02402       PlotterBase * plotter = getPlotter ();
02403       if ( !plotter ) return;
02404       const Range & r = plotter->getRange ( m_axis, true );
02405      m_range.setRange ( r.low(), r.high(), r.pos() );
02406     }
02407 
02408 }
02409 
02410 void
02411 Inspector::
02412 setOffsetText()
02413 {
02414   PlotterBase * plotter = getPlotter ();
02415   if ( !plotter ) return;
02416 
02417   DisplayController * controller = DisplayController::instance ();
02418   int index = controller -> activeDataRepIndex ( plotter );
02419   bool yes = controller -> hasNTupleBindings ( plotter, index );
02420   if ( yes ) {
02421     //Get the string and convert it to double.
02422     QString text = m_offset_text->text();
02423     double offset = text.toDouble();
02424 
02425     int value = static_cast < int > ( 50.0 * offset ) + 49;
02426     setDragOn ();
02427     setOffset( value );
02428     offsetDrag ();
02429   }
02430 
02431   updateAxisTab ();
02432 }
02433 
02434 void
02435 Inspector::
02436 setBinWidth ( int value )
02437 {
02438   setBinWidth ( value, m_dragging );
02439 
02440   if ( m_dragging == false ) m_width_range -> setValue ( 50 );
02441 }
02442 
02443 void
02444 Inspector::
02445 setBinWidth ( int value, bool drag )
02446 {
02447   PlotterBase * plotter = getPlotter ();
02448   if ( !plotter ) return;
02449   m_dragging = drag;
02450 
02451   plotter -> setBinWidth ( m_axis, value, m_dragging );
02452   updateAxisTab ();
02453 }
02454 
02455 void
02456 Inspector::
02457 axisLabelText()
02458 {
02459   PlotterBase * plotter = getPlotter ();
02460   if ( plotter != 0 ) {
02461     QString text = m_axis_label -> text ();
02462     string ltext = text.latin1();
02463     const string axis = convertToString ( m_axis );
02464 
02465     /* The size of drawrect, marginrect, need to be updated
02466        according to title text format. LaTeX format starts with
02467        "tex:" (case insensitive).
02468     */
02469     bool needMargin = String::ci_find(ltext, "tex:")==0;
02470     if ( needMargin ) {
02471 #ifdef HAVE_TEX_UTILS
02472     if (m_axis==Axes::X)
02473       plotter -> setBottomMargin ( needMargin?8.0:0.0 );
02474     else if (m_axis==Axes::Y)
02475       plotter -> setLeftMargin ( needMargin?0.0:0.0 );
02476     else if (m_axis==Axes::Z)
02477       plotter -> setZMargin ( needMargin?7.0:0.0 );
02478     plotter -> setNeedUpdate(true);
02479     plotter -> notifyObservers ();
02480 #else
02481     warningTex();
02482     ltext.erase( 0, 4 );
02483 #endif
02484     }
02485     plotter -> setLabel ( m_axis, ltext );
02486   }
02487   
02488 
02489 }
02490 
02491 void
02492 Inspector::
02493 setLowText()
02494 {
02495 
02496   PlotterBase * plotter = getPlotter ();
02497   if ( !plotter ) return;
02498 
02499   Range r = plotter->getRange ( m_axis, true );
02500 
02501   axisWidget1->processTextBoxReturnPressed ( r, r );
02502 
02503   plotter->setRange ( m_axis, r, true, false ); // scaled, keep bin width
02504   m_autoScale->setChecked ( false );
02505 
02506   updateAxisTab ();
02507 }
02508 
02509 void
02510 Inspector::
02511 setLowRange ( int value )
02512 {
02513   if ( m_is_updating == false ) {
02514     setLowRange ( value, m_dragging );
02515     if ( m_dragging == false ) {
02516       axisWidget1->setLowSliderValue ( 50 );
02517     }
02518   }
02519 }
02520 
02521 void
02522 Inspector::
02523 setLowRange ( int value, bool yes )
02524 {
02525   PlotterBase * plotter = getPlotter ();
02526   if ( !plotter ) return;
02527   m_dragging = yes;
02528 
02529   plotter->setAutoRanging ( m_axis, false );
02530 
02531   if ( ! axisWidget1->isZoomPanChecked() )
02532     {
02533       const string axis = convertToString ( m_axis );
02534       plotter->setLowRange ( m_axis, value, m_dragging );
02535       const Range & r = plotter->getRange ( m_axis, true );
02536       double low = r.low();
02537       axisWidget1 -> setLowText ( QString("%1").arg(low));
02538     }
02539   else
02540     {
02541       const Range & r = plotter->getRange ( m_axis, true );
02542       Range range ( r.low(), r.high(), r.pos() );
02543       axisWidget1->processLowSliderMoved ( value, range, m_range );
02544       if ( m_dragging ) plotter->setRange ( m_axis, range, true, false );
02545     }
02546 }
02547 
02548 void
02549 Inspector::
02550 setHighRange ( int value )
02551 {
02552   if ( m_is_updating == false ) {
02553     setHighRange ( value, m_dragging );
02554     if ( m_dragging == false ) {
02555       axisWidget1->setHighSliderValue ( 50 );
02556     }
02557   }
02558 }
02559 
02560 void
02561 Inspector::
02562 setHighRange ( int value, bool yes )
02563 {
02564   PlotterBase * plotter = getPlotter ();
02565   if ( !plotter ) return;
02566   m_dragging = yes;
02567 
02568   plotter->setAutoRanging ( m_axis, false );
02569 
02570   if ( !axisWidget1->isZoomPanChecked() )
02571     {
02572       const string axis = convertToString ( m_axis );
02573       plotter->setHighRange ( m_axis, value, m_dragging );
02574       const Range & r = plotter->getRange ( m_axis, true );
02575       double high = r.high();
02576       axisWidget1 -> setHighText ( QString("%1").arg(high));
02577       return;
02578     }
02579 
02580   BinaryTransform *t =
02581     dynamic_cast<  BinaryTransform* > ( plotter->getTransform() );
02582 
02583   if ( axisWidget1->isZoomPanChecked() && ! t->isPeriodic() )
02584     {
02585       const Range & r = plotter->getRange ( m_axis, true );
02586       Range range ( r.low(), r.high(), r.pos() );
02587       axisWidget1->processHighSliderMoved ( value, range, m_range );
02588       if ( m_dragging ) plotter->setRange ( m_axis, range, true, false );
02589       return;
02590     }
02591 
02592   double offset(0.0), incr(0.0);
02593 
02594   if ( axisWidget1->isZoomPanChecked() && t->isPeriodic() )
02595     {
02596           
02597       PeriodicBinaryTransform *tp =
02598         dynamic_cast< PeriodicBinaryTransform* > ( t );
02599 
02600       const Range & r = plotter->getRange ( m_axis, true );
02601       Range range (r.low(), r.high(), r.pos());
02602 
02603       incr = ( value - m_highslider1_last_val ) * r.length() / 100;
02604       m_highslider1_last_val = value;
02605 
02606       // Exchange axes to make the GUI more understandable.
02607       if ( m_axis == Axes::Y )
02608         {
02609           offset = tp->xOffset();
02610           offset = tp->moduloAddY( offset, incr );
02611           tp->setXOffset( offset );
02612         }
02613       else if ( m_axis == Axes::X )
02614         {
02615           offset = tp->yOffset();
02616           offset = tp->moduloAddX( offset, incr );
02617           tp->setYOffset( offset );
02618         }
02619 
02620       
02621       axisWidget1 -> setHighText ( QString( "%1" ).arg( offset ) );
02622       if ( m_dragging ) plotter->setRange ( m_axis, range, true, false );
02623       return;
02624     }
02625 }
02626 
02627 void
02628 Inspector::
02629 setHighText()
02630 {
02631 
02632   PlotterBase * plotter = getPlotter ();
02633   if ( !plotter ) return;
02634 
02635   Range r = plotter->getRange ( m_axis, true );
02636 
02637   axisWidget1->processTextBoxReturnPressed ( r, r );
02638 
02639   plotter->setRange ( m_axis, r, true, false ); // scaled and keep bin width
02640   m_autoScale->setChecked ( false );
02641 
02642   updateAxisTab ();
02643 }
02644 
02645 void
02646 Inspector::
02647 setOffset ( int value  )
02648 {
02649   setOffset( value, m_dragging );
02650 }
02651 
02652 void
02653 Inspector::
02654 setOffset ( int value, bool yes  )
02655 {
02656   PlotterBase * plotter = getPlotter ();
02657   if ( !plotter ) return;
02658   m_dragging = yes;
02659 
02660   const string axis = convertToString ( m_axis );
02661   DisplayController * controller = DisplayController::instance();
02662   controller ->  setOffset ( plotter, axis, value, m_dragging );
02663   double offset = plotter->getOffset ( m_axis );
02664   m_offset_text -> setText ( QString ("%1").arg (offset) );
02665 
02666   updateAxisTab ();
02667 }
02668 
02669 const std::vector < PlotterBase * > &
02670 Inspector::
02671 getDataCutList ( PlotterBase * plotter )
02672 {
02673   vector < PlotterBase * > plotterlist;
02674   fillPlotterList ( plotterlist );
02675 
02676 
02677   DisplayController * controller = DisplayController::instance ();
02678   const DataSource * tuple = controller -> getDataSource ( plotter );
02679   CutController * cutcontroller = CutController::instance();
02680   return cutcontroller->getCutList ( plotterlist, tuple );
02681 }
02682 
02683 void
02684 Inspector::
02685 cutText_returnPressed ()
02686 {
02687   m_is_updating = true;
02688 
02689   int id = cutRadioId ();
02690   bool fit_cut = id == 2;
02691 
02692   int index = m_selCutComboBox -> currentItem ();
02693   Range currentRange = m_tuple_cuts [index] -> getRange();
02694   PlotterBase * plotter = getSelectedCut();
02695 
02696   if ( fit_cut == false ) {
02697     Axes::Type cut_axis = getAxes ( index );
02698     const Range & fullRange = plotter -> getRange ( cut_axis, false );
02699     axisWidget2->processTextBoxReturnPressed ( currentRange, fullRange );
02700     plotter->setCutRangeAt ( currentRange, cut_axis );
02701   }
02702   else {
02703     const Range & fullRange = plotter -> getRange ( Axes::X, false );
02704     axisWidget2->processTextBoxReturnPressed ( currentRange, fullRange );
02705     plotter->setCutRangeAt ( currentRange, index );
02706   }
02707 }
02708 
02709 void Inspector::disableCutControls ( bool yes )
02710 {
02711   axisWidget2->setAllDisabled ( yes );
02712   colorSelect_2->setDisabled ( yes );
02713   cutRemovePushButton->setDisabled ( yes );
02714   cutInvertPushButton->setDisabled ( yes );
02715   cutEnablePushButton -> setDisabled ( yes );
02716   m_cutAddSelected->setDisabled ( yes );
02717   m_cutAddAll -> setDisabled ( yes );
02718 
02719   if ( yes ) {
02720     int number = m_selCutComboBox -> count ();
02721     while ( number-- > 0 ) {
02722       m_selCutComboBox -> removeItem ( 0 );
02723     }
02724   }
02725   m_selCutComboBox -> setDisabled ( yes );
02726 }
02727 
02728 void
02729 Inspector::
02730 updateTupleCuts ( const std::vector < PlotterBase * > & cutlist )
02731 {
02732   m_tuple_cuts.clear ();
02733   m_tuple_cut_plotters.clear ();
02734 
02735   unsigned int size = cutlist.size ();
02736 
02737   for ( unsigned int i = 0; i < size; i++ ) {
02738     PlotterBase * plotter = cutlist[i];
02739     TupleCutList_t cuts;
02740     plotter -> fillCutList ( cuts );
02741 
02742     for ( unsigned int j = 0; j < cuts.size (); j++ ) {
02743       m_tuple_cuts.push_back ( cuts[j] );
02744       m_tuple_cut_plotters.push_back ( plotter );
02745     }
02746   }
02747 }
02748 
02749 void
02750 Inspector::
02751 updateCutControls ( const std::vector < PlotterBase * > & cutlist )
02752 {
02753   QString old_current = m_selCutComboBox -> currentText ();
02754   int numberItems = m_selCutComboBox->count();
02755 
02756   while ( numberItems-- > 0 ) {
02757     m_selCutComboBox->removeItem(0);
02758   }
02759 
02760   m_selCutComboBox -> setEnabled ( true );
02761 
02762   updateTupleCuts ( cutlist );
02763   bool yes = m_tuple_cuts.empty ();
02764   if ( yes ) {
02765     cutRemovePushButton -> setEnabled ( false );
02766     return;
02767   }
02768 
02769   int index = -1;
02770   unsigned int size = m_tuple_cuts.size ();
02771 
02772   for ( unsigned int i = 0; i < size; i++ ) {
02773     const TupleCut * cut = m_tuple_cuts[i];
02774     const string & label = cut -> getLabel ();
02775     QString item = label.c_str ();
02776     m_selCutComboBox -> insertItem ( item );
02777     if ( item == old_current ) index = i;
02778   }
02779 
02780   PlotterBase * plotter = getPlotter ();
02781   assert ( plotter );
02782   index = -1;
02783   map < PlotterBase *, int > ::iterator first
02784     = m_cut_map.find ( plotter );
02785 
02786   if ( first == m_cut_map.end () ) { // not found
02787     index = 0;
02788     m_cut_map [ plotter ] = index;
02789   }
02790   else {
02791     index = first -> second;
02792   }
02793   int count = m_selCutComboBox -> count ();
02794   if ( index >= count ) {
02795     index = count -1;
02796     m_cut_map [ plotter] = index;
02797   }
02798 
02799   m_selCutComboBox -> setCurrentItem ( index );
02800   updateCutEnableButton ();
02801 }
02802 
02806 void
02807 Inspector::
02808 updateCutEnableButton ( )
02809 {
02810   if ( m_tuple_cuts.empty () ) return;
02811 
02812   int index = m_selCutComboBox -> currentItem ();
02813   const TupleCut * cut = m_tuple_cuts [ index ];
02814   assert ( cut != 0 );
02815   bool yes = cut -> isEnabled ();
02816   m_cut_enable_updating = true;
02817   cutEnablePushButton -> setOn ( ! yes );
02818   m_cut_enable_updating = false;
02819 }
02820 
02821 Axes::Type
02822 Inspector::
02823 getAxes ( unsigned int index )
02824 {
02825   Axes::Type axis = Axes::Y;
02826 
02827   PlotterBase * plotter = m_tuple_cut_plotters [ index ];
02828   unsigned int size = m_tuple_cut_plotters.size ();
02829   for ( unsigned int i = 0; i < size; i++ ) {
02830     if ( m_tuple_cut_plotters[i] == plotter ) {
02831       if ( i == index ) {
02832         axis = Axes::X;
02833       }
02834       break;
02835     }
02836   }
02837 
02838   return axis;
02839 }
02840 
02841 void
02842 Inspector::
02843 updateCutControlValues ( const PlotterBase * cplotter )
02844 {
02845   m_is_updating = true;
02846   int index = m_selCutComboBox -> currentItem ();
02847   const Range & currentRange = m_tuple_cuts[index] -> getRange ();
02848 
02849   Axes::Type cut_axis = Axes::X;
02850   int id = cutRadioId ();
02851   bool fit_cut = id == 2;
02852   if ( fit_cut == false ) {
02853     cut_axis = getAxes ( index );
02854   }
02855   const Range & fullRange = cplotter->getRange ( cut_axis, false );
02856 
02857   axisWidget2->updateCutControlValues ( currentRange, fullRange );
02858   CutController * controller = CutController::instance ();
02859 
02860   bool yes
02861     = controller -> isZoomPan ( cplotter, cut_axis );
02862   axisWidget2 -> setZoomPan ( yes );
02863   axisWidget2->processZoomPanCheckBoxClicked ( currentRange, fullRange );
02864   m_is_updating = false;
02865 }
02866 
02867 // void
02868 // Inspector::
02869 // fillCutsOn ( const PlotterBase * plotter,
02870 //           std::vector < PlotterBase * > & cutlist )
02871 // {
02872 //   cutlist.clear();
02873 
02874 //   DisplayController * controller = DisplayController::instance ();
02875 //   const DataRep * datarep = controller -> activeDataRep ( plotter );
02876 //   if ( datarep != 0 ) {
02877 //     CutController * cutcontroller = CutController::instance();
02878 
02879 //     cutcontroller->fillCutList ( datarep, cutlist );
02880 //   }
02881 // }
02882 
02883 const std::vector < const TupleCut * > &
02884 Inspector::
02885 getCutList ( const PlotterBase * plotter ) const
02886 {
02887   DisplayController * controller = DisplayController::instance ();
02888   int index = controller -> activeDataRepIndex ( plotter );
02889   if ( index < 0 ) {
02890     string what ( "Inspector::getCutList: " );
02891     what += "no active DataRep in PlotterBase object.";
02892     throw std::logic_error ( what );
02893   }
02894   const DataRep * datarep = plotter -> getDataRep ( index );
02895   CutController * cut_controller = CutController::instance ();
02896 
02897   return cut_controller -> getCutList ( datarep );
02898 }
02899 
02900 void
02901 Inspector::
02902 selectedCutsRadioButton_toggled ( bool )
02903 {
02904   if ( !m_selectedPlotRadioButton->isChecked() ) return;
02905 
02906   // Change the items in the combo box to only cuts over selected datarep.
02907 
02908   PlotterBase * plotter = getPlotter ();
02909   bool yes = plotter != 0;
02910   if ( yes ) yes = plotter -> isTargetable ();
02911   disableCutControls ( yes == false );
02912   if ( yes == false ) return;
02913 
02914   vector < PlotterBase * > cutlist;
02915 
02916   if ( cutRadioId () != 2 ) {
02917     CutController * controller = CutController::instance ();
02918     controller -> fillCutList ( plotter, cutlist );
02919 
02920     // Clear the combobox and insert the new strings.
02921 
02922     if ( cutlist.empty () ) {
02923       disableCutControls ( true );
02924       cutRemovePushButton->setEnabled ( false );
02925       return;
02926     }
02927   }
02928   else { // fitting cut
02929     cutlist.push_back ( plotter );
02930   }
02931 
02932   updateCutControls ( cutlist );
02933 
02934   if ( m_tuple_cuts.empty () ) {
02935     disableCutControls ( true );
02936     cutRemovePushButton->setEnabled ( false );
02937     return;
02938   }
02939 
02940   // Update Controls.
02941 
02942   disableCutControls ( false );
02943   cutRemovePushButton->setEnabled ( true );
02944   m_cutAddSelected -> setDisabled ( true );
02945   m_cutAddAll -> setDisabled ( true );
02946 
02947   // Update texts and sliders.
02948 
02949   int index = m_selCutComboBox -> currentItem ();
02950   const PlotterBase * cut_plotter = m_tuple_cut_plotters [ index ];
02951   updateCutControlValues ( cut_plotter );
02952 }
02953 
02954 void
02955 Inspector::
02956 cutAddSelected ()
02957 {
02958   // Take the selected cut from cutlistcombobox and add it to selected
02959   // plotter on canvas.
02960 
02961   // Find the selected cutplotter.
02962 
02963   CutPlotter * cp = getSelectedCut();
02964 
02965   // Find the selected Plotter.
02966   PlotterBase * plotter = getPlotter ();
02967   if ( !plotter ) return ;
02968 
02969   // Add the cut to the plotter.
02970   CutController * controller = CutController::instance();
02971   controller -> addCut ( cp, plotter );
02972 
02973 }
02974 
02975 void
02976 Inspector::
02977 cutAddAll ()
02978 {
02979   PlotterBase * plotter = getPlotter ();
02980   if ( plotter == 0 ) return;
02981 
02982   CutController * controller = CutController::instance ();
02983   const vector < PlotterBase * > & cut_list = getDataCutList ( plotter );
02984 
02985   controller -> addCuts ( cut_list, plotter );
02986 
02987   unsigned int size = cut_list.size ();
02988   for ( unsigned int i = 0; i < size; i++ ) {
02989     PlotterBase * pb = cut_list[i];
02990     CutPlotter * cut_plotter = dynamic_cast < CutPlotter * > ( pb );
02991     if ( cut_plotter == plotter ) {
02992       cutOnCutError ();
02993     }
02994   }
02995 }
02996 
02997 /* Take the selected cut from cutlistcombobox and remove it from the selected
02998     plotter on canvas.
02999 */
03000 void
03001 Inspector::
03002 cutRemovePushButton_clicked()
03003 {
03004   PlotterBase * plotter = getPlotter ();
03005   if ( !plotter ) return ;
03006 
03007   bool is_fit_radio = cutRadioId () == 2;
03008   if ( is_fit_radio ) {
03009     DisplayController * controller = DisplayController::instance ();
03010     int index = controller->activeDataRepIndex ( plotter );
03011     DataRep * rep = plotter -> getDataRep ( index );
03012     FunctionController::instance () -> removeTupleCut ( plotter, rep );
03013   }
03014   else {
03015     // Find the selected cutplotter.
03016     CutPlotter * cp = getSelectedCut();
03017     CutController::instance() -> removeCut ( cp, plotter );
03018   }
03019 
03020   if ( m_selectedPlotRadioButton -> isChecked () ) {
03021     // post event so we don't delete item that sent us the signal.
03022     PlotterEvent * event = new PlotterEvent ( plotter );
03023     QApplication::postEvent ( this, event );
03024   }
03025 }
03026 
03027 void
03028 Inspector::
03029 allCutsRadioButton_toggled ( bool )
03030 {
03031   if ( !allCutsRadioButton->isChecked() ) return;
03032 
03033   PlotterBase * plotter = getPlotter ();
03034 
03035   bool yes = plotter != 0;
03036   if ( yes ) yes = plotter -> isTargetable ();
03037 
03038   disableCutControls ( yes == false );
03039   if ( yes == false )  return;
03040 
03041   const vector < PlotterBase * > & cutlist = getDataCutList ( plotter );
03042 
03043   // Clear the combobox and insert the new strings.
03044 
03045   updateCutControls ( cutlist );
03046 
03047   if ( cutlist.empty () ) {
03048     disableCutControls ( true );
03049     return;
03050   }
03051 
03052   // Update Controls.
03053 
03054   disableCutControls ( false );
03055   cutRemovePushButton->setDisabled ( true );
03056   m_cutAddSelected -> setEnabled ( true );
03057   m_cutAddAll -> setEnabled ( true );
03058 
03059   // Update texts and sliders.
03060 
03061   const PlotterBase * cut_plotter = cutlist.back ();
03062   updateCutControlValues ( cut_plotter );
03063 }
03064 
03065 void Inspector::selCutChanged ( )
03066 {
03067   CutPlotter * cut_plotter = getSelectedCut ();
03068   updateCutControlValues ( cut_plotter );
03069 
03070   PlotterBase * plotter = getPlotter (); // the target
03071   int index = m_selCutComboBox -> currentItem ();
03072   m_cut_map [ plotter ] = index;
03073 
03074   updateCutEnableButton ();
03075 }
03076 
03077 CutPlotter *
03078 Inspector::
03079 getSelectedCut ()
03080 {
03081   if ( cutRadioId() != 2 ) {
03082     PlotterBase * plotter = getPlotter ();
03083     if ( plotter == 0 ) return 0;
03084 
03085     m_last_cut_index = m_selCutComboBox->currentItem();
03086 
03087     PlotterBase * pb = m_tuple_cut_plotters [ m_last_cut_index ];
03088     return dynamic_cast < CutPlotter * > ( pb );
03089   }
03090   else { // fitting cut
03091     PlotterBase * pb = getPlotter ();
03092     CutPlotter * plotter = dynamic_cast < CutPlotter * > ( pb);
03093     return plotter;
03094   }
03095 }
03096 
03100 void
03101 Inspector::
03102 cutNew()
03103 {
03104   // Get the column label from m_CutVariableComboBox1, and create a cut on
03105   // the selected plotter with that column label. Also update the list of
03106   // cuts and the high and low range.
03107 
03108   PlotterBase * plotter = getPlotter ();
03109   bool yes = plotter != 0;
03110 
03111   if ( yes ) yes = plotter -> isTargetable ();
03112   if ( yes == false ) {
03113     int index = plotter -> activePlotIndex ();
03114     if ( index <  0 ) {
03115       multipleDataRepError ( "Cut" );
03116     }
03117     else { // must be a function
03118       const QString message ( "Can not apply cut to a function" );
03119       QMessageBox::information ( this, /* parent */
03120                                  "Cut application error",
03121                                  message,
03122                                  QMessageBox::Ok,
03123                                  Qt::NoButton,
03124                                  Qt::NoButton );
03125     }
03126     return;
03127   }
03128 
03129   DisplayController * controller = DisplayController::instance ();
03130   int index = controller->activeDataRepIndex ( plotter );
03131   assert ( index >= 0 );
03132 
03133   const DataRep * rep = plotter -> getDataRep ( index );
03134   if ( rep -> hasNTupleBindings () == false ) {
03135       const QString message ( "Can not apply cut to a static histogram" );
03136       QMessageBox::information ( this, /* parent */
03137                                  "Cut application error",
03138                                  message,
03139                                  QMessageBox::Ok,
03140                                  Qt::NoButton,
03141                                  Qt::NoButton );
03142       return;
03143   }
03144 
03145   vector < string > bindings;
03146   int id = cutRadioId ();
03147   if ( id != 2 ) {
03148 #if QT_VERSION < 0x030100 // 3.1.0
03149     string label1 ( m_CutVariableComboBox1 -> currentText() );
03150     string label2 ( m_CutVariableComboBox2 -> currentText() );
03151 #else
03152     QString text1 = m_CutVariableComboBox1 -> currentText();
03153     string label1 = text1.latin1();
03154     QString text2 = m_CutVariableComboBox2 -> currentText();
03155     string label2 = text2.latin1();
03156 #endif
03157 
03158     switch ( id ) {
03159     case 0 : // 1d data cut
03160       bindings.push_back( label1 );
03161       break;
03162     case 1 : // 2d data cut
03163       bindings.push_back( label1 );
03164       bindings.push_back( label2 );
03165     break;
03166     }
03167     CutController * cutcontroller = CutController::instance();
03168     PlotterBase * cutplotter = cutcontroller -> addCut ( plotter, bindings );
03169     CanvasWindow * canvas = WindowController::instance () ->currentCanvas();
03170     if ( canvas == 0 ) return;
03171 
03172     canvas -> addPlotDisplay ( cutplotter, false );
03173   }
03174   else {
03175     DataRep * datarep = plotter -> getDataRep ( index );
03176     FunctionController * controller = FunctionController::instance ();
03177     controller -> setTupleCut ( plotter, datarep );
03178   }
03179 
03180   // Update other guys.
03181   selectedCutsRadioButton_toggled ( true );
03182   allCutsRadioButton_toggled ( true );
03183 }
03184 
03185 int
03186 Inspector::
03187 findCutIndex ( const QString & label )
03188 {
03189   int index = -1;
03190 
03191   int size = m_selCutComboBox -> count ();
03192   for ( int i = 0; i < size; i++ ) {
03193     QString text = m_selCutComboBox -> text ( i );
03194     if ( text == label ) {
03195       index = i;
03196       break;
03197     }
03198   }
03199     return index;
03200 }
03201 
03202 void
03203 Inspector::
03204 updateCutsTab ()
03205 {
03206   if ( m_new_plot_box->isEnabled () == false ) return;
03207 
03208   PlotterBase * plotter = getPlotter ();
03209   bool yes = plotter != 0;
03210   m_new_cut_box->setEnabled ( yes );
03211 
03212   if ( yes ) yes = plotter -> isTargetable ();
03213   m_cut_selected_box->setEnabled ( yes );
03214 
03215   if ( yes ) {
03216     int id = cutRadioId ();
03217     bool is_fit_radio = id == 2;
03218     selectedCutsRadioButton_toggled (true  );
03219     allCutsRadioButton_toggled ( true );
03220 
03221     if ( is_fit_radio == false ) {
03222       updateDataCutsTab ();
03223     }
03224     else {
03225       updateFitCutsTab ();
03226     }
03227   }
03228 }
03229 
03230 void
03231 Inspector::
03232 updateFitCutsTab ()
03233 {
03234 }
03235 
03236 void
03237 Inspector::
03238 updateDataCutsTab ()
03239 {
03240   int id = cutRadioId ();
03241 
03242   if ( id == 0 ) {
03243     m_CutVariableComboBox2 -> setEnabled ( false );
03244   }
03245 
03246   PlotterBase * plotter = getPlotter ();
03247   DisplayController * controller = DisplayController::instance ();
03248   int index = controller->activeDataRepIndex ( plotter );
03249   if ( index < 0 ) {
03250     m_new_cut_box -> setDisabled ( true );
03251     m_cut_selected_box -> setDisabled ( true );
03252   }
03253   else {
03254     DataRep * datarep = plotter->getDataRep ( index );
03255     if ( datarep->hasZeroRows() )
03256       {
03257         m_new_cut_box->setDisabled ( true );
03258         m_cut_selected_box->setDisabled ( true );
03259         return;
03260       }
03261 
03262     m_new_cut_box->setDisabled ( false );
03263     const vector < PlotterBase * > & cuts = getDataCutList ( plotter );
03264     if ( cuts.empty() ) {
03265       m_cut_selected_box->setDisabled ( true );
03266     }
03267     else {
03268       m_cut_selected_box -> setDisabled ( false );
03269     }
03270   }
03271 
03272   updateCutVarGroupBox ( plotter, index );
03273 }
03274 
03275 void
03276 Inspector::
03277 setAllCutsActive ( bool yes )
03278 {
03279   vector < PlotterBase * > plotters;
03280   fillPlotterList ( plotters );
03281 
03282   if ( plotters.empty () == false ) {
03283     CutController * controller = CutController::instance ();
03284     vector < CutPlotter * > cutters;
03285     controller -> fillCutList ( plotters, cutters );
03286     vector < CutPlotter * > ::iterator first = cutters.begin ();
03287 
03288     while ( first != cutters.end () ) {
03289       CutPlotter * cutter = *first++;
03290       cutter -> setActive ( yes );
03291     }
03292   }
03293 }
03294 
03295 void
03296 Inspector::
03297 updateCutVarGroupBox ( const PlotterBase * plotter, int index )
03298 {
03299   const DataSource * tuple
03300     = DisplayController::instance() -> getDataSource ( plotter, index );
03301 
03302   if (!tuple) return;
03303   int index1 = -1;
03304   int index2 = -1;
03305   if ( m_CutVariableComboBox1 -> count() > 0 ) {
03306     index1 = m_CutVariableComboBox1 -> currentItem ();
03307   }
03308   if ( m_CutVariableComboBox2 -> count() > 0 ) {
03309     index2 = m_CutVariableComboBox2 -> currentItem ();
03310   }
03311   m_CutVariableComboBox1->clear();
03312   m_CutVariableComboBox2->clear();
03313 
03314   const vector < string > & cols = tuple->getLabels();
03315 #ifdef ITERATOR_MEMBER_DEFECT
03316   std::
03317 #endif
03318     vector < string > ::const_iterator first = cols.begin ();
03319   while ( first != cols.end() ) {
03320     const string & str = *first++;
03321     m_CutVariableComboBox1 -> insertItem ( str.c_str() );
03322     m_CutVariableComboBox2 -> insertItem ( str.c_str() );
03323   }
03324   if ( index1 >= m_CutVariableComboBox1 -> count () ) {
03325     index1 = 0;
03326   }
03327   if ( index2 >= m_CutVariableComboBox2 -> count () ) {
03328     index2 = 0;
03329   }
03330 
03331   if ( index1 >= 0 ) {
03332     m_CutVariableComboBox1 -> setCurrentItem ( index1 );
03333   }
03334   if ( index2 >= 0 ) {
03335     m_CutVariableComboBox2 -> setCurrentItem ( index2 );
03336   }
03337 
03338   cut_button_group -> setEnabled ( true );
03339   int id = cutRadioId ();
03340   if ( id == 1 ) {
03341     m_CutVariableComboBox2 -> setEnabled( true );
03342   }
03343 }
03344 
03345 int
03346 Inspector::
03347 cutRadioId () const
03348 {
03349   int id = -1;
03350   if ( m_cut_data1 -> isChecked () ) id = 0;
03351   if ( m_cut_data2 -> isChecked () ) id = 1;
03352   if ( m_cut_fit_radio -> isChecked () ) id = 2;
03353 
03354   return id;
03355 }
03356 
03357 void
03358 Inspector::
03359 cut_button_group_clicked ( )
03360 {
03361   int id = cutRadioId ();
03362 
03363   switch  ( id ) {
03364   case 0 : // 1d data cut
03365     m_CutVariableComboBox1 -> setEnabled ( true );
03366     m_CutVariableComboBox2 -> setEnabled ( false );
03367     break;
03368   case 1 : // 2d data cut
03369     m_CutVariableComboBox1 -> setEnabled ( true );
03370     m_CutVariableComboBox2 -> setEnabled ( true );
03371     break;
03372   case 2 : // fit cut
03373     m_CutVariableComboBox1 -> setEnabled ( false );
03374     m_CutVariableComboBox2 -> setEnabled ( false );
03375     break;
03376   }
03377 
03378   updateCutsTab (); // in case of switching from data to fitting
03379 }
03380 void
03381 Inspector::
03382   setSelectedFitter ( const std::string & name )
03383 {
03384   FunctionController * controller = FunctionController::instance ();
03385   const vector < string > & fitters = controller -> getFitterNames ();
03386   for ( unsigned int i = 0; i < fitters.size(); i++ ) {
03387     if ( name == fitters[i] )
03388       {
03389         m_fitter_names -> setCurrentItem ( i );
03390         break;
03391       }
03392   }
03393 }
03394 
03395 void
03396 Inspector::
03397 updateFunctionsTab ()
03398 {
03399   FunctionController * controller = FunctionController::instance ();
03400   const vector < string > & names = controller -> getFunctionNames ();
03401   int current = newFunctionsComboBox->currentItem ();
03402 
03403   if ( newFunctionsComboBox -> count () !=
03404        static_cast < int > ( names.size () ) ) {
03405     newFunctionsComboBox->clear();
03406 
03407     for ( unsigned int i = 0; i < names.size(); i++) {
03408       if ( names[i] != "Linear Sum" ) {
03409         newFunctionsComboBox->insertItem ( names[i].c_str() );
03410       }
03411     }
03412   }
03413 
03414   PlotterBase * plotter = getPlotter();
03415   bool yes = plotter != 0;
03416   m_func_new->setEnabled ( yes );
03417 
03418   if ( yes ) yes = plotter -> isTargetable ();
03419   functionsRemoveButton -> setEnabled ( yes );
03420   m_IgnoreErrorCheckBox -> setEnabled (yes);
03421   functionsFitToDataButton -> setEnabled ( yes );
03422   functionsResetButton -> setEnabled ( yes );
03423   m_resid->setEnabled ( yes );
03424   if ( yes == false ) {
03425     return;
03426   }
03427 
03428   const DataSource * nt
03429     = DisplayController::instance()->getDataSource ( plotter, 0 );
03430 
03431   if ( nt && nt -> empty () )
03432     {
03433       m_func_new->setDisabled ( true );
03434       functionsRemoveButton -> setEnabled ( false );
03435       m_IgnoreErrorCheckBox -> setDisabled (true);
03436       functionsFitToDataButton -> setEnabled ( false );
03437       functionsResetButton -> setEnabled ( false );
03438       return;
03439     }
03440 
03441   // Update new functions section //
03442   //------------------------------//
03443   newFunctionsAddButton->setEnabled ( true );
03444   m_func_new->setEnabled ( true );
03445 
03446   if ( current >= 0 ) {
03447     newFunctionsComboBox->setCurrentItem(current);
03448   }
03449   newFunctionsComboBox->setEnabled ( true );
03450 
03451   // Update functionsAppliedComboBox. //
03452   //----------------------------------//
03453   bool to_enable = false;
03454   DisplayController * d_controller = DisplayController::instance ();
03455   int index = d_controller -> activeDataRepIndex ( plotter );
03456 
03457   FunctionController * f_controller = FunctionController::instance ();
03458 
03459   if ( index >= 0 ) {
03460     DataRep * datarep = plotter ->getDataRep ( index );
03461     if ( f_controller -> hasFunction ( plotter, datarep ) ) {
03462 
03463       const vector < string > & fnames
03464         = f_controller -> functionNames ( plotter, datarep );
03465         
03466       if ( fnames.size() != 0 )
03467         {
03468           to_enable = true;
03469           m_functionIndexMap.clear();
03470         
03471           for ( unsigned i = 0; i < fnames.size(); i++)
03472             {
03473               if ( fnames[i].find ( "Linear Sum" ) == string::npos )
03474                 {
03475                   m_functionIndexMap.push_back ( i );
03476                 }
03477             }
03478         }
03479     }
03480   }
03481 
03482   functionsRemoveButton -> setEnabled ( to_enable );
03483   m_IgnoreErrorCheckBox -> setEnabled (to_enable);
03484   functionsFitToDataButton -> setEnabled ( to_enable );
03485   functionsResetButton -> setEnabled ( to_enable );
03486   if ( to_enable == false ) {
03487     m_FunctionParamsListView -> clear();
03488   }
03489 
03490   if ( to_enable )
03491     {
03492       Fitter * fitter = f_controller -> getFitter ( plotter );
03493       string name = "none";
03494       if ( fitter != 0 ) {
03495         name = f_controller -> getFitterName ( plotter );
03496         setSelectedFitter ( name );
03497       }
03498     }
03499 
03500   m_resid->setEnabled ( to_enable );
03501 
03502   // Update function parameters tab //
03503   //--------------------------------//
03504 
03505   // Set Parameters in list view as well as in line editor and
03506   // the check box. Focus is set to the current selected item
03507   // or in case none is selected 1st item.
03508   if ( to_enable ) setParameters ( index, plotter );
03509     
03510   // Set the slider to be in the center
03511   m_FunctionParamsSlider -> setValue(50);
03512 
03513 }
03514 
03515 void
03516 Inspector::
03517 functionsRemoveButton_clicked()
03518 {
03519   PlotterBase * plotter = getPlotter ();
03520   if ( !plotter ) return ;
03521 
03522   FunctionRep * frep = getFunctionRep ( );
03523   FunctionController * controller = FunctionController::instance ();
03524   controller -> removeFunction ( plotter, frep );
03525   if ( plotter->activePlotIndex ( ) != 0 )
03526     plotter->setActivePlot ( -1, true );
03527   else
03528     plotter->setActivePlot ( 0, true );
03529 
03530   // Update the rest.
03531   updateFunctionsTab();
03532 }
03533 
03534 void
03535 Inspector::
03536 functionsResetButton_clicked()
03537 {
03538   PlotterBase * plotter = getPlotter ();
03539   if ( !plotter ) return ;
03540 
03541   DisplayController * dcontroller = DisplayController::instance ();
03542   int index = dcontroller -> activeDataRepIndex ( plotter );
03543   if ( index < 0 ) return;
03544   DataRep * datarep = plotter -> getDataRep ( index );
03545 
03546   FunctionController * fcontroller = FunctionController::instance();
03547   if ( ! ( fcontroller -> hasFunction ( plotter, datarep ) ) ) {
03548     return;
03549   }
03550 
03551   fcontroller -> restoreParameters ( plotter );
03552 
03553   // Set the parameters
03554   setParameters ( index, plotter );
03555 }
03556 
03557 void
03558 Inspector::
03559 setParameters ( int index, PlotterBase * plotter )
03560 {
03561   m_FunctionParamsListView -> clear();
03562   m_FunctionParamsCheckBox -> setChecked( false );
03563   m_FunctionParamsLineEdit -> clear();
03564 
03565   DataRep * datarep = plotter -> getDataRep ( index );
03566   assert ( datarep != 0 );
03567 
03568   FunctionController * controller = FunctionController::instance ();
03569   if ( ! ( controller -> hasFunction ( plotter, datarep ) ) )
03570     {
03571       return;
03572     }
03573 
03574   const vector < string > & fnames
03575     = controller -> functionNames ( plotter, datarep );
03576 
03577   if ( fnames.empty () ) {
03578     return;
03579   }
03580 
03581   m_function_lv_map.clear ();
03582   vector < FunctionRep * > freps;
03583   controller -> fillTopLevelFunctionReps ( freps, plotter, datarep );
03584   for ( unsigned int i = 0; i < freps.size (); i++ ) {
03585     FunctionRep * frep = freps [ i ];
03586     const string & func_name = frep -> functionName ();
03587 
03588 #if QT_VERSION < 0x040000
03589     QListViewItem * parent
03590       = new QListViewItem ( m_FunctionParamsListView );
03591 #else
03592     Q3ListViewItem * parent
03593       = new Q3ListViewItem ( m_FunctionParamsListView );
03594 #endif
03595     parent -> setOpen ( true );
03596     parent -> setText ( Index, QString ( func_name.c_str() ) );
03597     m_function_lv_map [ parent ] = frep;
03598 
03599   //Ignore errors flag, conected with the ignoreError check box.
03600     bool ignoreFlag = true;
03601 
03602     Fitter * fitter = frep -> getFitter ();
03603     if ( fitter != 0 ) {
03604       //Get the ignore errors flag of the current function.
03605       ignoreFlag = frep -> getIgnoreErrors ();
03606     }
03607     const vector < double > & parms = frep -> parameters ();
03608     unsigned int start_index = parms.size();
03609     fillFunctionParameters ( parent, frep, start_index );
03610 
03611     m_FunctionParamsListView -> setAllColumnsShowFocus ( true );
03612 #if QT_VERSION < 0x040000
03613     QListViewItem * firstItem = parent -> firstChild ();
03614 #else
03615     Q3ListViewItem * firstItem = parent -> firstChild ();
03616 #endif
03617     m_IgnoreErrorCheckBox -> setChecked(ignoreFlag);
03618 
03619     if ( firstItem != 0 ) {
03620       m_FunctionParamsLineEdit -> setText ( firstItem -> text( Value ) );
03621       m_FunctionParamsListView -> setSelected ( firstItem, true );
03622       m_FunctionParamsListView -> setCurrentItem ( firstItem );
03623     
03624       QString fixedFlag = firstItem -> text( Fixed );
03625       m_FunctionParamsCheckBox->setChecked((fixedFlag == QString ( "Yes" ) ) ? 
03626                                            true : false );
03627     }
03628   }
03629 }
03630 
03631 void
03632 Inspector::
03633 #if QT_VERSION < 0x040000
03634 fillFunctionParameters ( QListViewItem * parent,
03635                          const FunctionRep * frep,
03636                          unsigned int & index )
03637 #else
03638 fillFunctionParameters ( Q3ListViewItem * parent,
03639                          const FunctionRep * frep,
03640                          unsigned int & index )
03641 #endif
03642 {
03643   const CompositeFunctionRep * composite
03644     = dynamic_cast < const CompositeFunctionRep * > ( frep );
03645 
03646   if ( composite != 0 ) {
03647     const vector < FunctionRep * > & freps 
03648       = composite -> getFunctionReps ();
03649     unsigned int size = freps.size();
03650 
03651     //  because children are inserted at the beginning, we must do things
03652     // backwards
03653     for ( int i = size -1; i >= 0; i-- ) {
03654       FunctionRep * rep = freps[i];
03655       const string & func_name = rep -> functionName ();
03656 #if QT_VERSION < 0x040000
03657       QListViewItem * child
03658         = new QListViewItem ( parent );
03659 #else
03660       Q3ListViewItem * child
03661         = new Q3ListViewItem ( parent );
03662 #endif
03663       child -> setOpen ( true );
03664       child -> setText ( Index, QString ( func_name.c_str() ) );
03665       m_function_lv_map [ child ] = rep;
03666 
03667       fillFunctionParameters ( child, rep, index );
03668     }
03669   }
03670   else { // not composite
03671     vector < FunctionParameter > function_parameters;
03672     frep -> fillFunctionParameters ( function_parameters );
03673 
03674     QString qyes( "Yes" );
03675     QString qno( "No" );
03676 
03677     // Because items are inserted at the begining, we must do things
03678     // backwards
03679     unsigned int size = function_parameters.size ();
03680 
03681     for ( int pindex = size-1; pindex >= 0; pindex-- ) {
03682       FunctionParameter fp = function_parameters[pindex];
03683       QString dummy;
03684 #if QT_VERSION < 0x040000
03685       QCheckListItem * item
03686         = new QCheckListItem ( parent, dummy,
03687                                QCheckListItem::CheckBox );
03688 #else
03689       Q3CheckListItem * item
03690         = new Q3CheckListItem ( parent, dummy,
03691                                 Q3CheckListItem::CheckBox );
03692 #endif
03693       item -> setText( Index, QString( "%1" ).arg( index-- ) );
03694 
03695       const string & name = fp.name ();
03696       QString pname = name.c_str();
03697       QString fixedFlag ( qno );
03698       fixedFlag = fp.isFixed () ? qyes : qno;
03699 
03700       item -> setText( Name, QString( "%1" ).arg( pname ) );
03701       item -> setText( Value, QString( "%1" ).arg( fp.value() ) );
03702       item -> setText( Error, QString( "%1" ).arg( fp.error() ));
03703       item -> setText( Fixed, QString( "%1" ).arg( fixedFlag ) );
03704       item -> setText( Dummy, QString( "%1" ).arg( pindex ) );
03705     }
03706   }
03707 }
03708 
03712 void
03713 Inspector::
03714 functionAdd ()
03715 {
03716   PlotterBase * plotter = getPlotter ();
03717   if ( !plotter ) return ;
03718 
03719   bool yes = plotter -> isTargetable ();
03720   if ( yes == false ) {
03721     multipleDataRepError ( "function" );
03722     return;
03723   }
03724 
03725   DisplayController * dc = DisplayController::instance();
03726 
03727   DataRep * datarep = dc -> activeDataRep ( plotter );
03728   assert ( datarep != 0 );
03729 
03730   if ( !datarep->acceptFunction(1) ){
03731     functionAddError ();
03732     return;
03733   }
03734 
03735   // Get the selected function name.
03736 
03737   QString qstr  =  newFunctionsComboBox->currentText();
03738   std::string fun_name = qstr.latin1();
03739 
03740   // Add the function.
03741 
03742   QString s = m_fitter_names -> currentText ( );
03743   const string fit_name = s.latin1();
03744 
03745   FunctionController * fc = FunctionController::instance();
03746   yes = fc -> isCompatible ( fun_name, fit_name );
03747 
03748   if ( yes == false ) {
03749     incompatibleFunctionError ( fun_name );
03750     return;
03751   }
03752 
03753   FunctionRep * new_rep = 0;
03754   try {
03755 #if QT_VERSION < 0x040000
03756     QListViewItem * item = m_FunctionParamsListView -> currentItem ();
03757 #else
03758     Q3ListViewItem * item = m_FunctionParamsListView -> currentItem ();
03759 #endif
03760     bool is_selected = m_FunctionParamsListView -> isSelected ( item );
03761     FunctionRep * frep = 0;
03762     if ( is_selected ) {
03763       frep = getTopFunctionRep ( item );
03764     }
03765 
03766     new_rep = fc->addFunction ( plotter, fun_name, frep, datarep );
03767   }
03768   catch ( std::exception & e ) {
03769     badFunctionError ( fun_name, e.what() );
03770   }
03771 
03772   int index = m_fitter_names -> currentItem ();
03773   fitterNamesActivated ( index ); // sets the fitter
03774 
03775   functionsRemoveButton -> setEnabled ( true );
03776   m_IgnoreErrorCheckBox -> setEnabled (true);
03777   functionsFitToDataButton -> setEnabled ( true );
03778   functionsResetButton -> setEnabled ( true );
03779   fc->saveParameters ( plotter );
03780 
03781   bool ok = false;
03782   if ( new_rep != 0 ) {
03783     ok = fc -> tryFitFunction ( plotter, new_rep ); // try fit
03784   }
03785   if ( ! ok ) {
03786     fitFailedError ();
03787   }
03788   // Update other tabs that need it.
03789 
03790   updateFunctionsTab();
03791 }
03792 
03793 void
03794 Inspector::
03795 fitterNamesActivated ( int index )
03796 {
03797   FunctionController * controller = FunctionController::instance ();
03798   const vector < string > & names = controller -> getFitterNames ();
03799   const string & def_fitter = names [ index ];
03800   controller -> setDefaultFitter ( def_fitter );
03801 
03802   PlotterBase * plotter = getPlotter ();
03803   if ( plotter != 0 ) {
03804     const DataRep * datarep = plotter -> getTarget ();
03805     bool yes = controller -> hasFunction ( plotter, datarep );
03806     if ( yes ) {
03807       bool ok = controller -> changeFitter ( plotter, datarep,
03808                                              def_fitter );
03809       if ( ok == false ) {
03810         incompatibleFitterError ( def_fitter );
03811         functionsFitToDataButton -> setEnabled ( false );
03812       }
03813       else {
03814         functionsFitToDataButton -> setEnabled ( true );
03815       }
03816     }
03817   }
03818 }
03819 
03820 void
03821 Inspector::
03822 fitFailedError ()
03823 {
03824   const QString message ( "The Fit failed to converge" );
03825   QMessageBox::critical ( this, // parent
03826                           "Fit failed",
03827                           message,
03828                           QMessageBox::Ok,
03829                           Qt::NoButton,
03830                           Qt::NoButton );
03831 }
03832 
03833 FunctionRep *
03834 Inspector::
03835 #if QT_VERSION < 0x040000
03836 getTopFunctionRep ( QListViewItem * item )
03837 #else
03838 getTopFunctionRep ( Q3ListViewItem * item )
03839 #endif
03840 {
03841   FunctionRep * rep = 0;
03842   if ( item != 0 ) {
03843     item = getTopParent ( item );
03844     rep = m_function_lv_map [ item ];
03845   }
03846   return rep;
03847 }
03848 
03849 FunctionRep *
03850 Inspector::
03851 #if QT_VERSION < 0x040000
03852 getFunctionRep ( QListViewItem * item )
03853 #else
03854 getFunctionRep ( Q3ListViewItem * item )
03855 #endif
03856 {
03857   FunctionRep * rep = 0;
03858   if ( item != 0 ) {
03859     rep = m_function_lv_map [ item ];
03860   }
03861   return rep;
03862 }
03863 
03864 FunctionRep *
03865 Inspector::
03866 getTopFunctionRep ()
03867 {
03868 #if QT_VERSION < 0x040000
03869   QListViewItem * item = m_FunctionParamsListView -> currentItem();
03870 #else
03871   Q3ListViewItem * item = m_FunctionParamsListView -> currentItem();
03872 #endif
03873 
03874   return getTopFunctionRep ( item );
03875 }
03876 
03877 FunctionRep *
03878 Inspector::
03879 getFunctionRep ()
03880 {
03881 #if QT_VERSION < 0x040000
03882   QListViewItem * item = m_FunctionParamsListView -> currentItem();
03883 #else
03884   Q3ListViewItem * item = m_FunctionParamsListView -> currentItem();
03885 #endif
03886 
03887   if ( item -> childCount() == 0 ) { // parameter item
03888     item = item -> parent ();
03889   }
03890 
03891   return getFunctionRep ( item );
03892 }
03893 
03894 void
03895 Inspector::
03896 functionsFitToDataButton_clicked()
03897 {
03898   PlotterBase * plotter = getPlotter ();
03899   if ( !plotter ) return ;
03900 
03901   FunctionController * fcnt = FunctionController::instance();
03902   if ( ! ( fcnt -> hasFunction ( plotter, 0 ) ) ) { // any function
03903     return;
03904   }
03905 
03906   fcnt -> saveParameters ( plotter );
03907 
03908   FunctionRep * fun_rep = getTopFunctionRep ();
03909 
03910   bool ok = fcnt -> fitFunction ( plotter, fun_rep );
03911   if ( ! ok ) {
03912     fitFailedError ();
03913   }
03914 
03915   // Set the parameters
03916   DisplayController * dcontroller = DisplayController::instance ();
03917   int index = dcontroller -> activeDataRepIndex ( plotter );
03918 
03919   setParameters ( index, plotter );
03920 }
03921 
03922 void
03923 Inspector::
03924 statsStripValue ( QRadioButton * box )
03925 {
03926   QString text_str = box -> text ();
03927   int i = text_str.find ( "=" );
03928   text_str.remove ( i + 1, 1024 );
03929   box -> setText ( text_str );
03930 }
03931 
03932 void Inspector::updateSummaryTab()
03933 {
03934   if ( m_new_plot_box->isEnabled() == false ) return;
03935 
03936   PlotterBase * plotter = getPlotter();
03937   bool yes = plotter == 0;
03938   if ( yes == false ) {
03939     TextPlotter * text = dynamic_cast < TextPlotter * > ( plotter );
03940     yes |= text != 0;
03941   }
03942   bool enable = ! yes;
03943   m_summary->setEnabled ( enable );
03944 
03945   if ( enable == false ) return;
03946 
03947   DisplayController * dcontroller = DisplayController::instance ();
03948   const DataSource * nt = dcontroller -> getDataSource ( plotter, 0 );
03949 
03950   if ( nt && nt -> empty ()  ) {
03951     m_summary->setEnabled ( false );
03952     return;
03953   }
03954 
03955   enable = false; // might be changed below...
03956   int index = dcontroller -> activeDataRepIndex ( plotter );
03957   if ( index >= 0 ) {
03958     DataRep * datarep = plotter -> getDataRep ( index );
03959     FunctionController * controller = FunctionController::instance();
03960 
03961     enable = controller->hasFunction ( plotter, datarep );
03962   }
03963   if ( enable == false ) {
03964     if ( m_stats_fparms->isChecked () ||
03965          m_stats_chi->isChecked () ) {
03966       m_stats_number->setChecked ( true );
03967     }
03968   }
03969 
03970   m_stats_fparms->setEnabled ( enable );
03971   m_stats_chi->setEnabled ( enable );
03972 
03973   yes = index < 0;
03974 
03975   m_stats_number->setDisabled ( yes );
03976   m_stats_underflow->setDisabled ( yes );
03977   m_stats_overflow->setDisabled ( yes );
03978   m_stats_avg_x->setDisabled ( yes );
03979   m_stats_avg_y->setDisabled ( yes );
03980   m_stats_text->setDisabled ( yes );
03981   yes = m_stats_text -> isChecked ();
03982   m_statsTextField ->setEnabled ( yes );
03983 
03984   statsStripValue ( m_stats_number );
03985   statsStripValue ( m_stats_underflow );
03986   statsStripValue ( m_stats_overflow );
03987   statsStripValue ( m_stats_avg_x );
03988   statsStripValue ( m_stats_avg_y );
03989 
03990   if ( index >= 0 ) {
03991     int number = dcontroller -> getNumberOfEntries ( plotter, index );
03992     QString text = m_stats_number -> text ();
03993     QString str;
03994     str.setNum ( number );
03995     text += " ";
03996     text += str;
03997     m_stats_number -> setText ( text );
03998 
03999     int underflow = dcontroller -> getUnderflow ( plotter, index );
04000     text = m_stats_underflow -> text ();
04001     if ( underflow == -1 ) str = "meaningless";
04002     else str.setNum ( underflow );
04003     text += " ";
04004     text += str;
04005     m_stats_underflow -> setText ( text );
04006 
04007     int overflow = dcontroller -> getOverflow ( plotter, index );
04008     text = m_stats_overflow -> text ();
04009     if ( overflow == -1 ) str = "meaningless";
04010     else str.setNum ( overflow );
04011     text += " ";
04012     text += str;
04013     m_stats_overflow -> setText ( text );
04014 
04015     double average = dcontroller -> getAverage ( plotter, Axes::X, index );
04016     text = m_stats_avg_x -> text ();
04017     str.setNum ( average );
04018     text += " ";
04019     text += str;
04020     m_stats_avg_x -> setText ( text );
04021 
04022     average = dcontroller -> getAverage ( plotter, Axes::Y, index );
04023     text = m_stats_avg_y -> text ();
04024     str.setNum ( average );
04025     text += " ";
04026     text += str;
04027     m_stats_avg_y -> setText ( text );
04028   }
04029 
04030 }
04031 
04032 void
04033 Inspector::
04034 statsButtonGroupClicked ( int )
04035 {
04036   bool yes = m_stats_text -> isChecked ();
04037   m_statsTextField -> setEnabled ( yes );
04038 }
04039 
04041 void Inspector::
04042 summaryNew ()
04043 {
04044   PlotterBase * plotter = getPlotter ();
04045   if ( !plotter ) return;
04046 
04047   DisplayController * d_controller = DisplayController::instance ();
04048   int index = d_controller->activeDataRepIndex ( plotter );
04049   if ( index < 0 ) {
04050     multipleDataRepError ( "summary" );
04051     return;
04052   }
04053 
04054   CanvasWindow * canvas = WindowController::instance () ->currentCanvas();
04055 
04056   string nullstring ("");
04057 
04058   if ( m_stats_number->isChecked() )
04059     {
04060       const string s ("Total Entries");
04061       canvas->addTextDisplay ( plotter, s, nullstring );
04062     }
04063 
04064   else if ( m_stats_underflow->isChecked() )
04065     {
04066       const string s ("Underflow");
04067       canvas->addTextDisplay ( plotter, s, nullstring );
04068     }
04069   
04070   else if ( m_stats_overflow->isChecked() )
04071     {
04072       const string s ("Overflow");
04073       canvas->addTextDisplay ( plotter, s, nullstring );
04074     }
04075 
04076   else if ( m_stats_avg_x->isChecked() )
04077     {
04078       const string s ("averagex");
04079       canvas->addTextDisplay ( plotter, s, nullstring );
04080     }
04081 
04082   else if ( m_stats_avg_y->isChecked() )
04083     {
04084       const string s ("averagey");
04085       canvas->addTextDisplay ( plotter, s, nullstring );
04086     }
04087 
04088   else if ( m_stats_fparms->isChecked() )
04089     {
04090       const string s ("Function Parameters");
04091       FunctionController * controller = FunctionController::instance ();
04092       assert ( controller -> hasFunction ( plotter, 0 ) );
04093       canvas->addFuncDisplay ( plotter, s );
04094 
04095     }
04096 
04097   else if ( m_stats_chi->isChecked() )
04098     {
04099       const string s ("Chi-squared");
04100       FunctionController * controller = FunctionController::instance ();
04101       assert ( controller -> hasFunction ( plotter, 0 ) );
04102       canvas->addFuncDisplay ( plotter, s );
04103 
04104     }
04105 
04106   else if ( m_stats_text->isChecked() )
04107   {
04108 
04109       QString qtext = m_statsTextField->text();
04110       const string t = qtext.latin1();
04111     bool needMargin = String::ci_find(t, "tex:")==0;  
04112     if ( needMargin ) {
04113 #ifdef HAVE_TEX_UTILS
04114 #else
04115         qtext.remove (0, 4);
04116         warningTex ();
04117 #endif
04118     }
04119     string text (qtext.latin1());
04120     const string s ("Text From Box");
04121     canvas->addTextDisplay ( plotter, s, text );
04122   }
04123 }
04124 
04127 void Inspector::createResiduals()
04128 {
04129   PlotterBase * plotter = getPlotter ();
04130   if ( plotter == 0 ) return;
04131 
04132   FunctionRep * func_rep = getTopFunctionRep ();
04133   FunctionController * controller = FunctionController::instance ();
04134   PlotterBase * res_plotter 
04135     = controller -> createResidualsDisplay ( plotter, func_rep );
04136   const Range & range = plotter -> getRange ( Axes::X, false );
04137   res_plotter -> setRange ( Axes::X, range, false );
04138 
04139   CanvasWindow * canvas = WindowController::instance () -> currentCanvas ();
04140 
04141   canvas -> addPlotDisplay ( res_plotter, true );
04142 }
04143 
04144 void Inspector::
04145 fillCheckedFunctionRepItems ( )
04146 {
04147   m_func_parm_checked.clear ();
04148 
04149 #if QT_VERSION < 0x040000
04150   QListViewItemIterator it ( m_FunctionParamsListView );
04151 #else
04152   Q3ListViewItemIterator it ( m_FunctionParamsListView );
04153 #endif
04154   while ( it.current () ) {
04155 #if QT_VERSION < 0x040000
04156     QListViewItem * item = it.current ();
04157     QCheckListItem * check_item = dynamic_cast < QCheckListItem * > ( item );
04158 #else
04159     Q3ListViewItem * item = it.current ();
04160     Q3CheckListItem * check_item = dynamic_cast < Q3CheckListItem * > ( item );
04161 #endif
04162     if ( check_item != 0 ) {
04163       bool yes = check_item -> isOn ();
04164       if ( yes ) {
04165         m_func_parm_checked.push_back ( item );
04166       }
04167     }
04168     ++it;
04169   }
04170 }
04171 
04176 void
04177 Inspector::
04178 pushButtonNewErrorPlotClicked()
04179 {
04180   PlotterBase * plotter = getPlotter ();
04181   if ( plotter == 0 ) return;
04182 
04183   FunctionController * fcontroller = FunctionController::instance ();
04184 
04185   fillCheckedFunctionRepItems ();
04186   if ( m_func_parm_checked.size () != 2 ) {
04187     const QString
04188       message ( "Two and only two function parameters should be\n"
04189                 "checked to create error contour display.\n" );
04190       QMessageBox::critical( this, // parent
04191                              "Invalid parameter pair selection", // caption
04192                              message,
04193                              QMessageBox::Ok,
04194                              Qt::NoButton,
04195                              Qt::NoButton );
04196       return;
04197     }
04198 
04199 #if QT_VERSION < 0x040000
04200   QListViewItem * first = m_func_parm_checked[0];
04201   QListViewItem * second = m_func_parm_checked[1];
04202 #else
04203   Q3ListViewItem * first = m_func_parm_checked[0];
04204   Q3ListViewItem * second = m_func_parm_checked[1];
04205 #endif
04206   if ( getTopParent ( first ) != getTopParent ( second ) ) {
04207     const QString message = 
04208       "Both checked function parameters must\n"
04209       "have same parent function.";
04210     QMessageBox::critical( this, // parent
04211                            "Invalid parameter pair selection", // caption
04212                            message,
04213                            QMessageBox::Ok,
04214                            Qt::NoButton,
04215                            Qt::NoButton );
04216     return;
04217   }
04218   QString text = first -> text ( Index );
04219   bool ok = true;
04220   int index = text.toInt ( & ok ) - 1;
04221   fcontroller -> setEllpsoidParamIndex ( Axes::X , index );
04222 
04223   text = second -> text ( Index );
04224   ok = true;
04225   index = text.toInt ( & ok ) -1 ;
04226   fcontroller -> setEllpsoidParamIndex ( Axes::Y , index );
04227 
04228   // Create / refresh the error plot
04229   const QString xlabel = first -> text ( Name );
04230   const QString ylabel = second -> text ( Name );
04231   QString stat = m_PushButtonNewErrorPlot -> text();
04232 #if QT_VERSION < 0x040000
04233   QListViewItem * parent = getTopParent ( first );
04234 #else
04235   Q3ListViewItem * parent = getTopParent ( first );
04236 #endif
04237   FunctionRep * frep = m_function_lv_map [ parent ];
04238   if( stat == QString( "Change Error Plot" ) )
04239     {
04240       fcontroller -> refreshEllipsoidDisplay ( plotter, frep );
04241       plotter -> setLabel( Axes::X, xlabel.latin1() );
04242       plotter -> setLabel( Axes::Y, ylabel.latin1() );
04243     }
04244   else // "New Error Plot"
04245     {
04246       PlotterBase * err_plotter =
04247         fcontroller -> createNewEllipsoidDisplay ( plotter, frep );
04248       assert( err_plotter != 0);
04249 
04250       err_plotter -> setLabel( Axes::X, xlabel.latin1() );
04251       err_plotter -> setLabel( Axes::Y, ylabel.latin1() );
04252 
04253       CanvasWindow * canvas
04254         = WindowController::instance () -> currentCanvas ();
04255       assert( canvas != 0 );
04256 
04257       // Add the plot to the display BUT donot select it. Let mother
04258       // plot be the one which is selected.
04259       canvas -> addPlotDisplay ( err_plotter, false );
04260     }
04261 }
04262 
04263 const std::string
04264 Inspector::
04265 convertToString ( hippodraw::Axes::Type axis )
04266 {
04267   if ( axis == Axes::X ) return "X";
04268   else if ( axis == Axes::Y ) return "Y";
04269   else if ( axis == Axes::Z ) return "Z";
04270 
04271   return "nil";
04272 }
04273 
04274 void
04275 Inspector::
04276 updateLogBox ()
04277 {
04278   bool yes = m_plotter_list.empty () == false;
04279 
04280   logScale -> setEnabled ( yes );
04281   if ( yes ) {
04282     PlotterBase * plotter = m_plotter_list.front ();
04283     bool log = DisplayController::instance () -> getLog ( plotter, m_axis );
04284     logScale -> setChecked ( log );
04285   }
04286 }
04287 
04288 void
04289 Inspector::
04290 updateAutoScaleBox ()
04291 {
04292   bool yes = m_plotter_list.empty () == false;
04293   m_autoScale -> setEnabled ( yes );
04294   if ( yes ) {
04295     PlotterBase * plotter = m_plotter_list.front ();
04296     bool scaled = plotter -> isAutoRanging ( m_axis );
04297     m_autoScale -> setChecked ( scaled );
04298   }
04299 }
04300 
04301 void
04302 Inspector::
04303 updateReverseBox ()
04304 {
04305   bool yes = ( m_plotter_list.empty () == false ) 
04306     && ( m_axis == Axes::X );
04307   m_reverse -> setEnabled ( yes );
04308 
04309   if ( yes ) {
04310     PlotterBase * plotter = m_plotter_list.front ();
04311     bool reversed = plotter -> isReverse ();
04312     m_reverse -> setChecked ( reversed );
04313   }
04314 }
04315 
04322 void
04323 Inspector::
04324 updateAxisTab ()
04325 {
04326   updateLogBox ();
04327   updateAutoScaleBox ();
04328   updateReverseBox ();
04329 
04330   PlotterBase * plotter = getPlotter ();
04331   bool yes = plotter == 0;
04332   if ( yes == false ) {
04333     TextPlotter * text = dynamic_cast < TextPlotter * > ( plotter );
04334     yes |= text != 0;
04335   }
04336   m_axis_frame->setEnabled ( ! yes );
04337 
04338   if ( yes ) return;
04339 
04340   DisplayController * controller = DisplayController::instance ();
04341   int index = -1;
04342   if ( plotter -> isTargetable () ) {
04343     index = controller->activeDataRepIndex ( plotter );
04344   }
04345 
04346   bool has_ntuple = controller->hasNTupleBindings ( plotter, 0 );
04347   if ( has_ntuple )
04348     {
04349       const DataSource * nt
04350         = DisplayController::instance() -> getDataSource ( plotter, 0 );
04351       if ( nt && nt -> empty () ) return;
04352     }
04353 
04354   if ( plotter -> hasAxis ( m_axis ) == false ) setZRadioButton ( false );
04355   bool enabled =  plotter -> hasAxis ( Axes::Z );
04356   setZRadioButton ( enabled );
04357 
04358   const string & label = plotter -> getLabel ( m_axis );
04359   const QString ltext = label.c_str();
04360   m_axis_label -> setText ( ltext );
04361 
04362   const string s_axis = convertToString ( m_axis );
04363   bool axis_bined = controller -> isAxisBinned ( plotter, s_axis );
04364   const Range & r = plotter->getRange(m_axis, true);
04365   double low = r.low();
04366   double high = r.high();
04367 
04368   axisWidget1 -> setLowText ( QString("%1").arg(low),
04369                               axis_bined == true &&
04370                               has_ntuple == false );
04371   axisWidget1 -> setHighText ( QString("%1").arg(high),
04372                                axis_bined == true &&
04373                                has_ntuple == false );
04374 
04375   axisWidget1 -> setLowSliderValue( 50 );
04376   m_lowslider1_last_val = 50;
04377   axisWidget1 -> setHighSliderValue( 50 );
04378   m_highslider1_last_val = 50;
04379 
04380   if (getMinEntries()==-1) {
04381     m_combine_checkbox->setEnabled( false );
04382     min_entries_text->setEnabled ( false );
04383     min_entries_slider->setEnabled ( false );
04384   }
04385 
04386   else {
04387     m_combine_checkbox->setEnabled( true );
04388 
04389     if ( m_combine_checkbox->isChecked() )
04390       { 
04391         min_entries_text->setEnabled ( true );
04392         min_entries_slider->setEnabled ( true );
04393         unsigned int min = getMinEntries();
04394         min_entries_text->setText( QString ("%1").arg(min) );
04395         min_entries_slider->setValue (50);
04396       }
04397     else
04398       {
04399         min_entries_text->setEnabled ( false );
04400         min_entries_slider->setEnabled ( false );
04401         unsigned int min = getMinEntries();
04402         min_entries_text->setText( QString ("%1").arg(min) );
04403         min_entries_slider->setValue ( 50 );
04404       }
04405   }
04406 
04407 
04408 
04409 
04410   if (  axis_bined == false )
04411     {
04412       m_width_text->setEnabled ( false );
04413       m_width_range->setEnabled ( false );
04414       m_width_text -> setText ( QString ("%1").arg (0) );
04415 
04416       m_offset_text->setEnabled ( false );
04417       m_offset_range->setEnabled ( false );
04418       m_offset_text -> setText ( QString ("%1").arg (0) );
04419     }
04420   else
04421     {
04422       m_width_text->setEnabled ( true );
04423       m_width_range->setEnabled ( true );
04424       double width = plotter->getBinWidth ( m_axis );
04425       m_width_text -> setText ( QString ("%1").arg (width) );
04426 
04427       m_offset_text->setEnabled ( true );
04428       m_offset_range->setEnabled ( true );
04429       double offset = plotter->getOffset ( m_axis );
04430       m_offset_text -> setText ( QString ("%1").arg (offset) );
04431 
04432       // make read only if not bound to ntuple
04433       m_width_text->setReadOnly ( ! has_ntuple );
04434       m_width_range->setEnabled ( has_ntuple );
04435       m_offset_text->setReadOnly ( ! has_ntuple );
04436       m_offset_range->setEnabled ( has_ntuple );
04437     }
04438 
04439   //----------------------------//
04440   // Handling the log check box //
04441   //----------------------------//
04442   bool disable_log = has_ntuple == false && axis_bined == true;
04443   logScale -> setDisabled ( disable_log );
04444   m_autoScale -> setDisabled ( disable_log );
04445 
04446   const PeriodicBinaryTransform *pbtf =
04447     dynamic_cast < const PeriodicBinaryTransform * >
04448     ( plotter->getTransform() );
04449 
04450   if( pbtf == 0   ) {
04451     bool log = DisplayController::instance() -> getLog ( plotter, m_axis );
04452 
04453     if( log )
04454       {
04455         m_offset_text -> setEnabled( false );
04456         m_offset_range -> setEnabled( false );
04457       }
04458   }
04459 
04460 
04461   axisWidget1->setAllDisabled ( false );
04462 
04463   //--------------------------------//
04464   // Handling of zoom pan check box //
04465   //--------------------------------//
04466   bool isZoomPan = false;
04467 
04468   std::map < const PlotterBase *, bool >::const_iterator it
04469     = m_zoompan.find ( plotter );
04470   if ( it != m_zoompan.end () )
04471     isZoomPan = it->second;
04472 
04473   // By defalut for periodic binary transforms (pbtf) zoom pan mode should
04474   // be set for both X and Y axis. For Z axis setting zoom pan mode does
04475   // not make sense.
04476   if( pbtf != 0 && m_axis != Axes::Z) {
04477     axisWidget1->setZoomPan ( true, true );
04478   }
04479   else {
04480     if ( m_axis == Axes::Z ) {
04481       axisWidget1 -> setZoomPan ( false, true ); //disables it
04482     }
04483     else {
04484       axisWidget1->setZoomPan ( isZoomPan );
04485     }
04486   }
04487 
04488   axisWidget1->processZoomPanCheckBoxClicked ( r, r );
04489 
04490   yes = false;
04491   if ( index >= 0 ) {
04492     const DataRep * datarep = plotter -> getDataRep ( index );
04493     RepBase * rep = datarep -> getRepresentation ();
04494     ContourPointRep * contourRep = dynamic_cast < ContourPointRep * > ( rep );
04495     yes = contourRep != 0;
04496     if ( yes ) {
04497       bool user = contourRep->getUsingUserValues();
04498       contourRadioButton1->setChecked ( !user );
04499       contourRadioButton2->setChecked ( user );
04500       contourRadioButton1_toggled ( true );
04501     }
04502   }
04503 
04504   m_contourBox->setEnabled ( yes );
04505 }
04506 
04507 
04511 #if QT_VERSION < 0x040000
04512 void Inspector::functionParamsListViewCurrentChanged ()
04513 #else
04514 void Inspector::functionParamsListViewCurrentChanged ()
04515 #endif
04516 {
04517 #if QT_VERSION < 0x040000
04518   QListViewItem * item = m_FunctionParamsListView -> currentItem ();
04519 #else
04520   Q3ListViewItem * item = m_FunctionParamsListView -> currentItem ();
04521 #endif
04522   bool is_selected = m_FunctionParamsListView -> isSelected ( item );
04523   bool is_parm = item -> childCount () == 0;
04524   bool enable = is_selected && is_parm;
04525 
04526   m_FunctionParamsCheckBox -> setEnabled ( enable );
04527   m_FunctionParamsLineEdit -> setEnabled ( enable );
04528   m_FunctionParamsSlider -> setEnabled ( enable );
04529 
04530   if ( enable ) {
04531     QString fixedFlag = item -> text( Fixed );
04532     QString qyes( "Yes" );
04533     m_FunctionParamsCheckBox ->
04534       setChecked(( fixedFlag == qyes ) ? true : false );
04535     m_FunctionParamsLineEdit -> setText ( item -> text( Value ) );
04536   }
04537 
04538   enable = is_selected && (! is_parm);
04539   functionsRemoveButton -> setEnabled ( enable );
04540 
04541 }
04542 #if QT_VERSION < 0x040000
04543 QListViewItem *
04544 Inspector::
04545 getTopParent ( QListViewItem * item ) 
04546 {
04547   QListViewItem * parent = item;
04548   while ( true ) {
04549     QListViewItem * t = parent -> parent ();
04550     if ( t == 0 ) break;
04551     parent = t;
04552   }
04553 #else
04554 Q3ListViewItem *
04555 Inspector::
04556 getTopParent ( Q3ListViewItem * item ) 
04557 {
04558   Q3ListViewItem * parent = item;
04559   while ( true ) {
04560     Q3ListViewItem * t = parent -> parent ();
04561     if ( t == 0 ) break;
04562     parent = t;
04563   }
04564 #endif
04565   return  parent;
04566 }
04567 
04570 void
04571 Inspector::
04572 functionParamsCheckBoxToggled( bool )
04573 {
04574   PlotterBase * plotter = getPlotter();
04575   if ( !plotter ) return;
04576 
04577   FunctionController * fcontroller = FunctionController::instance();
04578   if ( ! ( fcontroller -> hasFunction ( plotter, 0 ) ) ) {
04579     return;
04580   }
04581 
04582   fcontroller -> saveParameters ( plotter );
04583 
04584 #if QT_VERSION < 0x040000
04585   QListViewItem * item = m_FunctionParamsListView -> currentItem();
04586 #else
04587   Q3ListViewItem * item = m_FunctionParamsListView -> currentItem();
04588 #endif
04589   if( !item ) return;
04590 
04591   FunctionRep * frep = getTopFunctionRep ( item );
04592 
04593   vector < int > fixed = frep -> getFixedFlags ();
04594 
04595   QString pidx = item -> text( Index ); // As a hack we hide in the 5th place
04596   int paramindex = pidx.toUInt() - 1;   // the index of the parameter
04597 
04598   // Set the new fixed flag for the function
04599   bool flag = m_FunctionParamsCheckBox -> isChecked();
04600 
04601   fixed[ paramindex ] = flag == true ? 1 : 0;
04602   frep -> setFixedFlags( fixed );
04603 
04604   if ( item -> childCount () == 0 ) {
04605     QString qyes ( "Yes" );
04606     QString qno ( "No" );
04607     QString fixedFlag = ( flag == true ) ? qyes : qno;
04608     item -> setText ( Fixed, fixedFlag );
04609   }
04610 
04611 }
04612 
04613 
04617 void Inspector::functionParamsLineEditReturnPressed()
04618 {
04619   // Check if there is plotter.
04620   PlotterBase * plotter = getPlotter();
04621   if ( !plotter ) return;
04622 
04623   // Check if there is a function attached to this plotter.
04624   FunctionController * fcontroller = FunctionController::instance();
04625   if ( ! ( fcontroller -> hasFunction ( plotter, 0 ) ) )
04626     return;
04627 
04628   // Save old parameters
04629   fcontroller -> saveParameters ( plotter );
04630 
04631   // Get the current item and item-number
04632 #if QT_VERSION < 0x040000
04633   QListViewItem * item = m_FunctionParamsListView -> currentItem();
04634 #else
04635   Q3ListViewItem * item = m_FunctionParamsListView -> currentItem();
04636 #endif
04637   if( !item ) return;
04638 
04639   QString pidx = item -> text( Index );
04640   int paramindex = pidx.toUInt() -1;   // the index of the parameter
04641 
04642   FunctionRep * frep = getTopFunctionRep ( item );
04643   vector < double >  parameters = frep-> parameters();
04644 
04645   // Set the new fixed flag for the function
04646   QString text = m_FunctionParamsLineEdit -> text();
04647   parameters[ paramindex ] = text.toDouble();
04648   frep  -> setParameters( parameters );
04649   frep  -> setDirty();
04650 
04651   // Change the new parameter in ListView
04652   item -> setText ( Value, QString ( "%1" ).arg ( parameters[ paramindex ] ) );
04653 }
04654 
04655 
04659 void
04660 Inspector::
04661 functionParamsSliderSliderPressed()
04662 {
04663   PlotterBase * plotter = getPlotter();
04664   if ( !plotter ) return;
04665 
04666   FunctionController * fcontroller = FunctionController::instance();
04667   if ( ! ( fcontroller -> hasFunction ( plotter, 0 ) ) )
04668     return;
04669 
04670   // Save old parameters
04671   fcontroller -> saveParameters ( plotter );
04672 
04673   FunctionRep * frep = getTopFunctionRep ( );
04674 
04675   if ( frep != 0 ) {
04676     m_oldParameters = frep -> parameters ();
04677   }
04678 }
04679 
04680 
04684 void
04685 Inspector::
04686 functionParamsSliderSliderMoved( int )
04687 {
04688   PlotterBase * plotter = getPlotter();
04689   if ( !plotter ) return;
04690 
04691   FunctionController * fcontroller = FunctionController::instance();
04692   if ( ! ( fcontroller -> hasFunction ( plotter, 0 ) ) )
04693     return;
04694 
04695 #if QT_VERSION < 0x040000
04696   QListViewItem * item = m_FunctionParamsListView -> currentItem();
04697 #else
04698   Q3ListViewItem * item = m_FunctionParamsListView -> currentItem();
04699 #endif
04700 
04701   if( !item ) return;
04702 
04703   QString pidx = item -> text( Index );
04704   int paramindex = pidx.toUInt() - 1;   // the index of the parameter
04705 
04706   vector < double > newParameters = m_oldParameters;
04707 
04708   int sliderValue = m_FunctionParamsSlider -> value();
04709   int sign = ( m_oldParameters[ paramindex ] < 0 )? -1:1;
04710 
04711   newParameters[ paramindex ]
04712     = m_oldParameters[ paramindex ] *
04713     pow ( 2.0,  static_cast<double>( (sliderValue - 50) * sign) / 50.0 );
04714 
04715   FunctionRep * frep   = getTopFunctionRep ( item );
04716   frep -> setParameters( newParameters ); // will set projector dirty
04717 
04718   item -> setText( Value, QString ( "%1" ).arg ( newParameters[ paramindex ]));
04719   m_FunctionParamsLineEdit ->
04720     setText ( QString ( "%1" ).arg ( newParameters[ paramindex ] ) );
04721 }
04722 
04725 void
04726 Inspector::
04727 functionParamsSliderSliderReleased()
04728 {
04729   m_FunctionParamsSlider -> setValue(50);
04730 }
04731 
04732 void 
04733 Inspector::
04734 invalidOperationError ( const string & message )
04735 {
04736   QMessageBox::critical ( this,  // parent )
04737                             "Operation error", // caption
04738                             message.c_str(), // message
04739                             QMessageBox::Ok,
04740                             Qt::NoButton,
04741                             Qt::NoButton );
04742 }
04743 
04747 void Inspector::logScale_clicked()
04748 {
04749   bool log = logScale -> isChecked();
04750   bool auto_scale = m_autoScale -> isChecked ();
04751 
04752   vector < PlotterBase * > ::iterator first = m_plotter_list.begin ();
04753 
04754   while ( first != m_plotter_list.end () ) {
04755     PlotterBase * plotter = *first++;
04756     try {
04757       DisplayController::instance()-> setLog ( plotter, m_axis, log );
04758       plotter -> setAutoRanging ( m_axis, auto_scale );
04759     }
04760     catch ( const runtime_error & e ) {
04761       invalidOperationError ( e.what () );
04762     }
04763   }
04764 
04765   updateAxisTab ();
04766 }
04767 
04768 void Inspector::reverse_clicked()
04769 {
04770   bool reverse = m_reverse -> isChecked();
04771 
04772   vector < PlotterBase * > ::iterator first = m_plotter_list.begin ();
04773 
04774   while ( first != m_plotter_list.end () ) {
04775     PlotterBase * plotter = *first++;
04776     plotter -> setReverse ( reverse );
04777   }
04778 
04779   updateAxisTab ();
04780 }
04781 
04782 void Inspector::autoScale_clicked()
04783 {
04784   bool scale = m_autoScale -> isChecked ();
04785   vector < PlotterBase * > ::iterator first = m_plotter_list.begin ();
04786 
04787   while ( first != m_plotter_list.end () ) {
04788     PlotterBase * plotter = *first++;
04789     plotter -> setAutoRanging ( m_axis, scale );
04790 
04791     // If the transform be periodic it sets both the offsets to be 0.0
04792     PeriodicBinaryTransform * tp =
04793       dynamic_cast< PeriodicBinaryTransform* > ( plotter->getTransform() );
04794     if ( tp != 0 )
04795       {
04796         tp->setXOffset( 0.0 );
04797         tp->setYOffset( 0.0 );
04798       }
04799   }
04800 
04801   updateAxisTab();
04802 }
04803 
04804 void Inspector::cutHighSlider_sliderMoved ( int value )
04805 {
04806   if ( m_is_updating == false ) {
04807     int index = m_selCutComboBox -> currentItem ();
04808     Range currentRange = m_tuple_cuts [ index] -> getRange ();
04809     int id = cutRadioId ();
04810     bool fit_cut = id == 2;
04811 
04812     if ( fit_cut == false ) { //data cut
04813       Axes::Type axis = getAxes ( index );
04814       PlotterBase * plotter = getSelectedCut();
04815       const Range & fullRange = plotter -> getRange ( axis, false );
04816       axisWidget2 -> processHighSliderMoved ( value, currentRange, fullRange );
04817       plotter -> setCutRangeAt ( currentRange, axis );
04818     }
04819     else { // fit cut
04820       PlotterBase * plotter = getPlotter ();
04821       const Range & fullRange = plotter -> getRange ( Axes::X, false );
04822       axisWidget2 -> processHighSliderMoved ( value, currentRange, fullRange );
04823       plotter -> setCutRangeAt ( currentRange, index );
04824     }
04825   }
04826 }
04827 
04828 void Inspector::cutLowSlider_sliderMoved ( int value )
04829 {
04830   if ( m_is_updating == false ) {
04831     int index = m_selCutComboBox -> currentItem ();
04832     Range currentRange = m_tuple_cuts [ index ] -> getRange ();
04833 
04834     bool fit_cut = cutRadioId () == 2;
04835 
04836     if ( fit_cut == false ) { //data cut
04837       Axes::Type axis = getAxes ( index );
04838       PlotterBase * plotter = getSelectedCut();
04839       const Range & fullRange = plotter -> getRange ( axis, false );
04840       axisWidget2 -> processLowSliderMoved ( value, currentRange, fullRange );
04841       plotter -> setCutRangeAt ( currentRange, axis );
04842     }
04843     else { // fit cut
04844       PlotterBase * plotter = getPlotter ();
04845       const Range & fullRange = plotter -> getRange ( Axes::X, false );
04846       axisWidget2 -> processLowSliderMoved ( value, currentRange, fullRange );
04847       plotter -> setCutRangeAt ( currentRange, index );
04848     }
04849   }
04850 }
04851 
04852 void Inspector::cutLowSlider_sliderReleased()
04853 {
04854   PlotterBase * cd = getSelectedCut();
04855   if ( cd == 0 ) return;
04856   int index = m_selCutComboBox -> currentItem ();
04857   Axes::Type axis = getAxes ( index );
04858   const Range & fullRange = cd->getRange ( axis, false );
04859   axisWidget2->processLowSliderReleased ( fullRange );
04860 }
04861 
04862 void Inspector::cutHighSlider_sliderReleased()
04863 {
04864   PlotterBase * cd = getSelectedCut();
04865   if ( cd == 0 ) return;
04866   int index = m_selCutComboBox -> currentItem ();
04867   Axes::Type axis = getAxes ( index );
04868   const Range & fullRange = cd->getRange ( axis, false );
04869   axisWidget2->processHighSliderReleased ( fullRange );
04870 }
04871 
04872 void Inspector::cutZoomPanCheckBox_clicked()
04873 {
04874   PlotterBase * plotter = getSelectedCut();
04875 
04876   int index = m_selCutComboBox -> currentItem ();
04877   int id = cutRadioId ();
04878   bool fit_cut = id ==2;
04879 
04880   Axes::Type axis = Axes::X;
04881   if ( fit_cut == false ) {
04882     axis = getAxes ( index );
04883   }
04884   bool yes = axisWidget2 -> isZoomPanChecked ();
04885   CutController * controller = CutController::instance ();
04886   controller -> setZoomPan ( plotter, axis, yes );
04887 
04888   Range currentRange = m_tuple_cuts [ index ] -> getRange ();
04889   const Range & fullRange = plotter -> getRange ( axis, false );
04890 
04891   axisWidget2 -> processZoomPanCheckBoxClicked ( currentRange, fullRange ) ;
04892 }
04893 
04894 
04895 void Inspector::cutInvertPushButton_clicked()
04896 {
04897   int id = cutRadioId ();
04898   bool fit_cut = id == 2;
04899 
04900   if ( fit_cut == false ) { //data cut
04901     PlotterBase * plotter = getSelectedCut ();
04902     CutPlotter * cp = dynamic_cast < CutPlotter * > ( plotter );
04903     cp -> toggleInverted ();
04904   }
04905   else {
04906     int index = m_selCutComboBox -> currentItem ();
04907     bool state = ! m_tuple_cuts [ index ] -> getInversion ();
04908     PlotterBase * plotter = getPlotter ();
04909     XyPlotter * xyplotter = dynamic_cast < XyPlotter * > ( plotter );
04910     xyplotter -> setCutInverted ( index, state );
04911   }
04912 }
04913 
04914 void
04915 Inspector::
04916 cutEnablePushButton_toggled ( bool on)
04917 {
04918   if ( m_cut_enable_updating == true ) return;
04919   
04920   bool fit_cut = cutRadioId () == 2;
04921 
04922   if ( fit_cut == false ) { //data cut
04923     PlotterBase * plotter = getSelectedCut ();
04924     CutPlotter * cut_plotter = dynamic_cast < CutPlotter * > ( plotter );
04925     cut_plotter -> setEnabled ( ! on );
04926   }
04927   else {
04928     int index = m_selCutComboBox -> currentItem ();
04929     PlotterBase * plotter = getPlotter ();
04930     XyPlotter * xyplotter = dynamic_cast < XyPlotter * > ( plotter );
04931     xyplotter -> setCutEnabled ( index, ! on );
04932   }
04933 }
04934 
04935 void
04936 Inspector::
04937 colorSelect_2_clicked()
04938 {
04939   int id = cutRadioId ();
04940   bool fit_cut = id == 2;
04941   if ( fit_cut ) {
04942   }
04943   else {
04944     PlotterBase * cplotter = getSelectedCut();
04945     CutPlotter * cp = dynamic_cast < CutPlotter * > ( cplotter );
04946 
04947     const Color & rep_color = cp -> getCutColor ();
04948     QColor color ( rep_color.getRed(),
04949                    rep_color.getGreen(),
04950                    rep_color.getBlue () );
04951 
04952     color = QColorDialog::getColor ( color );
04953 
04954     if ( color.isValid() == true ) {
04955       Color c( color.red(), color.green(), color.blue() );
04956       cp -> setCutColor ( c );
04957     }
04958   }
04959 }
04960 
04961 void
04962 Inspector::
04963 contourSlider_valueChanged ( int val )
04964 {
04965 
04966   PlotterBase * plotter = getPlotter ();
04967   if ( !plotter ) return;
04968   DisplayController * controller = DisplayController::instance ();
04969   int index = controller->activeDataRepIndex ( plotter );
04970   DataRep * datarep = plotter->getDataRep ( index );
04971 
04972   RepBase * rep = datarep->getRepresentation();
04973   ContourPointRep * contourRep = dynamic_cast < ContourPointRep * > ( rep );
04974 
04975   if ( !contourRep ) return;
04976 
04977   contourRep->setUsingUserValues ( false );
04978   contourRep->setNumContours ( val );
04979   m_numContoursTextBox->setText ( QString("%1").arg ( val ) );
04980 
04981   datarep->notifyObservers();
04982 
04983 }
04984 
04985 void
04986 Inspector::
04987 contourTextBox_returnPressed()
04988 {
04989 
04990   PlotterBase * plotter = getPlotter ();
04991   if ( !plotter ) return;
04992   DisplayController * controller = DisplayController::instance ();
04993   int index = controller->activeDataRepIndex ( plotter );
04994   DataRep * datarep = plotter->getDataRep ( index );
04995 
04996   RepBase * rep = datarep->getRepresentation();
04997   ContourPointRep * contourRep = dynamic_cast < ContourPointRep * > ( rep );
04998 
04999   if ( !contourRep ) return;
05000 
05001   QString text = m_numContoursTextBox->text();
05002   int val = text.toInt();
05003 
05004   if ( val < 1 || val > 100 ) {
05005     int num = contourRep->getNumContours ();
05006     m_numContourSlider->setValue ( num );
05007     m_numContoursTextBox->setText ( QString ("%1").arg ( num ) );
05008     return;
05009   }
05010 
05011   contourRep->setUsingUserValues ( false );
05012   contourRep->setNumContours ( val );
05013   m_numContourSlider->setValue ( val );
05014 
05015   datarep->notifyObservers();
05016 
05017 }
05018 
05019 void
05020 Inspector::
05021 contourRadioButton1_toggled ( bool )
05022 {
05023   PlotterBase * plotter = getPlotter ();
05024   if ( !plotter ) return;
05025   if ( plotter -> isTargetable () == false ) return;
05026 
05027   DataRep * datarep = plotter -> getTarget ( );
05028   RepBase * rep = datarep->getRepresentation();
05029 
05030   ContourPointRep * contourRep = dynamic_cast < ContourPointRep * > ( rep );
05031 
05032   if ( !contourRep ) return;
05033 
05034   if ( contourRadioButton1->isChecked() ) {
05035 
05036     m_numContourSlider->setEnabled ( true );
05037     m_numContoursTextBox->setEnabled ( true );
05038     m_numContoursLabel->setEnabled ( true );
05039     m_contourLevelsTextBox->setEnabled ( false );
05040 
05041     int num = contourRep->getNumContours ();
05042     m_numContourSlider->setValue ( num );
05043     m_numContoursTextBox->setText ( QString ("%1").arg ( num ) );
05044 
05045     contourSlider_valueChanged ( num );
05046 
05047   }
05048 
05049   else {
05050 
05051     m_numContourSlider->setEnabled ( false );
05052     m_numContoursTextBox->setEnabled ( false );
05053     m_numContoursLabel->setEnabled ( false );
05054     m_contourLevelsTextBox->setEnabled ( true );
05055 
05056     contourLevelsTextBox_returnPressed();
05057 
05058   }
05059 
05060 }
05061 
05062 void
05063 Inspector::
05064 contourError ()
05065 {
05066 //   const QString message =
05067 //     "Invalid Input String. Please check that\n"
05068 //     "1. The string contains only numbers separated by white spaces, and,\n"
05069 //     "2. The numbers are in increasing order without any duplicates.\n";
05070    const QString message =
05071       "Invalid Input String.\n"
05072       "Please check that the string contains only numbers,\n"
05073       "separated by commas or white space.\n";
05074   QMessageBox::critical ( this, // parent
05075                           "Invalid Input String", // caption
05076                           message,
05077                           QMessageBox::Ok,
05078                           Qt::NoButton,
05079                           Qt::NoButton );
05080 }
05081 
05082 void
05083 Inspector::
05084 contourLevelsTextBox_returnPressed ()
05085 {
05086   if ( contourRadioButton2->isChecked () == false ) return;
05087 
05088   PlotterBase * plotter = getPlotter ();
05089   if ( !plotter ) return;
05090   DisplayController * controller = DisplayController::instance ();
05091   int index = controller->activeDataRepIndex ( plotter );
05092   DataRep * datarep = plotter->getDataRep ( index );
05093 
05094   RepBase * rep = datarep->getRepresentation();
05095   ContourPointRep * contourRep = dynamic_cast < ContourPointRep * > ( rep );
05096 
05097   if ( !contourRep ) return;
05098 
05099   const QString qstr1 = m_contourLevelsTextBox->text();
05100   if ( qstr1.isEmpty () ) return;
05101   
05102   const QString qstr2 = qstr1.simplifyWhiteSpace();
05103 
05104   vector < double > values;
05105 
05106 // Get a std::string from the QString.
05107 #if QT_VERSION < 0x040000
05108   std::string contourLevels(qstr2.ascii());
05109 #else
05110   std::string contourLevels(qstr2.toAscii());
05111 #endif
05112    
05113 // Break string into components; convert and validate each value.
05114   std::vector<std::string> tokens;
05115   stringTokenize(contourLevels, " \t,", tokens);
05116   for (size_t i = 0; i < tokens.size(); i++) {
05117      QString strval(tokens.at(i).c_str() );
05118      bool ok(true);
05119      double value(strval.toDouble(&ok));
05120      if (!ok) {
05121         contourError();
05122         return;
05123      }
05124      values.push_back(value);
05125   }
05126   
05127 // Sort and remove duplicates.
05128   std::stable_sort(values.begin(), values.end());
05129   vector<double>::iterator leftover = 
05130      std::unique(values.begin(), values.end());
05131   values.erase(leftover, values.end());
05132 
05133   contourRep->setContourValues ( values, datarep->getProjector() );
05134   datarep->notifyObservers();
05135 }
05136 
05137 void Inspector::editLabelFontClicked()
05138 {
05139   PlotterBase * plotter = getPlotter ();
05140   if ( !plotter ) return ;
05141 
05142   QFont labelFont;
05143   bool ok;
05144 
05145   XyPlotter * xyplotter = dynamic_cast < XyPlotter * > ( plotter );
05146   assert ( xyplotter != 0 );
05147 
05148   const FontBase * fb = xyplotter -> labelFont ( m_axis );
05149   if ( fb == 0 ) {
05150     labelFont = QFontDialog::getFont ( &ok, this);
05151   }
05152   else {
05153     const QtFont * qtfont = dynamic_cast < const QtFont * > ( fb );
05154     const QFont & qfont = qtfont -> font ();
05155     labelFont = QFontDialog::getFont ( &ok, qfont, this);
05156   }
05157 
05158   if ( ok )
05159     {
05160       QtFont * font = new QtFont;
05161       font -> setFont( labelFont );
05162       xyplotter -> setLabelFont( font, m_axis );
05163 
05164       /* The size of drawrect, marginrect, need to be updated
05165          according to new font.
05166       */
05167       xyplotter -> setNeedUpdate(true);
05168       xyplotter -> notifyObservers ();
05169     }
05170 }
05171 
05172 void Inspector::editTitleFontClicked()
05173 {
05174   PlotterBase * plotter = getPlotter ();
05175   if ( plotter == 0 ) return ;
05176 
05177   XyPlotter * xyplotter = dynamic_cast< XyPlotter* > ( plotter );
05178   assert( xyplotter != 0 );
05179 
05180   QFont titleFont;
05181   bool ok;
05182 
05183   const FontBase * fb = xyplotter -> titleFont ();
05184   if ( fb == 0 ) {
05185     // From the Qt documentation - "The usual way to use QFontDialog class is
05186     // to call one of the static convenience functions"
05187     titleFont = QFontDialog::getFont ( &ok, this );
05188   }
05189   else {
05190     const QtFont * qtfont = dynamic_cast < const QtFont * > ( fb );
05191     const QFont & qfont = qtfont -> font ();
05192     titleFont = QFontDialog::getFont ( &ok, qfont, this );
05193   }
05194 
05195   if ( ok )
05196     {
05197       QtFont * font = new QtFont;
05198       font -> setFont( titleFont );
05199       xyplotter -> setTitleFont( font );
05200 
05201       /* The size of drawrect, marginrect, need to be updated
05202          according to new font.
05203       */
05204       xyplotter -> setNeedUpdate(true);
05205       xyplotter -> notifyObservers ();
05206     }
05207 }
05208 
05209 
05210 void Inspector::ignoreErrorCheckBoxToggled( bool )
05211 {
05212   // Check if there is plotter.
05213   PlotterBase * plotter = getPlotter();
05214   if ( !plotter ) return;
05215 
05216   // Check if there is a function attached to this plotter.
05217   FunctionController * fcontroller = FunctionController::instance();
05218   if ( ! ( fcontroller -> hasFunction ( plotter, 0 ) ) ) {
05219     return;
05220   }
05221 
05222   FunctionRep * frep = getTopFunctionRep ();
05223   Fitter * fitter = frep -> getFitter ();
05224 
05225   // Set the new ignoreError flag for the function
05226   bool flag = m_IgnoreErrorCheckBox -> isChecked();
05227   if ( fitter != 0 ) {
05228     frep -> setIgnoreError ( flag );
05229   }
05230 }
05231 
05232 void
05233 Inspector::
05234 updateTransformTab()
05235 {
05236 
05237   // Disable the tab if no plotter selected.
05238   PlotterBase * plotter = getPlotter ();
05239   bool yes = plotter == 0;
05240   if ( yes == false ) {
05241     TextPlotter * tp = dynamic_cast < TextPlotter * > ( plotter );
05242     yes |= tp != 0;
05243   }
05244   if ( yes ) {
05245     transform_button_group -> setEnabled ( false );
05246     rotateGroupBox -> setEnabled ( false );
05247     return;
05248   }
05249   else {
05250     transform_button_group -> setEnabled ( true );
05251   }
05252  
05253   bool hasZ = plotter -> hasAxis ( Axes::Z );
05254   m_hammer -> setEnabled ( hasZ );
05255   m_lambert -> setEnabled ( hasZ );
05256   m_Car -> setEnabled ( hasZ );
05257   m_Mer -> setEnabled ( hasZ );
05258   m_Gls -> setEnabled ( hasZ );
05259   m_Arc -> setEnabled ( hasZ );
05260   m_Tan -> setEnabled ( hasZ );
05261   m_Sin -> setEnabled ( hasZ );
05262   m_Stg -> setEnabled ( hasZ );
05263   m_Air -> setEnabled ( hasZ );
05264 
05265   
05266   DisplayController *d_controller = DisplayController::instance();
05267 
05268   bool xlog = d_controller -> getLog ( plotter, Axes::X );
05269   bool ylog = d_controller -> getLog ( plotter, Axes::Y );
05270 
05271 
05272   if ( ( !xlog ) && ( !ylog ) ){
05273       
05274       BinaryTransform *t =
05275         dynamic_cast<  BinaryTransform* > ( plotter->getTransform() );
05276    
05277       if (( t -> name () == "HammerAito" ) || ( t->name() == "HammerAito2")){
05278          m_hammer -> setChecked ( true );
05279       }
05280  
05281       else if (( t -> name() == "Lambert" ) || ( t->name() == "Lambert2")) {
05282          m_lambert -> setChecked ( true );
05283       }
05284 
05285       else if (( t -> name() == "Cartesian" ) || ( t->name() == "Cartesian2")){
05286          m_Car -> setChecked ( true );
05287       }
05288 
05289       else if (( t -> name() == "Mercator" ) || ( t->name() == "Mecator2")){
05290          m_Mer -> setChecked ( true );
05291       }
05292 
05293       else if (( t -> name() == "GlobalSinusoidal" ) || ( t->name() == "GlobalSinusoidal2")) {
05294          m_Gls -> setChecked ( true );
05295       }
05296 
05297       else if (( t -> name() == "ARC" ) || (t->name()=="ARC2")){
05298          m_Arc -> setChecked ( true );
05299       }
05300 
05301       else if (( t -> name() == "TAN" ) || (t->name()=="TAN2")){
05302          m_Tan -> setChecked ( true );
05303       }
05304 
05305       else if (( t -> name() == "SIN" ) || (t->name()=="SIN2")){
05306          m_Sin -> setChecked ( true );
05307       }
05308 
05309       else if (( t -> name() == "STG" ) || (t->name()=="STG2")){
05310          m_Stg -> setChecked ( true );
05311       }
05312 
05313       else if (( t -> name() == "AIR" ) || (t->name()=="AIR2")){
05314          m_Air -> setChecked ( true );
05315       }
05316 
05317       else  m_linear->setChecked ( true );
05318 
05319       // Enable rotation if periodic transform.
05320       // Then set the rotation offset.
05321       if  (t->isPeriodic()) {
05322 
05323         rotateGroupBox -> setEnabled ( true );
05324         
05325         PeriodicBinaryTransform *tp =
05326           dynamic_cast< PeriodicBinaryTransform* > ( t );
05327 
05328         int xoffset = (int) tp->xOffset();
05329         int yoffset = (int) tp->yOffset();
05330 
05331         setRotate ( yoffset, xoffset);
05332       }
05333       else {
05334         setRotate ( 0, 0 );
05335         rotateGroupBox -> setEnabled ( false );
05336       }
05337   }
05338  
05339   else if ( ( !xlog ) && ( ylog ) ){
05340     m_logy -> setChecked ( true );
05341   }
05342 
05343   else if ( ( xlog ) && ( !ylog ) ){
05344     m_logx -> setChecked ( true );
05345   }
05346 
05347   else if ( ( xlog ) && ( ylog ) ){
05348     m_logxy -> setChecked ( true );
05349   }
05350 }
05351     
05352 
05353 void
05354 Inspector::
05355 invalidPeriodicTransform ()
05356 {
05357   QString message (
05358                    "A transform of this type can not be used because\n"
05359                    "this application was not compiled with WCSLIB support." );
05360 
05361   QMessageBox::information ( this, // parent
05362                              "Invalid transform", // caption
05363                              message, // .c_str(),
05364                              QMessageBox::Ok,
05365                              Qt::NoButton,
05366                              Qt::NoButton );
05367 }
05368 
05369 int
05370 Inspector::
05371 transformId () const
05372 {
05373   int id = -1;
05374   for ( unsigned int i = 0; i < m_transform_buttons.size (); i++ ) {
05375     if ( m_transform_buttons[i] -> isChecked () ) {
05376       id = i;
05377       break;
05378     }
05379   }
05380   return id;
05381 }
05382 
05383 void
05384 Inspector::
05385 transform_button_group_clicked (  )
05386 {
05387 
05388   int id = transformId ();
05389 
05390   PlotterBase * plotter = getPlotter ();
05391   if ( !plotter ) return;
05392 
05393   // Reset rotation offset when do another transform
05394   setRotate ( 0, 0 );
05395 
05396 #ifndef HAVE_WCSLIB
05397   if ( id > 3 ) {
05398     invalidPeriodicTransform ();
05399     return;
05400   }
05401 #endif
05402 
05403   DisplayController *d_controller = DisplayController::instance();
05404   int max_x = validPeriodicTransformRange();
05405   bool valid2 = false;
05406   try {
05407     switch ( id ) {
05408     case 0:
05409       d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05410       d_controller -> setTransform ( plotter, "Linear Linear" );
05411       rotateGroupBox -> setEnabled ( false );
05412       break;
05413 
05414     case 1:
05415       d_controller -> setTransformAxis ( plotter, "Linear", "Log" );
05416       d_controller -> setTransform ( plotter, "Linear Log");
05417       rotateGroupBox -> setEnabled ( false );
05418       break;
05419 
05420     case 2:
05421       d_controller -> setTransformAxis ( plotter, "Log", "Linear" );
05422       d_controller -> setTransform ( plotter, "Log Linear" );
05423       rotateGroupBox -> setEnabled ( false );
05424       break;
05425 
05426     case 3:   
05427       d_controller -> setTransformAxis ( plotter, "Log", "Log" );
05428       d_controller -> setTransform ( plotter, "Log Log" );
05429       rotateGroupBox -> setEnabled ( false );
05430       break;
05431 
05432     case 4:   
05433       if ( max_x == 180 ) {
05434         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05435         d_controller -> setTransform ( plotter, "HammerAito" );
05436         rotateGroupBox -> setEnabled ( true );
05437       }
05438       else if ( max_x == 360 ) {
05439         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05440         d_controller -> setTransform ( plotter, "HammerAito2" );
05441         rotateGroupBox -> setEnabled ( true );
05442       }
05443       else {
05444         QString message (
05445                          "The range of current plotter is not valid for.\n"
05446                          "HammerAito transform.\n\n"
05447                          "A valid range should be within: \n"
05448                          "X axis [-180, 180] or [0, 360]\n" 
05449                          "Y axis [ -90,  90]\n" );
05450         QMessageBox::information ( this, // parent
05451                                    "Invalid range", // caption
05452                                    message, // .c_str(),
05453                                    QMessageBox::Ok,
05454                                    Qt::NoButton,
05455                                    Qt::NoButton );
05456       }
05457       break;
05458 
05459     case 5:
05460       if ( max_x == 180 ) {
05461         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05462         d_controller -> setTransform ( plotter, "Lambert" );
05463         rotateGroupBox -> setEnabled ( true );
05464       }
05465       else if ( max_x == 360 ) {
05466         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05467         d_controller -> setTransform ( plotter, "Lambert2" );
05468         rotateGroupBox -> setEnabled ( true );
05469       }
05470       else {
05471         QString message (
05472                          "The range of current plotter is not valid for.\n"
05473                          "Lambert transform.\n\n"
05474                          "A valid range should be within: \n"
05475                          "X axis [-180, 180] or [0, 360]\n" 
05476                          "Y axis [ -90,  90]\n" );
05477         QMessageBox::information ( this, // parent
05478                                    "Invalid range", // caption
05479                                    message, // .c_str(),
05480                                    QMessageBox::Ok,
05481                                    Qt::NoButton,
05482                                    Qt::NoButton );
05483       }
05484       break;
05485 
05486     case 6:
05487       if ( max_x==180 ) {
05488         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05489         d_controller -> setTransform ( plotter, "Cartesian" );
05490         rotateGroupBox -> setEnabled ( true );
05491       }
05492       else if ( max_x==360 ) {
05493         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05494         d_controller -> setTransform ( plotter, "Cartesian2" );
05495         rotateGroupBox -> setEnabled ( true );
05496       }
05497       else {
05498         QString message (
05499                          "The range of current plotter is not valid for.\n"
05500                          "Cartesian transform.\n\n"
05501                          "A valid range should be within: \n"
05502                          "X axis [-180, 180]\n" 
05503                          "Y axis [ -90,  90]\n" );
05504         QMessageBox::information ( this, // parent
05505                                    "Invalid range", // caption
05506                                    message, // .c_str(),
05507                                    QMessageBox::Ok,
05508                                    Qt::NoButton,
05509                                    Qt::NoButton );
05510       }
05511       break;
05512 
05513     case 7:
05514       if ( max_x == 180 ) {
05515         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05516         d_controller -> setTransform ( plotter, "Mercator" );
05517         rotateGroupBox -> setEnabled ( true );
05518       }
05519       else if ( max_x == 360 ) {
05520         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05521         d_controller -> setTransform ( plotter, "Mercator2" );
05522         rotateGroupBox -> setEnabled ( true );
05523       }
05524       else {
05525         QString message (
05526                          "The range of current plotter is not valid for.\n"
05527                          "Mercator transform.\n\n"
05528                          "A valid range should be within: \n"
05529                          "X axis [-180, 180] or [0, 360]\n" 
05530                          "Y axis [ -90,  90]\n" );
05531         QMessageBox::information ( this, // parent
05532                                    "Invalid range", // caption
05533                                    message, // .c_str(),
05534                                    QMessageBox::Ok,
05535                                    Qt::NoButton,
05536                                    Qt::NoButton );
05537       }
05538       break;
05539 
05540     case 8:
05541       if ( max_x == 180 ) {
05542         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05543         d_controller -> setTransform ( plotter, "GlobalSinusoidal" );
05544         rotateGroupBox -> setEnabled ( true );
05545       }
05546       else if ( max_x == 360 ) {
05547         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05548         d_controller -> setTransform ( plotter, "GlobalSinusoidal2" );
05549         rotateGroupBox -> setEnabled ( true );
05550       }
05551       else {
05552         QString message (
05553                          "The range of current plotter is not valid for.\n"
05554                          "GlobalSinusoidal transform.\n\n"
05555                          "A valid range should be within: \n"
05556                          "X axis [-180, 180] or [0, 360]\n" 
05557                          "Y axis [ -90,  90]\n" );
05558         QMessageBox::information ( this, // parent
05559                                    "Invalid range", // caption
05560                                    message, // .c_str(),
05561                                    QMessageBox::Ok,
05562                                    Qt::NoButton,
05563                                    Qt::NoButton );
05564       }
05565       break;
05566 
05567     case 9:
05568       if ( max_x == 180 ) {
05569         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05570         d_controller -> setTransform ( plotter, "ARC" );
05571         rotateGroupBox -> setEnabled ( true );
05572       }
05573       else if ( max_x == 360 ) {
05574         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05575         d_controller -> setTransform ( plotter, "ARC" );
05576         rotateGroupBox -> setEnabled ( true );
05577       }
05578       else {
05579         QString message (
05580                          "The range of current plotter is not valid for.\n"
05581                          "ARC transform.\n\n"
05582                          "A valid range should be within: \n"
05583                          "X axis [-180, 180] or [0, 360]\n" 
05584                          "Y axis [ -90,  90]\n" );
05585         QMessageBox::information ( this, // parent
05586                                    "Invalid range", // caption
05587                                    message, // .c_str(),
05588                                    QMessageBox::Ok,
05589                                    Qt::NoButton,
05590                                    Qt::NoButton );
05591       }
05592       break;
05593 
05594     case 10:
05595       valid2 = validPeriodicTransformRange( 0 );
05596       if ( max_x == 180 && valid2 ) {
05597         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05598         d_controller -> setTransform ( plotter, "TAN" );
05599         rotateGroupBox -> setEnabled ( true );
05600       }
05601       else if ( max_x == 360 && valid2 ) {
05602         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05603         d_controller -> setTransform ( plotter, "TAN2" );
05604         rotateGroupBox -> setEnabled ( true );
05605       }
05606       else {
05607         QString message (
05608                          "The range of current plotter is not valid for.\n"
05609                          "TAN transform.\n\n"
05610                          "A valid range should be within: \n"
05611                          "X axis [-180, 180] or [0, 360]\n" 
05612                          "Y axis ( 0,  90]\n" );
05613         QMessageBox::information ( this, // parent
05614                                    "Invalid range", // caption
05615                                    message, // .c_str(),
05616                                    QMessageBox::Ok,
05617                                    Qt::NoButton,
05618                                    Qt::NoButton );
05619       }
05620       break;
05621 
05622     case 11:
05623       valid2 = validPeriodicTransformRange( 0 );
05624       if ( max_x==180 && valid2 ) {
05625         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05626         d_controller -> setTransform ( plotter, "SIN" );
05627         rotateGroupBox -> setEnabled ( true );
05628       }
05629       if ( max_x==360 && valid2 ) {
05630         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05631         d_controller -> setTransform ( plotter, "SIN2" );
05632         rotateGroupBox -> setEnabled ( true );
05633       }
05634       else {
05635         QString message (
05636                          "The range of current plotter is not valid for.\n"
05637                          "SIN transform.\n\n"
05638                          "A valid range should be within: \n"
05639                          "X axis [-180, 180] or [0, 360]\n" 
05640                          "Y axis ( 0,  90]\n" );
05641         QMessageBox::information ( this, // parent
05642                                    "Invalid range", // caption
05643                                    message, // .c_str(),
05644                                    QMessageBox::Ok,
05645                                    Qt::NoButton,
05646                                    Qt::NoButton );
05647       }
05648       break;
05649 
05650     case 12:
05651       valid2 = true; //validPeriodicTransformRange( -90 );
05652       if ( max_x==180 && valid2 ) {
05653         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05654         d_controller -> setTransform ( plotter, "STG" );
05655         rotateGroupBox -> setEnabled ( true );
05656       }
05657       if ( max_x==360 && valid2 ) {
05658         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05659         d_controller -> setTransform ( plotter, "STG2" );
05660         rotateGroupBox -> setEnabled ( true );
05661       }
05662       else {
05663         QString message (
05664                          "The range of current plotter is not valid for.\n"
05665                          "STG transform.\n\n"
05666                          "A valid range should be within: \n"
05667                          "X axis [-180, 180] or [0, 360]\n" 
05668                          "Y axis ( -90,  90]\n" );
05669         QMessageBox::information ( this, // parent
05670                                    "Invalid range", // caption
05671                                    message, // .c_str(),
05672                                    QMessageBox::Ok,
05673                                    Qt::NoButton,
05674                                    Qt::NoButton );
05675       }
05676       break;
05677 
05678     case 13:
05679       valid2 = validPeriodicTransformRange( -90 );
05680       if ( max_x==180 && valid2 ) {
05681         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05682         d_controller -> setTransform ( plotter, "AIR" );
05683         rotateGroupBox -> setEnabled ( true );
05684       }
05685       if ( max_x==360 && valid2 ) {
05686         d_controller -> setTransformAxis ( plotter, "Linear", "Linear" );
05687         d_controller -> setTransform ( plotter, "AIR2" );
05688         rotateGroupBox -> setEnabled ( true );
05689       }
05690       else {
05691         QString message (
05692                          "The range of current plotter is not valid for.\n"
05693                          "AIR transform.\n\n"
05694                          "A valid range should be within: \n"
05695                          "X axis [-180, 180] or [0, 360]\n" 
05696                          "Y axis ( -90,  90]\n" );
05697         QMessageBox::information ( this, // parent
05698                                    "Invalid range", // caption
05699                                    message, // .c_str(),
05700                                    QMessageBox::Ok,
05701                                    Qt::NoButton,
05702                                    Qt::NoButton );
05703       }
05704       break;
05705 
05706     }
05707   }
05708   catch ( const std::runtime_error & e ) {
05709     invalidOperationError ( e.what() );
05710   }
05711 }
05712 
05713 
05714 
05715 int
05716 Inspector::
05717 validPeriodicTransformRange()
05718 {
05719   PlotterBase * plotter = getPlotter ();
05720   
05721   const Range & rx = plotter -> getDataRange ( Axes::X  );
05722   const Range & ry = plotter -> getDataRange ( Axes::Y  );
05723 
05724   if ( ( rx.low() > -181 ) && ( rx.high() < 181 ) &&
05725        ( ry.low() > -91 ) && ( ry.high() < 91 )) {
05726     return 180;
05727   }
05728   
05729   if ( ( rx.low() > -1 ) && ( rx.high() < 361 ) &&
05730        ( ry.low() > -91 ) && ( ry.high() < 91 )) {
05731     return 360;
05732   }
05733   
05734   else return 0;
05735 }
05736 
05737 
05738 bool
05739 Inspector::
05740 validPeriodicTransformRange( int miny )
05741 {
05742   PlotterBase * plotter = getPlotter ();
05743   
05744   const Range & rx = plotter -> getRange ( Axes::X, false  );
05745   const Range & ry = plotter -> getRange ( Axes::Y, false  );
05746 
05747   if ( ( rx.low() < -180 ) || ( rx.high() > 180 ) ||
05748        ( ry.low() <=  miny ) || ( ry.high() > 90  ) ) {
05749     return false;
05750   }
05751 
05752   else {
05753     return true;
05754   }
05755 }
05756 
05757 
05758 
05759 void
05760 Inspector::
05761 rotateX( int offset )
05762 {
05763   if (!m_rotate_enable) return;
05764 
05765   if (offset>180) offset = offset-360 ;
05766   if (offset< -180) offset = offset+360;
05767 
05768   PlotterBase * plotter = getPlotter ();
05769   if ( !plotter ) return;
05770 
05771   plotter->setAutoRanging ( Axes::X, false );
05772 
05773 
05774   BinaryTransform *t =
05775     dynamic_cast<  BinaryTransform* > ( plotter->getTransform() );
05776 
05777           
05778       PeriodicBinaryTransform *tp =
05779         dynamic_cast< PeriodicBinaryTransform* > ( t );
05780 
05781       const Range & r = plotter->getRange ( Axes::X, true );
05782       Range range (r.low(), r.high(), r.pos());
05783       
05784       // Actually rotating X axes
05785       tp->setYOffset( offset );
05786 
05787       plotter->setRange ( Axes::X, range, true, false );
05788       m_x_offset_text->setText ( QString("%1").arg(offset)) ;
05789 
05790 }
05791 
05792 
05793 void
05794 Inspector::
05795 rotateY( int offset )
05796 {
05797   if (!m_rotate_enable) return;
05798 
05799   if (offset>180) offset = offset-360 ;
05800   if (offset< -180) offset = offset+360;
05801 
05802   PlotterBase * plotter = getPlotter ();
05803   if ( !plotter ) return;
05804 
05805   plotter->setAutoRanging ( Axes::Y, false );
05806 
05807 
05808   BinaryTransform *t =
05809     dynamic_cast<  BinaryTransform* > ( plotter->getTransform() );
05810 
05811           
05812       PeriodicBinaryTransform *tp =
05813         dynamic_cast< PeriodicBinaryTransform* > ( t );
05814 
05815       const Range & r = plotter->getRange ( Axes::Y, true );
05816       Range range (r.low(), r.high(), r.pos());
05817       
05818       // Rotate Y;
05819       tp->setXOffset( offset );
05820 
05821       plotter->setRange ( Axes::Y, range, true, false );
05822       m_y_offset_text->setText ( QString("%1").arg(offset)) ;
05823 
05824 }
05825 
05826 void 
05827 Inspector::
05828 setRotate( int x, int y )
05829 {
05830   m_rotate_enable = false;
05831   m_x_offset -> setValue ( x );
05832   m_x_offset_text -> setText ( QString("%1").arg(x) );
05833   m_y_offset -> setValue ( y );
05834   m_y_offset_text -> setText ( QString("%1").arg(y) );
05835   m_rotate_enable = true;
05836 }
05837 
05838 void
05839 Inspector::
05840 resetRotate()
05841 {
05842   rotateX(0);
05843   rotateY(0);
05844   setRotate(0, 0);
05845 }
05846 
05847 void
05848 Inspector::
05849 m_grid_clicked()
05850 {
05851   PlotterBase * plotter = getPlotter ();
05852   if ( !plotter ) return;
05853 
05854   plotter->setShowGrid ( m_grid -> isChecked() );
05855 }
05856 
05857 void
05858 Inspector::
05859 m_boxedge_clicked()
05860 {
05861   PlotterBase * plotter = getPlotter();
05862   if ( !plotter ) return;
05863   plotter->setBoxEdge( m_boxedge->isChecked() );
05864 }
05865 
05866 
05867 void
05868 Inspector::
05869 combineCheckBox_clicked()
05870 {
05871   PlotterBase * plotter = getPlotter ();
05872   if ( !plotter ) return;
05873 
05874   if (m_combine_checkbox->isChecked()) {
05875     plotter->setMinEntries(m_min_entries);
05876   }
05877   else plotter->setMinEntries(0);
05878 
05879   updateAxisTab();
05880 }
05881 
05882 void
05883 Inspector::
05884 setMinEntries( int increment )
05885 { 
05886   int minEntries = m_min_entries + increment - 50;
05887   if ( minEntries < 0 ) minEntries = 0;
05888 
05889   PlotterBase * plotter = getPlotter ();
05890   if ( !plotter ) return;
05891 
05892   if (!m_combine_checkbox->isChecked()) return;
05893 
05894   plotter->setMinEntries(minEntries);
05895   min_entries_text->setText(QString("%1").arg(minEntries));
05896 
05897   if (m_dragging == false ) {
05898     m_min_entries = minEntries;
05899     min_entries_slider->setValue(50);
05900   }
05901 }
05902 
05903 int
05904 Inspector::
05905 getMinEntries()
05906 {
05907   PlotterBase * plotter = getPlotter ();
05908   if ( !plotter ) return -1;
05909   
05910   return plotter->getMinEntries ();
05911 }
05912 
05913 void
05914 Inspector::
05915 setMinEntriesText()
05916 {
05917   PlotterBase * plotter = getPlotter ();
05918   if ( !plotter ) return;
05919   
05920   int min = min_entries_text->text().toInt();
05921   plotter->setMinEntries(min);
05922   updateAxisTab();
05923 }
05924 
05925 
05926 void
05927 Inspector::
05928 setXRotateText()
05929 {
05930   PlotterBase * plotter = getPlotter ();
05931   if ( !plotter ) return;
05932   
05933   int offset = m_x_offset_text->text().toInt();
05934 
05935 
05936   if (!m_rotate_enable) return;
05937 
05938   if (offset>180) offset = offset-360 ;
05939   if (offset< -180) offset = offset+360;
05940 
05941   plotter->setAutoRanging ( Axes::X, false );
05942   
05943   BinaryTransform *t =
05944     dynamic_cast<  BinaryTransform* > ( plotter->getTransform() );
05945   
05946           
05947   PeriodicBinaryTransform *tp =
05948     dynamic_cast< PeriodicBinaryTransform* > ( t );
05949   
05950   const Range & r = plotter->getRange ( Axes::X, true );
05951   Range range (r.low(), r.high(), r.pos());
05952   
05953   // Actually rotating X axes
05954   tp->setYOffset( offset );
05955   
05956   plotter->setRange ( Axes::X, range, true, false );
05957   m_x_offset->setValue(offset);
05958   m_x_offset_text->setText ( QString("%1").arg(offset)) ;
05959 
05960   updateAxisTab();
05961 }
05962 
05963 void
05964 Inspector::
05965 setYRotateText()
05966 {
05967   PlotterBase * plotter = getPlotter ();
05968   if ( !plotter ) return;
05969   
05970   int offset = m_y_offset_text->text().toInt();
05971 
05972 
05973   if (!m_rotate_enable) return;
05974 
05975   if (offset>180) offset = offset-360 ;
05976   if (offset< -180) offset = offset+360;
05977 
05978   plotter->setAutoRanging ( Axes::Y, false );
05979   
05980   BinaryTransform *t =
05981     dynamic_cast<  BinaryTransform* > ( plotter->getTransform() );
05982   
05983           
05984   PeriodicBinaryTransform *tp =
05985     dynamic_cast< PeriodicBinaryTransform* > ( t );
05986   
05987   const Range & r = plotter->getRange ( Axes::Y, true );
05988   Range range (r.low(), r.high(), r.pos());
05989   
05990   // Actually rotating Y axes
05991   tp->setXOffset( offset );
05992   
05993   plotter->setRange ( Axes::Y, range, true, false );
05994   m_y_offset->setValue(offset);
05995   m_y_offset_text->setText ( QString("%1").arg(offset)) ;
05996 
05997   updateAxisTab();
05998 }
05999 
06002 void
06003 Inspector::
06004 diffDataRep()
06005 {
06006   PlotterBase * plotter = getPlotter ();
06007 
06008   if ( !plotter ) return;
06009 
06010   int num_rep = plotter -> getNumDataReps();
06011 
06012   // If number of datarep is not equal to 2
06013   // in the plot, show warning message and do nothing.
06014   if ( num_rep != 2 )
06015     {
06016       const QString message=
06017         "You must have two DataReps in this view.";
06018 
06019       QMessageBox::warning ( this, // parent
06020                              "Unable to compare DataRep", // caption
06021                              message,
06022                              QMessageBox::Ok,
06023                              Qt::NoButton,
06024                              Qt::NoButton );
06025       return;
06026     }
06027 
06028   
06029   FunctionRep * func_rep = getTopFunctionRep ();
06030   DisplayController * controller = DisplayController::instance ();
06031   PlotterBase * res_plotter 
06032     //= controller -> createResidualsDisplay ( plotter, func_rep );
06033     = controller -> createDifferenceDisplay ( plotter );
06034   const Range & range = plotter -> getRange ( Axes::X, false );
06035   res_plotter -> setRange ( Axes::X, range, false );
06036 
06037   CanvasWindow * canvas = WindowController::instance () -> currentCanvas ();
06038 
06039   canvas -> addPlotDisplay ( res_plotter, true );
06040 }

Generated for HippoDraw Class Library by doxygen