From: hama Date: Wed, 19 Aug 2015 22:13:28 +0000 (+0200) Subject: Storage, Workspace, Project X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=7a09555d041f4f01085d184bc76fd2e22cf58de1;p=reqt Storage, Workspace, Project --- diff --git a/appl/reditor/editor.qrc b/appl/reditor/editor.qrc index 285a782..3ec8152 100644 --- a/appl/reditor/editor.qrc +++ b/appl/reditor/editor.qrc @@ -21,5 +21,6 @@ icons/tables.png icons/wand.png icons/wrench.png + icons/folder_page.png diff --git a/appl/reditor/icons/folder_page.png b/appl/reditor/icons/folder_page.png new file mode 100644 index 0000000..1ef6e11 Binary files /dev/null and b/appl/reditor/icons/folder_page.png differ diff --git a/appl/reditor/main.cpp b/appl/reditor/main.cpp index 1e12b34..a145881 100644 --- a/appl/reditor/main.cpp +++ b/appl/reditor/main.cpp @@ -8,17 +8,31 @@ * You also can use this license: http://www.wtfpl.net * The latest sources: https://github.com/republib */ -#include "base/rebase.hpp" -#include "../reditor/mainwindow.hpp" +#include "reditor.hpp" #include int main(int argc, char *argv[]) { + const char* workspace = NULL; + const char* project = NULL; + for (int ix = 1; ix < argc; ix++) { + if (argv[ix][0] == '-') { + if (strcmp(argv[ix], "-w") == 0 && ix < argc - 1) { + workspace = argv[++ix]; + } else if (strncmp(argv[ix], "--workspace=", 12) == 0) { + workspace = argv[ix] + 12; + } else if (strcmp(argv[ix], "-p") == 0 && ix < argc - 1) { + project = argv[++ix]; + } else if (strncmp(argv[ix], "--project=", 10) == 0) { + workspace = argv[ix] + 10; + } + } + } QApplication a(argc, argv); ReLogger logger; ReDebugAppender appender; appender.setAutoDelete(false); logger.addAppender(&appender); - MainWindow w; + MainWindow w(workspace, project); logger.log(LOG_INFO, 1, "start"); w.show(); diff --git a/appl/reditor/mainwindow.cpp b/appl/reditor/mainwindow.cpp index 400b8f5..9c6e099 100644 --- a/appl/reditor/mainwindow.cpp +++ b/appl/reditor/mainwindow.cpp @@ -9,43 +9,116 @@ * The latest sources: https://github.com/republib */ -#include "base/rebase.hpp" -#include "gui/regui.hpp" -#include "../reditor/mainwindow.hpp" +#include "reditor.hpp" #include "ui_mainwindow.h" #include -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), ui(new Ui::MainWindow){ - ui->setupUi(this); - ReEdit* edit = ui->widget; +MainWindow::MainWindow(const char* workspace, const char* project, + QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow), + m_workspace(NULL), + m_project(NULL) { + if (workspace == NULL) + workspace = QDir::homePath().toUtf8(); + changeWorkspace(workspace == NULL ? QDir::homePath() : workspace); + + QString proj(project == NULL ? "" : project); + if (project == NULL) { + QStringList lastProjects = m_workspace->historyAsList("projects"); + int ix = 0; + while (proj.isEmpty() && ix < lastProjects.size()) { + QFileInfo dir(lastProjects.at(ix)); + if (dir.isDir() && dir.isWritable()) + proj = lastProjects.at(ix); + } + if (!proj.isEmpty()) + m_project = new Project(proj); + } + + ui->setupUi(this); + ReEdit* edit = ui->widget; #if defined __linux__ - m_file = new ReFile("/home/hm/editor.txt", false); + m_file = new ReFile("/home/hm/editor.txt", false); #else - m_file = new ReFile("U:\\ws_cpp\\rplqt\\Doxyfile", false); + m_file = new ReFile("U:\\ws_cpp\\rplqt\\Doxyfile", false); #endif - edit->setLines(m_file); - edit->setCursorLine(0); - connect(ui->actionOpen, SIGNAL(triggered()), this, - SLOT(openFile())); + edit->setLines(m_file); + edit->setCursorLine(0); + connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(open())); + open(); +} + +MainWindow::~MainWindow() { + delete ui; +} +/** + * Change the current project. + * + * @param path the directory containing the project data + */ +void MainWindow::changeProject(const QString& path) { + delete m_project; + m_project = new Project(path); } -MainWindow::~MainWindow(){ - delete ui; +/** + * Change the workspace. + * + * @param path the directory containing the workspace data + */ +void MainWindow::changeWorkspace(const QString& path) { + delete m_workspace; + m_workspace = new Workspace(path); } /** * Calls the file selection dialog. */ -void MainWindow::openFile(){ - QString name = m_file == NULL ? "" : m_file->filename(); - name = QFileDialog::getOpenFileName(this, tr("Select File"), - name); - if (!name.isEmpty()){ - delete m_file; - m_file = new ReFile(name, false); - ui->widget->setLines(m_file); - } +void MainWindow::openFile(const QString& name) { + m_file = new ReFile(name, false); + + ReEdit* edit = ui->widget; + edit->setLines(m_file); + edit->setCursorLine(0); +} + +/** + * Closes the current project. + */ +void MainWindow::closeProject() { + if (!m_project.isEmpty()) { + } } + +/** + * Opens a project. + */ +void MainWindow::openProject(const QString& name) { + closeProject(); + m_project = name; +} + +/** + * Shows the "open project/file dialog". + */ +void MainWindow::open() { + ProjectSelection dialog(this); + dialog.exec(); +} + +/** + * Returns the current workspace. + * + * @return the current workspace + */ +Storage* MainWindow::project() const { + return m_project; +} + +Storage* MainWindow::workspace() const { + return m_workspace; +} + diff --git a/appl/reditor/mainwindow.hpp b/appl/reditor/mainwindow.hpp index eb31030..a80d532 100644 --- a/appl/reditor/mainwindow.hpp +++ b/appl/reditor/mainwindow.hpp @@ -21,17 +21,27 @@ class MainWindow; } class MainWindow: public QMainWindow { - Q_OBJECT + Q_OBJECT public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); + explicit MainWindow(const char* workspace, const char* project, + QWidget *parent = 0); + ~MainWindow(); + void changeProject(const QString& path); + void changeWorkspace(const QString& path); + void closeProject(); + void openFile(const QString& name); + void openProject(const QString& name); + Storage* project() const; + Storage* workspace() const; -protected slots: - void openFile(); +public slots: + void open(); private: - Ui::MainWindow *ui; - ReFile* m_file; + Ui::MainWindow *ui; + ReFile* m_file; + Storage* m_project; + Storage* m_workspace; }; #endif // MAINWINDOW_HPP diff --git a/appl/reditor/project.cpp b/appl/reditor/project.cpp new file mode 100644 index 0000000..b64f6d0 --- /dev/null +++ b/appl/reditor/project.cpp @@ -0,0 +1,14 @@ +/* + * 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 "reditor.hpp" + +Project::Project(const QString& path) : + Storage(path, "proj") { +} + diff --git a/appl/reditor/project.hpp b/appl/reditor/project.hpp new file mode 100644 index 0000000..7768602 --- /dev/null +++ b/appl/reditor/project.hpp @@ -0,0 +1,17 @@ +/* + * 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 PROJECT_HPP +#define PROJECT_HPP + +class Project: public Storage { +public: + Project(const QString& path); +}; + +#endif // PROJECT_HPP diff --git a/appl/reditor/projectselection.cpp b/appl/reditor/projectselection.cpp index 3a1ab36..8ccc1dc 100644 --- a/appl/reditor/projectselection.cpp +++ b/appl/reditor/projectselection.cpp @@ -4,20 +4,110 @@ * 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 "projectselection.hpp" +#include "reditor.hpp" #include "ui_projectselection.h" +#include +#include -ProjectSelection::ProjectSelection(QWidget *parent) : - QDialog(parent), - ui(new Ui::ProjectSelection) -{ +/** + * Constructor. + * + * @param parent NULL or the parent + * @param mainWindow the main window + */ +ProjectSelection::ProjectSelection(MainWindow* mainWindow, QWidget *parent) : + QDialog(parent), + ui(new Ui::ProjectSelection), + m_mainWindow(mainWindow) { ui->setupUi(this); + connect(ui->toolButtonSelectFile, SIGNAL(clicked()), this, + SLOT(selectFile())); + connect(ui->toolButtonSelectProject, SIGNAL(clicked()), this, + SLOT(selectDir())); + connect(ui->pushButtonOpen, SIGNAL(clicked()), this, SLOT(open())); + connect(ui->pushButtonOpenLastFile, SIGNAL(clicked()), this, + SLOT(openLastFile())); + connect(ui->pushButtonOpenLastProject, SIGNAL(clicked()), this, + SLOT(openLastProject())); } -ProjectSelection::~ProjectSelection() -{ +/** + * Destructor. + */ +ProjectSelection::~ProjectSelection() { delete ui; } +/** + * Shows an error message. + * + * @param message message to show + */ +void ProjectSelection::error(const QString& message) { + QMessageBox dialog(QMessageBox::Critical, "Error", message, + QMessageBox::Close); + dialog.exec(); +} + +/** + * Opens a file or a directory (project directory). + */ +void ProjectSelection::open() { + QString name = ui->lineEditOpen->text(); + if (name.isEmpty()) + error("missing filename/project directory"); + else { + QFileInfo file(name); + if (!file.exists()) + error("does not exists: " + name); + else { + if (file.isDir()) + m_mainWindow->openProject(name); + else + m_mainWindow->openFile(name); + close(); + } + } +} + +/** + * Opens the selected recently opened file. + */ +void ProjectSelection::openLastFile() { + +} +/** + * Opens the selected recently opened project (project directory). + */ +void ProjectSelection::openLastProject() { + +} + +/** + * Selects a directory (project directory) with an open dialog. + */ +void ProjectSelection::selectDir() { + QString name = ui->lineEditOpen->text(); + if (name.isEmpty()) + name = m_mainWindow->project(); + name = QFileDialog::getExistingDirectory(this, + tr("Select Project Directory"), name); + if (!name.isEmpty()) { + ui->lineEditOpen->setText(name); + open(); + } +} + +/** + * Selects a file with a file open dialog. + */ +void ProjectSelection::selectFile() { + QString name = ui->lineEditOpen->text(); + name = QFileDialog::getOpenFileName(this, tr("Select File"), name); + if (!name.isEmpty()) { + ui->lineEditOpen->setText(name); + open(); + } +} + diff --git a/appl/reditor/projectselection.hpp b/appl/reditor/projectselection.hpp index 1625826..0439acc 100644 --- a/appl/reditor/projectselection.hpp +++ b/appl/reditor/projectselection.hpp @@ -4,8 +4,7 @@ * 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 PROJECTSELECTION_HPP #define PROJECTSELECTION_HPP @@ -15,17 +14,25 @@ namespace Ui { class ProjectSelection; } - -class ProjectSelection : public QDialog -{ +class MainWindow; +class ProjectSelection: public QDialog { Q_OBJECT public: - explicit ProjectSelection(QWidget *parent = 0); + explicit ProjectSelection(MainWindow* mainWindow, QWidget *parent = 0); ~ProjectSelection(); +public slots: + void open(); + void openLastFile(); + void openLastProject(); + void selectDir(); + void selectFile(); +private: + void error(const QString& message); private: Ui::ProjectSelection *ui; + MainWindow* m_mainWindow; }; #endif // PROJECTSELECTION_HPP diff --git a/appl/reditor/projectselection.ui b/appl/reditor/projectselection.ui index 91ccee6..baf7cd2 100644 --- a/appl/reditor/projectselection.ui +++ b/appl/reditor/projectselection.ui @@ -27,33 +27,46 @@ - + + + Name of the file/project directory to open + + + + Opens the file/project (Control-O) + - open + Open - Selects a file wit a file open dialog box + Selects a file wit a file open dialog box (Control-Shift-F) ... + + Ctrl+Shift+F + - + - Select a project directory with a directory open box + Select a project directory with a directory open box (Control-Shift-P) ... + + Ctrl+Shift+P + @@ -64,7 +77,7 @@ Qt::Horizontal - + @@ -101,7 +114,7 @@ Use wildcards: '*' (any string) and '?' (any character) - 6 + 3 1 @@ -124,9 +137,6 @@ Use wildcards: '*' (any string) and '?' (any character) Parent - - - @@ -145,9 +155,15 @@ Use wildcards: '*' (any string) and '?' (any character) - + + + Opens the selected last opened file (Control-F) + - Open again + Open File + + + Ctrl+F @@ -168,7 +184,7 @@ Use wildcards: '*' (any string) and '?' (any character) - + @@ -205,7 +221,7 @@ Use wildcards: '*' (any string) and '?' (any character) - 4 + 2 true @@ -223,8 +239,6 @@ Use wildcards: '*' (any string) and '?' (any character) Parent - - @@ -244,8 +258,14 @@ Use wildcards: '*' (any string) and '?' (any character) + + Opens the selected last opened project (Control-P) + - Open again + Open project + + + Ctrl+P diff --git a/appl/reditor/reditor.hpp b/appl/reditor/reditor.hpp new file mode 100644 index 0000000..47c5712 --- /dev/null +++ b/appl/reditor/reditor.hpp @@ -0,0 +1,19 @@ +/* + * 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 REDITOR_HPP +#define REDITOR_HPP +#include "base/rebase.hpp" +#include "gui/regui.hpp" +#include "storage.hpp" +#include "workspace.hpp" +#include "project.hpp" +#include "mainwindow.hpp" +#include "projectselection.hpp" +#endif // REDITOR_HPP + diff --git a/appl/reditor/reditor.pro b/appl/reditor/reditor.pro index b37d58c..22e1ff5 100644 --- a/appl/reditor/reditor.pro +++ b/appl/reditor/reditor.pro @@ -15,25 +15,33 @@ INCLUDEPATH += ../.. SOURCES += main.cpp\ ../../gui/ReEdit.cpp \ + ../../gui/ReStateStorage.cpp \ ../../base/ReFile.cpp \ mainwindow.cpp \ - ../../base/ReLogger.cpp \ - ../../base/ReQStringUtil.cpp \ - ../../base/ReException.cpp \ - projectselection.cpp + ../../base/ReLogger.cpp \ + ../../base/ReQStringUtil.cpp \ + ../../base/ReException.cpp \ + projectselection.cpp \ + workspace.cpp \ + project.cpp \ + storage.cpp HEADERS += mainwindow.hpp \ ../../base/rebase.hpp \ ../../gui/regui.hpp \ ../../gui/ReEdit.hpp \ - ../../base/ReStringUtil.hpp \ - ../../base/ReQStringUtil.hpp \ - ../../base/ReException.hpp \ - projectselection.hpp + ../../base/ReStringUtil.hpp \ + ../../base/ReQStringUtil.hpp \ + ../../base/ReException.hpp \ + projectselection.hpp \ + workspace.hpp \ + project.hpp \ + reditor.hpp \ + storage.hpp FORMS += mainwindow.ui \ - projectselection.ui + projectselection.ui RESOURCES += \ editor.qrc diff --git a/appl/reditor/storage.cpp b/appl/reditor/storage.cpp new file mode 100644 index 0000000..0acd8d9 --- /dev/null +++ b/appl/reditor/storage.cpp @@ -0,0 +1,31 @@ +/* + * 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 "reditor.hpp" + +/** + * Constructor. + * + * @param path the parent directory for the storage files + * @param prefix type of the storage: "proj" or "ws" (workspace) + */ +Storage::Storage(const QString& path, const QString prefix) : + m_path(path), + m_history(path + OS_SEPARATOR + ".reditor." + prefix + ".history"), + m_settings(path + OS_SEPARATOR + ".reditor." + prefix + ".settings") { + +} + +void Storage::addHistoryEntry(const char* key, const QString& value, + char separator, int maxEntries) { + ReStateStorage store(m_history); + store.addHistoryEntry(key, value, separator, maxEntries); + store.close(); + store.flushMap(); +} + diff --git a/appl/reditor/storage.hpp b/appl/reditor/storage.hpp new file mode 100644 index 0000000..9147586 --- /dev/null +++ b/appl/reditor/storage.hpp @@ -0,0 +1,24 @@ +/* + * 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 STORAGE_HPP +#define STORAGE_HPP + +class Storage { +public: + Storage(const QString& path, const QString prefix); +public: + void addHistoryEntry(const char* key, const QString& value, char separator, + int maxEntries); +protected: + QString m_path; + QString m_history; + QString m_settings; +}; + +#endif // STORAGE_HPP diff --git a/appl/reditor/workspace.cpp b/appl/reditor/workspace.cpp new file mode 100644 index 0000000..5f92d61 --- /dev/null +++ b/appl/reditor/workspace.cpp @@ -0,0 +1,15 @@ +/* + * 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 "reditor.hpp" + +Workspace::Workspace(const QString& path) : + Storage(path, "ws") { + +} + diff --git a/appl/reditor/workspace.hpp b/appl/reditor/workspace.hpp new file mode 100644 index 0000000..4602619 --- /dev/null +++ b/appl/reditor/workspace.hpp @@ -0,0 +1,17 @@ +/* + * 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 WORKSPACE_HPP +#define WORKSPACE_HPP + +class Workspace: public Storage { +public: + Workspace(const QString& path); +}; + +#endif // WORKSPACE_HPP diff --git a/appl/refind/mainwindow.cpp b/appl/refind/mainwindow.cpp index c7ec31b..bdf94df 100644 --- a/appl/refind/mainwindow.cpp +++ b/appl/refind/mainwindow.cpp @@ -39,24 +39,24 @@ const QString VERSION("2015.06.01"); */ MainWindow::MainWindow(const QString& startDir, const QString& homeDir, QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow), - m_statusMessage(NULL), - m_stdLabelBackgroundRole(NULL), - m_textFinder(), - m_lastBaseDir(), - m_horizontalHeader(NULL), - m_lastOrder(Qt::DescendingOrder), - m_homeDir(homeDir), - m_storageFile(), - m_contextHandlers(){ + QMainWindow(parent), + ui(new Ui::MainWindow), + m_statusMessage(NULL), + m_stdLabelBackgroundRole(NULL), + m_textFinder(), + m_lastBaseDir(), + m_horizontalHeader(NULL), + m_lastOrder(Qt::DescendingOrder), + m_homeDir(homeDir), + m_storageFile(), + m_contextHandlers(){ ui->setupUi(this); initializeHome(); m_statusMessage = new QLabel(tr("Welcome at refind")); if (!startDir.isEmpty()) - ui->comboBoxDirectory->setCurrentText(startDir); + ui->comboBoxDirectory->setCurrentText(startDir); if (ui->comboBoxDirectory->currentText().isEmpty()) - ui->comboBoxDirectory->setCurrentText(QDir::currentPath()); + ui->comboBoxDirectory->setCurrentText(QDir::currentPath()); ui->tableWidget->setMainWindow(this); statusBar()->addWidget(m_statusMessage); connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search())); @@ -65,37 +65,37 @@ MainWindow::MainWindow(const QString& startDir, const QString& homeDir, connect(ui->actionUp, SIGNAL(triggered()), this, SLOT(up())); connect(ui->pushButtonUp, SIGNAL(clicked()), this, SLOT(up())); connect(ui->actionSelectDirectory, SIGNAL(triggered()), this, - SLOT(selectDirectory())); + SLOT(selectDirectory())); connect(ui->actionSaveProgramState, SIGNAL(triggered()), this, - SLOT(saveState())); + SLOT(saveState())); connect(ui->pushButtonDirectory, SIGNAL(clicked()), this, - SLOT(selectDirectory())); + SLOT(selectDirectory())); connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about())); connect(ui->actionOptions, SIGNAL(triggered()), this, SLOT(options())); connect(ui->actionGetAbsPath, SIGNAL(triggered()), this, - SLOT(absPathToClipboard())); + SLOT(absPathToClipboard())); connect(ui->actionGetFullName, SIGNAL(triggered()), this, - SLOT(fullNameToClipboard())); + SLOT(fullNameToClipboard())); connect(ui->actionGetFullName, SIGNAL(triggered()), this, - SLOT(fullNameToClipboard())); + SLOT(fullNameToClipboard())); connect(ui->actionReset, SIGNAL(triggered()), this, SLOT(resetParameters())); connect(ui->tableWidget, SIGNAL(cellClicked(int,int)), this, SLOT(cellEntered(int, int))); connect(ui->actionExport, SIGNAL(triggered()), this, SLOT(exportFiles())); connect(ui->pushButtonExport, SIGNAL(clicked()), this, SLOT(exportFiles())); connect(ui->pushButtonExportFile, SIGNAL(clicked()), this, - SLOT(selectExportFile())); + SLOT(selectExportFile())); connect(ui->pushButtonFilePlaceholder, SIGNAL(clicked()), this, - SLOT(filePlaceholder())); + SLOT(filePlaceholder())); connect(ui->pushButtonHeaderPlaceholder, SIGNAL(clicked()), this, - SLOT(headerPlaceholder())); + SLOT(headerPlaceholder())); connect(ui->pushButtonFooterPlaceholder, SIGNAL(clicked()), this, - SLOT(footerPlaceholder())); + SLOT(footerPlaceholder())); connect(ui->actionPreview, SIGNAL(triggered()), this, SLOT(preview())); connect(ui->pushButtonPreview, SIGNAL(clicked()), this, SLOT(preview())); m_horizontalHeader = ui->tableWidget->horizontalHeader(); connect(m_horizontalHeader, SIGNAL(sectionClicked ( int ) ), - this, SLOT(headerClicked ( int ) )); + this, SLOT(headerClicked ( int ) )); ui->tableWidget->setColumnWidth(TC_NODE, 200); ui->tableWidget->setColumnWidth(TC_EXT, 40); ui->tableWidget->setColumnWidth(TC_SIZE, 125); @@ -116,18 +116,18 @@ MainWindow::~MainWindow(){ */ void MainWindow::initializeHome(){ if (m_homeDir.isEmpty()){ - m_homeDir = QDir::home().absoluteFilePath(".refind"); + m_homeDir = QDir::home().absoluteFilePath(".refind"); } QDir home(m_homeDir); if (!home.exists()){ - if (!home.mkpath(m_homeDir)){ - m_homeDir = home.tempPath() + "/.refind"; - home.mkpath(m_homeDir); - } + if (!home.mkpath(m_homeDir)){ + m_homeDir = home.tempPath() + "/.refind"; + home.mkpath(m_homeDir); + } } if (!m_homeDir.endsWith("/")) - m_homeDir += "/"; + m_homeDir += "/"; m_storageFile = m_homeDir + "state.conf"; restoreState(); } @@ -154,8 +154,8 @@ void MainWindow::options(){ void MainWindow::absPathToClipboard(){ int row = ui->tableWidget->currentRow(); if (row >= 0){ - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(buildAbsPath(row)); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(buildAbsPath(row)); } } @@ -180,17 +180,17 @@ QString MainWindow::buildAbsPath(int row, bool withNode, bool uriFormat){ QString rc(m_lastBaseDir.absolutePath()); QString value = cellAsText(row, TC_PATH); if (!value.isEmpty()){ - ReQStringUtil::ensureLastChar(rc, '/'); - rc += value; + ReQStringUtil::ensureLastChar(rc, '/'); + rc += value; } if (withNode){ - ReQStringUtil::ensureLastChar(rc, '/'); - rc += cellAsText(row, TC_NODE); + ReQStringUtil::ensureLastChar(rc, '/'); + rc += cellAsText(row, TC_NODE); } if (uriFormat){ - rc = "file://" + rc; + rc = "file://" + rc; #if defined WIN32 - rc = rc.replace('\\', '/'); + rc = rc.replace('\\', '/'); #endif } return rc; @@ -203,13 +203,13 @@ QString MainWindow::buildAbsPath(int row, bool withNode, bool uriFormat){ QDir::Filters MainWindow::buildFileTypes(){ QDir::Filters rc = 0; if (ui->checkBoxDirs->isChecked()) - rc |= QDir::Dirs; + rc |= QDir::Dirs; if (ui->checkBoxFiles->isChecked()) - rc |= QDir::Files; + rc |= QDir::Files; if (rc == 0) - rc |= QDir::Dirs | QDir::Files; + rc |= QDir::Dirs | QDir::Files; if (!ui->checkBoxLinks->isChecked()) - rc |= QDir::NoSymLinks; + rc |= QDir::NoSymLinks; return rc; } @@ -224,7 +224,7 @@ QString MainWindow::cellAsText(int row, int col){ QTableWidgetItem* widget = ui->tableWidget->item(row, col); QString rc; if (widget != NULL) - rc = widget->text(); + rc = widget->text(); return rc; } @@ -239,27 +239,27 @@ QString replaceEscSequences(const QString& text){ int start = 0; QString replacement; while (start < rc.length()){ - start = text.indexOf('\\', start); - if (start < 0) - break; - QChar replacement = 0; - switch (text[start + 1].toLatin1()) { - case 'n': - replacement = '\n'; - break; - case 't': - replacement = '\t'; - break; - case 'r': - replacement = '\r'; - break; - default: - replacement = text[start + 1]; - break; - } - rc.remove(start, 1); - rc[start] = replacement; - start++; + start = text.indexOf('\\', start); + if (start < 0) + break; + QChar replacement = 0; + switch (text[start + 1].toLatin1()) { + case 'n': + replacement = '\n'; + break; + case 't': + replacement = '\t'; + break; + case 'r': + replacement = '\r'; + break; + default: + replacement = text[start + 1]; + break; + } + rc.remove(start, 1); + rc[start] = replacement; + start++; } return rc; } @@ -277,25 +277,25 @@ void MainWindow::exportFiles(){ comboText(ui->comboBoxExportFile); comboText(ui->comboBoxFooter); if (ui->radioButtonFile->isChecked()){ - QString fn = ui->comboBoxExportFile->currentText(); - FILE* fp = fopen(fn.toUtf8(), "w"); - if (fp == NULL) - guiError(ui->comboBoxExportFile, tr("not a valid file: ") + fn); - else{ - QTextStream stream(fp); - exportToStream(stream); - fclose(fp); - setStatusMessage(false, tr("result exported to ") + fn); - } + QString fn = ui->comboBoxExportFile->currentText(); + FILE* fp = fopen(fn.toUtf8(), "w"); + if (fp == NULL) + guiError(ui->comboBoxExportFile, tr("not a valid file: ") + fn); + else{ + QTextStream stream(fp); + exportToStream(stream); + fclose(fp); + setStatusMessage(false, tr("result exported to ") + fn); + } }else{ - QString value; - QTextStream stream(&value); - m_errors = 0; - exportToStream(stream); - QClipboard* clipboard = QApplication::clipboard(); - clipboard->setText(value); - if (m_errors == 0) - setStatusMessage(false, tr("result exported to the clipboard")); + QString value; + QTextStream stream(&value); + m_errors = 0; + exportToStream(stream); + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(value); + if (m_errors == 0) + setStatusMessage(false, tr("result exported to the clipboard")); } } @@ -309,35 +309,35 @@ void MainWindow::exportToStream(QTextStream& stream, int maxRow){ QMap < QString, QString > placeholders; buildGlobalPlaceholders (placeholders); if (!ui->comboBoxHeader->currentText().isEmpty()){ - stream << replaceGlobalPlaceholders(ui->comboBoxHeader, placeholders) - << endl; + stream << replaceGlobalPlaceholders(ui->comboBoxHeader, placeholders) + << endl; } int count = ui->tableWidget->rowCount(); if (count > 0 && maxRow > 0) - count = maxRow; + count = maxRow; QString error; for (int ii = 0; ii < count; ii++){ - QString line = ui->comboBoxTemplate->currentText(); - QMap < QString, QString > placeholders; - QString path = m_lastBaseDir.absoluteFilePath( - ReQStringUtil::pathAppend(ui->tableWidget->item(ii, TC_PATH)->text(), - ui->tableWidget->item(ii, TC_NODE)->text())); - placeholders.insert("full", ReQStringUtil::nativePath(path)); - placeholders.insert("path", ui->tableWidget->item(ii, TC_PATH)->text()); - placeholders.insert("ext", ui->tableWidget->item(ii, TC_EXT)->text()); - placeholders.insert("node", ui->tableWidget->item(ii, TC_NODE)->text()); - placeholders.insert("modified", - ui->tableWidget->item(ii, TC_MODIFIED)->text()); - placeholders.insert("size", ui->tableWidget->item(ii, TC_SIZE)->text()); - if (!ReQStringUtil::replacePlaceholders(line, placeholders, &error)){ - guiError(ui->comboBoxTemplate, error); - break; - } - stream << replaceEscSequences(line) << endl; + QString line = ui->comboBoxTemplate->currentText(); + QMap < QString, QString > placeholders; + QString path = m_lastBaseDir.absoluteFilePath( + ReQStringUtil::pathAppend(ui->tableWidget->item(ii, TC_PATH)->text(), + ui->tableWidget->item(ii, TC_NODE)->text())); + placeholders.insert("full", ReQStringUtil::nativePath(path)); + placeholders.insert("path", ui->tableWidget->item(ii, TC_PATH)->text()); + placeholders.insert("ext", ui->tableWidget->item(ii, TC_EXT)->text()); + placeholders.insert("node", ui->tableWidget->item(ii, TC_NODE)->text()); + placeholders.insert("modified", + ui->tableWidget->item(ii, TC_MODIFIED)->text()); + placeholders.insert("size", ui->tableWidget->item(ii, TC_SIZE)->text()); + if (!ReQStringUtil::replacePlaceholders(line, placeholders, &error)){ + guiError(ui->comboBoxTemplate, error); + break; + } + stream << replaceEscSequences(line) << endl; } if (!ui->comboBoxFooter->currentText().isEmpty()){ - stream << replaceGlobalPlaceholders(ui->comboBoxFooter, placeholders) - << endl; + stream << replaceGlobalPlaceholders(ui->comboBoxFooter, placeholders) + << endl; } } @@ -350,42 +350,42 @@ void MainWindow::fileDragging(){ QMimeData *mimeData = new QMimeData; QList < QUrl > urls; QList < QTableWidgetSelectionRange > ranges = - ui->tableWidget->selectedRanges(); + ui->tableWidget->selectedRanges(); QList ::iterator it; int files = 0; int dirs = 0; bool isDir = false; for (it = ranges.begin(); it != ranges.end(); ++it){ - for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ - isDir = cellAsText(row, TC_SIZE).isEmpty(); - QUrl url(buildAbsPath(row, true, true)); - urls.append(url); - if (isDir) - dirs++; - else - files++; - } + for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ + isDir = cellAsText(row, TC_SIZE).isEmpty(); + QUrl url(buildAbsPath(row, true, true)); + urls.append(url); + if (isDir) + dirs++; + else + files++; + } } if (urls.size() > 0){ - mimeData->setUrls(urls); - drag->setMimeData(mimeData); - QPixmap image(200, 30); - QPainter painter(&image); - QString msg; - if (urls.size() == 1) - msg = tr("copy ") + ReQStringUtil::nodeOf(urls.at(0).toString()); - else if (files > 0 && dirs > 0) - msg = tr("copy %1 file(s) and %2 dir(s)").arg(files).arg(dirs); - else if (files > 0) - msg = tr("copy %1 file(s)").arg(files); - else - msg = tr("copy %1 dirs(s)").arg(dirs); - - painter.fillRect(image.rect(), Qt::white); - painter.drawText(10, 20, msg); - drag->setPixmap(image); - - Qt::DropAction dropAction = drag->exec(Qt::CopyAction); + mimeData->setUrls(urls); + drag->setMimeData(mimeData); + QPixmap image(200, 30); + QPainter painter(&image); + QString msg; + if (urls.size() == 1) + msg = tr("copy ") + ReQStringUtil::nodeOf(urls.at(0).toString()); + else if (files > 0 && dirs > 0) + msg = tr("copy %1 file(s) and %2 dir(s)").arg(files).arg(dirs); + else if (files > 0) + msg = tr("copy %1 file(s)").arg(files); + else + msg = tr("copy %1 dirs(s)").arg(dirs); + + painter.fillRect(image.rect(), Qt::white); + painter.drawText(10, 20, msg); + drag->setPixmap(image); + + Qt::DropAction dropAction = drag->exec(Qt::CopyAction); } } @@ -396,8 +396,8 @@ void MainWindow::filePlaceholder(){ DialogFilePlaceholder dialog; dialog.exec(); if (!dialog.var().isEmpty()){ - QComboBox* target = ui->comboBoxTemplate; - target->setCurrentText(target->currentText() + dialog.var()); + QComboBox* target = ui->comboBoxTemplate; + target->setCurrentText(target->currentText() + dialog.var()); } } @@ -414,10 +414,10 @@ void MainWindow::footerPlaceholder(){ void MainWindow::fullNameToClipboard(){ int row = ui->tableWidget->currentRow(); if (row >= 0){ - QClipboard* clipboard = QApplication::clipboard(); - QString path = buildAbsPath(row); - path += cellAsText(row, TC_NODE); - clipboard->setText(path); + QClipboard* clipboard = QApplication::clipboard(); + QString path = buildAbsPath(row); + path += cellAsText(row, TC_NODE); + clipboard->setText(path); } } @@ -432,30 +432,30 @@ void MainWindow::handleCopyToClipboard(int currentRow, const QString& full){ QList < QUrl > urls; bool isInSelection = false; QList < QTableWidgetSelectionRange > ranges = - ui->tableWidget->selectedRanges(); + ui->tableWidget->selectedRanges(); QList ::iterator it; QString textList; textList.reserve(ui->tableWidget->rowCount() * 80); for (it = ranges.begin(); it != ranges.end(); ++it){ - for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ - isInSelection = isInSelection || row == currentRow; - QString name(buildAbsPath(row, true)); - QUrl url(name); - textList += name + '\n'; - urls.append(url); - } + for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ + isInSelection = isInSelection || row == currentRow; + QString name(buildAbsPath(row, true)); + QUrl url(name); + textList += name + '\n'; + urls.append(url); + } } if (!isInSelection){ - urls.clear(); - urls.append(QUrl(full)); - textList = full; + urls.clear(); + urls.append(QUrl(full)); + textList = full; } mimeData->setUrls(urls); mimeData->setText(textList); QClipboard *clipboard = QApplication::clipboard(); clipboard->setMimeData(mimeData); setStatusMessage(false, - tr("%1 entry/entries copied to clipboard").arg(urls.length())); + tr("%1 entry/entries copied to clipboard").arg(urls.length())); } /** @@ -472,14 +472,14 @@ void MainWindow::handleExternalCommand(ContextHandler* handler, QString dir; switch (handler->m_directoryMode) { case ContextHandler::DM_TO_PARENT: - dir = parent; - break; + dir = parent; + break; case ContextHandler::DM_TO_FILE: - dir = full; - break; + dir = full; + break; default: - dir = ui->comboBoxDirectory->currentText(); - break; + dir = ui->comboBoxDirectory->currentText(); + break; } QMap < QString, QString > placeholders; placeholders.insert("full", full); @@ -490,18 +490,18 @@ void MainWindow::handleExternalCommand(ContextHandler* handler, QStringList args = arguments.split(' '); bool hasErrors = false; for (int ix = 0; ix < args.size(); ix++){ - QString arg = args.at(ix); - if (!ReQStringUtil::replacePlaceholders(arg, placeholders, &error)){ - guiError(NULL, error); - hasErrors = true; - break; - } - args.replace(ix, arg); + QString arg = args.at(ix); + if (!ReQStringUtil::replacePlaceholders(arg, placeholders, &error)){ + guiError(NULL, error); + hasErrors = true; + break; + } + args.replace(ix, arg); } if (!hasErrors){ - QProcess::startDetached(handler->m_program, args, dir, NULL); - setStatusMessage(false, - tr("started:") + " " + handler->m_program + " " + arguments); + QProcess::startDetached(handler->m_program, args, dir, NULL); + setStatusMessage(false, + tr("started:") + " " + handler->m_program + " " + arguments); } } @@ -514,7 +514,7 @@ void MainWindow::handlePlaceholder(QComboBox* target){ DialogGlobalPlaceholder dialog; dialog.exec(); if (!dialog.var().isEmpty()) - target->setCurrentText(target->currentText() + dialog.var()); + target->setCurrentText(target->currentText() + dialog.var()); } /** @@ -533,10 +533,10 @@ static int countSelectedRows(QTableWidget* table, int currentRow, QList < QTableWidgetSelectionRange > ranges = table->selectedRanges(); QList ::iterator it; for (it = ranges.begin(); it != ranges.end(); ++it){ - for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ - isInSelection = isInSelection || row == currentRow; - rc++; - } + for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ + isInSelection = isInSelection || row == currentRow; + rc++; + } } return rc; } @@ -549,51 +549,51 @@ static int countSelectedRows(QTableWidget* table, int currentRow, void MainWindow::handleTableContextMenu(const QPoint& position){ int currentRow = ui->tableWidget->rowAt(position.y()); if (currentRow >= 0){ - QMenu menu; - - QString node = ui->tableWidget->item(currentRow, TC_NODE)->text(); - QString parent = buildAbsPath(currentRow); - QString full = ReQStringUtil::pathAppend(parent, node); - QFileInfo file(full); - bool isDir = file.isDir(); - QList ::const_iterator it; - QMap actions; - ContextHandler* handler; - bool hasSeparator = false; - for (it = m_contextHandlers.list().begin(); - it != m_contextHandlers.list().end(); ++it){ - handler = *it; - if ((isDir && handler->m_fileType == ContextHandler::FT_FILE) - || (!isDir && handler->m_fileType == ContextHandler::FT_DIR)) - continue; - QString text = handler->m_text + " " + node; - if (handler->intrinsicType() != ContextHandler::IT_UNDEF){ - if (!hasSeparator){ - hasSeparator = true; - menu.addSeparator(); - } - bool inSelection = false; - int count = countSelectedRows(ui->tableWidget, currentRow, - inSelection); - if (inSelection) - text = handler->m_text + tr(" %1 object(s)").arg(count); - } - actions.insert(menu.addAction(text), handler); - } - QAction* selectedItem = menu.exec( - ui->tableWidget->viewport()->mapToGlobal(position)); - if (selectedItem != NULL){ - handler = *actions.find(selectedItem); - switch (handler->intrinsicType()) { - case ContextHandler::IT_COPY: - handleCopyToClipboard(currentRow, full); - break; - case ContextHandler::IT_UNDEF: - default: - handleExternalCommand(handler, parent, full, node); - break; - } - } + QMenu menu; + + QString node = ui->tableWidget->item(currentRow, TC_NODE)->text(); + QString parent = buildAbsPath(currentRow); + QString full = ReQStringUtil::pathAppend(parent, node); + QFileInfo file(full); + bool isDir = file.isDir(); + QList ::const_iterator it; + QMap actions; + ContextHandler* handler; + bool hasSeparator = false; + for (it = m_contextHandlers.list().begin(); + it != m_contextHandlers.list().end(); ++it){ + handler = *it; + if ((isDir && handler->m_fileType == ContextHandler::FT_FILE) + || (!isDir && handler->m_fileType == ContextHandler::FT_DIR)) + continue; + QString text = handler->m_text + " " + node; + if (handler->intrinsicType() != ContextHandler::IT_UNDEF){ + if (!hasSeparator){ + hasSeparator = true; + menu.addSeparator(); + } + bool inSelection = false; + int count = countSelectedRows(ui->tableWidget, currentRow, + inSelection); + if (inSelection) + text = handler->m_text + tr(" %1 object(s)").arg(count); + } + actions.insert(menu.addAction(text), handler); + } + QAction* selectedItem = menu.exec( + ui->tableWidget->viewport()->mapToGlobal(position)); + if (selectedItem != NULL){ + handler = *actions.find(selectedItem); + switch (handler->intrinsicType()) { + case ContextHandler::IT_COPY: + handleCopyToClipboard(currentRow, full); + break; + case ContextHandler::IT_UNDEF: + default: + handleExternalCommand(handler, parent, full, node); + break; + } + } } } /** @@ -603,8 +603,8 @@ void MainWindow::handleTableContextMenu(const QPoint& position){ */ void MainWindow::headerClicked(int col){ m_lastOrder = - m_lastOrder == Qt::AscendingOrder ? - Qt::DescendingOrder : Qt::AscendingOrder; + m_lastOrder == Qt::AscendingOrder ? + Qt::DescendingOrder : Qt::AscendingOrder; ui->tableWidget->sortItems(col, m_lastOrder); m_horizontalHeader->setSortIndicatorShown(true); m_horizontalHeader->setSortIndicator(col, m_lastOrder); @@ -624,8 +624,8 @@ void MainWindow::headerPlaceholder(){ void MainWindow::prepareContextMenu(){ ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->tableWidget, - SIGNAL(customContextMenuRequested(const QPoint&)), - SLOT(handleTableContextMenu(const QPoint&))); + SIGNAL(customContextMenuRequested(const QPoint&)), + SLOT(handleTableContextMenu(const QPoint&))); } /** @@ -786,33 +786,33 @@ else{ QStringList patterns; QString value = comboText(ui->comboBoxFilePatterns); if (!value.isEmpty()) - patterns = value.split(","); + patterns = value.split(","); finder.setPatterns(patterns); value = comboText(ui->comboBoxExcludedDirs); if (value.indexOf('/') >= 0 || value.indexOf('\\') >= 0) - guiError(ui->comboBoxExcludedDirs, tr("no path delimiter allowed")); + guiError(ui->comboBoxExcludedDirs, tr("no path delimiter allowed")); else if (value.indexOf('*') >= 0) - guiError(ui->comboBoxExcludedDirs, - tr("no patterns allowed. Do not use '*")); + guiError(ui->comboBoxExcludedDirs, + tr("no patterns allowed. Do not use '*")); else if (!value.isEmpty()) - patterns = value.split(","); + patterns = value.split(","); finder.setExcludedDirs(patterns); prepareTextFind(); if (m_errors == 0){ - if (!comboText(ui->comboBoxTextPattern).isEmpty()) - finder.setTextFinder(&m_textFinder); - m_statistics.clear(); - clock_t start = clock(); - finder.fillTable(path, 0, ui->tableWidget, m_statistics); - m_statistics.m_runtimeSeconds = (double) (clock() - start) - / CLOCKS_PER_SEC; - QString msg; - msg.sprintf( - QObject::tr( - "Found: %d dir(s) and %d file(s) with %.6f MByte. Duration of the search: %.3f sec").toUtf8(), - m_statistics.m_dirs, m_statistics.m_files, - m_statistics.m_bytes / 1000000.0, m_statistics.m_runtimeSeconds); - setStatusMessage(false, msg); + if (!comboText(ui->comboBoxTextPattern).isEmpty()) + finder.setTextFinder(&m_textFinder); + m_statistics.clear(); + clock_t start = clock(); + finder.fillTable(path, 0, ui->tableWidget, m_statistics); + m_statistics.m_runtimeSeconds = (double) (clock() - start) + / CLOCKS_PER_SEC; + QString msg; + msg.sprintf( + QObject::tr( + "Found: %d dir(s) and %d file(s) with %.6f MByte. Duration of the search: %.3f sec").toUtf8(), + m_statistics.m_dirs, m_statistics.m_files, + m_statistics.m_bytes / 1000000.0, m_statistics.m_runtimeSeconds); + setStatusMessage(false, msg); } } QApplication::restoreOverrideCursor(); @@ -847,7 +847,7 @@ if (!name.isEmpty()) void MainWindow::setStatusMessage(bool error, const QString& message){ if (m_stdLabelBackgroundRole == NULL) m_stdLabelBackgroundRole = new QPalette::ColorRole( - m_statusMessage->backgroundRole()); + m_statusMessage->backgroundRole()); m_statusMessage->setBackgroundRole( error ? QPalette::HighlightedText : *m_stdLabelBackgroundRole); m_statusMessage->setText(message); @@ -862,9 +862,9 @@ QDir dir(path); if (dir.exists()){ dir.cdUp(); if (dir.exists()){ - path = dir.absolutePath(); - ui->comboBoxDirectory->setEditText(path); - setInHistory(ui->comboBoxDirectory, path); + path = dir.absolutePath(); + ui->comboBoxDirectory->setEditText(path); + setInHistory(ui->comboBoxDirectory, path); } } } diff --git a/appl/refind/mainwindow.hpp b/appl/refind/mainwindow.hpp index e353573..7391964 100644 --- a/appl/refind/mainwindow.hpp +++ b/appl/refind/mainwindow.hpp @@ -41,11 +41,13 @@ class MainWindow: public QMainWindow, public ReGuiValidator { public: explicit MainWindow(const QString& startDir, const QString& homeDir, - QWidget *parent = 0); + QWidget *parent = 0); ~MainWindow(); public: - void fileDragging();private slots: + void fileDragging(); +protected: +private slots: void about(); void absPathToClipboard(); void baseDirToClipboard(); @@ -75,12 +77,12 @@ private: void exportToStream(QTextStream& stream, int maxRow = -1); void handleCopyToClipboard(int currentRow, const QString& full); void handleExternalCommand(ContextHandler* handler, const QString& parent, - const QString& full, const QString& node); + const QString& full, const QString& node); void handlePlaceholder(QComboBox* target); void initializeHome(); void prepareTextFind(); QString replaceGlobalPlaceholders(QComboBox* combo, - QMap & placeholders); + QMap & placeholders); void restoreState(); virtual void setStatusMessage(bool error, const QString& message); private: diff --git a/cunit/allTests.cpp b/cunit/allTests.cpp index 947702f..da2369b 100644 --- a/cunit/allTests.cpp +++ b/cunit/allTests.cpp @@ -20,6 +20,8 @@ static void testGui() { char* argv[2] = { (char*) "dummy", NULL }; int argc = 1; QApplication a(argc, argv); + void testReStateStorage(); + testReStateStorage(); void testReEdit(); testReEdit(); } diff --git a/cunit/cuReStateStorage.cpp b/cunit/cuReStateStorage.cpp new file mode 100644 index 0000000..0913da7 --- /dev/null +++ b/cunit/cuReStateStorage.cpp @@ -0,0 +1,97 @@ +/* + * cuReStateStorage.cpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ + +/** @file + * @brief Unit test of the ReStateStorage tools. + */ +#include "base/rebase.hpp" +#include "gui/regui.hpp" +/** + * @brief Unit test for ReStateStorage. + */ +class TestReStateStorage: public ReTest { +public: + TestReStateStorage() : + ReTest("ReStateStorage") { + doIt(); + } + +public: + void testBasic(){ + QByteArray fn(ReFile::tempFile("state.basic.$$$.txt", NULL, true)); + { + ReStateStorage store(fn); + store.setForm("singles"); + store.store("int", "4711"); + store.store("string", "\"with delimiters\""); + store.setForm("arrays"); + store.store("int", "111", 0); + store.store("int", "222", 1); + store.store("string", "abc", 0); + store.store("string", "xyz", 1); + // no explicite close() + } + ReStateStorage store(fn); + store.setForm("singles"); + checkEqu("4711", store.restore("int")); + checkEqu("\"with delimiters\"", store.restore("string")); + // unknown key: + checkEqu("", store.restore("unknown")); + + store.setForm("arrays"); + checkEqu("111", store.restore("int", 0)); + checkEqu("222", store.restore("int", 1)); + // unknown index: + checkEqu("", store.restore("int", 2)); + checkEqu("abc", store.restore("string", 0)); + checkEqu("xyz", store.restore("string", 1)); + checkEqu("", store.restore("string", 2)); + // unknown index: + store.close(); + } + void testAddHistoryEntry(){ + QByteArray fn(ReFile::tempFile("state.hist.$$$.txt", NULL, true)); + { + ReStateStorage store(fn); + store.setForm("common"); + store.addHistoryEntry("version", "v4", ';', 3); + store.addHistoryEntry("version", "v2", ';', 3); + // form as parameter: + store.setForm("disturbance"); + store.addHistoryEntry("version", "v3", ';', 3, "common"); + // move position of v2: + store.addHistoryEntry("version", "v2", ';', 3); + store.addHistoryEntry("version", "v1", ';', 3); + store.flushMap(); + } + ReStateStorage store(fn); + QStringList list; + store.setForm("common"); + checkEqu(3, store.historyAsList("version", list).size()); + checkEqu("v1", list.at(0)); + checkEqu("v2", list[1]); + checkEqu("v3", list[2]); + // wrong form: + store.setForm("nothing"); + checkEqu(0, store.historyAsList("version", list).size()); + // form as parameter: + checkEqu(3, store.historyAsList("version", list, "common").size()); + } + virtual void run() { + testAddHistoryEntry(); + testBasic(); + } +}; + +void testReStateStorage() { + TestReStateStorage test; +} + diff --git a/cunit/cunit.pro b/cunit/cunit.pro index 2c38ac6..f04aecf 100644 --- a/cunit/cunit.pro +++ b/cunit/cunit.pro @@ -19,7 +19,6 @@ SOURCES += main.cpp \ cuReQStringUtil.cpp \ cuReStringUtil.cpp \ cuReByteStorage.cpp \ - allTests.cpp \ cuReException.cpp \ ../base/ReByteStorage.cpp \ ../base/ReCharPtrMap.cpp \ @@ -33,15 +32,18 @@ SOURCES += main.cpp \ ../base/ReTerminator.cpp \ ../base/ReTest.cpp \ ../base/ReWriter.cpp \ + ../gui/ReStateStorage.cpp \ + ../gui/ReEdit.cpp \ cuReConfig.cpp \ cuReContainer.cpp \ cuReWriter.cpp \ cuReCharPtrMap.cpp \ cuReFile.cpp \ cuReEdit.cpp \ - ../gui/ReEdit.cpp + cuReStateStorage.cpp \ + allTests.cpp HEADERS += \ ../base/ReFile.hpp \ ../base/rebase.hpp \ - ../gui/ReEdit.hpp + ../gui/ReEdit.hpp diff --git a/gui/ReStateStorage.cpp b/gui/ReStateStorage.cpp index 3163cd2..b0c88c7 100644 --- a/gui/ReStateStorage.cpp +++ b/gui/ReStateStorage.cpp @@ -31,6 +31,68 @@ ReStateStorage::~ReStateStorage() { close(); } +/* + * Adds an entry to a history item at the first position. + * + * The entry will removed from the other positions. + * + * @param key the key in the map + * @param value the value to add + * @param separator separates the entries in the history item + * @param maxEntries the maximal count of entries in the history item.
+ * If the number exceeds the last entries will be removed + * @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) { + if (form != NULL) + setForm(form); + QByteArray key2; + if (!m_form.isEmpty()) + key2 = m_form + "."; + key2.append(key); + QString values; + QStringList listValues; + // Note: the first entry remains empty: + // the first char of the join is a separator + if (!m_map.contains(key2)) + listValues.append(""); + else { + values = m_map[key2]; + listValues = values.split(values[0]); + } + listValues.insert(1, value); + for (int ix = listValues.size() - 1; ix > 1; ix--) { + if (ix > maxEntries || listValues[ix] == value) { + listValues.removeAt(ix); + } + } + values = listValues.join(separator); + m_map.insert(key2, values); +} +/** + * Returns a history item as a list. + * + * @param key key of the history item + * @param list OUT: the list is filled with the history entries + * @param form a common prefix of the key. If NULL the current form is used + * @return list (for chaining) + */ +QStringList& ReStateStorage::historyAsList(const char* key, QStringList& list, + const char* form) { + list.clear(); + if (form != NULL) + setForm(form); + QString history = restore(key); + if (!history.isEmpty()) { + QChar separator = history[0]; + history = history.mid(1); + if (!history.isEmpty()) + list = history.split(separator); + } + return list; +} + /** * Closes open stream/file and frees the resources. */ @@ -43,6 +105,40 @@ void ReStateStorage::close() { } } +/** + * Writes the content of the map into the file. + */ +void ReStateStorage::flushMap() { + initForWrite(); + QMap::const_iterator it; + for (it = m_map.constBegin(); it != m_map.constEnd(); ++it) { + *m_stream << it.key() << "=" << it.value() << endl; + } + m_stream->flush(); +} +/** + * Returns the name of the current form. + * + * @return the name of the current form + */ +const QByteArray& ReStateStorage::form() const { + return m_form; +} + +/** + * Returns the full name of a widget. + * + * @param name the name of the widget + * @return
'.' or (if no form name is set) + */ +QByteArray ReStateStorage::fullname(const char* name) { + QByteArray rc; + if (!m_form.isEmpty()) + rc.append(m_form).append("."); + rc.append(name); + return rc; +} + /** * Initializes the instance for writing the storage information. */ @@ -59,7 +155,7 @@ bool ReStateStorage::initForRead() { int ixAssignment = line.indexOf('='); if (ixAssignment > 0) { value = line.mid(ixAssignment + 1); - QString key = line.mid(0, ixAssignment); + QByteArray key = line.mid(0, ixAssignment).toUtf8(); m_map.insert(key, value); } } @@ -76,33 +172,6 @@ bool ReStateStorage::initForWrite() { m_stream = new QTextStream(m_fp, QIODevice::ReadWrite); return m_stream != NULL; } -/** - * Returns the name of the current form. - * - * @return the name of the current form - */ -QString ReStateStorage::form() const { - return m_form; -} - -/** - * Returns the full name of a widget. - * - * @param name the name of the widget - * @return '.' or (if no form name is set) - */ -QString ReStateStorage::fullname(const QString& name) { - return m_form.isEmpty() ? name : m_form + "." + name; -} -/** - * Sets the name of the current form. - * - * @param form the name of the current form - */ -void ReStateStorage::setForm(const QString& form) { - m_form = form; -} - /** * Restores the data of a combobox. * @@ -110,14 +179,14 @@ void ReStateStorage::setForm(const QString& form) { * @param name the name of the combobox * @param withCurrentText true: the current text will be set too */ -void ReStateStorage::restore(QComboBox* combo, const QString& name, +void ReStateStorage::restore(QComboBox* combo, const char* name, bool withCurrentText) { if (initForRead()) { - QString keyPrefix = fullname(name) + ".item"; + QByteArray keyPrefix = fullname(name) + ".item"; int ix = 0; - QString key; + QByteArray key; while (true) { - key = keyPrefix + QString::number(ix); + key = keyPrefix + QByteArray::number(ix); if (!m_map.contains(key)) break; combo->addItem(m_map.value(key)); @@ -140,10 +209,10 @@ void ReStateStorage::restore(QComboBox* combo, const QString& name, * @return "": not found
* otherwise: the stored value of the variable */ -QString ReStateStorage::restore(const QString& name, int index) { +QString ReStateStorage::restore(const char* name, int index) { QString rc; if (initForRead()) { - QString key(name); + QByteArray key(fullname(name)); if (index >= 0) key += QString::number(index); if (m_map.contains(key)) @@ -151,6 +220,16 @@ QString ReStateStorage::restore(const QString& name, int index) { } return rc; } + +/** + * Sets the name of the current form. + * + * @param form the name of the current form + */ +void ReStateStorage::setForm(const char* form) { + m_form = form; +} + /** * Stores the data of a combobox. * @@ -158,19 +237,16 @@ QString ReStateStorage::restore(const QString& name, int index) { * @param name the name of the combobox * @param withCurrentText true: the current text will be saved too */ -void ReStateStorage::store(const QComboBox* combo, const QString& name, +void ReStateStorage::store(const QComboBox* combo, const char* name, bool withCurrentText) { if (initForWrite()) { - QString fullname; - if (!m_form.isEmpty()) - fullname = m_form + "."; - fullname += name; + QByteArray key(fullname(name)); for (int ii = 0; ii < combo->count(); ii++) { - *m_stream << fullname << ".item" << ii << "=" << combo->itemText(ii) + *m_stream << key << ".item" << ii << "=" << combo->itemText(ii) << endl; } if (withCurrentText) { - *m_stream << fullname << ".text=" << combo->currentText() << endl; + *m_stream << key << ".text=" << combo->currentText() << endl; } } m_stream->flush(); @@ -179,19 +255,16 @@ void ReStateStorage::store(const QComboBox* combo, const QString& name, /** * Stores the data of a combobox. * - * @param combo the combobox to store - * @param name the name of the combobox - * @param withCurrentText true: the current text will be saved too + * @param name the key of the key-value-pair. May be extended by m_form + * @param value the value to store */ -void ReStateStorage::store(const QString& name, const QString& value, - int index) { +void ReStateStorage::store(const char* name, const QString& value, int index) { if (initForWrite()) { - QString key(name); + QByteArray key(fullname(name)); if (index >= 0) key += QString::number(index); *m_stream << key << "=" << value << endl; } m_stream->flush(); - } diff --git a/gui/ReStateStorage.hpp b/gui/ReStateStorage.hpp index 99cec45..ddf2044 100644 --- a/gui/ReStateStorage.hpp +++ b/gui/ReStateStorage.hpp @@ -20,25 +20,36 @@ public: ReStateStorage(const QString& filename); virtual ~ReStateStorage(); public: + void addHistoryEntry(const char* key, const QString& value, char separator, + int maxEntries, const char* form = NULL); void close(); - QString form() const; - QString fullname(const QString& name); + void flushMap(); + const QByteArray& form() const; + QByteArray fullname(const char* name); + QStringList& historyAsList(const char* key, QStringList& list, + const char* form = NULL); bool initForRead(); bool initForWrite(); - void restore(QComboBox* combo, const QString& name, bool withCurrentText = + /** Returns the map containing the storage content. + * @return the map + */ + QMap& map() { + return m_map; + } + void restore(QComboBox* combo, const char* name, bool withCurrentText = false); - QString restore(const QString& name, int index = -1); - void setForm(const QString& form); - void store(const QComboBox* combo, const QString& name, - bool withCurrentText = true); - void store(const QString& name, const QString& value, int index = -1); + QString restore(const char* name, int index = -1); + void setForm(const char* form); + void store(const QComboBox* combo, const char* name, bool withCurrentText = + true); + void store(const char* name, const QString& value, int index = -1); private: QString m_filename; FILE* m_fp; QTextStream* m_stream; - QString m_form; - QMap m_map; + QByteArray m_form; + QMap m_map; }; #endif /* GUI_RESTATESTORAGE_HPP_ */