]> vaikene.ee Git - evaf/blob - src/apps/FileFinder/GUI/gui.cpp
Changed to use Gui::Panel instead of Gui::Window.
[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 int const FileFinder::GUI::Module::MaxHistoryItems = 20;
79
80 FileFinder::GUI::Module::Module()
81 : Plugins::iPlugin()
82 , mReady(false)
83 , mFinder(0)
84 , mOpenFileAction(0)
85 , mOpenDirectoryAction(0)
86 , wMain(0)
87 , wDirectory(0)
88 , wRecursive(0)
89 , wIncludeNames(0)
90 , wExcludeNames(0)
91 , wIncludeContent(0)
92 , wExcludeContent(0)
93 , wFind(0)
94 {
95 setObjectName(QString("%1.Module").arg(VER_MODULE_NAME_STR));
96
97 EVAF_INFO("%s created", qPrintable(objectName()));
98 }
99
100 FileFinder::GUI::Module::~Module()
101 {
102 EVAF_INFO("%s destroyed", qPrintable(objectName()));
103 }
104
105 bool FileFinder::GUI::Module::init(QString const & args)
106 {
107 Q_UNUSED(args)
108
109 // Get the iFileFinder interface
110 EVAF_TEST_X((mFinder = evafQueryInterface<FileFinder::iFileFinder>("iFileFinder")), "No iFileFinder interface");
111 connect(mFinder, SIGNAL(found(QString,QString)), this, SLOT(found(QString,QString)));
112 connect(mFinder, SIGNAL(finished(bool)), this, SLOT(finished(bool)));
113
114 // Get the main window interface and fill it with widgets
115 SdiWindow::iSdiWindow * win = evafQueryInterface<SdiWindow::iSdiWindow>("iSdiWindow");
116 EVAF_TEST_X(win, "No iSdiWindow interface");
117
118 // Create the main widget for this window
119 wMain = new Internal::MainWidget;
120 connect(wMain, SIGNAL(quit()), qApp, SLOT(quit()));
121 win->addPanel("FileFinder", wMain);
122
123 // Create actions for the window and widgets on it
124 createActions();
125
126 // Create all the other widgets
127 createWidgets();
128
129 // Load stored searches
130 loadHistory();
131
132 mReady = true;
133
134 EVAF_INFO("%s initialized", qPrintable(objectName()));
135
136 return true;
137 }
138
139 void FileFinder::GUI::Module::done()
140 {
141 mReady = false;
142
143 mFinder = 0;
144
145 /*
146 * Widgets are deleted by the SdiWindow module. We use wMain to track calls to done() without
147 * proper init().
148 */
149 if (wMain) {
150 wMain = 0;
151 saveHistory();
152 }
153
154 EVAF_INFO("%s finalized", qPrintable(objectName()));
155 }
156
157 void FileFinder::GUI::Module::saveHistory()
158 {
159 QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name());
160
161 QStringList t;
162 for (int i = 0; i < wDirectory->count() && i < MaxHistoryItems; ++i)
163 t.append(wDirectory->itemText(i));
164 settings.setValue("FileFinder/Directories", t);
165
166 t.clear();
167 for (int i = 0; i < wIncludeNames->count() && i < MaxHistoryItems; ++i)
168 t.append(wIncludeNames->itemText(i));
169 settings.setValue("FileFinder/IncludeNames", t);
170
171 t.clear();
172 for (int i = 0; i < wExcludeNames->count() && i < MaxHistoryItems; ++i)
173 t.append(wExcludeNames->itemText(i));
174 settings.setValue("FileFinder/ExcludeNames", t);
175
176 t.clear();
177 for (int i = 0; i < wIncludeContent->count() && i < MaxHistoryItems; ++i)
178 t.append(wIncludeContent->itemText(i));
179 settings.setValue("FileFinder/IncludeContent", t);
180
181 t.clear();
182 for (int i = 0; i < wExcludeContent->count() && i < MaxHistoryItems; ++i)
183 t.append(wExcludeContent->itemText(i));
184 settings.setValue("FileFinder/ExcludeContent", t);
185
186 }
187
188 void FileFinder::GUI::Module::loadHistory()
189 {
190 QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name());
191
192 wDirectory->addItems(settings.value("FileFinder/Directories").toStringList());
193 wDirectory->setEditText(QDir::currentPath());
194 mDirModel->setRootPath(QDir::currentPath());
195
196 wIncludeNames->addItems(settings.value("FileFinder/IncludeNames").toStringList());
197 wIncludeNames->setEditText("");
198
199 wExcludeNames->addItems(settings.value("FileFinder/ExcludeNames").toStringList());
200 wExcludeNames->setEditText("");
201
202 wIncludeContent->addItems(settings.value("FileFinder/IncludeContent").toStringList());
203 wIncludeContent->setEditText("");
204
205 wExcludeContent->addItems(settings.value("FileFinder/ExcludeContent").toStringList());
206 wExcludeContent->setEditText("");
207 }
208
209 void FileFinder::GUI::Module::createWidgets()
210 {
211 QVBoxLayout * vbox = new QVBoxLayout;
212 wMain->setLayout(vbox);
213
214 QHBoxLayout * hbox = new QHBoxLayout;
215 vbox->addLayout(hbox);
216
217 QLabel * l = new QLabel(tr("&Directory:"));
218 hbox->addWidget(l);
219
220 wDirectory = new QComboBox;
221 wDirectory->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
222 wDirectory->setEditable(true);
223 wDirectory->setInsertPolicy(QComboBox::InsertAtTop);
224 QCompleter * completer = new QCompleter(wMain);
225 mDirModel = new QFileSystemModel(wMain);
226 mDirModel->setFilter(QDir::AllDirs | QDir::Dirs | QDir::NoDotAndDotDot);
227 completer->setModel(mDirModel);
228 wDirectory->setCompleter(completer);
229 l->setBuddy(wDirectory);
230 hbox->addWidget(wDirectory);
231
232 wBrowse = new QPushButton(tr("&Browse"));
233 connect(wBrowse, SIGNAL(clicked()), this, SLOT(browseDirectory()));
234 hbox->addWidget(wBrowse);
235
236 wRecursive = new QCheckBox(tr("&Recursive"));
237 wRecursive->setChecked(true);
238 hbox->addWidget(wRecursive);
239
240 QGridLayout * gr = new QGridLayout;
241 vbox->addLayout(gr);
242
243 gr->setColumnStretch(1, 1);
244 gr->setColumnStretch(3, 1);
245
246 l = new QLabel(tr("&File filter:"));
247 gr->addWidget(l, 0, 0);
248
249 wIncludeNames = new QComboBox;
250 wIncludeNames->setEditable(true);
251 wIncludeNames->setInsertPolicy(QComboBox::InsertAtTop);
252 l->setBuddy(wIncludeNames);
253 gr->addWidget(wIncludeNames, 0, 1);
254
255 l = new QLabel(tr("&not:"));
256 gr->addWidget(l, 0, 2);
257
258 wExcludeNames = new QComboBox;
259 wExcludeNames->setEditable(true);
260 wExcludeNames->setInsertPolicy(QComboBox::InsertAtTop);
261 l->setBuddy(wExcludeNames);
262 gr->addWidget(wExcludeNames);
263
264 l = new QLabel(tr("C&ontains:"));
265 gr->addWidget(l, 1, 0);
266
267 wIncludeContent = new QComboBox;
268 wIncludeContent->setEditable(true);
269 wIncludeContent->setInsertPolicy(QComboBox::InsertAtTop);
270 l->setBuddy(wIncludeContent);
271 gr->addWidget(wIncludeContent, 1, 1);
272
273 l = new QLabel(tr("no&t:"));
274 gr->addWidget(l, 1, 2);
275
276 wExcludeContent = new QComboBox;
277 wExcludeContent->setEditable(true);
278 wExcludeContent->setInsertPolicy(QComboBox::InsertAtTop);
279 l->setBuddy(wExcludeContent);
280 gr->addWidget(wExcludeContent, 1, 3);
281
282 wResults = new QListWidget;
283 wResults->setContextMenuPolicy(Qt::ActionsContextMenu);
284 wResults->addAction(mOpenFileAction);
285 wResults->addAction(mOpenDirectoryAction);
286 connect(wResults, SIGNAL(currentRowChanged(int)), this, SLOT(currentRowChanged(int)));
287 connect(wResults, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(openFile(QModelIndex)));
288 vbox->addWidget(wResults);
289
290 hbox = new QHBoxLayout;
291 vbox->addLayout(hbox);
292 hbox->addStretch();
293
294 wFind = new QPushButton(tr("&Search"));
295 wFind->setDefault(true);
296 connect(wFind, SIGNAL(clicked()), this, SLOT(find()));
297 hbox->addWidget(wFind);
298
299 QPushButton * btn = new QPushButton(tr("&Close"));
300 connect(btn, SIGNAL(clicked()), qApp, SLOT(quit()));
301 hbox->addWidget(btn);
302 }
303
304 void FileFinder::GUI::Module::createActions()
305 {
306 QAction * a = new QAction(wMain);
307 a->setShortcuts(QKeySequence::Quit);
308 connect(a, SIGNAL(triggered()), qApp, SLOT(quit()));
309 wMain->addAction(a);
310
311 mOpenFileAction = new QAction(tr("&Open"), wMain);
312 mOpenFileAction->setEnabled(false);
313 connect(mOpenFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
314
315 mOpenDirectoryAction = new QAction(tr("Open &location"), wMain);
316 mOpenDirectoryAction->setEnabled(false);
317 connect(mOpenDirectoryAction, SIGNAL(triggered()), this, SLOT(openDirectory()));
318 }
319
320 void FileFinder::GUI::Module::browseDirectory()
321 {
322 QString s = QFileDialog::getExistingDirectory(wMain, tr("Select the directory"), wDirectory->currentText());
323 if (!s.isEmpty())
324 wDirectory->setEditText(s);
325 }
326
327 void FileFinder::GUI::Module::find()
328 {
329 if (!mFinder)
330 return;
331 if (mFinder->busy()) {
332 mFinder->cancel();
333 }
334 else {
335 wResults->clear();
336
337 if (wDirectory->findText(wDirectory->currentText()) == -1)
338 wDirectory->insertItem(0, wDirectory->currentText());
339 if (wIncludeNames->findText(wIncludeNames->currentText()) == -1)
340 wIncludeNames->insertItem(0, wIncludeNames->currentText());
341 if (wExcludeNames->findText(wExcludeNames->currentText()) == -1)
342 wExcludeNames->insertItem(0, wExcludeNames->currentText());
343 if (wIncludeContent->findText(wIncludeContent->currentText()) == -1)
344 wIncludeContent->insertItem(0, wIncludeContent->currentText());
345 if (wExcludeContent->findText(wExcludeContent->currentText()) == -1)
346 wExcludeContent->insertItem(0, wExcludeContent->currentText());
347
348 // Disable input fields
349 wDirectory->setEnabled(false);
350 wBrowse->setEnabled(false);
351 wRecursive->setEnabled(false);
352 wIncludeNames->setEnabled(false);
353 wExcludeNames->setEnabled(false);
354 wIncludeContent->setEnabled(false);
355 wExcludeContent->setEnabled(false);
356
357 mFinder->search(wDirectory->currentText(),
358 wRecursive->isChecked(),
359 FileFinder::Filter(
360 wIncludeNames->currentText(),
361 wExcludeNames->currentText(),
362 wIncludeContent->currentText(),
363 wExcludeContent->currentText()
364 )
365 );
366
367 wFind->setText(tr("&Stop"));
368 }
369 }
370
371 void FileFinder::GUI::Module::found(QString const & file, QString const & dir)
372 {
373 QString result = dir;
374 if (!result.endsWith(QChar('/')))
375 result.append(QChar('/'));
376 result.append(file);
377 wResults->addItem(result);
378 }
379
380 void FileFinder::GUI::Module::finished(bool canceled)
381 {
382 Q_UNUSED(canceled)
383
384 // Enable input fields
385 wDirectory->setEnabled(true);
386 wBrowse->setEnabled(true);
387 wRecursive->setEnabled(true);
388 wIncludeNames->setEnabled(true);
389 wExcludeNames->setEnabled(true);
390 wIncludeContent->setEnabled(true);
391 wExcludeContent->setEnabled(true);
392
393 wFind->setText(tr("&Search"));
394 }
395
396 void FileFinder::GUI::Module::currentRowChanged(int currentRow)
397 {
398 mOpenFileAction->setEnabled(currentRow >= 0);
399 mOpenDirectoryAction->setEnabled(currentRow >= 0);
400 }
401
402 void FileFinder::GUI::Module::openFile(QModelIndex const & index)
403 {
404 Q_UNUSED(index)
405 if (wResults->currentItem())
406 QDesktopServices::openUrl(QUrl(QString("file:///%1").arg(wResults->currentItem()->text())));
407 }
408
409 void FileFinder::GUI::Module::openDirectory()
410 {
411 if (wResults->currentItem()) {
412 QFileInfo fi(wResults->currentItem()->text());
413 QDesktopServices::openUrl(QUrl(QString("file:///%1").arg(fi.path())));
414 }
415 }