]> vaikene.ee Git - evaf/commitdiff
Added the FileFinder application.
authorEnar Väikene <enar@vaikene.net>
Fri, 25 Nov 2011 11:06:52 +0000 (13:06 +0200)
committerEnar Väikene <enar@vaikene.net>
Fri, 25 Nov 2011 11:06:52 +0000 (13:06 +0200)
The FileFinder application is used to search for files that match file and/or content patterns.

15 files changed:
src/apps/CMakeLists.txt
src/apps/FileFinder/CMakeLists.txt [new file with mode: 0644]
src/apps/FileFinder/Engine/CMakeLists.txt [new file with mode: 0644]
src/apps/FileFinder/Engine/engine.cpp [new file with mode: 0644]
src/apps/FileFinder/Engine/engine.h [new file with mode: 0644]
src/apps/FileFinder/Engine/iFileFinder [new file with mode: 0644]
src/apps/FileFinder/Engine/ifilefinder.h [new file with mode: 0644]
src/apps/FileFinder/Engine/version.h [new file with mode: 0644]
src/apps/FileFinder/Engine/version.rc [new file with mode: 0644]
src/apps/FileFinder/GUI/CMakeLists.txt [new file with mode: 0644]
src/apps/FileFinder/GUI/gui.cpp [new file with mode: 0644]
src/apps/FileFinder/GUI/gui.h [new file with mode: 0644]
src/apps/FileFinder/GUI/gui.qrc [new file with mode: 0644]
src/apps/FileFinder/GUI/version.h [new file with mode: 0644]
src/apps/FileFinder/GUI/version.rc [new file with mode: 0644]

index e6cf7f0e8dcd4b2b0ebe95c3f002f8072e3f1b00..3aa82ad26cbbc63de67bc7df7a6da4546df52c07 100644 (file)
@@ -1 +1,4 @@
+set(eVaf_INCLUDE ${eVaf_INCLUDE} ${CMAKE_SOURCE_DIR}/src/apps/FileFinder)
+
 add_subdirectory(PswGen)
