Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/visu.git] / src / GUITOOLS / VisuGUI_TableDlg.cxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 // 
4 //  This library is free software; you can redistribute it and/or 
5 //  modify it under the terms of the GNU Lesser General Public 
6 //  License as published by the Free Software Foundation; either 
7 //  version 2.1 of the License. 
8 // 
9 //  This library is distributed in the hope that it will be useful, 
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 //  Lesser General Public License for more details. 
13 // 
14 //  You should have received a copy of the GNU Lesser General Public 
15 //  License along with this library; if not, write to the Free Software 
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
17 // 
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //  File   : VisuGUI_TableDlg.cxx
21 //  Author : Vadim SANDLER
22 //  Module : SALOME
23
24 #include "VisuGUI_TableDlg.h"
25
26 #include "SUIT_Tools.h"
27 #include "SUIT_MessageBox.h"
28 #include "SUIT_ResourceMgr.h"
29 #include "SUIT_Session.h"
30
31 #include "LightApp_Application.h"
32
33 #include "SALOMEDSClient_Study.hxx"
34 #include "SALOMEDSClient_GenericAttribute.hxx"
35 #include "SALOMEDSClient_AttributeTableOfInteger.hxx"
36 #include "SALOMEDSClient_AttributeTableOfReal.hxx"
37 #include "SALOMEDSClient_StudyBuilder.hxx"
38
39 #include <qlayout.h>
40 #include <qvalidator.h>
41 #include <qtable.h>
42 #include <qtabwidget.h>
43 #include <qvaluelist.h>
44 #include <qmemarray.h>
45 #include <qinputdialog.h>
46 #include <qlabel.h>
47 #include "utilities.h"
48 using namespace std;
49
50 #define MARGIN_SIZE       11
51 #define SPACING_SIZE      6
52 #define SPACER_SIZE       5
53 #define MIN_TABLE_WIDTH   200
54 #define MIN_TABLE_HEIGHT  200
55
56
57 class VisuGUI_Table : public QTable {
58 public:
59   VisuGUI_Table( Orientation orient, QWidget* parent = 0, const char* name = 0 ) 
60     : QTable( parent, name ), myValidator( 0 ), myOrientation( orient ) {}
61   VisuGUI_Table( Orientation orient, int numRows, int numCols, QWidget* parent = 0, const char* name = 0 )
62     : QTable( numRows, numCols, parent, name ), myValidator( 0 ), myOrientation( orient ) {}
63   
64   void setValidator( QValidator* v = 0 ) { myValidator = v;  }
65   bool isEditing() const { return QTable::isEditing(); }
66   
67 protected:
68   QWidget* createEditor ( int row, int col, bool initFromCell ) const
69     {
70       bool testUnits = ( myOrientation == Horizontal && col == 0 ) || ( myOrientation == Vertical && row == 0 );
71       QWidget* wg = QTable::createEditor( row, col, initFromCell );
72       if ( wg && wg->inherits("QLineEdit") && myValidator && !testUnits ) 
73         (( QLineEdit*)wg)->setValidator( myValidator );
74       return wg;
75     }
76
77 protected:
78   QValidator* myValidator;
79   Orientation myOrientation;
80 };
81
82 /*!
83   Constructor
84 */
85 VisuGUI_TableDlg::VisuGUI_TableDlg( QWidget* parent, 
86                                     _PTR(SObject) obj, 
87                                     bool edit,
88                                     int which,
89                                     Orientation orient,
90                                     bool showColumnTitles )
91      : QDialog( parent, "", false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
92        myIntTable( 0 ), myRealTable( 0 )
93 {
94   setCaption( edit ? tr( "EDIT_TABLE_TLT" ) : tr( "VIEW_TABLE_TLT" ) );
95   setSizeGripEnabled( true );
96
97   myObject = obj;
98   bool bHasIntTable = false;
99   bool bHasRealTable = false;
100   if ( myObject ) {
101     _PTR(GenericAttribute) anAttr;
102     bHasIntTable  = myObject->FindAttribute( anAttr, "AttributeTableOfInteger");
103     bHasRealTable = myObject->FindAttribute( anAttr, "AttributeTableOfReal");
104   }
105   
106   QVBoxLayout* mainLayout = new QVBoxLayout( this );
107   mainLayout->setMargin( MARGIN_SIZE );
108   mainLayout->setSpacing( SPACING_SIZE );
109
110   bool bDoInt  = which == ttInt  || which == ttBoth || which == ttAuto && bHasIntTable;
111   bool bDoReal = which == ttReal || which == ttBoth || which == ttAuto && bHasRealTable;
112
113   QWidget* top;
114   QVBoxLayout* tl;
115   if ( bDoInt && bDoReal ) {
116     top = new QTabWidget( this, "TabWidget" );
117     ( ( QTabWidget* ) top) ->setMargin( MARGIN_SIZE );
118   }
119   else {
120     top = new QWidget( this, "DumbWidget" );
121     tl  = new QVBoxLayout( top ); tl->setMargin( 0 ); tl->setSpacing( SPACING_SIZE );
122   }
123
124   if ( bDoInt ) {
125     myIntTable = new VisuGUI_TableWidget( top, "myIntTable", edit, orient, showColumnTitles );
126     myIntTable->getTable()->setValidator( new QIntValidator( this ) );
127     if ( bDoInt && bDoReal )
128       ( ( QTabWidget* )top )->addTab( myIntTable, tr( "TABLE_OF_INTEGER_TLT" ) );
129     else
130       tl->addWidget( myIntTable );
131   }
132   if ( bDoReal ) {
133     myRealTable = new VisuGUI_TableWidget( top, "myRealTable", edit, orient, showColumnTitles );
134     myRealTable->getTable()->setValidator( new QDoubleValidator( this ) );
135     if ( bDoInt && bDoReal )
136       ( ( QTabWidget* )top )->addTab( myRealTable, tr( "TABLE_OF_REAL_TLT" ) );
137     else
138       tl->addWidget( myRealTable );
139   }
140   if ( !bDoInt && !bDoReal ) {
141     QLabel *dumbLabel = new QLabel( tr( "ERR_TABLE_NOT_AVAILABLE" ), top, "DumbLabel" );
142     dumbLabel->setAlignment( AlignCenter );
143     tl->addWidget( dumbLabel );
144   }
145
146   QHBoxLayout* btnLayout = new QHBoxLayout; 
147   btnLayout->setMargin( 0 ); btnLayout->setSpacing( SPACING_SIZE );
148   
149   myOKBtn = new QPushButton( tr( "BUT_OK" ), this );
150   myHelpBtn = new QPushButton( tr( "BUT_HELP" ), this );
151   if ( edit ) {
152     myCancelBtn = new QPushButton( tr( "BUT_CANCEL" ), this );
153     btnLayout->addWidget( myOKBtn );
154     btnLayout->addItem( new QSpacerItem( SPACER_SIZE, SPACER_SIZE, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
155     btnLayout->addWidget( myCancelBtn );
156     btnLayout->addWidget( myHelpBtn );
157     connect( myOKBtn,     SIGNAL( clicked() ), this, SLOT( onOK() ) );
158     connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
159   }
160   else {
161     btnLayout->addWidget( myOKBtn );
162     btnLayout->addItem( new QSpacerItem( SPACER_SIZE, SPACER_SIZE, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
163     btnLayout->addWidget( myHelpBtn );
164     connect( myOKBtn,     SIGNAL( clicked() ), this, SLOT( accept() ) );
165   }
166   connect( myHelpBtn,     SIGNAL( clicked() ), this, SLOT( onHelp() ) );
167
168   mainLayout->addWidget( top );
169   mainLayout->addLayout( btnLayout );
170
171   initDlg();
172   resize( 500, 400 );
173   SUIT_Tools::centerWidget( this, parent );
174 }
175
176 /*!
177   Destructor
178 */
179 VisuGUI_TableDlg::~VisuGUI_TableDlg()
180 {
181 }
182
183 /*!
184   <OK> button slot, saves table(s)
185   Called only in create/edit mode ( <edit> parameter for constructor is true )
186 */
187 void VisuGUI_TableDlg::onOK()
188 {
189   myOKBtn->setFocus(); // accept possible changes
190   bool done = true;
191
192   if ( myObject ) {
193     _PTR(Study) study = myObject->GetStudy();
194     _PTR(AttributeTableOfInteger) tblIntAttr;
195     _PTR(AttributeTableOfReal)    tblRealAttr;
196
197     if ( study ) {
198       _PTR(StudyBuilder) builder = study->NewBuilder();
199       builder->NewCommand(); // start transaction !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
200       try {
201         if ( myIntTable ) {
202           builder->RemoveAttribute( myObject, "AttributeTableOfInteger" );
203           tblIntAttr = builder->FindOrCreateAttribute( myObject, "AttributeTableOfInteger" );
204
205           int i;
206           int nbRows  = myIntTable->getNumRows();
207           int nbCols  = myIntTable->getNumCols();
208           QString tlt = myIntTable->getTableTitle();
209           QStringList rowTitles, colTitles, units;
210           myIntTable->getRowTitles( rowTitles );
211           myIntTable->getColTitles( colTitles );
212           myIntTable->getUnits( units );
213           
214           if ( nbRows > 0) {
215             // data
216             int nRow = 0;
217             tblIntAttr->SetNbColumns( nbCols );
218             for ( i = 0; i < nbRows; i++ ) {
219               QStringList data;
220               myIntTable->getRowData( i, data );
221               bool bEmptyRow = true;
222               for ( int j = 0; j < data.count(); j++ ) {
223                 if ( !data[ j ].isNull() ) {
224                   tblIntAttr->PutValue( data[ j ].toInt(), nRow+1, j+1 );
225                   bEmptyRow = false;
226                 }
227               }
228               if ( !bEmptyRow ) {  // Skip rows with no data !!!
229                 // set row title
230                 tblIntAttr->SetRowTitle( nRow+1, rowTitles[ i ].isNull() ? "" : rowTitles[ i ].latin1() ); 
231                 // set row unit
232                 tblIntAttr->SetRowUnit( nRow+1, units[ i ].isNull() ? "" : units[ i ].latin1() ); 
233                 nRow++;
234               }
235             }
236             if ( nRow > 0 ) { // Set columns only if table is not empty, otherwise exception is raised !!!
237               // column titles
238               for ( i = 0; i < colTitles.count(); i++ )
239                 tblIntAttr->SetColumnTitle( i+1, colTitles[ i ].isNull() ? "" : colTitles[ i ].latin1() );
240             }
241           }
242           // title
243           tblIntAttr->SetTitle( myIntTable->getTableTitle().latin1() );
244         }
245         if ( myRealTable ) {
246           builder->RemoveAttribute( myObject, "AttributeTableOfReal" );
247           tblRealAttr = builder->FindOrCreateAttribute( myObject, "AttributeTableOfReal" );
248
249           int i;
250           int nbRows  = myRealTable->getNumRows();
251           int nbCols  = myRealTable->getNumCols();
252           QString tlt = myRealTable->getTableTitle();
253           QStringList rowTitles, colTitles, units;
254           myRealTable->getRowTitles( rowTitles );
255           myRealTable->getColTitles( colTitles );
256           myRealTable->getUnits( units );
257           
258           if ( nbRows > 0) {
259             // data
260             int nRow = 0;
261             tblRealAttr->SetNbColumns( nbCols );
262             for ( i = 0; i < nbRows; i++ ) {
263               QStringList data;
264               myRealTable->getRowData( i, data );
265               bool bEmptyRow = true;
266               for ( int j = 0; j < data.count(); j++ ) {
267                 if ( !data[ j ].isNull() ) {
268                   tblRealAttr->PutValue( data[ j ].toDouble(), nRow+1, j+1 );
269                   bEmptyRow = false;
270                 }
271               }
272               if ( !bEmptyRow ) {  // Skip rows with no data !!!
273                 // set row title
274                 tblRealAttr->SetRowTitle( nRow+1, rowTitles[ i ].isNull() ? "" : rowTitles[ i ].latin1() ); 
275                 // set row unit
276                 tblRealAttr->SetRowUnit( nRow+1, units[ i ].isNull() ? "" : units[ i ].latin1() );
277                 nRow++;
278               }
279             }
280             if ( nRow > 0 ) { // Set columns only if table is not empty, otherwise exception is raised !!!
281               // column titles
282               for ( i = 0; i < colTitles.count(); i++ )
283                 tblRealAttr->SetColumnTitle( i+1, colTitles[ i ].isNull() ? "" : colTitles[ i ].latin1() );
284             }
285           }
286           // title
287           tblRealAttr->SetTitle( myRealTable->getTableTitle().latin1() );
288         }
289         if ( myIntTable || myRealTable)
290           builder->CommitCommand(); // commit transaction !!!!!!!!!!!!!!!!!!!!!!!!!!!
291         else
292           builder->AbortCommand();  // abort transaction  !!!!!!!!!!!!!!!!!!!!!!!!!!!
293       }
294       catch( ... ) {
295         MESSAGE("VisuGUI_TableDlg::onOK : Exception has been caught !!!");
296         builder->AbortCommand();  // abort transaction  !!!!!!!!!!!!!!!!!!!!!!!!!!!
297         done = false;
298         SUIT_MessageBox::error1 ( this, tr("ERR_ERROR"), tr("ERR_APP_EXCEPTION"), tr ("BUT_OK") );
299       }
300     }
301   }
302   if ( done ) 
303     accept();
304 }
305
306 /*!
307   <Help> button slot, shows corresponding help page
308 */
309 void VisuGUI_TableDlg::onHelp()
310 {
311   QString aHelpFileName = "/files/displaying_tables.htm";
312   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
313   if (app)
314     app->onHelpContextModule(app->activeModule() ? app->moduleName(app->activeModule()->moduleName()) : QString(""), aHelpFileName);
315   else {
316                 QString platform;
317 #ifdef WIN32
318                 platform = "winapplication";
319 #else
320                 platform = "application";
321 #endif
322     SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
323                            QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
324                            arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName),
325                            QObject::tr("BUT_OK"));
326   }
327 }
328
329 /*!
330    Populates table with data
331 */
332 void VisuGUI_TableDlg::initDlg()
333 {
334   int i, j;
335   if ( myObject ) {
336     _PTR(GenericAttribute) anAttr;
337     _PTR(AttributeTableOfInteger) tblIntAttr;
338     _PTR(AttributeTableOfReal)    tblRealAttr;
339     if ( myObject->FindAttribute( anAttr, "AttributeTableOfInteger") ) {
340       tblIntAttr = anAttr;
341     }
342     if ( myObject->FindAttribute( anAttr, "AttributeTableOfReal") ) {
343       tblRealAttr = anAttr;
344     }
345     // Table of integer
346     if ( tblIntAttr && myIntTable ) {
347       try {
348         // title
349         myIntTable->setTableTitle( tblIntAttr->GetTitle().c_str() );
350         // nb of rows & cols
351         int nbRows = tblIntAttr->GetNbRows() ; 
352         int nbCols = tblIntAttr->GetNbColumns();
353         myIntTable->setNumRows( nbRows );
354         myIntTable->setNumCols( nbCols );
355         // rows titles
356         QStringList strlist;
357         vector<string> rowTitles = tblIntAttr->GetRowTitles();
358         for ( i = 0; i < nbRows; i++ ) {
359           if ( rowTitles.size() > 0 )
360             strlist.append( rowTitles[i].c_str() );
361           else
362             strlist.append( "" );
363         }
364         myIntTable->setRowTitles( strlist );
365         // columns titles
366         strlist.clear();
367         vector<string> colTitles = tblIntAttr->GetColumnTitles();
368         for ( i = 0; i < nbCols; i++ ) {
369           if ( colTitles.size() > 0 )
370             strlist.append( colTitles[i].c_str() );
371           else
372             strlist.append( "" );
373         }
374         myIntTable->setColTitles( strlist );
375         // units
376         strlist.clear();
377         vector<string> rowUnits = tblIntAttr->GetRowUnits();
378         if ( rowUnits.size() > 0 ) {
379           for ( i = 0; i < nbRows; i++ )
380             strlist.append( rowUnits[i].c_str() );
381           myIntTable->setUnits( strlist );
382         }
383         // data
384         for ( i = 1; i <= nbRows; i++ ) {
385           strlist.clear();
386           for ( j = 1; j <= nbCols; j++ ) {
387             if ( tblIntAttr->HasValue( i, j ) )
388               strlist.append( QString::number( tblIntAttr->GetValue( i, j ) ) );
389             else
390               strlist.append( QString::null );
391           }
392           myIntTable->setRowData( i-1, strlist );
393         }
394         myIntTable->adjustTable();
395       }
396       catch( ... ) {
397         MESSAGE("VisuGUI_TableDlg::initDlg : Exception has been caught !!!");
398       }
399     } 
400     // Table of real
401     if ( tblRealAttr && myRealTable ) {
402       try {
403         // title
404         myRealTable->setTableTitle( tblRealAttr->GetTitle().c_str() );
405         // nb of rows & cols
406         int nbRows = tblRealAttr->GetNbRows() ; 
407         int nbCols = tblRealAttr->GetNbColumns();
408         myRealTable->setNumRows( nbRows );
409         myRealTable->setNumCols( nbCols );
410         // rows titles
411         QStringList strlist;
412         vector<string> rowTitles = tblRealAttr->GetRowTitles();
413         for ( i = 0; i < nbRows; i++ ) {
414           if ( rowTitles.size() > 0 )
415             strlist.append( rowTitles[i].c_str() );
416           else
417             strlist.append( "" );
418         }
419         myRealTable->setRowTitles( strlist );
420         // columns titles
421         strlist.clear();
422         vector<string> colTitles = tblRealAttr->GetColumnTitles();
423         for ( i = 0; i < nbCols; i++ ) {
424           if ( colTitles.size() > 0 )
425             strlist.append( colTitles[i].c_str() );
426           else
427             strlist.append( "" );
428         }
429         myRealTable->setColTitles( strlist );
430         // units
431         strlist.clear();
432         vector<string> rowUnits = tblRealAttr->GetRowUnits();
433         if ( rowUnits.size() > 0 ) {
434           for ( i = 0; i < nbRows; i++ )
435             strlist.append( rowUnits[i].c_str() );
436           myRealTable->setUnits( strlist );
437         }
438         // data
439         for ( i = 1; i <= nbRows; i++ ) {
440           strlist.clear();
441           for ( j = 1; j <= nbCols; j++ ) {
442             if ( tblRealAttr->HasValue( i, j ) )
443               strlist.append( QString::number( tblRealAttr->GetValue( i, j ) ) );
444             else
445               strlist.append( QString::null );
446           }
447           myRealTable->setRowData( i-1, strlist );
448         }
449         myRealTable->adjustTable();
450       }
451       catch( ... ) {
452         MESSAGE("VisuGUI_TableDlg::initDlg : Exception has been caught !!!");
453       }
454     } 
455   }
456 }
457
458 /*!
459   Provides help on F1 button click
460 */
461 void VisuGUI_TableDlg::keyPressEvent( QKeyEvent* e )
462 {
463   QDialog::keyPressEvent( e );
464   if ( e->isAccepted() )
465     return;
466
467   if ( e->key() == Key_F1 )
468     {
469       e->accept();
470       onHelp();
471     }
472 }
473
474 /*!
475   Constructor
476 */
477 VisuGUI_TableWidget::VisuGUI_TableWidget( QWidget* parent, 
478                                               const char* name, 
479                                               bool edit, 
480                                               Orientation orient,
481                                               bool showColumnTitles )
482      : QWidget( parent, name ), myOrientation( orient )
483 {
484   QGridLayout* mainLayout = new QGridLayout( this );
485   mainLayout->setMargin( 0 );
486   mainLayout->setSpacing( SPACING_SIZE );
487
488   myTitleEdit = new QLineEdit( this, "TitleEdit" );
489   myTitleEdit->setAlignment( AlignCenter );
490   myTitleEdit->setReadOnly( !edit );
491   QFont fnt = myTitleEdit->font();
492   fnt.setBold( true ); 
493   myTitleEdit->setFont( fnt );
494
495   myTable = new VisuGUI_Table( orient, this, "Table" );
496   myTable->setNumRows( 5 );
497   myTable->setNumCols( 5 );
498   myTable->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
499   myTable->setMinimumSize( MIN_TABLE_WIDTH, MIN_TABLE_HEIGHT );
500   myTable->setSelectionMode( QTable::Single );
501   myTable->setShowGrid( true );
502   myTable->setColumnMovingEnabled( false );
503   myTable->setRowMovingEnabled( false );
504   myTable->setReadOnly( !edit );
505   myTable->setDragEnabled( false );
506   setUnitsTitle( tr( "UNITS_TLT" ) );
507
508   if ( !showColumnTitles ) {
509     if ( myOrientation == Horizontal ) {
510       myTable->horizontalHeader()->hide();
511       myTable->setTopMargin( 0 );
512     }
513     else {
514       myTable->verticalHeader()->hide();
515       myTable->setLeftMargin( 0 );
516     }
517   }
518
519   mainLayout->addWidget( myTitleEdit, 0, 0 );
520   mainLayout->addWidget( myTable, 1, 0 );
521
522   if ( edit ) {
523     myAddRowBtn    = new QPushButton( tr( "ADD_ROW_BTN" ), this, "AddRowBtn" );
524     myDelRowBtn    = new QPushButton( tr( "REMOVE_ROW_BTN" ), this, "DelRowBtn" );
525     myAddColBtn    = new QPushButton( tr( "ADD_COLUMN_BTN" ), this, "AddColBtn" );
526     myDelColBtn    = new QPushButton( tr( "REMOVE_COLUMN_BTN" ), this, "DelColBtn" );
527     myAdjustBtn    = new QPushButton( tr( "ADJUST_CELLS_BTN" ), this, "AdjustBtn" );
528     mySelectAllBtn = new QPushButton( tr( "SELECT_ALL_BTN" ), this, "SelectAllBtn" );
529     myClearBtn     = new QPushButton( tr( "CLEAR_BTN"), this, "ClearBtn" );
530     QVBoxLayout* btnLayout = new QVBoxLayout; btnLayout->setMargin( 0 ); btnLayout->setSpacing( SPACING_SIZE );
531     btnLayout->addWidget( myAddRowBtn );
532     btnLayout->addWidget( myDelRowBtn );
533     btnLayout->addWidget( myAddColBtn );
534     btnLayout->addWidget( myDelColBtn );
535     btnLayout->addStretch();
536     btnLayout->addWidget( myAdjustBtn );
537     btnLayout->addStretch();
538     btnLayout->addWidget( mySelectAllBtn );
539     btnLayout->addWidget( myClearBtn );
540     mainLayout->addLayout( btnLayout, 1, 1 );
541     connect( myTable, SIGNAL( selectionChanged() ),        this, SLOT( updateButtonsState() ) );
542     connect( myTable, SIGNAL( currentChanged( int, int) ), this, SLOT( updateButtonsState() ) );
543     connect( myAddRowBtn,    SIGNAL( clicked() ),   this, SLOT( addRow() ) );
544     connect( myAddColBtn,    SIGNAL( clicked() ),   this, SLOT( addCol() ) );
545     connect( myDelRowBtn,    SIGNAL( clicked() ),   this, SLOT( delRow() ) );
546     connect( myDelColBtn,    SIGNAL( clicked() ),   this, SLOT( delCol() ) );
547     connect( myAdjustBtn,    SIGNAL( clicked() ),   this, SLOT( adjustTable() ) );
548     connect( mySelectAllBtn, SIGNAL( clicked() ),   this, SLOT( selectAll() ) );
549     connect( myClearBtn,     SIGNAL( clicked() ),   this, SLOT( clearTable() ) );
550     myTable->horizontalHeader()->installEventFilter( this );
551     myTable->verticalHeader()->installEventFilter( this );
552     myTable->installEventFilter( this );
553   }
554   updateButtonsState();
555 }
556 /*!
557   Destructor
558 */
559 VisuGUI_TableWidget::~VisuGUI_TableWidget()
560 {
561 }
562 /*!
563   Sets table title
564 */
565 void VisuGUI_TableWidget::setTableTitle( const QString& title )
566 {
567   myTitleEdit->setText( title );
568 }
569 /*!
570   Gets table title
571 */
572 QString VisuGUI_TableWidget::getTableTitle()
573 {
574   return myTitleEdit->text();
575 }
576 /*!
577   Sets total number of rows
578 */
579 void VisuGUI_TableWidget::setNumRows( const int num )
580 {
581   myOrientation == Horizontal ? myTable->setNumRows( num ) : myTable->setNumCols( num );
582 }
583 /*!
584   Gets total number of rows
585 */
586 int VisuGUI_TableWidget::getNumRows()
587 {
588   return myOrientation == Horizontal ? myTable->numRows() : myTable->numCols();
589 }
590 /*!
591   Sets total number of columns
592 */
593 void VisuGUI_TableWidget::setNumCols( const int num )
594 {
595   // !!! first column contains units !!!
596   myOrientation == Horizontal ? myTable->setNumCols( num+1 ) : myTable->setNumRows( num+1 );
597 //  myOrientation == Horizontal ? myTable->setColumnReadOnly( 0, true ) : myTable->setRowReadOnly( 0, true );
598 }
599 /*!
600   Gets total number of columns
601 */
602 int VisuGUI_TableWidget::getNumCols()
603 {
604   // !!! first column contains units !!!
605   return myOrientation == Horizontal ? myTable->numCols()-1 : myTable->numRows()-1;
606 }
607 /*!
608   Sets rows titles
609 */
610 void VisuGUI_TableWidget::setRowTitles( QStringList& tlts )
611 {
612   for ( int i = 0; i < tlts.count(); i++ ) {
613     myOrientation == Horizontal ? 
614       myTable->verticalHeader()->setLabel( i, tlts[i] ) : 
615       myTable->horizontalHeader()->setLabel( i, tlts[i] );
616   }
617 }
618 /*!
619   Gets rows titles
620 */
621 void VisuGUI_TableWidget::getRowTitles( QStringList& tlts )
622 {
623   tlts.clear();
624   if ( myOrientation == Horizontal ) {
625     for ( int i = 0; i < myTable->numRows(); i++ ) {
626       tlts.append( myTable->verticalHeader()->label( i ) );
627     }
628   }
629   else {
630     for ( int i = 0; i < myTable->numCols(); i++ ) {
631       tlts.append( myTable->horizontalHeader()->label( i ) );
632     }
633   }
634 }
635 /*!
636   Sets columns titles
637 */
638 void VisuGUI_TableWidget::setColTitles( QStringList& tlts )
639 {
640   // !!! first column contains units !!!
641   for ( int i = 0; i < tlts.count(); i++ ) {
642     myOrientation == Horizontal ? 
643       myTable->horizontalHeader()->setLabel( i+1, tlts[i].isNull() ? "" : tlts[i] ) :
644       myTable->verticalHeader()->setLabel( i+1, tlts[i].isNull() ? "" : tlts[i] );
645   }
646   setUnitsTitle( tr( "UNITS_TLT" ) );
647 }
648 /*!
649   Sets columns titles
650 */
651 void VisuGUI_TableWidget::getColTitles( QStringList& tlts )
652 {
653   // !!! first column contains units !!!
654   tlts.clear();
655   if ( myOrientation == Horizontal ) {
656     for ( int i = 1; i < myTable->numCols(); i++ ) {
657       tlts.append( myTable->horizontalHeader()->label( i ) );
658     }
659   }
660   else {
661     for ( int i = 1; i < myTable->numRows(); i++ ) {
662       tlts.append( myTable->verticalHeader()->label( i ) );
663     }
664   }
665 }
666 /*!
667   Sets units title
668 */
669 void VisuGUI_TableWidget::setUnitsTitle( const QString& tlt ) {
670   // !!! first column contains units !!!
671   myOrientation == Horizontal ? myTable->horizontalHeader()->setLabel( 0, tlt.isNull() ? "" : tlt ) : myTable->verticalHeader()->setLabel( 0, tlt.isNull() ? "" : tlt );
672 }
673 /*!
674   Sets units
675 */
676 void VisuGUI_TableWidget::setUnits( QStringList& units )
677 {
678   for ( int i = 0; i < units.count(); i++ ) {
679     myOrientation == Horizontal ? myTable->setText( i, 0, units[i].isNull() ? "" : units[i] ) : myTable->setText( 0, i, units[i].isNull() ? "" : units[i] );
680   }
681 }
682 /*!
683   Gets units
684 */
685 void VisuGUI_TableWidget::getUnits( QStringList& units )
686 {
687   units.clear();
688   if ( myOrientation == Horizontal ) {
689     for ( int i = 0; i < myTable->numRows(); i++ )
690       units.append( myTable->text( i, 0 ).isNull() ? QString("") : myTable->text( i, 0 ) );
691   }
692   else {
693     for ( int i = 0; i < myTable->numCols(); i++ )
694       units.append( myTable->text( 0, i ).isNull() ? QString("") : myTable->text( 0, i ) );
695   }
696 }
697 /*!
698   Sets row data
699 */
700 void VisuGUI_TableWidget::setRowData( int row, QStringList& data )
701 {
702   if ( row >= 0 && row < getNumRows() ) {
703     for ( int i = 0; i < data.count(); i++ ) {
704       if ( data[i].isNull() ) {
705         myOrientation == Horizontal ? myTable->clearCell( row, i+1 ) :
706                                       myTable->clearCell( i+1, row );
707       }
708       else {
709         myOrientation == Horizontal ? myTable->setText( row, i+1, data[i] ) :
710                                       myTable->setText( i+1, row, data[i] );
711       }
712     }
713   }
714 }
715 /*!
716   Gets row data
717 */
718 void VisuGUI_TableWidget::getRowData( int row, QStringList& data )
719 {
720   data.clear();
721   if ( row >= 0 && row < getNumRows() ) {
722     if ( myOrientation == Horizontal ) {
723       for ( int i = 1; i < myTable->numCols(); i++ )
724         data.append( myTable->text( row, i ) );
725     }
726     else {
727       for ( int i = 1; i < myTable->numRows(); i++ )
728         data.append( myTable->text( i, row ) );
729     }
730   }
731 }
732 /*!
733   Adjusts table cell to see contents, <Adjust Cells> button slot
734 */
735 void VisuGUI_TableWidget::adjustTable()
736 {
737   int i;
738   for ( i = 0; i < myTable->numRows(); i++ )
739     myTable->adjustRow( i );
740   for ( i = 0; i < myTable->numCols(); i++ )
741     myTable->adjustColumn( i );
742 }
743 /*!
744   Called when selection changed in table
745 */
746 void VisuGUI_TableWidget::updateButtonsState()
747 {
748   if ( myTable->isReadOnly() )
749     return;
750   bool bDR = false; // <Delete Row(s)>
751   bool bDC = false; // <Delete Column(s)>
752   bool bSA = false; // <Select All>
753   bool bCT = false; // <Clear>
754   int i;
755   int c = myOrientation == Horizontal ? 0 : 1;
756   for ( i = c; i < myTable->numRows(); i++ ) {
757     if ( myTable->isRowSelected( i, true ) )
758       bDR = true;
759     else 
760       bSA = true;
761   }
762   c = myOrientation == Horizontal ? 1 : 0;
763   for ( i = c; i < myTable->numCols(); i++ ) {
764     if ( myTable->isColumnSelected( i, true ) )
765       bDC = true;
766     else 
767       bSA = true;
768   }
769   int nbSel = myTable->numSelections();
770   for ( i = 0; i < nbSel; i++ ) {
771     QTableSelection ts = myTable->selection( i );
772     for ( int j = ts.topRow(); j < ts.bottomRow()+1; j++) {
773       for ( int k = ts.leftCol(); k < ts.rightCol()+1; k++) {
774         if ( myTable->item( j, k ) )
775           bCT = true;
776       }
777     }
778   }
779   if ( myTable->item( myTable->currentRow(), myTable->currentColumn() ) )
780     bCT = true;
781   myDelRowBtn->setEnabled( bDR );
782   myDelColBtn->setEnabled( bDC );
783   mySelectAllBtn->setEnabled( bSA );
784   myClearBtn->setEnabled( bCT );
785 }
786 /*!
787   <Add row> button slot
788 */
789 void VisuGUI_TableWidget::addRow()
790 {
791   myTable->insertRows( myTable->numRows(), 1 );
792   updateButtonsState();
793 }
794 /*!
795   <Add column> button slot
796 */
797 void VisuGUI_TableWidget::addCol()
798 {
799   myTable->insertColumns( myTable->numCols(), 1 );
800   updateButtonsState();
801 }
802 /*!
803   <Delete row(s)> button slot
804 */
805 void VisuGUI_TableWidget::delRow()
806 {
807   int c = myOrientation == Horizontal ? 0 : 1;
808   QValueList<int> il;
809   int i;
810   for ( i = c; i < myTable->numRows(); i++ )
811     if ( myTable->isRowSelected( i, true ) )
812       il.append( i );
813   if ( il.count() > 0 ) {
814     QMemArray<int> ildel( il.count() );
815     for ( i = 0; i < il.count(); i++ )
816       ildel[ i ] = il[ i ];
817     myTable->removeRows( ildel );
818   }
819   updateButtonsState();
820 }
821 /*!
822   <Delete column(s)> button slot
823 */
824 void VisuGUI_TableWidget::delCol()
825 {
826   int c = myOrientation == Horizontal ? 1 : 0;
827   QValueList<int> il;
828   int i;
829   for ( i = c; i < myTable->numCols(); i++ )
830     if ( myTable->isColumnSelected( i, true ) )
831       il.append( i );
832   if ( il.count() > 0 ) {
833     QMemArray<int> ildel( il.count() );
834     for ( i = 0; i < il.count(); i++ )
835       ildel[ i ] = il[ i ];
836     myTable->removeColumns( ildel );
837   }
838   updateButtonsState();
839 }
840 /*!
841   <Select All> button slot
842 */
843 void VisuGUI_TableWidget::selectAll()
844 {
845   myTable->clearSelection();
846   QTableSelection ts;
847   ts.init( 0, 0 ); ts.expandTo( myTable->numRows()-1, myTable->numCols()-1 );
848   myTable->addSelection( ts );
849   updateButtonsState();
850 }
851 /*!
852   <Clear> button slot
853 */
854 void VisuGUI_TableWidget::clearTable()
855 {
856   int nbSel = myTable->numSelections();
857   for ( int i = 0; i < nbSel; i++ ) {
858     QTableSelection ts = myTable->selection( i );
859     for ( int j = ts.topRow(); j < ts.bottomRow()+1; j++) {
860       if ( myOrientation == Vertical && j == 0 ) {
861 //      continue;      // UNITS
862       }
863       for ( int k = ts.leftCol(); k < ts.rightCol()+1; k++) {
864         if ( myOrientation == Horizontal && k == 0 ) {
865 //        continue;   // UNITS
866         }
867         myTable->clearCell( j, k );
868       }
869     }
870   }
871   if ( nbSel == 0 )
872     myTable->clearCell( myTable->currentRow(), myTable->currentColumn() );
873   myTable->clearSelection();
874   updateButtonsState();
875 }
876 /*!
877   Event filter - handles titles editing
878 */
879 bool VisuGUI_TableWidget::eventFilter( QObject* o, QEvent* e )
880 {
881   if ( e->type() == QEvent::MouseButtonDblClick) {
882     QMouseEvent* me = ( QMouseEvent* )e;
883     if ( me->button() == LeftButton && !myTable->isReadOnly() ) {
884       if ( o == myTable->horizontalHeader() ) {
885         for ( int i = 0; i < myTable->horizontalHeader()->count(); i++ ) {
886           QRect rect = myTable->horizontalHeader()->sectionRect( i );
887           rect.addCoords( 1, 1, -1, -1 );
888           if ( rect.contains( myTable->horizontalHeader()->mapFromGlobal( me->globalPos() ) ) ) {
889             if ( myOrientation == Vertical || i != 0 ) {
890               bool bOk;
891               QString tlt = QInputDialog::getText( tr( "SET_TITLE_TLT" ), 
892                                                    tr( "TITLE_LBL" ),
893                                                    QLineEdit::Normal,
894                                                    myTable->horizontalHeader()->label( i ),
895                                                    &bOk,
896                                                    this );
897               if ( bOk && !tlt.isNull() )
898                 myTable->horizontalHeader()->setLabel( i, tlt );
899               break;
900             }
901           }
902         }
903       }
904       if ( o == myTable->verticalHeader() ) {
905         for ( int i = 0; i < myTable->verticalHeader()->count(); i++ ) {
906           QRect rect = myTable->verticalHeader()->sectionRect( i );
907           rect.addCoords( 1, 1, -1, -1 );
908           if ( rect.contains( myTable->verticalHeader()->mapFromGlobal( me->globalPos() ) ) ) {
909             if ( myOrientation == Horizontal || i != 0 ) {
910               bool bOk;
911               QString tlt = QInputDialog::getText( tr( "SET_TITLE_TLT" ), 
912                                                    tr( "TITLE_LBL" ),
913                                                    QLineEdit::Normal,
914                                                    myTable->verticalHeader()->label( i ),
915                                                    &bOk,
916                                                    this );
917               if ( bOk && !tlt.isNull() )
918                 myTable->verticalHeader()->setLabel( i, tlt );
919               break;
920             }
921           }
922         }
923       }
924     }    
925   }
926   else if ( e->type() == QEvent::KeyRelease && o == myTable ) {
927     QKeyEvent* ke = (QKeyEvent*)e;
928     if ( ke->key() == Key_Delete && !myTable->isEditing() ) {
929       clearTable();
930     }
931     else if ( ke->key() == Key_Backspace && !myTable->isEditing() ) {
932       clearTable();
933       int i = myTable->currentRow();
934       int j = myTable->currentColumn() - 1;
935       if ( j < 0 ) { j = myTable->numCols()-1; i--; }
936       if ( i >= 0 && j >= 0 )
937         myTable->setCurrentCell( i, j );
938     }
939   }
940   return QWidget::eventFilter( o, e );
941 }
942
943
944