1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
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 The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include "assistant.h"
52#include "findfiledialog.h"
53#include "textedit.h"
54
55#include <QComboBox>
56#include <QDialogButtonBox>
57#include <QDir>
58#include <QFileDialog>
59#include <QHBoxLayout>
60#include <QLabel>
61#include <QPushButton>
62#include <QToolButton>
63#include <QTreeWidget>
64#include <QTreeWidgetItem>
65
66//! [0]
67FindFileDialog::FindFileDialog(TextEdit *editor, Assistant *assistant)
68 : QDialog(editor)
69{
70 currentAssistant = assistant;
71 currentEditor = editor;
72//! [0]
73
74 createButtons();
75 createComboBoxes();
76 createFilesTree();
77 createLabels();
78 createLayout();
79
80 directoryComboBox->addItem(atext: QDir::toNativeSeparators(pathName: QDir::currentPath()));
81 fileNameComboBox->addItem(atext: "*");
82 findFiles();
83
84 setWindowTitle(tr(s: "Find File"));
85//! [1]
86}
87//! [1]
88
89void FindFileDialog::browse()
90{
91 QString currentDirectory = directoryComboBox->currentText();
92 QString newDirectory = QFileDialog::getExistingDirectory(parent: this,
93 caption: tr(s: "Select Directory"), dir: currentDirectory);
94 if (!newDirectory.isEmpty()) {
95 directoryComboBox->addItem(atext: QDir::toNativeSeparators(pathName: newDirectory));
96 directoryComboBox->setCurrentIndex(directoryComboBox->count() - 1);
97 update();
98 }
99}
100
101//! [2]
102void FindFileDialog::help()
103{
104 currentAssistant->showDocumentation(file: "filedialog.html");
105}
106//! [2]
107
108void FindFileDialog::openFile()
109{
110 auto item = foundFilesTree->currentItem();
111 if (!item)
112 return;
113
114 QString fileName = item->text(column: 0);
115 QString path = QDir(directoryComboBox->currentText()).filePath(fileName);
116
117 currentEditor->setContents(path);
118 close();
119}
120
121void FindFileDialog::update()
122{
123 findFiles();
124 buttonBox->button(which: QDialogButtonBox::Open)->setEnabled(
125 foundFilesTree->topLevelItemCount() > 0);
126}
127
128void FindFileDialog::findFiles()
129{
130 QRegExp filePattern(fileNameComboBox->currentText() + "*");
131 filePattern.setPatternSyntax(QRegExp::Wildcard);
132
133 QDir directory(directoryComboBox->currentText());
134
135 const QStringList allFiles = directory.entryList(filters: QDir::Files | QDir::NoSymLinks);
136 QStringList matchingFiles;
137
138 for (const QString &file : allFiles) {
139 if (filePattern.exactMatch(str: file))
140 matchingFiles << file;
141 }
142 showFiles(files: matchingFiles);
143}
144
145void FindFileDialog::showFiles(const QStringList &files)
146{
147 foundFilesTree->clear();
148
149 for (int i = 0; i < files.count(); ++i) {
150 QTreeWidgetItem *item = new QTreeWidgetItem(foundFilesTree);
151 item->setText(column: 0, atext: files[i]);
152 }
153
154 if (files.count() > 0)
155 foundFilesTree->setCurrentItem(foundFilesTree->topLevelItem(index: 0));
156}
157
158void FindFileDialog::createButtons()
159{
160 browseButton = new QToolButton;
161 browseButton->setText(tr(s: "..."));
162 connect(sender: browseButton, signal: &QAbstractButton::clicked, receiver: this, slot: &FindFileDialog::browse);
163
164 buttonBox = new QDialogButtonBox(QDialogButtonBox::Open
165 | QDialogButtonBox::Cancel
166 | QDialogButtonBox::Help);
167 connect(sender: buttonBox, signal: &QDialogButtonBox::accepted, receiver: this, slot: &FindFileDialog::openFile);
168 connect(sender: buttonBox, signal: &QDialogButtonBox::rejected, receiver: this, slot: &QDialog::reject);
169 connect(sender: buttonBox, signal: &QDialogButtonBox::helpRequested, receiver: this, slot: &FindFileDialog::help);
170}
171
172void FindFileDialog::createComboBoxes()
173{
174 directoryComboBox = new QComboBox;
175 fileNameComboBox = new QComboBox;
176
177 fileNameComboBox->setEditable(true);
178 fileNameComboBox->setSizePolicy(hor: QSizePolicy::Expanding,
179 ver: QSizePolicy::Preferred);
180
181 directoryComboBox->setMinimumContentsLength(30);
182 directoryComboBox->setSizeAdjustPolicy(
183 QComboBox::AdjustToContents);
184 directoryComboBox->setSizePolicy(hor: QSizePolicy::Expanding,
185 ver: QSizePolicy::Preferred);
186
187 connect(sender: fileNameComboBox, signal: &QComboBox::editTextChanged,
188 receiver: this, slot: &FindFileDialog::update);
189 connect(sender: directoryComboBox, signal: &QComboBox::currentTextChanged,
190 receiver: this, slot: &FindFileDialog::update);
191}
192
193void FindFileDialog::createFilesTree()
194{
195 foundFilesTree = new QTreeWidget;
196 foundFilesTree->setColumnCount(1);
197 foundFilesTree->setHeaderLabels(QStringList(tr(s: "Matching Files")));
198 foundFilesTree->setRootIsDecorated(false);
199 foundFilesTree->setSelectionMode(QAbstractItemView::SingleSelection);
200
201 connect(sender: foundFilesTree, signal: &QTreeWidget::itemActivated,
202 receiver: this, slot: &FindFileDialog::openFile);
203}
204
205void FindFileDialog::createLabels()
206{
207 directoryLabel = new QLabel(tr(s: "Search in:"));
208 fileNameLabel = new QLabel(tr(s: "File name (including wildcards):"));
209}
210
211void FindFileDialog::createLayout()
212{
213 QHBoxLayout *fileLayout = new QHBoxLayout;
214 fileLayout->addWidget(fileNameLabel);
215 fileLayout->addWidget(fileNameComboBox);
216
217 QHBoxLayout *directoryLayout = new QHBoxLayout;
218 directoryLayout->addWidget(directoryLabel);
219 directoryLayout->addWidget(directoryComboBox);
220 directoryLayout->addWidget(browseButton);
221
222 QVBoxLayout *mainLayout = new QVBoxLayout;
223 mainLayout->addLayout(layout: fileLayout);
224 mainLayout->addLayout(layout: directoryLayout);
225 mainLayout->addWidget(foundFilesTree);
226 mainLayout->addStretch();
227 mainLayout->addWidget(buttonBox);
228 setLayout(mainLayout);
229}
230

source code of qttools/examples/assistant/simpletextviewer/findfiledialog.cpp