1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
43 #include <QtTest/QtTest>
45 #include <qcoreapplication.h>
47 #include <qfiledialog.h>
48 #include <qabstractitemdelegate.h>
49 #include <qdirmodel.h>
50 #include <qitemdelegate.h>
51 #include <qlistview.h>
52 #include <qcombobox.h>
53 #include <qpushbutton.h>
54 #include <qtoolbutton.h>
55 #include <qtreeview.h>
56 #include <qheaderview.h>
57 #include <qcompleter.h>
59 #include <qdialogbuttonbox.h>
60 #include <qsortfilterproxymodel.h>
61 #include <qlineedit.h>
63 #if defined QT_BUILD_INTERNAL
64 #include <private/qsidebar_p.h>
65 #include <private/qfilesystemmodel_p.h>
66 #include <private/qfiledialog_p.h>
68 #include <QFileDialog>
69 #include <QFileSystemModel>
71 #if defined(Q_OS_UNIX)
72 #ifdef QT_BUILD_INTERNAL
74 extern Q_GUI_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0);
79 class QNonNativeFileDialog : public QFileDialog
83 QNonNativeFileDialog(QWidget *parent = 0, const QString &caption = QString(), const QString &directory = QString(), const QString &filter = QString())
84 : QFileDialog(parent, caption, directory, filter)
86 setOption(QFileDialog::DontUseNativeDialog, true);
90 class tst_QFiledialog : public QObject
96 virtual ~tst_QFiledialog();
103 void currentChangedSignal();
104 #ifdef QT_BUILD_INTERNAL
105 void directoryEnteredSignal();
107 void filesSelectedSignal_data();
108 void filesSelectedSignal();
109 void filterSelectedSignal();
113 void completer_data();
117 void confirmOverwrite();
118 void defaultSuffix();
126 void resolveSymlinks();
127 void selectFile_data();
133 void setNameFilter();
137 void historyForward();
138 void disableSaveButton_data();
139 void disableSaveButton();
140 void saveButtonText_data();
141 void saveButtonText();
142 void clearLineEdit();
143 void enableChooseButton();
146 #ifdef QT_BUILD_INTERNAL
147 void tildeExpansion_data();
148 void tildeExpansion();
149 #endif // QT_BUILD_INTERNAL
153 QByteArray userSettings;
156 tst_QFiledialog::tst_QFiledialog()
160 tst_QFiledialog::~tst_QFiledialog()
164 void tst_QFiledialog::init()
166 // Save the developers settings so they don't get mad when their sidebar folders are gone.
167 QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
168 settings.beginGroup(QLatin1String("Qt"));
169 userSettings = settings.value(QLatin1String("filedialog")).toByteArray();
170 settings.remove(QLatin1String("filedialog"));
172 // populate it with some default settings
173 QNonNativeFileDialog fd;
174 #if defined(Q_OS_WINCE)
179 void tst_QFiledialog::cleanup()
181 QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
182 settings.beginGroup(QLatin1String("Qt"));
183 settings.setValue(QLatin1String("filedialog"), userSettings);
186 class MyAbstractItemDelegate : public QAbstractItemDelegate
189 MyAbstractItemDelegate() : QAbstractItemDelegate() {};
190 void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const {}
191 QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return QSize(); }
194 // emitted any time the selection model emits current changed
195 void tst_QFiledialog::currentChangedSignal()
197 QNonNativeFileDialog fd;
198 fd.setViewMode(QFileDialog::List);
199 QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
201 QListView* listView = qFindChild<QListView*>(&fd, "listView");
203 fd.setDirectory(QDir::root());
204 QModelIndex root = listView->rootIndex();
205 QTRY_COMPARE(listView->model()->rowCount(root) > 0, true);
208 for (int i = 0; i < listView->model()->rowCount(root); ++i) {
209 folder = listView->model()->index(i, 0, root);
210 if (listView->model()->hasChildren(folder))
213 QVERIFY(listView->model()->hasChildren(folder));
214 listView->setCurrentIndex(folder);
216 QCOMPARE(spyCurrentChanged.count(), 1);
219 // only emitted from the views, sidebar, or lookin combo
220 #if defined QT_BUILD_INTERNAL
221 void tst_QFiledialog::directoryEnteredSignal()
223 QNonNativeFileDialog fd(0, "", QDir::root().path());
224 fd.setOptions(QFileDialog::DontUseNativeDialog);
226 QTRY_COMPARE(fd.isVisible(), true);
227 QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
230 QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
231 sidebar->setCurrentIndex(sidebar->model()->index(1, 0));
232 QTest::keyPress(sidebar->viewport(), Qt::Key_Return);
233 QCOMPARE(spyDirectoryEntered.count(), 1);
234 spyDirectoryEntered.clear();
237 QComboBox *comboBox = qFindChild<QComboBox*>(&fd, "lookInCombo");
238 comboBox->showPopup();
239 QVERIFY(comboBox->view()->model()->index(1, 0).isValid());
240 comboBox->view()->setCurrentIndex(comboBox->view()->model()->index(1, 0));
241 QTest::keyPress(comboBox->view()->viewport(), Qt::Key_Return);
242 QCOMPARE(spyDirectoryEntered.count(), 1);
243 spyDirectoryEntered.clear();
248 fd.setViewMode(QFileDialog::ViewMode(QFileDialog::List));
249 QListView* listView = qFindChild<QListView*>(&fd, "listView");
251 QModelIndex root = listView->rootIndex();
252 QTRY_COMPARE(listView->model()->rowCount(root) > 0, true);
255 for (int i = 0; i < listView->model()->rowCount(root); ++i) {
256 folder = listView->model()->index(i, 0, root);
257 if (listView->model()->hasChildren(folder))
260 QVERIFY(listView->model()->hasChildren(folder));
261 listView->setCurrentIndex(folder);
262 QTRY_COMPARE((listView->indexAt(listView->visualRect(folder).center())), folder);
263 QTest::mouseDClick(listView->viewport(), Qt::LeftButton, 0, listView->visualRect(folder).center());
264 QTRY_COMPARE(spyDirectoryEntered.count(), 1);
269 Q_DECLARE_METATYPE(QFileDialog::FileMode)
270 void tst_QFiledialog::filesSelectedSignal_data()
272 QTest::addColumn<QFileDialog::FileMode>("fileMode");
273 QTest::newRow("any") << QFileDialog::AnyFile;
274 QTest::newRow("existing") << QFileDialog::ExistingFile;
275 QTest::newRow("directory") << QFileDialog::Directory;
276 QTest::newRow("directoryOnly") << QFileDialog::DirectoryOnly;
277 QTest::newRow("existingFiles") << QFileDialog::ExistingFiles;
280 // emitted when the dialog closes with the selected files
281 void tst_QFiledialog::filesSelectedSignal()
283 QNonNativeFileDialog fd;
284 fd.setViewMode(QFileDialog::List);
285 fd.setOptions(QFileDialog::DontUseNativeDialog);
286 QDir testDir(SRCDIR);
287 fd.setDirectory(testDir);
288 QFETCH(QFileDialog::FileMode, fileMode);
289 fd.setFileMode(fileMode);
290 QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
293 QVERIFY(QTest::qWaitForWindowExposed(&fd));
294 QListView *listView = qFindChild<QListView*>(&fd, "listView");
297 QModelIndex root = listView->rootIndex();
298 QTRY_COMPARE(listView->model()->rowCount(root) > 0, true);
300 for (int i = 0; i < listView->model()->rowCount(root); ++i) {
301 file = listView->model()->index(i, 0, root);
302 if (fileMode == QFileDialog::Directory || fileMode == QFileDialog::DirectoryOnly) {
303 if (listView->model()->hasChildren(file))
306 if (!listView->model()->hasChildren(file))
309 file = QModelIndex();
311 QVERIFY(file.isValid());
312 listView->selectionModel()->select(file, QItemSelectionModel::Select | QItemSelectionModel::Rows);
313 listView->setCurrentIndex(file);
315 QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
316 QPushButton *button = buttonBox->button(QDialogButtonBox::Open);
318 QVERIFY(button->isEnabled());
319 button->animateClick();
320 QTRY_COMPARE(fd.isVisible(), false);
321 QCOMPARE(spyFilesSelected.count(), 1);
324 // only emitted when the combo box is activated
325 void tst_QFiledialog::filterSelectedSignal()
327 QNonNativeFileDialog fd;
328 fd.setAcceptMode(QFileDialog::AcceptSave);
330 QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
332 QStringList filterChoices;
333 filterChoices << "Image files (*.png *.xpm *.jpg)"
334 << "Text files (*.txt)"
335 << "Any files (*.*)";
336 fd.setNameFilters(filterChoices);
337 QCOMPARE(fd.nameFilters(), filterChoices);
339 QComboBox *filters = qFindChild<QComboBox*>(&fd, "fileTypeCombo");
341 QVERIFY(filters->view());
342 QCOMPARE(filters->isVisible(), true);
344 QTest::keyPress(filters, Qt::Key_Down);
346 QCOMPARE(spyFilterSelected.count(), 1);
349 void tst_QFiledialog::args()
352 QString caption = "caption";
353 QString directory = QDir::tempPath();
354 QString filter = "*.mp3";
355 QNonNativeFileDialog fd(parent, caption, directory, filter);
356 QCOMPARE(fd.parent(), (QObject *)parent);
357 QCOMPARE(fd.windowTitle(), caption);
359 QCOMPARE(fd.directory(), QDir(directory));
361 QCOMPARE(fd.nameFilters(), QStringList(filter));
364 void tst_QFiledialog::directory()
366 QNonNativeFileDialog fd;
367 fd.setViewMode(QFileDialog::List);
368 QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
370 fd.setDirectory(QDir::currentPath());
371 QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
372 QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
373 QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
374 QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
376 QCOMPARE(QDir::current().absolutePath(), fd.directory().absolutePath());
377 QDir temp = QDir::temp();
378 QString tempPath = temp.absolutePath();
380 // since the user can have lowercase temp dir, check that we are actually case-insensitive.
381 tempPath = tempPath.toLower();
383 fd.setDirectory(tempPath);
385 QCOMPARE(tempPath, fd.directory().absolutePath());
387 QCOMPARE(spyCurrentChanged.count(), 0);
388 QCOMPARE(spyDirectoryEntered.count(), 0);
389 QCOMPARE(spyFilesSelected.count(), 0);
390 QCOMPARE(spyFilterSelected.count(), 0);
393 QList<QListView*> list = qFindChildren<QListView*>(&fd, "listView");
394 QVERIFY(list.count() > 0);
396 QCOMPARE(list.at(0)->rootIndex().data().toString().toLower(), temp.dirName().toLower());
398 QCOMPARE(list.at(0)->rootIndex().data().toString(), temp.dirName());
400 QNonNativeFileDialog *dlg = new QNonNativeFileDialog(0, "", tempPath);
401 QCOMPARE(model->index(tempPath), model->index(dlg->directory().absolutePath()));
402 QCOMPARE(model->index(tempPath).data(QFileSystemModel::FileNameRole).toString(),
403 model->index(dlg->directory().absolutePath()).data(QFileSystemModel::FileNameRole).toString());
405 dlg = new QNonNativeFileDialog();
406 QCOMPARE(model->index(tempPath), model->index(dlg->directory().absolutePath()));
410 void tst_QFiledialog::completer_data()
412 QTest::addColumn<QString>("startPath");
413 QTest::addColumn<QString>("input");
414 QTest::addColumn<int>("expected");
416 QTest::newRow("r, 10") << "" << "r" << 10;
417 QTest::newRow("x, 0") << "" << "x" << 0;
418 QTest::newRow("../, -1") << "" << "../" << -1;
420 QTest::newRow("goto root") << QString() << QDir::rootPath() << -1;
421 QTest::newRow("start at root") << QDir::rootPath() << QString() << -1;
423 QDir root = QDir::root();
424 QStringList list = root.entryList();
426 for (int i = 0; i < list.count(); ++i) {
427 if (list[i].at(0) == QChar('.'))
429 QFileInfo info(QDir::rootPath() + list[i]);
431 folder = QDir::rootPath() + list[i];
436 QTest::newRow("start at one below root r") << folder << "r" << -1;
437 QTest::newRow("start at one below root ../") << folder << "../" << -1;
440 void tst_QFiledialog::completer()
442 QFETCH(QString, input);
443 QFETCH(QString, startPath);
444 QFETCH(int, expected);
446 QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir";
447 if (startPath.isEmpty())
448 startPath = tempPath;
450 startPath = QDir::cleanPath(startPath);
452 // make temp dir and files
454 QDir cleanup(tempPath);
455 QStringList x = cleanup.entryList();
456 for (int i = 0; i < x.count(); ++i)
457 QFile::remove(tempPath + '/' + x[i]);
458 cleanup.rmdir(tempPath);
460 QDir tmp(QDir::tempPath());
461 if (!tmp.exists(tempPath))
462 QVERIFY(tmp.mkdir("QFileDialogTestDir"));
463 QList<QTemporaryFile*> files;
465 for (int i = 0; i < 10; ++i) {
466 QScopedPointer<QTemporaryFile> file(new QTemporaryFile(tempPath + "/rXXXXXX"));
468 files.append(file.take());
471 // ### flesh this out more
472 QNonNativeFileDialog fd(0,QString("Test it"),startPath);
473 fd.setOptions(QFileDialog::DontUseNativeDialog);
475 QVERIFY(QTest::qWaitForWindowExposed(&fd));
476 QVERIFY(fd.isVisible());
477 QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
479 QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
481 QCompleter *completer = lineEdit->completer();
483 QAbstractItemModel *cModel = completer->completionModel();
489 // path C:\depot\qt\examples\dialogs\standarddialogs
491 // [debug] [release] [tmp] dialog dialog main makefile makefile.debug makefile.release standarddialgos
493 // d -> D:\ debug dialog.cpp dialog.h
494 // ..\ -> ..\classwizard ..\configdialog ..\dialogs.pro
495 // c -> C:\ control panel
496 // c: -> C:\ (nothing more)
497 // C:\ -> C:\, C:\_viminfo, ...
499 // c:\depot -> 'nothing'
500 // c:\depot\ -> C:\depot\devtools, C:\depot\dteske
501 QCOMPARE(model->index(fd.directory().path()), model->index(startPath));
503 if (input.isEmpty()) {
504 QModelIndex r = model->index(model->rootPath());
505 QVERIFY(model->rowCount(r) > 0);
506 QModelIndex idx = model->index(0, 0, r);
507 input = idx.data().toString().at(0);
510 // press 'keys' for the input
511 for (int i = 0; i < input.count(); ++i)
512 QTest::keyPress(lineEdit, input[i].toLatin1());
514 QStringList expectedFiles;
515 if (expected == -1) {
516 QString fullPath = startPath.isEmpty() ? tempPath : startPath;
517 if (!fullPath.endsWith(QLatin1Char('/')))
518 fullPath.append(QLatin1Char('/'));
519 fullPath.append(input);
520 if (input.startsWith(QDir::rootPath())) {
525 QFileInfo fi(fullPath);
526 QDir x(fi.absolutePath());
527 expectedFiles = x.entryList(model->filter());
529 if (input.startsWith(".."))
531 for (int ii = 0; ii < expectedFiles.count(); ++ii) {
532 #if defined(Q_OS_WIN)
533 if (expectedFiles.at(ii).startsWith(input,Qt::CaseInsensitive))
535 if (expectedFiles.at(ii).startsWith(input))
542 if (cModel->rowCount() != expected) {
543 for (int i = 0; i < cModel->rowCount(); ++i) {
544 QString file = cModel->index(i, 0).data().toString();
545 expectedFiles.removeAll(file);
547 //qDebug() << expectedFiles;
550 QTRY_COMPARE(cModel->rowCount(), expected);
558 void tst_QFiledialog::completer_up()
560 QNonNativeFileDialog fd;
561 fd.setOptions(QFileDialog::DontUseNativeDialog);
562 QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
563 QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
564 QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
565 QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
568 QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
570 QCOMPARE(spyFilesSelected.count(), 0);
571 int depth = QDir::currentPath().split('/').count();
572 for (int i = 0; i <= depth * 3 + 1; ++i) {
573 lineEdit->insert("../");
574 qApp->processEvents();
576 QCOMPARE(spyCurrentChanged.count(), 0);
577 QCOMPARE(spyDirectoryEntered.count(), 0);
578 QCOMPARE(spyFilesSelected.count(), 0);
579 QCOMPARE(spyFilterSelected.count(), 0);
582 void tst_QFiledialog::acceptMode()
584 QNonNativeFileDialog fd;
587 QToolButton* newButton = qFindChild<QToolButton*>(&fd, "newFolderButton");
591 QCOMPARE(fd.acceptMode(), QFileDialog::AcceptOpen);
592 QCOMPARE(newButton && newButton->isVisible(), true);
594 //fd.setDetailsExpanded(true);
595 fd.setAcceptMode(QFileDialog::AcceptSave);
596 QCOMPARE(fd.acceptMode(), QFileDialog::AcceptSave);
597 QCOMPARE(newButton->isVisible(), true);
599 fd.setAcceptMode(QFileDialog::AcceptOpen);
600 QCOMPARE(fd.acceptMode(), QFileDialog::AcceptOpen);
601 QCOMPARE(newButton->isVisible(), true);
604 void tst_QFiledialog::confirmOverwrite()
606 QNonNativeFileDialog fd;
607 QCOMPARE(fd.confirmOverwrite(), true);
608 fd.setConfirmOverwrite(true);
609 QCOMPARE(fd.confirmOverwrite(), true);
610 fd.setConfirmOverwrite(false);
611 QCOMPARE(fd.confirmOverwrite(), false);
612 fd.setConfirmOverwrite(true);
613 QCOMPARE(fd.confirmOverwrite(), true);
616 void tst_QFiledialog::defaultSuffix()
618 QNonNativeFileDialog fd;
619 QCOMPARE(fd.defaultSuffix(), QString());
620 fd.setDefaultSuffix("txt");
621 QCOMPARE(fd.defaultSuffix(), QString("txt"));
622 fd.setDefaultSuffix(QString());
623 QCOMPARE(fd.defaultSuffix(), QString());
626 void tst_QFiledialog::fileMode()
628 QNonNativeFileDialog fd;
629 QCOMPARE(fd.fileMode(), QFileDialog::AnyFile);
630 fd.setFileMode(QFileDialog::ExistingFile);
631 QCOMPARE(fd.fileMode(), QFileDialog::ExistingFile);
632 fd.setFileMode(QFileDialog::Directory);
633 QCOMPARE(fd.fileMode(), QFileDialog::Directory);
634 fd.setFileMode(QFileDialog::DirectoryOnly);
635 QCOMPARE(fd.fileMode(), QFileDialog::DirectoryOnly);
636 fd.setFileMode(QFileDialog::ExistingFiles);
637 QCOMPARE(fd.fileMode(), QFileDialog::ExistingFiles);
640 void tst_QFiledialog::caption()
642 QNonNativeFileDialog fd;
643 fd.setWindowTitle("testing");
644 fd.setFileMode(QFileDialog::Directory);
645 QCOMPARE(fd.windowTitle(), QString("testing"));
648 void tst_QFiledialog::filters()
650 QNonNativeFileDialog fd;
651 fd.setOptions(QFileDialog::DontUseNativeDialog);
652 QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
653 QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
654 QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
655 QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
656 QCOMPARE(fd.nameFilters(), QStringList("All Files (*)"));
659 QList<QComboBox*> views = qFindChildren<QComboBox*>(&fd, "fileTypeCombo");
660 QVERIFY(views.count() == 1);
661 QCOMPARE(views.at(0)->isVisible(), false);
664 filters << "Image files (*.png *.xpm *.jpg)"
665 << "Text files (*.txt)"
666 << "Any files (*.*)";
667 fd.setNameFilters(filters);
668 QCOMPARE(views.at(0)->isVisible(), false);
670 fd.setAcceptMode(QFileDialog::AcceptSave);
671 QCOMPARE(views.at(0)->isVisible(), true);
672 QCOMPARE(fd.nameFilters(), filters);
673 fd.setNameFilter("Image files (*.png *.xpm *.jpg);;Text files (*.txt);;Any files (*.*)");
674 QCOMPARE(fd.nameFilters(), filters);
675 QCOMPARE(spyCurrentChanged.count(), 0);
676 QCOMPARE(spyDirectoryEntered.count(), 0);
677 QCOMPARE(spyFilesSelected.count(), 0);
678 QCOMPARE(spyFilterSelected.count(), 0);
680 // setting shouldn't emit any signals
681 for (int i = views.at(0)->currentIndex(); i < views.at(0)->count(); ++i)
682 views.at(0)->setCurrentIndex(i);
683 QCOMPARE(spyFilterSelected.count(), 0);
685 //Let check if filters with whitespaces
686 QNonNativeFileDialog fd2;
687 QStringList expected;
688 expected << "C++ Source Files(*.cpp)";
689 expected << "Any(*.*)";
690 fd2.setNameFilter("C++ Source Files(*.cpp);;Any(*.*)");
691 QCOMPARE(expected, fd2.nameFilters());
692 fd2.setNameFilter("C++ Source Files(*.cpp) ;;Any(*.*)");
693 QCOMPARE(expected, fd2.nameFilters());
694 fd2.setNameFilter("C++ Source Files(*.cpp);; Any(*.*)");
695 QCOMPARE(expected, fd2.nameFilters());
696 fd2.setNameFilter(" C++ Source Files(*.cpp);; Any(*.*)");
697 QCOMPARE(expected, fd2.nameFilters());
698 fd2.setNameFilter("C++ Source Files(*.cpp) ;; Any(*.*)");
699 QCOMPARE(expected, fd2.nameFilters());
702 void tst_QFiledialog::selectFilter()
704 QNonNativeFileDialog fd;
705 QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
706 QCOMPARE(fd.selectedNameFilter(), QString("All Files (*)"));
708 filters << "Image files (*.png *.xpm *.jpg)"
709 << "Text files (*.txt)"
710 << "Any files (*.*)";
711 fd.setNameFilters(filters);
712 QCOMPARE(fd.selectedNameFilter(), filters.at(0));
713 fd.selectNameFilter(filters.at(1));
714 QCOMPARE(fd.selectedNameFilter(), filters.at(1));
715 fd.selectNameFilter(filters.at(2));
716 QCOMPARE(fd.selectedNameFilter(), filters.at(2));
718 fd.selectNameFilter("bob");
719 QCOMPARE(fd.selectedNameFilter(), filters.at(2));
720 fd.selectNameFilter("");
721 QCOMPARE(fd.selectedNameFilter(), filters.at(2));
722 QCOMPARE(spyFilterSelected.count(), 0);
725 void tst_QFiledialog::history()
727 QNonNativeFileDialog fd;
728 fd.setViewMode(QFileDialog::List);
729 QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
731 QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
732 QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
733 QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
734 QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
735 QCOMPARE(model->index(fd.history().first()), model->index(QDir::toNativeSeparators(fd.directory().absolutePath())));
736 fd.setDirectory(QDir::current().absolutePath());
738 history << QDir::toNativeSeparators(QDir::current().absolutePath())
739 << QDir::toNativeSeparators(QDir::home().absolutePath())
740 << QDir::toNativeSeparators(QDir::temp().absolutePath());
741 fd.setHistory(history);
742 if (fd.history() != history) {
743 qDebug() << fd.history() << history;
744 // quick and dirty output for windows failure.
745 QListView* list = qFindChild<QListView*>(&fd, "listView");
747 QModelIndex root = list->rootIndex();
748 while (root.isValid()) {
749 qDebug() << root.data();
750 root = root.parent();
753 QCOMPARE(fd.history(), history);
755 QStringList badHistory;
756 badHistory << "junk";
757 fd.setHistory(badHistory);
758 badHistory << QDir::toNativeSeparators(QDir::current().absolutePath());
759 QCOMPARE(fd.history(), badHistory);
761 QCOMPARE(spyCurrentChanged.count(), 0);
762 QCOMPARE(spyDirectoryEntered.count(), 0);
763 QCOMPARE(spyFilesSelected.count(), 0);
764 QCOMPARE(spyFilterSelected.count(), 0);
767 void tst_QFiledialog::iconProvider()
769 QNonNativeFileDialog *fd = new QNonNativeFileDialog();
770 QVERIFY(fd->iconProvider() != 0);
771 QFileIconProvider *ip = new QFileIconProvider();
772 fd->setIconProvider(ip);
773 QCOMPARE(fd->iconProvider(), ip);
778 void tst_QFiledialog::isReadOnly()
780 QNonNativeFileDialog fd;
782 QPushButton* newButton = qFindChild<QPushButton*>(&fd, "newFolderButton");
783 QAction* renameAction = qFindChild<QAction*>(&fd, "qt_rename_action");
784 QAction* deleteAction = qFindChild<QAction*>(&fd, "qt_delete_action");
786 QCOMPARE(fd.isReadOnly(), false);
788 // This is dependent upon the file/dir, find cross platform way to test
789 //fd.setDirectory(QDir::home());
790 //QCOMPARE(newButton && newButton->isEnabled(), true);
791 //QCOMPARE(renameAction && renameAction->isEnabled(), true);
792 //QCOMPARE(deleteAction && deleteAction->isEnabled(), true);
794 fd.setReadOnly(true);
795 QCOMPARE(fd.isReadOnly(), true);
797 QCOMPARE(newButton && newButton->isEnabled(), false);
798 QCOMPARE(renameAction && renameAction->isEnabled(), false);
799 QCOMPARE(deleteAction && deleteAction->isEnabled(), false);
802 void tst_QFiledialog::itemDelegate()
804 QNonNativeFileDialog fd;
805 QVERIFY(fd.itemDelegate() != 0);
806 QItemDelegate *id = new QItemDelegate(&fd);
807 fd.setItemDelegate(id);
808 QCOMPARE(fd.itemDelegate(), (QAbstractItemDelegate *)id);
811 void tst_QFiledialog::labelText()
813 QNonNativeFileDialog fd;
814 QDialogButtonBox buttonBox;
815 QPushButton *cancelButton = buttonBox.addButton(QDialogButtonBox::Cancel);
816 QCOMPARE(fd.labelText(QFileDialog::LookIn), QString("Look in:"));
817 QCOMPARE(fd.labelText(QFileDialog::FileName), QString("File &name:"));
818 QCOMPARE(fd.labelText(QFileDialog::FileType), QString("Files of type:"));
819 QCOMPARE(fd.labelText(QFileDialog::Accept), QString("&Open")); ///### see task 241462
820 QCOMPARE(fd.labelText(QFileDialog::Reject), cancelButton->text());
822 fd.setLabelText(QFileDialog::LookIn, "1");
823 QCOMPARE(fd.labelText(QFileDialog::LookIn), QString("1"));
824 fd.setLabelText(QFileDialog::FileName, "2");
825 QCOMPARE(fd.labelText(QFileDialog::FileName), QString("2"));
826 fd.setLabelText(QFileDialog::FileType, "3");
827 QCOMPARE(fd.labelText(QFileDialog::FileType), QString("3"));
828 fd.setLabelText(QFileDialog::Accept, "4");
829 QCOMPARE(fd.labelText(QFileDialog::Accept), QString("4"));
830 fd.setLabelText(QFileDialog::Reject, "5");
831 QCOMPARE(fd.labelText(QFileDialog::Reject), QString("5"));
834 void tst_QFiledialog::resolveSymlinks()
836 QNonNativeFileDialog fd;
839 QCOMPARE(fd.resolveSymlinks(), true);
840 fd.setResolveSymlinks(false);
841 QCOMPARE(fd.resolveSymlinks(), false);
842 fd.setResolveSymlinks(true);
843 QCOMPARE(fd.resolveSymlinks(), true);
845 // the file dialog doesn't do anything based upon this, just passes it to the model
846 // the model should fully test it, don't test it here
849 void tst_QFiledialog::selectFile_data()
851 QTest::addColumn<QString>("file");
852 QTest::addColumn<int>("count");
853 QTest::newRow("null") << QString() << 1;
854 QTest::newRow("file") << "foo" << 1;
855 QTest::newRow("tmp") << "temp" << 1;
858 void tst_QFiledialog::selectFile()
860 QFETCH(QString, file);
862 QNonNativeFileDialog fd;
863 QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
865 fd.setDirectory(QDir::currentPath());
867 QCOMPARE(fd.selectedFiles().count(), 1);
869 QTemporaryFile tempFile(QDir::tempPath() + "/aXXXXXX");
870 bool inTemp = (file == "temp");
873 file = tempFile.fileName();
877 QCOMPARE(fd.selectedFiles().count(), count);
879 QCOMPARE(model->index(fd.directory().path()), model->index(QDir::tempPath()));
881 QCOMPARE(model->index(fd.directory().path()), model->index(QDir::currentPath()));
885 void tst_QFiledialog::selectFiles()
887 QNonNativeFileDialog fd;
888 fd.setViewMode(QFileDialog::List);
889 QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir4SelectFiles";
891 QVERIFY(dir.mkpath(tempPath));
892 fd.setDirectory(tempPath);
893 QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
894 QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
895 QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
896 QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
898 fd.setFileMode(QFileDialog::ExistingFiles);
900 QString filesPath = fd.directory().absolutePath();
901 for (int i=0; i < 5; ++i) {
902 QFile file(filesPath + QString::fromLatin1("/qfiledialog_auto_test_not_pres_%1").arg(i));
903 file.open(QIODevice::WriteOnly);
909 // Get a list of files in the view and then get the corresponding index's
910 QStringList list = fd.directory().entryList(QDir::Files);
911 QModelIndexList toSelect;
912 QVERIFY(list.count() > 1);
913 QListView* listView = qFindChild<QListView*>(&fd, "listView");
915 for (int i = 0; i < list.count(); ++i) {
916 fd.selectFile(fd.directory().path() + "/" + list.at(i));
917 QTRY_VERIFY(!listView->selectionModel()->selectedRows().isEmpty());
918 toSelect.append(listView->selectionModel()->selectedRows().last());
920 QCOMPARE(spyFilesSelected.count(), 0);
922 listView->selectionModel()->clear();
923 QCOMPARE(spyFilesSelected.count(), 0);
925 // select the indexes
926 for (int i = 0; i < toSelect.count(); ++i) {
927 listView->selectionModel()->select(toSelect.at(i),
928 QItemSelectionModel::Select | QItemSelectionModel::Rows);
930 QCOMPARE(fd.selectedFiles().count(), toSelect.count());
931 QCOMPARE(spyCurrentChanged.count(), 0);
932 QCOMPARE(spyDirectoryEntered.count(), 0);
933 QCOMPARE(spyFilesSelected.count(), 0);
934 QCOMPARE(spyFilterSelected.count(), 0);
935 for (int i=0; i < 5; ++i)
936 QFile::remove(filesPath + QString::fromLatin1("/qfiledialog_auto_test_not_pres_%1").arg(i));
938 //If the selection is invalid then we fill the line edit but without the /
939 QNonNativeFileDialog * dialog = new QNonNativeFileDialog( 0, "Save" );
940 dialog->setFileMode( QFileDialog::AnyFile );
941 dialog->setAcceptMode( QFileDialog::AcceptSave );
942 QString temporary = QDir::tempPath() + QLatin1String("/blah");
943 dialog->selectFile(temporary);
945 QVERIFY(QTest::qWaitForWindowExposed(dialog));
946 QLineEdit *lineEdit = qFindChild<QLineEdit*>(dialog, "fileNameEdit");
948 QCOMPARE(lineEdit->text(),QLatin1String("blah"));
952 void tst_QFiledialog::viewMode()
954 QNonNativeFileDialog fd;
955 fd.setViewMode(QFileDialog::List);
959 QList<QTreeView*> treeView = qFindChildren<QTreeView*>(&fd, "treeView");
960 QCOMPARE(treeView.count(), 1);
961 QList<QListView*> listView = qFindChildren<QListView*>(&fd, "listView");
962 QCOMPARE(listView.count(), 1);
963 QList<QToolButton*> listButton = qFindChildren<QToolButton*>(&fd, "listModeButton");
964 QCOMPARE(listButton.count(), 1);
965 QList<QToolButton*> treeButton = qFindChildren<QToolButton*>(&fd, "detailModeButton");
966 QCOMPARE(treeButton.count(), 1);
969 QCOMPARE(fd.viewMode(), QFileDialog::List);
972 fd.setViewMode(QFileDialog::ViewMode(QFileDialog::Detail));
974 QCOMPARE(QFileDialog::ViewMode(QFileDialog::Detail), fd.viewMode());
975 QCOMPARE(listView.at(0)->isVisible(), false);
976 QCOMPARE(listButton.at(0)->isDown(), false);
977 QCOMPARE(treeView.at(0)->isVisible(), true);
978 QCOMPARE(treeButton.at(0)->isDown(), true);
981 fd.setViewMode(QFileDialog::ViewMode(QFileDialog::List));
983 QCOMPARE(QFileDialog::ViewMode(QFileDialog::List), fd.viewMode());
984 QCOMPARE(treeView.at(0)->isVisible(), false);
985 QCOMPARE(treeButton.at(0)->isDown(), false);
986 QCOMPARE(listView.at(0)->isVisible(), true);
987 QCOMPARE(listButton.at(0)->isDown(), true);
990 void tst_QFiledialog::proxymodel()
992 QNonNativeFileDialog fd;
993 QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
996 QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
998 QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(&fd);
999 fd.setProxyModel(proxyModel);
1000 QCOMPARE(fd.proxyModel(), (QAbstractProxyModel *)proxyModel);
1002 fd.setProxyModel(0);
1003 QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
1006 void tst_QFiledialog::setNameFilter()
1008 QNonNativeFileDialog fd;
1009 fd.setNameFilter(QString());
1010 fd.setNameFilters(QStringList());
1013 void tst_QFiledialog::focus()
1015 QNonNativeFileDialog fd;
1016 fd.setDirectory(QDir::currentPath());
1018 QApplication::setActiveWindow(&fd);
1019 QVERIFY(QTest::qWaitForWindowActive(&fd));
1020 QCOMPARE(fd.isVisible(), true);
1021 QCOMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
1022 qApp->processEvents();
1024 // make sure the tests work with focus follows mouse
1025 QCursor::setPos(fd.geometry().center());
1026 QApplication::syncX();
1028 QList<QWidget*> treeView = qFindChildren<QWidget*>(&fd, "fileNameEdit");
1029 QCOMPARE(treeView.count(), 1);
1030 QVERIFY(treeView.at(0));
1031 QTRY_COMPARE(treeView.at(0)->hasFocus(), true);
1032 QCOMPARE(treeView.at(0)->hasFocus(), true);
1036 void tst_QFiledialog::historyBack()
1038 QNonNativeFileDialog fd;
1039 QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
1041 QToolButton *backButton = qFindChild<QToolButton*>(&fd, "backButton");
1042 QVERIFY(backButton);
1043 QToolButton *forwardButton = qFindChild<QToolButton*>(&fd, "forwardButton");
1044 QVERIFY(forwardButton);
1046 QSignalSpy spy(model, SIGNAL(rootPathChanged(const QString &)));
1048 QString home = fd.directory().absolutePath();
1049 QString desktop = QDir::homePath();
1050 QString temp = QDir::tempPath();
1052 QCOMPARE(backButton->isEnabled(), false);
1053 QCOMPARE(forwardButton->isEnabled(), false);
1054 fd.setDirectory(temp);
1055 qApp->processEvents();
1056 QCOMPARE(backButton->isEnabled(), true);
1057 QCOMPARE(forwardButton->isEnabled(), false);
1058 fd.setDirectory(desktop);
1059 QCOMPARE(spy.count(), 2);
1061 backButton->click();
1062 qApp->processEvents();
1063 QCOMPARE(backButton->isEnabled(), true);
1064 QCOMPARE(forwardButton->isEnabled(), true);
1065 QCOMPARE(spy.count(), 3);
1066 QString currentPath = qvariant_cast<QString>(spy.last().first());
1067 QCOMPARE(model->index(currentPath), model->index(temp));
1069 backButton->click();
1070 currentPath = qvariant_cast<QString>(spy.last().first());
1071 QCOMPARE(currentPath, home);
1072 QCOMPARE(backButton->isEnabled(), false);
1073 QCOMPARE(forwardButton->isEnabled(), true);
1074 QCOMPARE(spy.count(), 4);
1076 // nothing should change at this point
1077 backButton->click();
1078 QCOMPARE(spy.count(), 4);
1079 QCOMPARE(backButton->isEnabled(), false);
1080 QCOMPARE(forwardButton->isEnabled(), true);
1083 void tst_QFiledialog::historyForward()
1085 QNonNativeFileDialog fd;
1086 fd.setDirectory(QDir::currentPath());
1087 QToolButton *backButton = qFindChild<QToolButton*>(&fd, "backButton");
1088 QVERIFY(backButton);
1089 QToolButton *forwardButton = qFindChild<QToolButton*>(&fd, "forwardButton");
1090 QVERIFY(forwardButton);
1092 QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
1094 QSignalSpy spy(model, SIGNAL(rootPathChanged(const QString &)));
1096 QString home = fd.directory().absolutePath();
1097 QString desktop = QDir::homePath();
1098 QString temp = QDir::tempPath();
1100 fd.setDirectory(home);
1101 fd.setDirectory(temp);
1102 fd.setDirectory(desktop);
1104 backButton->click();
1105 QCOMPARE(forwardButton->isEnabled(), true);
1106 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp));
1108 forwardButton->click();
1109 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(desktop));
1110 QCOMPARE(backButton->isEnabled(), true);
1111 QCOMPARE(forwardButton->isEnabled(), false);
1112 QCOMPARE(spy.count(), 4);
1114 backButton->click();
1115 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp));
1116 QCOMPARE(backButton->isEnabled(), true);
1118 backButton->click();
1119 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(home));
1120 QCOMPARE(backButton->isEnabled(), false);
1121 QCOMPARE(forwardButton->isEnabled(), true);
1122 QCOMPARE(spy.count(), 6);
1124 forwardButton->click();
1125 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp));
1126 backButton->click();
1127 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(home));
1128 QCOMPARE(spy.count(), 8);
1130 forwardButton->click();
1131 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp));
1132 forwardButton->click();
1133 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(desktop));
1135 backButton->click();
1136 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(temp));
1137 backButton->click();
1138 QCOMPARE(model->index(qvariant_cast<QString>(spy.last().first())), model->index(home));
1139 fd.setDirectory(desktop);
1140 QCOMPARE(forwardButton->isEnabled(), false);
1143 void tst_QFiledialog::disableSaveButton_data()
1145 QTest::addColumn<QString>("path");
1146 QTest::addColumn<bool>("isEnabled");
1148 QTest::newRow("valid path") << QDir::temp().absolutePath() + QDir::separator() + "qfiledialog.new_file" << true;
1149 QTest::newRow("no path") << "" << false;
1150 #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_OPENBSD)
1151 QTest::newRow("too long path") << "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" << false;
1153 QTest::newRow("file") << "foo.html" << true;
1156 void tst_QFiledialog::disableSaveButton()
1158 QFETCH(QString, path);
1159 QFETCH(bool, isEnabled);
1161 QNonNativeFileDialog fd(0, "caption", path);
1162 fd.setAcceptMode(QFileDialog::AcceptSave);
1163 QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
1164 QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
1166 QCOMPARE(button->isEnabled(), isEnabled);
1169 void tst_QFiledialog::saveButtonText_data()
1171 QTest::addColumn<QString>("path");
1172 QTest::addColumn<QString>("label");
1173 QTest::addColumn<QString>("caption");
1175 QTest::newRow("empty path") << "" << QString() << QFileDialog::tr("&Save");
1176 QTest::newRow("file path") << "qfiledialog.new_file" << QString() << QFileDialog::tr("&Save");
1177 QTest::newRow("dir") << QDir::temp().absolutePath() << QString() << QFileDialog::tr("&Open");
1178 QTest::newRow("setTextLabel") << "qfiledialog.new_file" << "Mooo" << "Mooo";
1179 QTest::newRow("dir & label") << QDir::temp().absolutePath() << "Poo" << QFileDialog::tr("&Open");
1182 void tst_QFiledialog::saveButtonText()
1184 QFETCH(QString, path);
1185 QFETCH(QString, label);
1186 QFETCH(QString, caption);
1188 QNonNativeFileDialog fd(0, "auto test", QDir::temp().absolutePath());
1189 fd.setAcceptMode(QFileDialog::AcceptSave);
1190 if (!label.isNull())
1191 fd.setLabelText(QFileDialog::Accept, label);
1192 fd.setDirectory(QDir::temp());
1193 fd.selectFile(path);
1194 QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
1196 QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
1198 QCOMPARE(button->text(), caption);
1201 void tst_QFiledialog::clearLineEdit()
1203 QNonNativeFileDialog fd(0, "caption", "foo");
1204 fd.setViewMode(QFileDialog::List);
1205 fd.setFileMode(QFileDialog::AnyFile);
1206 fd.setOptions(QFileDialog::DontUseNativeDialog);
1209 //play it really safe by creating a directory
1210 QDir::home().mkdir("_____aaaaaaaaaaaaaaaaaaaaaa");
1212 QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
1214 QVERIFY(lineEdit->text() == "foo");
1215 fd.setDirectory(QDir::home());
1217 QListView* list = qFindChild<QListView*>(&fd, "listView");
1220 // saving a file the text shouldn't be cleared
1221 fd.setDirectory(QDir::home());
1224 #ifdef QT_KEYPAD_NAVIGATION
1225 list->setEditFocus(true);
1227 QTest::keyClick(list, Qt::Key_Down);
1229 QTest::keyClick(list, Qt::Key_Return);
1231 QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
1236 QEXPECT_FAIL("", "QTBUG-23703", Abort);
1238 QVERIFY(fd.directory().absolutePath() != QDir::home().absolutePath());
1239 QVERIFY(!lineEdit->text().isEmpty());
1241 // selecting a dir the text should be cleared so one can just hit ok
1242 // and it selects that directory
1243 fd.setFileMode(QNonNativeFileDialog::Directory);
1244 fd.setDirectory(QDir::home());
1247 QTest::keyClick(list, Qt::Key_Down);
1249 QTest::keyClick(list, Qt::Key_Return);
1251 QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
1255 QVERIFY(fd.directory().absolutePath() != QDir::home().absolutePath());
1256 QVERIFY(lineEdit->text().isEmpty());
1259 QDir::home().rmdir("_____aaaaaaaaaaaaaaaaaaaaaa");
1262 void tst_QFiledialog::enableChooseButton()
1264 QNonNativeFileDialog fd;
1265 fd.setFileMode(QFileDialog::Directory);
1267 QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
1268 QPushButton *button = buttonBox->button(QDialogButtonBox::Open);
1270 QCOMPARE(button->isEnabled(), true);
1274 typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
1275 extern Q_GUI_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook;
1277 QString existing(QWidget *, const QString &, const QString &, QFileDialog::Options) {
1282 typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
1283 extern Q_GUI_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook;
1285 QString openName(QWidget *, const QString &, const QString &, const QString &, QString *, QFileDialog::Options) {
1290 typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
1291 extern Q_GUI_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook;
1293 QStringList openNames(QWidget *, const QString &, const QString &, const QString &, QString *, QFileDialog::Options) {
1294 return QStringList("openNames");
1298 typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
1299 extern Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook;
1301 QString saveName(QWidget *, const QString &, const QString &, const QString &, QString *, QFileDialog::Options) {
1306 void tst_QFiledialog::hooks()
1308 qt_filedialog_existing_directory_hook = &existing;
1309 qt_filedialog_save_filename_hook = &saveName;
1310 qt_filedialog_open_filename_hook = &openName;
1311 qt_filedialog_open_filenames_hook = &openNames;
1313 QCOMPARE(QFileDialog::getExistingDirectory(), QString("dir"));
1314 QCOMPARE(QFileDialog::getOpenFileName(), QString("openName"));
1315 QCOMPARE(QFileDialog::getOpenFileNames(), QStringList("openNames"));
1316 QCOMPARE(QFileDialog::getSaveFileName(), QString("saveName"));
1320 #ifdef QT_BUILD_INTERNAL
1321 void tst_QFiledialog::tildeExpansion_data()
1323 QTest::addColumn<QString>("tildePath");
1324 QTest::addColumn<QString>("expandedPath");
1326 QTest::newRow("empty path") << QString() << QString();
1327 QTest::newRow("~") << QString::fromLatin1("~") << QDir::homePath();
1328 QTest::newRow("~/some/sub/dir/") << QString::fromLatin1("~/some/sub/dir") << QDir::homePath()
1329 + QString::fromLatin1("/some/sub/dir");
1330 QString userHome = QString(qgetenv("USER"));
1331 userHome.prepend('~');
1332 QTest::newRow("current user (~<user> syntax)") << userHome << QDir::homePath();
1333 QString invalid = QString::fromLatin1("~thisIsNotAValidUserName");
1334 QTest::newRow("invalid user name") << invalid << invalid;
1336 #endif // QT_BUILD_INTERNAL
1338 #ifdef QT_BUILD_INTERNAL
1339 void tst_QFiledialog::tildeExpansion()
1341 QFETCH(QString, tildePath);
1342 QFETCH(QString, expandedPath);
1344 QCOMPARE(qt_tildeExpansion(tildePath), expandedPath);
1346 #endif // QT_BUILD_INTERNAL
1349 QTEST_MAIN(tst_QFiledialog)
1350 #include "tst_qfiledialog.moc"