+add_subdirectory(FileFinder)
diff --git a/src/apps/FileFinder/CMakeLists.txt b/src/apps/FileFinder/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cea6206
--- /dev/null
@@ -0,0 +1,2 @@
+add_subdirectory(Engine)
+add_subdirectory(GUI)
diff --git a/src/apps/FileFinder/Engine/CMakeLists.txt b/src/apps/FileFinder/Engine/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4e9e9ba
--- /dev/null
@@ -0,0 +1,39 @@
+# Name of the target
+set(TARGET FileFinderEngine)
+
+# Qt modules
+set(QT_DONT_USE_QTGUI TRUE)
+include(${QT_USE_FILE})
+
+# Needed for exporting/importing symbols
+add_definitions(-DFILEFINDER_ENGINE_LIBRARY)
+
+# Include files
+include_directories(${eVaf_INCLUDE})
+
+# Required eVaf libraries
+set(eVaf_LIBRARIES CommonLib PluginsLib)
+
+# Source files
+set(SRCS
+    engine.cpp
+)
+
+# Header files for the meta-object compiler
+set(MOC_HDRS
+    ifilefinder.h
+    engine.h
+)
+
+# Version info resource file for Windows builds
+if(WIN32)
+    set(SRCS ${SRCS} version.rc)
+endif(WIN32)
+
+qt4_wrap_cpp(MOC_SRCS ${MOC_HDRS})
+
+add_library(${TARGET} SHARED ${SRCS} ${MOC_SRCS})
+
+target_link_libraries(${TARGET} ${QT_LIBRARIES} ${eVaf_LIBRARIES})
+
+install(TARGETS ${TARGET} DESTINATION bin)
diff --git a/src/apps/FileFinder/Engine/engine.cpp b/src/apps/FileFinder/Engine/engine.cpp
new file mode 100644 (file)
index 0000000..b9fae0e
--- /dev/null
@@ -0,0 +1,397 @@
+/**
+ * @file FileFinder/Engine/engine.h
+ * @brief Module for the FileFinder application that searches for files
+ * @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 "engine.h"
+#include "version.h"
+
+#include <Common/iLogger>
+#include <Common/iRegistry>
+
+#include <QtCore>
+
+VER_EXPORT_VERSION_INFO()
+Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR, eVaf::FileFinder::Engine::Module)
+
+using namespace eVaf;
+using namespace eVaf::FileFinder;
+using namespace eVaf::FileFinder::Engine;
+
+//-------------------------------------------------------------------
+
+Module::Module()
+    : Plugins::iPlugin()
+    , mReady(false)
+{
+    setObjectName(QString("%1.Module").arg(VER_MODULE_NAME_STR));
+
+    mEngine = new Internal::Engine;
+
+    EVAF_INFO("%s created", qPrintable(objectName()));
+}
+
+Module::~Module()
+{
+    delete mEngine;
+
+    EVAF_INFO("%s destroyed", qPrintable(objectName()));
+}
+
+bool Module::init(QString const & args)
+{
+    Q_UNUSED(args)
+
+    if (!mEngine->init())
+        return false;
+
+    mReady = true;
+
+    EVAF_INFO("%s initialized", qPrintable(objectName()));
+
+    return true;
+}
+
+void Module::done()
+{
+    mReady = false;
+
+    mEngine->done();
+
+    EVAF_INFO("%s finalized", qPrintable(objectName()));
+}
+
+
+//-------------------------------------------------------------------
+
+Internal::Engine::Engine()
+    : iFileFinder()
+    , mWorker(0)
+{
+    setObjectName(QString("%1.Engine").arg(VER_MODULE_NAME_STR));
+
+    EVAF_INFO("%s created", qPrintable(objectName()));
+}
+
+Internal::Engine::~Engine()
+{
+    EVAF_INFO("%s destroyed", qPrintable(objectName()));
+}
+
+bool Internal::Engine::init()
+{
+    // Register the iFileFinder interface
+    Common::iRegistry::instance()->registerInterface("iFileFinder", this);
+
+    mWorker = new Internal::Worker(this);
+    connect(mWorker, SIGNAL(found(QString, QString)), this, SIGNAL(found(QString,QString)));
+    connect(mWorker, SIGNAL(finished(bool)), this, SIGNAL(finished(bool)));
+    mWorker->start();
+
+    EVAF_INFO("%s initialized", qPrintable(objectName()));
+
+    return true;
+}
+
+void Internal::Engine::done()
+{
+    if (mWorker) {
+        mWorker->stop();
+        delete mWorker;
+        mWorker = 0;
+    }
+
+    EVAF_INFO("%s finalized", qPrintable(objectName()));
+}
+
+void Internal::Engine::search(QString const & dir, bool recursive, Filter const & filter)
+{
+    if (mWorker)
+        mWorker->search(dir, recursive, filter);
+}
+
+bool Internal::Engine::busy() const
+{
+    if (mWorker)
+        return mWorker->busy();
+    return false;
+}
+
+void Internal::Engine::cancel()
+{
+    if (mWorker)
+        mWorker->cancel();
+}
+
+
+//-------------------------------------------------------------------
+
+Internal::RegExpChain::~RegExpChain()
+{
+    clear();
+}
+
+void Internal::RegExpChain::clear()
+{
+    foreach (QRegExp * pattern, mPatterns) {
+        delete pattern;
+    }
+    mPatterns.clear();
+    mValid = false;
+}
+
+void Internal::RegExpChain::setPattern(QString const & pattern)
+{
+    clear();
+
+    QStringList patterns = split(pattern);
+
+    foreach (QString s, patterns) {
+        if (s.isEmpty())
+            continue;
+        QRegExp * rx = new QRegExp(s, Qt::CaseSensitive, QRegExp::WildcardUnix);
+        if (!rx->isValid()) {
+            delete rx;
+            continue;
+        }
+        mPatterns.append(rx);
+    }
+
+    mValid = !mPatterns.isEmpty();
+}
+
+bool Internal::RegExpChain::exactMatch(const QString& str) const
+{
+    if (mPatterns.isEmpty())
+        return false;
+
+    foreach (QRegExp * pattern, mPatterns) {
+        if (pattern->exactMatch(str))
+            return true;
+    }
+    return false;
+}
+
+QStringList Internal::RegExpChain::split(const QString & pattern)
+{
+    QStringList rval;
+    int offset = 0;
+    int sz = pattern.size();
+    QString s;
+    bool e = false;
+
+    while (offset < sz) {
+        QChar ch = pattern.at(offset++);
+        if (e) {
+            e = false;
+            if (ch == '*' || ch == '?' || ch == '[' || ch == ']')
+                s.append('\\');
+            s.append(ch);
+        }
+        else {
+            if (ch == '\\')
+                e = true;
+            else if (ch == ',') {
+                rval.append(s);
+                s.clear();
+            }
+            else
+                s.append(ch);
+        }
+    }
+    if (!s.isEmpty())
+        rval.append(s);
+
+    return rval;
+}
+
+
+//-------------------------------------------------------------------
+
+int const Internal::Worker::ReadBufferSize = 4096;
+
+Internal::Worker::Worker(QObject * parent)
+    : QThread(parent)
+    , mNewRecursive(false)
+    , mRecursive(false)
+    , mDoSearch(false)
+    , mDoTerminate(false)
+    , mDoCancel(false)
+    , mBusy(false)
+{
+    setObjectName(QString("%1.Worker").arg(VER_MODULE_NAME_STR));
+}
+
+void Internal::Worker::cancel()
+{
+    mLock.lock();
+    mDoCancel = true;
+    mSomethingToDo.wakeAll();
+    mLock.unlock();
+}
+
+void Internal::Worker::stop()
+{
+    mLock.lock();
+    mDoTerminate = true;
+    mDoCancel = true;
+    mSomethingToDo.wakeAll();
+    mLock.unlock();
+    wait();
+}
+
+void Internal::Worker::search(QString const & dir, bool recursive, Filter const & filter)
+{
+    mLock.lock();
+    mDoCancel = true;
+    mNewDir = dir;
+    mNewRecursive = recursive;
+    mNewFilter = filter;
+    mDoSearch = true;
+    mSomethingToDo.wakeAll();
+    mLock.unlock();
+}
+
+bool Internal::Worker::busy() const
+{
+    QMutexLocker l(&mLock);
+    return mBusy;
+}
+
+void Internal::Worker::run()
+{
+    forever {
+        QMutexLocker lock(&mLock);
+
+        mSomethingToDo.wait(&mLock);
+
+        if (mDoTerminate)
+            break;
+
+        mDoCancel = false;
+
+        if (mDoSearch) {
+            mDoSearch = false;
+            mBusy = true;
+
+            // Copy search arguments
+            mDir.setPath(mNewDir);
+            mRecursive = mNewRecursive;
+            mRxIncludeNames.setPattern(mNewFilter.includeNames);
+            mRxExcludeNames.setPattern(mNewFilter.excludeNames);
+            mRxIncludeContent.setPattern(mNewFilter.includeContent);
+            mRxExcludeContent.setPattern(mNewFilter.excludeContent);
+
+            lock.unlock();
+
+            // Perform the actual search
+            recursiveSearch(mDir.path());
+
+            lock.relock();
+            mBusy = false;
+
+            emit finished(mDoCancel);
+        }
+    }
+}
+
+void Internal::Worker::recursiveSearch(QString const & path)
+{
+    QString l = path;
+    if (!l.endsWith(QChar('/')))
+        l.append(QChar('/'));
+    QDir dir(l);
+
+    // Get the list of files in this directory
+    QStringList files = dir.entryList(QDir::Files | QDir::NoSymLinks);
+    foreach (QString const & file, files) {
+
+        // Check for the cancel flag
+        {
+            QMutexLocker l(&mLock);
+            if (mDoCancel)
+                break;
+        }
+
+        // Check for the file name to match the include filter and not the exclude filter
+        if (mRxIncludeNames.isValid() && !mRxIncludeNames.isEmpty()) {
+            if (!mRxIncludeNames.exactMatch(file))
+                continue;
+        }
+        if (mRxExcludeNames.isValid() && !mRxExcludeNames.isEmpty()) {
+            if (mRxExcludeNames.exactMatch(file))
+                continue;
+        }
+
+        // Check for the file content to match the include filter and not the exclude filter
+        if ((mRxIncludeContent.isValid() && !mRxIncludeContent.isEmpty()) ||
+            (mRxExcludeContent.isValid() && !mRxExcludeContent.isEmpty())) {
+
+            QFile f(l + file);
+            if (!f.open(QFile::ReadOnly))
+                continue; // Ignore silently if opening fails
+
+            int includeFilterMatched = 0;
+            if (!mRxIncludeContent.isValid() || mRxIncludeContent.isEmpty())
+                includeFilterMatched = 1;
+            int excludeFilterMatched = 0;
+            if (!mRxExcludeContent.isValid() || mRxExcludeContent.isEmpty())
+                excludeFilterMatched = -1;
+            QByteArray buf;
+            while (!f.atEnd() && (includeFilterMatched <= 0 || excludeFilterMatched <= 0)) {
+
+                /* We read ReadBufferSize bytes from the file and append to the buffer.
+                 * We keep max 2 x ReadBufferSize bytes in the buffer and throw away the oldest
+                 * ReadBufferSize bytes of data. Every block is checked twice, but we make sure that
+                 * also strings that stretch from one block to another are checked.
+                 */
+                QByteArray b = f.read(ReadBufferSize);
+                buf.append(b);
+                if (buf.size() > (2 * ReadBufferSize))
+                    buf.remove(0, ReadBufferSize);
+                if (includeFilterMatched == 0 && mRxIncludeContent.indexIn(buf) >= 0)
+                    ++includeFilterMatched;
+                if (excludeFilterMatched == 0 && mRxExcludeContent.indexIn(buf) >= 0)
+                    ++excludeFilterMatched;
+
+            }
+
+            if (includeFilterMatched == 0 || excludeFilterMatched > 0)
+                continue;
+        }
+
+        // Found a file
+        emit found(mDir.relativeFilePath(l + file), mDir.path());
+    }
+
+    // Process sub-directories
+    if (mRecursive) {
+        QStringList dirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
+        foreach (QString const & directory, dirs) {
+
+            // Check for the cancel flag
+            {
+                QMutexLocker l(&mLock);
+                if (mDoCancel)
+                    break;
+            }
+
+            recursiveSearch(l + directory);
+        }
+    }
+}
diff --git a/src/apps/FileFinder/Engine/engine.h b/src/apps/FileFinder/Engine/engine.h
new file mode 100644 (file)
index 0000000..384fa40
--- /dev/null
@@ -0,0 +1,286 @@
+/**
+ * @file FileFinder/Engine/engine.h
+ * @brief Module for the FileFinder application that searches for files
+ * @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.
+ */
+
+#ifndef __FILEFINDER_ENGINE_ENGINE_H
+#  define __FILEFINDER_ENGINE_ENGINE_H
+
+#include "ifilefinder.h"
+
+#include <Plugins/iPlugin>
+
+#include <QDir>
+#include <QRegExp>
+#include <QVector>
+#include <QThread>
+#include <QMutex>
+#include <QWaitCondition>
+#include <QStringList>
+
+
+namespace eVaf {
+
+/**
+ * Application for searching files.
+ */
+namespace FileFinder {
+
+/**
+ * Module that implements the engine for searching files.
+ */
+namespace Engine {
+
+/**
+ * Internal implementation of the FileFinder engine.
+ */
+namespace Internal {
+    class Engine;
+} // namespace eVaf::FileFinder::Engine::Internal
+
+/**
+ * Module for the FileFinder application that searches for files.
+ *
+ * The Module class implements the Plugins::iPlugin interface and
+ * creates the Internal::Engine object for file searching.
+ */
+class Module : public Plugins::iPlugin
+{
+    Q_OBJECT
+    Q_INTERFACES(eVaf::Plugins::iPlugin)
+
+public:
+
+    Module();
+
+    virtual ~Module();
+
+    virtual bool init(QString const & args);
+
+    virtual void done();
+
+    virtual bool isReady() const { return mReady; }
+
+
+private: // Members
+
+    /// Flag indicating that the module is ready
+    bool mReady;
+
+    /// iFileFinder interface implementation
+    Internal::Engine * mEngine;
+
+};
+
+
+namespace Internal {
+
+class Worker;
+
+/**
+ * Implements the iFileFinder interface.
+ *
+ * The Internal::Engine class implements the iFileFinder interface.
+ * Searching for files is done in a separate worker thread Internal::Worker.
+ */
+class Engine : public iFileFinder
+{
+    Q_OBJECT
+    Q_INTERFACES(eVaf::FileFinder::iFileFinder)
+
+public:
+
+    Engine();
+
+    virtual ~Engine();
+
+    bool init();
+
+    void done();
+
+    virtual void search(QString const & dir, bool recursive, Filter const & filter);
+
+    virtual void cancel();
+
+    virtual bool busy() const;
+
+
+private: // Members
+
+    /// Worker thread
+    Worker * mWorker;
+
+};
+
+/**
+ * A chain of QRegExp patterns.
+ */
+class RegExpChain
+{
+public:
+
+    RegExpChain()
+        : mValid(false)
+    {}
+
+    ~RegExpChain();
+
+    void setPattern(QString const & pattern);
+
+    void clear();
+
+    bool isEmpty() const { return mPatterns.isEmpty(); }
+
+    bool isValid() const { return mValid; }
+
+    bool exactMatch(QString const & str) const;
+
+
+private:
+
+    QVector<QRegExp *> mPatterns;
+
+    bool mValid;
+
+    /**
+     * Splits the string str into individual patterns separated by commas
+     * @param str Input string
+     * @return List of individual patterns
+     *
+     * The split() function splits the string str into individual patterns. Patterns are
+     * separated with commas. To use the comma as part of the pattern, escape it with '\'.
+     */
+    QStringList split(QString const & str);
+};
+
+/**
+ * Worker thread searching for files.
+ * 
+ * The Worker class is a separate thread that searches for files and then emits
+ * the found() signal on every file found.
+ */
+class Worker : public QThread
+{
+    Q_OBJECT
+
+public:
+
+    Worker(QObject * parent = 0);
+
+    /**
+     * Starts a new search.
+     * @param dir Directory where to search
+     * @param recursive If true, searches recurively in sub-directories
+     * @param filter Search filter
+     * 
+     * The search() function starts a new search. If a search is already ongoing,
+     * cancels it and starts a new one.
+     * 
+     * Search results are reported back with the found() signal and the finished()
+     * signal indicates that the search is done.
+     */
+    void search(QString const & dir, bool recursive, Filter const & filter);
+
+    /**
+     * Indicates that a search is ongoing and the worker thread busy.
+     */
+    bool busy() const;
+
+    /**
+     * Cancels an ongoing search.
+     */
+    void cancel();
+
+    /**
+     * Stops and terminates the worker thread.
+     */
+    void stop();
+
+
+signals:
+
+    /**
+     * A file was found during the search.
+     * @param fileName Name of the file with a path relative to the search directory
+     * @param dir Search directory
+     */
+    void found(QString const & fileName, QString const & dir);
+
+    /**
+     * Signal indicating that a search is finished.
+     * @param canceled True if the search was canceled instead of finished
+     */
+    void finished(bool canceled);
+
+
+protected:
+
+    virtual void run();
+
+
+private: // Members
+
+    /// Size of the read buffer
+    static int const ReadBufferSize;
+
+    /// RW access lock
+    mutable QMutex mLock;
+
+    /// Wait for something to do
+    QWaitCondition mSomethingToDo;
+
+    QString mNewDir;
+    QDir mDir;
+
+    bool mNewRecursive;
+    bool mRecursive;
+
+    Filter mNewFilter;
+    RegExpChain mRxIncludeNames;
+    RegExpChain mRxExcludeNames;
+    QRegExp mRxIncludeContent;
+    QRegExp mRxExcludeContent;
+
+    bool mDoSearch;
+    
+    bool mDoTerminate;
+
+    bool mDoCancel;
+
+    bool mBusy;
+
+
+private: // Methods
+
+    /**
+     * Searches for files in the given directory
+     * @param path Path to the directory
+     *
+     * The recursiveSearch() function searches for files in the given directory and emits found()
+     * signals for every file found. If the mRecursive flag is set to true, searches recurively
+     * in all the sub-directories.
+     */
+    void recursiveSearch(QString const & path);
+
+};
+
+} // namespace eVaf::FileFinder::Engine::Internal
+} // namespace eVaf::FileFinder::Engine
+} // namespace eVaf::FileFinder
+} // namespace eVaf
+
+#endif // engine.h
diff --git a/src/apps/FileFinder/Engine/iFileFinder b/src/apps/FileFinder/Engine/iFileFinder
new file mode 100644 (file)
index 0000000..07999fa
--- /dev/null
@@ -0,0 +1 @@
+#include "ifilefinder.h"
diff --git a/src/apps/FileFinder/Engine/ifilefinder.h b/src/apps/FileFinder/Engine/ifilefinder.h
new file mode 100644 (file)
index 0000000..7c0380e
--- /dev/null
@@ -0,0 +1,137 @@
+/**
+ * @file FileFinder/Engine/ifilefinder.h
+ * @brief Interface for the file finder engine
+ * @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.
+ */
+
+#ifndef __FILEFINDER_ENGINE_IFILEFINDER_H
+#  define __FILEFINDER_ENGINE_IFILEFINDER_H
+
+#include <QObject>
+#include <QString>
+
+namespace eVaf {
+namespace FileFinder {
+
+/**
+ * File filter defining patterns for file names and contents.
+ *
+ * File name patterns are wildcards (QRegExp::WildcardUnix). Multiple patterns can be separated by comma like,
+ * for example, "*.cpp,*.h". To include a comma in the pattern, escape it with '\'.
+ *
+ * Content patterns are regular expressions (QRegExp::RegExp).
+ * 
+ * A file matches the filter if:
+ * @li file name matches the includeNames pattern or the includeNames pattern is empty;
+ * @li and; file name does not match the excludeNames pattern or the excludeNames pattern is empty;
+ * @li and; file content matches the includeContent pattern or the includeContent pattern is empty;
+ * @li and; file content does not match the excludeContent pattern or the excludeContent patytern is empty.
+ */
+struct Filter
+{
+    Filter()
+    {}
+
+    Filter(QString const & in, QString const & en, QString const & ic, QString const & ec)
+        : includeNames(in)
+        , excludeNames(en)
+        , includeContent(ic)
+        , excludeContent(ec)
+    {}
+
+    /// QRegExp expression specifying file names that are included in the search result
+    QString includeNames;
+
+    /// QRegExp expression specifying file names that are excluded from the search result
+    QString excludeNames;
+
+    /// QRegExp expression specifying file content that is included in the search result
+    QString includeContent;
+
+    /// QRegExp expression specifying file content that is excluded from the search result
+    QString excludeContent;
+};
+
+/**
+ * File finder interface.
+ *
+ * The iFileFinder interface is used to search for files using name and content filters.
+ */
+class iFileFinder : public QObject
+{
+    Q_OBJECT
+
+public:
+
+    /// Interface constructor
+    iFileFinder() : QObject() {}
+
+    /// Empty virtual destructor
+    virtual ~iFileFinder() {}
+
+    /**
+     * Starts a file search in the directory dir using filter.
+     * @param dir Directory where to search
+     * @param recursive If True, searches also in sub-directories
+     * @param filter File name and content filter
+     *
+     * The search() function searches for files matching the given filter. The search is started
+     * in the directory dir and continues recursively into sub-directories if the recursive flag
+     * is set to true.
+     *
+     * The function is non-blocking and returns immediately. Results of the search are reported
+     * with found() signals and the finished() signal indicates that the search is either finished
+     * or canceled.
+     *
+     * If a new search is started before the current search is finished, then the current search is canceled.
+     */
+    virtual void search(QString const & dir, bool recursive, Filter const & filter) = 0;
+
+    /**
+     * Cancels an ongoing search.
+     */
+    virtual void cancel() = 0;
+
+    /**
+     * Indicates that a search is ongoing
+     */
+    virtual bool busy() const = 0;
+
+
+signals:
+
+    /**
+     * Signal emitted for every file found during the search.
+     * @param fileName name of the file with a path relative to the search directory
+     * @param dir Search directory
+     */
+    void found(QString const & fileName, QString const & dir);
+
+    /**
+     * Signal emitted when the search is finished
+     * @param canceled True if the search was canceled instead of finished
+     */
+    void finished(bool canceled);
+
+};
+
+
+} // namespace eVaf::FileFinder
+} // namespace eVaf
+
+Q_DECLARE_INTERFACE(eVaf::FileFinder::iFileFinder, "eVaf.FileFinder.iFileFinder/1.0")
+
+#endif // ifilefinder.h
diff --git a/src/apps/FileFinder/Engine/version.h b/src/apps/FileFinder/Engine/version.h
new file mode 100644 (file)
index 0000000..5e2f8ae
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * @file FileFinder/Engine/version.h
+ * @brief Version information for eVaf modules
+ * @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.
+ */
+
+#ifndef __FILEFINDER_ENGINE_VERSION_H
+#  define __FILEFINDER_ENGINE_VERSION_H
+
+#include <version_rc.h>
+
+/**
+ * Module/library version number in the form major,minor,release,build
+ */
+#define VER_FILE_VERSION                0,1,1,1
+
+/**
+ * Module/library version number in the string format (shall end with \0)
+ */
+#define VER_FILE_VERSION_STR            "0.1.1.1\0"
+
+/**
+ * Module/library name (shall end with \0)
+ */
+#define VER_MODULE_NAME_STR             "FileFinderEngine\0"
+
+/**
+ * Module type (see version_rc.h for all the types)
+ */
+#define VER_MODULE_TYPE                 MT_GENERIC
+
+/**
+ * Module type in the string format (see version_rc for all the types)
+ */
+#define VER_MODULE_TYPE_STR             MT_GENERIC
+
+/**
+ * Original file name for windows (shall end with \0)
+ */
+#define VER_ORIGINAL_FILE_NAME_STR      "FileFinderEngine.dll\0"
+
+/**
+ * Description of the module/library (shall end with \0)
+ */
+#define VER_FILE_DESCRIPTION_STR         "Search engine for the FileFinder application.\0"
+
+#endif // version.h
diff --git a/src/apps/FileFinder/Engine/version.rc b/src/apps/FileFinder/Engine/version.rc
new file mode 100644 (file)
index 0000000..33672fb
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * @file PswGen/Generator/version.rc
+ * @brief Windows resource file with module/library version information.
+ * @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 "version.h"
+#include <version_rc.h>
+#include <winver.h>
+
+
+VS_VERSION_INFO VERSIONINFO
+        FILEVERSION VER_FILE_VERSION
+        PRODUCTVERSION VER_PRODUCT_VERSION
+        FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+        FILEFLAGS VS_FF_DEBUG
+#else
+        FILEFLAGS 0x0L
+#endif
+        FILEOS VOS__WINDOWS32
+        FILETYPE VFT_DLL
+        FILESUBTYPE 0x0L
+        BEGIN
+                BLOCK "StringFileInfo"
+                BEGIN
+                        BLOCK "040904B0"
+                        BEGIN
+                                VALUE "CompanyName", VER_COMPANY_NAME_STR
+                                VALUE "FileDescription", VER_FILE_DESCRIPTION_STR
+                                VALUE "FileVersion", VER_FILE_VERSION_STR
+                                VALUE "LegalCopyright", VER_LEGAL_COPYRIGHT_STR
+                                VALUE "OriginalFilename", VER_ORIGINAL_FILE_NAME_STR
+                                VALUE "ProductName", VER_PRODUCT_NAME_STR
+                                VALUE "ProductVersion", VER_PRODUCT_VERSION_STR
+                                VALUE "Build Date", VER_PRODUCT_DATE_STR
+                                VALUE "Module Name", VER_MODULE_NAME_STR
+                                VALUE "Module Type", VER_MODULE_TYPE_STR
+                        END
+                END
+        END
diff --git a/src/apps/FileFinder/GUI/CMakeLists.txt b/src/apps/FileFinder/GUI/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a29d09f
--- /dev/null
@@ -0,0 +1,41 @@
+# Name of the target
+set(TARGET FileFinderGui)
+
+# Qt modules
+include(${QT_USE_FILE})
+
+# Include files
+include_directories(${eVaf_INCLUDE})
+
+# Required eVaf libraries
+set(eVaf_LIBRARIES CommonLib PluginsLib)
+
+# Source files
+set(SRCS
+    gui.cpp
+)
+
+# Header files for the meta-object compiler
+set(MOC_HDRS
+    gui.h
+)
+
+# Resources
+#set(RCCS
+#    gui.qrc
+#)
+
+# Version info resource file for Windows builds
+if(WIN32)
+    set(SRCS ${SRCS} version.rc)
+endif(WIN32)
+
+qt4_add_resources(RCC_SRCS ${RCCS})
+
+qt4_wrap_cpp(MOC_SRCS ${MOC_HDRS})
+
+add_library(${TARGET} SHARED ${SRCS} ${MOC_SRCS} ${RCC_SRCS})
+
+target_link_libraries(${TARGET} ${QT_LIBRARIES} ${eVaf_LIBRARIES})
+
+install(TARGETS ${TARGET} DESTINATION bin)
diff --git a/src/apps/FileFinder/GUI/gui.cpp b/src/apps/FileFinder/GUI/gui.cpp
new file mode 100644 (file)
index 0000000..a849da9
--- /dev/null
@@ -0,0 +1,376 @@
+/**
+ * @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 "version.h"
+
+#include "Engine/iFileFinder"
+
+#include <Common/Globals>
+#include <Common/iLogger>
+#include <Common/iRegistry>
+#include <Common/iApp>
+#include <SdiWindow/iSdiWindow>
+
+#include <QtGui>
+
+VER_EXPORT_VERSION_INFO()
+Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR, eVaf::FileFinder::GUI::Module)
+
+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<QPushButton *> buttons = qFindChildren<QPushButton *>(this);
+                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();
+    }
+}
+
+
+//-------------------------------------------------------------------
+
+FileFinder::GUI::Module::Module()
+    : Plugins::iPlugin()
+    , mReady(false)
+    , mFinder(0)
+    , mOpenFileAction(0)
+    , mOpenDirectoryAction(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<FileFinder::iFileFinder>("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<SdiWindow::iSdiWindow>("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->addWidget(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;
+
+    /*
+     * 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)
+        t.append(wDirectory->itemText(i));
+    settings.setValue("FileFinder/Directories", t);
+
+    t.clear();
+    for (int i = 0; i < wIncludeNames->count(); ++i)
+        t.append(wIncludeNames->itemText(i));
+    settings.setValue("FileFinder/IncludeNames", t);
+
+    t.clear();
+    for (int i = 0; i < wExcludeNames->count(); ++i)
+        t.append(wExcludeNames->itemText(i));
+    settings.setValue("FileFinder/ExcludeNames", t);
+
+    t.clear();
+    for (int i = 0; i < wIncludeContent->count(); ++i)
+        t.append(wIncludeContent->itemText(i));
+    settings.setValue("FileFinder/IncludeContent", t);
+
+    t.clear();
+    for (int i = 0; i < wExcludeContent->count(); ++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());
+
+    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);
+    l->setBuddy(wDirectory);
+    hbox->addWidget(wDirectory);
+
+    QPushButton * btn = new QPushButton(tr("&Browse"));
+    connect(btn, SIGNAL(clicked()), this, SLOT(browseDirectory()));
+    hbox->addWidget(btn);
+
+    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("&not:"));
+    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->addAction(mOpenFileAction);
+    wResults->addAction(mOpenDirectoryAction);
+    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);
+
+    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()));
+}
+
+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();
+        
+        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)
+
+    wFind->setText(tr("&Search"));
+}
+
+void FileFinder::GUI::Module::currentRowChanged(int currentRow)
+{
+    mOpenFileAction->setEnabled(currentRow >= 0);
+    mOpenDirectoryAction->setEnabled(currentRow >= 0);
+}
+
+void FileFinder::GUI::Module::openFile(QModelIndex const & index)
+{
+    Q_UNUSED(index)
+    if (wResults->currentItem())
+        QDesktopServices::openUrl(QUrl(QString("file:///%1").arg(wResults->currentItem()->text())));
+}
+
+void FileFinder::GUI::Module::openDirectory()
+{
+    if (wResults->currentItem()) {
+        QFileInfo fi(wResults->currentItem()->text());
+        QDesktopServices::openUrl(QUrl(QString("file:///%1").arg(fi.path())));
+    }
+}
diff --git a/src/apps/FileFinder/GUI/gui.h b/src/apps/FileFinder/GUI/gui.h
new file mode 100644 (file)
index 0000000..809dab1
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * @file FileFinder/GUI/gui.h
+ * @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.
+ */
+
+#ifndef __FILEFINDER_GUI_GUI_H
+#  define __FILEFINDER_GUI_GUI_H
+
+#include <Plugins/iPlugin>
+
+#include <QObject>
+#include <QString>
+#include <QModelIndex>
+#include <QWidget>
+
+class QWidget;
+class QCheckBox;
+class QComboBox;
+class QPushButton;
+class QListWidget;
+class QAction;
+
+namespace eVaf {
+namespace SdiWindow {
+    struct iSdiWindow;    
+} // namespace eVaf::SdiWindow
+namespace FileFinder {
+    struct iFileFinder;
+namespace GUI {
+
+namespace Internal {
+
+/**
+ * Main widget for the FileFinder window
+ */
+class MainWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+
+    MainWidget(QWidget * parent = 0)
+        : QWidget(parent)
+    {}
+
+    virtual void keyPressEvent(QKeyEvent * e);
+
+
+signals:
+
+    /**
+     * Request to close the windows/application
+     */
+    void quit();
+
+};
+    
+} // namespace eVaf::FileFinder::GUI::Internal
+
+/**
+ * Graphical User Interface for the FileFinder application.
+ *
+ * This module adds a GUI window to the FileFinder application using the SdiWindow module.
+ */
+class Module : public Plugins::iPlugin
+{
+    Q_OBJECT
+    Q_INTERFACES(eVaf::Plugins::iPlugin)
+
+public:
+
+    Module();
+
+    virtual ~Module();
+
+    virtual bool init(QString const & args);
+
+    virtual void done();
+
+    virtual bool isReady() const { return mReady; }
+
+
+private slots:
+
+    void browseDirectory();
+
+    void find();
+
+    void found(QString const & file, QString const & dir);
+
+    void finished(bool);
+
+    void currentRowChanged(int currentRow);
+
+    void openFile(QModelIndex const & index = QModelIndex());
+
+    void openDirectory();
+
+
+private: // Members
+
+    /// Flag indicating that the module is ready
+    bool mReady;
+
+    /// The iFileFinder interface
+    eVaf::FileFinder::iFileFinder * mFinder;
+
+    /// Actions
+    QAction * mOpenFileAction;
+    QAction * mOpenDirectoryAction;
+
+    /// Widgets on the screen
+    Internal::MainWidget * wMain;
+    QComboBox * wDirectory;
+    QCheckBox * wRecursive;
+    QComboBox * wIncludeNames;
+    QComboBox * wExcludeNames;
+    QComboBox * wIncludeContent;
+    QComboBox * wExcludeContent;
+    QListWidget * wResults;
+    QPushButton * wFind;
+
+
+private: // Methods
+
+    void createWidgets();
+
+    void createActions();
+
+    void saveHistory();
+
+    void loadHistory();
+
+};
+    
+} // namespace eVaf::FileFinder::GUI
+} // namespace eVaf::FileFinder
+} // namespace eVaf
+
+#endif // gui.h
diff --git a/src/apps/FileFinder/GUI/gui.qrc b/src/apps/FileFinder/GUI/gui.qrc
new file mode 100644 (file)
index 0000000..ef1de7a
--- /dev/null
@@ -0,0 +1,4 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/FileFinder">
+</qresource>
+</RCC>
diff --git a/src/apps/FileFinder/GUI/version.h b/src/apps/FileFinder/GUI/version.h
new file mode 100644 (file)
index 0000000..745d9c7
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * @file FileFinder/GUI/version.h
+ * @brief Version information for eVaf modules
+ * @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.
+ */
+
+#ifndef __FILEFINDER_GUI_VERSION_H
+#  define __FILEFINDER_GUI_VERSION_H
+
+#include <version_rc.h>
+
+/**
+ * Module/library version number in the form major,minor,release,build
+ */
+#define VER_FILE_VERSION                0,1,1,1
+
+/**
+ * Module/library version number in the string format (shall end with \0)
+ */
+#define VER_FILE_VERSION_STR            "0.1.1.1\0"
+
+/**
+ * Module/library name (shall end with \0)
+ */
+#define VER_MODULE_NAME_STR             "FileFinderGui\0"
+
+/**
+ * Module type (see version_rc.h for all the types)
+ */
+#define VER_MODULE_TYPE                 MT_GENERIC
+
+/**
+ * Module type in the string format (see version_rc for all the types)
+ */
+#define VER_MODULE_TYPE_STR             MT_GENERIC
+
+/**
+ * Original file name for windows (shall end with \0)
+ */
+#define VER_ORIGINAL_FILE_NAME_STR      "FileFinderGui.dll\0"
+
+/**
+ * Description of the module/library (shall end with \0)
+ */
+#define VER_FILE_DESCRIPTION_STR         "GUI for the FileFinder application.\0"
+
+#endif // version.h
diff --git a/src/apps/FileFinder/GUI/version.rc b/src/apps/FileFinder/GUI/version.rc
new file mode 100644 (file)
index 0000000..33672fb
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * @file PswGen/Generator/version.rc
+ * @brief Windows resource file with module/library version information.
+ * @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 "version.h"
+#include <version_rc.h>
+#include <winver.h>
+
+
+VS_VERSION_INFO VERSIONINFO
+        FILEVERSION VER_FILE_VERSION
+        PRODUCTVERSION VER_PRODUCT_VERSION
+        FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+        FILEFLAGS VS_FF_DEBUG
+#else
+        FILEFLAGS 0x0L
+#endif
+        FILEOS VOS__WINDOWS32
+        FILETYPE VFT_DLL
+        FILESUBTYPE 0x0L
+        BEGIN
+                BLOCK "StringFileInfo"
+                BEGIN
+                        BLOCK "040904B0"
+                        BEGIN
+                                VALUE "CompanyName", VER_COMPANY_NAME_STR
+                                VALUE "FileDescription", VER_FILE_DESCRIPTION_STR
+                                VALUE "FileVersion", VER_FILE_VERSION_STR
+                                VALUE "LegalCopyright", VER_LEGAL_COPYRIGHT_STR
+                                VALUE "OriginalFilename", VER_ORIGINAL_FILE_NAME_STR
+                                VALUE "ProductName", VER_PRODUCT_NAME_STR
+                                VALUE "ProductVersion", VER_PRODUCT_VERSION_STR
+                                VALUE "Build Date", VER_PRODUCT_DATE_STR
+                                VALUE "Module Name", VER_MODULE_NAME_STR
+                                VALUE "Module Type", VER_MODULE_TYPE_STR
+                        END
+                END
+        END