Salome HOME
Porting SMESH module to Qt 4
[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(currentTextChanged(const QString&)),
229           this, SLOT(onFilterChanged(const QString&)));
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   QLabel* aLbl = new QLabel(aGrp);
260   aLbl->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
261
262   myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"), aGrp);
263   myButtons[ BTN_Close  ] = new QPushButton(tr("SMESH_BUT_CLOSE"),  aGrp);
264   myButtons[ BTN_Help   ] = new QPushButton(tr("SMESH_BUT_HELP"),   aGrp);
265
266   aLay->addWidget(myButtons[ BTN_OK     ]);
267   aLay->addSpacing(10);
268   aLay->addWidget(myButtons[ BTN_Apply  ]);
269   aLay->addSpacing(10);
270   aLay->addStretch();
271   aLay->addWidget(myButtons[ BTN_Cancel ]);
272   aLay->addWidget(myButtons[ BTN_Close  ]);
273   aLay->addWidget(myButtons[ BTN_Help   ]);
274
275   connect(myButtons[ BTN_OK     ], SIGNAL(clicked()), SLOT(onOk()));
276   connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose()));
277   connect(myButtons[ BTN_Close  ], SIGNAL(clicked()), SLOT(onClose()));
278   connect(myButtons[ BTN_Apply  ], SIGNAL(clicked()), SLOT(onApply()));
279   connect(myButtons[ BTN_Help   ], SIGNAL(clicked()), SLOT(onHelp()));
280
281   QMap<int, QPushButton*>::iterator anIter;
282   for (anIter = myButtons.begin(); anIter != myButtons.end(); ++anIter)
283     anIter.value()->setAutoDefault(false);
284
285   updateMainButtons();
286
287   return aGrp;
288 }
289
290 //=======================================================================
291 // name    : SMESHGUI_FilterLibraryDlg::updateMainButtons
292 // Purpose : Update visibility of main buttons (OK, Cancel, Close ...)
293 //=======================================================================
294 void SMESHGUI_FilterLibraryDlg::updateMainButtons()
295 {
296   if (myTypes.count() == 1) {
297     myButtons[ BTN_Cancel ]->show();
298     myButtons[ BTN_Apply  ]->hide();
299     myButtons[ BTN_Close  ]->hide();
300   } else {
301     myButtons[ BTN_Cancel ]->hide();
302     myButtons[ BTN_Apply  ]->show();
303     myButtons[ BTN_Close  ]->show();
304   }
305 }
306
307 //=======================================================================
308 // name    : SMESHGUI_FilterLibraryDlg::~SMESHGUI_FilterLibraryDlg
309 // Purpose : Destructor
310 //=======================================================================
311 SMESHGUI_FilterLibraryDlg::~SMESHGUI_FilterLibraryDlg()
312 {
313 }
314
315 //=======================================================================
316 // name    : SMESHGUI_FilterLibraryDlg::Init
317 // Purpose : Init dialog fields, connect signals and slots, show dialog
318 //=======================================================================
319 void SMESHGUI_FilterLibraryDlg::Init (const int type, const int theMode)
320 {
321   QList<int> aTypes;
322   aTypes.append(type);
323   Init(aTypes, theMode);
324 }
325
326 //=======================================================================
327 // name    : SMESHGUI_FilterLibraryDlg::Init
328 // Purpose : Init dialog fields, connect signals and slots, show dialog
329 //=======================================================================
330 void SMESHGUI_FilterLibraryDlg::Init (const QList<int>& theTypes,
331                                       const int theMode)
332 {
333   myMode = theMode;
334   myTypes = theTypes;
335   myTable->Init(theTypes);
336   myCurrFilterName = "";
337   myCurrFilter = -1;
338   myListBox->clear();
339   myName->clear();
340   myTable->Clear();
341
342   updateControlsVisibility();
343   setEnabled(true);
344
345   connect( mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
346   connect( mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
347
348   if (myMode == ADD_TO)
349   {
350     setWindowTitle(tr("ADD_TO_TLT"));
351     if (myFileName->text().isEmpty())
352       myFileName->setText(getDefaultLibraryName());
353     processNewLibrary();
354   }
355   else if (myMode == COPY_FROM)
356   {
357     setWindowTitle(tr("COPY_FROM_TLT"));
358     if (myFileName->text().isEmpty())
359       myFileName->setText(getDefaultLibraryName());
360     processNewLibrary();
361     if (myListBox->count() > 0)
362       myListBox->setCurrentItem(0);
363   }
364   else
365   {
366     setWindowTitle(tr("EDIT_LIB_TLT"));
367     if (myFileName->text().isEmpty())
368       myFileName->setText(getDefaultLibraryName());
369     processNewLibrary();
370     if (myListBox->count() > 0)
371       myListBox->setCurrentItem(0);
372   }
373
374   this->show();
375
376   updateMainButtons();
377   isPermissionValid(false);
378 }
379
380 //=======================================================================
381 // name    : SMESHGUI_FilterLibraryDlg::updateControlsVisibility
382 // Purpose : Update visibility of controls in accordance with myMode
383 //=======================================================================
384 void SMESHGUI_FilterLibraryDlg::updateControlsVisibility()
385 {
386   if (myMode == ADD_TO)
387   {
388     myNameGrp->show();
389     myNameGrp->setEnabled(true);
390     myAddBtn->hide();
391     myDeleteBtn->hide();
392     myTable->SetEditable(false);
393   }
394   else if (myMode == COPY_FROM)
395   {
396     myNameGrp->hide();
397     myNameGrp->setEnabled(false);
398     myAddBtn->hide();
399     myDeleteBtn->hide();
400     myTable->SetEditable(false);
401   }
402   else if (myMode == EDIT)
403   {
404     myNameGrp->show();
405     myNameGrp->setEnabled(true);
406     myAddBtn->show();
407     myDeleteBtn->show();
408     myTable->SetEditable(true);
409   }
410
411   qApp->processEvents();
412   updateGeometry();
413   adjustSize();
414 }
415
416 //=======================================================================
417 // name    : SMESHGUI_FilterLibraryDlg::onApply
418 // Purpose : SLOT called when "Apply" button pressed.
419 //=======================================================================
420 bool SMESHGUI_FilterLibraryDlg::onApply()
421 {
422   if (!isValid(true) || !isPermissionValid(false))
423     return false;
424
425   if (myLibrary->_is_nil()) {
426     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
427                                  tr("LIBRARY_IS_NOT_LOADED"));
428     return false;
429   }
430
431   if (myFileName->text() != myLibrary->GetFileName())
432     myLibrary->SetFileName(myFileName->text().toLatin1().data());
433
434   bool aResult = false;
435
436   if (myMode == COPY_FROM || myListBox->count() == 0) {
437     aResult = true;
438   } else if (myMode == EDIT || myMode == ADD_TO) {
439     SMESH::Filter_var aFilter = createFilter();
440     if (!myLibrary->Replace(myCurrFilterName.toLatin1().data(),
441                             myName->text().toLatin1().data(),
442                             aFilter.in())) {
443       SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
444                                    tr("ERROR_OF_EDITING"));
445       aResult = false;
446     }
447     else
448       aResult = true;
449   }
450
451   if (aResult && myMode != COPY_FROM)
452     aResult = myLibrary->Save();
453
454   if (aResult) {
455     char* aFileName = myLibrary->GetFileName();
456     getDefaultLibraryName() = QString(aFileName);
457     delete aFileName;
458   } else if (myMode != COPY_FROM) {
459     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
460                                  tr("ERROR_OF_SAVING"));
461   } else {
462   }
463
464   return aResult;
465 }
466
467 //=======================================================================
468 // name    : SMESHGUI_FilterLibraryDlg::onOk
469 // Purpose : SLOT called when "Ok" button pressed.
470 //           Assign filters VTK viewer and close dialog
471 //=======================================================================
472 void SMESHGUI_FilterLibraryDlg::onOk()
473 {
474   if (onApply())
475   {
476     disconnect( mySMESHGUI, 0, this, 0);
477     mySMESHGUI->ResetState();
478     accept();
479   }
480 }
481
482 //=======================================================================
483 // name    : SMESHGUI_FilterLibraryDlg::onClose
484 // Purpose : SLOT called when "Close" button pressed. Close dialog
485 //=======================================================================
486 void SMESHGUI_FilterLibraryDlg::onClose()
487 {
488   disconnect( mySMESHGUI, 0, this, 0);
489   mySMESHGUI->ResetState();
490   reject();
491 }
492
493 //=================================================================================
494 // function : onHelp()
495 // purpose  :
496 //=================================================================================
497 void SMESHGUI_FilterLibraryDlg::onHelp()
498 {
499   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
500   if (app) 
501     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
502   else {
503     QString platform;
504 #ifdef WIN32
505     platform = "winapplication";
506 #else
507     platform = "application";
508 #endif
509     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
510                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
511                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
512                                                                  platform)).
513                              arg(myHelpFileName));
514   }
515 }
516
517 //=======================================================================
518 // name    : SMESHGUI_FilterLibraryDlg::onDeactivate
519 // Purpose : SLOT called when dialog must be deativated
520 //=======================================================================
521 void SMESHGUI_FilterLibraryDlg::onDeactivate()
522 {
523   setEnabled(false);
524 }
525
526 //=======================================================================
527 // name    : SMESHGUI_FilterLibraryDlg::enterEvent
528 // Purpose : Event filter
529 //=======================================================================
530 void SMESHGUI_FilterLibraryDlg::enterEvent(QEvent*)
531 {
532   setEnabled(true);
533 }
534
535 //=================================================================================
536 // function : closeEvent()
537 // purpose  : Close dialog
538 //=================================================================================
539 void SMESHGUI_FilterLibraryDlg::closeEvent(QCloseEvent* e)
540 {
541   onClose();
542 }
543
544 //=======================================================================
545 // name    : SMESHGUI_FilterLibraryDlg::getFileName
546 // Purpose : Get file name
547 //=======================================================================
548 QString SMESHGUI_FilterLibraryDlg::getFileName() const
549 {
550   return myFileName != 0 ? myFileName->text() : QString("");
551 }
552
553 //================================================================
554 // Function : setFileName
555 // Purpose  : Set file name to line edit
556 //================================================================
557 void SMESHGUI_FilterLibraryDlg::setFileName(const QString& txt, const bool autoExt)
558 {
559   if (myFileName == 0)
560     return;
561   myFileName->setText(autoExt ? autoExtension(txt) : txt);
562 }
563
564 //================================================================
565 // Function : autoExtension
566 // Purpose  : Append extension to the file name
567 //================================================================
568 QString SMESHGUI_FilterLibraryDlg::autoExtension(const QString& theFileName) const
569 {
570   QString anExt = theFileName.section('.', -1);
571   return anExt != "xml" && anExt != "XML" ? theFileName + ".xml" : theFileName;
572 }
573
574 //================================================================
575 // Function : filterWildCards
576 // Purpose  :
577 //================================================================
578 QStringList SMESHGUI_FilterLibraryDlg::filterWildCards(const QString& theFilter) const
579 {
580   QStringList res;
581
582   int b = theFilter.lastIndexOf("(");
583   int e = theFilter.lastIndexOf(")");
584   if (b != -1 && e != -1)
585   {
586     QString content = theFilter.mid(b + 1, e - b - 1).trimmed();
587     QStringList lst = content.split(" ", QString::SkipEmptyParts);
588     for (QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it)
589       if ((*it).indexOf(".") != -1)
590         res.append((*it).trimmed());
591   }
592   return res;
593 }
594
595 //=======================================================================
596 // name    : SMESHGUI_FilterLibraryDlg::prepareFilters
597 // Purpose : Prepare filters for dialog
598 //=======================================================================
599 QStringList SMESHGUI_FilterLibraryDlg::prepareFilters() const
600 {
601   static QStringList aList;
602   if (aList.isEmpty())
603   {
604     aList.append(tr("XML_FILT"));
605     //aList.append(tr("ALL_FILES_FILTER"));
606   }
607
608   return aList;
609 }
610
611 //================================================================
612 // Function : onBrowse
613 // Purpose  : SLOT. Display "Open file" dialog for chosing library name
614 //================================================================
615 void SMESHGUI_FilterLibraryDlg::onBrowse()
616 {
617   Dialog* aDlg = new Dialog(this, true);
618   aDlg->setWindowTitle(tr("OPEN_LIBRARY"));
619
620   //aDlg->setMode(myMode == COPY_FROM ? QFileDialogP::ExistingFile : QFileDialogP::AnyFile);
621   aDlg->setFileMode(myMode == COPY_FROM ? QFileDialog::ExistingFile : QFileDialog::AnyFile);
622   aDlg->setFilters(prepareFilters());
623   aDlg->selectFile(getFileName());
624
625   QPushButton* anOkBtn = (QPushButton*)aDlg->findChild<QPushButton*>("OK");
626   if (anOkBtn != 0)
627     anOkBtn->setText(tr("SMESH_BUT_OK"));
628
629   if (aDlg->exec() != Accepted)
630     return;
631
632   QString fName = aDlg->selectedFile();
633
634   if (fName.isEmpty())
635     return;
636
637   if (QFileInfo(fName).suffix().isEmpty())
638     fName = autoExtension(fName);
639
640   fName = QDir::convertSeparators(fName);
641   QString prev = QDir::convertSeparators(getFileName());
642
643   if (prev == fName)
644     return;
645
646   setFileName(fName);
647
648   QString aName = myListBox->item(myListBox->count() - 1)->text();
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().data());
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().data());
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->clear();
698   myListBox->addItems(aList);
699   if (myListBox->count() == 0)
700   {
701     myTable->Clear(myTable->GetType());
702     myName->clear();
703     myName->setEnabled(false);
704     myTable->SetEnabled(false);
705   }
706   else
707   {
708     myName->setEnabled(true);
709     myTable->SetEnabled(true);
710     if (myListBox->count())
711     {
712       myCurrFilterName = "";
713       myListBox->setCurrentItem(0);
714     }
715   }
716 }
717
718 //=======================================================================
719 // name    : SMESHGUI_FilterLibraryDlg::isNameValid
720 // Purpose : Verify validity if entered data
721 //=======================================================================
722 bool SMESHGUI_FilterLibraryDlg::isNameValid(const bool theMess) const
723 {
724   // verify validity of filter name
725   if (myName->isEnabled() && !myCurrFilterName.isEmpty()) {
726     QString aCurrName = myName->text();
727     if (aCurrName.isEmpty()) {
728       if (theMess)
729         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
730                                      tr("EMPTY_FILTER_NAME"));
731       return false;
732     }
733
734     SMESH::string_array_var aNames = myLibrary->GetAllNames();
735     for (int f = 0, n = aNames->length(); f < n; f++) {
736       if (aNames[ f ] == aCurrName && aNames[ f ] != myCurrFilterName) {
737         if (theMess)
738           SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
739                                        tr("ERROR_FILTER_NAME"));
740         return false;
741       }
742     }
743   }
744
745   return true;
746 }
747
748 //=======================================================================
749 // name    : SMESHGUI_FilterLibraryDlg::isPermissionValid
750 // Purpose : Verify write permission on file
751 //=======================================================================
752 bool SMESHGUI_FilterLibraryDlg::isPermissionValid(const bool theIsExistingOnly)
753 {
754   if (myMode == COPY_FROM)
755     return true;
756
757   // Verify write permission
758   bool isWritable = false;
759
760   QString fName(myFileName->text());
761   if (QFileInfo(fName).suffix().isEmpty())
762     fName = autoExtension(fName);
763
764   fName = QDir::convertSeparators(fName);
765
766   if (QFileInfo(fName).exists()) {
767     isWritable = QFileInfo(fName).isWritable();
768   } else if (!theIsExistingOnly) {
769     QFileInfo aDirInfo(QFileInfo(fName).absolutePath());
770     isWritable = aDirInfo.isWritable();
771     /*if (QDir(QFileInfo(fName).dirPath(true)).exists() ||
772          QDir().mkdir(QFileInfo(fName).dirPath(true)))
773     {
774       QFile aFile(fName);
775       if (aFile.open(IO_WriteOnly))
776         isWritable = true;
777       else
778         aFile.close();
779     }
780     */
781   } else {
782     isWritable = true;
783   }
784
785   if (!isWritable) {
786     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
787                                  tr("NO_PERMISSION"));
788     return false;
789   }
790
791   return true;
792 }
793
794 //=======================================================================
795 // name    : SMESHGUI_FilterLibraryDlg::isValid
796 // Purpose : Verify validity if entered data
797 //=======================================================================
798 bool SMESHGUI_FilterLibraryDlg::isValid(const bool theMess) const
799 {
800   // verify validity of table
801   if (!myTable->IsValid(theMess) || !isNameValid(theMess))
802     return false;
803   else
804     return true;
805 }
806
807 //=======================================================================
808 // name    : SMESHGUI_FilterLibraryDlg::onFilterChanged
809 // Purpose : SLOT. Called when selected filter of library  changed
810 //=======================================================================
811 void SMESHGUI_FilterLibraryDlg::onFilterChanged(const QString& theName)
812 {
813   if (myLibrary->_is_nil())
814     return;
815
816   // Save parameters of filter if it was changed
817
818   if (!myCurrFilterName.isEmpty() && myTable->IsEditable())
819   {
820     if (!isValid(true))
821     {
822       myListBox->blockSignals(true);
823       myListBox->setCurrentRow(myCurrFilter);
824       myListBox->blockSignals(false);
825       return;
826     }
827
828     SMESH::Filter_var aFilter = createFilter();
829     myLibrary->Replace(myCurrFilterName.toLatin1().data(), 
830                        myName->text().toLatin1().data(), 
831                        aFilter);
832   }
833
834   // Fill table with filter parameters
835
836   SMESH::Filter_var aFilter = myLibrary->Copy(theName.toLatin1().data());
837   myCurrFilterName = theName;
838   myCurrFilter = myListBox->currentRow();
839   myName->setText(theName);
840
841
842   SMESH::Filter::Criteria_var aCriteria;
843
844   myTable->Clear(myTable->GetType());
845
846   if (!aFilter->GetCriteria(aCriteria))
847     return;
848
849   for (int i = 0, n = aCriteria->length(); i < n; i++)
850     myTable->AddCriterion(aCriteria[ i ], myTable->GetType());
851
852   myTable->Update();
853 }
854
855 //=======================================================================
856 // name    : SMESHGUI_FilterLibraryDlg::onReturnPressed
857 // Purpose : SLOT. Called when enter button is pressed in library name field
858 //           Reload library
859 //=======================================================================
860 void SMESHGUI_FilterLibraryDlg::onReturnPressed()
861 {
862   QString aName = myListBox->item(myListBox->count() - 1)->text();
863
864   processNewLibrary();
865
866   if (myMode == ADD_TO)
867   {
868     myTable->Copy((SMESHGUI_FilterTable*)parentWidget());
869     myCurrFilterName = "";
870     myCurrFilter = -1;
871     addFilterToLib(aName);
872   }
873
874   isPermissionValid(false);
875 }
876
877 //=======================================================================
878 // name    : SMESHGUI_FilterLibraryDlg::enableMainButtons
879 // Purpose : Update state of "OK", "Cancel" buttons
880 //=======================================================================
881 void SMESHGUI_FilterLibraryDlg::enableMainButtons()
882 {
883   /*bool isEnabled = isValid(false);
884   if (myButtons.contains(BTN_OK))
885     myButtons[ BTN_OK ]->setEnabled(isEnabled);
886   else if (myButtons.contains(BTN_Apply))
887     myButtons[ BTN_OK ]->setEnabled(isEnabled);
888   if (myButtons.contains(BTN_Cancel))
889     myButtons[ BTN_Cancel ]->setEnabled(isEnabled);
890   else if (myButtons.contains(BTN_Close))
891     myButtons[ BTN_Cancel ]->setEnabled(isEnabled);
892     */
893 }
894
895 //=======================================================================
896 // name    : SMESHGUI_FilterLibraryDlg::createFilter
897 // Purpose : Cerate filter in accordance with library
898 //=======================================================================
899 SMESH::Filter_ptr SMESHGUI_FilterLibraryDlg::createFilter(const int theType)
900 {
901   int n = myTable->NumRows(theType);
902
903   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
904   aCriteria->length(n);
905
906   for (int i = 0; i < n; i++)
907   {
908     SMESH::Filter::Criterion aCriterion = SMESHGUI_FilterDlg::createCriterion();
909     myTable->GetCriterion(i, aCriterion);
910     aCriteria[ i ] = aCriterion;
911   }
912
913   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
914   SMESH::Filter_var aFilter = aFilterMgr->CreateFilter();
915   aFilter->SetCriteria(aCriteria.in());
916
917   return aFilter._retn();
918 }
919
920 //=======================================================================
921 // name    : SMESHGUI_FilterLibraryDlg::onAddBtnPressed
922 // Purpose : SLOT. Called when "Add" button pressed
923 //           Add new filter to the end of library
924 //=======================================================================
925 void SMESHGUI_FilterLibraryDlg::onAddBtnPressed()
926 {
927   // Save parameters of filter if it was changed
928   if (!myCurrFilterName.isEmpty() && myTable->IsEditable())
929   {
930     if (!isValid(true))
931       return;
932
933     SMESH::Filter_var aFilter = createFilter();
934     myLibrary->Replace(myCurrFilterName.toLatin1().data(), 
935                        myName->text().toLatin1().data(), 
936                        aFilter);
937   }
938
939   addFilterToLib(getDefaultFilterName());
940 }
941
942 //=======================================================================
943 // name    : onAddBtnPressed()
944 // Purpose : SLOT. Called when "Add" button pressed
945 //           Add new filter to the end of library
946 //=======================================================================
947 void SMESHGUI_FilterLibraryDlg::addFilterToLib (const QString& theName)
948 {
949   if (myLibrary->_is_nil()) {
950     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
951                                  tr("LIBRARY_IS_NOT_LOADED"));
952     return;
953   }
954
955   // create filter
956   SMESH::Filter_var aFilter = createFilter();
957
958   // if name of filter already exist in the library assign default name for the filter
959   QString aName(theName);
960   SMESH::string_array_var aNames = myLibrary->GetAllNames();
961   for (int i = 0, n = aNames->length(); i < n; i++)
962     if (aName == QString(aNames[ i ]))
963     {
964       aName = getDefaultFilterName();
965       break;
966     }
967
968   // add new filter in library
969   bool aResult = !aFilter->GetPredicate()->_is_nil()
970     ? myLibrary->Add(aName.toLatin1().data(), aFilter)
971     : myLibrary->AddEmpty(aName.toLatin1().data(), (SMESH::ElementType)myTable->GetType());
972
973   if (!aResult) {
974     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
975                                  tr("ERROR_OF_ADDING"));
976   }
977
978   updateList();
979   myCurrFilterName = "";
980   myCurrFilter = -1;
981   setSelected(aName);
982
983   if (theName != aName)
984     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WARNING"),
985                                  tr("ASSIGN_NEW_NAME").arg(theName).arg(aName));
986 }
987
988 //=======================================================================
989 // name    : SMESHGUI_FilterLibraryDlg::getDefaultLibraryName
990 // Purpose : Get default library name
991 //=======================================================================
992 QString& SMESHGUI_FilterLibraryDlg::getDefaultLibraryName() const
993 {
994   static QString aName;
995   if (aName.isEmpty())
996   {
997     QString aHomeDir = QDir(QDir::home()).absolutePath();
998     aName = aHomeDir + "/" + tr ("LIB_NAME");
999   }
1000   return aName;
1001 }
1002
1003 //=======================================================================
1004 // name    : SMESHGUI_FilterLibraryDlg::getDefaultFilterName
1005 // Purpose : Create default filter name
1006 //=======================================================================
1007 QString SMESHGUI_FilterLibraryDlg::getDefaultFilterName() const
1008 {
1009   QString aName;
1010
1011   if (myTable->GetType() == SMESH::NODE)
1012     aName = tr("NODE");
1013   else if (myTable->GetType() == SMESH::EDGE)
1014     aName = tr("EDGE");
1015   else if (myTable->GetType() == SMESH::FACE)
1016     aName = tr("FACE");
1017   else if (myTable->GetType() == SMESH::VOLUME)
1018     aName = tr("VOLUME");
1019   else if (myTable->GetType() == SMESH::ALL)
1020     aName = tr("ELEMENT");
1021   else
1022     aName = tr("SELECTION");
1023
1024   aName += tr("FILTER");
1025
1026
1027   QMap< QString, int > anAllNames;
1028   SMESH::string_array_var aNames = myLibrary->GetAllNames();
1029   for(int i = 0, n = aNames->length(); i < n; i++)
1030     anAllNames[ QString(aNames[ i ]) ] = -1;
1031
1032   bool isNotValid = true;
1033   int k = 1;
1034   QString aNewName;
1035   while (isNotValid)
1036   {
1037     isNotValid = false;
1038     aNewName = aName + "_" + QString("%1").arg(k);
1039     if (anAllNames.contains(aNewName))
1040     {
1041       isNotValid = true;
1042       k++;
1043     }
1044   }
1045
1046   return aNewName;
1047 }
1048
1049 //=======================================================================
1050 // name    : SMESHGUI_FilterLibraryDlg::setSelected
1051 // Purpose : set selected item in list box containing filters
1052 //=======================================================================
1053 bool SMESHGUI_FilterLibraryDlg::setSelected(const QString& theName)
1054 {
1055   int anIndex = getIndex(theName);
1056   if (anIndex != -1)
1057   {
1058     myListBox->setCurrentRow(anIndex);
1059     myCurrFilterName = theName;
1060     myCurrFilter = anIndex;
1061   }
1062   return anIndex != -1;
1063 }
1064
1065 //=======================================================================
1066 // name    : SMESHGUI_FilterLibraryDlg::getIndex
1067 // Purpose : Get index of the filter in list box
1068 //=======================================================================
1069 int SMESHGUI_FilterLibraryDlg::getIndex(const QString& theName) const
1070 {
1071   for (int i = 0, n = myListBox->count(); i < n; i++)
1072     if (myListBox->item(i)->text() == theName)
1073       return i;
1074   return -1;
1075 }
1076
1077 //=======================================================================
1078 // name    : SMESHGUI_FilterLibraryDlg::onDeleteBtnPressed
1079 // Purpose : SLOT. Called when "Delete" button pressed
1080 //=======================================================================
1081 void SMESHGUI_FilterLibraryDlg::onDeleteBtnPressed()
1082 {
1083   if (myLibrary->_is_nil()) {
1084     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
1085                                  tr("LIBRARY_IS_NOT_LOADED"));
1086     return;
1087   }
1088
1089   int anIndex = getIndex(myCurrFilterName);
1090
1091   if (anIndex == -1 || !myLibrary->Delete(myCurrFilterName.toLatin1().data())) {
1092     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
1093                                  tr("ERROR_OF_DELETING"));
1094   } else {
1095     myCurrFilterName = "";
1096     myCurrFilter = -1;
1097     delete myListBox->item(anIndex);
1098
1099     if (anIndex >= 1)
1100       myListBox->item(anIndex - 1)->setSelected(true);
1101     else if (anIndex == 0 && myListBox->count() > 0)
1102       myListBox->item(0)->setSelected(true);
1103     else
1104       myTable->Clear();
1105   }
1106
1107   myTable->SetEnabled(myListBox->count() > 0);
1108   if (myListBox->count() == 0) {
1109     myName->setText("");
1110     myName->setEnabled(false);
1111   }
1112 }
1113
1114 //=======================================================================
1115 // name    : onFilterNameChanged()
1116 // Purpose : SLOT. Called when name of filter changed
1117 //           Change filter name in list box
1118 //=======================================================================
1119 void SMESHGUI_FilterLibraryDlg::onFilterNameChanged (const QString& theName)
1120 {
1121   int aCurrItem = myListBox->currentRow();
1122   if (aCurrItem == -1)
1123     return;
1124
1125   myListBox->blockSignals(true);
1126   myListBox->item(aCurrItem)->setText(theName);
1127   myListBox->blockSignals(false);
1128 }
1129
1130 //=======================================================================
1131 // name    : SMESHGUI_FilterLibraryDlg::SetTable
1132 // Purpose : Set table
1133 //=======================================================================
1134 void SMESHGUI_FilterLibraryDlg::SetTable(const SMESHGUI_FilterTable* theTable)
1135 {
1136   myTable->Copy(theTable);
1137   myName->setText(getDefaultFilterName());
1138   addFilterToLib(myName->text());
1139   myTable->Update();
1140 }
1141
1142 //=======================================================================
1143 // name    : SMESHGUI_FilterLibraryDlg::GetTable
1144 // Purpose : Get table
1145 //=======================================================================
1146 const SMESHGUI_FilterTable* SMESHGUI_FilterLibraryDlg::GetTable() const
1147 {
1148   return myTable;
1149 }
1150
1151
1152 //=======================================================================
1153 // name    : SMESHGUI_FilterLibraryDlg::onEntityTypeChanged
1154 // Purpose : SLOT. Called when entiyt type changed
1155 //=======================================================================
1156 void SMESHGUI_FilterLibraryDlg::onEntityTypeChanged(const int theType)
1157 {
1158   if (myLibrary->_is_nil())
1159     return;
1160
1161   myName->clear();
1162   myCurrFilterName = "";
1163   myCurrFilter = -1;
1164   updateList();
1165   if (myListBox->count())
1166     myListBox->setCurrentItem(0);
1167 }
1168
1169 //=======================================================================
1170 // name    : SMESHGUI_FilterLibraryDlg::onNeedValidation
1171 // Purpose :
1172 //=======================================================================
1173 void SMESHGUI_FilterLibraryDlg::onNeedValidation()
1174 {
1175   if (!myCurrFilterName.isEmpty())
1176   {
1177     bool valid = isValid(true);
1178     myTable->SetValidity(valid);
1179
1180     if (valid)
1181     {
1182       SMESH::Filter_var aFilter = createFilter(myTable->GetType());
1183       myLibrary->Replace(myCurrFilterName.toLatin1().data(),
1184                          myName->text().toLatin1().data(),
1185                          aFilter);
1186     }
1187   }
1188 }
1189
1190 //=================================================================================
1191 // function : keyPressEvent()
1192 // purpose  :
1193 //=================================================================================
1194 void SMESHGUI_FilterLibraryDlg::keyPressEvent( QKeyEvent* e )
1195 {
1196   QDialog::keyPressEvent( e );
1197   if ( e->isAccepted() )
1198     return;
1199
1200   if ( e->key() == Qt::Key_F1 ) {
1201     e->accept();
1202     onHelp();
1203   }
1204 }