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

Generated for HippoDraw Class Library by doxygen