]> gitweb.hamatoma.de Git - reqt/commitdiff
fix ReMatcher, improvement ReSearch
authorHamatoma <hamatoma@gmx.de>
Mon, 21 Nov 2016 23:30:41 +0000 (00:30 +0100)
committerHamatoma <hamatoma@gmx.de>
Mon, 21 Nov 2016 23:30:41 +0000 (00:30 +0100)
* ReIncludeExcludeMatcher: first char of exclude patterns now removed
* ReSearch: table is filled

13 files changed:
appl/research/filefinder.cpp [new file with mode: 0644]
appl/research/filefinder.hpp [new file with mode: 0644]
appl/research/mainwindow.cpp
appl/research/mainwindow.hpp
appl/research/mainwindow.ui
appl/research/research.hpp
appl/research/research.pro
base/ReFileSearch.cpp
base/ReFileSearch.hpp
base/ReMatcher.cpp
cunit/allTests.cpp
cunit/cuReFileSearch.cpp
cunit/cuReMatcher.cpp

diff --git a/appl/research/filefinder.cpp b/appl/research/filefinder.cpp
new file mode 100644 (file)
index 0000000..552d607
--- /dev/null
@@ -0,0 +1,80 @@
+#include "research.hpp"
+
+const int IX_NODE = 0;
+const int IX_SIZE = 1;
+const int IX_DATE = 2;
+const int IX_PATH = 3;
+
+
+/**
+ * Constructor.
+ *
+ * @param table the table for the found files
+ */
+FileFinder::FileFinder(QTableWidget& table) :
+    ReFileSearch(),
+    m_table(table),
+    m_files()
+{
+    setSearchMode(smFiles);
+}
+
+/**
+ * Adds a file to the file table.
+ *
+ * @param full  the filename with path
+ * @param path  the path of the file
+ * @param node  the filename without path
+ * @param info  the info about the file
+ */
+void FileFinder::addToTable(const QString& full, const QString &path,
+        const QString &node, const QFileInfo& info)
+{
+    if (! m_files.contains(full)){
+        int last = m_table.rowCount();
+        m_files.insert(full);
+        m_table.setRowCount(last + 1);
+        m_table.setItem(last, IX_NODE, new QTableWidgetItem(node));
+        m_table.setItem(last, IX_SIZE, new QTableWidgetItem(QString::number(info.size())));
+        QString date = info.lastModified().toString("yyyy.MM.dd hh:mm.ss");
+        m_table.setItem(last, IX_DATE, new QTableWidgetItem(date));
+        m_table.setItem(last, IX_PATH, new QTableWidgetItem(path));
+    }
+}
+
+
+/**
+ * Handle a file found by the file search criteria.
+ *
+ * @param full  the filename with path
+ * @param path  the path of the file
+ * @param node  the filename without path
+ */
+bool FileFinder::handleFile(const QString &full, const QString &path,
+        const QString &node, const QFileInfo& info)
+{
+    addToTable(full, path, node, info);
+    return true;
+}
+
+/**
+ * Searches files in a directory tree and put them into a table widget.
+ *
+ * @param baseDirectory the start directory
+ * @param patterns      the patterns describing the files to find: comma
+ *                      separated list of include patterns or exclude patterns
+ *                      (starting with '-')
+ * @param minDepth      the minimal depth of the directory tree which contain
+ *                      files to find
+ * @param maxDepth      the maximal depth of the directory tree which contain
+ *                      files to find
+ */
+void FileFinder::search(const QString &baseDirectory, const QString &patterns,
+    int minDepth, int maxDepth)
+{
+    setMinDepth(minDepth);
+    setMaxDepth(maxDepth);
+    setPatterns(patterns);
+    oneDirectory(baseDirectory, 0);
+}
+
diff --git a/appl/research/filefinder.hpp b/appl/research/filefinder.hpp
new file mode 100644 (file)
index 0000000..acfedec
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef FILEFINDER_H
+#define FILEFINDER_H
+
+
+class FileFinder : public ReFileSearch
+{
+public:
+    FileFinder( QTableWidget& m_table);
+public:
+    bool handleFile(const QString &full, const QString &path,
+        const QString &node, const QFileInfo &info);
+    void search(const QString& baseDirectory, const QString& patterns,
+                int minDepth, int maxDepth);
+public:
+    void addToTable(const QString& full, const QString &path,
+        const QString &node, const QFileInfo &info);
+private:
+    QTableWidget& m_table;
+    QSet<QString> m_files;
+};
+
+#endif // FILEFINDER_H
index 6818f0b13039c43c6d38cb2c273e439232808e5e..8ea04108557878a92d9eab1d567d619e09420528 100644 (file)
@@ -3,13 +3,16 @@
 #include "ui_mainwindow.h"
 #include "aboutdialog.hpp"
 
