From: hama Date: Tue, 8 Sep 2015 22:28:31 +0000 (+0200) Subject: delayed storage X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=32c99b0543ec5715b9feb8e040eb045ee5756a72;p=reqt delayed storage --- diff --git a/appl/reide/mainwindow.cpp b/appl/reide/mainwindow.cpp index 2113d55..0d8aca2 100644 --- a/appl/reide/mainwindow.cpp +++ b/appl/reide/mainwindow.cpp @@ -14,11 +14,13 @@ #include MainWindow::MainWindow(const char* workspace, const char* project, - ReLogger* logger, QWidget *parent) : - QMainWindow(parent), - m_workspace(NULL), - m_logger(logger), - m_perspectives(this) { + ReLogger* logger, QWidget *parent) : + QMainWindow(parent), + m_workspace(NULL), + m_logger(logger), + m_perspectives(this), + m_timerRuns(false), + m_timer(this){ setLayout(new QVBoxLayout); if (workspace == NULL) workspace = QDir::homePath().toUtf8(); @@ -38,15 +40,36 @@ MainWindow::MainWindow(const char* workspace, const char* project, proj = QDir::homePath(); } - changeProject(proj); +// changeProject(proj); //connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(open())); + connect(this, SIGNAL(xChanged(int)), this, SLOT(geometryChanged(int))); + connect(this, SIGNAL(yChanged(int)), this, SLOT(geometryChanged(int))); + connect(this, SIGNAL(widthChanged(int)), this, SLOT(geometryChanged(int))); + connect(this, SIGNAL(heightChanged(int)), this, SLOT(geometryChanged(int))); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(timeout())); Perspective* mainPerspective = new StartPerspective(this); m_perspectives.addPerspective(mainPerspective); m_perspectives.change(mainPerspective->name()); m_perspectives.addPerspective(new ProjectPerspective(proj, this)); } +/** + * Handles the change of the geometry. + * + * @param value changed x, y, width or height + */ +void MainWindow::geometryChanged(int value){ + ReUseParameter(value); + if (! m_timer.isActive()){ + m_timer.start(5000); + } +} + +void MainWindow::timeout(){ + ReSettings +} + /** * Destructor. */ diff --git a/appl/reide/mainwindow.hpp b/appl/reide/mainwindow.hpp index d80f3b4..2254719 100644 --- a/appl/reide/mainwindow.hpp +++ b/appl/reide/mainwindow.hpp @@ -22,7 +22,7 @@ class MainWindow: public QMainWindow { public: explicit MainWindow(const char* workspace, const char* project, - ReLogger* logger, QWidget *parent = 0); + ReLogger* logger, QWidget *parent = 0); ~MainWindow(); void changeProject(QString path); void changeWorkspace(const QString& path); @@ -33,10 +33,13 @@ public: public slots: void open(); + void geometryChanged(int value); private: Workspace* m_workspace; ReLogger* m_logger; PerspectiveList m_perspectives; + bool m_timerRuns; + QTimer m_timer; }; #endif // MAINWINDOW_HPP diff --git a/appl/reide/views/EditorView.cpp b/appl/reide/views/EditorView.cpp index 992d58d..043c4bf 100644 --- a/appl/reide/views/EditorView.cpp +++ b/appl/reide/views/EditorView.cpp @@ -11,15 +11,16 @@ #include "reide.hpp" +const char* EditorView::NAME = "Editor"; /** * Constructor. * * @param mainWindow the parent (main window) */ EditorView::EditorView(MainWindow* mainWindow) : - View("EditorView", mainWindow), - m_edit(new ReEdit(NULL)), - m_file(NULL) { + View(NAME, mainWindow), + m_edit(new ReEdit(NULL)), + m_file(NULL) { m_edit->setLines(&m_dummyFile); } diff --git a/appl/reide/views/EditorView.hpp b/appl/reide/views/EditorView.hpp index bb3d8f8..15fbe0e 100644 --- a/appl/reide/views/EditorView.hpp +++ b/appl/reide/views/EditorView.hpp @@ -20,6 +20,8 @@ class MainWindow; * A view is a widget displayed as a dock in the window displaying a perspective. */ class EditorView: public View { +public: + static const char* NAME; public: EditorView(MainWindow* mainWindow); ~EditorView(); diff --git a/appl/reide/views/Perspective.cpp b/appl/reide/views/Perspective.cpp index 14c1e42..539c3d3 100644 --- a/appl/reide/views/Perspective.cpp +++ b/appl/reide/views/Perspective.cpp @@ -18,16 +18,19 @@ * @param mainWindow the parent (main window) */ Perspective::Perspective(const char* name, MainWindow* mainWindow) : - m_name(name), - m_mainWindow(mainWindow) { + m_name(name), + m_mainWindow(mainWindow) { } /** * Destructor. */ Perspective::~Perspective() { - for (int ix = 0; ix < m_views.size(); ix++) - delete m_views.at(ix); + for (int ix = 0; ix < m_views.size(); ix++){ + ViewInfo* info = m_views.at(ix); + delete info->m_dockWidget; + delete info; + } m_views.clear(); } @@ -54,8 +57,11 @@ void Perspective::append(View* view, Qt::DockWidgetArea position) { ViewInfo* info = new ViewInfo(); info->m_position = position; info->m_view = view; - info->m_dockWidget = new QDockWidget(m_mainWindow); - info->m_dockWidget->setWidget(view->widget()); + info->m_dockWidget = NULL; + if (position != Qt::NoDockWidgetArea){ + info->m_dockWidget = new QDockWidget(NULL); + info->m_dockWidget->setWidget(view->widget()); + } m_views.append(info); } @@ -74,9 +80,9 @@ void Perspective::deactivate() { * Constructor. */ PerspectiveList::PerspectiveList(MainWindow* mainWindow) : - m_current(NULL), - m_map(), - m_mainWindow(mainWindow) { + m_current(NULL), + m_map(), + m_mainWindow(mainWindow) { } /** @@ -126,9 +132,9 @@ ProjectPerspective* PerspectiveList::project(bool activate) { ProjectPerspective* rc; if (activate) rc = reinterpret_cast(change( - ProjectPerspective::NAME)); + ProjectPerspective::NAME)); else rc = - reinterpret_cast(get(ProjectPerspective::NAME)); + reinterpret_cast(get(ProjectPerspective::NAME)); return rc; } diff --git a/appl/reide/views/StartView.cpp b/appl/reide/views/StartView.cpp index 470c8d7..672367c 100644 --- a/appl/reide/views/StartView.cpp +++ b/appl/reide/views/StartView.cpp @@ -17,17 +17,17 @@ * @param mainWindow the main window, the parent */ StartView::StartView(MainWindow* mainWindow) : - QWidget(mainWindow), - View("StartView", mainWindow), - ui(new Ui::StartView) { + QWidget(NULL), + View("StartView", mainWindow), + ui(new Ui::StartView) { ui->setupUi(this); connect(ui->toolButtonSelectFile, SIGNAL(clicked()), this, - SLOT(selectFile())); + SLOT(selectFile())); connect(ui->toolButtonSelectProject, SIGNAL(clicked()), this, - SLOT(selectDir())); + SLOT(selectDir())); connect(ui->pushButtonOpen, SIGNAL(clicked()), this, SLOT(open())); connect(ui->lineEditFilterLastFile, SIGNAL(textChanged(QString)), this, - SLOT(textChangedFilterFiles(QString))); + SLOT(textChangedFilterFiles(QString))); connect(ui->tableWidgetFiles, SIGNAL(cellEntered(int,int)), this, SLOT(cellEnteredFiles(int, int))); connect(ui->tableWidgetProjects, SIGNAL(cellEntered(int,int)), this, @@ -35,7 +35,7 @@ StartView::StartView(MainWindow* mainWindow) : Workspace* workspace = mainWindow->workspace(); buildTableInfo(workspace, Workspace::KEY_HISTORY_FILES, true, m_files); buildTableInfo(workspace, Workspace::KEY_HISTORY_PROJECTS, false, - m_projects); + m_projects); buildTable("", m_files, ui->tableWidgetFiles); buildTable("", m_projects, ui->tableWidgetProjects); } @@ -79,7 +79,7 @@ void StartView::cellEnteredProjects(int row, int col) { * @param table OUT: will be filled with all lines matching the filter */ void StartView::buildTable(const QString& filter, const QStringList& lines, - QTableWidget* table) { + QTableWidget* table) { QStringList::const_iterator it; int rowCount = 0; ReMatcher matcher(filter, Qt::CaseInsensitive, true); @@ -117,7 +117,7 @@ void StartView::buildTable(const QString& filter, const QStringList& lines, * @param tableContent OUT: the list containing the table info */ void StartView::buildTableInfo(ReSettings* settings, const char* key, - bool withDate, QStringList& tableContent) { + bool withDate, QStringList& tableContent) { QStringList files; settings->historyAsList(key, files); QStringList::const_iterator it; @@ -127,7 +127,7 @@ void StartView::buildTableInfo(ReSettings* settings, const char* key, QString info = file.fileName(); if (withDate) info.append("\t").append( - file.lastModified().toString("yyyy.mm.dd/HH:MM:SS")); + file.lastModified().toString("yyyy.mm.dd/HH:MM:SS")); info.append("\t").append(file.path()); tableContent.append(info); } @@ -141,7 +141,7 @@ void StartView::buildTableInfo(ReSettings* settings, const char* key, */ void StartView::error(const QString& message) { QMessageBox dialog(QMessageBox::Critical, "Error", message, - QMessageBox::Close); + QMessageBox::Close); dialog.exec(); } @@ -157,7 +157,7 @@ void StartView::error(const QString& message) { QString StartView::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(); + + table->item(row, 0)->text(); return file; } /** @@ -189,7 +189,7 @@ void StartView::selectDir() { if (name.isEmpty()) name = m_mainWindow->perspectives().project()->path(); name = QFileDialog::getExistingDirectory(this, - tr("Select Project Directory"), name); + tr("Select Project Directory"), name); if (!name.isEmpty()) { ui->lineEditOpen->setText(name); open(); @@ -216,7 +216,7 @@ void StartView::selectFile() { * @param lines the full (unfiltered) table info */ void StartView::textChanged(const QString& text, QTableWidget* table, - const QStringList& lines) { + const QStringList& lines) { buildTable(text, lines, table); if (table->rowCount() > 0) { QString file = fileOfTable(table, 0); diff --git a/base/ReFileUtils.cpp b/base/ReFileUtils.cpp index 6d667f4..ca78ec3 100644 --- a/base/ReFileUtils.cpp +++ b/base/ReFileUtils.cpp @@ -21,9 +21,9 @@ enum { * Constructor. */ ReTreeStatistic::ReTreeStatistic() : - m_files(0), - m_directories(0), - m_fileSizes(0L) { + m_files(0), + m_directories(0), + m_fileSizes(0L) { } /** @@ -38,8 +38,27 @@ bool ReFileUtils::isAbsolutPath(const QString& path) { #ifdef __linux__ rc = path.startsWith(OS_SEPARATOR); #else - rc = path.startsWith(OS_SEPARATOR) - || path.length() > 2 && path.at(1) == ':'; + rc = path.length() > 3 && path.at(1) == ':' && path.at(2) == OS_SEPARATOR + || path.startsWith("\\\\"); +#endif + return rc; +} + +/** + * Returns whether a path is an absolute path. + * + * @param path the path to test + * @return true: the path is absolute
+ * false: the path is relative + */ +bool ReFileUtils::isAbsolutPath(const char* path) +{ + bool rc; +#ifdef __linux__ + rc = path[0] == OS_SEPARATOR; +#else + rc = isalpha(path[0]) && path[1] == ':' && path[2] == OS_SEPARATOR + || path[0] == OS_SEPARATOR && path[1] == OS_SEPARATOR; #endif return rc; } @@ -56,15 +75,15 @@ bool ReFileUtils::isAbsolutPath(const QString& path) { * false: at least one deletion failed */ bool ReFileUtils::deleteTree(const QString& path, bool withBase, - ReLogger* logger) { + ReLogger* logger) { bool rc = true; QDir dir(path); if (dir.exists(path)) { QFileInfo info; QStringList names = dir.entryList( - QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs - | QDir::Files); + QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs + | QDir::Files); QStringList::const_iterator it; for (it = names.constBegin(); it != names.constEnd(); ++it) { QString full(path); @@ -77,16 +96,16 @@ bool ReFileUtils::deleteTree(const QString& path, bool withBase, rc = false; if (logger != NULL) logger->logv(LOG_ERROR, LOC_DELETE_TREE_1, - "cannot delete directory (%d): %s", errno, - full.toUtf8().constData()); + "cannot delete directory (%d): %s", errno, + full.toUtf8().constData()); } } else { if (!QFile::remove(full)) { rc = false; if (logger != NULL) logger->logv(LOG_ERROR, LOC_DELETE_TREE_2, - "cannot delete file (%d): %s", errno, - full.toUtf8().constData()); + "cannot delete file (%d): %s", errno, + full.toUtf8().constData()); } } } @@ -94,7 +113,7 @@ bool ReFileUtils::deleteTree(const QString& path, bool withBase, if (withBase && (rmdir(path.toUtf8())) != 0) { rc = false; logger->logv(LOG_ERROR, LOC_DELETE_TREE_3, - "cannot delete directory (%d): %s", errno, path.toUtf8()); + "cannot delete directory (%d): %s", errno, path.toUtf8()); } return rc; } @@ -107,7 +126,7 @@ bool ReFileUtils::deleteTree(const QString& path, bool withBase, * @return buffer (for chaining) */ QByteArray& ReFileUtils::readFromFile(const char* filename, - QByteArray& buffer) { + QByteArray& buffer) { FILE* fp = fopen(filename, "r"); if (fp != NULL) { struct stat info; @@ -132,7 +151,7 @@ QByteArray& ReFileUtils::readFromFile(const char* filename, * @return the name of an existing directory */ QByteArray ReFileUtils::tempDir(const char* node, const char* parent, - bool withSeparator) { + bool withSeparator) { #if defined __linux__ QByteArray temp("/tmp"); static const char* firstVar = "TMP"; @@ -179,7 +198,7 @@ QByteArray ReFileUtils::tempDir(const char* node, const char* parent, * @return the full name of a temporary file */ QByteArray ReFileUtils::tempFile(const char* node, const char* parent, - bool deleteIfExists) { + bool deleteIfExists) { QByteArray rc(tempDir(parent)); if (!rc.endsWith('/')) rc += '/'; @@ -200,7 +219,7 @@ QByteArray ReFileUtils::tempFile(const char* node, const char* parent, * @param mode file write mode: "w" (write) or "a" (append) */ void ReFileUtils::writeToFile(const char* filename, const char* content, - size_t contentLength, const char* mode) { + size_t contentLength, const char* mode) { FILE* fp = fopen(filename, mode); if (fp != NULL) { if (contentLength == (size_t) - 1) diff --git a/cunit/cuReFileUtils.cpp b/cunit/cuReFileUtils.cpp index 5889992..d6895b5 100644 --- a/cunit/cuReFileUtils.cpp +++ b/cunit/cuReFileUtils.cpp @@ -81,7 +81,25 @@ public: checkT(ReFileUtils::deleteTree(QString(base), false, &m_logger)); checkEqu(0, stat(base, &info)); } + void testIsAbsolutePath(){ +#ifdef __linux__ + checkT(ReFileUtils::isAbsolutPath("/abc/def/xyz.123")); + checkT(ReFileUtils::isAbsolutPath("/")); + + checkF(ReFileUtils::isAbsolutPath("../abc/x.y")); + checkF(ReFileUtils::isAbsolutPath("./abc")); +#else + checkT(ReFileUtils::isAbsolutPath("e:\\abc\\def\\xyz.123")); + checkT(ReFileUtils::isAbsolutPath("a:\\")); + + checkF(ReFileUtils::isAbsolutPath("e:\\abc\\def\\xyz.123")); + checkF(ReFileUtils::isAbsolutPath("a:\\")); +#endif + checkF(ReFileUtils::isAbsolutPath("")); + } + virtual void run() { + testIsAbsolutePath(); testDeleteTree(); testTempDir(); testTempFile(); diff --git a/cunit/cuReSettings.cpp b/cunit/cuReSettings.cpp index 4900459..63f8c73 100644 --- a/cunit/cuReSettings.cpp +++ b/cunit/cuReSettings.cpp @@ -20,7 +20,7 @@ class TestReSettings: public ReTest { public: TestReSettings() : - ReTest("ReSettings") { + ReTest("ReSettings") { doIt(); } @@ -29,11 +29,14 @@ public: QByteArray dir(ReFile::tempDir("resettings", NULL, false)); ReFile::deleteTree((QString) dir, false, &m_logger); { - ReSettings settings(dir, "test", &m_logger); + ReSettings settings(dir, "test", &m_memoryLogger); settings.addHistoryEntry("digits", "4", ' ', 3); + checkT(logContains("cannot open .*resettings.test\\.history: \\d+")); + settings.addHistoryEntry("digits", "3", ' ', 3); settings.addHistoryEntry("digits", "2", ' ', 3); settings.addHistoryEntry("digits", "1", ' ', 3); + m_memoryAppender.clear(); } ReSettings settings(dir, "test", &m_logger); QStringList list; @@ -42,14 +45,14 @@ public: } void setSettings(ReSettings& settings) { settings.insertProperty( - new ReProperty("level1.boolVal", "Boolean", - "Boolean value for test", ReSettings::TRUE, PT_BOOL)); + new ReProperty("level1.boolVal", "Boolean", + "Boolean value for test", ReSettings::TRUE, PT_BOOL)); settings.insertProperty( - new ReProperty("level1.intVal", "Integer", "Integer value for test", - "4711", PT_INT, "[0,9999]")); + new ReProperty("level1.intVal", "Integer", "Integer value for test", + "4711", PT_INT, "[0,9999]")); settings.insertProperty( - new ReProperty("level2.strVal", "String", "String value for test", - "crazy horse", PT_STRING)); + new ReProperty("level2.strVal", "String", "String value for test", + "crazy horse", PT_STRING)); } void testBasic() { @@ -89,9 +92,11 @@ public: QByteArray dir(ReFile::tempDir("resettings", NULL, false)); ReFile::deleteTree((QString) dir, false, &m_logger); { - ReSettings settings(dir, "test", &m_logger); + ReSettings settings(dir, "test", &m_memoryLogger); settings.addHistoryEntry("fluid", "beer", ' ', 3); + checkT(logContains("cannot open .*resettings.test\\.history: \\d+")); settings.addHistoryEntry("fluid", "wine", ' ', 3); + m_memoryAppender.clear(); } ReSettings settings(dir, "test", &m_logger); checkEqu("wine", settings.topOfHistory("fluid")); diff --git a/cunit/cuReStateStorage.cpp b/cunit/cuReStateStorage.cpp index 0913da7..c019536 100644 --- a/cunit/cuReStateStorage.cpp +++ b/cunit/cuReStateStorage.cpp @@ -27,8 +27,9 @@ public: public: void testBasic(){ QByteArray fn(ReFile::tempFile("state.basic.$$$.txt", NULL, true)); + unlink(fn); { - ReStateStorage store(fn); + ReStateStorage store(fn, &m_logger); store.setForm("singles"); store.store("int", "4711"); store.store("string", "\"with delimiters\""); @@ -39,7 +40,7 @@ public: store.store("string", "xyz", 1); // no explicite close() } - ReStateStorage store(fn); + ReStateStorage store(fn, &m_logger); store.setForm("singles"); checkEqu("4711", store.restore("int")); checkEqu("\"with delimiters\"", store.restore("string")); @@ -60,7 +61,7 @@ public: void testAddHistoryEntry(){ QByteArray fn(ReFile::tempFile("state.hist.$$$.txt", NULL, true)); { - ReStateStorage store(fn); + ReStateStorage store(fn, &m_logger); store.setForm("common"); store.addHistoryEntry("version", "v4", ';', 3); store.addHistoryEntry("version", "v2", ';', 3); @@ -72,7 +73,7 @@ public: store.addHistoryEntry("version", "v1", ';', 3); store.flushMap(); } - ReStateStorage store(fn); + ReStateStorage store(fn, &m_logger); QStringList list; store.setForm("common"); checkEqu(3, store.historyAsList("version", list).size()); diff --git a/gui/ReSettings.cpp b/gui/ReSettings.cpp index 12904ee..db352a6 100644 --- a/gui/ReSettings.cpp +++ b/gui/ReSettings.cpp @@ -41,15 +41,15 @@ QString ReSettings::FALSE = ""; * @param limits NULL or some rules for the property value */ ReProperty::ReProperty(const char* name, const QString& title, - const QString& description, const QString& defaultValue, - RePropertyType type, const char* limits) : - m_name(name), - m_title(title), - m_description(description), - m_value(defaultValue), - m_defaultValue(defaultValue), - m_type(type), - m_limits(limits) { + const QString& description, const QString& defaultValue, + RePropertyType type, const char* limits) : + m_name(name), + m_title(title), + m_description(description), + m_value(defaultValue), + m_defaultValue(defaultValue), + m_type(type), + m_limits(limits) { } /** @@ -103,14 +103,14 @@ bool ReProperty::isValid(const QString& value, QString* error) { * @param prefix type of the storage: "proj" or "ws" (workspace) */ ReSettings::ReSettings(const QString& path, const QString& prefix, - ReLogger* logger) : - m_prefix(prefix), - m_path(), - m_fileHistory(), - m_fileSettings(), - m_settings(), - m_chapters(), - m_logger(logger) { + ReLogger* logger) : + m_prefix(prefix), + m_path(), + m_fileHistory(), + m_fileSettings(), + m_settings(), + m_chapters(), + m_logger(logger) { setPath(path); } @@ -127,7 +127,7 @@ ReSettings::ReSettings(const QString& path, const QString& prefix, * @param form the prefix of the key. If NULL the current form will be taken */ void ReSettings::addHistoryEntry(const char* key, const QString& value, - char separator, int maxEntries) { + char separator, int maxEntries) { ReStateStorage store(m_fileHistory, m_logger); store.initForRead(); store.addHistoryEntry(key, value, separator, maxEntries); @@ -177,10 +177,10 @@ bool ReSettings::boolValue(const char* name) { ReProperty* property = m_settings.value(name, NULL); if (property == NULL) m_logger->logv(LOG_ERROR, LOC_BOOL_VALUE_1, "missing bool property %s", - name); + name); else if (property->m_type != PT_BOOL) m_logger->logv(LOG_ERROR, LOC_BOOL_VALUE_2, "not a bool property %s", - name); + name); else rc = !property->m_value.isEmpty(); return rc; @@ -197,11 +197,11 @@ void ReSettings::changeValue(const char* name, const QString& value) { ReProperty* property = m_settings.value(name, NULL); if (property == NULL) m_logger->logv(LOG_ERROR, LOC_CHANGE_VALUE_1, "unknown property: %s", - name); + name); else if (!property->isValid(value, &error)) m_logger->logv(LOG_ERROR, LOC_CHANGE_VALUE_2, - "invalid value for %s: %s\n+++ %s", name, - value.toUtf8().constData(), error.toUtf8().constData()); + "invalid value for %s: %s\n+++ %s", name, + value.toUtf8().constData(), error.toUtf8().constData()); else property->m_value = value; } @@ -215,7 +215,7 @@ void ReSettings::changeValue(const char* name, const QString& value) { * @return list (for chaining) */ QStringList&ReSettings::historyAsList(const char* key, QStringList& list, - const char* form) { + const char* form) { ReStateStorage store(m_fileHistory, m_logger); store.initForRead(); QStringList& rc = store.historyAsList(key, list, form); @@ -251,10 +251,10 @@ int ReSettings::intValue(const char* name) { ReProperty* property = m_settings.value(name, NULL); if (property == NULL) m_logger->logv(LOG_ERROR, LOC_INT_VALUE_1, "missing int property %s", - name); + name); else if (property->m_type != PT_INT) m_logger->logv(LOG_ERROR, LOC_INT_VALUE_2, "not a int property %s", - name); + name); else rc = property->m_value.toInt(); return rc; @@ -276,7 +276,7 @@ void ReSettings::readSettings() { QFile file(m_fileSettings); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) m_logger->logv(LOG_ERROR, LOC_READ_SETTINGS_1, "cannot open (%d): ", - errno, m_fileSettings.toUtf8().constData()); + errno, m_fileSettings.toUtf8().constData()); else { QTextStream input(&file); int lineNo = 0; @@ -286,14 +286,14 @@ void ReSettings::readSettings() { int ix = line.indexOf('='); if (ix < 0) m_logger->logv(LOG_ERROR, LOC_READ_SETTINGS_2, - "missing '=': %s-%d: %s", - m_fileSettings.toUtf8().constData(), lineNo, - line.mid(0, 20).toUtf8().constData()); + "missing '=': %s-%d: %s", + m_fileSettings.toUtf8().constData(), lineNo, + line.mid(0, 20).toUtf8().constData()); else if (ix == 0 || (ix == 1 && line.at(0) == '!')) m_logger->logv(LOG_ERROR, LOC_READ_SETTINGS_3, - "line starts with '=': %s-%d: %s", - m_fileSettings.toUtf8().constData(), lineNo, - line.mid(0, 20).toUtf8().constData()); + "line starts with '=': %s-%d: %s", + m_fileSettings.toUtf8().constData(), lineNo, + line.mid(0, 20).toUtf8().constData()); else { QByteArray name; QString value; @@ -301,7 +301,7 @@ void ReSettings::readSettings() { name = line.left(ix - 1).toUtf8(); value = line.mid(ix + 1); value.replace("\\\\", "\01").replace("\\n", "\n").replace( - "\\r", "\r").replace('\01', '\\'); + "\\r", "\r").replace('\01', '\\'); } else { name = line.left(ix).toUtf8(); value = line.mid(ix + 1); @@ -311,8 +311,8 @@ void ReSettings::readSettings() { switch (property->m_type) { case PT_BOOL: property->m_value = - value.isEmpty() ? - ReSettings::FALSE : ReSettings::TRUE; + value.isEmpty() ? + ReSettings::FALSE : ReSettings::TRUE; break; case PT_INT: if (property->isValid(value)) @@ -354,10 +354,10 @@ QString ReSettings::stringValue(const char* name) { ReProperty* property = m_settings.value(name, NULL); if (property == NULL) m_logger->logv(LOG_ERROR, LOC_STRING_VALUE_1, - "missing string property %s", name); + "missing string property %s", name); else if (property->m_type != PT_STRING) m_logger->logv(LOG_ERROR, LOC_STRING_VALUE_2, - "not a string property %s", name); + "not a string property %s", name); else rc = property->m_value; return rc; @@ -370,7 +370,7 @@ void ReSettings::writeSettings() { QFile file(m_fileSettings); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) m_logger->logv(LOG_ERROR, LOC_WRITE_SETTINGS_1, "cannot open (%d): ", - errno, m_fileSettings.toUtf8().constData()); + errno, m_fileSettings.toUtf8().constData()); else { QTextStream out(&file); QMap::const_iterator it; @@ -383,11 +383,101 @@ void ReSettings::writeSettings() { else { QString value = it.value()->m_value; out << it.key() << "!=" - << value.replace("\\", "\\\\").replace("\n", "\\n").replace( - "\r", "\\r") << "\n"; + << value.replace("\\", "\\\\").replace("\n", "\\n").replace( + "\r", "\\r") << "\n"; } } file.close(); } } +/** + * Constructor. + * + * @param delay time between first change of setting and storage in seconds + */ +ReDelayedStorage::ReDelayedStorage(const QString& file, int delay) : + m_timer(NULL), + m_list(), + m_delay(delay), + m_file(file){ + m_timer.setSingleShot(true); + QObject::connect(&m_timer, SIGNAL(timeout()), this, SLOT(timeout())); +} + +/** + * Tests whether a given widget is in the internal list. + * + * @param widget the widget to search + * @return true: the widget is in the list + */ +bool ReDelayedStorage::contains(const QWidget* widget){ + QList::const_iterator; + bool rc = false; + for (it = m_list.cbegin(); ! rc && it != m_list.cend(); ++it){ + ObjInfo* info = *it; + if (info->m_widget == widget) + rc = true; + } + return rc; +} + +/** + * Finds the index of the widget in the list. + * + * @param widget widget to search + * @return -1: not found
+ * otherwise: the index in m_list + */ +QWidget*ReDelayedStorage::indexOf(const QWidget* widget) +{ + int rc = -1; + for (int ix = 0; rc < 0 && ix < m_list.size(); ix++) + if (m_list.at(ix)->m_widget == widget) + rc = ix; + return rc; +} + +/** + * Initializes the storage of the window geometry. + * + * @param window the window to store + */ +void ReDelayedStorage::storeWindow(QMainWindow* window) +{ + int ix = indexOf(window); + if (ix < 0){ + ObjInfo* info = new ObjInfo; + info->m_type = OT_WINDOW; + info->m_widget = widget; + m_list.append(info); + if (! m_timer.isActive()){ + timer.start(m_delay*1000); + } + } +} + +/** + * Handles the event timeout of the timer. + */ +void ReDelayedStorage::timeout() +{ + ReStateStorage storage(m_file); + storage.initForRead(); + for (int ix = 0; ix < m_list.size(); ix++){ + ObjInfo* info = m_list.at(ix); + switch(info->m_type){ + case OT_WINDOW: + { + const QMainWindow* window = reinterpret_cast + (info->m_widget); + storage.store(window); + break; + } + default: + break; + } + } + storage.flushMap(); +} + diff --git a/gui/ReSettings.hpp b/gui/ReSettings.hpp index aa85000..9e1efa0 100644 --- a/gui/ReSettings.hpp +++ b/gui/ReSettings.hpp @@ -11,7 +11,7 @@ #ifndef STORAGE_HPP #define STORAGE_HPP - +#include enum RePropertyType { PT_UNDEF, PT_INT, @@ -22,8 +22,8 @@ enum RePropertyType { class ReProperty { public: ReProperty(const char* name, const QString& title, - const QString& description, const QString& defaultValue, - RePropertyType type, const char* limits = NULL); + const QString& description, const QString& defaultValue, + RePropertyType type, const char* limits = NULL); public: bool isValid(const QString& value, QString* error = NULL); public: @@ -36,6 +36,31 @@ public: const char* m_limits; }; +class ReDelayedStorage{ + Q_OBJECT + enum ObjType { + OT_UNDEF, + OT_WINDOW + }; + typedef struct { + ObjType m_type; + const QWidget* m_widget; + } ObjInfo; +public: + ReDelayedStorage(const QString& file, int delay = 5); +public: + void storeWindow(const QMainWindow* window); +public: + void timeout(); +private: + int indexOf(const QWidget* widget); +private: + QTimer m_timer; + QList m_list; + int m_delay; + QString m_file; +}; + class ReSettings { public: static QString TRUE; @@ -44,11 +69,11 @@ public: ReSettings(const QString& path, const QString& prefix, ReLogger* logger); public: void addHistoryEntry(const char* key, const QString& value, char separator, - int maxEntries); + int maxEntries); bool boolValue(const char* name); void changeValue(const char* name, const QString& value); QStringList& historyAsList(const char* key, QStringList& list, - const char* form = NULL); + const char* form = NULL); void insertProperty(ReProperty* property); int intValue(const char* name); const QString& path() const; diff --git a/gui/ReStateStorage.cpp b/gui/ReStateStorage.cpp index 0a48e3f..f59c428 100644 --- a/gui/ReStateStorage.cpp +++ b/gui/ReStateStorage.cpp @@ -11,10 +11,11 @@ #include "QIODevice" #include "base/rebase.hpp" #include "gui/regui.hpp" - +#include enum { LOC_INIT_FOR_WRITE_1 = LOC_FIRST_OF(LOC_STATESTORAGE), // 12001 - LOC_INIT_FOR_READ_1, // 12002 + LOC_INIT_FOR_READ_1, // 12002 + LOC_RESTORE_WINDOW_1, // 12003 }; /** * Constructor. @@ -22,11 +23,11 @@ enum { * @param filename filename with path of the storage file */ ReStateStorage::ReStateStorage(const QString& filename, ReLogger* logger) : - m_filename(filename), - m_fp(NULL), - m_stream(NULL), - m_form(), - m_logger(logger) { + m_filename(filename), + m_fp(NULL), + m_stream(NULL), + m_form(), + m_logger(logger) { } /** @@ -49,7 +50,7 @@ ReStateStorage::~ReStateStorage() { * @param form the prefix of the key. If NULL the current form will be taken */ void ReStateStorage::addHistoryEntry(const char* key, const QString& value, - char separator, int maxEntries, const char* form) { + char separator, int maxEntries, const char* form) { if (form != NULL) setForm(form); QByteArray key2; @@ -84,7 +85,7 @@ void ReStateStorage::addHistoryEntry(const char* key, const QString& value, * @return list (for chaining) */ QStringList& ReStateStorage::historyAsList(const char* key, QStringList& list, - const char* form) { + const char* form) { list.clear(); if (form != NULL) setForm(form); @@ -153,8 +154,8 @@ bool ReStateStorage::initForRead() { if ((m_fp = fopen(m_filename.toUtf8().constData(), "rb")) == NULL) { if (m_logger != NULL) m_logger->logv(LOG_ERROR, LOC_INIT_FOR_READ_1, - "cannot open %s: %d", m_filename.toUtf8().constData(), - errno); + "cannot open %s: %d", m_filename.toUtf8().constData(), + errno); } if (m_fp != NULL && m_stream == NULL) { m_stream = new QTextStream(m_fp, QIODevice::ReadOnly); @@ -182,7 +183,7 @@ bool ReStateStorage::initForWrite() { if (m_fp == NULL) { if (m_logger != NULL) m_logger->logv(LOG_ERROR, LOC_INIT_FOR_WRITE_1, - "cannot open %s: %d", m_filename.toUtf8().constData(), errno); + "cannot open %s: %d", m_filename.toUtf8().constData(), errno); } else m_stream = new QTextStream(m_fp, QIODevice::ReadWrite); return m_stream != NULL; @@ -195,7 +196,7 @@ bool ReStateStorage::initForWrite() { * @param withCurrentText true: the current text will be set too */ void ReStateStorage::restore(QComboBox* combo, const char* name, - bool withCurrentText) { + bool withCurrentText) { if (initForRead()) { QByteArray keyPrefix = fullname(name) + ".item"; int ix = 0; @@ -236,6 +237,48 @@ QString ReStateStorage::restore(const char* name, int index) { return rc; } +/** + * Reads the window geometry. + * + * Adaptions will be taken if the stored settings exceeds + * the current screen. + * + * @param window OUT: the geometry will be taken from the settings + */ +void ReStateStorage::restore(QMainWindow* window) +{ + if (initForRead()) { + QByteArray key("window"); + if (m_map.contains(key)){ + QString line = m_map.value(key); + int x, y, width, height; + x = y = width = height = 0; + QTextStream stream(&line); + stream >> x >> y >> width >> height; + QDesktopWidget desktop; + if (x > desktop.screen()->width() - 100) + x = 50; + if (y > desktop.screen()->height() - 100) + y = 50; + if (width > desktop.screen()->width()){ + width = desktop.screen()->width() - 50; + x = 50; + } + if (height > desktop.screen()->height()){ + height = desktop.screen()->height() - 50; + x = 50; + } + if (x + width > desktop.screen()->width()) + x = desktop.screen()->width() - width; + if (y + height > desktop.screen()->height()){ + y = desktop.screen()->height() - height; + } + window->move(x, y); + window->resize(width, height); + } + } +} + /** * Sets the name of the current form. * @@ -253,18 +296,18 @@ void ReStateStorage::setForm(const char* form) { * @param withCurrentText true: the current text will be saved too */ void ReStateStorage::store(const QComboBox* combo, const char* name, - bool withCurrentText) { + bool withCurrentText) { if (initForWrite()) { QByteArray key(fullname(name)); for (int ii = 0; ii < combo->count(); ii++) { *m_stream << key << ".item" << ii << "=" << combo->itemText(ii) - << endl; + << endl; } if (withCurrentText) { *m_stream << key << ".text=" << combo->currentText() << endl; } + m_stream->flush(); } - m_stream->flush(); } /** @@ -279,7 +322,19 @@ void ReStateStorage::store(const char* name, const QString& value, int index) { if (index >= 0) key += QString::number(index); *m_stream << key << "=" << value << endl; + m_stream->flush(); } - m_stream->flush(); } +/** + * Stores geometry of a main window. + * + * @param window the combobox to store + */ +void ReStateStorage::store(const QMainWindow* window) { + if (initForWrite()) { + *m_stream << "window=" << window->x() << ' ' << window->y() + << ' ' << window->width() << ' ' << window->height() << endl; + m_stream->flush(); + } +} diff --git a/gui/ReStateStorage.hpp b/gui/ReStateStorage.hpp index 529a763..e7d6511 100644 --- a/gui/ReStateStorage.hpp +++ b/gui/ReStateStorage.hpp @@ -14,6 +14,7 @@ #include #include +#include class ReStateStorage { public: @@ -21,13 +22,13 @@ public: virtual ~ReStateStorage(); public: void addHistoryEntry(const char* key, const QString& value, char separator, - int maxEntries, const char* form = NULL); + int maxEntries, const char* form = NULL); void close(); void flushMap(); const QByteArray& form() const; QByteArray fullname(const char* name); QStringList& historyAsList(const char* key, QStringList& list, - const char* form = NULL); + const char* form = NULL); bool initForRead(); bool initForWrite(); /** Returns the map containing the storage content. @@ -37,13 +38,14 @@ public: return m_map; } void restore(QComboBox* combo, const char* name, bool withCurrentText = - false); + false); QString restore(const char* name, int index = -1); + void restore(QMainWindow* window); void setForm(const char* form); void store(const QComboBox* combo, const char* name, bool withCurrentText = - true); + true); void store(const char* name, const QString& value, int index = -1); - + void store(const QMainWindow* window); private: QString m_filename; FILE* m_fp;