From: hama Date: Sun, 24 Jan 2016 23:08:31 +0000 (+0100) Subject: dayly work X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=6d1e107a34b9a2d2ad80a76d0edc23db482874fe;p=reqt dayly work --- diff --git a/appl/rebackgui/BackupEngine.cpp b/appl/rebackgui/BackupEngine.cpp new file mode 100644 index 0000000..c01718e --- /dev/null +++ b/appl/rebackgui/BackupEngine.cpp @@ -0,0 +1,197 @@ +/* + * Licence: + * You can use and modify this file without any restriction. + * There is no warranty. + * You also can use the licence from http://www.wtfpl.net/. + * The original sources can be found on https://github.com/republib. +*/ + +#include "backupgui.hpp" + +bool BackupEngine::m_shouldStop = false; +QStringList BackupEngine::m_files; +qint64 BackupEngine::m_matchedBytes = 0; +int BackupEngine::m_matchedFiles = 0; +int BackupEngine::m_totalFiles = 0; +int BackupEngine::m_totalDirs = 0; +bool BackupEngine::m_searchReady = false; +QMutex BackupEngine::m_mutex; + +/** + * Constructor. + * + * @param sourceDirs the list of source directories to inspect + * @param targetDir the base of the target directories + * @param mainWindow the GUI module + */ +BackupEngine::BackupEngine(const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow) : + QThread(), + m_sourceDirs(sourceDirs), + m_targetDir(targetDir), + m_mainWindow(mainWindow) +{ + +} + +/** + * @brief Logs an error message. + * + * @param message the message to log + * @return false + * @throws ConverterException + */ +bool BackupEngine::error(const QString& message){ + m_mainWindow->externalError(message); + return false; +} + +/** + * @brief Logs a message. + * + * @param message the message to log + * @return true + */ +bool BackupEngine::log(const QString& message){ + //printf("%s\n", I18N::s2b(message).constData()); + m_mainWindow->externalLog(message); + return true; +} + +/** + * Constructor. + * + * @param filePatterns only files which match the patterns will be found + * @param dirPatterns only subdirectories which matches the patterns will be entered + * @param source the list of base directories to search + * @param targetDir the base target directory + * @param mainWindow the GUI module, the parent + */ +SearchTask::SearchTask(const QString& filePatterns, const QString& dirPatterns, + const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow) : + BackupEngine(sourceDirs, targetDir, mainWindow), + m_fileMatcher(filePatterns), + m_dirMatcher(dirPatterns) +{ + +} + +/** + * Runs the task. + */ +void SearchTask::run() +{ + qint64 start = QDateTime::currentMSecsSinceEpoch(); + m_searchReady = false; + for (int ix = 0; ix < m_sourceDirs.size(); ix++){ + processOneDirectory(m_sourceDirs.at(ix), m_targetDir, ix); + } + m_searchReady = true; + m_mainWindow->externalLog(tr("%1 matching file(s) under %2 with %3 in %4 subdirs %5") + .arg(m_matchedFiles).arg(m_totalFiles) + .arg(ReQStringUtils::readableSize(m_matchedBytes)) + .arg(m_totalDirs) + .arg(ReQStringUtils::readableDuration( + QDateTime::currentMSecsSinceEpoch() - start))); +} +/** + * Search the files to backup and write it to a list. + * + * This method is recursive. + * + * @param source the directory to inspect + * @param target "": no target directory exists
+ * otherwise: only files will be written if the file found in + * the source directory does not exists in this target or + * it is newer or has another size + * @param index the index of the base directory in m_sourceDirs + */ +void SearchTask::processOneDirectory(const QString& source, + const QString& target, int index){ + QDirIterator it(source); + QString relPath; + QString info; + int lengthBase = m_sourceDirs.at(index).length(); + if (source.length() > lengthBase){ + relPath = source.mid(lengthBase + 1) + OS_SEPARATOR_STR; + } + while (it.hasNext()){ + if (m_shouldStop){ + break; + } + it.next(); + if (it.fileInfo().isDir() && m_fileMatcher.matches(it.fileName()) >= 0){ + m_mutex.lock(); + m_totalFiles++; + m_mutex.unlock(); + } else { + bool doCopy = false; + if (! target.isEmpty()){ + QFileInfo trg(target + it.fileName()); + doCopy = trg.exists() && (trg.size() != it.fileInfo().size() + || trg.lastModified() > it.fileInfo().lastModified()); + } + if (doCopy) + info = relPath + "\t" + it.fileName(); + m_mutex.lock(); + if (doCopy){ + m_files.append(info); + } + m_totalFiles++; + m_matchedFiles++; + m_matchedBytes += it.fileInfo().size(); + m_mutex.unlock(); + } + } + if (! m_shouldStop){ + QDirIterator it2(source); + QString node; + QString subTarget; + while (it2.hasNext()){ + if (m_shouldStop){ + break; + } + it2.next(); + + if (it2.fileInfo().isDir() && (node = it2.fileName()) != "." && node != ".." + && m_dirMatcher.matches(node)){ + if (target.isEmpty()) + subTarget.clear(); + else{ + subTarget = target + it2.fileName() + OS_2nd_SEPARATOR_STR; + if (! ReFileUtils::isDirectory(subTarget)) + subTarget.clear(); + processOneDirectory(it2.filePath(), subTarget, index); + m_mutex.lock(); + m_totalDirs++; + m_mutex.unlock(); + } + } + } + } +} + +/** + * Constructor. + * + * @param sourceDirs the list of source directories to inspect + * @param targetDir the base of the target directories + * @param mainWindow the GUI module + */ +BackupTask::BackupTask(const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow) : + BackupEngine(sourceDirs, targetDir, mainWindow) +{ + +} + +/** + * Do the backup task. + */ +void BackupTask::run() +{ + while(! m_searchReady) + QThread::sleep(50); + m_mainWindow->externalTaskFinished("ready"); +} diff --git a/appl/rebackgui/BackupEngine.hpp b/appl/rebackgui/BackupEngine.hpp new file mode 100644 index 0000000..fb665c5 --- /dev/null +++ b/appl/rebackgui/BackupEngine.hpp @@ -0,0 +1,65 @@ +/* + * Licence: + * You can use and modify this file without any restriction. + * There is no warranty. + * You also can use the licence from http://www.wtfpl.net/. + * The original sources can be found on https://github.com/republib. +*/ + +#ifndef BACKUPPROCESSOR_HPP +#define BACKUPPROCESSOR_HPP + + +class BackupEngine : public QThread +{ +public: + BackupEngine(const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow); +public: + bool error(const QString& message); + bool log(const QString& message); +protected: + virtual void run() = 0; +protected: + QStringList m_sourceDirs; + QString m_targetDir; + MainWindow* m_mainWindow; +public: + static bool m_shouldStop; + static QStringList m_files; + static qint64 m_matchedBytes; + static int m_matchedFiles; + static int m_totalFiles; + static int m_totalDirs; + static bool m_searchReady; + static QMutex m_mutex; +}; + +class SearchTask : public BackupEngine +{ +public: + SearchTask(const QString& filePatterns, const QString& dirPatterns, + const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow); +public: + virtual void run(); +private: + QString m_filePatterns; + QString m_dirPatterns; + ReIncludeExcludeMatcher m_fileMatcher; + ReIncludeExcludeMatcher m_dirMatcher; + void processOneDirectory(const QString& source, const QString& target, + int index); +}; + +class BackupTask : public BackupEngine +{ +public: + BackupTask(const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow); +public: + virtual void run(); +protected: +}; + +#endif // BACKUPPROCESSOR_HPP diff --git a/appl/rebackgui/Configuration.cpp b/appl/rebackgui/Configuration.cpp index d3db984..633261c 100644 --- a/appl/rebackgui/Configuration.cpp +++ b/appl/rebackgui/Configuration.cpp @@ -116,16 +116,22 @@ void Configuration::load(QString filename) // ignore comments and empty lines: if (line[0] == '#' || line[strspn(line, " \t\r\n")] == '\0') continue; - line2.fromUtf8(line); + line2 = line2.fromUtf8(line); ReQStringUtils::chomp(line2); if (ReQStringUtils::hasPrefixAndNumber("name", line2, no, value)){ getItem(no, map).m_name = value; } else if (ReQStringUtils::hasPrefixAndNumber("sources", line2, no, value)){ getItem(no, map).m_sources = value.split(';'); } else if (ReQStringUtils::hasPrefixAndNumber("target", line2, no, value)){ - getItem(no, map).m_name = value; + getItem(no, map).m_target = value; + } else if (ReQStringUtils::hasPrefixAndNumber("filepatterns", line2, no, value)){ + getItem(no, map).m_filePatterns = value; + } else if (ReQStringUtils::hasPrefixAndNumber("dirpatterns", line2, no, value)){ + getItem(no, map).m_dirPatterns = value; } else if (ReQStringUtils::hasPrefixAndNumber("lastbackup", line2, no, value)){ - getItem(no, map).m_lastBackup.setMSecsSinceEpoch(value.toLongLong()); + qint64 time = value.toLongLong(); + if (time > 24*3600) + getItem(no, map).m_lastBackup.setMSecsSinceEpoch(time); } else { m_mainWindow->error(QObject::tr("unknown format in %1-%2: %3") .arg(filename).arg(lineNo) @@ -161,13 +167,15 @@ void Configuration::save(QString filename) QByteArray buffer; for (int ix = 0; ix < m_items.size(); ix++){ BackupItem& item = m_items[ix]; - buffer = "name." + QByteArray::number(ix + 1) + "=" + buffer = "name." + QByteArray::number(ix) + "=" + item.m_name.toUtf8() + "\n"; - buffer += "sources." + QByteArray::number(ix + 1) + "=" + buffer += "sources." + QByteArray::number(ix) + "=" + item.m_sources.join(';').toUtf8() + "\n"; - buffer += "target." + QByteArray::number(ix + 1) + "=" + buffer += "target." + QByteArray::number(ix) + "=" + + item.m_target.toUtf8() + "\n"; + buffer += "target." + QByteArray::number(ix) + "=" + item.m_target.toUtf8() + "\n"; - buffer += "lastbackup." + QByteArray::number(ix + 1) + "=" + buffer += "lastbackup." + QByteArray::number(ix) + "=" + item.m_lastBackup.toString("yyyy.MM.dd/hh:mm") + "\n"; if (fputs(buffer.constData(), fp) != buffer.length()) m_mainWindow->error(QObject::tr("cannot write (%1): %2").arg(errno) diff --git a/appl/rebackgui/Configuration.hpp b/appl/rebackgui/Configuration.hpp index af9a4a6..7ea2986 100644 --- a/appl/rebackgui/Configuration.hpp +++ b/appl/rebackgui/Configuration.hpp @@ -21,6 +21,8 @@ public: QStringList m_sources; QString m_target; QDateTime m_lastBackup; + QString m_filePatterns; + QString m_dirPatterns; }; typedef QMap BackupItemMap; typedef QList BackupItemList; diff --git a/appl/rebackgui/backupgui.hpp b/appl/rebackgui/backupgui.hpp index 4df436c..ea5db17 100644 --- a/appl/rebackgui/backupgui.hpp +++ b/appl/rebackgui/backupgui.hpp @@ -11,6 +11,7 @@ #include "base/rebase.hpp" #include "gui/regui.hpp" #include "Configuration.hpp" +#include "BackupEngine.hpp" #include "mainwindow.hpp" #include "ui_mainwindow.h" diff --git a/appl/rebackgui/mainwindow.cpp b/appl/rebackgui/mainwindow.cpp index e171b90..38ed855 100644 --- a/appl/rebackgui/mainwindow.cpp +++ b/appl/rebackgui/mainwindow.cpp @@ -14,11 +14,14 @@ const QString VERSION("2016.01.20"); MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : ReGuiApplication("rebackupgui", homeDir, 2, 100100100, parent), + ReGuiValidator(), ui(new Ui::MainWindow), m_configuration(this), m_currentRowConfiguration(0), m_currentRowBackup(0), - m_lastSource() + m_lastSource(), + m_searchTask(NULL), + m_backupTask(NULL) { ui->setupUi(this); initializeGuiElements(); @@ -32,6 +35,7 @@ MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : connect(ui->pushButtonAddItem, SIGNAL(clicked()), this, SLOT(onAddItem())); connect(ui->pushButtonDeleteItem, SIGNAL(clicked()), this, SLOT(onDeleteItem())); connect(ui->pushButtonAddSource, SIGNAL(clicked()), this, SLOT(onAddSource())); + connect(ui->pushButtonDeleteSource, SIGNAL(clicked()), this, SLOT(onDeleteSource())); connect(ui->pushButtonSelectTarget, SIGNAL(clicked()), this, SLOT(onSelectTarget())); connect(ui->pushButtonSaveConfig, SIGNAL(clicked()), this, SLOT(onSaveConfig())); connect(ui->pushButtonUpdate, SIGNAL(clicked()), this, SLOT(onUpdate())); @@ -172,7 +176,10 @@ void MainWindow::onDeleteItem() */ void MainWindow::onDeleteSource() { - + int row = ui->listWidgetSource->selectionModel()->currentIndex().row(); + if (row >= 0){ + ui->listWidgetSource->takeItem(row); + } } void MainWindow::onSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected){ @@ -215,10 +222,11 @@ void MainWindow::onSelectTarget(){ * @param dir the directory on the external medium (already mounted) */ void MainWindow::findTarget(const QString& dir){ + QString target = ";" + dir; #if defined __linux__ - #else #endif + ui->lineEditTarget->setText(target); } /** @@ -247,17 +255,41 @@ void MainWindow::onSaveConfig(){ m_configuration.save(""); } +/** + * Builds the target directory. + * + * @return the target directory + */ +QString MainWindow::buildTargetFile(){ + QString rc = ui->lineEditTarget->text(); + int ix = rc.indexOf(rc, ';'); + if (ix == 0) + rc.remove(0, 1); + return rc; +} + /** * Starts the backup. */ void MainWindow::onStart(){ startStop(true); + int row = ui->tableWidget->currentRow(); + const BackupItem& item = m_configuration.items().at(row); + delete m_searchTask; + m_searchTask = new SearchTask(item.m_filePatterns, item.m_dirPatterns, + item.m_sources, buildTargetFile(), + this); + m_searchTask->start(); + delete m_backupTask; + m_backupTask = new BackupTask(item.m_sources, buildTargetFile(), + this); + } /** * Stops the backup. */ void MainWindow::onStop(){ - startStop(false); + BackupEngine::m_shouldStop = true; } /** @@ -267,11 +299,32 @@ void MainWindow::onUpdate(){ BackupItem& item = m_configuration.items()[m_currentRowConfiguration]; item.m_name = ui->lineEditName->text(); item.m_target = ui->lineEditTarget->text(); + item.m_filePatterns = comboText(ui->comboBoxFilePatterns); + item.m_dirPatterns = comboText(ui->comboBoxDirPatterns); item.m_sources.clear(); for (int ix = 0; ix < ui->listWidgetSource->count(); ix++){ item.m_sources.append(ui->listWidgetSource->item(ix)->text()); } updateTable(); + saveState(); +} + + +/** + * Show a message. + * + * @param level LOG_ERROR or LOG_INFO + * @param message the message to show + * @return false: the message is an error message + */ +bool MainWindow::say(ReLoggerLevel level, const QString& message) +{ + if (level == LOG_ERROR) + error(message); + else + log(message); + setStatusMessage(level, message); + return level >= LOG_INFO; } /** @@ -285,6 +338,27 @@ void MainWindow::setStatusMessage(bool error, const QString& message){ m_statusMessage->setText(message); } +/** + * Reads the history of the widget values and other parameters and set it. + */ +void MainWindow::restoreState(){ + ReStateStorage storage(m_storageFile, &m_logger); + storage.setForm("main"); + storage.restore(ui->comboBoxFilePatterns, "comboBoxFilePatterns", false); + storage.restore(ui->comboBoxDirPatterns, "comboBoxDirPatterns", false); + storage.close(); +} + +/** + * Stores the history of the widget values and other parameters. + */ +void MainWindow::saveState(){ + ReStateStorage storage(m_storageFile, &m_logger); + storage.setForm("main"); + storage.store(ui->comboBoxFilePatterns, "comboBoxFilePatterns"); + storage.store(ui->comboBoxDirPatterns, "comboBoxDirPatterns"); + storage.close(); +} /** * Starts or stops the backup. * @@ -310,6 +384,8 @@ void MainWindow::updateItem(int index){ ui->lineEditName->setText(item.m_name); ui->lineEditTarget->setText(item.m_target); ui->listWidgetSource->clear(); + ui->comboBoxFilePatterns->setEditText(item.m_filePatterns); + ui->comboBoxDirPatterns->setEditText(item.m_dirPatterns); for (int ix = 0; ix < item.m_sources.size(); ix++){ ui->listWidgetSource->insertItem(ix, m_lastSource = item.m_sources.at(ix)); } @@ -356,3 +432,4 @@ void MainWindow::updateTableRow(int row, BackupItem& item, QTableWidget* target) } + diff --git a/appl/rebackgui/mainwindow.hpp b/appl/rebackgui/mainwindow.hpp index 78fc425..ea6a7fa 100644 --- a/appl/rebackgui/mainwindow.hpp +++ b/appl/rebackgui/mainwindow.hpp @@ -15,7 +15,7 @@ namespace Ui { class MainWindow; } -class MainWindow : public ReGuiApplication +class MainWindow : public ReGuiApplication, public ReGuiValidator { Q_OBJECT @@ -23,10 +23,14 @@ public: explicit MainWindow(const QString& homeDir, QWidget *parent = 0); ~MainWindow(); public: + QString buildTargetFile(); bool error(const QString& message); bool log(const QString& message); + virtual bool say(ReLoggerLevel level, const QString& message); void setStatusMessage(bool error, const QString& message); void startStop(bool isStart); + void restoreState(); + void saveState(); private slots: virtual void aboutToQuit(); void findTarget(const QString& dir); @@ -53,6 +57,8 @@ private: int m_currentRowConfiguration; int m_currentRowBackup; QString m_lastSource; + SearchTask* m_searchTask; + BackupTask* m_backupTask; }; #endif // MAINWINDOW_HPP diff --git a/appl/rebackgui/mainwindow.ui b/appl/rebackgui/mainwindow.ui index 2f10162..945433d 100644 --- a/appl/rebackgui/mainwindow.ui +++ b/appl/rebackgui/mainwindow.ui @@ -7,7 +7,7 @@ 0 0 820 - 654 + 679 @@ -18,7 +18,7 @@ - 0 + 1 @@ -384,7 +384,57 @@ - ... + Select target + + + + + + + + + + + + 125 + 0 + + + + File patterns: + + + + + + + <html><head/><body><p>A comma (',') separated list of filename patterns. A prefix of '-' means inversion: if a filename matches it will not be found.</p><p>Example: *.txt,*.odt</p></body></html> + + + true + + + + + + + + 125 + 0 + + + + Dir patterns: + + + + + + + <html><head/><body><p>A comma (',') separated list of directory name patterns. A prefix of '-' means inversion: if a directory name matches it will not be found.</p><p>Example: *,-.git,-*cache*</p></body></html> + + + true @@ -394,8 +444,14 @@ + + + 125 + 0 + + - Source directories: + Source dirs: diff --git a/appl/rebackgui/rebackgui.pro b/appl/rebackgui/rebackgui.pro index f8e147b..49b131a 100644 --- a/appl/rebackgui/rebackgui.pro +++ b/appl/rebackgui/rebackgui.pro @@ -16,13 +16,16 @@ SOURCES += main.cpp\ ../../base/ReException.cpp \ ../../base/ReQStringUtils.cpp \ ../../base/ReFileUtils.cpp \ + ../../base/ReMatcher.cpp \ ../../base/ReLogger.cpp \ ../../gui/ReStateStorage.cpp \ ../../gui/ReGuiApplication.cpp \ + ../../gui/ReGuiValidator.cpp \ ../../gui/ReGuiQueue.cpp \ mainwindow.cpp \ aboutdialog.cpp \ - Configuration.cpp + Configuration.cpp \ + BackupEngine.cpp HEADERS += mainwindow.hpp \ ../../base/rebase.hpp \ @@ -32,7 +35,8 @@ HEADERS += mainwindow.hpp \ ../../gui/regui.hpp \ aboutdialog.hpp \ Configuration.hpp \ - backupgui.hpp + backupgui.hpp \ + BackupEngine.hpp FORMS += mainwindow.ui \ aboutdialog.ui diff --git a/appl/reimgconvert/converter.cpp b/appl/reimgconvert/converter.cpp index 20c3e9d..3302c0d 100644 --- a/appl/reimgconvert/converter.cpp +++ b/appl/reimgconvert/converter.cpp @@ -253,7 +253,7 @@ void TaskConverter::convertOneFile(const QString& source, const QString& target, int width = 0; int height = 0; QString info; - clock_t start = clock(); + qint64 start = QDateTime::currentMSecsSinceEpoch(); if (readProperties(source, width, height, info)){ int widthNew = width; int heightNew = height; @@ -276,7 +276,8 @@ void TaskConverter::convertOneFile(const QString& source, const QString& target, preSize += size; postSize += fileInfo.st_size; message += "-> " + info + " " + ReQStringUtils::readableSize(fileInfo.st_size) - + " " + ReQStringUtils::readableDuration(clock() - start); + + " " + ReQStringUtils::readableDuration( + QDateTime::currentMSecsSinceEpoch() - start); log(message); int percentFiles = int(no * 100 / max(1, m_totalFiles)); int percentSize = int(preSize * 100 / max(1, min(preSize, m_totalBytes))); diff --git a/base/ReFileUtils.cpp b/base/ReFileUtils.cpp index 12041a9..fe2b822 100644 --- a/base/ReFileUtils.cpp +++ b/base/ReFileUtils.cpp @@ -270,6 +270,26 @@ bool ReFileUtils::isAbsolutPath(const char* path) { return rc; } +/** + * Tests whether a path is a directory. + * + * @param path full name of the directory to inspect + * @param isFile OUT: true: this is a file (and not a directory) + * @return true: path is a directory + */ +bool ReFileUtils::isDirectory(const QString& path, bool* isFile) +{ + QFileInfo info(path); + bool rc = info.exists(); + if (rc){ + if (isFile != NULL) + *isFile = true; + if (! info.isDir()) + rc = false; + } + return rc; +} + /** * Checks whether path is a root directory. * diff --git a/base/ReFileUtils.hpp b/base/ReFileUtils.hpp index bd5aace..5ba8f07 100644 --- a/base/ReFileUtils.hpp +++ b/base/ReFileUtils.hpp @@ -36,6 +36,7 @@ public: static QByteArray extensionOf(const char* filename); static bool isAbsolutPath(const QString& path); static bool isAbsolutPath(const char* path); + static bool isDirectory(const QString& path, bool* isFile = NULL); static bool isRootDir(const char* path); /** Returns a path with native separators. * QT under windows can operator with 2 separators: '\\' and '/'. diff --git a/base/ReQStringUtils.cpp b/base/ReQStringUtils.cpp index e8ad967..350f7c2 100644 --- a/base/ReQStringUtils.cpp +++ b/base/ReQStringUtils.cpp @@ -100,7 +100,7 @@ bool ReQStringUtils::hasPrefixAndNumber(const QString prefix, const QString& lin if (line.at(lengthPrefix + 1 + lengthNumber) == '='){ no = number; rc = true; - value = line.mid(lengthPrefix + 1 + lengthNumber); + value = line.mid(lengthPrefix + 2 + lengthNumber); } } } @@ -505,14 +505,14 @@ void ReQStringUtils::skipExpected(const ReString& text, QChar expected, /** * Returns a readable string for a duration given by clock_t. * - * @param duration a duration measured by clock() + * @param duration a duration in msec * * @return a string describing the duration. */ -QString ReQStringUtils::readableDuration(clock_t duration){ +QString ReQStringUtils::readableDuration(qint64 duration){ QString rc; char buffer[128]; - double duration2 = (double) duration / CLOCKS_PER_SEC; + double duration2 = (double) duration / 1000; if (duration2 < 60.0){ rc = QString::number(duration2, 'f', 3) + " sec"; } else if (duration2 < 3600.0){ diff --git a/base/ReQStringUtils.hpp b/base/ReQStringUtils.hpp index 22cf850..a82853a 100644 --- a/base/ReQStringUtils.hpp +++ b/base/ReQStringUtils.hpp @@ -73,7 +73,7 @@ public: return path; #endif } - static QString readableDuration(clock_t duration); + static QString readableDuration(qint64 duration); static QString readableSize(int64_t filesize); static bool replacePlaceholders(QString& text, const QMap& placeholders, QString* error);