]> gitweb.hamatoma.de Git - reqt/commitdiff
reidos navigation works
authorhama <hama@siduction.net>
Sun, 1 Nov 2015 22:37:08 +0000 (23:37 +0100)
committerhama <hama@siduction.net>
Sun, 1 Nov 2015 22:37:08 +0000 (23:37 +0100)
13 files changed:
appl/reidos/idosmain.cpp
base/ReFileUtils.cpp
base/ReFileUtils.hpp
base/ReMatcher.cpp
base/ReMatcher.hpp
base/rebase.hpp
cunit/allTests.cpp
cunit/cuReFileUtils.cpp
gui/ReGuiValidator.cpp
guiwidget/ReFileTable.cpp
guiwidget/ReFileTable.hpp
os/ReFileSystem.cpp
os/ReFileSystem.hpp

index b36c4813ee8e879893b5a6daadfb5091d6951e33..fd9440481347fa5497756d0bb8de0f9cba91b107 100644 (file)
@@ -22,12 +22,15 @@ IDosMain::IDosMain(const QString& startDir, const QString& homeDir,
        ui->setupUi(this);
        initializeHome();
        m_statusMessage = new QLabel(tr("Welcome at reidos"));
+       ui->statusBar->addWidget(m_statusMessage);
        if (!startDir.isEmpty())
           ui->fileTableTop->comboBoxPath->setCurrentText(startDir);
        ui->fileTableTop->fileSystem = new ReLocalFileSystem("/", m_logger);
        ui->fileTableTop->fillTable();
+       ui->fileTableTop->announcer = this;
        ui->fileTableBottom->fileSystem = new ReLocalFileSystem("/", m_logger);
        ui->fileTableBottom->fillTable();
+       ui->fileTableTop->announcer = this;
        QString dir(ui->fileTableTop->comboBoxPath->currentText());
        if (dir.isEmpty())
                dir = startDir;
index dc4909444620c9ba48bbb6bf548795d3ed520241..dd93aec7c96d6382c724b27902d583bc154282ed 100644 (file)
@@ -67,7 +67,7 @@ QByteArray ReFileUtils::pathAppend(const char* base, const char* path) {
        } else {
                rc = path;
        }
-       return rc = cleanPath(rc);
+       return cleanPath(rc.constData());
 }
 
 /**
@@ -296,7 +296,8 @@ QString ReFileUtils::parentOf(const QString& filename) {
 
 /** Normalizes a file path.
  *
- * Removes duplicated slashes and "." and "..", but not leading ".."
+ * Removes duplicated slashes and "." and "..", but not leading "..".
+ * Change the 2nd separator to the native separator, e.g. "/" to "\\"
  *
  * @param path path to clean
  * @return             the path without duplicated separators and "." and ".."
@@ -308,60 +309,77 @@ QByteArray ReFileUtils::cleanPath(const char* path) {
        int minLength = 0;
 #ifdef __WIN32__
        // UNC path, e.g. "\\server\share"?
-       if (path[0] == OS_SEPARATOR && path[1] == OS_SEPARATOR) {
+       if ((path[0] == OS_SEPARATOR || path[0] == OS_2nd_SEPARATOR)
+                       && (path[1] == OS_SEPARATOR || path[1] == OS_2nd_SEPARATOR)) {
                rc.append("\\\\");
                path += 2;
                minLength = 2;
        }
 #endif
-       const char* ptr;
-       if (path[0] == OS_SEPARATOR) {
-               rc.append(OS_SEPARATOR);
+       char cc = *path;
+       int startNode = 0;
+       if (cc == OS_SEPARATOR || cc == OS_2nd_SEPARATOR){
                path++;
+               startNode++;
+               rc.append(OS_SEPARATOR);
        }
-       while ((ptr = strchr(path, OS_SEPARATOR)) != NULL) {
+       while ((cc = *path++) != '\0') {
+               if (cc != OS_SEPARATOR && cc != OS_2nd_SEPARATOR)
+                       rc.append(cc);
                // ignore duplicated slashes:
-               if (ptr != path) {
-                       int length = ptr - path;
-                       if (length == 1 && path[0] == '.') {
-                               // ignore ".": do nothing
-                       } else if (length == 2 && path[0] == '.' && path[1] == '.') {
+               else if (rc.length() > 0 && rc.at(rc.length() - 1) != OS_SEPARATOR){
+                       int length = rc.length() - startNode;
+                       if (length == 1 && rc.at(startNode) == '.') {
+                               // ignore ".": remove it:
+                               rc.resize(startNode);
+                       } else if (length == 2 && rc.at(startNode) == '.' &&rc.at(startNode + 1) == '.') {
+                               // remove "..":
+                               rc.resize(startNode);
                                // remove the last slash and node
                                if (rc.length() > minLength) {
                                        rc.resize(rc.size() - 1);
                                        int ix = rc.lastIndexOf(OS_SEPARATOR);
                                        if (ix > minLength)
                                                rc.resize(ix + 1);
+                                       startNode = rc.length();
                                }
-
                        } else {
-                               // copy with separator:
-                               rc.append(path, length + 1);
+                               rc.append(OS_SEPARATOR);
+                               startNode = rc.length();
                        }
-
                }
-               path = ptr + 1;
        }
-       if (path[0] != '\0') {
-               if (path[0] == '.' && path[1] == '\0') {
-                       if (rc.size() == 0)
-                               rc.append('.');
-               } else if (path[0] == '.' && path[1] == '.' && path[2] == '\0' && rc.length() > 0) {
-                       // remove the last slash and node
-                       if (rc.size() > minLength) {
-                               rc.resize(rc.size() - 1);
-                               int ix = rc.lastIndexOf(OS_SEPARATOR);
-                               if (ix > minLength)
-                                       rc.resize(ix);
-                       }
-               } else {
-                       // copy with separator:
-                       rc.append(path);
+       length = rc.length() - startNode;
+       if (length == 1 && rc.at(startNode) == '.') {
+               // ignore ".": remove it:
+               rc.resize(startNode);
+       } else if (length == 2 && rc.at(startNode) == '.'
+                          && startNode > 0 &&rc.at(startNode + 1) == '.') {
+               // remove "..":
+               rc.resize(startNode);
+               // remove the last slash and node
+               if (rc.length() > minLength) {
+                       rc.resize(rc.size() - 1);
+                       int ix = rc.lastIndexOf(OS_SEPARATOR);
+                       if (ix > minLength)
+                               rc.resize(ix);
                }
        }
        return rc;
 }
 
+/** Normalizes a file path.
+ *
+ * Removes duplicated slashes and "." and "..", but not leading "..".
+ * Change the 2nd separator to the native separator, e.g. "/" to "\\"
+ *
+ * @param path path to clean
+ * @return             the path without duplicated separators and "." and ".."
+ */
+QString ReFileUtils::cleanPath(const QString& path) {
+       return (QString) cleanPath(path.toUtf8().constData());
+}
+
 /**
  * Reads a string from a given file.
  *
index 8fa57c4c84cba1f082690458f2016876727832c5..1de0e252d65373f5e448f43fbdcd2e3b9516b708 100644 (file)
@@ -31,6 +31,7 @@ public:
        static bool deleteTree(const QString& path, bool withBase,
                ReLogger* logger);
        static QByteArray cleanPath(const char* path);
+       static QString cleanPath(const QString& path);
        static QString extensionOf(const QString& filename);
        static QByteArray extensionOf(const char* filename);
        static bool isAbsolutPath(const QString& path);
index 7506aa4343ea1ddc76c5fe86d8a9bef55c510816..9ed1c913a5345446c207b368dda93ffbfd7c2b6b 100644 (file)
@@ -273,7 +273,7 @@ bool ReListMatcher::empty() const {
  *                             matches the text<br>
  *                             <code>false</code>: none of the patterns matches
  */
