delete m_project;
        m_project = new Project(path, m_logger);
        int maxEntries = m_workspace->intValue("history.max_projects");
-       m_workspace->addHistoryEntry("projects", path, ';', maxEntries);
+       m_workspace->addHistoryEntry(Workspace::KEY_HISTORY_PROJECTS, path, ';',
+           maxEntries);
 }
 
 /**
        edit->setLines(m_file);
        edit->setCursorLine(0);
        int maxEntries = m_workspace->intValue("history.max_files");
-       m_workspace->addHistoryEntry("files", name, ';', maxEntries);
+       m_workspace->addHistoryEntry(Workspace::KEY_HISTORY_FILES, name, ';',
+           maxEntries);
 }
 
 /**
 
            SLOT(openLastFile()));
        connect(ui->pushButtonOpenLastProject, SIGNAL(clicked()), this,
            SLOT(openLastProject()));
+       connect(ui->lineEditFilterLastFile, SIGNAL(textChanged(QString))), this, SLOT(
+           textChanged(QString));
        Workspace* workspace = mainWindow->workspace();
        buildTableInfo(workspace, Workspace::KEY_HISTORY_FILES, true, m_files);
        buildTableInfo(workspace, Workspace::KEY_HISTORY_PROJECTS, false,
            m_projects);
        buildTable("", m_files, ui->tableWidgetFiles);
-       buildTable("", m_projects, ui->tableWidgetProjects);
+       buildTable(QString(""), m_projects, ui->tableWidgetProjects);
 }
+
+/**
+ * Destructor.
+ */
+ProjectSelection::~ProjectSelection() {
+       delete ui;
+}
+void ProjectSelection::textChangedFilterFiles(const QString& text) {
+
+}
+void ProjectSelection::textChangedFilterProjects(const QString& text) {
+
+}
+
 /**
  * Builds the table from the table using a filter expression.
  *
  * @param lines                the full table info
  * @param table                OUT: will be filled with all lines matching the filter
  */
