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