+#include "QFileDialog"
+
 static const char* VERSION = "2016.11.16";
 
 MainWindow::MainWindow(QApplication& application, const QString& homeDir,
                                           QWidget *parent) :
        ReGuiApplication(application, "rsearch", homeDir, 2, 10100100, "de", parent),
        ReGuiValidator(),
-       ui(new Ui::MainWindow)
+    ui(new Ui::MainWindow),
+    m_fileFinder(NULL)
 {
        ReComboBox::setDefaultHistorySize(20);
        initializeGui();
@@ -31,6 +34,12 @@ void MainWindow::initializeGui(){
        connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(onAbout()));
        connect(ui->comboBoxBaseDirectory, SIGNAL(textEdited(const QString&, const QString&)),
                        this, SLOT(textEdited(const QString&, const QString&)));
+    connect(ui->pushButtonSelectBase, SIGNAL(clicked()), this, SLOT(onSelectBaseDirectory()));
+    connect(ui->pushButtonAdd, SIGNAL(clicked()), this, SLOT(onAdd()));
+    connect(ui->pushButtonClear, SIGNAL(clicked()), this, SLOT(onClear()));
+
+    delete m_fileFinder;
+    m_fileFinder = new FileFinder(*ui->tableWidget);
 
 }
 
@@ -51,6 +60,29 @@ void MainWindow::onAboutToQuit()
        ReGuiApplication::onAboutToQuit();
 }
 
+/**
+ * Handles the click of the "Add" button.
+ */
+void MainWindow::onAdd()
+{
+    QString base = ui->comboBoxBaseDirectory->currentText();
+    if (base.isEmpty()){
+        say(LOG_ERROR, tr("missing a base directory"));
+    } else {
+        m_fileFinder->search(base, ui->comboBoxFilePatterns->currentText(),
+             atoi(ui->lineEditMaxDepth->text().toLocal8Bit().data()),
+             atoi(ui->lineEditMinDepth->text().toLocal8Bit().data()));
+    }
+}
+
+/**
+ * Handles the click of the "Clear" button.
+ */
+void MainWindow::onClear()
+{
+
+}
+
 /**
  * Set GUI elements from the queue when the GUI timer is triggered.
  */
@@ -67,6 +99,16 @@ void MainWindow::onLanguageChange()
        initializeGui();
 }
 
