/** * @file FileFinder/GUI/gui.cpp * @brief GUI for the FileFinder application * @author Enar Vaikene * * Copyright (c) 2011 Enar Vaikene * * This file is part of the eVaf C++ cross-platform application development framework. * * This file can be used under the terms of the GNU General Public License * version 3.0 as published by the Free Software Foundation and appearing in * the file LICENSE included in the packaging of this file. Please review the * the following information to ensure the GNU General Public License version * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. * * Alternatively, this file may be used in accordance with the Commercial License * Agreement provided with the Software. */ #include "gui.h" #include "Engine/iFileFinder" #include #include #include #include #include #include VER_EXPORT_VERSION_INFO() using namespace eVaf; //------------------------------------------------------------------- void FileFinder::GUI::Internal::MainWidget::keyPressEvent(QKeyEvent * e) { if (!e->modifiers() || ((e->modifiers() & Qt::KeypadModifier) && e->key() == Qt::Key_Enter)) { switch (e->key()) { case Qt::Key_Enter: case Qt::Key_Return: { QList buttons = findChildren(); foreach (QPushButton * btn, buttons) { if (btn->isDefault() && btn->isVisible()) { if (btn->isEnabled()) btn->click(); return; } } break; } case Qt::Key_Escape: emit quit(); break; case Qt::Key_Up: focusPreviousChild(); break; case Qt::Key_Down: focusNextChild(); break; default: e->ignore(); } } else { e->ignore(); } } //------------------------------------------------------------------- int const FileFinder::GUI::Module::MaxHistoryItems = 20; FileFinder::GUI::Module::Module() : Plugins::iPlugin() , mReady(false) , mFinder(0) , mOpenFileAction(0) , mOpenDirectoryAction(0) , mCopyNameAction(0) , mCopyAllNamesAction(0) , wMain(0) , wDirectory(0) , wRecursive(0) , wIncludeNames(0) , wExcludeNames(0) , wIncludeContent(0) , wExcludeContent(0) , wFind(0) { setObjectName(QString("%1.Module").arg(VER_MODULE_NAME_STR)); EVAF_INFO("%s created", qPrintable(objectName())); } FileFinder::GUI::Module::~Module() { EVAF_INFO("%s destroyed", qPrintable(objectName())); } bool FileFinder::GUI::Module::init(QString const & args) { Q_UNUSED(args) // Get the iFileFinder interface EVAF_TEST_X((mFinder = evafQueryInterface("iFileFinder")), "No iFileFinder interface"); connect(mFinder, SIGNAL(found(QString,QString)), this, SLOT(found(QString,QString))); connect(mFinder, SIGNAL(finished(bool)), this, SLOT(finished(bool))); // Get the main window interface and fill it with widgets SdiWindow::iSdiWindow * win = evafQueryInterface("iSdiWindow"); EVAF_TEST_X(win, "No iSdiWindow interface"); // Create the main widget for this window wMain = new Internal::MainWidget; connect(wMain, SIGNAL(quit()), qApp, SLOT(quit())); win->addPanel("FileFinder", wMain); // Create actions for the window and widgets on it createActions(); // Create all the other widgets createWidgets(); // Load stored searches loadHistory(); mReady = true; EVAF_INFO("%s initialized", qPrintable(objectName())); return true; } void FileFinder::GUI::Module::done() { mReady = false; mFinder = 0; /* * Widgets are deleted by the SdiWindow module. We use wMain to track calls to done() without * proper init(). */ if (wMain) { wMain = 0; saveHistory(); } EVAF_INFO("%s finalized", qPrintable(objectName())); } void FileFinder::GUI::Module::saveHistory() { QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name()); QStringList t; for (int i = 0; i < wDirectory->count() && i < MaxHistoryItems; ++i) t.append(wDirectory->itemText(i)); settings.setValue("FileFinder/Directories", t); t.clear(); for (int i = 0; i < wIncludeNames->count() && i < MaxHistoryItems; ++i) t.append(wIncludeNames->itemText(i)); settings.setValue("FileFinder/IncludeNames", t); t.clear(); for (int i = 0; i < wExcludeNames->count() && i < MaxHistoryItems; ++i) t.append(wExcludeNames->itemText(i)); settings.setValue("FileFinder/ExcludeNames", t); t.clear(); for (int i = 0; i < wIncludeContent->count() && i < MaxHistoryItems; ++i) t.append(wIncludeContent->itemText(i)); settings.setValue("FileFinder/IncludeContent", t); t.clear(); for (int i = 0; i < wExcludeContent->count() && i < MaxHistoryItems; ++i) t.append(wExcludeContent->itemText(i)); settings.setValue("FileFinder/ExcludeContent", t); } void FileFinder::GUI::Module::loadHistory() { QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name()); wDirectory->addItems(settings.value("FileFinder/Directories").toStringList()); wDirectory->setEditText(QDir::currentPath()); mDirModel->setRootPath(QDir::currentPath()); wIncludeNames->addItems(settings.value("FileFinder/IncludeNames").toStringList()); wIncludeNames->setEditText(""); wExcludeNames->addItems(settings.value("FileFinder/ExcludeNames").toStringList()); wExcludeNames->setEditText(""); wIncludeContent->addItems(settings.value("FileFinder/IncludeContent").toStringList()); wIncludeContent->setEditText(""); wExcludeContent->addItems(settings.value("FileFinder/ExcludeContent").toStringList()); wExcludeContent->setEditText(""); } void FileFinder::GUI::Module::createWidgets() { QVBoxLayout * vbox = new QVBoxLayout; wMain->setLayout(vbox); QHBoxLayout * hbox = new QHBoxLayout; vbox->addLayout(hbox); QLabel * l = new QLabel(tr("&Directory:")); hbox->addWidget(l); wDirectory = new QComboBox; wDirectory->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); wDirectory->setEditable(true); wDirectory->setInsertPolicy(QComboBox::InsertAtTop); QCompleter * completer = new QCompleter(wMain); mDirModel = new QFileSystemModel(wMain); mDirModel->setFilter(QDir::AllDirs | QDir::Dirs | QDir::NoDotAndDotDot); completer->setModel(mDirModel); wDirectory->setCompleter(completer); l->setBuddy(wDirectory); hbox->addWidget(wDirectory); wBrowse = new QPushButton(tr("&Browse")); connect(wBrowse, SIGNAL(clicked()), this, SLOT(browseDirectory())); hbox->addWidget(wBrowse); wRecursive = new QCheckBox(tr("&Recursive")); wRecursive->setChecked(true); hbox->addWidget(wRecursive); QGridLayout * gr = new QGridLayout; vbox->addLayout(gr); gr->setColumnStretch(1, 1); gr->setColumnStretch(3, 1); l = new QLabel(tr("&File filter:")); gr->addWidget(l, 0, 0); wIncludeNames = new QComboBox; wIncludeNames->setEditable(true); wIncludeNames->setInsertPolicy(QComboBox::InsertAtTop); l->setBuddy(wIncludeNames); gr->addWidget(wIncludeNames, 0, 1); l = new QLabel(tr("¬:")); gr->addWidget(l, 0, 2); wExcludeNames = new QComboBox; wExcludeNames->setEditable(true); wExcludeNames->setInsertPolicy(QComboBox::InsertAtTop); l->setBuddy(wExcludeNames); gr->addWidget(wExcludeNames); l = new QLabel(tr("C&ontains:")); gr->addWidget(l, 1, 0); wIncludeContent = new QComboBox; wIncludeContent->setEditable(true); wIncludeContent->setInsertPolicy(QComboBox::InsertAtTop); l->setBuddy(wIncludeContent); gr->addWidget(wIncludeContent, 1, 1); l = new QLabel(tr("no&t:")); gr->addWidget(l, 1, 2); wExcludeContent = new QComboBox; wExcludeContent->setEditable(true); wExcludeContent->setInsertPolicy(QComboBox::InsertAtTop); l->setBuddy(wExcludeContent); gr->addWidget(wExcludeContent, 1, 3); wResults = new QListWidget; wResults->setContextMenuPolicy(Qt::ActionsContextMenu); wResults->addActions(QList() << mOpenFileAction << mOpenDirectoryAction << mCopyNameAction << mCopyAllNamesAction); connect(wResults, SIGNAL(currentRowChanged(int)), this, SLOT(currentRowChanged(int))); connect(wResults, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(openFile(QModelIndex))); vbox->addWidget(wResults); hbox = new QHBoxLayout; vbox->addLayout(hbox); hbox->addStretch(); wFind = new QPushButton(tr("&Search")); wFind->setDefault(true); connect(wFind, SIGNAL(clicked()), this, SLOT(find())); hbox->addWidget(wFind); QPushButton * btn = new QPushButton(tr("&Close")); connect(btn, SIGNAL(clicked()), qApp, SLOT(quit())); hbox->addWidget(btn); } void FileFinder::GUI::Module::createActions() { QAction * a = new QAction(wMain); a->setShortcuts(QKeySequence::Quit); connect(a, SIGNAL(triggered()), qApp, SLOT(quit())); wMain->addAction(a); mOpenFileAction = new QAction(tr("&Open"), wMain); mOpenFileAction->setEnabled(false); connect(mOpenFileAction, SIGNAL(triggered()), this, SLOT(openFile())); mOpenDirectoryAction = new QAction(tr("Open &location"), wMain); mOpenDirectoryAction->setEnabled(false); connect(mOpenDirectoryAction, SIGNAL(triggered()), this, SLOT(openDirectory())); mCopyNameAction = new QAction(tr("&Copy name"), wMain); mCopyNameAction->setEnabled(false); connect(mCopyNameAction, SIGNAL(triggered()), this, SLOT(copyName())); mCopyAllNamesAction = new QAction(tr("Copy &all names"), wMain); connect(mCopyAllNamesAction, SIGNAL(triggered()), this, SLOT(copyAllNames())); } void FileFinder::GUI::Module::browseDirectory() { QString s = QFileDialog::getExistingDirectory(wMain, tr("Select the directory"), wDirectory->currentText()); if (!s.isEmpty()) wDirectory->setEditText(s); } void FileFinder::GUI::Module::find() { if (!mFinder) return; if (mFinder->busy()) { mFinder->cancel(); } else { wResults->clear(); if (wDirectory->findText(wDirectory->currentText()) == -1) wDirectory->insertItem(0, wDirectory->currentText()); if (wIncludeNames->findText(wIncludeNames->currentText()) == -1) wIncludeNames->insertItem(0, wIncludeNames->currentText()); if (wExcludeNames->findText(wExcludeNames->currentText()) == -1) wExcludeNames->insertItem(0, wExcludeNames->currentText()); if (wIncludeContent->findText(wIncludeContent->currentText()) == -1) wIncludeContent->insertItem(0, wIncludeContent->currentText()); if (wExcludeContent->findText(wExcludeContent->currentText()) == -1) wExcludeContent->insertItem(0, wExcludeContent->currentText()); // Disable input fields wDirectory->setEnabled(false); wBrowse->setEnabled(false); wRecursive->setEnabled(false); wIncludeNames->setEnabled(false); wExcludeNames->setEnabled(false); wIncludeContent->setEnabled(false); wExcludeContent->setEnabled(false); mFinder->search(wDirectory->currentText(), wRecursive->isChecked(), FileFinder::Filter( wIncludeNames->currentText(), wExcludeNames->currentText(), wIncludeContent->currentText(), wExcludeContent->currentText() ) ); wFind->setText(tr("&Stop")); } } void FileFinder::GUI::Module::found(QString const & file, QString const & dir) { QString result = dir; if (!result.endsWith(QChar('/'))) result.append(QChar('/')); result.append(file); wResults->addItem(result); } void FileFinder::GUI::Module::finished(bool canceled) { Q_UNUSED(canceled) // Enable input fields wDirectory->setEnabled(true); wBrowse->setEnabled(true); wRecursive->setEnabled(true); wIncludeNames->setEnabled(true); wExcludeNames->setEnabled(true); wIncludeContent->setEnabled(true); wExcludeContent->setEnabled(true); wFind->setText(tr("&Search")); } void FileFinder::GUI::Module::currentRowChanged(int currentRow) { mOpenFileAction->setEnabled(currentRow >= 0); mOpenDirectoryAction->setEnabled(currentRow >= 0); mCopyNameAction->setEnabled(currentRow >= 0); } void FileFinder::GUI::Module::openFile(QModelIndex const & index) { Q_UNUSED(index) if (wResults->currentItem()) { QString t = wResults->currentItem()->text(); t.replace("?", "\0453f"); QDesktopServices::openUrl(QUrl::fromEncoded(QString("file:///%1").arg(t).toUtf8())); } } void FileFinder::GUI::Module::openDirectory() { if (wResults->currentItem()) { QString t = wResults->currentItem()->text(); t.replace("?", "\0453f"); QFileInfo fi(t); QDesktopServices::openUrl(QUrl::fromEncoded(QString("file:///%1").arg(fi.path()).toUtf8())); } } void FileFinder::GUI::Module::copyName() { if (wResults->currentItem()) { QClipboard * cb = QApplication::clipboard(); if (cb) cb->setText(wResults->currentItem()->text()); } } void FileFinder::GUI::Module::copyAllNames() { #ifdef Q_OS_WIN32 static char const * const EOLN = "\r\n"; #else static char const * const EOLN = "\n"; #endif QString t; for (int i = 0; i < wResults->count(); ++i) t.append(wResults->item(i)->text() + EOLN); if (!t.isEmpty()) { QClipboard * cb = QApplication::clipboard(); if (cb) cb->setText(t); } }