summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2017-05-09 12:42:18 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2017-12-27 08:40:22 +0000
commit0c4d31d8c9cdab18743bde17de5ea0bd0daf02e5 (patch)
treee7d3d60dc82876ad4fcf827072acb9451e4b56ab
parentc4f397ee11fc3cea1fc132ebe1db24e3970bb477 (diff)
Improve the findfiles example: use QDirIterator, etc
It hasn't been necessary for a long time now to write the recursive file-find function manually. It has just been an obscurely documented feature of QDirIterator for far too long. Demonstrate the new QLocale::formattedDataSize() function. Also sync up the qdoc description of this example with the recent changes. Change-Id: I9c2bb15bb5ec353d38181b160f0be198774cbea2 Reviewed-by: Robin Burchell <robin.burchell@crimson.no> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--examples/widgets/dialogs/findfiles/window.cpp57
-rw-r--r--examples/widgets/dialogs/findfiles/window.h2
-rw-r--r--examples/widgets/doc/src/findfiles.qdoc41
3 files changed, 46 insertions, 54 deletions
diff --git a/examples/widgets/dialogs/findfiles/window.cpp b/examples/widgets/dialogs/findfiles/window.cpp
index f2ce853d99..1b16cdcd35 100644
--- a/examples/widgets/dialogs/findfiles/window.cpp
+++ b/examples/widgets/dialogs/findfiles/window.cpp
@@ -74,6 +74,7 @@ static inline void openFile(const QString &fileName)
Window::Window(QWidget *parent)
: QWidget(parent)
{
+ setWindowTitle(tr("Find Files"));
QPushButton *browseButton = new QPushButton(tr("&Browse..."), this);
connect(browseButton, &QAbstractButton::clicked, this, &Window::browse);
findButton = new QPushButton(tr("&Find"), this);
@@ -92,9 +93,7 @@ Window::Window(QWidget *parent)
filesFoundLabel = new QLabel;
createFilesTable();
-//! [0]
-//! [1]
QGridLayout *mainLayout = new QGridLayout(this);
mainLayout->addWidget(new QLabel(tr("Named:")), 0, 0);
mainLayout->addWidget(fileComboBox, 0, 1, 1, 2);
@@ -106,12 +105,13 @@ Window::Window(QWidget *parent)
mainLayout->addWidget(filesTable, 3, 0, 1, 3);
mainLayout->addWidget(filesFoundLabel, 4, 0, 1, 2);
mainLayout->addWidget(findButton, 4, 2);
+//! [0]
- setWindowTitle(tr("Find Files"));
- const QRect screenGeometry = QApplication::desktop()->screenGeometry(this);
- resize(screenGeometry.width() / 2, screenGeometry.height() / 3);
-}
//! [1]
+ connect(new QShortcut(QKeySequence::Quit, this), &QShortcut::activated,
+ qApp, &QApplication::quit);
+//! [1]
+}
//! [2]
void Window::browse()
@@ -133,21 +133,7 @@ static void updateComboBox(QComboBox *comboBox)
comboBox->addItem(comboBox->currentText());
}
-//! [13]
-
-static void findRecursion(const QString &path, const QString &pattern, QStringList *result)
-{
- QDir currentDir(path);
- const QString prefix = path + QLatin1Char('/');
- foreach (const QString &match, currentDir.entryList(QStringList(pattern), QDir::Files | QDir::NoSymLinks))
- result->append(prefix + match);
- foreach (const QString &dir, currentDir.entryList(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot))
- findRecursion(prefix + dir, pattern, result);
-}
-
-//! [13]
//! [3]
-
void Window::find()
{
filesTable->setRowCount(0);
@@ -155,6 +141,7 @@ void Window::find()
QString fileName = fileComboBox->currentText();
QString text = textComboBox->currentText();
QString path = QDir::cleanPath(directoryComboBox->currentText());
+ currentDir = QDir(path);
//! [3]
updateComboBox(fileComboBox);
@@ -162,12 +149,16 @@ void Window::find()
updateComboBox(directoryComboBox);
//! [4]
-
- currentDir = QDir(path);
+ QStringList filter;
+ if (!fileName.isEmpty())
+ filter << fileName;
+ QDirIterator it(path, filter, QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
QStringList files;
- findRecursion(path, fileName.isEmpty() ? QStringLiteral("*") : fileName, &files);
+ while (it.hasNext())
+ files << it.next();
if (!text.isEmpty())
files = findFiles(files, text);
+ files.sort();
showFiles(files);
}
//! [4]
@@ -225,20 +216,18 @@ QStringList Window::findFiles(const QStringList &files, const QString &text)
//! [7]
//! [8]
-void Window::showFiles(const QStringList &files)
+void Window::showFiles(const QStringList &paths)
{
- for (int i = 0; i < files.size(); ++i) {
- const QString &fileName = files.at(i);
- const QString toolTip = QDir::toNativeSeparators(fileName);
- const QString relativePath = QDir::toNativeSeparators(currentDir.relativeFilePath(fileName));
- const qint64 size = QFileInfo(fileName).size();
+ for (const QString &filePath : paths) {
+ const QString toolTip = QDir::toNativeSeparators(filePath);
+ const QString relativePath = QDir::toNativeSeparators(currentDir.relativeFilePath(filePath));
+ const qint64 size = QFileInfo(filePath).size();
QTableWidgetItem *fileNameItem = new QTableWidgetItem(relativePath);
- fileNameItem->setData(absoluteFileNameRole, QVariant(fileName));
+ fileNameItem->setData(absoluteFileNameRole, QVariant(filePath));
fileNameItem->setToolTip(toolTip);
fileNameItem->setFlags(fileNameItem->flags() ^ Qt::ItemIsEditable);
- QTableWidgetItem *sizeItem = new QTableWidgetItem(tr("%1 KB")
- .arg(int((size + 1023) / 1024)));
- sizeItem->setData(absoluteFileNameRole, QVariant(fileName));
+ QTableWidgetItem *sizeItem = new QTableWidgetItem(QLocale().formattedDataSize(size));
+ sizeItem->setData(absoluteFileNameRole, QVariant(filePath));
sizeItem->setToolTip(toolTip);
sizeItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
sizeItem->setFlags(sizeItem->flags() ^ Qt::ItemIsEditable);
@@ -248,7 +237,7 @@ void Window::showFiles(const QStringList &files)
filesTable->setItem(row, 0, fileNameItem);
filesTable->setItem(row, 1, sizeItem);
}
- filesFoundLabel->setText(tr("%n file(s) found (Double click on a file to open it)", 0, files.size()));
+ filesFoundLabel->setText(tr("%n file(s) found (Double click on a file to open it)", 0, paths.size()));
filesFoundLabel->setWordWrap(true);
}
//! [8]
diff --git a/examples/widgets/dialogs/findfiles/window.h b/examples/widgets/dialogs/findfiles/window.h
index fe217381e2..949df704bb 100644
--- a/examples/widgets/dialogs/findfiles/window.h
+++ b/examples/widgets/dialogs/findfiles/window.h
@@ -79,7 +79,7 @@ private slots:
private:
QStringList findFiles(const QStringList &files, const QString &text);
- void showFiles(const QStringList &files);
+ void showFiles(const QStringList &paths);
QComboBox *createComboBox(const QString &text = QString());
void createFilesTable();
diff --git a/examples/widgets/doc/src/findfiles.qdoc b/examples/widgets/doc/src/findfiles.qdoc
index b8363dc698..a2eb326519 100644
--- a/examples/widgets/doc/src/findfiles.qdoc
+++ b/examples/widgets/doc/src/findfiles.qdoc
@@ -74,19 +74,23 @@
\snippet dialogs/findfiles/window.cpp 0
- We create the application's buttons using the private \c
- createButton() function. Then we create the comboboxes associated
- with the search specifications, using the private \c
- createComboBox() function. We also create the application's labels
- before we use the private \c createFilesTable() function to create
- the table displaying the search results.
+ We create the widgets to build up the UI, and we add them to a main layout
+ using QGridLayout. We have, however, put the \c Find and \c Quit buttons
+ and a stretchable space in a separate \l QHBoxLayout first, to make the
+ buttons appear in the \c Window widget's bottom right corner.
+
+ Alternatively, we could have used Qt Designer to construct a UI file,
+ and \l {uic} to generate this code.
\snippet dialogs/findfiles/window.cpp 1
- Then we add all the widgets to a main layout using QGridLayout. We
- have, however, put the \c Find and \c Quit buttons and a
- stretchable space in a separate QHBoxLayout first, to make the
- buttons appear in the \c Window widget's bottom right corner.
+ We did not create a \l QMenuBar with a \uicontrol Quit menu item; but we
+ would still like to have a keyboard shortcut for quitting. Since we
+ construct a \l QShortcut with \l QKeySequence::Quit, and connect it to
+ \l QApplication::quit(), on most platforms it will be possible to press
+ Control-Q to quit (or whichever standard Quit key is configured on that platform).
+ (On \macos, this is redundant, because every application gets a
+ \uicontrol Quit menu item automatically; but it helps to make the application portable.)
\snippet dialogs/findfiles/window.cpp 2
@@ -122,18 +126,16 @@
We use the directory's path to create a QDir; the QDir class
provides access to directory structures and their contents.
- \snippet dialogs/findfiles/window.cpp 13
-
- We recursively create a list of the files (contained in the newl
- created QDir) that match the specified file name.
+ We use QDirIterator to iterate over the files that match the
+ specified file name and build a QStringList of paths.
Then we search through all the files in the list, using the private
- \c findFiles() function, eliminating the ones that don't contain
- the specified text. And finally, we display the results using the
- private \c showFiles() function.
+ \c findFiles() function, eliminating the ones that don't contain the
+ specified text. We sort them (because QDirIterator did not). And finally,
+ we display the results using the private \c showFiles() function.
If the user didn't specify any text, there is no reason to search
- through the files, and we display the results immediately.
+ through the files, so we sort and display the results immediately.
\image findfiles_progress_dialog.png Screenshot of the Progress Dialog
@@ -196,7 +198,8 @@
the \c find() slot. In the \c showFiles() function we run through
the provided list of file names, adding each relative file name to the
first column in the table widget and retrieving the file's size using
- QFileInfo for the second column. For later use, we set
+ QFileInfo for the second column. We use \l QLocale::formattedDataSize()
+ to format the file size in a human-readable form. For later use, we set
the absolute path as a data on the QTableWidget using the
the role absoluteFileNameRole defined to be Qt::UserRole + 1.