Salome HOME
074f2d3e351034adf06895a9dbe733e26bf2bf77
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_FilterLibraryDlg.cxx
1 // SMESH SMESHGUI : GUI for SMESH component
2 //
3 // Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 //
6 // This library is free software; you can redistribute it and/or 
7 // modify it under the terms of the GNU Lesser General Public 
8 // License as published by the Free Software Foundation; either 
9 // version 2.1 of the License. 
10 //
11 // This library is distributed in the hope that it will be useful, 
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 // Lesser General Public License for more details. 
15 //
16 // You should have received a copy of the GNU Lesser General Public 
17 // License along with this library; if not, write to the Free Software 
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File   : SMESHGUI_FilterLibraryDlg.cxx
23 // Author : Sergey LITONIN, Open CASCADE S.A.S.
24 //
25
26 // SMESH includes
27 #include "SMESHGUI_FilterLibraryDlg.h"
28
29 #include "SMESHGUI.h"
30 #include "SMESHGUI_FilterUtils.h"
31 #include "SMESHGUI_FilterDlg.h"
32
33 // SALOME GUI includes
34 #include <SUIT_Session.h>
35 #include <SUIT_Desktop.h>
36 #include <SUIT_FileDlg.h>
37 #include <SUIT_MessageBox.h>
38 #include <SUIT_ResourceMgr.h>
39
40 #include <LightApp_Application.h>
41
42 // Qt includes
43 #include <QApplication>
44 #include <QVBoxLayout>
45 #include <QHBoxLayout>
46 #include <QGridLayout>
47 #include <QLineEdit>
48 #include <QPushButton>
49 #include <QGroupBox>
50 #include <QLabel>
51 #include <QListWidget>
52 #include <QFileInfo>
53 #include <QDir>
54 #include <QKeyEvent>
55
56 #define SPACING 6
57 #define MARGIN  11
58
59 /*!
60  *  Class       : SMESHGUI_FilterLibraryDlg::Dialog
61  *  Description : Dialog for opening filter library
62  */
63
64 class SMESHGUI_FilterLibraryDlg::Dialog : public SUIT_FileDlg
65 {
66 public:
67   Dialog(QWidget* theParent, const bool theToOpen);
68   virtual ~Dialog();
69
70 protected:
71   virtual bool acceptData();
72 };
73
74 SMESHGUI_FilterLibraryDlg::Dialog::Dialog (QWidget*   theParent,
75                                            const bool theToOpen)
76   : SUIT_FileDlg(theParent, theToOpen)
77 {
78 }
79
80 SMESHGUI_FilterLibraryDlg::Dialog::~Dialog()
81 {
82 }
83
84 bool SMESHGUI_FilterLibraryDlg::Dialog::acceptData()
85 {
86 //  if (mode() != QFileDialogP::AnyFile)
87 //    return SUIT_FileDlg::acceptData();
88
89   return true;
90 }
91
92 /*!
93  *  Class       : SMESHGUI_FilterLibraryDlg
94  *  Description : Dialog to specify filters for VTK viewer
95  */
96
97 //=======================================================================
98 // name    : SMESHGUI_FilterLibraryDlg::SMESHGUI_FilterLibraryDlg
99 // Purpose : Constructor
100 //=======================================================================
101 SMESHGUI_FilterLibraryDlg::SMESHGUI_FilterLibraryDlg (SMESHGUI* theModule,
102                                                       QWidget* parent,
103                                                       const QList<int>& theTypes,
104                                                       const int theMode)
105   : QDialog( parent ),
106     mySMESHGUI( theModule )
107 {
108   setModal(false);
109   construct(theTypes, theMode);
110 }
111
112 //=======================================================================
113 // name    : SMESHGUI_FilterLibraryDlg::SMESHGUI_FilterLibraryDlg
114 // Purpose : Constructor
115 //=======================================================================
116 SMESHGUI_FilterLibraryDlg::SMESHGUI_FilterLibraryDlg (SMESHGUI* theModule,
117                                                       QWidget* parent,
118                                                       const int   theType,
119                                                       const int   theMode)
120   : QDialog( parent ),
121     mySMESHGUI( theModule )
122 {
123   setModal(true);
124   QList<int> aTypes;
125   aTypes.append(theType);
126   construct(aTypes, theMode);
127 }
128
129 //=======================================================================
130 // name    : SMESHGUI_FilterLibraryDlg::construct
131 // Purpose : Construct dialog (called by constructor)
132 //=======================================================================
133 void SMESHGUI_FilterLibraryDlg::construct (const QList<int>& theTypes,
134                                            const int theMode)
135 {
136   myTypes = theTypes;
137   myMode  = theMode;
138
139   QVBoxLayout* aDlgLay = new QVBoxLayout(this);
140   aDlgLay->setMargin(MARGIN);
141   aDlgLay->setSpacing(SPACING);
142
143   myMainFrame        = createMainFrame  (this);
144   QWidget* aBtnFrame = createButtonFrame(this);
145
146   aDlgLay->addWidget(myMainFrame);
147   aDlgLay->addWidget(aBtnFrame);
148
149   aDlgLay->setStretchFactor(myMainFrame, 1);
150
151   myHelpFileName = "selection_filter_library_page.html";
152   
153   Init(myTypes, myMode);
154 }
155
156 //=======================================================================
157 // name    : SMESHGUI_FilterLibraryDlg::createMainFrame
158 // Purpose : Create frame containing dialog's input fields
159 //=======================================================================
160 QWidget* SMESHGUI_FilterLibraryDlg::createMainFrame (QWidget* theParent)
161 {
162   QWidget* aMainFrame = new QWidget(theParent);
163   QGridLayout* aMainLay = new QGridLayout(aMainFrame);
164   aMainLay->setMargin(0);
165   aMainLay->setSpacing(SPACING);
166
167   // library name
168
169   QLabel* aFileLab = new QLabel(tr("LIBRARY_FILE"), aMainFrame);
170   myFileName = new QLineEdit(aMainFrame);
171   myOpenBtn = new QPushButton(aMainFrame);
172   myOpenBtn->setIcon(SUIT_Session::session()->resourceMgr()->loadPixmap(
173     "SUIT", tr("ICON_FILE_OPEN")));
174
175   // filters list box
176
177   QGroupBox* aFiltersGrp = new QGroupBox(tr("FILTER_NAMES"), aMainFrame);
178   QGridLayout* aLay = new QGridLayout(aFiltersGrp);
179   aLay->setMargin(MARGIN);
180   aLay->setSpacing(SPACING);
181
182   myListBox = new QListWidget(aFiltersGrp);
183
184   myAddBtn    = new QPushButton(tr("ADD"), aFiltersGrp);
185   myDeleteBtn = new QPushButton(tr("DELETE"), aFiltersGrp);
186
187   aLay->addWidget(myListBox,   0, 0, 3, 1);
188   aLay->addWidget(myAddBtn,    0, 1);
189   aLay->addWidget(myDeleteBtn, 1, 1);
190   aLay->setRowStretch(2, 5);
191
192   // filter name
193
194   myNameGrp = new QWidget(aMainFrame);
195   QHBoxLayout* myNameGrpLayout = new QHBoxLayout(myNameGrp);
196   myNameGrpLayout->setMargin(0);
197   myNameGrpLayout->setSpacing(SPACING);
198
199   myNameGrpLayout->addWidget( new QLabel(tr("FILTER_NAME"), myNameGrp) );
200   myNameGrpLayout->addWidget( myName = new QLineEdit(myNameGrp) );
201
202   // table
203
204   myTable = new SMESHGUI_FilterTable( mySMESHGUI, aMainFrame, myTypes);
205   myTable->SetEditable(myMode == EDIT);
206   myTable->SetLibsEnabled(false);
207
208   myListBox->setMinimumHeight((int)(myTable->sizeHint().height() * 0.5));
209   //myListBox->setRowMode(QListWidget::FitToWidth); //VSR : TODO ???
210   myListBox->setSelectionMode(QListWidget::SingleSelection);
211
212   myOpenBtn->setAutoDefault(false);
213   myAddBtn->setAutoDefault(false);
214   myDeleteBtn->setAutoDefault(false);
215
216   aMainLay->addWidget(aFileLab,    0, 0);
217   aMainLay->addWidget(myFileName,  0, 1);
218   aMainLay->addWidget(myOpenBtn,   0, 2);
219   aMainLay->addWidget(aFiltersGrp, 1, 0, 1, 3);
220   aMainLay->addWidget(myNameGrp,   2, 0, 1, 3);
221   aMainLay->addWidget(myTable,     3, 0, 1, 3);
222
223   // connect signals and slots
224
225   connect(myFileName, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
226   connect(myOpenBtn, SIGNAL(clicked()), this, SLOT(onBrowse()));
227
228   connect(myListBox, SIGNAL( currentItemChanged( QListWidgetItem*, QListWidgetItem* ) ),
229           this, SLOT( onFilterChanged( QListWidgetItem*, QListWidgetItem* ) ) );
230
231   connect(myAddBtn, SIGNAL(clicked()), this, SLOT(onAddBtnPressed()));
232   connect(myDeleteBtn, SIGNAL(clicked()), this, SLOT(onDeleteBtnPressed()));
233
234   connect(myName, SIGNAL(textChanged(const QString&)),
235            this, SLOT(onFilterNameChanged(const QString&)));
236
237   connect(myTable, SIGNAL(EntityTypeChanged(const int)),
238            this, SLOT(onEntityTypeChanged(const int)));
239
240   connect(myTable, SIGNAL(NeedValidation()), this, SLOT(onNeedValidation()));
241
242   return aMainFrame;
243 }
244
245 //=======================================================================
246 // name    : SMESHGUI_FilterLibraryDlg::createButtonFrame
247 // Purpose : Create frame containing buttons
248 //=======================================================================
249 QWidget* SMESHGUI_FilterLibraryDlg::createButtonFrame (QWidget* theParent)
250 {
251   QGroupBox* aGrp = new QGroupBox(theParent);
252   QHBoxLayout* aLay = new QHBoxLayout(aGrp);
253   aLay->setMargin(MARGIN);
254   aLay->setSpacing(SPACING);
255
256   myButtons[ BTN_OK    ] = new QPushButton(tr("SMESH_BUT_OK"   ), aGrp);
257   myButtons[ BTN_Apply ] = new QPushButton(tr("SMESH_BUT_APPLY"), aGrp);
258
259   myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"), aGrp);
260   myButtons[ BTN_Close  ] = new QPushButton(tr("SMESH_BUT_CLOSE"),  aGrp);
261   myButtons[ BTN_Help   ] = new QPushButton(tr("SMESH_BUT_HELP"),   aGrp);
262
263   aLay->addWidget(myButtons[ BTN_OK     ]);
264   aLay->addSpacing(10);
265   aLay->addWidget(myButtons[ BTN_Apply  ]);
266   aLay->addSpacing(10);
267   aLay->addStretch();
268   aLay->addWidget(myButtons[ BTN_Cancel ]);
269   aLay->addWidget(myButtons[ BTN_Close  ]);
270   aLay->addWidget(myButtons[ BTN_Help   ]);
271
272   connect(myButtons[ BTN_OK     ], SIGNAL(clicked()), SLOT(onOk()));
273   connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose()));
274   connect(myButtons[ BTN_Close  ], SIGNAL(clicked()), SLOT(onClose()));
275   connect(myButtons[ BTN_Apply  ], SIGNAL(clicked()), SLOT(onApply()));
276   connect(myButtons[ BTN_Help   ], SIGNAL(clicked()), SLOT(onHelp()));
277
278   QMap<int, QPushButton*>::iterator anIter;
279   for (anIter = myButtons.begin(); anIter != myButtons.end(); ++anIter)
280     anIter.value()->setAutoDefault(false);
281
282   updateMainButtons();
283
284   return aGrp;
285 }
286
287 //=======================================================================
288 // name    : SMESHGUI_FilterLibraryDlg::updateMainButtons
289 // Purpose : Update visibility of main buttons (OK, Cancel, Close ...)
290 //=======================================================================
291 void SMESHGUI_FilterLibraryDlg::updateMainButtons()
292 {
293   if (myTypes.count() == 1) {
294     myButtons[ BTN_Cancel ]->show();
295     myButtons[ BTN_Apply  ]->hide();
296     myButtons[ BTN_Close  ]->hide();
297   } else {
298     myButtons[ BTN_Cancel ]->hide();
299     myButtons[ BTN_Apply  ]->show();
300     myButtons[ BTN_Close  ]->show();
301   }
302 }
303
304 //=======================================================================
305 // name    : SMESHGUI_FilterLibraryDlg::~SMESHGUI_FilterLibraryDlg
306 // Purpose : Destructor
307 //=======================================================================
308 SMESHGUI_FilterLibraryDlg::~SMESHGUI_FilterLibraryDlg()
309 {
310 }
311
312 //=======================================================================
313 // name    : SMESHGUI_FilterLibraryDlg::Init
314 // Purpose : Init dialog fields, connect signals and slots, show dialog
315 //=======================================================================
316 void SMESHGUI_FilterLibraryDlg::Init (const int type, const int theMode)
317 {
318   QList<int> aTypes;
319   aTypes.append(type);
320   Init(aTypes, theMode);
321 }
322
323 //=======================================================================
324 // name    : SMESHGUI_FilterLibraryDlg::Init
325 // Purpose : Init dialog fields, connect signals and slots, show dialog
326 //=======================================================================
327 void SMESHGUI_FilterLibraryDlg::Init (const QList<int>& theTypes,
328                                       const int theMode)
329 {
330   myMode = theMode;
331   myTypes = theTypes;
332   myTable->Init(theTypes);
333   myCurrFilterName = "";
334   myCurrFilter = -1;
335   myListBox->blockSignals(true);
336   myListBox->clear();
337   myListBox->blockSignals(false);
338   myName->clear();
339   myTable->Clear();
340
341   updateControlsVisibility();
342   setEnabled(true);
343
344   connect( mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
345   connect( mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
346
347   if (myMode == ADD_TO)
348   {
349     setWindowTitle(tr("ADD_TO_TLT"));
350     if (myFileName->text().isEmpty())
351       myFileName->setText(getDefaultLibraryName());
352     processNewLibrary();
353   }
354   else if (myMode == COPY_FROM)
355   {
356     setWindowTitle(tr("COPY_FROM_TLT"));
357     if (myFileName->text().isEmpty())
358       myFileName->setText(getDefaultLibraryName());
359     processNewLibrary();
360     if (myListBox->count() > 0)
361       myListBox->setCurrentItem(0);
362   }
363   else
364   {
365     setWindowTitle(tr("EDIT_LIB_TLT"));
366     if (myFileName->text().isEmpty())
367       myFileName->setText(getDefaultLibraryName());
368     processNewLibrary();
369     if (myListBox->count() > 0)
370       myListBox->setCurrentItem(0);
371   }
372
373   this->show();
374
375   updateMainButtons();
376   isPermissionValid(false);
377 }
378
379 //=======================================================================
380 // name    : SMESHGUI_FilterLibraryDlg::updateControlsVisibility
381 // Purpose : Update visibility of controls in accordance with myMode
382 //=======================================================================
383 void SMESHGUI_FilterLibraryDlg::updateControlsVisibility()
384 {
385   if (myMode == ADD_TO)
386   {
387     myNameGrp->show();
388     myNameGrp->setEnabled(true);
389     myAddBtn->hide();
390     myDeleteBtn->hide();
391     myTable->SetEditable(false);
392   }
393   else if (myMode == COPY_FROM)
394   {
395     myNameGrp->hide();
396     myNameGrp->setEnabled(false);
397     myAddBtn->hide();
398     myDeleteBtn->hide();
399     myTable->SetEditable(false);
400   }
401   else if (myMode == EDIT)
402   {
403     myNameGrp->show();
404     myNameGrp->setEnabled(true);
405     myAddBtn->show();
406     myDeleteBtn->show();
407     myTable->SetEditable(true);
408   }
409
410   qApp->processEvents();
411   updateGeometry();
412   adjustSize();
413 }
414
415 //=======================================================================
416 // name    : SMESHGUI_FilterLibraryDlg::onApply
417 // Purpose : SLOT called when "Apply" button pressed.
418 //=======================================================================
419 bool SMESHGUI_FilterLibraryDlg::onApply()
420 {
421   if (!isValid(true) || !isPermissionValid(false))
422     return false;
423
424   if (myLibrary->_is_nil()) {
425     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
426                                  tr("LIBRARY_IS_NOT_LOADED"));
427     return false;
428   }
429
430   if (myFileName->text() != myLibrary->GetFileName())
431     myLibrary->SetFileName( myFileName->text().toLatin1().constData() );
432
433   bool aResult = false;
434
435   if (myMode == COPY_FROM || myListBox->count() == 0) {
436     aResult = true;
437   } else if (myMode == EDIT || myMode == ADD_TO) {
438     SMESH::Filter_var aFilter = createFilter();
439     if (!myLibrary->Replace(myCurrFilterName.toLatin1().constData(),
440                             myName->text().toLatin1().constData(),
441                             aFilter.in())) {
442       SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
443                                    tr("ERROR_OF_EDITING"));
444       aResult = false;
445     }
446     else
447       aResult = true;
448   }
449
450   if (aResult && myMode != COPY_FROM)
451     aResult = myLibrary->Save();
452
453   if (aResult) {
454     char* aFileName = myLibrary->GetFileName();
455     getDefaultLibraryName() = QString(aFileName);
456     delete aFileName;
457   } else if (myMode != COPY_FROM) {
458     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
459                                  tr("ERROR_OF_SAVING"));
460   } else {
461   }
462
463   return aResult;
464 }
465
466 //=======================================================================
467 // name    : SMESHGUI_FilterLibraryDlg::onOk
468 // Purpose : SLOT called when "Ok" button pressed.
469 //           Assign filters VTK viewer and close dialog
470 //=======================================================================
471 void SMESHGUI_FilterLibraryDlg::onOk()
472 {
473   if (onApply())
474   {
475     disconnect( mySMESHGUI, 0, this, 0);
476     mySMESHGUI->ResetState();
477     accept();
478   }
479 }
480
481 //=======================================================================
482 // name    : SMESHGUI_FilterLibraryDlg::onClose
483 // Purpose : SLOT called when "Close" button pressed. Close dialog
484 //=======================================================================
485 void SMESHGUI_FilterLibraryDlg::onClose()
486 {
487   disconnect( mySMESHGUI, 0, this, 0);
488   mySMESHGUI->ResetState();
489   reject();
490 }
491
492 //=================================================================================
493 // function : onHelp()
494 // purpose  :
495 //=================================================================================
496 void SMESHGUI_FilterLibraryDlg::onHelp()
497 {
498   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
499   if (app) 
500     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
501   else {
502     QString platform;
503 #ifdef WIN32
504     platform = "winapplication";
505 #else
506     platform = "application";
507 #endif
508     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
509                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
510                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
511                                                                  platform)).
512                              arg(myHelpFileName));
513   }
514 }
515
516 //=======================================================================
517 // name    : SMESHGUI_FilterLibraryDlg::onDeactivate
518 // Purpose : SLOT called when dialog must be deativated
519 //=======================================================================
520 void SMESHGUI_FilterLibraryDlg::onDeactivate()
521 {
522   setEnabled(false);
523 }
524
525 //=======================================================================
526 // name    : SMESHGUI_FilterLibraryDlg::enterEvent
527 // Purpose : Event filter
528 //=======================================================================
529 void SMESHGUI_FilterLibraryDlg::enterEvent(QEvent*)
530 {
531   setEnabled(true);
532 }
533
534 //=================================================================================
535 // function : closeEvent()
536 // purpose  : Close dialog
537 //=================================================================================
538 void SMESHGUI_FilterLibraryDlg::closeEvent(QCloseEvent* e)
539 {
540   onClose();
541 }
542
543 //=======================================================================
544 // name    : SMESHGUI_FilterLibraryDlg::getFileName
545 // Purpose : Get file name
546 //=======================================================================
547 QString SMESHGUI_FilterLibraryDlg::getFileName() const
548 {
549   return myFileName != 0 ? myFileName->text() : QString("");
550 }
551
552 //================================================================
553 // Function : setFileName
554 // Purpose  : Set file name to line edit
555 //================================================================
556 void SMESHGUI_FilterLibraryDlg::setFileName(const QString& txt, const bool autoExt)
557 {
558   if (myFileName == 0)
559     return;
560   myFileName->setText(autoExt ? autoExtension(txt) : txt);
561 }
562
563 //================================================================
564 // Function : autoExtension
565 // Purpose  : Append extension to the file name
566 //================================================================
567 QString SMESHGUI_FilterLibraryDlg::autoExtension(const QString& theFileName) const
568 {
569   QString anExt = theFileName.section('.', -1);
570   return anExt != "xml" && anExt != "XML" ? theFileName + ".xml" : theFileName;
571 }
572
573 //================================================================
574 // Function : filterWildCards
575 // Purpose  :
576 //================================================================
577 QStringList SMESHGUI_FilterLibraryDlg::filterWildCards(const QString& theFilter) const
578 {
579   QStringList res;
580
581   int b = theFilter.lastIndexOf("(");
582   int e = theFilter.lastIndexOf(")");
583   if (b != -1 && e != -1)
584   {
585     QString content = theFilter.mid(b + 1, e - b - 1).trimmed();
586     QStringList lst = content.split(" ", QString::SkipEmptyParts);
587     for (QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it)
588       if ((*it).indexOf(".") != -1)
589         res.append((*it).trimmed());
590   }
591   return res;
592 }
593
594 //=======================================================================
595 // name    : SMESHGUI_FilterLibraryDlg::prepareFilters
596 // Purpose : Prepare filters for dialog
597 //=======================================================================
598 QStringList SMESHGUI_FilterLibraryDlg::prepareFilters() const
599 {
600   static QStringList aList;
601   if (aList.isEmpty())
602   {
603     aList.append(tr("XML_FILT"));
604     //aList.append(tr("ALL_FILES_FILTER"));
605   }
606
607   return aList;
608 }
609
610 //================================================================
611 // Function : onBrowse
612 // Purpose  : SLOT. Display "Open file" dialog for chosing library name
613 //================================================================
614 void SMESHGUI_FilterLibraryDlg::onBrowse()
615 {
616   Dialog* aDlg = new Dialog(this, true);
617   aDlg->setWindowTitle(tr("OPEN_LIBRARY"));
618
619   //aDlg->setMode(myMode == COPY_FROM ? QFileDialogP::ExistingFile : QFileDialogP::AnyFile);
620   aDlg->setFileMode(myMode == COPY_FROM ? QFileDialog::ExistingFile : QFileDialog::AnyFile);
621   aDlg->setFilters(prepareFilters());
622   aDlg->selectFile(getFileName());
623
624   QPushButton* anOkBtn = (QPushButton*)aDlg->findChild<QPushButton*>("OK");
625   if (anOkBtn != 0)
626     anOkBtn->setText(tr("SMESH_BUT_OK"));
627
628   if (aDlg->exec() != Accepted)
629     return;
630
631   QString fName = aDlg->selectedFile();
632
633   if (fName.isEmpty())
634     return;
635
636   if (QFileInfo(fName).suffix().isEmpty())
637     fName = autoExtension(fName);
638
639   fName = QDir::convertSeparators(fName);
640   QString prev = QDir::convertSeparators(getFileName());
641
642   if (prev == fName)
643     return;
644
645   setFileName(fName);
646
647   QListWidgetItem* item = myListBox->item( myListBox->count()-1 );
648   QString aName = item ? item->text() : QString::null;
649   processNewLibrary();
650
651   if (myMode == ADD_TO)
652   {
653     myTable->Copy((SMESHGUI_FilterTable*)parentWidget());
654     myCurrFilterName = "";
655     myCurrFilter = -1;
656     addFilterToLib(aName);
657   }
658
659   isPermissionValid(false);
660 }
661
662 //=======================================================================
663 // name    : SMESHGUI_FilterLibraryDlg::processNewLibrary
664 // Purpose : SLOT. Calleds when file name changed
665 //=======================================================================
666 void SMESHGUI_FilterLibraryDlg::processNewLibrary()
667 {
668   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
669   if (aFilterMgr->_is_nil())
670     return;
671
672   myLibrary = aFilterMgr->LoadLibrary(autoExtension(getFileName()).toLatin1().constData());
673   if (myLibrary->_is_nil()) {
674     if (myMode == COPY_FROM) {
675       SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
676                                    tr("ERROR_LOAD"));
677       return;
678     } else {
679       myLibrary = aFilterMgr->CreateLibrary();
680       myLibrary->SetFileName(getFileName().toLatin1().constData());
681     }
682   }
683
684   updateList();
685 }
686
687 //=======================================================================
688 // name    : SMESHGUI_FilterLibraryDlg::updateList
689 // Purpose : Fill list box with filter names
690 //=======================================================================
691 void SMESHGUI_FilterLibraryDlg::updateList()
692 {
693   QStringList aList;
694   SMESH::string_array_var aNames = myLibrary->GetNames((SMESH::ElementType)myTable->GetType());
695   for (int i = 0, n = aNames->length(); i < n; i++)
696     aList.append(QString(aNames[ i ]));
697   myListBox->blockSignals(true);
698   myListBox->clear();
699   myListBox->blockSignals(false);
700   myListBox->addItems(aList);
701   if (myListBox->count() == 0)
702   {
703     myTable->Clear(myTable->GetType());
704     myName->clear();
705     myName->setEnabled(false);
706     myTable->SetEnabled(false);
707   }
708   else
709   {
710     myName->setEnabled(true);
711     myTable->SetEnabled(true);
712     if (myListBox->count())
713     {
714       myCurrFilterName = "";
715       myListBox->setCurrentItem(0);
716     }
717   }
718 }
719
720 //=======================================================================
721 // name    : SMESHGUI_FilterLibraryDlg::isNameValid
722 // Purpose : Verify validity if entered data
723 //=======================================================================
724 bool SMESHGUI_FilterLibraryDlg::isNameValid(const bool theMess) const
725 {
726   // verify validity of filter name
727   if (myName->isEnabled() && !myCurrFilterName.isEmpty()) {
728     QString aCurrName = myName->text();
729     if (aCurrName.isEmpty()) {
730       if (theMess)
731         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
732                                      tr("EMPTY_FILTER_NAME"));
733       return false;
734     }
735
736     SMESH::string_array_var aNames = myLibrary->GetAllNames();
737     for (int f = 0, n = aNames->length(); f < n; f++) {
738       if (aNames[ f ] == aCurrName && aNames[ f ] != myCurrFilterName) {
739         if (theMess)
740           SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
741                                        tr("ERROR_FILTER_NAME"));
742         return false;
743       }
744     }
745   }
746
747   return true;
748 }
749
750 //=======================================================================
751 // name    : SMESHGUI_FilterLibraryDlg::isPermissionValid
752 // Purpose : Verify write permission on file
753 //=======================================================================
754 bool SMESHGUI_FilterLibraryDlg::isPermissionValid(const bool theIsExistingOnly)
755 {
756   if (myMode == COPY_FROM)
757     return true;
758
759   // Verify write permission
760   bool isWritable = false;
761
762   QString fName(myFileName->text());
763   if (QFileInfo(fName).suffix().isEmpty())
764     fName = autoExtension(fName);
765
766   fName = QDir::convertSeparators(fName);
767
768   if (QFileInfo(fName).exists()) {
769     isWritable = QFileInfo(fName).isWritable();
770   } else if (!theIsExistingOnly) {
771     QFileInfo aDirInfo(QFileInfo(fName).absolutePath());
772     isWritable = aDirInfo.isWritable();
773     /*if (QDir(QFileInfo(fName).dirPath(true)).exists() ||
774          QDir().mkdir(QFileInfo(fName).dirPath(true)))
775     {
776       QFile aFile(fName);
777       if (aFile.open(IO_WriteOnly))
778         isWritable = true;
779       else
780         aFile.close();
781     }
782     */
783   } else {
784     isWritable = true;
785   }
786
787   if (!isWritable) {
788     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
789                                  tr("NO_PERMISSION"));
790     return false;
791   }
792
793   return true;
794 }
795
796 //=======================================================================
797 // name    : SMESHGUI_FilterLibraryDlg::isValid
798 // Purpose : Verify validity if entered data
799 //=======================================================================
800 bool SMESHGUI_FilterLibraryDlg::isValid(const bool theMess) const
801 {
802   // verify validity of table
803   if (!myTable->IsValid(theMess) || !isNameValid(theMess))
804     return false;
805   else
806     return true;
807 }
808
809 //=======================================================================
810 // name    : SMESHGUI_FilterLibraryDlg::onFilterChanged
811 // Purpose : SLOT. Called when selected filter of library  changed
812 //=======================================================================
813 void SMESHGUI_FilterLibraryDlg::onFilterChanged( QListWidgetItem* item, QListWidgetItem* )
814 {
815   QString theName = item ? item->text() : QString::null;
816   if (myLibrary->_is_nil())
817     return;
818
819   // Save parameters of filter if it was changed
820
821   if (!myCurrFilterName.isEmpty() && myTable->IsEditable())
822   {
823     if (!isValid(true))
824     {
825       myListBox->blockSignals(true);
826       myListBox->setCurrentRow(myCurrFilter);
827       myListBox->blockSignals(false);
828       return;
829     }
830
831     SMESH::Filter_var aFilter = createFilter();
832     myLibrary->Replace(myCurrFilterName.toLatin1().constData(), 
833                        myName->text().toLatin1().constData(), 
834                        aFilter);
835   }
836
837   // Fill table with filter parameters
838
839   SMESH::Filter_var aFilter = myLibrary->Copy(theName.toLatin1().constData());
840   myCurrFilterName = theName;
841   myCurrFilter = myListBox->currentRow();
842   myName->setText(theName);
843
844
845   SMESH::Filter::Criteria_var aCriteria;
846
847   myTable->Clear(myTable->GetType());
848
849   if (CORBA::is_nil( aFilter ) || !aFilter->GetCriteria(aCriteria))
850     return;
851
852   for (int i = 0, n = aCriteria->length(); i < n; i++)
853     myTable->AddCriterion(aCriteria[ i ], myTable->GetType());
854
855   myTable->Update();
856 }
857
858 //=======================================================================
859 // name    : SMESHGUI_FilterLibraryDlg::onReturnPressed
860 // Purpose : SLOT. Called when enter button is pressed in library name field
861 //           Reload library
862 //=======================================================================
863 void SMESHGUI_FilterLibraryDlg::onReturnPressed()
864 {
865   QListWidgetItem* item = myListBox->item( myListBox->count()-1 );
866   QString aName = item ? item->text() : QString::null;
867
868   processNewLibrary();
869
870   if (myMode == ADD_TO)
871   {
872     myTable->Copy((SMESHGUI_FilterTable*)parentWidget());
873     myCurrFilterName = "";
874     myCurrFilter = -1;
875     addFilterToLib(aName);
876   }
877
878   isPermissionValid(false);
879 }
880
881 //=======================================================================
882 // name    : SMESHGUI_FilterLibraryDlg::enableMainButtons
883 // Purpose : Update state of "OK", "Cancel" buttons
884 //=======================================================================
885 void SMESHGUI_FilterLibraryDlg::enableMainButtons()
886 {
887   /*bool isEnabled = isValid(false);
888   if (myButtons.contains(BTN_OK))
889     myButtons[ BTN_OK ]->setEnabled(isEnabled);
890   else if (myButtons.contains(BTN_Apply))
891     myButtons[ BTN_OK ]->setEnabled(isEnabled);
892   if (myButtons.contains(BTN_Cancel))
893     myButtons[ BTN_Cancel ]->setEnabled(isEnabled);
894   else if (myButtons.contains(BTN_Close))
895     myButtons[ BTN_Cancel ]->setEnabled(isEnabled);
896     */
897 }
898
899 //=======================================================================
900 // name    : SMESHGUI_FilterLibraryDlg::createFilter
901 // Purpose : Cerate filter in accordance with library
902 //=======================================================================
903 SMESH::Filter_ptr SMESHGUI_FilterLibraryDlg::createFilter(const int theType)
904 {
905   int n = myTable->NumRows(theType);
906
907   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
908   aCriteria->length(n);
909
910   for (int i = 0; i < n; i++)
911   {
912     SMESH::Filter::Criterion aCriterion = SMESHGUI_FilterDlg::createCriterion();
913     myTable->GetCriterion(i, aCriterion);
914     aCriteria[ i ] = aCriterion;
915   }
916
917   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
918   SMESH::Filter_var aFilter = aFilterMgr->CreateFilter();
919   aFilter->SetCriteria(aCriteria.in());
920
921   return aFilter._retn();
922 }
923
924 //=======================================================================
925 // name    : SMESHGUI_FilterLibraryDlg::onAddBtnPressed
926 // Purpose : SLOT. Called when "Add" button pressed
927 //           Add new filter to the end of library
928 //=======================================================================
929 void SMESHGUI_FilterLibraryDlg::onAddBtnPressed()
930 {
931   // Save parameters of filter if it was changed
932   if (!myCurrFilterName.isEmpty() && myTable->IsEditable())
933   {
934     if (!isValid(true))
935       return;
936   }
937   {
938     SMESH::Filter_var aFilter = createFilter();
939     myLibrary->Replace(myCurrFilterName.toLatin1().constData(), 
940                        myName->text().toLatin1().constData(), 
941                        aFilter);
942   }
943
944   addFilterToLib(getDefaultFilterName());
945 }
946
947 //=======================================================================
948 // name    : onAddBtnPressed()
949 // Purpose : SLOT. Called when "Add" button pressed
950 //           Add new filter to the end of library
951 //=======================================================================
952 void SMESHGUI_FilterLibraryDlg::addFilterToLib (const QString& theName)
953 {
954   if (myLibrary->_is_nil()) {
955     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
956                                  tr("LIBRARY_IS_NOT_LOADED"));
957     return;
958   }
959
960   // create filter
961   SMESH::Filter_var aFilter = createFilter();
962
963   // if name of filter already exist in the library assign default name for the filter
964   QString aName(theName);
965   SMESH::string_array_var aNames = myLibrary->GetAllNames();
966   for (int i = 0, n = aNames->length(); i < n; i++)
967     if (aName == QString(aNames[ i ]))
968     {
969       aName = getDefaultFilterName();
970       break;
971     }
972
973   // add new filter in library
974   bool aResult = !aFilter->GetPredicate()->_is_nil()
975     ? myLibrary->Add(aName.toLatin1().constData(), aFilter)
976     : myLibrary->AddEmpty(aName.toLatin1().constData(), (SMESH::ElementType)myTable->GetType());
977
978   if (!aResult) {
979     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
980                                  tr("ERROR_OF_ADDING"));
981   }
982
983   updateList();
984   myCurrFilterName = "";
985   myCurrFilter = -1;
986   setSelected(aName);
987
988   if (theName != aName)
989     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WARNING"),
990                                  tr("ASSIGN_NEW_NAME").arg(theName).arg(aName));
991 }
992
993 //=======================================================================
994 // name    : SMESHGUI_FilterLibraryDlg::getDefaultLibraryName
995 // Purpose : Get default library name
996 //=======================================================================
997 QString& SMESHGUI_FilterLibraryDlg::getDefaultLibraryName() const
998 {
999   static QString aName;
1000   if (aName.isEmpty())
1001   {
1002     QString aHomeDir = QDir(QDir::home()).absolutePath();
1003     aName = aHomeDir + "/" + tr ("LIB_NAME");
1004   }
1005   return aName;
1006 }
1007
1008 //=======================================================================
1009 // name    : SMESHGUI_FilterLibraryDlg::getDefaultFilterName
1010 // Purpose : Create default filter name
1011 //=======================================================================
1012 QString SMESHGUI_FilterLibraryDlg::getDefaultFilterName() const
1013 {
1014   QString aName;
1015
1016   if (myTable->GetType() == SMESH::NODE)
1017     aName = tr("NODE");
1018   else if (myTable->GetType() == SMESH::EDGE)
1019     aName = tr("EDGE");
1020   else if (myTable->GetType() == SMESH::FACE)
1021     aName = tr("FACE");
1022   else if (myTable->GetType() == SMESH::VOLUME)
1023     aName = tr("VOLUME");
1024   else if (myTable->GetType() == SMESH::ALL)
1025     aName = tr("ELEMENT");
1026   else
1027     aName = tr("SELECTION");
1028
1029   aName += tr("FILTER");
1030
1031
1032   QMap< QString, int > anAllNames;
1033   SMESH::string_array_var aNames = myLibrary->GetAllNames();
1034   for(int i = 0, n = aNames->length(); i < n; i++)
1035     anAllNames[ QString(aNames[ i ]) ] = -1;
1036
1037   bool isNotValid = true;
1038   int k = 1;
1039   QString aNewName;
1040   while (isNotValid)
1041   {
1042     isNotValid = false;
1043     aNewName = aName + "_" + QString("%1").arg(k);
1044     if (anAllNames.contains(aNewName))
1045     {
1046       isNotValid = true;
1047       k++;
1048     }
1049   }
1050
1051   return aNewName;
1052 }
1053
1054 //=======================================================================
1055 // name    : SMESHGUI_FilterLibraryDlg::setSelected
1056 // Purpose : set selected item in list box containing filters
1057 //=======================================================================
1058 bool SMESHGUI_FilterLibraryDlg::setSelected(const QString& theName)
1059 {
1060   int anIndex = getIndex(theName);
1061   if (anIndex != -1)
1062   {
1063     myListBox->setCurrentRow(anIndex);
1064     myCurrFilterName = theName;
1065     myCurrFilter = anIndex;
1066   }
1067   return anIndex != -1;
1068 }
1069
1070 //=======================================================================
1071 // name    : SMESHGUI_FilterLibraryDlg::getIndex
1072 // Purpose : Get index of the filter in list box
1073 //=======================================================================
1074 int SMESHGUI_FilterLibraryDlg::getIndex(const QString& theName) const
1075 {
1076   for (int i = 0, n = myListBox->count(); i < n; i++)
1077     if (myListBox->item(i)->text() == theName)
1078       return i;
1079   return -1;
1080 }
1081
1082 //=======================================================================
1083 // name    : SMESHGUI_FilterLibraryDlg::onDeleteBtnPressed
1084 // Purpose : SLOT. Called when "Delete" button pressed
1085 //=======================================================================
1086 void SMESHGUI_FilterLibraryDlg::onDeleteBtnPressed()
1087 {
1088   if (myLibrary->_is_nil()) {
1089     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
1090                                  tr("LIBRARY_IS_NOT_LOADED"));
1091     return;
1092   }
1093
1094   int anIndex = getIndex(myCurrFilterName);
1095
1096   if (anIndex == -1 || !myLibrary->Delete(myCurrFilterName.toLatin1().constData())) {
1097     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
1098                                  tr("ERROR_OF_DELETING"));
1099   } else {
1100     myCurrFilterName = "";
1101     myCurrFilter = -1;
1102     delete myListBox->item(anIndex);
1103
1104     if (anIndex >= 1)
1105       myListBox->item(anIndex - 1)->setSelected(true);
1106     else if (anIndex == 0 && myListBox->count() > 0)
1107       myListBox->item(0)->setSelected(true);
1108     else
1109       myTable->Clear();
1110   }
1111
1112   myTable->SetEnabled(myListBox->count() > 0);
1113   if (myListBox->count() == 0) {
1114     myName->setText("");
1115     myName->setEnabled(false);
1116   }
1117 }
1118
1119 //=======================================================================
1120 // name    : onFilterNameChanged()
1121 // Purpose : SLOT. Called when name of filter changed
1122 //           Change filter name in list box
1123 //=======================================================================
1124 void SMESHGUI_FilterLibraryDlg::onFilterNameChanged (const QString& theName)
1125 {
1126   int aCurrItem = myListBox->currentRow();
1127   if (aCurrItem == -1)
1128     return;
1129
1130   myListBox->blockSignals(true);
1131   myListBox->item(aCurrItem)->setText(theName);
1132   myListBox->blockSignals(false);
1133 }
1134
1135 //=======================================================================
1136 // name    : SMESHGUI_FilterLibraryDlg::SetTable
1137 // Purpose : Set table
1138 //=======================================================================
1139 void SMESHGUI_FilterLibraryDlg::SetTable(const SMESHGUI_FilterTable* theTable)
1140 {
1141   myTable->Copy(theTable);
1142   myName->setText(getDefaultFilterName());
1143   addFilterToLib(myName->text());
1144   myTable->Update();
1145 }
1146
1147 //=======================================================================
1148 // name    : SMESHGUI_FilterLibraryDlg::GetTable
1149 // Purpose : Get table
1150 //=======================================================================
1151 const SMESHGUI_FilterTable* SMESHGUI_FilterLibraryDlg::GetTable() const
1152 {
1153   return myTable;
1154 }
1155
1156
1157 //=======================================================================
1158 // name    : SMESHGUI_FilterLibraryDlg::onEntityTypeChanged
1159 // Purpose : SLOT. Called when entiyt type changed
1160 //=======================================================================
1161 void SMESHGUI_FilterLibraryDlg::onEntityTypeChanged(const int theType)
1162 {
1163   if (myLibrary->_is_nil())
1164     return;
1165
1166   myName->clear();
1167   myCurrFilterName = "";
1168   myCurrFilter = -1;
1169   updateList();
1170   if (myListBox->count())
1171     myListBox->setCurrentItem(0);
1172 }
1173
1174 //=======================================================================
1175 // name    : SMESHGUI_FilterLibraryDlg::onNeedValidation
1176 // Purpose :
1177 //=======================================================================
1178 void SMESHGUI_FilterLibraryDlg::onNeedValidation()
1179 {
1180   if (!myCurrFilterName.isEmpty())
1181   {
1182     bool valid = isValid(true);
1183     myTable->SetValidity(valid);
1184
1185     if (valid)
1186     {
1187       SMESH::Filter_var aFilter = createFilter(myTable->GetType());
1188       myLibrary->Replace(myCurrFilterName.toLatin1().constData(),
1189                          myName->text().toLatin1().constData(),
1190                          aFilter);
1191     }
1192   }
1193 }
1194
1195 //=================================================================================
1196 // function : keyPressEvent()
1197 // purpose  :
1198 //=================================================================================
1199 void SMESHGUI_FilterLibraryDlg::keyPressEvent( QKeyEvent* e )
1200 {
1201   QDialog::keyPressEvent( e );
1202   if ( e->isAccepted() )
1203     return;
1204
1205   if ( e->key() == Qt::Key_F1 ) {
1206     e->accept();
1207     onHelp();
1208   }
1209 }