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

Generated for HippoDraw Class Library by doxygen