-bool ReListMatcher::matches(const QString& text) {
+bool ReListMatcher::matches(const QString& text) const {
        QList<ReMatcher*>::const_iterator it;
        bool rc = m_list.size() == 0;
        for (it = m_list.cbegin(); !rc && it != m_list.cend(); ++it) {
@@ -405,7 +405,7 @@ const ReListMatcher& ReIncludeExcludeMatcher::includes() const {
  * @return                             <code>true</code>: at least one of the include patterns
  *                                             matches and none of the exclude patterns matches
  */
-bool ReIncludeExcludeMatcher::matches(const QString& text, bool excludeToo) {
+bool ReIncludeExcludeMatcher::matches(const QString& text, bool excludeToo) const {
        bool rc = m_includes.matches(text);
        if (rc && excludeToo && !m_excludes.empty())
                rc = !m_excludes.matches(text);
@@ -449,6 +449,12 @@ void ReIncludeExcludeMatcher::setPatterns(const QString& patterns,
                }
                start = ix + 1;
        }
+       if (patterns.length() > start){
+               if (patterns.at(start) == excludeMarker)
+                       excludes.append(patterns.mid(start + 1));
+               else
+                       includes.append(patterns.mid(start));
+       }
        m_includes.setPatterns(includes, m_includes.caseSensivitiy(),
                                                   m_includes.anchored());
        m_excludes.setPatterns(excludes, m_excludes.caseSensivitiy(),
index 4c736582e76847f382d9dbb2caec2ec7d83cc6fa..57c43b253c850696183fffd4f19439f64d96dddf 100644 (file)
@@ -53,7 +53,7 @@ public:
        bool allMatching() const;
        Qt::CaseSensitivity caseSensivitiy() const;
        bool empty() const;
-       bool matches(const QString& text);
+       bool matches(const QString& text) const;
        const QStringList& patterns() const;
        void setCaseSensivitiy(const Qt::CaseSensitivity& caseSensivitiy);
        void setPatterns(const QStringList& patterns,
@@ -89,7 +89,7 @@ public:
                        Qt::CaseSensitive, bool anchored = false);
 public:
        Qt::CaseSensitivity caseSensivitiy() const;
-       bool matches(const QString& text, bool excludeToo = true);
+       bool matches(const QString& text, bool excludeToo = true) const;
        const ReListMatcher& includes() const;
        const ReListMatcher& excludes() const;
        void setCaseSensivitiy(const Qt::CaseSensitivity& caseSensivitiy);
index 322ccd7575b16998c548ace95c9fee0ee25d34f4..0f265c3d79651a440723aaf9cabf66d3e799c52c 100644 (file)
@@ -62,12 +62,16 @@ typedef QString ReString;
 #define _strcasecmp strcasecmp
 #define OS_SEPARATOR '/'
 #define OS_SEPARATOR_STR "/"
+#define OS_2nd_SEPARATOR '\\'
+#define OS_2nd_SEPARATOR_STR "\\"
 #define _mkdir(path) mkdir(path, -1)
 #define _memicmp memicmp
 #else
 #define _strcasecmp _stricmp
 #define OS_SEPARATOR '\\'
 #define OS_SEPARATOR_STR "\\"
+#define OS_2nd_SEPARATOR '/'
+#define OS_2nd_SEPARATOR_STR "/"
 #endif
 
 #define UNUSED_VAR(var) (void) var
index dbfea147fd37b5c80bc64b3a6b604afc402c6221..499b20b89c17c92399e5da3a5f7759c66ee7b034 100644 (file)
@@ -37,9 +37,9 @@ static void testBase() {
        void testReException();
        void testReQStringUtil();
        void testReStringUtil();
+       void testReFileUtils();
        void testReWriter();
        void testReFile();
-       void testReFileUtils();
        void testReMatcher();
        testReFileUtils();
        testReRandomizer();
@@ -94,8 +94,8 @@ static void testOs() {
        testReFileSystem();
 }
 void allTests() {
-       testOs();
        testBase();
+       testOs();
        testGui();
        if (s_allTest) {
                testBase();
index c3d21e4bdf7f3dcd345dd8665393ebe8e0c790f4..e58e839af94e4493f1626d5dd5f7a94fa900c20f 100644 (file)
@@ -17,7 +17,7 @@
 class TestReFileUtils: public ReTest {
 public:
        TestReFileUtils() :
-                   ReTest("ReFileUtils") {
+                       ReTest("ReFileUtils") {
                doIt();
        }
 
@@ -42,7 +42,7 @@ public:
        }
        void testTempDirEmpty() {
                QByteArray dir(
-                   ReFileUtils::tempDirEmpty("subdir2", "cuReFileUtils", true));
+                       ReFileUtils::tempDirEmpty("subdir2", "cuReFileUtils", true));
                QByteArray subdir(dir);
                subdir.append("subdirX");
                mkdir(subdir.constData(), ALLPERMS);
@@ -133,10 +133,10 @@ public:
                QByteArray fn(ReFileUtils::tempFile("timetest.txt", NULL, true));
                ReFileUtils::writeToFile(fn.constData(), "");
                QDateTime time = QDateTime::fromString("03.09.2015 07:14:24.432",
-                   "dd.MM.yyyy hh:mm:ss.zzz");
+                       "dd.MM.yyyy hh:mm:ss.zzz");
                checkT(
-                   ReFileUtils::setTimes(fn.constData(), time,
-                       ReFileUtils::m_undefinedTime, &m_logger));
+                       ReFileUtils::setTimes(fn.constData(), time,
+                               ReFileUtils::m_undefinedTime, &m_logger));
                QFileInfo info(fn);
                checkEqu(time, info.lastModified());
        }
@@ -150,12 +150,15 @@ public:
                checkEqu("x/y/z.x/", ReFileUtils::cleanPath("x//y/////z.x//"));
                // remove "./"
                checkEqu("x/y/z.x", ReFileUtils::cleanPath("./x/././y/z.x"));
+               checkEqu("/x/y/z.x", ReFileUtils::cleanPath("/x/././y/z.x"));
                // remove "..":
                // inside...
+               checkEqu("x/a/b", ReFileUtils::cleanPath("x/y/../a/b"));
                checkEqu("x/y/a/b", ReFileUtils::cleanPath("x/y/z/../a/b"));
                checkEqu("x/a/b", ReFileUtils::cleanPath("x/y/z/../../a/b"));
                // at the end..
                checkEqu("x", ReFileUtils::cleanPath("x/y/z/../.."));
+               checkEqu("x/", ReFileUtils::cleanPath("x/y/z/../../"));
                // wrong forms:
                checkEqu("..", ReFileUtils::cleanPath(".."));
                checkEqu("../..", ReFileUtils::cleanPath("../.."));
@@ -177,8 +180,8 @@ public:
                assertEquals(QString(exp), ReFileUtils::extensionOf(QString(sArg1)),
                __FILE__, lineNo);
                assertEquals(exp.constData(),
-                   ReFileUtils::extensionOf(sArg1.constData()),
-                   __FILE__, lineNo);
+                       ReFileUtils::extensionOf(sArg1.constData()),
+                       __FILE__, lineNo);
        }
 
        void testExtensionOf() {
@@ -225,11 +228,18 @@ public:
                checkNodeOf("", "", __LINE__);
        }
 
+       void testParentOf(){
+               checkEqu("/abc/", ReFileUtils::parentOf("/abc/def"));
+               checkEqu("/abc/def/x.y/", ReFileUtils::parentOf("/abc/def/x.y/"));
+               checkEqu("/", ReFileUtils::parentOf("/"));
+               checkEqu("", ReFileUtils::parentOf("abc.def"));
+       }
+
        void checkPathAppend(const char* expected, const char* arg1,
-           const char* arg2, int lineNo) {
+               const char* arg2, int lineNo) {
                assertEquals(QString(expected),
-                   ReFileUtils::pathAppend(QString(arg1), QString(arg2)),
-                   __FILE__, lineNo);
+                       ReFileUtils::pathAppend(QString(arg1), QString(arg2)),
+                       __FILE__, lineNo);
                assertEquals(expected, ReFileUtils::pathAppend(arg1, arg2),
                __FILE__, lineNo);
                QByteArray exp(expected);
@@ -239,11 +249,11 @@ public:
                sArg1.replace("/", "\\");
                sArg2.replace("/", "\\");
                assertEquals(QString(exp),
-                   ReFileUtils::pathAppend(QString(sArg1), QString(sArg2)),
-                   __FILE__, lineNo);
+                       ReFileUtils::pathAppend(QString(sArg1), QString(sArg2)),
+                       __FILE__, lineNo);
                assertEquals(exp,
-                   ReFileUtils::pathAppend(sArg1.constData(), sArg2.constData()),
-                   __FILE__, lineNo);
+                       ReFileUtils::pathAppend(sArg1.constData(), sArg2.constData()),
+                       __FILE__, lineNo);
 
        }
        void testPathAppend() {
@@ -260,10 +270,10 @@ public:
                checkPathAppend("/abc", "/", "bef", __LINE__);
        }
        void checkReplaceExt(const char* expected, const char* arg1,
-           const char* arg2, int lineNo) {
+               const char* arg2, int lineNo) {
                assertEquals(QString(expected),
-                   ReFileUtils::replaceExtension(QString(arg1), QString(arg2)),
-                   __FILE__, lineNo);
+                       ReFileUtils::replaceExtension(QString(arg1), QString(arg2)),
+                       __FILE__, lineNo);
                assertEquals(expected, ReFileUtils::replaceExtension(arg1, arg2),
                __FILE__, lineNo);
                QByteArray exp(expected);
@@ -273,11 +283,11 @@ public:
                sArg1.replace("/", "\\");
                sArg2.replace("/", "\\");
                assertEquals(QString(exp),
-                   ReFileUtils::replaceExtension(QString(sArg1), QString(sArg2)),
-                   __FILE__, lineNo);
+                       ReFileUtils::replaceExtension(QString(sArg1), QString(sArg2)),
+                       __FILE__, lineNo);
                assertEquals(exp,
-                   ReFileUtils::replaceExtension(sArg1.constData(), sArg2.constData()),
-                   __FILE__, lineNo);
+                       ReFileUtils::replaceExtension(sArg1.constData(), sArg2.constData()),
+                       __FILE__, lineNo);
 
        }
        void testReplaceExtension() {
@@ -288,10 +298,11 @@ public:
        }
 
        virtual void run() {
+               testParentOf();
+               testCleanPath();
                testReplaceExtension();
                testNodeOf();
                testExtensionOf();
-               testCleanPath();
                testSetTimes();
                testSeekTell();
                testIsAbsolutePath();
index 608cf831c33fa05fe6f46d22ed8673e4bebc3492..d98fa3bcd3de5d638495d570ed1618aeae6bd637 100644 (file)
@@ -154,6 +154,8 @@ void ReGuiValidator::setInHistory(QComboBox* combo, const QString& value) {
                }
                if (combo->count() > 20)
                        combo->removeItem(20);
+               if (combo->currentText() != value)
+                       combo->setCurrentText(value);
        }
 }
 