+/**
+ * Handles the push of the button "select directory".
+ */
+void MainWindow::onSelectBaseDirectory(){
+QString dir = QFileDialog::getExistingDirectory(this, tr("Select Directory"),
+    ui->comboBoxBaseDirectory->currentText(), QFileDialog::ShowDirsOnly);
+if (!dir.isEmpty())
+   ui->comboBoxBaseDirectory->setCurrentText(ReFileUtils::nativePath(dir));
+}
+
 /**
  * Writes a message.
  *
index 700799afa3bb04f906233004bb24283608dc3e35..61c141088860b7707285133d7ea885f6b6cb7d32 100644 (file)
@@ -7,7 +7,9 @@
 #ifndef REGUI_HPP
 #include "gui/regui.hpp"
 #endif
+#include <QMainWindow>
 
+class FileFinder;
 namespace Ui {
 class MainWindow;
 }
@@ -25,15 +27,18 @@ public:
 
 private:
        void initializeGui();
-
+    virtual void onAboutToQuit();
+    virtual void onGuiTimerUpdate();
+    virtual void onLanguageChange();
 private slots:
    void onAbout();
-   virtual void onAboutToQuit();
-   virtual void onGuiTimerUpdate();
-   virtual void onLanguageChange();
+   void onAdd();
+   void onClear();
+   void onSelectBaseDirectory();
    void textEdited(const QString& oldString, const QString& newString);
 
 private:
    Ui::MainWindow *ui;
+   FileFinder* m_fileFinder;
 };
 #endif // MAINWINDOW_H
index c35be511beacf331321bab23cf270635e26ea5bd..b944641a42939140a1277944324d61f66e74abeb 100644 (file)
@@ -84,6 +84,9 @@
                       <height>16777215</height>
                      </size>
                     </property>
+                    <property name="toolTip">
+                     <string>Starts a dialog to choose the base directory</string>
+                    </property>
                     <property name="text">
                      <string notr="true">...</string>
                     </property>
                 </item>
                 <item row="1" column="1">
                  <layout class="QHBoxLayout" name="horizontalLayout">
-                  <item>
-                   <widget class="QCheckBox" name="checkBoxRecursive">
-                    <property name="text">
-                     <string>Recursive</string>
-                    </property>
-                    <property name="checked">
-                     <bool>true</bool>
-                    </property>
-                   </widget>
-                  </item>
-                  <item>
-                   <spacer name="horizontalSpacer">
-                    <property name="orientation">
-                     <enum>Qt::Horizontal</enum>
-                    </property>
-                    <property name="sizeHint" stdset="0">
-                     <size>
-                      <width>188</width>
-                      <height>17</height>
-                     </size>
-                    </property>
-                   </spacer>
-                  </item>
                   <item>
                    <widget class="QLabel" name="label_3">
                     <property name="text">
                     </property>
                    </widget>
                   </item>
+                  <item>
+                   <spacer name="horizontalSpacer">
+                    <property name="orientation">
+                     <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                     <size>
+                      <width>188</width>
+                      <height>17</height>
+                     </size>
+                    </property>
+                   </spacer>
+                  </item>
                  </layout>
                 </item>
                 <item row="2" column="0">
                  <height>33</height>
                 </rect>
                </property>
+               <property name="toolTip">
+                <string>Adds the described files into the table below</string>
+               </property>
                <property name="text">
                 <string>&amp;Add</string>
                </property>
                  <height>33</height>
                 </rect>
                </property>
+               <property name="toolTip">
+                <string>Clears the table below</string>
+               </property>
                <property name="text">
                 <string>&amp;Clear</string>
                </property>
              <attribute name="title">
               <string>Options</string>
              </attribute>
-             <widget class="QWidget" name="">
+             <widget class="QWidget" name="layoutWidget">
               <property name="geometry">
                <rect>
                 <x>175</x>
                 <y>10</y>
                 <width>321</width>
-                <height>35</height>
+                <height>38</height>
                </rect>
               </property>
               <layout class="QHBoxLayout" name="horizontalLayout_6">
      <x>0</x>
      <y>0</y>
      <width>869</width>
-     <height>31</height>
+     <height>30</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
index eaa4d76fc5bdd47b773943788821802bb47ba68b..5f92b0510e004245f151716dd554b67447da30b5 100644 (file)
@@ -10,5 +10,5 @@
 #define RESEARCH_HPP
 #include "base/rebase.hpp"
 #include "gui/regui.hpp"
-#include <QMainWindow>
+#include "filefinder.hpp"
 #endif // RESEARCH_HPP
index d4d26ba9649d3cc1d8a5c9139772a841b0c283c0..7aaf1ad3c374d42a3e24a7916f656043daa6a153 100644 (file)
@@ -31,7 +31,8 @@ SOURCES += main.cpp \
        ../../gui/ReGuiUtils.cpp \
                mainwindow.cpp \
        aboutdialog.cpp \
-    ../../base/ReFileSearch.cpp
+    ../../base/ReFileSearch.cpp \
+    filefinder.cpp
 
 HEADERS  += mainwindow.hpp \
         ../../base/rebase.hpp \
@@ -43,7 +44,8 @@ HEADERS  += mainwindow.hpp \
        ../../gui/ReGuiUtils.hpp \
        aboutdialog.hpp \
        research.hpp \
-    ../../base/ReFileSearch.hpp
+    ../../base/ReFileSearch.hpp \
+    filefinder.hpp
 
 FORMS    += mainwindow.ui \
        aboutdialog.ui
index bfd947e1839025b9753fa15ddd8c8cda526fcd51..e2a09289bff1e65fff7e51a3097c67a82c8e7f97 100644 (file)
@@ -46,7 +46,8 @@ void ReFileSearch::oneDirectory(const QString& directory, int depth)
        QString node;
        QString full;
        QStringList dirs;
-       for (int ix = 0; ix < files.size(); ix++){
+    bool stop = false;
+    for (int ix = 0; ! stop && ix < files.size(); ix++){
                node = files[ix];
         if (node == "." || node == "..")
             continue;
@@ -60,19 +61,21 @@ void ReFileSearch::oneDirectory(const QString& directory, int depth)
                        }
                } else {
                        if (depth < m_maxDepth)
-                               dirs += full;
+                dirs += node;
 
                        if (m_searchMode == smFiles || depth < m_minDepth){
                                continue;
                        }
                }
                if (m_matcher.matches(node))
-                       handleFile(full, directory, node);
-       }
-       ++depth;
-       for (int ix = 0; ix < dirs.size(); ix++){
-               oneDirectory(directory + OS_SEPARATOR_STR + dirs[ix], depth);
+            stop = ! handleFile(full, directory, node, info);
        }
+    if (! stop){
+        ++depth;
+        for (int ix = 0; ix < dirs.size(); ix++){
+            oneDirectory(directory + OS_SEPARATOR_STR + dirs[ix], depth);
+        }
+    }
 }
 
 /**
index cd777d1808c554b3c7e4574bc8fd3c66c5c333e7..75de6333a1f660af48a400c9ae44014b3f61a973 100644 (file)
@@ -27,7 +27,18 @@ public:
 public:
        ReFileSearch();
 public:
-       virtual void handleFile(const QString& full, const QString& path, const QString& node) = 0;
+    /**
+     * Handles the found file.
+     *
+     * @param full  the filename with path
+     * @param path  the file's path
+     * @param node  the filename without path
+     * @param info  the info about the found file
+     * @return      <i>true</i>: continue searching
+     *              <i>false</i>: stop searching
+     */
+    virtual bool handleFile(const QString& full, const QString& path,
+        const QString& node, const QFileInfo& info) = 0;
        int maxDepth() const;
        int minDepth() const;
        void oneDirectory(const QString& directory, int depth);
