Salome HOME
NRI : Update in order to search MODULES documentation and open active MODULE document...
[modules/kernel.git] / src / SALOMEGUI / QAD_DirListDlg.cxx
1 using namespace std;
2 //  File      : QAD_DirListDlg.cxx
3 //  Created   : 10/10/2002
4 //  Descr     : Dialog box for editing of directory list
5
6 //  Author    : Vadim SANDLER
7 //  Project   : SALOME Pro
8 //  Module    : SALOMEGUI 
9 //  Copyright : Open CASCADE
10 //  $Header$
11
12 #include "QAD_DirListDlg.h"
13 #include "QAD_Desktop.h"
14 #include "QAD_FileDlg.h"
15 #include "QAD_MessageBox.h"
16 #include "QAD_Tools.h"
17 #include <qlayout.h>
18 #include <qlabel.h>
19 #include <qpushbutton.h>
20 #include <qapplication.h>
21
22 #define MIN_WIDTH     400
23 #define MIN_HEIGHT    200
24 #define MARGIN_SIZE    11
25 #define SPACING_SIZE    6
26 #define SPACER_SIZE     5
27
28 /*!
29   Constructor
30 */
31 QAD_DirListDlg::QAD_DirListDlg(QWidget* parent, const char* name) 
32      : QDialog (parent, name, true, WStyle_NormalBorder | WStyle_Customize | WStyle_Title |  WStyle_SysMenu ) 
33 {
34   myEdited       = false;
35   myLastSelected = 0;
36   myEdit         = 0; 
37   myBtn          = 0;
38
39   setCaption(tr("QUICK_DIR_LIST_TLT"));
40   setSizeGripEnabled( true );
41
42   QGridLayout* topLayout = new QGridLayout(this);
43   topLayout->setMargin(MARGIN_SIZE);
44   topLayout->setSpacing(SPACING_SIZE);
45
46   myDirList = new QListBox(this);
47   myDirList->setMinimumSize(MIN_WIDTH, MIN_HEIGHT);
48 //  myDirList->setMaximumSize(MIN_WIDTH, MIN_HEIGHT);
49   myDirList->setSelectionMode(QListBox::Single);
50   myDirList->setHScrollBarMode(QListBox::AlwaysOff);
51   myDirList->horizontalScrollBar()->installEventFilter(this);
52   myDirList->verticalScrollBar()->installEventFilter(this);
53   myDirList->insertItem(tr("EMPTY_DIR"));
54   myDirList->installEventFilter(this);
55
56   QHBoxLayout* ctrlLayout = new QHBoxLayout;
57   ctrlLayout->setMargin(0);
58   ctrlLayout->setSpacing(0);
59
60   QLabel* lab = new QLabel(myDirList, tr("DIRECTORIES_LBL"), this);
61
62   QToolButton* insertBtn = new QToolButton(this);
63   insertBtn->setIconSet(QAD_Desktop::getResourceManager()->loadPixmap("QAD", tr("ICON_DIRLIST_INSERT")));
64   insertBtn->setAutoRaise(true);
65
66   QToolButton* deleteBtn = new QToolButton(this);
67   deleteBtn->setIconSet(QAD_Desktop::getResourceManager()->loadPixmap("QAD", tr("ICON_DIRLIST_DELETE")));
68   deleteBtn->setAutoRaise(true);
69
70   QToolButton* upBtn = new QToolButton(this);
71   upBtn->setIconSet(QAD_Desktop::getResourceManager()->loadPixmap("QAD", tr("ICON_DIRLIST_MOVEUP")));
72   upBtn->setAutoRaise(true);
73
74   QToolButton* downBtn = new QToolButton(this);
75   downBtn->setIconSet(QAD_Desktop::getResourceManager()->loadPixmap("QAD", tr("ICON_DIRLIST_MOVEDOWN")));
76   downBtn->setAutoRaise(true);
77   
78   ctrlLayout->addWidget(lab);
79   ctrlLayout->addItem(new QSpacerItem(SPACER_SIZE, SPACER_SIZE, QSizePolicy::Expanding, QSizePolicy::Minimum));
80   ctrlLayout->addWidget(insertBtn);
81   ctrlLayout->addWidget(deleteBtn);
82   ctrlLayout->addWidget(upBtn);
83   ctrlLayout->addWidget(downBtn);
84
85   QHBoxLayout* btnLayout = new QHBoxLayout;
86   btnLayout->setMargin(0);
87   btnLayout->setSpacing(6);
88
89   QPushButton * okBtn     = new QPushButton(tr("BUT_OK"), this);
90   QPushButton * cancelBtn = new QPushButton(tr("BUT_CANCEL"), this);
91   okBtn->setDefault(true);
92   okBtn->setAutoDefault(true);
93   cancelBtn->setAutoDefault(true);
94
95   btnLayout->addWidget(okBtn);
96   btnLayout->addItem(new QSpacerItem(SPACER_SIZE, SPACER_SIZE, QSizePolicy::Expanding, QSizePolicy::Minimum));
97   btnLayout->addWidget(cancelBtn);
98
99   topLayout->addLayout(ctrlLayout, 0, 0);
100   topLayout->addWidget(myDirList,  1, 0);
101   topLayout->addLayout(btnLayout,  2, 0);
102
103   connect(myDirList, SIGNAL(mouseButtonClicked(int, QListBoxItem*, const QPoint&)), 
104           this, SLOT(onMouseButtonClicked(int, QListBoxItem*, const QPoint&)));
105   connect(myDirList, SIGNAL(doubleClicked(QListBoxItem*)), 
106           this, SLOT(onDblClicked(QListBoxItem*)));
107   
108   connect(insertBtn, SIGNAL(clicked()), this, SLOT(onInsert()));
109   connect(deleteBtn, SIGNAL(clicked()), this, SLOT(onDelete()));
110   connect(upBtn,     SIGNAL(clicked()), this, SLOT(onUp()));
111   connect(downBtn,   SIGNAL(clicked()), this, SLOT(onDown()));
112   connect(okBtn,     SIGNAL(clicked()), this, SLOT(onOk()));
113   connect(cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
114
115   QAD_Tools::centerWidget(this, parent);
116 }
117
118 /*!
119   Destructor
120 */
121 QAD_DirListDlg::~QAD_DirListDlg() {
122 }
123
124 /*!
125   Gets list of paths
126 */
127 void QAD_DirListDlg::getPathList(QStringList& list) {
128   list.clear();
129   for (unsigned i = 0; i < myDirList->count()-1; i++)
130     list.append(myDirList->text(i));
131 }
132
133 /*!
134   Sets list of paths
135 */
136 void QAD_DirListDlg::setPathList(const QStringList& list) {
137   for (unsigned i = 0; i < list.count(); i++)
138     myDirList->insertItem(list[i], myDirList->count()-1);
139 }
140
141 /*!
142   Validates entered path, returns true if OK
143 */
144 bool QAD_DirListDlg::validate() {
145   if (myEdited) {
146     QString dirPath = myEdit->text().stripWhiteSpace();
147     QDir dir(dirPath);
148     QListBoxItem* found = 0;
149     for (unsigned i = 0; i < myDirList->count()-1; i++) {
150       QDir aDir(myDirList->text(i));
151       if ( aDir.canonicalPath().isNull() && myDirList->text(i) == dir.absPath() ||
152           !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath()) {
153           found = myDirList->item(i);
154         break;
155       }
156     }
157     if (dirPath.isEmpty()) {
158       if (found) {
159         // it should be last (empty) item in the list - nothing to do
160         return true;
161       }
162       else {
163         // delete directory from the list
164         removeDir(myLastSelected);
165         return true;
166       }
167     }
168     else {
169       if (found) {
170         if (found != myLastSelected) {
171           // it is forbidden to add directory more then once
172           QAD_MessageBox::error1(this, 
173                                  tr("ERR_ERROR"),
174                                  tr("ERR_DIRECTORY_SPECIFIED"), 
175                                  tr("BUT_OK"));
176           myEdit->setFocus();
177           return false;
178         }
179       }
180       else {
181         if (!dir.exists()) {
182           if ( QAD_MessageBox::info2(this, 
183                                      tr("WRN_WARNING"),
184                                      tr("WRN_DIRECTORY_N0T_EXIST").arg(dir.absPath()),
185                                      tr ("BUT_YES"), tr ("BUT_NO"), 
186                                      QAD_YES, QAD_NO, QAD_NO ) == QAD_NO ) {
187             myEdit->setFocus();
188             return false;
189           }
190         }
191         // append
192         appendDir(myLastSelected, dir.absPath());
193       }
194     }
195   }
196   return true;
197 }
198
199 /*!
200   Appends/changes directory
201 */
202 void QAD_DirListDlg::appendDir(QListBoxItem* item, const QString& dir) {
203   int index = myDirList->index(item);
204   if (index >= 0 && index < (int)myDirList->count()) {
205     if (index == (int)myDirList->count()-1) {
206       // it is the last item (new), well, insert it before the last (empty)
207       myDirList->insertItem(dir, myDirList->count()-1);
208     }
209     else {
210       // change item
211       myDirList->changeItem(dir, index);
212     }
213   }
214 }
215
216 /*!
217   Removes directory from list
218 */
219 void QAD_DirListDlg::removeDir(QListBoxItem* item) {
220   // do not remove last item (empty)
221   int index = myDirList->index(item);
222   if (index >= 0 && index < (int)myDirList->count()-1) {
223     delete item;
224     myLastSelected = myDirList->item(index);
225     myDirList->setSelected(myLastSelected, true);
226   }
227 }
228
229 /*!
230   KeyPress event handler, processes <Enter> and <Escape> keys
231 */
232 void QAD_DirListDlg::keyPressEvent(QKeyEvent* event) {
233   if ( myEdited ) {
234     if ( event->key() == Key_Escape ) {
235       delete myEdit;
236       delete myBtn;
237       myEdit = 0;
238       myBtn  = 0;
239       myEdited = false;
240       myDirList->setFocus();
241     }
242     return;
243   }
244   if (event->key() == Key_Return || event->key() == Key_Enter) {
245     accept();
246   }
247   QDialog::keyPressEvent(event);
248 }
249
250 /*!
251   Resize event
252 */
253 void QAD_DirListDlg::resizeEvent(QResizeEvent* event) {
254   QDialog::resizeEvent(event);
255   if ( myEdited ) {
256     myEdit->resize(myDirList->viewport()->width()-myBtn->sizeHint().width(), myEdit->height());
257     myBtn->move(myEdit->width(), myEdit->y());
258   }
259 }
260
261 /*!
262   Called when user clicks inside directories list box
263 */
264 void QAD_DirListDlg::onMouseButtonClicked(int           button, 
265                                           QListBoxItem* item, 
266                                           const QPoint& point) {
267   if (myEdited) {
268     if (!validate()) {
269       myDirList->setCurrentItem(myLastSelected);
270       myDirList->setSelected(myLastSelected, true);
271       return;
272     }
273     delete myEdit;
274     delete myBtn;
275     myEdit = 0;
276     myBtn  = 0;
277     myEdited = false;
278     myDirList->setFocus();
279   }
280   if (item) {
281     myDirList->setCurrentItem(item);
282     myDirList->setSelected(item, true);
283     myDirList->ensureCurrentVisible();
284     qApp->processEvents();
285     if (button == LeftButton && myLastSelected == item) {
286       QRect ir = myDirList->itemRect(myLastSelected);
287       
288       myEdit = new QLineEdit(myDirList->viewport());
289       myBtn  = new QToolButton(myDirList->viewport());
290       myBtn->setText(" ... ");
291       connect(myBtn, SIGNAL(clicked()), this, SLOT(onBtnClicked()));
292       myEdit->setGeometry(0, 
293                           ir.top()-(myEdit->sizeHint().height()-ir.height())/2, 
294                           myDirList->viewport()->width()-myBtn->sizeHint().width(), 
295                           myEdit->sizeHint().height());
296       myBtn->setGeometry (myEdit->width(), 
297                           ir.top()-(myEdit->sizeHint().height()-ir.height())/2, 
298                           myBtn->sizeHint().width(),
299                           myEdit->sizeHint().height());
300       connect(myEdit, SIGNAL(returnPressed()), this, SLOT(onEditFinished()));
301       myEdited = true;
302       myEdit->show();
303       myBtn->show();
304       if (myDirList->index(myLastSelected) != (int)myDirList->count()-1)
305         myEdit->setText(myLastSelected->text());
306       myEdit->selectAll();
307       myEdit->setCursorPosition(myEdit->text().length());
308       myEdit->installEventFilter(this);
309       myEdit->setFocus();
310     }
311   }
312   else {
313     myDirList->clearSelection();
314   }
315   myLastSelected = item;
316 }
317
318 /*!
319   Called when user double-clicks on any item
320 */
321 void QAD_DirListDlg::onDblClicked(QListBoxItem* item) {
322   onMouseButtonClicked(LeftButton, item, QPoint(0,0));
323 }
324
325 /*!
326   <...> (Browse dir) button slot
327 */
328 void QAD_DirListDlg::onBtnClicked() {
329   QString dir = myEdit->text().stripWhiteSpace().isEmpty() ? 
330                 QString::null : 
331                 myEdit->text().stripWhiteSpace();
332   dir = QAD_FileDlg::getExistingDirectory(this, dir, tr("SELECT_DIRECTORY"), true);
333   if (!dir.isEmpty()) {
334     myEdit->setText(dir);
335     myEdit->selectAll();
336     myEdit->setCursorPosition(myEdit->text().length());
337   }
338 }
339
340 /*!
341   Called when user finises editing of path by pressing <Enter>
342 */
343 void QAD_DirListDlg::onEditFinished() {
344   if (myEdit) {
345     if (!validate()) {
346       myDirList->setCurrentItem(myLastSelected);
347       myDirList->setSelected(myLastSelected, true);
348       return;
349     }
350     delete myEdit;
351     delete myBtn;
352     myEdit = 0;
353     myBtn  = 0;
354     myEdited = false;
355     myDirList->setFocus();
356   }
357 }
358
359 /*!
360   Event filter
361 */
362 bool QAD_DirListDlg::eventFilter(QObject* object, QEvent* event) {
363   if ( myEdited ) {
364     if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) {
365       if (object == myDirList->horizontalScrollBar() || object == myDirList->verticalScrollBar()) {
366         if (!validate()) {
367           myDirList->setCurrentItem(myLastSelected);
368           myDirList->setSelected(myLastSelected, true);
369           return true;
370         }
371         delete myEdit;
372         delete myBtn;
373         myEdit = 0;
374         myBtn  = 0;
375         myEdited = false;
376         myDirList->setFocus();
377       }
378     }
379     else if (event->type() == QEvent::KeyPress) {
380       QKeyEvent* ke = (QKeyEvent*)event;
381       if (ke->key() == Key_Tab)
382         return true;
383       if (object == myDirList) {
384         return true;
385       }
386       else if (object == myEdit) {
387         if ( ke->key() == Key_Up || ke->key() == Key_Down || ke->key() == Key_PageUp || ke->key() == Key_PageDown ||
388              ( ke->key() == Key_Home  || ke->key() == Key_End  || ke->key() == Key_Prior || ke->key() == Key_Next ) && 
389                  (ke->state() & ControlButton) ) {
390           return true;
391         }
392         else if ( ke->key() == Key_Escape ) {
393           delete myEdit;
394           delete myBtn;
395           myEdit = 0;
396           myBtn  = 0;
397           myEdited = false;
398           myDirList->setFocus();
399           return true;
400         }
401       }
402     }
403   }
404   else {
405     if (event->type() == QEvent::KeyPress) {
406       if (object == myDirList) {
407         QKeyEvent* ke = (QKeyEvent*)event;
408         if (ke->key() == Key_Return || ke->key() == Key_Enter) {
409           accept();
410         }
411         else {
412           QChar c(ke->ascii());
413           if (c.isPrint()) {
414             QListBoxItem* item = myDirList->item(myDirList->currentItem());
415             if (item) {
416               myDirList->setCurrentItem(item);
417               myDirList->setSelected(item, true);
418               myDirList->ensureCurrentVisible();
419               myLastSelected = item;
420               qApp->processEvents();
421               QRect ir = myDirList->itemRect(myLastSelected);
422                 
423               myEdit = new QLineEdit(myDirList->viewport());
424               myBtn  = new QToolButton(myDirList->viewport());
425               myBtn->setText(" ... ");
426               connect(myBtn, SIGNAL(clicked()), this, SLOT(onBtnClicked()));
427               myEdit->setGeometry(0, 
428                                   ir.top()-(myEdit->sizeHint().height()-ir.height())/2, 
429                                   myDirList->viewport()->width()-myBtn->sizeHint().width(), 
430                                   myEdit->sizeHint().height());
431               myBtn->setGeometry (myEdit->width(), 
432                                   ir.top()-(myEdit->sizeHint().height()-ir.height())/2, 
433                                   myBtn->sizeHint().width(),
434                                   myEdit->sizeHint().height());
435               connect(myEdit, SIGNAL(returnPressed()), this, SLOT(onEditFinished()));
436               myEdited = true;
437               myEdit->show();
438               myBtn->show();
439               myEdit->setText(c);
440               myEdit->setCursorPosition(myEdit->text().length());
441               myEdit->installEventFilter(this);
442               myEdit->setFocus();
443             }
444           }
445         }
446       }
447     }
448   }
449   return QDialog::eventFilter(object, event);
450 }
451
452 /*!
453   <Insert> button slot
454 */
455 void QAD_DirListDlg::onInsert() {
456   if (!myEdited) {
457     myLastSelected = 0;
458     onMouseButtonClicked(LeftButton, myDirList->item(myDirList->count()-1), QPoint(0,0));
459     onMouseButtonClicked(LeftButton, myDirList->item(myDirList->count()-1), QPoint(0,0));
460   }
461 }
462
463 /*!
464   <Delete> button slot
465 */
466 void QAD_DirListDlg::onDelete() {
467   if (!myEdited && myDirList->currentItem() >=0) {
468     removeDir(myDirList->item(myDirList->currentItem()));
469     myDirList->setFocus();
470   }
471 }
472
473 /*!
474   <Move up> button slot
475 */
476 void QAD_DirListDlg::onUp() {
477   if (!myEdited && myLastSelected) {
478     int index = myDirList->currentItem();
479     if (index > 0 && index < (int)myDirList->count()-1 && myDirList->isSelected(index)) {
480       QString t = myDirList->text(index-1);
481       myDirList->changeItem(myDirList->text(index), index-1);
482       myDirList->changeItem(t, index);
483       myDirList->setCurrentItem(index-1);
484       myLastSelected = myDirList->item(index-1);
485       myDirList->setSelected(myLastSelected, true);
486       myDirList->setFocus();
487     }
488   }
489 }
490
491 /*!
492   <Move down> button slot
493 */
494 void QAD_DirListDlg::onDown() {
495   if (!myEdited && myLastSelected) {
496     int index = myDirList->currentItem();
497     if (index >= 0 && index < (int)myDirList->count()-2 && myDirList->isSelected(index)) {
498       QString t = myDirList->text(index+1);
499       myDirList->changeItem(myDirList->text(index), index+1);
500       myDirList->changeItem(t, index);
501       myDirList->setCurrentItem(index+1);
502       myLastSelected = myDirList->item(index+1);
503       myDirList->setSelected(myLastSelected, true);
504       myDirList->setFocus();
505     }
506   }
507 }
508
509 /*!
510   Purpose  : <OK> button slot
511 */
512 void QAD_DirListDlg::onOk() {
513   if (validate())
514     accept();
515 }