1 #include "QtxDirListEditor.h"
5 #include <qpushbutton.h>
6 #include <qmessagebox.h>
7 #include <qfiledialog.h>
8 #include <qapplication.h>
10 #define MARGIN_SIZE 11
11 #define SPACING_SIZE 6
14 static const char* delete_icon[] = {
37 static const char* insert_icon[] = {
62 static const char* movedown_icon[] = {
84 static const char* moveup_icon[] = {
109 QtxDirListEditor::QtxDirListEditor( QWidget* parent )
117 QGridLayout* topLayout = new QGridLayout(this);
118 topLayout->setMargin(0);
119 topLayout->setSpacing(0);
121 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
123 myDirList = new QListBox(this);
124 myDirList->setSelectionMode(QListBox::Single);
125 myDirList->setHScrollBarMode(QListBox::AlwaysOff);
126 myDirList->horizontalScrollBar()->installEventFilter(this);
127 myDirList->verticalScrollBar()->installEventFilter(this);
128 myDirList->insertItem(tr("<empty>"));
129 myDirList->installEventFilter(this);
131 QHBoxLayout* ctrlLayout = new QHBoxLayout;
132 ctrlLayout->setMargin(0);
133 ctrlLayout->setSpacing(0);
135 // QLabel* lab = new QLabel(myDirList, tr("DIRECTORIES_LBL"), this);
137 QToolButton* insertBtn = new QToolButton(this);
138 insertBtn->setIconSet(QPixmap( insert_icon ));
139 insertBtn->setAutoRaise(true);
141 QToolButton* deleteBtn = new QToolButton(this);
142 deleteBtn->setIconSet(QPixmap( delete_icon ));
143 deleteBtn->setAutoRaise(true);
145 QToolButton* upBtn = new QToolButton(this);
146 upBtn->setIconSet(QPixmap( moveup_icon ));
147 upBtn->setAutoRaise(true);
149 QToolButton* downBtn = new QToolButton(this);
150 downBtn->setIconSet(QPixmap( movedown_icon ));
151 downBtn->setAutoRaise(true);
153 // ctrlLayout->addWidget(lab);
154 ctrlLayout->addItem(new QSpacerItem(SPACER_SIZE, SPACER_SIZE, QSizePolicy::Expanding, QSizePolicy::Minimum));
155 ctrlLayout->addWidget(insertBtn);
156 ctrlLayout->addWidget(deleteBtn);
157 ctrlLayout->addWidget(upBtn);
158 ctrlLayout->addWidget(downBtn);
160 QHBoxLayout* btnLayout = new QHBoxLayout;
161 btnLayout->setMargin(0);
162 btnLayout->setSpacing(6);
164 topLayout->addLayout(ctrlLayout, 0, 0);
165 topLayout->addWidget(myDirList, 1, 0);
166 topLayout->addLayout(btnLayout, 2, 0);
168 connect(myDirList, SIGNAL(mouseButtonClicked(int, QListBoxItem*, const QPoint&)),
169 this, SLOT(onMouseButtonClicked(int, QListBoxItem*, const QPoint&)));
170 connect(myDirList, SIGNAL(doubleClicked(QListBoxItem*)),
171 this, SLOT(onDblClicked(QListBoxItem*)));
173 connect(insertBtn, SIGNAL(clicked()), this, SLOT(onInsert()));
174 connect(deleteBtn, SIGNAL(clicked()), this, SLOT(onDelete()));
175 connect(upBtn, SIGNAL(clicked()), this, SLOT(onUp()));
176 connect(downBtn, SIGNAL(clicked()), this, SLOT(onDown()));
182 QtxDirListEditor::~QtxDirListEditor()
189 void QtxDirListEditor::getPathList(QStringList& list)
192 for (unsigned i = 0; i < myDirList->count()-1; i++)
193 list.append(myDirList->text(i));
199 void QtxDirListEditor::setPathList(const QStringList& list) {
201 myDirList->insertItem(tr("<empty>"));
202 for (unsigned i = 0; i < list.count(); i++)
203 myDirList->insertItem(list[i], myDirList->count()-1);
207 Validates entered path, returns true if OK
209 bool QtxDirListEditor::validate()
213 QString dirPath = QFileInfo( myEdit->text().stripWhiteSpace() ).absFilePath();
216 if ( dirPath.startsWith( "~") ) {
217 dirPath = dirPath.remove(0,1);
219 int slashPos = dirPath.find("/");
220 if ( slashPos >= 0 ) {
221 user = dirPath.left(slashPos);
222 dirPath = dirPath.mid(slashPos);
228 if ( user.isEmpty() )
229 user = getenv( "USER" );
231 struct passwd* user_data = getpwnam( user.latin1() );
232 if ( user_data == NULL ) {
233 // unknown user or something another error
234 QMessageBox::critical(this,
236 tr("Unknown user %1").arg(user),
241 dirPath = user_data->pw_dir + dirPath;
246 QListBoxItem* found = 0;
247 for (unsigned i = 0; i < myDirList->count()-1; i++) {
248 QDir aDir(myDirList->text(i));
249 if ( aDir.canonicalPath().isNull() && myDirList->text(i) == dir.absPath() ||
250 !aDir.canonicalPath().isNull() && aDir.exists() && aDir.canonicalPath() == dir.canonicalPath()) {
251 found = myDirList->item(i);
255 if (dirPath.isEmpty()) {
257 // it should be last (empty) item in the list - nothing to do
261 // delete directory from the list
262 removeDir(myLastSelected);
268 if (found != myLastSelected) {
269 // it is forbidden to add directory more then once
270 QMessageBox::critical(this,
272 tr("Directory already specified."),
280 if ( QMessageBox::information(this,
282 tr("%1\n\nThe directory doesn't exist.\nAdd directory anyway?").arg(dir.absPath()),
283 tr("Yes"), tr("No"), QString::null, 1, 1) == 1) {
289 appendDir(myLastSelected, dir.absPath());
297 Appends/changes directory
299 void QtxDirListEditor::appendDir(QListBoxItem* item, const QString& dir) {
300 int index = myDirList->index(item);
301 if (index >= 0 && index < (int)myDirList->count()) {
302 if (index == (int)myDirList->count()-1) {
303 // it is the last item (new), well, insert it before the last (empty)
304 myDirList->insertItem(dir, myDirList->count()-1);
308 myDirList->changeItem(dir, index);
314 Removes directory from list
316 void QtxDirListEditor::removeDir(QListBoxItem* item) {
317 // do not remove last item (empty)
318 int index = myDirList->index(item);
319 if (index >= 0 && index < (int)myDirList->count()-1) {
321 myLastSelected = myDirList->item(index);
322 myDirList->setSelected(myLastSelected, true);
329 void QtxDirListEditor::resizeEvent(QResizeEvent* event) {
330 QWidget::resizeEvent(event);
332 myEdit->resize(myDirList->viewport()->width()-myBtn->sizeHint().width(), myEdit->height());
333 myBtn->move(myEdit->width(), myEdit->y());
338 Called when user clicks inside directories list box
340 void QtxDirListEditor::onMouseButtonClicked(int button,
342 const QPoint& point) {
345 myDirList->setCurrentItem(myLastSelected);
346 myDirList->setSelected(myLastSelected, true);
354 myDirList->setFocus();
357 myDirList->setCurrentItem(item);
358 myDirList->setSelected(item, true);
359 myDirList->ensureCurrentVisible();
360 qApp->processEvents();
361 if (button == LeftButton && myLastSelected == item) {
362 QRect ir = myDirList->itemRect(myLastSelected);
364 myEdit = new QLineEdit(myDirList->viewport());
365 myBtn = new QToolButton(myDirList->viewport());
366 myBtn->setText(" ... ");
367 connect(myBtn, SIGNAL(clicked()), this, SLOT(onBtnClicked()));
368 myEdit->setGeometry(0,
369 ir.top()-(myEdit->sizeHint().height()-ir.height())/2,
370 myDirList->viewport()->width()-myBtn->sizeHint().width(),
371 myEdit->sizeHint().height());
372 myBtn->setGeometry (myEdit->width(),
373 ir.top()-(myEdit->sizeHint().height()-ir.height())/2,
374 myBtn->sizeHint().width(),
375 myEdit->sizeHint().height());
376 connect(myEdit, SIGNAL(returnPressed()), this, SLOT(onEditFinished()));
380 if (myDirList->index(myLastSelected) != (int)myDirList->count()-1)
381 myEdit->setText(myLastSelected->text());
383 myEdit->setCursorPosition(myEdit->text().length());
384 myEdit->installEventFilter(this);
389 myDirList->clearSelection();
391 myLastSelected = item;
395 Called when user double-clicks on any item
397 void QtxDirListEditor::onDblClicked(QListBoxItem* item) {
398 onMouseButtonClicked(LeftButton, item, QPoint(0,0));
402 <...> (Browse dir) button slot
404 void QtxDirListEditor::onBtnClicked() {
405 QString dir = myEdit->text().stripWhiteSpace().isEmpty() ?
407 myEdit->text().stripWhiteSpace();
409 dir = QFileDialog::getExistingDirectory(dir, this, 0, tr("Select directory"), true);
411 if (!dir.isEmpty()) {
412 myEdit->setText(dir);
414 myEdit->setCursorPosition(myEdit->text().length());
419 Called when user finises editing of path by pressing <Enter>
421 void QtxDirListEditor::onEditFinished() {
424 myDirList->setCurrentItem(myLastSelected);
425 myDirList->setSelected(myLastSelected, true);
428 myEdit->deleteLater();
429 myBtn->deleteLater();
433 myDirList->setFocus();
440 bool QtxDirListEditor::eventFilter(QObject* object, QEvent* event) {
442 if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) {
443 if (object == myDirList->horizontalScrollBar() || object == myDirList->verticalScrollBar()) {
445 myDirList->setCurrentItem(myLastSelected);
446 myDirList->setSelected(myLastSelected, true);
454 myDirList->setFocus();
457 else if (event->type() == QEvent::KeyPress) {
458 QKeyEvent* ke = (QKeyEvent*)event;
459 if (ke->key() == Key_Tab)
461 if (object == myDirList) {
464 else if (object == myEdit) {
465 if ( ke->key() == Key_Up || ke->key() == Key_Down || ke->key() == Key_PageUp || ke->key() == Key_PageDown ||
466 ( ke->key() == Key_Home || ke->key() == Key_End || ke->key() == Key_Prior || ke->key() == Key_Next ) &&
467 (ke->state() & ControlButton) ) {
470 else if ( ke->key() == Key_Escape ) {
476 myDirList->setFocus();
482 return QWidget::eventFilter(object, event);
488 void QtxDirListEditor::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 QtxDirListEditor::onDelete() {
500 if (!myEdited && myDirList->currentItem() >=0) {
501 removeDir(myDirList->item(myDirList->currentItem()));
502 myDirList->setFocus();
507 <Move up> button slot
509 void QtxDirListEditor::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 QtxDirListEditor::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();