From: hama Date: Sat, 29 Aug 2015 22:50:40 +0000 (+0200) Subject: ReMatcher, ReEditor X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=be119e607ea901463c8ba9aa4eb3332a8a6f2ede;p=reqt ReMatcher, ReEditor * ReMatcher: case sensitivity * ReEditor: file/project open works --- diff --git a/appl/reditor/projectselection.cpp b/appl/reditor/projectselection.cpp index 7124e10..df22c55 100644 --- a/appl/reditor/projectselection.cpp +++ b/appl/reditor/projectselection.cpp @@ -30,12 +30,12 @@ ProjectSelection::ProjectSelection(MainWindow* mainWindow, QWidget *parent) : connect(ui->toolButtonSelectProject, SIGNAL(clicked()), this, SLOT(selectDir())); connect(ui->pushButtonOpen, SIGNAL(clicked()), this, SLOT(open())); - connect(ui->pushButtonOpenLastFile, SIGNAL(clicked()), this, - SLOT(openLastFile())); - connect(ui->pushButtonOpenLastProject, SIGNAL(clicked()), this, - SLOT(openLastProject())); - connect(ui->lineEditFilterLastFile, SIGNAL(textChanged(QString))), this, SLOT( - textChanged(QString)); + connect(ui->lineEditFilterLastFile, SIGNAL(textChanged(QString)), this, + SLOT(textChangedFilterFiles(QString))); + connect(ui->tableWidgetFiles, SIGNAL(cellEntered(int,int)), this, + SLOT(cellEnteredFiles(int, int))); + connect(ui->tableWidgetProjects, SIGNAL(cellEntered(int,int)), this, + SLOT(cellEnteredProjects(int, int))); Workspace* workspace = mainWindow->workspace(); buildTableInfo(workspace, Workspace::KEY_HISTORY_FILES, true, m_files); buildTableInfo(workspace, Workspace::KEY_HISTORY_PROJECTS, false, @@ -50,11 +50,28 @@ ProjectSelection::ProjectSelection(MainWindow* mainWindow, QWidget *parent) : ProjectSelection::~ProjectSelection() { delete ui; } -void ProjectSelection::textChangedFilterFiles(const QString& text) { - +/** + * Handles the event cellEntered for the last opened files. + * + * @param row the row of the entered cell + * @param col the column of the entered cell + */ +void ProjectSelection::cellEnteredFiles(int row, int col) { + ReUseParameter(col); + QString file = fileOfTable(ui->tableWidgetFiles, row); + ui->lineEditOpen->setText(file); } -void ProjectSelection::textChangedFilterProjects(const QString& text) { +/** + * Handles the event cellEntered for the last opened projects. + * + * @param row the row of the entered cell + * @param col the column of the entered cell + */ +void ProjectSelection::cellEnteredProjects(int row, int col) { + ReUseParameter(col); + QString file = fileOfTable(ui->tableWidgetProjects, row); + ui->lineEditOpen->setText(file); } /** @@ -64,36 +81,19 @@ void ProjectSelection::textChangedFilterProjects(const QString& text) { * @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, - QTableWidget* table) { +void ProjectSelection::buildTable(const QString& filter, + const QStringList& lines, QTableWidget* table) { QStringList::const_iterator it; int rowCount = 0; + ReMatcher matcher(filter, Qt::CaseInsensitive, true); for (it = lines.cbegin(); it != lines.cend(); ++it) { - bool matches = filter.isEmpty(); - if (!matches) { - //@ToDo: coding - if (filter.startsWith("*")) { - - } else { - - } - } - if (matches) + if (matcher.matches(*it)) 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) { + if (matcher.matches(*it)) { row++; QStringList cols = it->split('\t'); for (int col = 0; col < cols.size(); col++) { @@ -148,6 +148,21 @@ void ProjectSelection::error(const QString& message) { dialog.exec(); } +/** + * Extracts the full filename of a given table. + * + * The node is the first column, the path the last. + * + * @param table the table from which the filename is taken + * @param row the row where the filename is + * @return the full name of the file in the given row + */ +QString ProjectSelection::fileOfTable(QTableWidget* table, int row) { + int colPath = table->columnCount() - 1; + QString file = table->item(row, colPath)->text() + OS_SEPARATOR_STR + + table->item(row, 0)->text(); + return file; +} /** * Opens a file or a directory (project directory). */ @@ -169,31 +184,6 @@ void ProjectSelection::open() { } } -/** - * 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. */ @@ -221,3 +211,36 @@ void ProjectSelection::selectFile() { } } +/** + * Handles the filter text change for a given table. + * + * @param text the filter text + * @param table the table which will be filled + * @param lines the full (unfiltered) table info + */ +void ProjectSelection::textChanged(const QString& text, QTableWidget* table, + const QStringList& lines) { + buildTable(text, lines, table); + if (table->rowCount() > 0) { + QString file = fileOfTable(table, 0); + ui->lineEditOpen->setText(file); + } +} + +/** + * Handles the event "text changed" of the last opened files. + * + * @param text the new text + */ +void ProjectSelection::textChangedFilterFiles(const QString& text) { + textChanged(text, ui->tableWidgetFiles, m_files); +} + +/** + * Handles the event "text changed" of the last opened projects. + * + * @param text the new text + */ +void ProjectSelection::textChangedFilterProjects(const QString& text) { + textChanged(text, ui->tableWidgetProjects, m_projects); +} diff --git a/appl/reditor/projectselection.hpp b/appl/reditor/projectselection.hpp index c0ee0dd..ea17c30 100644 --- a/appl/reditor/projectselection.hpp +++ b/appl/reditor/projectselection.hpp @@ -27,18 +27,20 @@ public: public slots: void open(); - void openLastFile(); - void openLastProject(); void selectDir(); void selectFile(); protected: - void buildTable(const QString& filter, QStringList& lines, + void buildTable(const QString& filter, const QStringList& lines, QTableWidget* table); void buildTableInfo(ReSettings* settings, const char* key, bool withDate, QStringList& tableContent); - QString openSelectedItem(QTableWidget* table); + QString fileOfTable(QTableWidget* table, int row); + void textChanged(const QString& text, QTableWidget* table, + const QStringList& lines);protected slots: + void cellEnteredFiles(int row, int col); + void cellEnteredProjects(int row, int col); void textChangedFilterFiles(const QString& text); - void textChangedFilterProjecs(const QString& text); + void textChangedFilterProjects(const QString& text); private: void error(const QString& message); private: diff --git a/appl/reditor/projectselection.ui b/appl/reditor/projectselection.ui index 5897074..8b24b07 100644 --- a/appl/reditor/projectselection.ui +++ b/appl/reditor/projectselection.ui @@ -117,7 +117,7 @@ Use wildcards: '*' (any string) and '?' (any character) - false + true QAbstractItemView::NoEditTriggers @@ -149,47 +149,7 @@ Use wildcards: '*' (any string) and '?' (any character) - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Opens the selected last opened file (Control-F) - - - Open File - - - Ctrl+F - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + @@ -229,6 +189,9 @@ Use wildcards: '*' (any string) and '?' (any character) + + true + 2 @@ -251,47 +214,7 @@ Use wildcards: '*' (any string) and '?' (any character) - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Opens the selected last opened project (Control-P) - - - Open Project - - - Ctrl+P - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + diff --git a/base/ReQStringUtils.cpp b/base/ReQStringUtils.cpp index 312a5b9..65dabff 100644 --- a/base/ReQStringUtils.cpp +++ b/base/ReQStringUtils.cpp @@ -819,25 +819,13 @@ QDateTime ReDateTimeParser::parseDateTime(const QString& expr) { * false: the pattern can start anywhere in the string
*/ -ReMatcher::ReMatcher(const QString& pattern, bool anchored) : - m_needles(pattern.split(QChar('*'))), +ReMatcher::ReMatcher(const QString& pattern, Qt::CaseSensitivity caseSensivity, + bool anchored) : + m_needles(), 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() { + m_anchored(anchored), + m_caseSensivitiy(caseSensivity) { + setPattern(pattern); } /** @@ -847,36 +835,45 @@ ReMatcher::~ReMatcher() { * @return true: 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); + bool found = m_needles.size() == 0; + if (!found) { + found = + m_anchored ? + text.startsWith(m_needles.at(0), m_caseSensivitiy) : true; + if (found) { + int startIx = m_anchored ? 1 : 0; + int textIndex = m_anchored ? m_needles.at(0).length() : 0; + for (int ix = startIx; found && ix < m_needles.size(); ix++) { + found = text.size() - textIndex >= m_restLengths.at(ix); + if (found) + found = (textIndex = text.indexOf(m_needles.at(ix), + textIndex, m_caseSensivitiy)) >= 0; + } + } } return found; } /** - * Recursive matching test. + * Sets the search pattern. * - * @param text text to inspect - * @param textIndex the first index in text to inspect - * @param needleIndex the index of the pattern part to test - * @return true: the needles from the given index - * up to the last index matches + * @param pattern the search pattern, with wildcards '*' (any string) */ -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; +void ReMatcher::setPattern(const QString& pattern) { + m_needles = pattern.split('*'); + // Eliminate empty entries: + for (int ix = m_needles.size() - 1; ix >= 0; ix--) { + if (m_needles.at(ix).length() == 0) + m_needles.removeAt(ix); else - found = matches(text, ix + needle.length(), needleIndex); + m_restLengths.append(0); } - return found; + 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; + } + } + diff --git a/base/ReQStringUtils.hpp b/base/ReQStringUtils.hpp index e929150..443620c 100644 --- a/base/ReQStringUtils.hpp +++ b/base/ReQStringUtils.hpp @@ -105,17 +105,17 @@ private: class ReMatcher { public: - ReMatcher(const QString& pattern, bool anchored = false); - virtual ~ReMatcher(); + ReMatcher(const QString& pattern, Qt::CaseSensitivity caseSensitivty = + Qt::CaseSensitive, bool anchored = false); public: - virtual bool matches(const QString& text); -protected: - bool matches(const QString& text, int textIndex, int needleIndex); + bool matches(const QString& text); + void setPattern(const QString& pattern); protected: QStringList m_needles; // m_restLengths[ix] = sum(m_needles[ix..last].size() QList m_restLengths; bool m_anchored; + Qt::CaseSensitivity m_caseSensivitiy; }; #endif // RPLQSTRING_HPP diff --git a/cunit/cuReQStringUtils.cpp b/cunit/cuReQStringUtils.cpp index 513cb52..e3dd466 100644 --- a/cunit/cuReQStringUtils.cpp +++ b/cunit/cuReQStringUtils.cpp @@ -187,15 +187,37 @@ public: checkEqu(QTime(1, 2, 9), time); } void testReMatcher() { - ReMatcher m1("a*b*c", true); + ReMatcher m1("a*b*c", Qt::CaseSensitive, true); checkT(m1.matches("a b c d")); checkT(m1.matches("abc d")); - checkF(m1.matches("ababc")); - ReMatcher m2("a*b*c", false); + checkT(m1.matches("ababc")); + checkT(m1.matches("abc")); + checkF(m1.matches("aBc")); + ReMatcher m2("a*b*c", Qt::CaseSensitive, false); checkT(m2.matches("a b c d")); checkT(m2.matches("ababc")); checkT(m2.matches("a b a b c")); + checkT(m2.matches(" abc")); + checkF(m2.matches(" ab")); + + ReMatcher m3("a**B*C", Qt::CaseInsensitive, true); + checkT(m3.matches("a b c d")); + checkT(m3.matches("abc d")); + checkT(m3.matches("ababc")); + checkT(m3.matches("abc")); + + ReMatcher m4("A*B*c", Qt::CaseInsensitive, false); + checkT(m4.matches("a b c d")); + checkT(m4.matches("ababc")); + checkT(m4.matches("a b a b c")); + checkT(m4.matches(" abc")); + checkF(m4.matches(" ab")); + + m4.setPattern("*"); + checkT(m4.matches("x")); + m4.setPattern(""); + checkT(m4.matches("any")); } virtual void run(void) {