index c616776151f1572d7de0b5ffcf8c757ad21f6df4..c95dc1d14b5e9e9009062a4a48ae0f5ef400c574 100644 (file)
@@ -51,7 +51,8 @@ ReFileTable::ReFileTable(QWidget *parent) :
        tableWidget->setColumnWidth(MODIFIED, 175);
        connect(pushButtonUp, SIGNAL(clicked()), SLOT(pushButtonUpClicked()));
        connect(pushButtonRoot, SIGNAL(clicked()), SLOT(pushButtonRootClicked()));
-
+       connect(tableWidget, SIGNAL(cellDoubleClicked(int, int)), this,
+                       SLOT(tableDoubleClicked(int, int)));
        tableWidget->setHorizontalHeaderLabels(labels);
        tableWidget->horizontalHeader()->setStretchLastSection(true);
        tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
@@ -108,16 +109,35 @@ void ReFileTable::fillTable()
        }
 }
 
+/**
+ * Change the include/exclude patterns of the file table.
+ *
+ * @param patterns     a comma separated list of patterns
+ */
+void ReFileTable::changePatterns(const QString& patterns)
+{
+       // update the history:
+       comboText(comboBoxPatterns);
+       matcher.setPatterns(patterns, ',', '-');
+       fillTable();
+}
+
 /**
  * Changes the current directory.
  *
  * @param directory    full path of the new directory
+ * @return                     <code>true</code>: success<br>
+ *                                     <code>false</code>: error
  */