index 5b3d9de1b6e9b94d150acb06f4bd1a3b2e07fd47..6c85d327d17845fd9a1d781c8520ec2e1501a5f4 100644 (file)
@@ -441,7 +441,7 @@ void ReIncludeExcludeMatcher::setPatterns(const QString& patterns,
                if (length > 0){
                        if (patterns.at(start) == excludeMarker){
                                if (length > 1)
-                                       excludes.append(patterns.mid(start, length - 1));
+                    excludes.append(patterns.mid(start + 1, length - 1));
                        } else {
                                includes.append(patterns.mid(start, length));
                        }
index b6dff3bfee40a833f5c691642927dcdc71203305..0f51627b99ae722b32fb40e5fc38da5ad4eaa0ae 100644 (file)
@@ -34,12 +34,12 @@ static void testBase() {
        void testReFile();
        void testReMatcher();
        testReFileSearch();
+    testReMatcher();
        testReFileUtils();
        testReQStringUtil();
        testReProgArgs();
        testReProcess();
        testReRandomizer();
-       testReMatcher();
        testReFile();
        if (s_allTest) {
                testReProcess();
index 32b4d2c49c06c76076675a83cb531ad7ad4b6d99..cad10ef665acc58bb1f115be1bac9e1bf3538384 100644 (file)
@@ -23,10 +23,15 @@ public:
        }
 
 public:
+    /**
+     * Tests the standard behaviour: all depths, only one pattern, only files.
+     */
        void testBasic() {
         m_found.clear();
-        setPatterns("test3.txt");
+        setPatterns("file3.txt");
         setSearchMode(smFiles);
+        setMaxDepth(99);
+        setMinDepth(0);
         oneDirectory(m_baseDir, 0);
         checkEqu(5, m_found.size());
         checkT(m_found.contains("file3.txt"));
@@ -35,11 +40,32 @@ public:
         checkT(m_found.contains("dir1/dir2/dir3/file3.txt"));
         checkT(m_found.contains("dir1/dir2/dir3/dir4/file3.txt"));
     }
-       virtual void handleFile(const QString& full, const QString& path, const QString& node){
+    /**
+     * Tests more features:
+     * min. depth, max. depth, multiple patterns, excluding pattern.
+     */
+    void testOneDirectoryDepthExclude(){
+        m_found.clear();
+        setPatterns("*.txt,-*1*,-*2*,-*4*,-file5.txt,dir*,-dir2");
+        setMinDepth(1);
+        setMaxDepth(3);
+        setSearchMode(smFilesAndDirs);
+        oneDirectory(m_baseDir, 0);
+        checkEqu(4, m_found.size());
+        checkT(m_found.contains("dir1/file3.txt"));
+        checkT(m_found.contains("dir1/dir2/file3.txt"));
+        checkT(m_found.contains("dir1/dir2/dir3/file3.txt"));
+        checkT(m_found.contains("dir1/dir2/dir3"));
+    }
+
+    virtual bool handleFile(const QString& full, const QString& path,
+            const QString& node, const QFileInfo& info){
+        ReUseParameter(info);
         checkEqu(full, path + OS_SEPARATOR_STR + node);
         QString relPath = full.mid(m_baseDir.length() + 1);
         relPath.replace(OS_SEPARATOR, "/");
         m_found.insert(relPath, 0);
+        return true;
        }
 private:
     void makeFile(const QString& name){
@@ -62,6 +88,7 @@ private:
 
        virtual void runTests() {
         makeTree();
+        testOneDirectoryDepthExclude();
                testBasic();
        }
 private:
index b261c0d3b232442e9e6b56788d15bc65c6cc461c..0a074851c03d68763af3e94834b9524c916e33f3 100644 (file)
@@ -164,12 +164,25 @@ public:
                checkT(matcher2.matches("abc"));
 
        }
+    void testIncludeExcludeMatcher(){
+        ReIncludeExcludeMatcher matcher;
+        matcher.setCaseSensivitiy(Qt::CaseSensitive);
+        matcher.setPatterns("a*,-*.txt,b*,-*ef*");
+        checkT(matcher.matches("abc"));
+        checkF(matcher.matches("abc.txt"));
+        checkT(matcher.matches("b"));
+        checkF(matcher.matches("b.txt"));
+        checkT(matcher.matches("bEfg"));
+        checkF(matcher.matches("efg"));
+        checkF(matcher.matches(".efg"));
+    }
 
        virtual void runTests(void) {
                testBasics();
                test0Star();
                test1Star();
                testList();
+        testIncludeExcludeMatcher();
        }
 };
 void testReMatcher() {