| 1 | /****************************************************************************
|
|---|
| 2 | **
|
|---|
| 3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|---|
| 4 | ** Contact: Qt Software Information (qt-info@nokia.com)
|
|---|
| 5 | **
|
|---|
| 6 | ** This file is part of the documentation of the Qt Toolkit.
|
|---|
| 7 | **
|
|---|
| 8 | ** $QT_BEGIN_LICENSE:LGPL$
|
|---|
| 9 | ** Commercial Usage
|
|---|
| 10 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
|---|
| 11 | ** accordance with the Qt Commercial License Agreement provided with the
|
|---|
| 12 | ** Software or, alternatively, in accordance with the terms contained in
|
|---|
| 13 | ** a written agreement between you and Nokia.
|
|---|
| 14 | **
|
|---|
| 15 | ** GNU Lesser General Public License Usage
|
|---|
| 16 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
|---|
| 17 | ** General Public License version 2.1 as published by the Free Software
|
|---|
| 18 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
|---|
| 19 | ** packaging of this file. Please review the following information to
|
|---|
| 20 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
|---|
| 21 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|---|
| 22 | **
|
|---|
| 23 | ** In addition, as a special exception, Nokia gives you certain
|
|---|
| 24 | ** additional rights. These rights are described in the Nokia Qt LGPL
|
|---|
| 25 | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
|---|
| 26 | ** package.
|
|---|
| 27 | **
|
|---|
| 28 | ** GNU General Public License Usage
|
|---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU
|
|---|
| 30 | ** General Public License version 3.0 as published by the Free Software
|
|---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
|---|
| 32 | ** packaging of this file. Please review the following information to
|
|---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
|---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
|---|
| 35 | **
|
|---|
| 36 | ** If you are unsure which license is appropriate for your use, please
|
|---|
| 37 | ** contact the sales department at qt-sales@nokia.com.
|
|---|
| 38 | ** $QT_END_LICENSE$
|
|---|
| 39 | **
|
|---|
| 40 | ****************************************************************************/
|
|---|
| 41 |
|
|---|
| 42 | /*!
|
|---|
| 43 | \example dialogs/findfiles
|
|---|
| 44 | \title Find Files Example
|
|---|
| 45 |
|
|---|
| 46 | The Find Files example shows how to use QProgressDialog to provide
|
|---|
| 47 | feedback on the progress of a slow operation. The example also
|
|---|
| 48 | shows how to use QFileDialog to facilitate browsing, how to use
|
|---|
| 49 | QTextStream's streaming operators to read a file, and how to use
|
|---|
| 50 | QTableWidget to provide standard table display facilities for
|
|---|
| 51 | applications. In addition, files can be opened using the
|
|---|
| 52 | QDesktopServices class.
|
|---|
| 53 |
|
|---|
| 54 | \image findfiles-example.png Screenshot of the Find Files example
|
|---|
| 55 |
|
|---|
| 56 | With the Find Files application the user can search for files in a
|
|---|
| 57 | specified directory, matching a specified file name (using wild
|
|---|
| 58 | cards if appropiate) and containing a specified text.
|
|---|
| 59 |
|
|---|
| 60 | The user is provided with a \gui Browse option, and the result of
|
|---|
| 61 | the search is displayed in a table with the names of the files
|
|---|
| 62 | found and their sizes. In addition the application provides a
|
|---|
| 63 | total count of the files found.
|
|---|
| 64 |
|
|---|
| 65 | \section1 Window Class Definition
|
|---|
| 66 |
|
|---|
| 67 | The \c Window class inherits QWidget, and is the main application
|
|---|
| 68 | widget. It shows the search options, and displays the search
|
|---|
| 69 | results.
|
|---|
| 70 |
|
|---|
| 71 | \snippet examples/dialogs/findfiles/window.h 0
|
|---|
| 72 |
|
|---|
| 73 | We need two private slots: The \c browse() slot is called whenever
|
|---|
| 74 | the user wants to browse for a directory to search in, and the \c
|
|---|
| 75 | find() slot is called whenever the user requests a search to be
|
|---|
| 76 | performed by pressing the \gui Find button.
|
|---|
| 77 |
|
|---|
| 78 | In addition we declare several private functions: We use the \c
|
|---|
| 79 | findFiles() function to search for files matching the user's
|
|---|
| 80 | specifications, we call the \c showFiles() function to display the
|
|---|
| 81 | results, and we use \c createButton(), \c createComboBox() and \c
|
|---|
| 82 | createFilesTable() when we are constructing the widget.
|
|---|
| 83 |
|
|---|
| 84 | \section1 Window Class Implementation
|
|---|
| 85 |
|
|---|
| 86 | In the constructor we first create the application's widgets.
|
|---|
| 87 |
|
|---|
| 88 | \snippet examples/dialogs/findfiles/window.cpp 0
|
|---|
| 89 |
|
|---|
| 90 | We create the application's buttons using the private \c
|
|---|
| 91 | createButton() function. Then we create the comboboxes associated
|
|---|
| 92 | with the search specifications, using the private \c
|
|---|
| 93 | createComboBox() function. We also create the application's labels
|
|---|
| 94 | before we use the private \c createFilesTable() function to create
|
|---|
| 95 | the table displaying the search results.
|
|---|
| 96 |
|
|---|
| 97 | \snippet examples/dialogs/findfiles/window.cpp 1
|
|---|
| 98 |
|
|---|
| 99 | Then we add all the widgets to a main layout using QGridLayout. We
|
|---|
| 100 | have, however, put the \c Find and \c Quit buttons and a
|
|---|
| 101 | stretchable space in a separate QHBoxLayout first, to make the
|
|---|
| 102 | buttons appear in the \c Window widget's bottom right corner.
|
|---|
| 103 |
|
|---|
| 104 | \snippet examples/dialogs/findfiles/window.cpp 2
|
|---|
| 105 |
|
|---|
| 106 | The \c browse() slot presents a file dialog to the user, using the
|
|---|
| 107 | QFileDialog class. QFileDialog enables a user to traverse the file
|
|---|
| 108 | system in order to select one or many files or a directory. The
|
|---|
| 109 | easiest way to create a QFileDialog is to use the convenience
|
|---|
| 110 | static functions.
|
|---|
| 111 |
|
|---|
| 112 | Here we use the static QFileDialog::getExistingDirectory()
|
|---|
| 113 | function which returns an existing directory selected by the
|
|---|
| 114 | user. Then we display the directory in the directory combobox
|
|---|
| 115 | using the QComboBox::addItem() function, and updates the current
|
|---|
| 116 | index.
|
|---|
| 117 |
|
|---|
| 118 | QComboBox::addItem() adds an item to the combobox with the given
|
|---|
| 119 | text (if it is not already present in the list), and containing
|
|---|
| 120 | the specified userData. The item is appended to the list of
|
|---|
| 121 | existing items.
|
|---|
| 122 |
|
|---|
| 123 | \snippet examples/dialogs/findfiles/window.cpp 3
|
|---|
| 124 |
|
|---|
| 125 | The \c find() slot is called whenever the user requests a new
|
|---|
| 126 | search by pressing the \gui Find button.
|
|---|
| 127 |
|
|---|
| 128 | First we eliminate any previous search results by setting the
|
|---|
| 129 | table widgets row count to zero. Then we retrieve the
|
|---|
| 130 | specified file name, text and directory path from the respective
|
|---|
| 131 | comboboxes.
|
|---|
| 132 |
|
|---|
| 133 | \snippet examples/dialogs/findfiles/window.cpp 4
|
|---|
| 134 |
|
|---|
| 135 | We use the directory's path to create a QDir; the QDir class
|
|---|
| 136 | provides access to directory structures and their contents. We
|
|---|
| 137 | create a list of the files (contained in the newly created QDir)
|
|---|
| 138 | that match the specified file name. If the file name is empty
|
|---|
| 139 | the list will contain all the files in the directory.
|
|---|
| 140 |
|
|---|
| 141 | Then we search through all the files in the list, using the private
|
|---|
| 142 | \c findFiles() function, eliminating the ones that don't contain
|
|---|
| 143 | the specified text. And finally, we display the results using the
|
|---|
| 144 | private \c showFiles() function.
|
|---|
| 145 |
|
|---|
| 146 | If the user didn't specify any text, there is no reason to search
|
|---|
| 147 | through the files, and we display the results immediately.
|
|---|
| 148 |
|
|---|
| 149 | \image findfiles_progress_dialog.png Screenshot of the Progress Dialog
|
|---|
| 150 |
|
|---|
| 151 | \snippet examples/dialogs/findfiles/window.cpp 5
|
|---|
| 152 |
|
|---|
| 153 | In the private \c findFiles() function we search through a list of
|
|---|
| 154 | files, looking for the ones that contain a specified text. This
|
|---|
| 155 | can be a very slow operation depending on the number of files as
|
|---|
| 156 | well as their sizes. In case there are a large number of files, or
|
|---|
| 157 | there exists some large files on the list, we provide a
|
|---|
| 158 | QProgressDialog.
|
|---|
| 159 |
|
|---|
| 160 | The QProgressDialog class provides feedback on the progress of a
|
|---|
| 161 | slow operation. It is used to give the user an indication of how
|
|---|
| 162 | long an operation is going to take, and to demonstrate that the
|
|---|
| 163 | application has not frozen. It can also give the user an
|
|---|
| 164 | opportunity to abort the operation.
|
|---|
| 165 |
|
|---|
| 166 | \snippet examples/dialogs/findfiles/window.cpp 6
|
|---|
| 167 |
|
|---|
| 168 | We run through the files, one at a time, and for each file we
|
|---|
| 169 | update the QProgressDialog value. This property holds the current
|
|---|
| 170 | amount of progress made. We also update the progress dialog's
|
|---|
| 171 | label.
|
|---|
| 172 |
|
|---|
| 173 | Then we call the QCoreApplication::processEvents() function using
|
|---|
| 174 | the QApplication object. In this way we interleave the display of
|
|---|
| 175 | the progress made with the process of searching through the files
|
|---|
| 176 | so the application doesn't appear to be frozen.
|
|---|
| 177 |
|
|---|
| 178 | The QApplication class manages the GUI application's control flow
|
|---|
| 179 | and main settings. It contains the main event loop, where all
|
|---|
| 180 | events from the window system and other sources are processed and
|
|---|
| 181 | dispatched. QApplication inherits QCoreApplication. The
|
|---|
| 182 | QCoreApplication::processEvents() function processes all pending
|
|---|
| 183 | events according to the specified QEventLoop::ProcessEventFlags
|
|---|
| 184 | until there are no more events to process. The default flags are
|
|---|
| 185 | QEventLoop::AllEvents.
|
|---|
| 186 |
|
|---|
| 187 | \snippet examples/dialogs/findfiles/window.cpp 7
|
|---|
| 188 |
|
|---|
| 189 | After updating the QProgressDialog, we create a QFile using the
|
|---|
| 190 | QDir::absoluteFilePath() function which returns the absolute path
|
|---|
| 191 | name of a file in the directory. We open the file in read-only
|
|---|
| 192 | mode, and read one line at a time using QTextStream.
|
|---|
| 193 |
|
|---|
| 194 | The QTextStream class provides a convenient interface for reading
|
|---|
| 195 | and writing text. Using QTextStream's streaming operators, you can
|
|---|
| 196 | conveniently read and write words, lines and numbers.
|
|---|
| 197 |
|
|---|
| 198 | For each line we read we check if the QProgressDialog has been
|
|---|
| 199 | canceled. If it has, we abort the operation, otherwise we check if
|
|---|
| 200 | the line contains the specified text. When we find the text within
|
|---|
| 201 | one of the files, we add the file's name to a list of found files
|
|---|
| 202 | that contain the specified text, and start searching a new file.
|
|---|
| 203 |
|
|---|
| 204 | Finally, we return the list of the files found.
|
|---|
| 205 |
|
|---|
| 206 | \snippet examples/dialogs/findfiles/window.cpp 8
|
|---|
| 207 |
|
|---|
| 208 | Both the \c findFiles() and \c showFiles() functions are called from
|
|---|
| 209 | the \c find() slot. In the \c showFiles() function we run through
|
|---|
| 210 | the provided list of file names, adding each file name to the
|
|---|
| 211 | first column in the table widget and retrieving the file's size using
|
|---|
| 212 | QFile and QFileInfo for the second column.
|
|---|
| 213 |
|
|---|
| 214 | We also update the total number of files found.
|
|---|
| 215 |
|
|---|
| 216 | \snippet examples/dialogs/findfiles/window.cpp 9
|
|---|
| 217 |
|
|---|
| 218 | The private \c createButton() function is called from the
|
|---|
| 219 | constructor. We create a QPushButton with the provided text,
|
|---|
| 220 | connect it to the provided slot, and return a pointer to the
|
|---|
| 221 | button.
|
|---|
| 222 |
|
|---|
| 223 | \snippet examples/dialogs/findfiles/window.cpp 10
|
|---|
| 224 |
|
|---|
| 225 | The private \c createComboBox() function is also called from the
|
|---|
| 226 | contructor. We create a QComboBox with the given text, and make it
|
|---|
| 227 | editable.
|
|---|
| 228 |
|
|---|
| 229 | When the user enters a new string in an editable combobox, the
|
|---|
| 230 | widget may or may not insert it, and it can insert it in several
|
|---|
| 231 | locations, depending on the QComboBox::InsertPolicy. The default
|
|---|
| 232 | policy is is QComboBox::InsertAtBottom.
|
|---|
| 233 |
|
|---|
| 234 | Then we add the provided text to the combobox, and specify the
|
|---|
| 235 | widget's size policies, before we return a pointer to the
|
|---|
| 236 | combobox.
|
|---|
| 237 |
|
|---|
| 238 | \snippet examples/dialogs/findfiles/window.cpp 11
|
|---|
| 239 |
|
|---|
| 240 | The private \c createFilesTable() function is called from the
|
|---|
| 241 | constructor. In this function we create the QTableWidget that
|
|---|
| 242 | will display the search results. We set its horizontal headers and
|
|---|
| 243 | their resize mode.
|
|---|
| 244 |
|
|---|
| 245 | QTableWidget inherits QTableView which provides a default
|
|---|
| 246 | model/view implementation of a table view. The
|
|---|
| 247 | QTableView::horizontalHeader() function returns the table view's
|
|---|
| 248 | horizontal header as a QHeaderView. The QHeaderView class provides
|
|---|
| 249 | a header row or header column for item views, and the
|
|---|
| 250 | QHeaderView::setResizeMode() function sets the constraints on how
|
|---|
| 251 | the section in the header can be resized.
|
|---|
| 252 |
|
|---|
| 253 | Finally, we hide the QTableWidget's vertical headers using the
|
|---|
| 254 | QWidget::hide() function, and remove the default grid drawn for
|
|---|
| 255 | the table using the QTableView::setShowGrid() function.
|
|---|
| 256 |
|
|---|
| 257 | \snippet examples/dialogs/findfiles/window.cpp 12
|
|---|
| 258 |
|
|---|
| 259 | The \c openFileOfItem() slot is invoked when the user double
|
|---|
| 260 | clicks on a cell in the table. The QDesktopServices::openUrl()
|
|---|
| 261 | knows how to open a file given the file name.
|
|---|
| 262 | */
|
|---|
| 263 |
|
|---|