-void ProjectSelection::buildTable(const QString* filter, QStringList& lines,
+void ProjectSelection::buildTable(const QString& filter, QStringList& lines,
     QTableWidget* table) {
        QStringList::const_iterator it;
+       int rowCount = 0;
        for (it = lines.cbegin(); it != lines.cend(); ++it) {
-               bool matches = filter->isEmpty();
+               bool matches = filter.isEmpty();
                if (!matches) {
-                       if (filter->startsWith("*")) {
+                       //@ToDo: coding
+                       if (filter.startsWith("*")) {
+
+                       } else {
+
+                       }
+               }
+               if (matches)
+                       rowCount++;
+       }
+       table->setRowCount(rowCount);
+       int row = -1;
+       for (it = lines.cbegin(); it != lines.cend(); ++it) {
+               bool matches = filter.isEmpty();
+               if (!matches) {
+                       //@ToDo: coding
+                       if (filter.startsWith("*")) {
 
                        } else {
 
                        }
                }
                if (matches) {
+                       row++;
                        QStringList cols = it->split('\t');
-
+                       for (int col = 0; col < cols.size(); col++) {
+                               QTableWidgetItem* item = table->item(row, col);
+                               if (item != NULL)
+                                       item->setText(cols.at(col));
+                               else {
+                                       item = new QTableWidgetItem(cols.at(col));
+                                       table->setItem(row, col, item);
+                               }
+                       }
                }
-
        }
 }
 
  */
 void ProjectSelection::buildTableInfo(ReSettings* settings, const char* key,
     bool withDate, QStringList& tableContent) {
+       QStringList files;
        settings->historyAsList(key, files);
        QStringList::const_iterator it;
        for (it = files.cbegin(); it != files.cend(); ++it) {
                        if (withDate)
                                info.append("\t").append(
                                    file.lastModified().toString("yyyy.mm.dd/HH:MM:SS"));
-                       info.append(file.dir());
+                       info.append("\t").append(file.path());
+                       tableContent.append(info);
                }
        }
 }
 
-/**
- * Destructor.
- */
-ProjectSelection::~ProjectSelection() {
-       delete ui;
-}
 /**
  * Shows an error message.
  *
  * Opens the selected recently opened file.
  */
 void ProjectSelection::openLastFile() {
-
+       openSelectedItem(ui->tableWidgetFiles);
 }
+
 /**
  * Opens the selected recently opened project (project directory).
  */
 void ProjectSelection::openLastProject() {
-
+       openSelectedItem(ui->tableWidgetProjects);
 }
 
+QString ProjectSelection::openSelectedItem(QTableWidget* table) {
+       int row = max(0, table->currentRow());
+       if (row < table->rowCount()) {
+               QString file;
+               int colPath = table->columnCount() - 1;
+               file = table->item(row, colPath)->text() + OS_SEPARATOR_STR
+                   + table->item(row, 0)->text();
+               ui->lineEditOpen->setText(file);
+               open();
+       }
+}
 /**
  * Selects a directory (project directory) with an open dialog.
  */
 
 
 #ifndef PROJECTSELECTION_HPP
 #define PROJECTSELECTION_HPP
-
+#include "reditor.hpp"
 #include <QDialog>
-
+#include <QTableWidget>
 namespace Ui {
 class ProjectSelection;
 }
        void selectDir();
        void selectFile();
 protected:
-       void buildTable(const QString* filter, QStringList& lines,
+       void buildTable(const QString& filter, QStringList& lines,
            QTableWidget* table);
        void buildTableInfo(ReSettings* settings, const char* key, bool withDate,
            QStringList& tableContent);
+       QString openSelectedItem(QTableWidget* table);
+       void textChangedFilterFiles(const QString& text);
+       void textChangedFilterProjecs(const QString& text);
 private:
        void error(const QString& message);
 private:
 
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>982</width>
+    <width>1034</width>
     <height>703</height>
    </rect>
   </property>
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
+     <property name="handleWidth">
+      <number>3</number>
+     </property>
      <widget class="QWidget" name="layoutWidget">
       <layout class="QVBoxLayout" name="verticalLayout">
        <item>
        </item>
        <item>
         <widget class="QTableWidget" name="tableWidgetFiles">
+         <property name="mouseTracking">
+          <bool>false</bool>
+         </property>
+         <property name="editTriggers">
+          <set>QAbstractItemView::NoEditTriggers</set>
+         </property>
          <property name="columnCount">
           <number>3</number>
          </property>
          </attribute>
          <column>
           <property name="text">
-           <string>Name</string>
+           <string>File</string>
           </property>
          </column>
          <column>
          </column>
          <column>
           <property name="text">
-           <string>Parent</string>
+           <string>Directory</string>
           </property>
          </column>
         </widget>
             <string>Opens the selected last opened project (Control-P)</string>
            </property>
            <property name="text">
-            <string>Open project</string>
+            <string>Open Project</string>
            </property>
            <property name="shortcut">
             <string>Ctrl+P</string>
 
 
 #include "reditor.hpp"
 
-const char* Workspace::KEY_HISTORY_FILES = "history.files";
-const char* Workspace::KEY_HISTORY_PROJECTS = "history.projecs";
+const char* Workspace::KEY_HISTORY_FILES = "files";
+const char* Workspace::KEY_HISTORY_PROJECTS = "projecs";
 
 /**
  * Constructor.
 
                <string>...</string>
               </property>
               <property name="icon">
-               <iconset resource="refind.qrc">
+               <iconset resource="../reditor/editor.qrc">
                 <normaloff>:/main/icons/layout_add.png</normaloff>:/main/icons/layout_add.png</iconset>
               </property>
              </widget>
    </item>
   </layout>
  </widget>
- <resources>
-  <include location="refind.qrc"/>
- </resources>
+ <resources/>
  <connections>
   <connection>
    <sender>buttonBox</sender>
 
  * @return      0: no date found<br>
  *              otherwise: the length of the date in the string
  */
-int ReQStringUtils::lengthOfDate(const ReString& text, int start, QDate* value) {
+int ReQStringUtils::lengthOfDate(const ReString& text, int start,
+    QDate* value) {
        uint day = 0;
        uint month = 0;
        uint year = 0;
  * @return  0: no date found<br>
  *          otherwise: the length of the date in the string
  */
-int ReQStringUtils::lengthOfTime(const ReString& text, int start, QTime* value) {
+int ReQStringUtils::lengthOfTime(const ReString& text, int start,
+    QTime* value) {
        uint hour = 0;
        uint minute = 0;
        uint sec = 0;
        return rc;
 }
 
+/**
+ * Constructor.
+ *
+ * @param pattern      a pattern with wildcards '*' (any string)
+ * @param anchored     <code>true<code>: the pattern starts at the strings start<br>
+ *                                     <code>false<code>: the pattern can start anywhere in the string<br>
+ */
+
+ReMatcher::ReMatcher(const QString& pattern, bool anchored) :
+           m_needles(pattern.split(QChar('*'))),
+           m_restLengths(),
+           m_anchored(anchored) {
+       for (int ix = 0; ix < m_needles.size(); ix++) {
+               m_restLengths.append(0);
+       }
+       int sum = 0;
+       for (int ix = m_needles.size() - 1; ix >= 0; ix--) {
+               int size = m_needles.at(ix).size();
+               m_restLengths.append(size + sum);
+               sum += size;
+       }
+}
+
+/**
+ * Destructor.
+ */
+ReMatcher::~ReMatcher() {
+}
+
+/**
+ * Tests whether the given string matches the pattern.
+ *
+ * @param text the text to test
+ * @return             <code>true</code>: the pattern matches
+ */
+bool ReMatcher::matches(const QString& text) {
+       bool found = false;
+       if (m_anchored)
+               found = matches(text, 0, 0);
+       else {
+               found = text.startsWith(m_needles.at(0));
+               if (found && m_needles.size() > 1)
+                       found = matches(text, m_needles.at(0).length(), 1);
+       }
+       return found;
+}
+
+/**
+ * Recursive matching test.
+ *
+ * @param text                 text to inspect
+ * @param textIndex            the first index in <code>text</code> to inspect
+ * @param needleIndex  the index of the pattern part to test
+ * @return                             <code>true</code>: the needles from the given index
+ *                                             up to the last index matches
+ */
+bool ReMatcher::matches(const QString& text, int textIndex, int needleIndex) {
+       int ix = textIndex;
+       QString needle = m_needles.at(needleIndex);
+       bool found = text.size() - textIndex >= m_restLengths.at(needleIndex);
+       while (!found && (ix = text.indexOf(needle, textIndex)) >= 0) {
+               textIndex = ix;
+               if (needleIndex >= m_needles.size() - 1)
+                       found = true;
+               else
+                       found = matches(text, ix + needle.length(), needleIndex);
+       }
+       return found;
+}
 
            10, uint64_t* value = NULL);
        static int lengthOfUInt(const ReString& text, int start, int radix,
            uint* pValue);
+       static bool match(const QString& heap, const QStringList& needles);
        /**
         * Returns the path with native path separators.
         *
        QDateTime m_dateTime;
 };
 
+class ReMatcher {
+public:
+       ReMatcher(const QString& pattern, bool anchored = false);
+       virtual ~ReMatcher();
+public:
+       virtual bool matches(const QString& text);
+protected:
+       bool matches(const QString& text, int textIndex, int needleIndex);
+protected:
+       QStringList m_needles;
+       // m_restLengths[ix] = sum(m_needles[ix..last].size()
+       QList<int> m_restLengths;
+       bool m_anchored;
+};
+
 #endif // RPLQSTRING_HPP
 
        void testReWriter();
        void testReFile();
        void testReFileUtils();
+       testReQStringUtil();
        testReFile();
        testReFileUtils();
        if (s_allTest) {
-               testReQStringUtil();
                testReByteStorage();
                testReCharPtrMap();
                testReConfig();
 
 }
 void allTests() {
-       testGui();
        testBase();
+       testGui();
        if (s_allTest) {
                testBase();
                testMath();
 
 class TestReQStringUtil: public ReTest {
 public:
        TestReQStringUtil() :
-                       ReTest("ReQStringUtil") {
+                   ReTest("ReQStringUtil") {
                doIt();
        }
 
        void testLengthOfUInt64() {
                quint64 value = -3;
                checkEqu(1,
-                       ReQStringUtils::lengthOfUInt64(ReString("0"), 0, 10, &value));
+                   ReQStringUtils::lengthOfUInt64(ReString("0"), 0, 10, &value));
                checkEqu(int64_t(0), value);
                checkEqu(3, ReQStringUtils::lengthOfUInt64("x432", 1, 10, &value));
                checkEqu(int64_t(432LL), value);
                checkEqu(3, ReQStringUtils::lengthOfUInt64("x432 x", 1, 10, &value));
                checkEqu(int64_t(432LL), value);
-               checkEqu(3, ReQStringUtils::lengthOfUInt64("x432fabc x", 1, 10, &value));
+               checkEqu(3,
+                   ReQStringUtils::lengthOfUInt64("x432fabc x", 1, 10, &value));
                checkEqu(int64_t(432LL), value);
                checkEqu(16,
-                       ReQStringUtils::lengthOfUInt64("a1234567890123567", 1, 10, &value));
+                   ReQStringUtils::lengthOfUInt64("a1234567890123567", 1, 10, &value));
                checkEqu(int64_t(1234567890123567LL), value);
                checkEqu(10,
-                       ReQStringUtils::lengthOfUInt64("x1234abcdef", 1, 16, &value));
+                   ReQStringUtils::lengthOfUInt64("x1234abcdef", 1, 16, &value));
                checkEqu(int64_t(0x1234abcdefLL), value);
                checkEqu(3, ReQStringUtils::lengthOfUInt64("432", 0, 8, &value));
                checkEqu(int64_t(0432LL), value);
                checkEqu(1, ReQStringUtils::lengthOfReal(ReString(" 0"), 1, &value));
                checkEqu(0.0, value);
                checkEqu(17,
-                       ReQStringUtils::lengthOfReal(ReString("X12345678901234567"), 1,
-                               &value));
+                   ReQStringUtils::lengthOfReal(ReString("X12345678901234567"), 1,
+                       &value));
                checkEqu(12345678901234567.0, value);
                checkEqu(2, ReQStringUtils::lengthOfReal(ReString(".5"), 0, &value));
                checkEqu(0.5, value);
-               checkEqu(5, ReQStringUtils::lengthOfReal(ReString("2.5e2x"), 0, &value));
+               checkEqu(5,
+                   ReQStringUtils::lengthOfReal(ReString("2.5e2x"), 0, &value));
                checkEqu(250.0, value);
-               checkEqu(6, ReQStringUtils::lengthOfReal(ReString("2.5e+2"), 0, &value));
+               checkEqu(6,
+                   ReQStringUtils::lengthOfReal(ReString("2.5e+2"), 0, &value));
                checkEqu(250.0, value);
                checkEqu(7,
-                       ReQStringUtils::lengthOfReal(ReString("2.5E-33"), 0, &value));
+                   ReQStringUtils::lengthOfReal(ReString("2.5E-33"), 0, &value));
                checkEqu(2.5e-33, value);
 
                checkEqu(3, ReQStringUtils::lengthOfReal(ReString("2.5E"), 0, &value));
                checkEqu(2.5, value);
                checkEqu(3, ReQStringUtils::lengthOfReal(ReString("2.5E+"), 0, &value));
                checkEqu(2.5, value);
-               checkEqu(3, ReQStringUtils::lengthOfReal(ReString("2.5E-a"), 0, &value));
+               checkEqu(3,
+                   ReQStringUtils::lengthOfReal(ReString("2.5E-a"), 0, &value));
                checkEqu(2.5, value);
        }
 
                ReString name = "Heinz Müller";
                char buffer[32];
                checkEqu("Heinz Müller",
-                       ReQStringUtils::utf8(name, buffer, sizeof buffer));
+                   ReQStringUtils::utf8(name, buffer, sizeof buffer));
                memset(buffer, 'x', sizeof buffer);
                checkEqu("Heinz", ReQStringUtils::utf8(name, buffer, (size_t)(5 + 1)));
                checkEqu(buffer[6], 'x');
                checkEqu(8, ReQStringUtils::lengthOfTime("301:02:09x", 1, &time));
                checkEqu(QTime(1, 2, 9), time);
        }
+       void testReMatcher() {
+               ReMatcher m1("a*b*c", true);
+               checkT(m1.matches("a b c d"));
+               checkT(m1.matches("abc d"));
+               checkF(m1.matches("ababc"));
+               ReMatcher m2("a*b*c", false);
+
+               checkT(m2.matches("a b c d"));
+               checkT(m2.matches("ababc"));
+               checkT(m2.matches("a b a b c"));
+       }
 
        virtual void run(void) {
+               testReMatcher();
                testLengtOfTime();
                testLengtOfDate();
                testDateTimeParser();