]> vaikene.ee Git - evaf/blob - src/apps/FileFinder/GUI/gui.cpp
Added the FileFinder application.
[evaf] / src / apps / FileFinder / GUI / gui.cpp
1 /**
2 * @file FileFinder/GUI/gui.cpp
3 * @brief GUI for the FileFinder application
4 * @author Enar Vaikene
5 *
6 * Copyright (c) 2011 Enar Vaikene
7 *
8 * This file is part of the eVaf C++ cross-platform application development framework.
9 *
10 * This file can be used under the terms of the GNU General Public License
11 * version 3.0 as published by the Free Software Foundation and appearing in
12 * the file LICENSE included in the packaging of this file. Please review the
13 * the following information to ensure the GNU General Public License version
14 * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
15 *
16 * Alternatively, this file may be used in accordance with the Commercial License
17 * Agreement provided with the Software.
18 */
19
20 #include "gui.h"
21 #include "version.h"
22
23 #include "Engine/iFileFinder"
24
25 #include <Common/Globals>
26 #include <Common/iLogger>
27 #include <Common/iRegistry>
28 #include <Common/iApp>
29 #include <SdiWindow/iSdiWindow>
30
31 #include <QtGui>
32
33 VER_EXPORT_VERSION_INFO()
34 Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR, eVaf::FileFinder::GUI::Module)
35
36 using namespace eVaf;
37
38
39 //-------------------------------------------------------------------
40
41 void FileFinder::GUI::Internal::MainWidget::keyPressEvent(QKeyEvent * e)
42 {
43 if (!e->modifiers() || ((e->modifiers() & Qt::KeypadModifier) && e->key() == Qt::Key_Enter)) {
44 switch (e->key()) {
45 case Qt::Key_Enter:
46 case Qt::Key_Return: {
47 QList<QPushButton *> buttons = qFindChildren<QPushButton *>(this);
48 foreach (QPushButton * btn, buttons) {
49 if (btn->isDefault() && btn->isVisible()) {
50 if (btn->isEnabled())
51 btn->click();
52 return;
53 }
54 }
55 break;
56 }
57 case Qt::Key_Escape:
58 emit quit();
59 break;
60 case Qt::Key_Up:
61 focusPreviousChild();
62 break;
63 case Qt::Key_Down:
64 focusNextChild();
65 break;
66 default:
67 e->ignore();
68 }
69 }
70 else {
71 e->ignore();
72 }
73 }
74
75
76 //-------------------------------------------------------------------
77
78 FileFinder::GUI::Module::Module()
79 : Plugins::iPlugin()
80 , mReady(false)
81 , mFinder(0)
82 , mOpenFileAction(0)
83 , mOpenDirectoryAction(0)
84 , wMain(0)
85 , wDirectory(0)
86 , wRecursive(0)
87 , wIncludeNames(0)
88 , wExcludeNames(0)
89 , wIncludeContent(0)
90 , wExcludeContent(0)
91 , wFind(0)
92 {
93 setObjectName(QString("%1.Module").arg(VER_MODULE_NAME_STR));
94
95 EVAF_INFO("%s created", qPrintable(objectName()));
96 }
97
98 FileFinder::GUI::Module::~Module()
99 {
100 EVAF_INFO("%s destroyed", qPrintable(objectName()));
101 }
102
103 bool FileFinder::GUI::Module::init(QString const & args)
104 {
105 Q_UNUSED(args)
106
107 // Get the iFileFinder interface
108 EVAF_TEST_X((mFinder = evafQueryInterface<FileFinder::iFileFinder>("iFileFinder")), "No iFileFinder interface");
109 connect(mFinder, SIGNAL(found(QString,QString)), this, SLOT(found(QString,QString)));
110 connect(mFinder, SIGNAL(finished(bool)), this, SLOT(finished(bool)));
111
112 // Get the main window interface and fill it with widgets
113 SdiWindow::iSdiWindow * win = evafQueryInterface<SdiWindow::iSdiWindow>("iSdiWindow");
114 EVAF_TEST_X(win, "No iSdiWindow interface");
115
116 // Create the main widget for this window
117 wMain = new Internal::MainWidget;
118 connect(wMain, SIGNAL(quit()), qApp, SLOT(quit()));
119 win->addWidget(wMain);
120
121 // Create actions for the window and widgets on it
122 createActions();
123
124 // Create all the other widgets
125 createWidgets();
126
127 // Load stored searches
128 loadHistory();
129
130 mReady = true;
131
132 EVAF_INFO("%s initialized", qPrintable(objectName()));
133
134 return true;
135 }
136
137 void FileFinder::GUI::Module::done()
138 {
139 mReady = false;
140
141 /*
142 * Widgets are deleted by the SdiWindow module. We use wMain to track calls to done() without
143 * proper init().
144 */
145 if (wMain) {
146 wMain = 0;
147 saveHistory();
148 }
149
150 EVAF_INFO("%s finalized", qPrintable(objectName()));
151 }
152
153 void FileFinder::GUI::Module::saveHistory()
154 {
155 QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name());
156
157 QStringList t;
158 for (int i = 0; i < wDirectory->count(); ++i)
159 t.append(wDirectory->itemText(i));
160 settings.setValue("FileFinder/Directories", t);
161
162 t.clear();
163 for (int i = 0; i < wIncludeNames->count(); ++i)
164 t.append(wIncludeNames->itemText(i));
165 settings.setValue("FileFinder/IncludeNames", t);
166
167 t.clear();
168 for (int i = 0; i < wExcludeNames->count(); ++i)
169 t.append(wExcludeNames->itemText(i));
170 settings.setValue("FileFinder/ExcludeNames", t);
171
172 t.clear();
173 for (int i = 0; i < wIncludeContent->count(); ++i)
174 t.append(wIncludeContent->itemText(i));
175 settings.setValue("FileFinder/IncludeContent", t);
176
177 t.clear();
178 for (int i = 0; i < wExcludeContent->count(); ++i)
179 t.append(wExcludeContent->itemText(i));
180 settings.setValue("FileFinder/ExcludeContent", t);
181
182 }
183
184 void FileFinder::GUI::Module::loadHistory()
185 {
186 QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name());
187
188 wDirectory->addItems(settings.value("FileFinder/Directories").toStringList());
189 wDirectory->setEditText(QDir::currentPath());
190
191 wIncludeNames->addItems(settings.value("FileFinder/IncludeNames").toStringList());
192 wIncludeNames->setEditText("");
193
194 wExcludeNames->addItems(settings.value("FileFinder/ExcludeNames").toStringList());
195 wExcludeNames->setEditText("");
196
197 wIncludeContent->addItems(settings.value("FileFinder/IncludeContent").toStringList());
198 wIncludeContent->setEditText("");
199
200 wExcludeContent->addItems(settings.value("FileFinder/ExcludeContent").toStringList());
201 wExcludeContent->setEditText("");
202 }
203
204 void FileFinder::GUI::Module::createWidgets()
205 {
206 QVBoxLayout * vbox = new QVBoxLayout;
207 wMain->setLayout(vbox);
208
209 QHBoxLayout * hbox = new QHBoxLayout;
210 vbox->addLayout(hbox);
211
212 QLabel * l = new QLabel(tr("&Directory:"));
213 hbox->addWidget(l);
214
215 wDirectory = new QComboBox;
216 wDirectory->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
217 wDirectory->setEditable(true);
218 wDirectory->setInsertPolicy(QComboBox::InsertAtTop);
219 l->setBuddy(wDirectory);
220 hbox->addWidget(wDirectory);
221
222 QPushButton * btn = new QPushButton(tr("&Browse"));
223 connect(btn, SIGNAL(clicked()), this, SLOT(browseDirectory()));
224 hbox->addWidget(btn);
225
226 wRecursive = new QCheckBox(tr("&Recursive"));
227 wRecursive->setChecked(true);
228 hbox->addWidget(wRecursive);
229
230 QGridLayout * gr = new QGridLayout;
231 vbox->addLayout(gr);
232
233 gr->setColumnStretch(1, 1);
234 gr->setColumnStretch(3, 1);
235
236 l = new QLabel(tr("&File filter:"));
237 gr->addWidget(l, 0, 0);
238
239 wIncludeNames = new QComboBox;
240 wIncludeNames->setEditable(true);
241 wIncludeNames->setInsertPolicy(QComboBox::InsertAtTop);
242 l->setBuddy(wIncludeNames);
243 gr->addWidget(wIncludeNames, 0, 1);
244
245 l = new QLabel(tr("&not:"));
246 gr->addWidget(l, 0, 2);
247
248 wExcludeNames = new QComboBox;
249 wExcludeNames->setEditable(true);
250 wExcludeNames->setInsertPolicy(QComboBox::InsertAtTop);
251 l->setBuddy(wExcludeNames);
252 gr->addWidget(wExcludeNames);
253
254 l = new QLabel(tr("C&ontains:"));
255 gr->addWidget(l, 1, 0);
256
257 wIncludeContent = new QComboBox;
258 wIncludeContent->setEditable(true);
259 wIncludeContent->setInsertPolicy(QComboBox::InsertAtTop);
260 l->setBuddy(wIncludeContent);
261 gr->addWidget(wIncludeContent, 1, 1);
262
263 l = new QLabel(tr("no&t:"));
264 gr->addWidget(l, 1, 2);
265
266 wExcludeContent = new QComboBox;
267 wExcludeContent->setEditable(true);
268 wExcludeContent->setInsertPolicy(QComboBox::InsertAtTop);
269 l->setBuddy(wExcludeContent);
270 gr->addWidget(wExcludeContent, 1, 3);
271
272 wResults = new QListWidget;
273 wResults->setContextMenuPolicy(Qt::ActionsContextMenu);
274 wResults->addAction(mOpenFileAction);
275 wResults->addAction(mOpenDirectoryAction);
276 connect(wResults, SIGNAL(currentRowChanged(int)), this, SLOT(currentRowChanged(int)));
277 connect(wResults, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(openFile(QModelIndex)));
278 vbox->addWidget(wResults);
279
280 hbox = new QHBoxLayout;
281 vbox->addLayout(hbox);
282 hbox->addStretch();
283
284 wFind = new QPushButton(tr("&Search"));
285 wFind->setDefault(true);
286 connect(wFind, SIGNAL(clicked()), this, SLOT(find()));
287 hbox->addWidget(wFind);
288
289 btn = new QPushButton(tr("&Close"));
290 connect(btn, SIGNAL(clicked()), qApp, SLOT(quit()));
291 hbox->addWidget(btn);
292 }
293
294 void FileFinder::GUI::Module::createActions()
295 {
296 QAction * a = new QAction(wMain);
297 a->setShortcuts(QKeySequence::Quit);
298 connect(a, SIGNAL(triggered()), qApp, SLOT(quit()));
299 wMain->addAction(a);
300
301 mOpenFileAction = new QAction(tr("&Open"), wMain);
302 mOpenFileAction->setEnabled(false);
303 connect(mOpenFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
304
305 mOpenDirectoryAction = new QAction(tr("Open &location"), wMain);
306 mOpenDirectoryAction->setEnabled(false);
307 connect(mOpenDirectoryAction, SIGNAL(triggered()), this, SLOT(openDirectory()));
308 }
309
310 void FileFinder::GUI::Module::browseDirectory()
311 {
312 QString s = QFileDialog::getExistingDirectory(wMain, tr("Select the directory"), wDirectory->currentText());
313 if (!s.isEmpty())
314 wDirectory->setEditText(s);
315 }
316
317 void FileFinder::GUI::Module::find()
318 {
319 if (!mFinder)
320 return;
321 if (mFinder->busy()) {
322 mFinder->cancel();
323 }
324 else {
325 wResults->clear();
326
327 mFinder->search(wDirectory->currentText(),
328 wRecursive->isChecked(),
329 FileFinder::Filter(
330 wIncludeNames->currentText(),
331 wExcludeNames->currentText(),
332 wIncludeContent->currentText(),
333 wExcludeContent->currentText()
334 )
335 );
336
337 wFind->setText(tr("&Stop"));
338 }
339 }
340
341 void FileFinder::GUI::Module::found(QString const & file, QString const & dir)
342 {
343 QString result = dir;
344 if (!result.endsWith(QChar('/')))
345 result.append(QChar('/'));
346 result.append(file);
347 wResults->addItem(result);
348 }
349
350 void FileFinder::GUI::Module::finished(bool canceled)
351 {
352 Q_UNUSED(canceled)
353
354 wFind->setText(tr("&Search"));
355 }
356
357 void FileFinder::GUI::Module::currentRowChanged(int currentRow)
358 {
359 mOpenFileAction->setEnabled(currentRow >= 0);
360 mOpenDirectoryAction->setEnabled(currentRow >= 0);
361 }
362
363 void FileFinder::GUI::Module::openFile(QModelIndex const & index)
364 {
365 Q_UNUSED(index)
366 if (wResults->currentItem())
367 QDesktopServices::openUrl(QUrl(QString("file:///%1").arg(wResults->currentItem()->text())));
368 }
369
370 void FileFinder::GUI::Module::openDirectory()
371 {
372 if (wResults->currentItem()) {
373 QFileInfo fi(wResults->currentItem()->text());
374 QDesktopServices::openUrl(QUrl(QString("file:///%1").arg(fi.path())));
375 }
376 }