-void ReFileTable::chDir(const QString& directory){
+bool ReFileTable::changeDirectory(QString directory){
+       bool rc = true;
+       directory = ReFileUtils::cleanPath(directory);
+       ReQStringUtils::ensureLastChar(directory, OS_SEPARATOR);
        if (directory != fileSystem->directory()){
                if (directory.indexOf('*') < 0){
-                       if (fileSystem->setDirectory(directory) != ReFileSystem::EC_SUCCESS){
-                               say(LOG_ERROR, tr("unknown directory:") + " " + directory);
+                       ReFileSystem::ErrorCode rc2 = fileSystem->setDirectory(directory);
+                       if (rc2 != ReFileSystem::EC_SUCCESS){
+                               rc = say(LOG_ERROR, fileSystem->errorMessage(rc2) + " " + directory);
                        } else {
                                comboBoxPath->setCurrentText(directory);
                                // update the history:
@@ -128,6 +148,7 @@ void ReFileTable::chDir(const QString& directory){
 
                }
        }
+       return rc;
 }
 
 /**
@@ -142,21 +163,42 @@ void ReFileTable::keyPressEvent(QKeyEvent* event){
        if (sender == comboBoxPath){
                if (key == Qt::Key_Return){
                        if (modifiers == Qt::NoModifier)
-                               chDir(comboBoxPath->currentText());
+                               changeDirectory(comboBoxPath->currentText());
                }
        } else if (sender == comboBoxPatterns){
-
+               if (key == Qt::Key_Return && modifiers == Qt::NoModifier)
+                       changePatterns(comboBoxPatterns->currentText());
        } else if (sender == tableWidget){
-
+               if (key == Qt::Key_Return && modifiers == Qt::NoModifier)
+                       openEntry(tableWidget->currentRow());
        }
 
 }
+
+/**
+ * Starts the standard program for the given table entry.
+ *
+ * @param row  the row containing the entry to open
+ */
+void ReFileTable::openEntry(int row){
+       bool isDir = tableWidget->item(row, TYPE)->text().startsWith('<');
+       QString node = tableWidget->item(row, NAME)->text();
+       if (isDir){
+               changeDirectory(fileSystem->directory() + node);
+       } else {
+
+       }
+}
+
 /**
  * Handles the event push button "up" clicked()
  */
 void ReFileTable::pushButtonUpClicked()
 {
-       chDir(ReFileUtils::parentOf(comboBoxPath->currentText()));
+       QString path(fileSystem->directory());
+       path.resize(max(0, path.length() - 1));
+       if (! path.isEmpty())
+               changeDirectory(ReFileUtils::parentOf(path));
 }
 
 /**
@@ -164,7 +206,7 @@ void ReFileTable::pushButtonUpClicked()
  */
 void ReFileTable::pushButtonRootClicked()
 {
-       chDir("/");
+       changeDirectory("/");
 }
 
 /**
@@ -182,4 +224,11 @@ bool ReFileTable::say(ReLoggerLevel level, const QString& message)
        return level >= LOG_INFO;
 }
 
-
+/**
+ * Handles the double click of a table cell.
+ *
+ * @param index        the abstract index of the cell
+ */
+void ReFileTable::tableDoubleClicked(int row, int column){
+       openEntry(row);
+}
index 150749b13f2fc8ad6d311f25deff54b62dcce853..66b6cac240084794e79dbdd0df6814555ce21577 100644 (file)
@@ -26,11 +26,16 @@ public slots:
 
 public:
        void fillTable();
-       void chDir(const QString& directory);
-protected slots:
-       void keyPressEvent(QKeyEvent* event);
+       void changePatterns(const QString& patterns);
+       bool changeDirectory(QString directory);
+public:
+       virtual void keyPressEvent(QKeyEvent* event);
+public slots:
+       void tableDoubleClicked(int row, int column);
        void pushButtonUpClicked();
        void pushButtonRootClicked();
+protected:
+       void openEntry(int row);
 protected:
        QVBoxLayout* mainLayout;
        QHBoxLayout* horizontalLayout;
index bff8b785cd9fdeb36790eee5146c1d9316717d3f..33aa0fccd157addb9589a17764c5fb81083da080 100644 (file)
@@ -87,6 +87,65 @@ ReFileSystem::ErrorCode ReFileSystem::copy(ReFileMetaData& source,
        return rc;
 }
 
+/**
+ * Returns a message describing the given error code.
+ *
+ * @param errorCode    code to convert
+ * @return                     a description of the error code
+ */
+QString ReFileSystem::errorMessage(ReFileSystem::ErrorCode errorCode)
+{
+       QString rc;
+       switch(errorCode){
+       case EC_SUCCESS:
+               rc = QObject::tr("Success");
+               break;
+       case EC_PATH_NOT_FOUND:
+               rc = QObject::tr("Path not found");
+               break;
+       case EC_NOT_ACCESSIBLE:
+               rc = QObject::tr("not accessable");
+               break;
+       case EC_NOT_READABLE:
+               rc = QObject::tr("not readable");
+               break;
+       case EC_READ:
+               rc = QObject::tr("cannot read");
+               break;
+       case EC_FS_READ_ONLY:
+               rc = QObject::tr("file is read only");
+               break;
+       case EC_NOT_WRITEABLE:
+               rc = QObject::tr("file is not writeable");
+               break;
+       case EC_WRITE:
+               rc = QObject::tr("cannot write");
+               break;
+       case EC_POSITION:
+               rc = QObject::tr("cannot set new file position");
+               break;
+       case EC_ALREADY_EXISTS:
+               rc = QObject::tr("file already exists");
+               break;
+       case EC_NOT_EXISTS:
+               rc = QObject::tr("file does not exist");
+               break;
+       case EC_RENAME:
+               rc = QObject::tr("file cannot renamed");
+               break;
+       case EC_HEADER_LENGTH:
+               rc = QObject::tr("Header length mismatch");
+               break;
+       case EC_MARKER:
+               rc = QObject::tr("marker mismatch");
+               break;
+       default:
+               rc = QObject::tr("unknown error code: ") + QString::number(errorCode);
+               break;
+       }
+       return rc;
+}
+
 /**
  * Returns the name of the current directory.
  *
@@ -216,25 +275,47 @@ void ReLocalFileSystem::close() {
  * Fills a list with the items of the current directory.
  *
  * @param matcher      the matching processor
+ * @param list         OUT: the list of the found files
+ * @param options      a set (bitmap) of options, e.g. LO_FILES | LO_DIRS
  * @return                     the count of the found entries (<code>list.size()</code>)
  */
 int ReLocalFileSystem::listInfos(const ReIncludeExcludeMatcher& matcher,
-       ReFileMetaDataList& list) {
+       ReFileMetaDataList& list, ListOptions options) {
        list.clear();
+       bool withDirs = (options & LO_DIRS) != 0;
+       bool withFiles = (options & LO_FILES) != 0;
+       if (! (withDirs | withFiles))
+               withDirs = withFiles = true;
+       bool matchDirs = (options & LO_NAME_FILTER_FOR_DIRS) != 0;
+       bool earlyMatching = matchDirs || ! withDirs;
        const QStringList& patterns = matcher.includes().patterns();
        QStringList nodes =
-               patterns.size() == 0 ? m_dir.entryList() : m_dir.entryList(patterns);
+               ! earlyMatching || patterns.size() == 0
+                       ? m_dir.entryList() : m_dir.entryList(patterns);
        QStringList::const_iterator it;
        QByteArray full = m_directory.toUtf8();
        full.append(OS_SEPARATOR);
        int pathLength = full.length();
        struct stat info;
+       const ReListMatcher& excludeMatcher = matcher.excludes();
+       bool excludeActive = excludeMatcher.patterns().length() > 0;
        for (it = nodes.cbegin(); it != nodes.cend(); it++) {
                QString node = *it;
                if (node != "." &&  node != ".."){
+                       if (earlyMatching){
+                               if (excludeActive && excludeMatcher.matches(node))
+                                       continue;
+                       }
                        full.resize(pathLength);
                        full.append(node.toUtf8());
                        if (stat(full.constData(), &info) == 0) {
+                               bool isDir = S_ISDIR(info.st_mode);
+                               if (isDir && ! withDirs || ! isDir && ! withFiles)
+                                       continue;
+                               if (! earlyMatching){
+                                       if ( (! isDir || matchDirs) && ! matcher.matches(node))
+                                               continue;
+                               }
                                list.append(
                                                        ReFileMetaData(node, QDateTime::fromTime_t(info.st_mtime),
                                                                                   QDateTime::fromTime_t(info.st_ctime), info.st_uid,
index 5aad9783da96ad5616bf28fb7cb4ba080959d06b..243aa41681b7adb49cee5b38c7dd93abf7e24cbd 100644 (file)
@@ -48,12 +48,11 @@ typedef QList<ReFileMetaData> ReFileMetaDataList;
 
 class ReFileSystem {
 public:
-       enum ListOption {
+       enum ListOptions {
                LO_UNDEF = 0,
                LO_FILES = 1,
                LO_DIRS = 2,
-               LO_EXCLUDE_MATCH_FILES = 4,
-               LO_EXCLUDE_MATCH_DIRS = 8
+               LO_NAME_FILTER_FOR_DIRS = 4,
        };
 
        enum ErrorCode {
@@ -86,10 +85,12 @@ public:
        virtual const QString& directory() const;
        /** Fills a list with the items of the current directory.
         * @param matcher       the matching processor
+        * @param options       a set (bitmap) of options, e.g. LO_FILES | LO_DIRS
         * @return                      the count of the found entries (<code>list.size()</code>)
         */
        virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
-               ReFileMetaDataList& list) = 0;
+               ReFileMetaDataList& list, ListOptions opts
+                                                 = ListOptions(LO_FILES | LO_DIRS )) = 0;
        /** Creates a directory.
         * @param node  the name without path (in the current directory)
         * @return              EC_SUCCESS or error code
@@ -135,6 +136,7 @@ public:
                const QByteArray& buffer) = 0;
 public:
        virtual ErrorCode copy(ReFileMetaData& source, ReFileSystem& sourceFS);
+       virtual QString errorMessage(ErrorCode rc);
 public:
        int blocksize() const;
        bool first(const QString& pattern, ReFileMetaData& file);
@@ -187,7 +189,7 @@ public:
        // ReFileSystem interface
        virtual void close();
        virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
-               ReFileMetaDataList& list);
+               ReFileMetaDataList& list, ListOptions options);
        ErrorCode makeDir(const QString& node);
        virtual ErrorCode read(const ReFileMetaData& source, int64_t offset,
                int size, QByteArray& buffer);