From: Hamatoma Date: Thu, 8 Dec 2016 23:31:49 +0000 (+0100) Subject: Research: ReIntComboBox, near-by-search, hits per file, block per file X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=HEAD;p=reqt Research: ReIntComboBox, near-by-search, hits per file, block per file --- diff --git a/appl/research/filefilter.cpp b/appl/research/filefilter.cpp index 16425ae..faac182 100644 --- a/appl/research/filefilter.cpp +++ b/appl/research/filefilter.cpp @@ -15,7 +15,7 @@ FileFilter::FileFilter(QTableWidget &table, QListWidget &list, FileCache& cache, m_excludeExpr(NULL), m_blockStartExpr(NULL), m_blockEndExpr(NULL), - m_singleBlock(false), + m_blocksPerFile(false), m_caseSensitive(false), m_fromHit(0), m_toHit(0), @@ -54,7 +54,7 @@ void FileFilter::filter(const QString &includePattern, int linesAbove, int linesBelow, bool caseSensitive, PrefixMode prefixMode, const QString& blockStart, const QString& blockEnd, - bool singleBlock) + int blocksPerFile) { int ixFile = -1; int hitNo = 0; @@ -65,7 +65,7 @@ void FileFilter::filter(const QString &includePattern, m_linesAbove = linesAbove; m_linesBelow = linesBelow; m_prefixMode = prefixMode; - m_singleBlock = singleBlock; + m_blocksPerFile = blocksPerFile; delete m_includeExpr; delete m_excludeExpr; @@ -81,7 +81,7 @@ void FileFilter::filter(const QString &includePattern, m_blockEndExpr = blockEnd.isEmpty() ? NULL : new QRegularExpression(blockEnd, option); QString full; QString node; - int hitFileNo = -1; + int hitFileNo = 0; while (ixFile < fileCount - 1 && hitNo < m_toHit){ ++ixFile; full = m_table.item(ixFile, colPath)->text(); @@ -130,6 +130,7 @@ int FileFilter::filterOneFile(const QString& filename, const QString& node, default: break; } + int currentBlock = 0; QString prefixOther = prefixHit; if (m_linesAbove + m_linesBelow > 0){ prefixHit = ">" + prefixHit; @@ -144,7 +145,7 @@ int FileFilter::filterOneFile(const QString& filename, const QString& node, lineNo = m_lastHitPosition.m_line; } int firstHitFile = true; - int firstFileIndex = 0; + int firstFileIndex = -1; bool inBlock = m_blockStartExpr == NULL; while(lastHit < m_toHit && lineNo < lastIx){ QString line = lines[++lineNo]; @@ -191,7 +192,7 @@ int FileFilter::filterOneFile(const QString& filename, const QString& node, } if (m_blockEndExpr != 0 && m_blockEndExpr->match(line).hasMatch()){ inBlock = false; - if (m_singleBlock) + if (++currentBlock >= m_blocksPerFile) break; } } diff --git a/appl/research/filefilter.hpp b/appl/research/filefilter.hpp index 08c79ff..f239835 100644 --- a/appl/research/filefilter.hpp +++ b/appl/research/filefilter.hpp @@ -30,7 +30,7 @@ public: int fromHit, int toHit, int linesAbove, int linesBelow, bool caseSensitive, PrefixMode prefixMode, const QString& blockStart, const QString& blockEnd, - bool singleBlock); + int blocksPerFile); private: int filterOneFile(const QString &filename, const QString& node, int lastHit, @@ -43,7 +43,7 @@ private: QRegularExpression* m_excludeExpr; QRegularExpression* m_blockStartExpr; QRegularExpression* m_blockEndExpr; - bool m_singleBlock; + int m_blocksPerFile; bool m_caseSensitive; int m_fromHit; int m_toHit; diff --git a/appl/research/mainwindow.cpp b/appl/research/mainwindow.cpp index 24bd7e1..a38ac84 100644 --- a/appl/research/mainwindow.cpp +++ b/appl/research/mainwindow.cpp @@ -12,7 +12,7 @@ MainWindow::MainWindow(QApplication& application, const QString& homeDir, const QString& baseDirectory, const QString& filePatterns, QWidget *parent) : - ReGuiApplication(application, "rsearch", homeDir, 2, 10100100, "de", parent), + ReGuiApplication(application, "research", homeDir, 2, 10100100, "de", parent), ReGuiValidator(), ui(new Ui::MainWindow), m_fileFinder(NULL), @@ -23,6 +23,7 @@ MainWindow::MainWindow(QApplication& application, const QString& homeDir, m_timer(new QTimer(this)), m_filenames() { + ReIntComboBox::m_defaultAnnouncer = this; ReComboBox::setDefaultHistorySize(20); m_timer->setSingleShot(true); initializeGui(); @@ -154,6 +155,7 @@ void MainWindow::initializeGui(){ connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimerTask())); + ui->comboBoxFromHit->setMinValue(1); delete m_fileFinder; m_fileFinder = new FileFinder(*ui->tableWidget, *m_fileCache); @@ -325,7 +327,7 @@ void MainWindow::onFilter() (PrefixMode) ui->comboBoxPrefixMode->currentIndex(), ui->comboBoxStartPattern->currentText(), ui->comboBoxEndPattern->currentText(), - ui->checkBoxSingleBlock->isChecked()); + ui->comboBoxBlocksPerFile->currentValue()); switchFilter(false); int found = pageSize; if (m_lastHitPosition->m_hitCount >= 0 diff --git a/appl/research/mainwindow.ui b/appl/research/mainwindow.ui index b7a4fc0..743085a 100644 --- a/appl/research/mainwindow.ui +++ b/appl/research/mainwindow.ui @@ -118,7 +118,7 @@ - 99 + 99 @@ -144,7 +144,7 @@ - 0 + 0 @@ -580,205 +580,364 @@ If the checkbox "inverse search" is checked a file is found only if th Options - - - - - QLayout::SetMaximumSize - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Lines above: - - - - - - - - 0 - 0 - - - - - 175 - 16777215 - - - - true - - - 0 - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Lines below: - - - - - - - - 0 - 0 - - - - - 175 - 16777215 - - - - true - - - 0 - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Prefix: - - - - - - - - 0 - 0 - - - - - 175 - 16777215 - - - + + + + 11 + 11 + 608 + 90 + + + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + - Placeholder + Lines above: + + + + + + + + 0 + 0 + + + + + 75 + 16777215 + + + + true + + + 0 + + + + + + + + 0 + 0 + + + + + 75 + 16777215 + + + + true + + + 0 + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + - - - Filename with path + Lines below: - - + + + + + + + + - Filename without path + Case sensitive - - + + false + + + + + - No filename + - - - - - - + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Prefix: + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + Placeholder + + + + + Filename with path + + + + + Filename without path + + + + + No filename + + + + + + + + Hits per file: + + + + + + + + 75 + 16777215 + + + + true + + + + + + + Block - - - - - Start pattern: - - - - - - - true - - - - - - - End pattern: - - - - - - - true - - + + + + + + + + + Start pattern: + + + + + + + true + + + + + + + End pattern: + + + + + + + true + + + + + + + + + + + Blocks per file: + + + + + + + + 75 + 16777215 + + + + true + + + + + + + Case sensitive + + + + + + - + - Block Options + "Near by" Search - - - - 20 - 20 - 171 - 25 - - - - A single block only - - + + + + + + + + + Search pattern: + + + + + + + true + + + + + + + Case sensitive + + + + + + + + + + + Max. lines above the hit: + + + + + + + + 75 + 16777215 + + + + true + + + 0 + + + + + + + Max. lines below the hit: + + + + + + + + 75 + 16777215 + + + + true + + + 0 + + + + + + + + @@ -872,7 +1031,7 @@ If the checkbox "inverse search" is checked a file is found only if th - + 100 @@ -895,7 +1054,7 @@ If the checkbox "inverse search" is checked a file is found only if th - + 100 @@ -909,7 +1068,7 @@ If the checkbox "inverse search" is checked a file is found only if th true - 10 + 50 @@ -994,6 +1153,11 @@ If the checkbox "inverse search" is checked a file is found only if th QComboBox
gui/ReComboBox.hpp
+ + ReIntComboBox + QComboBox +
ReIntComboBox.hpp
+
diff --git a/appl/research/research.de.ts b/appl/research/research.de.ts index 1515dc3..9374650 100644 --- a/appl/research/research.de.ts +++ b/appl/research/research.de.ts @@ -1211,7 +1211,7 @@ Wenn die Checkbox "Inverse Suche" ausgewählt ist, wird eine Datei nur Found: %1 hit(s) in %2 - Gefunden: %1 Treffer in %d + Gefunden: %1 Treffer in %2 missing a base directory @@ -1229,6 +1229,30 @@ Wenn die Checkbox "Inverse Suche" ausgewählt ist, wird eine Datei nur I am working... Ich arbeite... + + Hits per file: + Treffer je Datei: + + + Blocks per file: + Blöcke je Datei: + + + Search pattern: + Suchmuster: + + + Max. lines above the hit: + Max. Zeilen über dem Treffer: + + + Max. lines below the hit: + Max. Zeilen unter dem Treffer: + + + "Near by" Search + "Nahe bei"-Suche + QObject @@ -1391,4 +1415,23 @@ yyy Willkommen! + + ReIntComboBox + + integer expected, not an empty string + Ganzzahl erwartet, kein leerer String + + + not a number: + Keine Zahl: + + + value to small: %1 < %2 + Wert zu klein: %1 < %2 + + + value to large: %1 > %2 + Wert zu groß: %1 > %2 + + diff --git a/appl/research/research.pro b/appl/research/research.pro index 5b1bfdd..a72cfce 100644 --- a/appl/research/research.pro +++ b/appl/research/research.pro @@ -34,7 +34,8 @@ SOURCES += main.cpp \ ../../base/ReFileSearch.cpp \ filefinder.cpp \ filecache.cpp \ - filefilter.cpp + filefilter.cpp \ + ../../gui/ReIntComboBox.cpp HEADERS += mainwindow.hpp \ ../../base/rebase.hpp \ @@ -49,7 +50,8 @@ HEADERS += mainwindow.hpp \ ../../base/ReFileSearch.hpp \ filefinder.hpp \ filecache.hpp \ - filefilter.hpp + filefilter.hpp \ + ../../gui/ReIntComboBox.hpp FORMS += mainwindow.ui \ aboutdialog.ui diff --git a/base/ReQStringUtils.cpp b/base/ReQStringUtils.cpp index a930415..036fb30 100644 --- a/base/ReQStringUtils.cpp +++ b/base/ReQStringUtils.cpp @@ -104,7 +104,31 @@ bool ReQStringUtils::hasPrefixAndNumber(const QString prefix, const QString& lin } } } - return rc; + return rc; +} + +/** + * Tests whether a string is a number. + * + * @param text text to inspect + * @param value OUT: the value of text interpreted as integer + * @return true: textis a number + */ +bool ReQStringUtils::isAnInteger(const QString &text, int *value) +{ + bool isNegative = false; + bool rc = ! text.isEmpty(); + if (rc){ + int start = 0; + if (text[0] == QChar('-')){ + isNegative = true; + start = 1; + } + rc = lengthOfUInt(text, start, 10, (unsigned *) value) == text.length() - start; + if (value != NULL && isNegative) + *value = - *value; + } + return rc; } /** @@ -516,8 +540,8 @@ void ReQStringUtils::skipExpected(const ReString& text, QChar expected, QString ReQStringUtils::numberToName(int number, const char* charSet, int charSetSize){ QString rc; if (charSet == NULL){ - charSet = "-$ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - charSetSize = 37+1; // strlen(charSet) + charSet = "-$ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + charSetSize = 26+1+1; // strlen(charSet) } if (number < 0){ number = -number; diff --git a/base/ReQStringUtils.hpp b/base/ReQStringUtils.hpp index dc23232..909d42d 100644 --- a/base/ReQStringUtils.hpp +++ b/base/ReQStringUtils.hpp @@ -58,6 +58,7 @@ public: static QString& ensureLastChar(QString& value, QChar lastChar); static bool hasPrefixAndNumber(const QString prefix, const QString& line, int& no, QString& value); + static bool isAnInteger(const QString& text, int* value = NULL); static int lengthOfDate(const ReString& text, int start = 0, QDate* value = NULL); static int lengthOfDateTime(const ReString& text, int start = 0, diff --git a/base/ReTest.cpp b/base/ReTest.cpp index 335b634..b9a34a3 100644 --- a/base/ReTest.cpp +++ b/base/ReTest.cpp @@ -444,9 +444,8 @@ void ReTest::assertLogContains(const char* pattern, bool isRegExpr, */ void ReTest::assertLogContainsLocation(int location, const char* file, int lineNo) { - QByteArray pattern("^.20[\\d:. ]+\\("); - pattern += location; - pattern += "\\)"; + char pattern[128]; + snprintf(pattern, sizeof pattern, "^.20[\\d:. ]+\\(%d\\)", location); if (! logContains(pattern, true)){ error("%s-%d: not found: location %d\n", file, lineNo, location, m_memoryAppender.getLines().join().constData()); diff --git a/cunit/cuReFileUtils.cpp b/cunit/cuReFileUtils.cpp index 533d777..a4221d3 100644 --- a/cunit/cuReFileUtils.cpp +++ b/cunit/cuReFileUtils.cpp @@ -351,7 +351,7 @@ public: checkEqu(0, stat(dir.constData(), &info)); checkF(S_ISDIR(info.st_mode)); checkF(ReFileUtils::makeDirWithParents(dir.constData(), &m_memoryLogger)); - checkLogContainsLocation(51003); + checkLogContainsLocation(12508); checkLogContains(dir.constData(), false); } void testIsDirectoy(){ diff --git a/cunit/cuReQStringUtils.cpp b/cunit/cuReQStringUtils.cpp index 087a2c2..643036d 100644 --- a/cunit/cuReQStringUtils.cpp +++ b/cunit/cuReQStringUtils.cpp @@ -222,7 +222,7 @@ public: checkEqu("1.001 TB", ReQStringUtils::readableSize(1001000000000l)); } void testReadableDuration(){ -#define clf(sec) clock_t(clock_t((sec) * CLOCKS_PER_SEC)) +#define clf(sec) qint64((sec) * 1000) checkEqu("0.000 sec", ReQStringUtils::readableDuration(clf(0.0))); QString value = ReQStringUtils::readableDuration(clf(1.234)); checkEqu("1.234 sec", value); @@ -244,7 +244,25 @@ public: checkEqu("/a/b/c", s); } + void testIsAnInteger(){ + checkT(ReQStringUtils::isAnInteger("1")); + int value; + checkT(ReQStringUtils::isAnInteger("1", &value)); + checkEqu(1, value); + checkT(ReQStringUtils::isAnInteger("-76453", &value)); + checkEqu(-76453, value); + checkF(ReQStringUtils::isAnInteger("")); + checkF(ReQStringUtils::isAnInteger("", &value)); + checkF(ReQStringUtils::isAnInteger("12a")); + checkF(ReQStringUtils::isAnInteger("12a", &value)); + checkF(ReQStringUtils::isAnInteger(".12")); + checkF(ReQStringUtils::isAnInteger(".12", &value)); + checkF(ReQStringUtils::isAnInteger("-12,")); + checkF(ReQStringUtils::isAnInteger("-12,", &value)); + } + virtual void runTests(void) { + testIsAnInteger(); testChomp(); testReadableSize(); testReadableDuration(); diff --git a/gui/ReIntComboBox.cpp b/gui/ReIntComboBox.cpp new file mode 100644 index 0000000..723900e --- /dev/null +++ b/gui/ReIntComboBox.cpp @@ -0,0 +1,174 @@ +#include "base/rebase.hpp" +#include "gui/regui.hpp" + +ReAnnouncer* ReIntComboBox::m_defaultAnnouncer = NULL; + +/** + * Constructor. + * @param parent + */ +ReIntComboBox::ReIntComboBox(QWidget *parent) : + ReComboBox(parent), + m_minValue(0), + m_maxValue(0x7ffffff), + m_defaultValue(0), + m_announcer(m_defaultAnnouncer), + m_emptyAllowed(false) +{ + connect(this, SIGNAL(textEdited(const QString&, const QString&)), + this, SLOT(textEdited(const QString&, const QString&))); +} + +/** + * Returns the current value. + * + * @return the current value + */ +int ReIntComboBox::currentValue() const +{ + QString value = currentText(); + int rc = m_defaultValue; + if (! value.isEmpty()) + rc = value.toInt(); + return rc; +} + +/** + * Returns the current announcer (logger for error messages). + * @return the current announcer + */ +ReAnnouncer* ReIntComboBox::announcer() const +{ + return m_announcer; +} + +/** + * Returns the flag "empty allowed". + * + * @return the flag "empty allowed" + */ +bool ReIntComboBox::emptyAllowed() const +{ + return m_emptyAllowed; +} + +/** + * Prints an error message with the stored announcer. + * + * @param message the error message + */ +void ReIntComboBox::error(const QString& message, const QString* defaultValue) +{ + if (m_announcer != NULL) + m_announcer->say(LOG_ERROR, message); + if (defaultValue == NULL){ + setCurrentText(QString::number(m_defaultValue)); + } else { + if (ReQStringUtils::isAnInteger(*defaultValue)) + setCurrentText(*defaultValue); + else + setCurrentText(QString::number(m_defaultValue)); + } +} +/** + * Returns the current default value (uses for errors). + * + * @return the current default value + */ +int ReIntComboBox::defaultValue() const +{ + return m_defaultValue; +} + +/** + * Gets the maximal allowed value. + * + * @return the maximal allowed value + */ +int ReIntComboBox::maxValue() const +{ + return m_maxValue; +} + +/** + * Gets the maximal allowed value. + * + * @return the maximal allowed value + */ +int ReIntComboBox::minValue() const +{ + return m_minValue; +} + +/** + * Handles the event "changed text". + * + * @param oldValue value before editing + * @param newValue value after editing + */ +void ReIntComboBox::textEdited(const QString& oldValue, const QString& newValue) +{ + int value; + if (newValue.isEmpty()){ + if (! m_emptyAllowed) + error(tr("integer expected, not an empty string"), &oldValue); + } else if (! ReQStringUtils::isAnInteger(newValue, &value)){ + error(tr("not a number:") + " " + newValue, &oldValue); + } else if (value < m_minValue) { + error(tr("value to small: %1 < %2").arg(value).arg(m_minValue), &oldValue); + } else if (value > m_maxValue) { + error(tr("value to large: %1 > %2").arg(value).arg(m_maxValue), &oldValue); + } +} + +/** + * Sets the flag "empty allowed". + * + * @param emptyAllowed true: the field may be empty.
+ * false: the field must not be empty + */ +void ReIntComboBox::setEmptyAllowed(bool emptyAllowed) +{ + m_emptyAllowed = emptyAllowed; +} + +/** + * Sets the maximal value. + * + * @param maxValue the maximal allowed value + */ +void ReIntComboBox::setMaxValue(int maxValue) +{ + m_maxValue = maxValue; +} + +/** + * Sets the minimal value. + * + * @param minValue the minimal allowed value + */ +void ReIntComboBox::setMinValue(int minValue) +{ + m_minValue = minValue; +} + +/** + * Sets the maximal value. + * + * @param maxValue the maximal allowed value + */ +void ReIntComboBox::setDefaultValue(int defaultValue) +{ + m_defaultValue = defaultValue; +} + +/** + * Sets the announcer (to log errors). + * + * @param announcer the new announcer (or NULL) + */ +void ReIntComboBox::setAnnouncer(ReAnnouncer* announcer) +{ + m_announcer = announcer; +} + diff --git a/gui/ReIntComboBox.hpp b/gui/ReIntComboBox.hpp new file mode 100644 index 0000000..788620e --- /dev/null +++ b/gui/ReIntComboBox.hpp @@ -0,0 +1,41 @@ +#ifndef REINTCOMBOBOX_H +#define REINTCOMBOBOX_H + +#ifndef RECOMBOBOX_HPP +#include "gui/ReComboBox.hpp" +#endif + +class ReAnnouncer; +/** + * Implements a combo box containing a integer as value. + */ +class ReIntComboBox : public ReComboBox +{ + Q_OBJECT +public: + ReIntComboBox(QWidget *parent); +public: + ReAnnouncer* announcer() const; + int currentValue() const; + int defaultValue() const; + bool emptyAllowed() const; + void error(const QString& message, const QString* defaultValue = NULL); + int maxValue() const; + int minValue() const; + void textEdited(const QString& oldValue, const QString& newValue); + void setAnnouncer(ReAnnouncer* announcer); + void setDefaultValue(int defaultValue); + void setEmptyAllowed(bool emptyAllowed); + void setMaxValue(int maxValue); + void setMinValue(int minValue); +private: + int m_minValue; + int m_maxValue; + int m_defaultValue; + ReAnnouncer* m_announcer; + bool m_emptyAllowed; +public: + static ReAnnouncer* m_defaultAnnouncer; +}; + +#endif // REINTCOMBOBOX_H diff --git a/gui/ReSettings.cpp b/gui/ReSettings.cpp index a07cfb7..94e6f3f 100644 --- a/gui/ReSettings.cpp +++ b/gui/ReSettings.cpp @@ -27,8 +27,8 @@ enum { LOC_CHANGE_VALUE_2, // 11712 }; -QString ReSettings::TRUE = "t"; -QString ReSettings::FALSE = ""; +QString ReSettings::sTRUE = "t"; +QString ReSettings::sFALSE = ""; /** * Constructor. @@ -56,10 +56,10 @@ ReProperty::ReProperty(const char* name, const QString& title, * Tests whether a given value is allowed respecting the m_limits * @param value the value to test * @param error OUT: NULL or the error message - * @return true: the value is allowed
+ * @return sTRUE: the value is allowed
*/ bool ReProperty::isValid(const QString& value, QString* error) { - bool rc = true; + bool rc = true; if (error != NULL) *error = ""; if (m_limits != NULL) { @@ -75,11 +75,11 @@ bool ReProperty::isValid(const QString& value, QString* error) { int minimum, maximum; if (sscanf(m_limits, "[%d,%d]", &minimum, &maximum) == 2) { if (nValue < minimum) { - rc = false; + rc = false; if (error != NULL) *error = value + " < " + minimum; } else if (nValue > maximum) { - rc = false; + rc = false; if (error != NULL) *error = value + " < " + maximum; } @@ -182,7 +182,7 @@ QString ReSettings::topOfHistory(const char* key, const QString& defaultValue) { * @return the value of the property */ bool ReSettings::boolValue(const char* name) { - bool rc = false; + bool rc = false; ReProperty* property = m_settings.value(name, NULL); if (property == NULL) m_logger->logv(LOG_ERROR, LOC_BOOL_VALUE_1, "missing bool property %s", @@ -330,7 +330,7 @@ void ReSettings::readSettings() { case PT_BOOL: property->m_value = value.isEmpty() ? - ReSettings::FALSE : ReSettings::TRUE; + ReSettings::sFALSE : ReSettings::sTRUE; break; case PT_INT: if (property->isValid(value)) @@ -423,7 +423,7 @@ ReDelayedStorage::ReDelayedStorage(const QString& file, ReLogger* logger, m_delay(delay), m_file(file), m_logger(logger){ - m_timer.setSingleShot(true); + m_timer.setSingleShot(true); connect(&m_timer, SIGNAL(timeout()), this, SLOT(timeout())); } diff --git a/gui/regui.hpp b/gui/regui.hpp index 1921093..4bc0c30 100644 --- a/gui/regui.hpp +++ b/gui/regui.hpp @@ -19,6 +19,7 @@ #include #include #include "gui/ReComboBox.hpp" +#include "gui/ReIntComboBox.hpp" #include "gui/ReGuiUtils.hpp" #include "gui/ReGuiQueue.hpp" #include "gui/ReStateStorage.hpp"