1 // SALOME SALOMEGUI : implementation of desktop and GUI kernel
3 // Copyright (C) 2003 CEA/DEN, EDF R&D
7 // File : QAD_DirListDlg.cxx
8 // Author : Vadim SANDLER
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"
19 #include <qpushbutton.h>
20 #include <qapplication.h>
24 #define MIN_HEIGHT 200
25 #define MARGIN_SIZE 11
26 #define SPACING_SIZE 6
32 QAD_DirListDlg::QAD_DirListDlg(QWidget* parent, const char* name)
33 : QDialog (parent, name, true, WStyle_NormalBorder | WStyle_Customize | WStyle_Title | WStyle_SysMenu )
40 setCaption(tr("QUICK_DIR_LIST_TLT"));
41 setSizeGripEnabled( true );
43 QGridLayout* topLayout = new QGridLayout(this);
44 topLayout->setMargin(MARGIN_SIZE);
45 topLayout->setSpacing(SPACING_SIZE);
47 myDirList = new QListBox(this);
48 myDirList->setMinimumSize(MIN_WIDTH, MIN_HEIGHT);
49 // myDirList->setMaximumSize(MIN_WIDTH, MIN_HEIGHT);
50 myDirList->setSelectionMode(QListBox::Single);
51 myDirList->setHScrollBarMode(QListBox::AlwaysOff);
52 myDirList->horizontalScrollBar()->installEventFilter(this);
53 myDirList->verticalScrollBar()->installEventFilter(this);
54 myDirList->insertItem(tr("EMPTY_DIR"));
55 myDirList->installEventFilter(this);
57 QHBoxLayout* ctrlLayout = new QHBoxLayout;
58 ctrlLayout->setMargin(0);
59 ctrlLayout->setSpacing(0);
61 QLabel* lab = new QLabel(myDirList, tr("DIRECTORIES_LBL"), this);
63 QToolButton* insertBtn = new QToolButton(this);
64 insertBtn->setIconSet(QAD_Desktop::getResourceManager()->loadPixmap("QAD", tr("ICON_DIRLIST_INSERT")));
65 insertBtn->setAutoRaise(true);
67 QToolButton* deleteBtn = new QToolButton(this);
68 deleteBtn->setIconSet(QAD_Desktop::getResourceManager()->loadPixmap("QAD", tr("ICON_DIRLIST_DELETE")));
69 deleteBtn->setAutoRaise(true);
71 QToolButton* upBtn = new QToolButton(this);
72 upBtn->setIconSet(QAD_Desktop::getResourceManager()->loadPixmap("QAD", tr("ICON_DIRLIST_MOVEUP")));
73 upBtn->setAutoRaise(true);
75 QToolButton* downBtn = new QToolButton(this);
76 downBtn->setIconSet(QAD_Desktop::getResourceManager()->loadPixmap("QAD", tr("ICON_DIRLIST_MOVEDOWN")));
77 downBtn->setAutoRaise(true);
79 ctrlLayout->addWidget(lab);
80 ctrlLayout->addItem(new QSpacerItem(SPACER_SIZE, SPACER_SIZE, QSizePolicy::Expanding, QSizePolicy::Minimum));
81 ctrlLayout->addWidget(insertBtn);
82 ctrlLayout->addWidget(deleteBtn);
83 ctrlLayout->addWidget(upBtn);
84 ctrlLayout->addWidget(downBtn);
86 QHBoxLayout* btnLayout = new QHBoxLayout;
87 btnLayout->setMargin(0);
88 btnLayout->setSpacing(6);
90 QPushButton * okBtn = new QPushButton(tr("BUT_OK"), this);
91 QPushButton * cancelBtn = new QPushButton(tr("BUT_CANCEL"), this);
92 okBtn->setDefault(true);
93 okBtn->setAutoDefault(true);
94 cancelBtn->setAutoDefault(true);
96 btnLayout->addWidget(okBtn);
97 btnLayout->addItem(new QSpacerItem(SPACER_SIZE, SPACER_SIZE, QSizePolicy::Expanding, QSizePolicy::Minimum));
98 btnLayout->addWidget(cancelBtn);
100 topLayout->addLayout(ctrlLayout, 0, 0);
101 topLayout->addWidget(myDirList, 1, 0);
102 topLayout->addLayout(btnLayout, 2, 0);
104 connect(myDirList, SIGNAL(mouseButtonClicked(int, QListBoxItem*, const QPoint&)),
105 this, SLOT(onMouseButtonClicked(int, QListBoxItem*, const QPoint&)));
106 connect(myDirList, SIGNAL(doubleClicked(QListBoxItem*)),
107 this, SLOT(onDblClicked(QListBoxItem*)));
109 connect(insertBtn, SIGNAL(clicked()), this, SLOT(onInsert()));
110 connect(deleteBtn, SIGNAL(clicked()), this, SLOT(onDelete()));
111 connect(upBtn, SIGNAL(clicked()), this, SLOT(onUp()));
112 connect(downBtn, SIGNAL(clicked()), this, SLOT(onDown()));
113 connect(okBtn, SIGNAL(clicked()), this, SLOT(onOk()));
114 connect(cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
116 QAD_Tools::centerWidget(this, parent);
122 QAD_DirListDlg::~QAD_DirListDlg() {
128 void QAD_DirListDlg::getPathList(QStringList& list) {
130 for (unsigned i = 0; i < myDirList->count()-1; i++)
131 list.append(myDirList->text(i));
137 void QAD_DirListDlg::setPathList(const QStringList& list) {
138 for (unsigned i = 0; i < list.count(); i++)
139 myDirList->insertItem(list[i], myDirList->count()-1);
143 Validates entered path, returns true if OK
148 bool QAD_DirListDlg::validate() {
150 QString dirPath = myEdit->text().stripWhiteSpace();
152 if ( dirPath.startsWith( "~") ) {
153 dirPath = dirPath.remove(0,1);
155 int slashPos = dirPath.find("/");
156 if ( slashPos >= 0 ) {
157 user = dirPath.left(slashPos);
158 dirPath = dirPath.mid(slashPos);
164 if ( user.isEmpty() )
165 user = getenv( "USER" );
167 struct passwd* user_data = getpwnam( user.latin1() );
168 if ( user_data == NULL ) {
169 // unknown user or something another error
170 QAD_MessageBox::error1(this,
172 tr("Unknown user %1").arg(user),
177 dirPath = user_data->pw_dir + dirPath;
181 QListBoxItem* found = 0;
182 for (unsigned i = 0; i < myDirList->count()-1; i++) {
183 QDir aDir(myDirList->text(i));
184 if ( aDir.canonicalPath().isNull() && myDirList->text(i) == dir.absPath() ||
185 !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath()) {
186 found = myDirList->item(i);
190 if (dirPath.isEmpty()) {
192 // it should be last (empty) item in the list - nothing to do
196 // delete directory from the list
197 removeDir(myLastSelected);
203 if (found != myLastSelected) {
204 // it is forbidden to add directory more then once
205 QAD_MessageBox::error1(this,
207 tr("ERR_DIRECTORY_SPECIFIED"),
215 if ( QAD_MessageBox::info2(this,
217 tr("WRN_DIRECTORY_N0T_EXIST").arg(dir.absPath()),
218 tr ("BUT_YES"), tr ("BUT_NO"),
219 QAD_YES, QAD_NO, QAD_NO ) == QAD_NO ) {
225 appendDir(myLastSelected, dir.absPath());
233 Appends/changes directory
235 void QAD_DirListDlg::appendDir(QListBoxItem* item, const QString& dir) {
236 int index = myDirList->index(item);
237 if (index >= 0 && index < (int)myDirList->count()) {
238 if (index == (int)myDirList->count()-1) {
239 // it is the last item (new), well, insert it before the last (empty)
240 myDirList->insertItem(dir, myDirList->count()-1);
244 myDirList->changeItem(dir, index);
250 Removes directory from list
252 void QAD_DirListDlg::removeDir(QListBoxItem* item) {
253 // do not remove last item (empty)
254 int index = myDirList->index(item);
255 if (index >= 0 && index < (int)myDirList->count()-1) {
257 myLastSelected = myDirList->item(index);
258 myDirList->setSelected(myLastSelected, true);
263 KeyPress event handler, processes <Enter> and <Escape> keys
265 void QAD_DirListDlg::keyPressEvent(QKeyEvent* event) {
267 if ( event->key() == Key_Escape ) {
273 myDirList->setFocus();
277 if (event->key() == Key_Return || event->key() == Key_Enter) {
280 QDialog::keyPressEvent(event);
286 void QAD_DirListDlg::resizeEvent(QResizeEvent* event) {
287 QDialog::resizeEvent(event);
289 myEdit->resize(myDirList->viewport()->width()-myBtn->sizeHint().width(), myEdit->height());
290 myBtn->move(myEdit->width(), myEdit->y());
295 Called when user clicks inside directories list box
297 void QAD_DirListDlg::onMouseButtonClicked(int button,
299 const QPoint& point) {
302 myDirList->setCurrentItem(myLastSelected);
303 myDirList->setSelected(myLastSelected, true);
311 myDirList->setFocus();
314 myDirList->setCurrentItem(item);
315 myDirList->setSelected(item, true);
316 myDirList->ensureCurrentVisible();
317 qApp->processEvents();
318 if (button == LeftButton && myLastSelected == item) {
319 QRect ir = myDirList->itemRect(myLastSelected);
321 myEdit = new QLineEdit(myDirList->viewport());
322 myBtn = new QToolButton(myDirList->viewport());
323 myBtn->setText(" ... ");
324 connect(myBtn, SIGNAL(clicked()), this, SLOT(onBtnClicked()));
325 myEdit->setGeometry(0,
326 ir.top()-(myEdit->sizeHint().height()-ir.height())/2,
327 myDirList->viewport()->width()-myBtn->sizeHint().width(),
328 myEdit->sizeHint().height());
329 myBtn->setGeometry (myEdit->width(),
330 ir.top()-(myEdit->sizeHint().height()-ir.height())/2,
331 myBtn->sizeHint().width(),
332 myEdit->sizeHint().height());
333 connect(myEdit, SIGNAL(returnPressed()), this, SLOT(onEditFinished()));
337 if (myDirList->index(myLastSelected) != (int)myDirList->count()-1)
338 myEdit->setText(myLastSelected->text());
340 myEdit->setCursorPosition(myEdit->text().length());
341 myEdit->installEventFilter(this);
346 myDirList->clearSelection();
348 myLastSelected = item;
352 Called when user double-clicks on any item
354 void QAD_DirListDlg::onDblClicked(QListBoxItem* item) {
355 onMouseButtonClicked(LeftButton, item, QPoint(0,0));
359 <...> (Browse dir) button slot
361 void QAD_DirListDlg::onBtnClicked() {
362 QString dir = myEdit->text().stripWhiteSpace().isEmpty() ?
364 myEdit->text().stripWhiteSpace();
365 dir = QAD_FileDlg::getExistingDirectory(this, dir, tr("SELECT_DIRECTORY"), true);
366 if (!dir.isEmpty()) {
367 myEdit->setText(dir);
369 myEdit->setCursorPosition(myEdit->text().length());
374 Called when user finises editing of path by pressing <Enter>
376 void QAD_DirListDlg::onEditFinished() {
379 myDirList->setCurrentItem(myLastSelected);
380 myDirList->setSelected(myLastSelected, true);
388 myDirList->setFocus();
395 bool QAD_DirListDlg::eventFilter(QObject* object, QEvent* event) {
397 if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) {
398 if (object == myDirList->horizontalScrollBar() || object == myDirList->verticalScrollBar()) {
400 myDirList->setCurrentItem(myLastSelected);
401 myDirList->setSelected(myLastSelected, true);
409 myDirList->setFocus();
412 else if (event->type() == QEvent::KeyPress) {
413 QKeyEvent* ke = (QKeyEvent*)event;
414 if (ke->key() == Key_Tab)
416 if (object == myDirList) {
419 else if (object == myEdit) {
420 if ( ke->key() == Key_Up || ke->key() == Key_Down || ke->key() == Key_PageUp || ke->key() == Key_PageDown ||
421 ( ke->key() == Key_Home || ke->key() == Key_End || ke->key() == Key_Prior || ke->key() == Key_Next ) &&
422 (ke->state() & ControlButton) ) {
425 else if ( ke->key() == Key_Escape ) {
431 myDirList->setFocus();
438 if (event->type() == QEvent::KeyPress) {
439 if (object == myDirList) {
440 QKeyEvent* ke = (QKeyEvent*)event;
441 if (ke->key() == Key_Return || ke->key() == Key_Enter) {
445 QChar c(ke->ascii());
447 QListBoxItem* item = myDirList->item(myDirList->currentItem());
449 myDirList->setCurrentItem(item);
450 myDirList->setSelected(item, true);
451 myDirList->ensureCurrentVisible();
452 myLastSelected = item;
453 qApp->processEvents();
454 QRect ir = myDirList->itemRect(myLastSelected);
456 myEdit = new QLineEdit(myDirList->viewport());
457 myBtn = new QToolButton(myDirList->viewport());
458 myBtn->setText(" ... ");
459 connect(myBtn, SIGNAL(clicked()), this, SLOT(onBtnClicked()));
460 myEdit->setGeometry(0,
461 ir.top()-(myEdit->sizeHint().height()-ir.height())/2,
462 myDirList->viewport()->width()-myBtn->sizeHint().width(),
463 myEdit->sizeHint().height());
464 myBtn->setGeometry (myEdit->width(),
465 ir.top()-(myEdit->sizeHint().height()-ir.height())/2,
466 myBtn->sizeHint().width(),
467 myEdit->sizeHint().height());
468 connect(myEdit, SIGNAL(returnPressed()), this, SLOT(onEditFinished()));
473 myEdit->setCursorPosition(myEdit->text().length());
474 myEdit->installEventFilter(this);
482 return QDialog::eventFilter(object, event);
488 void QAD_DirListDlg::onInsert() {
491 onMouseButtonClicked(LeftButton, myDirList->item(myDirList->count()-1), QPoint(0,0));
492 onMouseButtonClicked(LeftButton, myDirList->item(myDirList->count()-1), QPoint(0,0));
499 void QAD_DirListDlg::onDelete() {
500 if (!myEdited && myDirList->currentItem() >=0) {
501 removeDir(myDirList->item(myDirList->currentItem()));
502 myDirList->setFocus();
507 <Move up> button slot
509 void QAD_DirListDlg::onUp() {
510 if (!myEdited && myLastSelected) {
511 int index = myDirList->currentItem();
512 if (index > 0 && index < (int)myDirList->count()-1 && myDirList->isSelected(index)) {
513 QString t = myDirList->text(index-1);
514 myDirList->changeItem(myDirList->text(index), index-1);
515 myDirList->changeItem(t, index);
516 myDirList->setCurrentItem(index-1);
517 myLastSelected = myDirList->item(index-1);
518 myDirList->setSelected(myLastSelected, true);
519 myDirList->setFocus();
525 <Move down> button slot
527 void QAD_DirListDlg::onDown() {
528 if (!myEdited && myLastSelected) {
529 int index = myDirList->currentItem();
530 if (index >= 0 && index < (int)myDirList->count()-2 && myDirList->isSelected(index)) {
531 QString t = myDirList->text(index+1);
532 myDirList->changeItem(myDirList->text(index), index+1);
533 myDirList->changeItem(t, index);
534 myDirList->setCurrentItem(index+1);
535 myLastSelected = myDirList->item(index+1);
536 myDirList->setSelected(myLastSelected, true);
537 myDirList->setFocus();
543 Purpose : <OK> button slot
545 void QAD_DirListDlg::onOk() {