1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/
19 #include "QtxDirListEditor.h"
23 #include <qpushbutton.h>
24 #include <qmessagebox.h>
25 #include <qfiledialog.h>
26 #include <qapplication.h>
28 #define MARGIN_SIZE 11
29 #define SPACING_SIZE 6
32 static const char* delete_icon[] = {
55 static const char* insert_icon[] = {
80 static const char* movedown_icon[] = {
102 static const char* moveup_icon[] = {
127 QtxDirListEditor::QtxDirListEditor( QWidget* parent )
135 QGridLayout* topLayout = new QGridLayout(this);
136 topLayout->setMargin(0);
137 topLayout->setSpacing(0);
139 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
141 myDirList = new QListBox(this);
142 myDirList->setSelectionMode(QListBox::Single);
143 myDirList->setHScrollBarMode(QListBox::AlwaysOff);
144 myDirList->horizontalScrollBar()->installEventFilter(this);
145 myDirList->verticalScrollBar()->installEventFilter(this);
146 myDirList->insertItem(tr("<empty>"));
147 myDirList->installEventFilter(this);
149 QHBoxLayout* ctrlLayout = new QHBoxLayout;
150 ctrlLayout->setMargin(0);
151 ctrlLayout->setSpacing(0);
153 // QLabel* lab = new QLabel(myDirList, tr("DIRECTORIES_LBL"), this);
155 QToolButton* insertBtn = new QToolButton(this);
156 insertBtn->setIconSet(QPixmap( insert_icon ));
157 insertBtn->setAutoRaise(true);
159 QToolButton* deleteBtn = new QToolButton(this);
160 deleteBtn->setIconSet(QPixmap( delete_icon ));
161 deleteBtn->setAutoRaise(true);
163 QToolButton* upBtn = new QToolButton(this);
164 upBtn->setIconSet(QPixmap( moveup_icon ));
165 upBtn->setAutoRaise(true);
167 QToolButton* downBtn = new QToolButton(this);
168 downBtn->setIconSet(QPixmap( movedown_icon ));
169 downBtn->setAutoRaise(true);
171 // ctrlLayout->addWidget(lab);
172 ctrlLayout->addItem(new QSpacerItem(SPACER_SIZE, SPACER_SIZE, QSizePolicy::Expanding, QSizePolicy::Minimum));
173 ctrlLayout->addWidget(insertBtn);
174 ctrlLayout->addWidget(deleteBtn);
175 ctrlLayout->addWidget(upBtn);
176 ctrlLayout->addWidget(downBtn);
178 QHBoxLayout* btnLayout = new QHBoxLayout;
179 btnLayout->setMargin(0);
180 btnLayout->setSpacing(6);
182 topLayout->addLayout(ctrlLayout, 0, 0);
183 topLayout->addWidget(myDirList, 1, 0);
184 topLayout->addLayout(btnLayout, 2, 0);
186 connect(myDirList, SIGNAL(mouseButtonClicked(int, QListBoxItem*, const QPoint&)),
187 this, SLOT(onMouseButtonClicked(int, QListBoxItem*, const QPoint&)));
188 connect(myDirList, SIGNAL(doubleClicked(QListBoxItem*)),
189 this, SLOT(onDblClicked(QListBoxItem*)));
191 connect(insertBtn, SIGNAL(clicked()), this, SLOT(onInsert()));
192 connect(deleteBtn, SIGNAL(clicked()), this, SLOT(onDelete()));
193 connect(upBtn, SIGNAL(clicked()), this, SLOT(onUp()));
194 connect(downBtn, SIGNAL(clicked()), this, SLOT(onDown()));
200 QtxDirListEditor::~QtxDirListEditor()
207 void QtxDirListEditor::getPathList(QStringList& list)
209 // Finish the path editing
213 myEdit->deleteLater();
214 myBtn->deleteLater();
218 myDirList->setFocus();
222 for (unsigned i = 0; i < myDirList->count()-1; i++)
223 list.append(myDirList->text(i));
229 void QtxDirListEditor::setPathList(const QStringList& list) {
231 myDirList->insertItem(tr("<empty>"));
232 for (unsigned i = 0; i < list.count(); i++)
233 myDirList->insertItem(list[i], myDirList->count()-1);
237 Validates entered path, returns true if OK
239 bool QtxDirListEditor::validate( const bool quietMode )
243 QString dirPath = QFileInfo( myEdit->text().stripWhiteSpace() ).filePath();
246 if ( dirPath.startsWith( "~") ) {
247 dirPath = dirPath.remove(0,1);
249 int slashPos = dirPath.find("/");
250 if ( slashPos >= 0 ) {
251 user = dirPath.left(slashPos);
252 dirPath = dirPath.mid(slashPos);
258 if ( user.isEmpty() )
259 user = getenv( "USER" );
261 struct passwd* user_data = getpwnam( user.latin1() );
262 if ( user_data == NULL ) {
263 // unknown user or something another error
264 QMessageBox::critical(this,
266 tr("Unknown user %1").arg(user),
271 dirPath = user_data->pw_dir + dirPath;
276 QListBoxItem* found = 0;
277 for (unsigned i = 0; i < myDirList->count()-1; i++) {
278 QDir aDir(myDirList->text(i));
279 if ( aDir.canonicalPath().isNull() && myDirList->text(i) == dir.absPath() ||
280 !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath()) {
281 found = myDirList->item(i);
285 if (dirPath.isEmpty()) {
287 // it should be last (empty) item in the list - nothing to do
291 // delete directory from the list
292 removeDir(myLastSelected);
298 if (found != myLastSelected) {
299 // it is forbidden to add directory more then once
301 QMessageBox::critical(this,
303 tr("Directory already specified."),
311 if ( !quietMode && QMessageBox::information(this,
313 tr("%1\n\nThe directory doesn't exist.\nAdd directory anyway?").arg(dir.absPath()),
314 tr("Yes"), tr("No"), QString::null, 1, 1) == 1) {
320 appendDir(myLastSelected, dir.absPath());
328 Appends/changes directory
330 void QtxDirListEditor::appendDir(QListBoxItem* item, const QString& dir) {
331 int index = myDirList->index(item);
332 if (index >= 0 && index < (int)myDirList->count()) {
333 if (index == (int)myDirList->count()-1) {
334 // it is the last item (new), well, insert it before the last (empty)
335 myDirList->insertItem(dir, myDirList->count()-1);
339 myDirList->changeItem(dir, index);
345 Removes directory from list
347 void QtxDirListEditor::removeDir(QListBoxItem* item) {
348 // do not remove last item (empty)
349 int index = myDirList->index(item);
350 if (index >= 0 && index < (int)myDirList->count()-1) {
352 myLastSelected = myDirList->item(index);
353 myDirList->setSelected(myLastSelected, true);
360 void QtxDirListEditor::resizeEvent(QResizeEvent* event) {
361 QWidget::resizeEvent(event);
363 myEdit->resize(myDirList->viewport()->width()-myBtn->sizeHint().width(), myEdit->height());
364 myBtn->move(myEdit->width(), myEdit->y());
369 Called when user clicks inside directories list box
371 void QtxDirListEditor::onMouseButtonClicked(int button,
373 const QPoint& point) {
376 myDirList->setCurrentItem(myLastSelected);
377 myDirList->setSelected(myLastSelected, true);
385 myDirList->setFocus();
388 myDirList->setCurrentItem(item);
389 myDirList->setSelected(item, true);
390 myDirList->ensureCurrentVisible();
391 qApp->processEvents();
392 if (button == LeftButton && myLastSelected == item) {
393 QRect ir = myDirList->itemRect(myLastSelected);
395 myEdit = new QLineEdit(myDirList->viewport());
396 myBtn = new QToolButton(myDirList->viewport());
397 myBtn->setText(" ... ");
398 connect(myBtn, SIGNAL(clicked()), this, SLOT(onBtnClicked()));
399 myEdit->setGeometry(0,
400 ir.top()-(myEdit->sizeHint().height()-ir.height())/2,
401 myDirList->viewport()->width()-myBtn->sizeHint().width(),
402 myEdit->sizeHint().height());
403 myBtn->setGeometry (myEdit->width(),
404 ir.top()-(myEdit->sizeHint().height()-ir.height())/2,
405 myBtn->sizeHint().width(),
406 myEdit->sizeHint().height());
407 connect(myEdit, SIGNAL(returnPressed()), this, SLOT(onEditFinished()));
411 if (myDirList->index(myLastSelected) != (int)myDirList->count()-1)
412 myEdit->setText(myLastSelected->text());
414 myEdit->setCursorPosition(myEdit->text().length());
415 myEdit->installEventFilter(this);
420 myDirList->clearSelection();
422 myLastSelected = item;
426 Called when user double-clicks on any item
428 void QtxDirListEditor::onDblClicked(QListBoxItem* item) {
429 onMouseButtonClicked(LeftButton, item, QPoint(0,0));
433 <...> (Browse dir) button slot
435 void QtxDirListEditor::onBtnClicked() {
436 QString dir = myEdit->text().stripWhiteSpace().isEmpty() ?
438 myEdit->text().stripWhiteSpace();
440 dir = QFileDialog::getExistingDirectory(dir, this, 0, tr("Select directory"), true);
442 if (!dir.isEmpty()) {
443 myEdit->setText(dir);
445 myEdit->setCursorPosition(myEdit->text().length());
450 Called when user finises editing of path by pressing <Enter>
452 void QtxDirListEditor::onEditFinished() {
455 myDirList->setCurrentItem(myLastSelected);
456 myDirList->setSelected(myLastSelected, true);
459 myEdit->deleteLater();
460 myBtn->deleteLater();
464 myDirList->setFocus();
471 bool QtxDirListEditor::eventFilter(QObject* object, QEvent* event) {
473 if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) {
474 if (object == myDirList->horizontalScrollBar() || object == myDirList->verticalScrollBar()) {
476 myDirList->setCurrentItem(myLastSelected);
477 myDirList->setSelected(myLastSelected, true);
485 myDirList->setFocus();
488 else if (event->type() == QEvent::KeyPress) {
489 QKeyEvent* ke = (QKeyEvent*)event;
490 if (ke->key() == Key_Tab)
492 if (object == myDirList) {
495 else if (object == myEdit) {
496 if ( ke->key() == Key_Up || ke->key() == Key_Down || ke->key() == Key_PageUp || ke->key() == Key_PageDown ||
497 ( ke->key() == Key_Home || ke->key() == Key_End || ke->key() == Key_Prior || ke->key() == Key_Next ) &&
498 (ke->state() & ControlButton) ) {
501 else if ( ke->key() == Key_Escape ) {
507 myDirList->setFocus();
513 return QWidget::eventFilter(object, event);
519 void QtxDirListEditor::onInsert() {
522 onMouseButtonClicked(LeftButton, myDirList->item(myDirList->count()-1), QPoint(0,0));
523 onMouseButtonClicked(LeftButton, myDirList->item(myDirList->count()-1), QPoint(0,0));
530 void QtxDirListEditor::onDelete() {
531 if (!myEdited && myDirList->currentItem() >=0) {
532 removeDir(myDirList->item(myDirList->currentItem()));
533 myDirList->setFocus();
538 <Move up> button slot
540 void QtxDirListEditor::onUp() {
541 if (!myEdited && myLastSelected) {
542 int index = myDirList->currentItem();
543 if (index > 0 && index < (int)myDirList->count()-1 && myDirList->isSelected(index)) {
544 QString t = myDirList->text(index-1);
545 myDirList->changeItem(myDirList->text(index), index-1);
546 myDirList->changeItem(t, index);
547 myDirList->setCurrentItem(index-1);
548 myLastSelected = myDirList->item(index-1);
549 myDirList->setSelected(myLastSelected, true);
550 myDirList->setFocus();
556 <Move down> button slot
558 void QtxDirListEditor::onDown() {
559 if (!myEdited && myLastSelected) {
560 int index = myDirList->currentItem();
561 if (index >= 0 && index < (int)myDirList->count()-2 && myDirList->isSelected(index)) {
562 QString t = myDirList->text(index+1);
563 myDirList->changeItem(myDirList->text(index), index+1);
564 myDirList->changeItem(t, index);
565 myDirList->setCurrentItem(index+1);
566 myLastSelected = myDirList->item(index+1);
567 myDirList->setSelected(myLastSelected, true);
568 myDirList->setFocus();