Back to index

salome-gui  6.5.0
SalomeApp_NoteBookDlg.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 // File:    SalomeApp_NoteBookDlg.cxx
00021 // Author : Roman NIKOLAEV, Open CASCADE S.A.S.
00022 // Module : GUI
00023 //
00024 #include <PyConsole_Interp.h> // this include must be first (see PyInterp_base.h)!
00025 #include <PyConsole_Console.h>
00026 
00027 #include "SalomeApp_NoteBookDlg.h"
00028 #include "SalomeApp_Application.h"
00029 #include "SalomeApp_Study.h"
00030 #include "SalomeApp_VisualState.h"
00031 
00032 #include <Qtx.h>
00033 
00034 #include <CAM_Module.h>
00035 
00036 #include <SUIT_Desktop.h>
00037 #include <SUIT_MessageBox.h>
00038 #include <SUIT_ResourceMgr.h>
00039 #include <SUIT_Session.h>
00040 
00041 #include <SALOMEDS_Tool.hxx>
00042 
00043 #include <QWidget>
00044 #include <QDialog>
00045 #include <QGridLayout>
00046 #include <QTableWidget>
00047 #include <QTableWidgetItem>
00048 #include <QPushButton>
00049 #include <QFont>
00050 #include <QGroupBox>
00051 #include <QList>
00052 #include <QApplication>
00053 #include <QDir>
00054 
00055 #include <string>
00056 #include <vector>
00057 
00058 #define DEFAULT_MARGIN  11
00059 #define DEFAULT_SPACING 6
00060 #define SPACER_SIZE     120
00061 #define COLUMN_SIZE     180
00062 
00063 #define NAME_COLUMN  0
00064 #define VALUE_COLUMN 1
00065 
00066 
00068 //                 NoteBook_TableRow class                               //
00070 //============================================================================
00074 //============================================================================
00075 NoteBook_TableRow::NoteBook_TableRow(int index, NoteBook_Table* parentTable, QWidget* parent):
00076   QWidget(parent),
00077   myParentTable(parentTable),
00078   myIndex(index),
00079   myRowHeader(new QTableWidgetItem()),
00080   myVariableName(new QTableWidgetItem()),
00081   myVariableValue(new QTableWidgetItem())
00082 {
00083 }
00084 
00085 //============================================================================
00089 //============================================================================
00090 NoteBook_TableRow::~NoteBook_TableRow()
00091 {
00092 }
00093 
00094 //============================================================================
00098 //============================================================================
00099 void NoteBook_TableRow::AddToTable(QTableWidget *theTable)
00100 {
00101   int aPosition = theTable->rowCount();
00102   int aRowCount = aPosition+1;
00103   theTable->setRowCount(aRowCount);
00104   myRowHeader->setText(QString::number(aRowCount));
00105 
00106   theTable->setVerticalHeaderItem(aPosition,myRowHeader);
00107   theTable->setItem(aPosition, NAME_COLUMN, myVariableName);
00108   theTable->setItem(aPosition, VALUE_COLUMN, myVariableValue);
00109 }
00110 
00111 //============================================================================
00115 //============================================================================
00116 void NoteBook_TableRow::SetName(const QString theName)
00117 {
00118   myVariableName->setText(theName);
00119 }
00120 
00121 //============================================================================
00125 //============================================================================
00126 void NoteBook_TableRow::SetValue(const QString theValue)
00127 {
00128   myVariableValue->setText(theValue);
00129 }
00130 
00131 //============================================================================
00135 //============================================================================
00136 QString NoteBook_TableRow::GetName() const
00137 {
00138   return myVariableName->text();
00139 }
00140 
00141 //============================================================================
00145 //============================================================================
00146 QString NoteBook_TableRow::GetValue() const
00147 {
00148   return myVariableValue->text(); 
00149 }
00150 
00151 //============================================================================
00155 //============================================================================
00156 bool NoteBook_TableRow::CheckName()
00157 {
00158   QString aName = GetName();
00159   int aPos = 0;
00160   QRegExpValidator aValidator( QRegExp("^([a-zA-Z]+)([a-zA-Z0-9_]*)$"), 0 );
00161   if( aName.isEmpty() || !aValidator.validate( aName, aPos ) )
00162     return false;
00163   return true;
00164 }
00165 
00166 //============================================================================
00170 //============================================================================
00171 bool NoteBook_TableRow::CheckValue()
00172 {
00173   bool aResult = false;
00174   QString aValue = GetValue();
00175   if(!aValue.isEmpty() && 
00176      (IsRealValue(aValue) ||
00177       IsIntegerValue(aValue) ||
00178       IsBooleanValue(aValue) ||
00179       IsValidStringValue(aValue)))
00180     aResult = true;
00181   
00182   return aResult;
00183 }
00184 
00185 //============================================================================
00189 //============================================================================
00190 QTableWidgetItem* NoteBook_TableRow::GetVariableItem()
00191 {
00192   return myVariableValue;
00193 }
00194 
00195 //============================================================================
00199 //============================================================================
00200 QTableWidgetItem* NoteBook_TableRow::GetNameItem()
00201 {
00202   return myVariableName;
00203 }
00204 
00205 //============================================================================
00209 //============================================================================
00210 QTableWidgetItem* NoteBook_TableRow::GetHeaderItem()
00211 {
00212   return myRowHeader;
00213 }
00214 
00215 //============================================================================
00220 //============================================================================
00221 bool NoteBook_TableRow::IsRealValue(const QString theValue, double* theResult)
00222 {
00223   bool aResult = false;
00224   double aDResult = theValue.toDouble(&aResult);
00225   if(aResult && theResult)
00226     *theResult = aDResult;
00227   
00228   return aResult;
00229 }
00230 
00231 //============================================================================
00236 //============================================================================
00237 bool NoteBook_TableRow::IsBooleanValue(const QString theValue, bool* theResult){
00238   bool aResult = false;
00239   bool aBResult; 
00240   if(theValue.compare("True") == 0) {
00241     aBResult = true;
00242     aResult = true;
00243   }
00244   else if(theValue.compare("False") == 0) {
00245     aBResult = false;
00246     aResult = true;
00247   }
00248   if(aResult && theResult)
00249     *theResult = aBResult;
00250   
00251   return aResult;
00252 }
00253 
00254 //============================================================================
00259 //============================================================================
00260 bool NoteBook_TableRow::IsIntegerValue(const QString theValue, int* theResult)
00261 {
00262   bool aResult = false;
00263   int anIResult;
00264   anIResult = theValue.toInt(&aResult);
00265 
00266   if(aResult && theResult)
00267     *theResult = anIResult;  
00268   
00269   return aResult;
00270 }
00271 
00272 //============================================================================
00279 //============================================================================
00280 bool NoteBook_TableRow::IsValidStringValue(const QString theValue)
00281 {
00282   int aNumRows = myParentTable->myRows.count();
00283   if( aNumRows == 0 )
00284     return true;
00285 
00286   bool aLastRowIsEmpty = myParentTable->myRows[ aNumRows - 1 ]->GetName().isEmpty() &&
00287                          myParentTable->myRows[ aNumRows - 1 ]->GetValue().isEmpty();
00288 
00289   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
00290   PyConsole_Console* pyConsole = app->pythonConsole();
00291   PyConsole_Interp* pyInterp = pyConsole->getInterp();
00292   PyLockWrapper aLock = pyInterp->GetLockWrapper();
00293   std::string command = "import salome_notebook ; ";
00294   command += "salome_notebook.checkThisNoteBook(";
00295   for( int i = 0, n = aLastRowIsEmpty ? aNumRows - 1 : aNumRows; i < n; i++ ) {
00296     command += myParentTable->myRows[i]->GetName().toStdString();
00297     command += "=\"";
00298     command += myParentTable->myRows[i]->GetValue().toStdString();
00299     command += "\", ";
00300   }
00301   command += ") ";
00302 
00303   //rnv: fix for bug 21947 WinTC5.1.4: Wrong error management of "Salome NoteBook"
00304   bool oldSuppressValue = pyConsole->isSuppressOutput();
00305   pyConsole->setIsSuppressOutput(true);   
00306   bool aResult = pyInterp->run(command.c_str());
00307   pyConsole->setIsSuppressOutput(oldSuppressValue);     
00308   return !aResult;
00309 }
00310 
00312 //                      NoteBook_Table class                             //
00314 //============================================================================
00318 //============================================================================
00319 NoteBook_Table::NoteBook_Table(QWidget * parent)
00320   :QTableWidget(parent),
00321    isProcessItemChangedSignal(false),
00322    myIsModified(false)
00323 {
00324   setColumnCount(2);
00325   setSelectionMode(QAbstractItemView::SingleSelection);
00326   
00327   //Add Headers Columns
00328   QFont aFont = QFont();
00329   aFont.setBold(true);
00330   aFont.setPointSize(10);
00331   
00332   //"Name" column
00333   QTableWidgetItem * aNameHeader = new QTableWidgetItem();
00334   aNameHeader->setText(tr("VARNAME_COLUMN"));
00335   aNameHeader->setFont(aFont);
00336   setHorizontalHeaderItem(0,aNameHeader);
00337   setColumnWidth ( 0, COLUMN_SIZE);
00338 
00339   //"Value" Column
00340   QTableWidgetItem * aValueHeader = new QTableWidgetItem();
00341   aValueHeader->setText(tr("VARVALUE_COLUMN"));
00342   aValueHeader->setFont(aFont);
00343   setHorizontalHeaderItem(1,aValueHeader);
00344   setColumnWidth ( 1, COLUMN_SIZE);
00345   setSortingEnabled(false);
00346   
00347   connect(this,SIGNAL(itemChanged(QTableWidgetItem*)),this,SLOT(onItemChanged(QTableWidgetItem*)));
00348 }
00349 
00350 //============================================================================
00354 //============================================================================
00355 NoteBook_Table::~NoteBook_Table(){}
00356 
00357 //============================================================================
00361 //============================================================================
00362 int NoteBook_Table::getUniqueIndex() const
00363 {
00364   int anIndex = 0;
00365   if( !myRows.isEmpty() )
00366     if( NoteBook_TableRow* aRow = myRows.last() )
00367       anIndex = aRow->GetIndex();
00368 
00369   int aMaxRemovedRow = 0;
00370   for( QListIterator<int> anIter( myRemovedRows ); anIter.hasNext(); )
00371   {
00372     int aRemovedRow = anIter.next();
00373     aMaxRemovedRow = qMax( aRemovedRow, aMaxRemovedRow );
00374   }
00375 
00376   anIndex = qMax( anIndex, aMaxRemovedRow ) + 1;
00377   return anIndex;
00378 }
00379 
00380 //============================================================================
00384 //============================================================================
00385 void NoteBook_Table::Init(_PTR(Study) theStudy)
00386 {
00387   isProcessItemChangedSignal = false;
00388 
00389   int aNumRows = myRows.count();
00390   if( aNumRows > 0 )
00391   {
00392     for( int i = 0; i < myRows.size(); i++ )
00393     {
00394       NoteBook_TableRow* aRow = myRows[ i ];
00395       if( aRow )
00396       {
00397         delete aRow;
00398         aRow = 0;
00399       }
00400     }
00401     myRows.clear();
00402   }
00403   setRowCount( 0 );
00404 
00405   myRemovedRows.clear();
00406   myVariableMapRef.clear();
00407   myVariableMap.clear();
00408 
00409   //Add all variables into the table
00410   std::vector<std::string> aVariables = theStudy->GetVariableNames();
00411   for(int iVar = 0; iVar < aVariables.size(); iVar++ ) {
00412     AddRow(QString(aVariables[iVar].c_str()),
00413            Variable2String(aVariables[iVar],theStudy));
00414   }
00415 
00416   //Add empty row
00417   AddEmptyRow();
00418   isProcessItemChangedSignal = true;
00419 
00420   ResetMaps();
00421 
00422   myStudy = theStudy;
00423 }
00424 
00425 //============================================================================
00429 //============================================================================
00430 QString NoteBook_Table::Variable2String(const std::string& theVarName,
00431                                         _PTR(Study) theStudy)
00432 {
00433   QString aResult;
00434   if( theStudy->IsReal(theVarName) )
00435     aResult = QString::number(theStudy->GetReal(theVarName));
00436   else if( theStudy->IsInteger(theVarName) )
00437     aResult = QString::number(theStudy->GetInteger(theVarName));
00438   else if( theStudy->IsBoolean(theVarName) )
00439     aResult = theStudy->GetBoolean(theVarName) ? QString("True") : QString("False");
00440   else if( theStudy->IsString(theVarName) )
00441     aResult = theStudy->GetString(theVarName).c_str();
00442   
00443   return aResult;
00444 }
00445 
00446 //============================================================================
00450 //============================================================================
00451 bool NoteBook_Table::IsValid() const
00452 {
00453   int aNumRows = myRows.count();
00454   if( aNumRows == 0 )
00455     return true;
00456 
00457   bool aLastRowIsEmpty = myRows[ aNumRows - 1 ]->GetName().isEmpty() &&
00458                          myRows[ aNumRows - 1 ]->GetValue().isEmpty();
00459 
00460   for( int i = 0, n = aLastRowIsEmpty ? aNumRows - 1 : aNumRows; i < n; i++ )
00461     if( !myRows[i]->CheckName() || !IsUniqueName( myRows[i] ) || !myRows[i]->CheckValue() )
00462       return false;
00463 
00464   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
00465   PyConsole_Console* pyConsole = app->pythonConsole();
00466   PyConsole_Interp* pyInterp = pyConsole->getInterp();
00467   PyLockWrapper aLock = pyInterp->GetLockWrapper();
00468   std::string command = "import salome_notebook ; ";
00469   command += "salome_notebook.checkThisNoteBook(";
00470   for( int i = 0, n = aLastRowIsEmpty ? aNumRows - 1 : aNumRows; i < n; i++ )
00471     {
00472       command += myRows[i]->GetName().toStdString();
00473       command += "=\"";
00474       command += myRows[i]->GetValue().toStdString();
00475       command += "\",";
00476     }
00477   command += ")";
00478 
00479   //rnv: fix for bug 21947 WinTC5.1.4: Wrong error management of "Salome NoteBook"
00480   bool oldSuppressValue = pyConsole->isSuppressOutput();
00481   pyConsole->setIsSuppressOutput(true);   
00482   bool aResult = pyInterp->run(command.c_str());
00483   pyConsole->setIsSuppressOutput(oldSuppressValue);     
00484 
00485   return !aResult;
00486 }
00487 
00488 //============================================================================
00492 //============================================================================
00493 void NoteBook_Table::RenamberRowItems() {
00494   for(int i=0; i<myRows.size();i++){
00495     myRows[i]->GetHeaderItem()->setText(QString::number(i+1));
00496   }
00497 }
00498 
00499 //============================================================================
00503 //============================================================================
00504 void NoteBook_Table::AddRow(const QString& theName, const QString& theValue)
00505 {
00506   int anIndex = getUniqueIndex();
00507   NoteBook_TableRow* aRow = new NoteBook_TableRow(anIndex, this, this);
00508   aRow->SetName(theName);
00509   aRow->SetValue(theValue);
00510   aRow->AddToTable(this);
00511   myRows.append(aRow);
00512 
00513   myVariableMap.insert( anIndex, NoteBoox_Variable( theName, theValue ) );
00514 }
00515 
00516 //============================================================================
00520 //============================================================================
00521 void NoteBook_Table::AddEmptyRow()
00522 {
00523   isProcessItemChangedSignal = false;
00524   AddRow();
00525   isProcessItemChangedSignal = true;
00526 }
00527 
00528 //============================================================================
00532 //============================================================================
00533 NoteBook_TableRow* NoteBook_Table::GetRowByItem(const QTableWidgetItem* theItem) const
00534 {
00535   int aCurrentRow = row(theItem);
00536   
00537   if( (myRows.size() <= aCurrentRow ) && (aCurrentRow < 0))
00538     return NULL;
00539   else
00540     return myRows.at(aCurrentRow);
00541 }
00542 
00543 //============================================================================
00547 //============================================================================
00548 bool NoteBook_Table::IsLastRow(const NoteBook_TableRow* theRow) const
00549 {
00550   return (myRows.last() == theRow);
00551 }
00552 
00553 //============================================================================
00557 //============================================================================
00558 void NoteBook_Table::onItemChanged(QTableWidgetItem* theItem)
00559 {
00560   if(isProcessItemChangedSignal) {
00561     bool isModified = true;
00562     NoteBook_TableRow* aRow = GetRowByItem(theItem);
00563     if(aRow) {
00564       int aCurrentColumn = column(theItem);
00565       bool IsCorrect = true, IsVariableComplited = false;
00566       QString aMsg;
00567 
00568       if(aCurrentColumn == NAME_COLUMN) {
00569         int anIndex = aRow->GetIndex();
00570         if( myVariableMap.contains( anIndex ) )
00571         {
00572           const NoteBoox_Variable& aVariable = myVariableMap[ anIndex ];
00573           if( !aVariable.Name.isEmpty() && myStudy->IsVariableUsed( std::string( aVariable.Name.toLatin1().constData() ) ) )
00574           {
00575             if( QMessageBox::warning( parentWidget(), tr( "WARNING" ),
00576                                       tr( "RENAME_VARIABLE_IS_USED" ).arg( aVariable.Name ),
00577                                       QMessageBox::Yes, QMessageBox::No ) == QMessageBox::No )
00578             {
00579               bool isBlocked = blockSignals( true );
00580               aRow->SetName( aVariable.Name );
00581               blockSignals( isBlocked );
00582               return;
00583             }
00584           }
00585         }
00586       }
00587 
00588       //Case then varible name changed. 
00589       if(aCurrentColumn == NAME_COLUMN) {
00590         if(!aRow->CheckName()) {
00591           IsCorrect = false;
00592           aMsg = tr( "VARNAME_INCORRECT" ).arg(aRow->GetName());
00593         }
00594         else if(!IsUniqueName(aRow)) {
00595           IsCorrect = false;
00596           aMsg = tr( "VARNAME_EXISTS" ).arg(aRow->GetName());
00597         }
00598         else
00599           IsVariableComplited = aRow->CheckValue();
00600       }
00601       
00602       //Case then varible value changed. 
00603       else if(aCurrentColumn == VALUE_COLUMN){
00604         if(!aRow->CheckValue()) {
00605           IsCorrect = false;
00606           aMsg = tr( "VARVALUE_INCORRECT" ).arg(aRow->GetName());
00607         }
00608         else
00609           IsVariableComplited = aRow->CheckName() && IsUniqueName(aRow);
00610       }
00611 
00612       if(!IsCorrect && !aMsg.isEmpty())
00613         SUIT_MessageBox::warning( parentWidget(), tr( "WARNING" ), aMsg );
00614 
00615       bool isBlocked = blockSignals( true );
00616       theItem->setForeground( QBrush( IsCorrect ? Qt::black : Qt::red ) );
00617       blockSignals( isBlocked );
00618 
00619       int anIndex = aRow->GetIndex();
00620       if( myVariableMap.contains( anIndex ) )
00621       {
00622         NoteBoox_Variable& aVariable = myVariableMap[ anIndex ];
00623         if( aVariable.Name.compare( aRow->GetName() ) != 0 ||
00624             aVariable.Value.compare( aRow->GetValue() ) != 0 )
00625         {
00626           aVariable.Name = aRow->GetName();
00627           aVariable.Value = aRow->GetValue();
00628         }
00629         else
00630           isModified = false;
00631       }
00632 
00633       if(IsCorrect && IsVariableComplited && IsLastRow(aRow))
00634         AddEmptyRow();
00635     }
00636 
00637     if( !myIsModified )
00638       myIsModified = isModified;
00639   }
00640 }
00641 
00642 //============================================================================
00646 //============================================================================
00647 bool NoteBook_Table::IsUniqueName(const NoteBook_TableRow* theRow) const
00648 {
00649   for(int i=0; i<myRows.size();i++) {
00650     if(myRows[i] == theRow ) 
00651       continue;
00652     if(myRows[i]->GetName().compare(theRow->GetName()) == 0)
00653       return false;
00654   }
00655   return true;
00656 }
00657 
00658 //============================================================================
00662 //============================================================================
00663 void NoteBook_Table::RemoveSelected()
00664 {
00665   isProcessItemChangedSignal = false;
00666   QList<QTableWidgetItem*> aSelectedItems = selectedItems();
00667   if( !(aSelectedItems.size() > 0)) {
00668     isProcessItemChangedSignal = true;
00669     return;
00670   }
00671   bool removedFromStudy = false;
00672   for(int i=0; i < aSelectedItems.size(); i++ ) {
00673     NoteBook_TableRow* aRow = GetRowByItem(aSelectedItems[i]);
00674     if(aRow) {
00675       if(IsLastRow(aRow)) {
00676         aRow->SetName(QString());
00677         aRow->SetValue(QString());
00678       }
00679       else {
00680         int nRow = row(aSelectedItems[i]);
00681 
00682         if( myStudy->IsVariableUsed( std::string( aRow->GetName().toLatin1().constData() ) ) )
00683         {
00684           if( QMessageBox::warning( parentWidget(), tr( "WARNING" ),
00685                                     tr( "REMOVE_VARIABLE_IS_USED" ).arg( aRow->GetName() ),
00686                                     QMessageBox::Yes, QMessageBox::No ) == QMessageBox::No )
00687           {
00688             isProcessItemChangedSignal = true;
00689             return;
00690           }
00691         }
00692 
00693         int index = aRow->GetIndex();
00694         QString aVarName = aRow->GetName();
00695         myRemovedRows.append( index );
00696         if( myVariableMap.contains( index ) )
00697           myVariableMap.remove( index );
00698         removeRow(nRow);
00699         myRows.removeAt(nRow);
00700         if(myStudy->IsVariable(aVarName.toLatin1().constData()))
00701           removedFromStudy = true;
00702       }
00703     }
00704   }
00705   if(removedFromStudy)
00706     myIsModified = true;
00707   RenamberRowItems();
00708   isProcessItemChangedSignal = true;
00709 }
00710 
00711 //============================================================================
00715 //============================================================================
00716 void NoteBook_Table::SetProcessItemChangedSignalFlag(const bool enable)
00717 {
00718   isProcessItemChangedSignal = enable;
00719 }
00720 
00721 //============================================================================
00725 //============================================================================
00726 bool NoteBook_Table::GetProcessItemChangedSignalFlag() const
00727 {
00728   return isProcessItemChangedSignal;
00729 }
00730 
00731 //============================================================================
00735 //============================================================================
00736 QList<NoteBook_TableRow*> NoteBook_Table::GetRows() const
00737 {
00738   return myRows;
00739 }
00740 
00741 //============================================================================
00745 //============================================================================
00746 void NoteBook_Table::ResetMaps()
00747 {
00748   myIsModified = false;
00749   myVariableMapRef = myVariableMap;
00750   myRemovedRows.clear();
00751 }
00752 
00754 //                  SalomeApp_NoteBookDlg class                          //
00756 //============================================================================
00760 //============================================================================
00761 SalomeApp_NoteBookDlg::SalomeApp_NoteBookDlg(QWidget * parent, _PTR(Study) theStudy):
00762   QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
00763   myStudy(theStudy)
00764 {
00765   setModal(false);
00766   setObjectName("SalomeApp_NoteBookDlg");
00767   setWindowTitle(tr("NOTEBOOK_TITLE"));
00768   QGridLayout* aLayout = new QGridLayout(this);
00769   aLayout->setMargin(DEFAULT_MARGIN);
00770   aLayout->setSpacing(DEFAULT_SPACING);
00771 
00772   //Table
00773   myTable = new NoteBook_Table(this);
00774   aLayout->addWidget(myTable, 0, 0, 1, 3);
00775   
00776   //Buttons
00777   myRemoveButton = new QPushButton(tr("BUT_REMOVE"));
00778   aLayout->addWidget(myRemoveButton, 1, 0, 1, 1);
00779 
00780   QSpacerItem* spacer =
00781     new QSpacerItem(DEFAULT_SPACING, 5 , QSizePolicy::Expanding, QSizePolicy::Minimum);
00782   aLayout->addItem(spacer, 1, 1, 2, 1);
00783 
00784   myUpdateStudyBtn = new QPushButton(tr("BUT_UPDATE_STUDY"));
00785   aLayout->addWidget(myUpdateStudyBtn, 1, 2, 1, 1);
00786   
00787   QGroupBox* groupBox = new QGroupBox(this);
00788 
00789   QGridLayout* aLayout1 = new QGridLayout(groupBox);
00790 
00791   aLayout1->setMargin(DEFAULT_MARGIN);
00792   aLayout1->setSpacing(DEFAULT_SPACING);
00793 
00794   myOkBtn = new QPushButton(tr("BUT_APPLY_AND_CLOSE"));
00795   aLayout1->addWidget(myOkBtn, 0, 0, 1, 1);
00796   
00797   myApplyBtn = new QPushButton(tr("BUT_APPLY"));
00798   aLayout1->addWidget(myApplyBtn, 0, 1, 1, 1);  
00799 
00800   QSpacerItem* spacer1 =
00801     new QSpacerItem(DEFAULT_SPACING, 5, QSizePolicy::Expanding, QSizePolicy::Minimum);
00802   aLayout1->addItem(spacer1, 0, 2, 1, 1);
00803 
00804   myCancelBtn = new QPushButton(tr("BUT_CLOSE"));
00805   aLayout1->addWidget(myCancelBtn, 0, 3, 1, 1);
00806 
00807   myHelpBtn = new QPushButton(tr("BUT_HELP"));
00808   aLayout1->addWidget(myHelpBtn, 0, 4, 1, 1);
00809   
00810   aLayout->addWidget(groupBox, 2, 0, 1, 3);
00811 
00812   QWidgetList aWidgetList;
00813   aWidgetList.append( myTable );
00814   aWidgetList.append( myOkBtn );
00815   aWidgetList.append( myApplyBtn );
00816   aWidgetList.append( myCancelBtn );
00817   aWidgetList.append( myHelpBtn );
00818   aWidgetList.append( myUpdateStudyBtn );
00819   aWidgetList.append( myRemoveButton );
00820   Qtx::setTabOrder( aWidgetList );
00821 
00822   connect( myOkBtn, SIGNAL(clicked()), this, SLOT(onOK()) );
00823   connect( myApplyBtn, SIGNAL(clicked()), this, SLOT(onApply()) );
00824   connect( myCancelBtn, SIGNAL(clicked()), this, SLOT(onCancel()) );
00825   connect( myUpdateStudyBtn, SIGNAL(clicked()), this, SLOT(onUpdateStudy()) );
00826   connect( myRemoveButton, SIGNAL(clicked()), this, SLOT(onRemove()));
00827   connect( myHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp()));
00828   
00829   myTable->Init(myStudy);
00830 }
00831 
00832 //============================================================================
00836 //============================================================================
00837 SalomeApp_NoteBookDlg::~SalomeApp_NoteBookDlg(){}
00838 
00839 
00840 //============================================================================
00844 //============================================================================
00845 void SalomeApp_NoteBookDlg::Init(_PTR(Study) theStudy){
00846   if(myStudy!= theStudy)
00847     myStudy = theStudy;
00848   myTable->Init(myStudy);
00849 }
00850 
00851 
00852 //============================================================================
00856 //============================================================================
00857 void SalomeApp_NoteBookDlg::onOK()
00858 {
00859   onApply();
00860   if( myTable->IsValid() )
00861     accept();
00862 }
00863 
00864 //============================================================================
00868 //============================================================================
00869 void SalomeApp_NoteBookDlg::onHelp()
00870 {
00871   QString aHelpFileName("using_notebook.html");
00872   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
00873   if (app)
00874     app->onHelpContextModule("GUI",aHelpFileName);
00875   else {
00876     QString platform;
00877 #ifdef WIN32
00878     platform = "winapplication";
00879 #else
00880     platform = "application";
00881 #endif
00882     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
00883                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
00884                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
00885                                                                  platform)).
00886                              arg(aHelpFileName));
00887   }
00888 
00889 }
00890 //============================================================================
00894 //============================================================================
00895 void SalomeApp_NoteBookDlg::onApply()
00896 {
00897   if( !myTable->IsValid() )
00898   {
00899     SUIT_MessageBox::warning( this, tr( "WARNING" ), tr( "INCORRECT_DATA" ) );
00900     return;
00901   }
00902 
00903   double aDVal;
00904   int    anIVal;
00905   bool   aBVal;
00906 
00907   const QList<int>& aRemovedRows = myTable->GetRemovedRows();
00908   const VariableMap& aVariableMap = myTable->GetVariableMap();
00909   const VariableMap& aVariableMapRef = myTable->GetVariableMapRef();
00910 
00911   for( QListIterator<int> anIter( aRemovedRows ); anIter.hasNext(); )
00912   {
00913     int anIndex = anIter.next();
00914     if( aVariableMapRef.contains( anIndex ) )
00915     {
00916       QString aRemovedVariable = aVariableMapRef[ anIndex ].Name;
00917       myStudy->RemoveVariable( std::string( aRemovedVariable.toLatin1().constData() ) );
00918     }
00919   }
00920 
00921   VariableMap::const_iterator it = aVariableMap.constBegin(), itEnd = aVariableMap.constEnd();
00922   for( ; it != itEnd; ++it )
00923   {
00924     int anIndex = it.key();
00925     const NoteBoox_Variable& aVariable = it.value();
00926     QString aName = aVariable.Name;
00927     QString aValue = aVariable.Value;
00928 
00929     if( !aName.isEmpty() && !aValue.isEmpty() )
00930     {
00931       if( aVariableMapRef.contains( anIndex ) )
00932       {
00933         const NoteBoox_Variable& aVariableRef = aVariableMapRef[ anIndex ];
00934         QString aNameRef = aVariableRef.Name;
00935         QString aValueRef = aVariableRef.Value;
00936 
00937         if( !aNameRef.isEmpty() && !aValueRef.isEmpty() && aNameRef != aName )
00938         {
00939           myStudy->RenameVariable( std::string( aNameRef.toLatin1().constData() ),
00940                                    std::string( aName.toLatin1().constData() ) );
00941         }
00942       }
00943 
00944       if( NoteBook_TableRow::IsIntegerValue(aValue,&anIVal) )
00945         myStudy->SetInteger(std::string(aName.toLatin1().constData()),anIVal);
00946 
00947       else if( NoteBook_TableRow::IsRealValue(aValue,&aDVal) )
00948         myStudy->SetReal(std::string(aName.toLatin1().constData()),aDVal);
00949     
00950       else if( NoteBook_TableRow::IsBooleanValue(aValue,&aBVal) )
00951         myStudy->SetBoolean(std::string(aName.toLatin1().constData()),aBVal);
00952     
00953       else
00954         myStudy->SetString(std::string(aName.toLatin1().constData()),aValue.toStdString());
00955     }
00956   }
00957   myTable->ResetMaps();
00958 
00959   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
00960   if(app)
00961     app->updateActions();
00962 
00963 }
00964 
00965 //============================================================================
00969 //============================================================================
00970 void SalomeApp_NoteBookDlg::onCancel()
00971 {
00972   if( myTable->IsModified() )
00973   {
00974     int answer = QMessageBox::question( this, tr( "CLOSE_CAPTION" ), tr( "CLOSE_DESCRIPTION" ),
00975                                         QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel );
00976     switch( answer )
00977     {
00978       case QMessageBox::Yes    : onOK(); return;
00979       case QMessageBox::No     : break;
00980       case QMessageBox::Cancel : return;
00981       default : break;
00982     }
00983   }
00984   reject();
00985 }
00986 
00987 //============================================================================
00991 //============================================================================
00992 void SalomeApp_NoteBookDlg::onRemove()
00993 {
00994   myTable->RemoveSelected();
00995 }
00996 
00997 //============================================================================
01001 //============================================================================
01002 void SalomeApp_NoteBookDlg::onUpdateStudy()
01003 {
01004   onApply();
01005   if( !myTable->IsValid() )
01006     return;
01007 
01008   QApplication::setOverrideCursor( Qt::WaitCursor );
01009 
01010   if( !updateStudy() )
01011     SUIT_MessageBox::warning( this, tr( "ERROR" ), tr( "ERR_UPDATE_STUDY_FAILED" ) );
01012     
01013   QApplication::restoreOverrideCursor();
01014 }
01015 
01016 //============================================================================
01020 //============================================================================
01021 bool SalomeApp_NoteBookDlg::updateStudy()
01022 {
01023   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
01024   if( !app )
01025     return false;
01026 
01027   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
01028   if( !study )
01029     return false;
01030 
01031   bool isStudySaved = study->isSaved();
01032   QString aStudyName = study->studyName();
01033 
01034   _PTR(Study) studyDS = study->studyDS();
01035 
01036   // get unique temporary directory name
01037   QString aTmpDir = QString::fromStdString( SALOMEDS_Tool::GetTmpDir() );
01038   if( aTmpDir.isEmpty() )
01039     return false;
01040 
01041   if( aTmpDir.right( 1 ).compare( QDir::separator() ) == 0 )
01042     aTmpDir.remove( aTmpDir.length() - 1, 1 );
01043 
01044   // dump study to the temporary directory
01045   QString aFileName( "notebook" );
01046   bool toPublish = true;
01047   bool isMultiFile = false;
01048   bool toSaveGUI = true;
01049 
01050   int savePoint;
01051   _PTR(AttributeParameter) ap;
01052   _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
01053   if(ip->isDumpPython(studyDS)) ip->setDumpPython(studyDS); //Unset DumpPython flag.
01054   if ( toSaveGUI ) { //SRN: Store a visual state of the study at the save point for DumpStudy method
01055     ip->setDumpPython(studyDS);
01056     savePoint = SalomeApp_VisualState( app ).storeState(); //SRN: create a temporary save point
01057   }
01058   bool ok = studyDS->DumpStudy( aTmpDir.toStdString(), aFileName.toStdString(), toPublish, isMultiFile );
01059   if ( toSaveGUI )
01060     study->removeSavePoint(savePoint); //SRN: remove the created temporary save point.
01061 
01062   if( !ok )
01063     return false;
01064 
01065   // clear a study (delete all objects)
01066   clearStudy();
01067 
01068   // get active application
01069   app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
01070 
01071   // load study from the temporary directory
01072   QString command = QString( "execfile(r\"%1\")" ).arg( aTmpDir + QDir::separator() + aFileName + ".py" );
01073 
01074   PyConsole_Console* pyConsole = app->pythonConsole();
01075   if ( pyConsole )
01076     pyConsole->execAndWait( command );
01077 
01078   // remove temporary directory
01079   QDir aDir( aTmpDir );
01080   QStringList aFiles = aDir.entryList( QStringList( "*.py*" ) );
01081   for( QStringList::iterator it = aFiles.begin(), itEnd = aFiles.end(); it != itEnd; ++it )
01082     ok = aDir.remove( *it ) && ok;
01083   if( ok )
01084     ok = aDir.rmdir( aTmpDir );
01085 
01086   if( SalomeApp_Study* newStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) )
01087   {
01088     myStudy = newStudy->studyDS();
01089     myTable->Init(myStudy);
01090     if(isStudySaved) {
01091       newStudy->markAsSavedIn(aStudyName);
01092     }
01093   }
01094   else
01095     ok = false;
01096 
01097   return ok;
01098 }
01099 
01100 //============================================================================
01104 //============================================================================
01105 void SalomeApp_NoteBookDlg::clearStudy()
01106 {
01107   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
01108   if( !app )
01109     return;
01110 
01111   QList<SUIT_Application*> aList = SUIT_Session::session()->applications();
01112   int anIndex = aList.indexOf( app );
01113 
01114   //Store position and size of the this dialog
01115   int aW = width();
01116   int aH = height();
01117   int aX = x();
01118   int aY = y();
01119 
01120   // Disconnect dialog from application desktop in case if:
01121   // 1) Application is not the first application in the session 
01122   // 2) Application is the first application in session but not the only.
01123   bool changeDesktop = ((anIndex > 0) || (anIndex == 0 && aList.count() > 1));
01124 
01125   if( changeDesktop )
01126     setParent( 0 );
01127 
01128   app->onCloseDoc( false );
01129   
01130   if( anIndex > 0 && anIndex < aList.count() )
01131     app = dynamic_cast<SalomeApp_Application*>( aList[ anIndex - 1 ] );
01132   else if(anIndex == 0 && aList.count() > 1)
01133     app = dynamic_cast<SalomeApp_Application*>( aList[ 1 ] );
01134 
01135   if( !app )
01136     return;
01137 
01138   app->onNewDoc();
01139 
01140   app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
01141   if( changeDesktop && app ) {
01142     setParent( app->desktop(), Qt::Dialog );
01143     app->setNoteBook(this);
01144   }
01145   //Set position and size of the this dialog
01146   resize( aW, aH );
01147   move( aX, aY );
01148   show();
01149 }