*/
BackupItem::BackupItem() :
m_no(0),
- m_uid(),
+ m_uid(),
m_name(),
m_sources(),
m_target(),
*/
BackupItem::BackupItem(int no) :
m_no(no),
- m_uid(),
+ m_uid(),
m_name(),
m_sources(),
m_target(),
{
BackupItem item(m_items.size());
item.m_name = QObject::tr("item") + QString::number(item.m_no + 1);
- item.m_uid = QString(ReRandomizer::buildUUID());
+ item.m_uid = QString(ReRandomizer::buildUUID());
m_items.append(item);
}
if (m_items.size() == 0){
appendNew();
}
- for (int ix =0; ix < m_items.size(); ix++){
- BackupItem& item = m_items[ix];
- if (item.m_uid.isEmpty())
- item.m_uid = QString(ReRandomizer::buildUUID());
- }
+ for (int ix =0; ix < m_items.size(); ix++){
+ BackupItem& item = m_items[ix];
+ if (item.m_uid.isEmpty())
+ item.m_uid = QString(ReRandomizer::buildUUID());
+ }
}
/**
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("uid", line2, no, value)){
- getItem(no, map).m_uid = value;
- } else if (ReQStringUtils::hasPrefixAndNumber("target", line2, no, value)){
- getItem(no, map).m_target = value;
- } else if (ReQStringUtils::hasPrefixAndNumber("filepatterns", line2, no, value)){
+ } else if (ReQStringUtils::hasPrefixAndNumber("uid", line2, no, value)){
+ getItem(no, map).m_uid = value;
+ } else if (ReQStringUtils::hasPrefixAndNumber("target", line2, no, 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;
QByteArray buffer;
for (int ix = 0; ix < m_items.size(); ix++){
BackupItem& item = m_items[ix];
- buffer = "name." + QByteArray::number(ix) + "="
- + item.m_name.toUtf8() + "\n";
- buffer += "uid." + QByteArray::number(ix) + "="
- + item.m_uid.toUtf8() + "\n";
- buffer += "sources." + QByteArray::number(ix) + "="
+ buffer = "name." + QByteArray::number(ix) + "="
+ + item.m_name.toUtf8() + "\n";
+ buffer += "uid." + QByteArray::number(ix) + "="
+ + item.m_uid.toUtf8() + "\n";
+ buffer += "sources." + QByteArray::number(ix) + "="
+ item.m_sources.join(';').toUtf8() + "\n";
buffer += "target." + QByteArray::number(ix) + "="
+ item.m_target.toUtf8() + "\n";
buffer += "dirpatterns." + QByteArray::number(ix) + "="
+ item.m_dirPatterns.toUtf8() + "\n";
buffer += "lastbackup." + QByteArray::number(ix) + "="
- + BackupUtils::dateToString(item.m_lastBackup) + "\n";
- if (fputs(buffer.constData(), fp) != buffer.length())
+ + BackupUtils::dateToString(item.m_lastBackup) + "\n";
+ if (fputs(buffer.constData(), fp) < 0)
m_mainWindow->error(QObject::tr("cannot write (%1): %2").arg(errno)
.arg(filename));
}
m_currentRowBackup(0),
m_lastSource(),
m_searchTask(NULL),
- m_backupTask(NULL),
- m_errors(0)
+ m_backupTask(NULL),
+ m_errors(0)
{
ui->setupUi(this);
initializeGuiElements();
bool MainWindow::error(const QString& message){
ui->listWidgetError->addItem(message);
ui->listWidgetError->setCurrentRow(ui->listWidgetError->count() - 1);
- m_errors++;
+ m_errors++;
return false;
}
+/**
+ * Returns the count of errors since the last start of the backup.
+ *
+ * @return the current count of errors
+ */
+int MainWindow::errors() const
+{
+ return m_errors;
+}
/**
* Find the target identification.
* Handles the push of the button "select directory".
*/
void MainWindow::onAddSource(){
- QFileDialog dialog(NULL);
- dialog.setOption(QFileDialog::ShowDirsOnly, true);
- // native dialog does not support multiselection:
- dialog.setOption(QFileDialog::DontUseNativeDialog,true);
- dialog.setFileMode(QFileDialog::Directory);
- dialog.setWindowTitle(tr("Select Source Directory"));
- dialog.setDirectory(ReFileUtils::parentOf(m_lastSource));
- QListView *listView = dialog.findChild<QListView*>("listView");
- if (listView) {
- listView->setSelectionMode(QAbstractItemView::MultiSelection);
- }
- QTreeView *treeView = dialog.findChild<QTreeView*>();
- if (treeView) {
- treeView->setSelectionMode(QAbstractItemView::MultiSelection);
- }
-
- if (dialog.exec()){
- QStringList dirs = dialog.selectedFiles();
- if (dirs.size() > 0){
- m_lastSource = ReFileUtils::nativePath(dirs.at(0));
- for (int ix = 0; ix < dirs.size(); ix++){
- QString newEntry = ReFileUtils::nativePath(dirs.at(ix));
- bool found = false;
- for (int ix2 = 0; ! found && ix2 < ui->listWidgetSource->count(); ix2++){
- QString oldEntry = ui->listWidgetSource->item(ix2)->text();
- if (oldEntry.isEmpty()){
- ui->listWidgetSource->takeItem(ix2);
- ix2--;
- }
- found = oldEntry == newEntry;
- }
- if (! found)
- ui->listWidgetSource->addItem(newEntry);
- }
- }
+QStringList dirs = ReGuiUtils::selectDirectories(tr("Select Source Directory"),
+ ReFileUtils::parentOf(m_lastSource));
+ m_lastSource = ReFileUtils::nativePath(dirs.at(0));
+ for (int ix = 0; ix < dirs.size(); ix++){
+ QString newEntry = ReFileUtils::nativePath(dirs.at(ix));
+ bool found = false;
+ for (int ix2 = 0; ! found && ix2 < ui->listWidgetSource->count(); ix2++){
+ QString oldEntry = ui->listWidgetSource->item(ix2)->text();
+ if (oldEntry.isEmpty()){
+ ui->listWidgetSource->takeItem(ix2);
+ ix2--;
+ }
+ found = oldEntry == newEntry;
+ }
+ if (! found)
+ ui->listWidgetSource->addItem(newEntry);
}
}
* Handles the push of the button "select directory".
*/
void MainWindow::onSelectTarget(){
- QString dir = QFileDialog::getExistingDirectory(this,
- tr("Select Target Directory"), m_lastSource,
- QFileDialog::ShowDirsOnly);
+ QString dir = ui->lineEditTarget->text();
+ int pos = dir.indexOf(';');
+ if (pos < 0){
+ dir.clear();
+ } else {
+ dir.remove(0, pos + 1);
+ if (! ReFileUtils::isAbsolutPath(dir))
+ dir.clear();
+ }
+ dir = ReGuiUtils::selectDirectory(tr("Select Target Directory"), dir);
if (!dir.isEmpty()){
dir = ReFileUtils::nativePath(dir);
extractTarget(dir);
if (row < 0){
say(LOG_ERROR, tr("no backup item selected"));
} else {
- const BackupItem& item = m_configuration.items().at(row);
+ BackupItem& item = m_configuration.items()[row];
BackupEngine::m_searchReady = false;
BackupEngine::m_hotBytes = 0;
BackupEngine::m_hotFiles = 0;
BackupEngine::m_totalFiles = 0;
BackupEngine::m_processedFiles = 0;
BackupEngine::m_processedBytes = 0;
- m_errors = 0;
+ m_errors = 0;
QString target = BackupUtils::findTarget(item, &m_logger);
if (target.isEmpty()){
say(LOG_ERROR, tr("Target not available"));
} else {
ReQStringUtils::ensureLastChar(target, OS_SEPARATOR);
+ writeTargetConfiguration(item, target);
startStop(true);
delete m_searchTask;
m_searchTask = new SearchTask(item.m_name,
*/
void MainWindow::updateItem(int index){
m_currentRowConfiguration = index;
- if (index < m_configuration.items().size()){
- BackupItem& item = m_configuration.items()[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));
- }
- }
+ if (index < m_configuration.items().size()){
+ BackupItem& item = m_configuration.items()[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));
+ }
+ }
}
/**
target->setItem(row, base + 3, new QTableWidgetItem(item.m_sources.join(" ")));
}
}
-int MainWindow::errors() const
-{
- return m_errors;
-}
+/**
+ * Write the current settings into the configuration file of the target.
+ *
+ * @param item the backup item
+ * @param target
+ */
+void MainWindow::writeTargetConfiguration(BackupItem& item, const QString& target){
+ QByteArray markerFile = I18N::s2b(BackupUtils::nameOfTargetDescription(target));
+
+ QByteArray keyPrefix = item.m_uid.toLatin1() + ".";
+ ReConfig config(markerFile, false, &m_logger);
+ item.m_lastBackup = QDateTime::currentDateTime();
+ if (config.asString(keyPrefix + "created", "").isEmpty())
+ config.put(keyPrefix + "created",
+ BackupUtils::dateToString(item.m_lastBackup).toLatin1().constData());
+ config.put(keyPrefix + "lastbackup",
+ BackupUtils::dateToString(item.m_lastBackup).toLatin1().constData());
+ config.put(keyPrefix + "sources", I18N::s2b(item.m_sources.join(';')).constData());
+ config.put(keyPrefix + "filepatterns", I18N::s2b(item.m_filePatterns).constData());
+ config.put(keyPrefix + "dirpatterns", I18N::s2b(item.m_dirPatterns).constData());
+ // store the last backup:
+ updateTable();
+ onSaveConfig();
+}
+
private:
QString extractTarget(const QString& dir);
+ void writeTargetConfiguration(BackupItem& item, const QString& target);
private slots:
virtual void aboutToQuit();
virtual void guiTimerUpdate();
QString m_lastSource;
SearchTask* m_searchTask;
BackupTask* m_backupTask;
- int m_errors;
+ int m_errors;
};
#endif // MAINWINDOW_HPP
-#-------------------------------------------------\r
-#\r
-# Project created by QtCreator 2016-01-18T00:51:17\r
-#\r
-#-------------------------------------------------\r
-\r
-QT += core gui\r
-\r
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets\r
-\r
-TARGET = rebackgui\r
-TEMPLATE = app\r
-INCLUDEPATH = ../.. /usr/include/c++/4.9\r
-\r
-SOURCES += main.cpp\\r
- ../../base/ReException.cpp \\r
- ../../base/ReConfig.cpp \\r
- ../../base/ReQStringUtils.cpp \\r
- ../../base/ReFileUtils.cpp \\r
- ../../base/ReMatcher.cpp \\r
- ../../base/ReLogger.cpp \\r
- ../../base/ReRandomizer.cpp \\r
- ../../base/ReStringUtils.cpp \\r
- ../../gui/ReStateStorage.cpp \\r
- ../../gui/ReGuiApplication.cpp \\r
- ../../gui/ReGuiValidator.cpp \\r
- ../../gui/ReGuiQueue.cpp \\r
- mainwindow.cpp \\r
- aboutdialog.cpp \\r
- Configuration.cpp \\r
- BackupEngine.cpp \\r
- BackupUtils.cpp\r
-\r
-HEADERS += mainwindow.hpp \\r
- ../../base/rebase.hpp \\r
- ../../base/ReQStringUtils.hpp \\r
- ../../gui/ReStateStorage.hpp \\r
- ../../gui/ReGuiValidator.hpp \\r
- ../../gui/regui.hpp \\r
- aboutdialog.hpp \\r
- Configuration.hpp \\r
- backupgui.hpp \\r
- BackupEngine.hpp \\r
- BackupUtils.hpp\r
-\r
-FORMS += mainwindow.ui \\r
- aboutdialog.ui\r
-\r
-DISTFILES += \\r
- ReBackGui.html\r
-\r
+#-------------------------------------------------
+#
+# Project created by QtCreator 2016-01-18T00:51:17
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = rebackgui
+TEMPLATE = app
+INCLUDEPATH = ../.. /usr/include/c++/4.9
+
+SOURCES += main.cpp\
+ ../../base/ReException.cpp \
+ ../../base/ReConfig.cpp \
+ ../../base/ReQStringUtils.cpp \
+ ../../base/ReFileUtils.cpp \
+ ../../base/ReMatcher.cpp \
+ ../../base/ReLogger.cpp \
+ ../../base/ReRandomizer.cpp \
+ ../../base/ReStringUtils.cpp \
+ ../../gui/ReStateStorage.cpp \
+ ../../gui/ReGuiApplication.cpp \
+ ../../gui/ReGuiValidator.cpp \
+ ../../gui/ReGuiQueue.cpp \
+ ../../gui/ReGuiUtils.cpp \
+ mainwindow.cpp \
+ aboutdialog.cpp \
+ Configuration.cpp \
+ BackupEngine.cpp \
+ BackupUtils.cpp
+
+HEADERS += mainwindow.hpp \
+ ../../base/rebase.hpp \
+ ../../base/ReQStringUtils.hpp \
+ ../../gui/ReStateStorage.hpp \
+ ../../gui/ReGuiValidator.hpp \
+ ../../gui/regui.hpp \
+ ../../gui/ReGuiUtils.hpp \
+ aboutdialog.hpp \
+ Configuration.hpp \
+ backupgui.hpp \
+ BackupEngine.hpp \
+ BackupUtils.hpp
+
+FORMS += mainwindow.ui \
+ aboutdialog.ui
+
+DISTFILES += \
+ ReBackGui.html
+
* @param logger NULL or a logger
*/
ReConfig::ReConfig(const char* file, bool readOnly, ReLogger* logger) :
- m_file(file),
- m_lineList(),
- m_readOnly(readOnly),
- m_logger(logger),
- m_ownLogger(logger == NULL),
- m_modified(false){
+ m_file(file),
+ m_lineList(),
+ m_readOnly(readOnly),
+ m_logger(logger),
+ m_ownLogger(logger == NULL),
+ m_modified(false){
if (logger == NULL) {
initLogger();
}
* Frees the resources.
*/
ReConfig::~ReConfig() {
- if (! m_readOnly && m_modified)
- write(m_file);
+ if (! m_readOnly && m_modified)
+ write(m_file);
if (m_ownLogger)
delete m_logger;
m_logger = NULL;
if (contains(key)) {
QByteArray value = (*this)[key].toLower();
rc = value == "1" || value == "y" || value == "yes" || value == "t"
- || value == "true";
+ || value == "true";
}
return rc;
if (contains(key)) {
rc = (*this)[key];
}
- return rc;
+ return rc;
}
/**
*/
void ReConfig::put(const char *key, bool value)
{
- put(key, value ? "true" : "false");
+ put(key, value ? "true" : "false");
}
/**
*/
void ReConfig::put(const char *key, int value)
{
- put(key, QByteArray::number(value).constData());
+ put(key, QByteArray::number(value).constData());
}
/**
*/
void ReConfig::put(const char *key, const char *value)
{
- m_modified = true;
- if (! contains(key)){
- m_lineList.append(key + QByteArray("="));
- }
- insert(key, value);
+ m_modified = true;
+ if (! contains(key)){
+ m_lineList.append(key + QByteArray("="));
+ }
+ insert(key, value);
}
/**
bool ReConfig::read(const char* file) {
bool rc = true;
m_lineList.reserve(1024);
- if (file == NULL)
- file = m_file.constData();
+ if (file == NULL)
+ file = m_file.constData();
FILE* fp = fopen(file, "r");
if (fp == NULL) {
m_logger->logv(LOG_ERROR, LOC_READ_1, "cannot read: %s", file);
value = value.trimmed();
if (contains(key))
m_logger->logv(LOG_WARNING, LOC_READ_2,
- "defined more than once: %s-%d: %s", file, lineNo,
- line);
+ "defined more than once: %s-%d: %s", file, lineNo,
+ line);
else
insert(key, value);
}
if (m_readOnly)
m_logger->log(LOG_ERROR, LOC_WRITE_1, "cannot write: (readonly");
else {
- if (file == NULL){
- file = m_file.constData();
- }
- int pos = 0;
- QByteArray key;
- FILE* fp = fopen(file, "w");
- if (fp == NULL)
- m_logger->logv(LOG_ERROR, LOC_WRITE_2, "cannot open (%d): %s", errno, file);
- else {
- for (int ix = 0; ix < m_lineList.size(); ix++){
- QByteArray& line = m_lineList[ix];
- if (isalnum(line[0]) && (pos = line.indexOf('=')) >= 0) {
- key = line.mid(0, pos);
- if (contains(key))
- line = key + "=" + value(key) + "\n";
- }
- fputs(line.constData(), fp);
- }
- fclose(fp);
- }
- }
+ if (file == NULL){
+ file = m_file.constData();
+ }
+ int pos = 0;
+ QByteArray key;
+ FILE* fp = fopen(file, "w");
+ if (fp == NULL)
+ m_logger->logv(LOG_ERROR, LOC_WRITE_2, "cannot open (%d): %s", errno, file);
+ else {
+ for (int ix = 0; ix < m_lineList.size(); ix++){
+ QByteArray& line = m_lineList[ix];
+ if (isalnum(line[0]) && (pos = line.indexOf('=')) >= 0) {
+ key = line.mid(0, pos);
+ if (contains(key))
+ line = key + "=" + value(key) + "\n";
+ }
+ fputs(line.constData(), fp);
+ }
+ fclose(fp);
+ }
+ m_modified = false;
+ }
return rc;
}
--- /dev/null
+/*
+ * 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 "base/rebase.hpp"
+#include "gui/regui.hpp"
+#include <QFileDialog>
+#include <QListView>
+#include <QTreeView>
+/**
+ * Executes a directory selection dialog.
+ *
+ * Starts a non native dialog.
+ *
+ * @param title the dialog title
+ * @param directory "" or the start directory
+ * @return empty list: nothing selected<br>
+ * the list with the selected directories
+ */
+QStringList ReGuiUtils::selectDirectories(const QString& title, const QString& directory)
+{
+ QFileDialog dialog(NULL);
+ dialog.setOption(QFileDialog::ShowDirsOnly, true);
+ // native dialog does not support multiselection:
+ dialog.setOption(QFileDialog::DontUseNativeDialog,true);
+ dialog.setFileMode(QFileDialog::Directory);
+ dialog.setWindowTitle(title);
+ if (!directory.isEmpty())
+ dialog.setDirectory(directory);
+ QListView *listView = dialog.findChild<QListView*>("listView");
+ if (listView) {
+ listView->setSelectionMode(QAbstractItemView::MultiSelection);
+ }
+ QTreeView *treeView = dialog.findChild<QTreeView*>();
+ if (treeView) {
+ treeView->setSelectionMode(QAbstractItemView::MultiSelection);
+ }
+ QStringList dirs;
+ if (dialog.exec()){
+ dirs = dialog.selectedFiles();
+ }
+ return dirs;
+}
+/**
+ * Executes a directory selection dialog.
+ *
+ * Starts a non native dialog.
+ *
+ * @param title the dialog title
+ * @param directory "" or the start directory
+ * @return "": nothing selected<br>
+ * the selected directory
+ */
+QString ReGuiUtils::selectDirectory(const QString& title, const QString& directory)
+{
+ QFileDialog dialog(NULL);
+ dialog.setOption(QFileDialog::ShowDirsOnly, true);
+ dialog.setOption(QFileDialog::DontUseNativeDialog,true);
+ dialog.setFileMode(QFileDialog::Directory);
+ dialog.setWindowTitle(title);
+ if (!directory.isEmpty())
+ dialog.setDirectory(directory);
+ QString dir;
+ if (dialog.exec()){
+ dir = dialog.directory().absolutePath();
+ }
+ return dir;
+}
--- /dev/null
+/*
+ * 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 REGUIUTILS_HPP
+#define REGUIUTILS_HPP
+
+
+class ReGuiUtils
+{
+public:
+ static QString selectDirectory(const QString& title, const QString& directory);
+ static QStringList selectDirectories(const QString& title,
+ const QString& directory);
+};
+
+#endif // REGUIUTILS_HPP
#include <QPushButton>
#include <QLabel>
#include <QTableWidget>
+#include "gui/ReGuiUtils.hpp"
#include "gui/ReGuiQueue.hpp"
#include "gui/ReStateStorage.hpp"
#include "gui/ReGuiApplication.hpp"