From: hama Date: Sat, 13 Feb 2016 00:39:38 +0000 (+0100) Subject: recommand: interpolate + expand works X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=72f629dfd9358326d56e45a64313f1d7bbbe11df;p=reqt recommand: interpolate + expand works --- diff --git a/appl/rebackgui/BackupEngine.cpp b/appl/rebackgui/BackupEngine.cpp index 2b11701..56a906f 100644 --- a/appl/rebackgui/BackupEngine.cpp +++ b/appl/rebackgui/BackupEngine.cpp @@ -27,7 +27,7 @@ QString BackupEngine::m_separatorString = "\t"; QStringList ChecksumTask::m_checksumInfo; bool ChecksumTask::m_sourceProcessingReady = false; - +static const int MAX_INDEX = 0x7fff; /** * Constructor. * @@ -122,15 +122,10 @@ bool BackupEngine::log(const QString& message){ * * @param directory directory to inspect, e.g. "/media/trg/x" * @param maxAge all files older than this time point will be deleted - * @param index the index in the shadow directories */ -void BackupEngine::removeOlder(const QString& directory, const QDateTime& time, - int index){ +void BackupEngine::removeOlder(const QString& directory, const QDateTime& time){ QDirIterator it(directory); QString info, node; - int lengthBase = m_shadowDirs.at(index).length(); - assert(index < 0x7fff); - QString prefix; m_mutex.lock(); m_totalDirs++; m_mutex.unlock(); @@ -143,13 +138,13 @@ void BackupEngine::removeOlder(const QString& directory, const QDateTime& time, node = it.fileName(); if (it.fileInfo().isDir()){ if (node != "." && node != ".."){ - removeOlder(it.filePath(), time, index); + removeOlder(it.filePath(), time); isEmpty = false; } } else if (it.fileInfo().lastModified() < time){ isEmpty = false; - info = QChar(index + 1) + it.filePath() + m_separatorString - + QChar(CmdRemove) ; + info = QChar(MAX_INDEX) + it.filePath() + m_separatorString + + QChar(CmdRemove); m_mutex.lock(); m_files.append(info); m_hotFiles++; @@ -159,7 +154,7 @@ void BackupEngine::removeOlder(const QString& directory, const QDateTime& time, } } if (isEmpty){ - info = QChar(index + 1) + it.filePath() + m_separatorString + info = QChar(MAX_INDEX) + it.filePath() + m_separatorString + QChar(CmdRemoveDir); m_mutex.lock(); m_files.append(info); @@ -233,8 +228,8 @@ void BackupTask::run() { QString relPath, node; QString info; - qint64 start = QDateTime::currentMSecsSinceEpoch(); - while (true){ + QDateTime start = QDateTime::currentDateTime(); + while (! m_shouldStop){ m_mutex.lock(); if (m_files.size() == 0) info.clear(); @@ -257,21 +252,20 @@ void BackupTask::run() relPath = info.mid(1, pos - 1); node = info.mid(pos + 1); copyFile(index, relPath, node); - qint64 now = QDateTime::currentMSecsSinceEpoch(); - qint64 estimated = qint64(double(now - start) / max(1LL, m_processedBytes) * m_hotBytes); + qint64 duration = QDateTime::currentMSecsSinceEpoch() - start.currentMSecsSinceEpoch(); + double factor = double(m_hotBytes) / max(1LL, m_processedBytes); m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL, - tr("%1 of %2 (%3 of %4) %5 MB/sec Remaining: %6 of %7") + tr("%1 of %2 (%3 of %4) %5 MB/sec runtime: %6") .arg(m_processedFiles).arg(m_hotFiles) - .arg(ReQStringUtils::readableSize(m_processedBytes)) - .arg(ReQStringUtils::readableSize(m_hotBytes)) - .arg(m_processedBytes / 1024.0 / 1024 / (now - start) * 1000, 0, 'f', 3) - .arg(ReQStringUtils::readableDuration(estimated - (now - start))) - .arg(ReQStringUtils::readableDuration(estimated))); + .arg(ReQStringUtils::readableSize(m_processedBytes)) + .arg(ReQStringUtils::readableSize(m_hotBytes)) + .arg(m_processedBytes / 1024.0 / 1024 * 1000 / max(1LL, duration), 0, 'f', 3) + .arg(ReQStringUtils::runtimeEstimation(start, factor))); } } m_mainWindow->externalTaskFinished(tr("backup complete after %1. Errors: %2") .arg(ReQStringUtils::readableDuration( - QDateTime::currentMSecsSinceEpoch() - start)) + QDateTime::currentMSecsSinceEpoch() - start.currentMSecsSinceEpoch())) .arg(m_mainWindow->errors())); } @@ -350,7 +344,7 @@ void ChecksumOfSourceTask::run() QString relPath, node; QString info; int count = 0; - while (true){ + while (! m_shouldStop){ m_mutex.lock(); if (m_files.size() == 0) info.clear(); @@ -411,12 +405,12 @@ ChecksumOfTargetTask::ChecksumOfTargetTask(const QString& name, */ void ChecksumOfTargetTask::run() { - qint64 start = QDateTime::currentMSecsSinceEpoch(); + QDateTime start = QDateTime::currentDateTime(); QString relPath, node; qint64 now = 0; QString info; int count = 0; - while (true){ + while (! m_shouldStop){ m_mutex.lock(); if (m_checksumInfo.size() == 0) info.clear(); @@ -457,25 +451,21 @@ void ChecksumOfTargetTask::run() processedFiles = m_processedFiles; m_mutex.unlock(); now = QDateTime::currentMSecsSinceEpoch(); - double duration = (now - start); - double estimated = qint64(double(now - start)); - estimated /= max(1LL, m_processedBytes); - estimated *= m_hotBytes * 2; - qint64 rest = qint64(estimated - duration); + qint64 duration = (now - start.currentMSecsSinceEpoch()); + double factor = double(m_hotBytes) * 2 / max(1LL, m_processedBytes); m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL, - tr("%1 of %2 (%3 of %4) %5 MB/sec Remaining: %6 of %7") + tr("%1 of %2 (%3 of %4) %5 MB/sec runtime: %6") .arg(processedFiles).arg(hotFiles * 2) .arg(ReQStringUtils::readableSize(processedBytes)) .arg(ReQStringUtils::readableSize(hotBytes * 2)) - .arg(processedBytes / 1024.0 / 1024 / duration * 1000.0, 0, 'f', 3) - .arg(ReQStringUtils::readableDuration(rest)) - .arg(ReQStringUtils::readableDuration(qint64(estimated)))); + .arg(processedBytes / 1024.0 / 1024 / max(1LL, duration) * 1000.0, 0, 'f', 3) + .arg(ReQStringUtils::runtimeEstimation(start, factor))); } } now = QDateTime::currentMSecsSinceEpoch(); m_mainWindow->externalTaskFinished(tr("Building target checksums complete after %1. Processed: %2 Errors: %3") - .arg(ReQStringUtils::readableDuration(now - start)) + .arg(ReQStringUtils::readableDuration(now - start.currentMSecsSinceEpoch())) .arg(count) .arg(m_mainWindow->errors())); } @@ -505,8 +495,8 @@ void CleanTask::run() { QString relPath, node; QString info; - qint64 start = QDateTime::currentMSecsSinceEpoch(); - while (true){ + QDateTime start = QDateTime::currentDateTime(); + while (! m_shouldStop){ m_mutex.lock(); if (m_files.size() == 0) info.clear(); @@ -543,6 +533,7 @@ void CleanTask::run() break; case CmdMove: { + assert(index < MAX_INDEX); QString target = m_targetDirs.at(index) + relPath + node; QString shadowDir = m_shadowDirs.at(index) + relPath; ReQStringUtils::chomp(shadowDir, OS_SEPARATOR); @@ -567,21 +558,22 @@ void CleanTask::run() error("unknown command: " + QString::number(command)); break; } - qint64 now = QDateTime::currentMSecsSinceEpoch(); - qint64 estimated = qint64(double(now - start) / max(1, m_processedFiles) * m_hotFiles); + double factor = double(m_hotFiles) / max(1, m_processedFiles); + qint64 duration = QDateTime::currentMSecsSinceEpoch() - start.currentMSecsSinceEpoch(); m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL, - tr("%1 of %2 (%3 of %4) %5 MB/sec Remaining: %6 of %7") - .arg(m_processedFiles).arg(m_hotFiles) - .arg(ReQStringUtils::readableSize(m_processedBytes)) - .arg(ReQStringUtils::readableSize(m_hotBytes)) - .arg(m_processedBytes / 1024.0 / 1024 / (now - start) * 1000, 0, 'f', 3) - .arg(ReQStringUtils::readableDuration(estimated - (now - start))) - .arg(ReQStringUtils::readableDuration(estimated))); + tr("%1 of %2 (%3 of %4) %5 MB/sec runtime: %6") + .arg(m_processedFiles) + .arg(m_hotFiles) + .arg(ReQStringUtils::readableSize(m_processedBytes)) + .arg(ReQStringUtils::readableSize(m_hotBytes)) + .arg(m_processedBytes / 1024.0 / 1024 * 1000 + / max(1.0, (double) duration), 0, 'f', 3) + .arg(ReQStringUtils::runtimeEstimation(start, factor))); } } m_mainWindow->externalTaskFinished(tr("backup complete after %1. Errors: %2") .arg(ReQStringUtils::readableDuration( - QDateTime::currentMSecsSinceEpoch() - start)) + QDateTime::currentMSecsSinceEpoch() - start.currentMSecsSinceEpoch())) .arg(m_mainWindow->errors())); } @@ -618,7 +610,7 @@ void SearchTask::run() qint64 start = QDateTime::currentMSecsSinceEpoch(); m_searchReady = false; QString targetDir, sourceDir; - for (int ix = 0; ix < m_sourceDirs.size(); ix++){ + for (int ix = 0; ! m_shouldStop && ix < m_sourceDirs.size(); ix++){ sourceDir = m_sourceDirs.at(ix); if (m_compareWithTarget) targetDir = m_targetDirs.at(ix) + ReFileUtils::nodeOf(sourceDir); @@ -652,7 +644,7 @@ void SearchTask::searchOneDirectory(const QString& source, QDirIterator it(source); QString info, node; int lengthBase = m_sourceDirs.at(index).length(); - assert(index < 0x7fff); + assert(index < MAX_INDEX); QString prefix; m_mutex.lock(); m_totalDirs++; @@ -770,7 +762,7 @@ void SearchTargetTask::searchOneDirectory(const QString& target, QDirIterator it(target); QString info, node, relPath; int lengthBase = m_targetDirs.at(index).length(); - assert(index < 0x7fff); + assert(index < MAX_INDEX); QString prefix; m_mutex.lock(); m_totalDirs++; @@ -855,7 +847,7 @@ void SearchTargetTask::moveToShadow(const QString& target, const QString& relPat error(QObject::tr("cannot move to shadow directory (%1): %2 -> %3") .arg(errno).arg(target).arg(shadow)); } else { - removeOlder(shadow, m_maxAge, index); + removeOlder(shadow, m_maxAge); } } } @@ -868,11 +860,14 @@ void SearchTargetTask::run() qint64 start = QDateTime::currentMSecsSinceEpoch(); m_searchReady = false; QString targetDir, sourceDir; - for (int ix = 0; ix < m_sourceDirs.size(); ix++){ + for (int ix = 0; ! m_shouldStop && ix < m_sourceDirs.size(); ix++){ sourceDir = m_sourceDirs.at(ix); targetDir = m_targetDirs.at(ix); searchOneDirectory(targetDir, sourceDir, ix); } + if (! m_shouldStop){ + removeOlder(m_shadowBaseDir, m_maxAge); + } m_searchReady = true; m_mainWindow->externalLog(tr( "Search in target finished: to process: %1 with %2 dirs to delete: %3 total: %4 " diff --git a/appl/rebackgui/BackupEngine.hpp b/appl/rebackgui/BackupEngine.hpp index f1f9bc8..80b1cac 100644 --- a/appl/rebackgui/BackupEngine.hpp +++ b/appl/rebackgui/BackupEngine.hpp @@ -35,7 +35,7 @@ public: bool log(const QString& message); protected: void initializeShadowDir(); - void removeOlder(const QString& directory, const QDateTime& time, int index); + void removeOlder(const QString& directory, const QDateTime& time); virtual void run() = 0; protected: // list of source dirs, trailing with separator diff --git a/appl/rebackgui/mainwindow.cpp b/appl/rebackgui/mainwindow.cpp index 339053e..2524d4d 100644 --- a/appl/rebackgui/mainwindow.cpp +++ b/appl/rebackgui/mainwindow.cpp @@ -629,7 +629,7 @@ void MainWindow::updateTableRow(int row, BackupItem& item, QTableWidget* target) target->setItem(row, base + 1, new QTableWidgetItem(item.m_target)); target->setItem(row, base + 2, new QTableWidgetItem(! item.m_lastBackup.isValid() ? "" : BackupUtils::dateToString(item.m_lastBackup))); - target->setItem(row, base + 3, new QTableWidgetItem(item.m_sources.join(" "))); + target->setItem(row, base + 3, new QTableWidgetItem(item.m_sources.join(";"))); } } diff --git a/appl/recommand/mainwindow.cpp b/appl/recommand/mainwindow.cpp index 7d6afdb..e8645e4 100644 --- a/appl/recommand/mainwindow.cpp +++ b/appl/recommand/mainwindow.cpp @@ -30,6 +30,8 @@ MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : connect(ui->pushButtonClearEdit, SIGNAL(clicked()), this, SLOT(onClearEdit())); connect(ui->pushButtonClearList, SIGNAL(clicked()), this, SLOT(onClearList())); connect(ui->pushButtonSave, SIGNAL(clicked()), this, SLOT(onSave())); + connect(ui->pushButtonInterpolate, SIGNAL(clicked()), this, SLOT(onInterpolate())); + connect(ui->pushButtonExpand, SIGNAL(clicked()), this, SLOT(onExpand())); onLoad(); } @@ -48,7 +50,7 @@ MainWindow::~MainWindow() */ void MainWindow::onClearEdit() { - ui->textEditResult->setText(""); + ui->plainTextEditResult->setPlainText(""); } /** @@ -59,6 +61,29 @@ void MainWindow::onClearList() ui->listWidgetResult->clear(); } +/** + * Copies the input buffer n times and replaces the placeholder with values. + * + * The values are taken from the values buffer. + */ +void MainWindow::onExpand() +{ + QString var = ui->lineEditVariable->text(); + if (var.isEmpty()) + say(LOG_ERROR, "cannot expand: no variable given"); + else { + QString block = ui->plainTextEditInput->toPlainText(); + QString vals = ui->plainTextEditValues->toPlainText(); + QStringList values = vals.split('\n'); + QString result; + result.reserve(block.length() * values.count() + vals.length()); + for (int ix = 0; ix < values.count(); ix++){ + result += QString(block).replace(var, values.at(ix)); + } + ui->plainTextEditResult->setPlainText(result); + } +} + /** * Set GUI elements from the queue when the GUI timer is triggered. */ @@ -94,14 +119,47 @@ void MainWindow::onGuiTimerUpdate() } } +/** + * Interpolates the range into the values buffer. + */ +void MainWindow::onInterpolate() +{ + QString range = ui->lineEditRange->text(); + QRegularExpression regExpr("^(\\d+)-(\\d+)(,(\\d+))?$"); + QRegularExpressionMatch match = regExpr.match(range); + QString lines; + if (match.hasMatch()){ + int from = match.captured(1).toInt(); + int to = match.captured(2).toInt(); + int step = match.captured(3).isEmpty() ? 1 : match.captured(4).toInt(); + for (int ix = from; ix <= to; ix += step){ + lines += QString::number(ix) + "\n"; + } + } else if (range.length() == 3 && range.at(1) == '-') { + QChar from = range.at(0); + QChar to = range.at(2); + for (QChar ix = from; ix <= to; ix = QChar(ix.unicode() + 1)){ + lines += QString(ix)+ "\n"; + } + } else { + say(LOG_ERROR, QObject::tr("wrong range: use - or -,")); + } + if (! lines.isEmpty()){ + QString content = ui->plainTextEditValues->toPlainText(); + if (! content.isEmpty() && ! content.endsWith("\n")) + lines = "\n" + lines; + ui->plainTextEditValues->setPlainText(content + lines); + } +} + /** * Executes the current commands. */ void MainWindow::onRun() { - QString text = ui->textEditPad->toPlainText(); + QString text = ui->plainTextEditPad->toPlainText(); int length = text.length(); - int position = min(ui->textEditPad->textCursor().position(), length - 1); + int position = min(ui->plainTextEditPad->textCursor().position(), length - 1); int pos1; for (pos1 = position; pos1 > 0; pos1--){ if (text.at(pos1) == '\n' && text.at(pos1 - 1) == '\n') @@ -116,7 +174,7 @@ void MainWindow::onRun() } if (pos2 < length - 1 && text.at(pos2 + 1) != '\n') pos2++; - ui->textEditResult->clear(); + ui->plainTextEditResult->clear(); QString script = text.mid(pos1, pos2 - pos1 + 1); if (script.length() > 10 || script.trimmed().length() > 0) m_processor->interpret(script); @@ -130,7 +188,7 @@ void MainWindow::onLoad() QString fname = m_homeDir + "pad.txt"; QByteArray content; ReFileUtils::readFromFile(I18N::s2b(fname).constData(), content); - ui->textEditPad->setText(QString::fromUtf8(content)); + ui->plainTextEditPad->setPlainText(QString::fromUtf8(content)); } @@ -141,7 +199,7 @@ void MainWindow::onSave() { QString fname = m_homeDir + "pad.txt"; ReFileUtils::writeToFile(I18N::s2b(fname).constData(), - ui->textEditPad->toPlainText().toUtf8().constData()); + ui->plainTextEditPad->toPlainText().toUtf8().constData()); } /** @@ -158,6 +216,7 @@ bool MainWindow::say(ReLoggerLevel level, const QString& message){ msg = "+ "; break; case LOG_ERROR: + setStatusMessage(level, message); msg = "! "; break; default: @@ -166,13 +225,13 @@ bool MainWindow::say(ReLoggerLevel level, const QString& message){ ui->listWidgetResult->addItem(msg + message); ui->listWidgetResult->setCurrentRow(ui->listWidgetResult->count() - 1); - QString edit = ui->textEditResult->toPlainText(); + QString edit = ui->plainTextEditResult->toPlainText(); if (! edit.isEmpty() && ! edit.endsWith("\n")){ msg += "\n"; } msg += message; edit += msg; - ui->textEditResult->setPlainText(edit); + ui->plainTextEditResult->setPlainText(edit); return level >= LOG_INFO; } diff --git a/appl/recommand/mainwindow.hpp b/appl/recommand/mainwindow.hpp index e6488ec..a75d985 100644 --- a/appl/recommand/mainwindow.hpp +++ b/appl/recommand/mainwindow.hpp @@ -32,6 +32,8 @@ public slots: virtual void onGuiTimerUpdate(); void onClearEdit(); void onClearList(); + void onExpand(); + void onInterpolate(); void onLoad(); void onRun(); void onSave(); diff --git a/appl/recommand/mainwindow.ui b/appl/recommand/mainwindow.ui index 3c57d02..ffd4d40 100644 --- a/appl/recommand/mainwindow.ui +++ b/appl/recommand/mainwindow.ui @@ -73,13 +73,13 @@ - + - 0 + 2 @@ -174,7 +174,7 @@ - + FreeMono @@ -184,6 +184,142 @@ + + + Buffers + + + + + + Qt::Horizontal + + + + + + + + + B0! (input) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Var: + + + + + + + + 75 + 16777215 + + + + $$$ + + + + + + + Copies the input buffer multiple times and replaces the variable with the values. Each line of B1! defines gives one block in the result buffer + + + Expand + + + + + + + + + + + + + + + + + + B1! (values) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Range: + + + + + + + + 125 + 16777215 + + + + Rage to create values, e.g. "2-64,3", "A-F" + + + + + + + Converts the range into values (appended at the end) + + + Interpol. + + + + + + + + + + + + + + diff --git a/base/ReQStringUtils.cpp b/base/ReQStringUtils.cpp index 74d2c23..48057d5 100644 --- a/base/ReQStringUtils.cpp +++ b/base/ReQStringUtils.cpp @@ -503,7 +503,7 @@ void ReQStringUtils::skipExpected(const ReString& text, QChar expected, } /** - * Returns a readable string for a duration given by clock_t. + * Returns a readable string for a duration given by milliseconds. * * @param durationMilliSec a duration in msec * @@ -536,7 +536,26 @@ QString ReQStringUtils::readableDuration(qint64 durationMilliSec){ } return rc; } - +/** + * Returns a readable string for a duration given by clock_t. + * + * @param start the time of the start + * @param factor the factor of the estimated runtime, should be < 1.0 + * + * @return a string describing the current runtime and the estimation. + */ +QString ReQStringUtils::runtimeEstimation(const QDateTime& start, + double factor){ + qint64 duration = QDateTime::currentMSecsSinceEpoch() - start.currentMSecsSinceEpoch(); + if (factor < 1) + factor = 1; + else if (factor <= 0.001) + factor = 0.001; + qint64 estimated = qint64((double) duration / factor); + QString rc = QObject::tr("%1 of %2").arg(readableDuration(duration)) + .arg(readableDuration(estimated)); + return rc; +} /** * Returns a readable string for a filesize. * diff --git a/base/ReQStringUtils.hpp b/base/ReQStringUtils.hpp index bdb9f28..6bb421f 100644 --- a/base/ReQStringUtils.hpp +++ b/base/ReQStringUtils.hpp @@ -77,6 +77,7 @@ public: static QString readableSize(int64_t filesize); static bool replacePlaceholders(QString& text, const QMap& placeholders, QString* error); + static QString runtimeEstimation(const QDateTime& start, double factor); static void skipExpected(const ReString& text, QChar expected, int& index, int& length); /**