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