From ad538bf4d43446a8d0d30029146c594223ca66ce Mon Sep 17 00:00:00 2001 From: hama Date: Sun, 6 Sep 2015 13:21:52 +0200 Subject: [PATCH] StartPerspective + ProjectPerspective work --- appl/reide/mainwindow.cpp | 84 ++++----- appl/reide/mainwindow.hpp | 11 +- appl/reide/projectselection.cpp | 4 +- appl/reide/projectselection.hpp | 7 +- appl/reide/reide.hpp | 3 + appl/reide/views/EditorView.cpp | 15 +- appl/reide/views/EditorView.hpp | 6 +- appl/reide/views/FileTreeView.cpp | 7 +- appl/reide/views/FileTreeView.hpp | 3 + appl/reide/views/Perspective.cpp | 49 +++++- appl/reide/views/Perspective.hpp | 6 +- appl/reide/views/ProjectPerspective.cpp | 76 ++++++++- appl/reide/views/ProjectPerspective.hpp | 15 +- appl/reide/views/StartPerspective.cpp | 6 +- appl/reide/views/StartPerspective.hpp | 2 + appl/reide/views/StartView.cpp | 217 +++++++++++++++++++++++- appl/reide/views/StartView.hpp | 22 ++- appl/reide/views/View.cpp | 16 +- appl/reide/views/View.hpp | 9 +- base/ReFileUtils.cpp | 67 +++++--- base/ReFileUtils.hpp | 11 +- gui/ReSettings.cpp | 28 ++- gui/ReSettings.hpp | 5 +- gui/ReStateStorage.cpp | 33 +++- gui/ReStateStorage.hpp | 3 +- gui/regui.hpp | 6 +- remodules.hpp | 1 + 27 files changed, 569 insertions(+), 143 deletions(-) diff --git a/appl/reide/mainwindow.cpp b/appl/reide/mainwindow.cpp index b4a8188..2113d55 100644 --- a/appl/reide/mainwindow.cpp +++ b/appl/reide/mainwindow.cpp @@ -16,13 +16,10 @@ MainWindow::MainWindow(const char* workspace, const char* project, ReLogger* logger, QWidget *parent) : QMainWindow(parent), - ui(new Ui::MainWindow), - m_project(NULL), m_workspace(NULL), m_logger(logger), - m_fileTree(NULL), - m_dockProjectTree(NULL), m_perspectives(this) { + setLayout(new QVBoxLayout); if (workspace == NULL) workspace = QDir::homePath().toUtf8(); changeWorkspace(workspace == NULL ? QDir::homePath() : workspace); @@ -37,23 +34,23 @@ MainWindow::MainWindow(const char* workspace, const char* project, if (dir.isDir() && dir.isWritable()) proj = lastProjects.at(ix); } - if (!proj.isEmpty()) - changeProject(proj); + if (proj.isEmpty()) + proj = QDir::homePath(); + } + changeProject(proj); - //ui->setupUi(this); - //ReEdit* edit = ui->widget; - //edit->setLines(m_file); - //edit->setCursorLine(0); //connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(open())); Perspective* mainPerspective = new StartPerspective(this); m_perspectives.addPerspective(mainPerspective); - m_perspectives.changePerspective(mainPerspective->name()); - //open(); + m_perspectives.change(mainPerspective->name()); + m_perspectives.addPerspective(new ProjectPerspective(proj, this)); } +/** + * Destructor. + */ MainWindow::~MainWindow() { - delete ui; } /** @@ -62,23 +59,9 @@ MainWindow::~MainWindow() { * @param path the directory containing the project data */ void MainWindow::changeProject(QString path) { - delete m_project; - if (path.endsWith(OS_SEPARATOR_STR)) - path.remove(path.size() - 1, 1); - m_project = new Project(path, this); - int maxEntries = m_workspace->intValue("history.max_projects"); - m_workspace->addHistoryEntry(Workspace::KEY_HISTORY_PROJECTS, path, ';', - maxEntries); - if (m_fileTree == NULL) { - m_fileTree = new ReFileTree(path, m_logger, this); - m_dockProjectTree = new QDockWidget("", this); - m_dockProjectTree->setWidget(m_fileTree); - addDockWidget(Qt::LeftDockWidgetArea, m_dockProjectTree); - } - m_fileTree->setPath(path); - m_dockProjectTree->setWindowTitle( - tr("Project") + " " + ReQStringUtils::nodeOf(path)); - + ProjectPerspective* perspective = perspectives().project(true); + if (perspective != NULL) + perspective->changeProject(path); } /** @@ -95,22 +78,9 @@ void MainWindow::changeWorkspace(const QString& path) { * Calls the file selection dialog. */ void MainWindow::openFile(const QString& name) { - m_file = new ReFile(name, false); - - //ReEdit* edit = ui->widget; - //edit->setLines(m_file); - //edit->setCursorLine(0); - int maxEntries = m_workspace->intValue("history.max_files"); - m_workspace->addHistoryEntry(Workspace::KEY_HISTORY_FILES, name, ';', - maxEntries); -} - -/** - * Closes the current project. - */ -void MainWindow::closeProject() { - delete m_project; - m_project = NULL; + ProjectPerspective* perspective = perspectives().project(true); + if (perspective != NULL) + perspective->openFile(name); } /** @@ -120,19 +90,29 @@ void MainWindow::open() { ProjectSelection dialog(this); dialog.exec(); } -ReLogger* MainWindow::logger() const { - return m_logger; +/** + * Returns the perspective list. + * + * @return the perspective list + */ +PerspectiveList& MainWindow::perspectives() { + return m_perspectives; } /** - * Returns the current workspace. + * Returns the logger. * - * @return the current workspace + * @return the logger */ -Project* MainWindow::project() const { - return m_project; +ReLogger* MainWindow::logger() const { + return m_logger; } +/** + * Returns the workspace. + * + * @return the workspace + */ Workspace* MainWindow::workspace() const { return m_workspace; } diff --git a/appl/reide/mainwindow.hpp b/appl/reide/mainwindow.hpp index dfb35fb..d80f3b4 100644 --- a/appl/reide/mainwindow.hpp +++ b/appl/reide/mainwindow.hpp @@ -16,9 +16,6 @@ #ifndef REBASE_HPP #include "reide.hpp" #endif -namespace Ui { -class MainWindow; -} class MainWindow: public QMainWindow { Q_OBJECT @@ -29,22 +26,16 @@ public: ~MainWindow(); void changeProject(QString path); void changeWorkspace(const QString& path); - void closeProject(); void openFile(const QString& name); - Project* project() const; Workspace* workspace() const; ReLogger* logger() const; + PerspectiveList& perspectives(); public slots: void open(); private: - Ui::MainWindow *ui; - ReFile* m_file; - Project* m_project; Workspace* m_workspace; ReLogger* m_logger; - ReFileTree* m_fileTree; - QDockWidget* m_dockProjectTree; PerspectiveList m_perspectives; }; diff --git a/appl/reide/projectselection.cpp b/appl/reide/projectselection.cpp index e8972a7..17c78d6 100644 --- a/appl/reide/projectselection.cpp +++ b/appl/reide/projectselection.cpp @@ -189,8 +189,8 @@ void ProjectSelection::open() { */ void ProjectSelection::selectDir() { QString name = ui->lineEditOpen->text(); - if (name.isEmpty() && m_mainWindow->project() != NULL) - name = m_mainWindow->project()->path(); + if (name.isEmpty()) + name = m_mainWindow->perspectives().project()->path(); name = QFileDialog::getExistingDirectory(this, tr("Select Project Directory"), name); if (!name.isEmpty()) { diff --git a/appl/reide/projectselection.hpp b/appl/reide/projectselection.hpp index 9a56e71..a04d1e3 100644 --- a/appl/reide/projectselection.hpp +++ b/appl/reide/projectselection.hpp @@ -11,9 +11,14 @@ #ifndef PROJECTSELECTION_HPP #define PROJECTSELECTION_HPP -#include "reide.hpp" #include #include +#if ! defined REBASE_HPP +#include "base/rebase.hpp" +#endif +#if ! defined REGUI_HPP +#include "gui/regui.hpp" +#endif namespace Ui { class ProjectSelection; } diff --git a/appl/reide/reide.hpp b/appl/reide/reide.hpp index bacca58..028baf2 100644 --- a/appl/reide/reide.hpp +++ b/appl/reide/reide.hpp @@ -12,6 +12,9 @@ #ifndef REIDE_HPP #define REIDE_HPP #include +#include +#include +#include #include "base/rebase.hpp" #include "gui/regui.hpp" #include "views/View.hpp" diff --git a/appl/reide/views/EditorView.cpp b/appl/reide/views/EditorView.cpp index 3c15d7e..992d58d 100644 --- a/appl/reide/views/EditorView.cpp +++ b/appl/reide/views/EditorView.cpp @@ -18,7 +18,9 @@ */ EditorView::EditorView(MainWindow* mainWindow) : View("EditorView", mainWindow), - m_edit(new ReEdit(NULL)) { + m_edit(new ReEdit(NULL)), + m_file(NULL) { + m_edit->setLines(&m_dummyFile); } /** @@ -29,3 +31,14 @@ EditorView::~EditorView() { m_edit = NULL; } +/** + * Opens a file into the editor widget. + * + * @param filename the filename with path + */ +void EditorView::openFile(const QString& filename) { + delete m_file; + m_file = new ReFile(filename, false, m_mainWindow->logger()); + m_edit->setLines(m_file); +} + diff --git a/appl/reide/views/EditorView.hpp b/appl/reide/views/EditorView.hpp index bd556fe..bb3d8f8 100644 --- a/appl/reide/views/EditorView.hpp +++ b/appl/reide/views/EditorView.hpp @@ -23,13 +23,17 @@ class EditorView: public View { public: EditorView(MainWindow* mainWindow); ~EditorView(); +public: + void openFile(const QString& filename); + public: virtual QWidget* widget() { return m_edit; } - ; protected: ReEdit* m_edit; + ReFile* m_file; + ReLines m_dummyFile; }; #endif // EDITORVIEW_HPP diff --git a/appl/reide/views/FileTreeView.cpp b/appl/reide/views/FileTreeView.cpp index 90388d5..5eacbc0 100644 --- a/appl/reide/views/FileTreeView.cpp +++ b/appl/reide/views/FileTreeView.cpp @@ -11,6 +11,7 @@ #include "reide.hpp" +const char* FileTreeView::NAME = "FileTree"; /** * Constructor. * @@ -18,6 +19,10 @@ * @param mainWindow the parent (main window) */ FileTreeView::FileTreeView(const QString& directory, MainWindow* mainWindow) : - View("FileTreeView", mainWindow), + View(NAME, mainWindow), m_fileTree(new ReFileTree(directory, mainWindow->logger())) { } + +FileTreeView::~FileTreeView() { + delete m_fileTree; +} diff --git a/appl/reide/views/FileTreeView.hpp b/appl/reide/views/FileTreeView.hpp index 239a9bf..b83e2f9 100644 --- a/appl/reide/views/FileTreeView.hpp +++ b/appl/reide/views/FileTreeView.hpp @@ -18,8 +18,11 @@ * A view is a widget displayed as a dock in the window displaying a perspective. */ class FileTreeView: public View { +public: + static const char* NAME; public: FileTreeView(const QString& directory, MainWindow* mainWindow); + ~FileTreeView(); public: /** Returns the view specific widget. * @return the view specific widget diff --git a/appl/reide/views/Perspective.cpp b/appl/reide/views/Perspective.cpp index c733b93..14c1e42 100644 --- a/appl/reide/views/Perspective.cpp +++ b/appl/reide/views/Perspective.cpp @@ -36,7 +36,8 @@ Perspective::~Perspective() { */ void Perspective::activate() { // the first view is the central widget, not a dock - m_mainWindow->setCentralWidget(m_views.at(0)->m_view->widget()); + QWidget* root = m_views.at(0)->m_view->widget(); + m_mainWindow->setCentralWidget(root); for (int ix = 1; ix < m_views.size(); ix++) { ViewInfo* info = m_views.at(ix); m_mainWindow->addDockWidget(info->m_position, info->m_dockWidget); @@ -90,12 +91,44 @@ void PerspectiveList::addPerspective(Perspective* perspective) { /** * Deactivates the current perspective and activates another. * - * @param perspective name of the new active perspective + * @param name name of the new active perspective */ -void PerspectiveList::changePerspective(const QByteArray& perspective) { - if (m_current != NULL) - m_current->deactivate(); - m_current = m_map.value(perspective); - if (m_current != NULL) - m_current->activate(); +Perspective* PerspectiveList::change(const QByteArray& name) { + if (m_current == NULL || m_current->name() != name) { + if (m_current != NULL) + m_current->deactivate(); + m_current = get(name); + if (m_current != NULL) + m_current->activate(); + } + return m_current; +} + +/** + * Returns the perspective given by name. + * + * @param name the name of the wanted perspective + * @return NULL: not known
+ * otherwise: the wanted perspective + */ +Perspective*PerspectiveList::get(const QByteArray& name) { + Perspective* rc = m_map.value(name); + return rc; +} + +/** + * Returns the project perspective. + * + * @param activate true: the project perspective will be activated + * @return the project perspective + */ +ProjectPerspective* PerspectiveList::project(bool activate) { + ProjectPerspective* rc; + if (activate) + rc = reinterpret_cast(change( + ProjectPerspective::NAME)); + else + rc = + reinterpret_cast(get(ProjectPerspective::NAME)); + return rc; } diff --git a/appl/reide/views/Perspective.hpp b/appl/reide/views/Perspective.hpp index 64d6388..f070304 100644 --- a/appl/reide/views/Perspective.hpp +++ b/appl/reide/views/Perspective.hpp @@ -50,7 +50,7 @@ protected: MainWindow* m_mainWindow; QList m_views; }; - +class ProjectPerspective; /** * Manages a collection of Perspectives. */ @@ -59,7 +59,9 @@ public: PerspectiveList(MainWindow* mainWindow); public: void addPerspective(Perspective* perspective); - void changePerspective(const QByteArray& perspective); + Perspective* change(const QByteArray& name); + Perspective* get(const QByteArray& name); + ProjectPerspective* project(bool activate = false); private: Perspective* m_current; QMap m_map; diff --git a/appl/reide/views/ProjectPerspective.cpp b/appl/reide/views/ProjectPerspective.cpp index c8216ee..1cf21a3 100644 --- a/appl/reide/views/ProjectPerspective.cpp +++ b/appl/reide/views/ProjectPerspective.cpp @@ -11,20 +11,90 @@ #include "reide.hpp" +const char* ProjectPerspective::NAME = "Project"; + +const char* ProjectPerspective::KEY_HISTORY_OPEN_FILES = "openFiles"; /** * Constructor. * * @param mainWindow the parent (main window) */ -ProjectPerspective::ProjectPerspective(MainWindow* mainWindow) : - Perspective("ProjectPerspective", mainWindow) { +ProjectPerspective::ProjectPerspective(const QString& path, + MainWindow* mainWindow) : + Perspective(NAME, mainWindow), + ReSettings(path, ".reditor.proj", mainWindow->logger()), + m_editorView(NULL) { setDefaultViews(); + //QString filename = topOfHistory(KEY_HISTORY_OPEN_FILES); + //QFileInfo info(filename); + //if (!filename.isEmpty() && info.exists() && !info.isDir()) { + // openFile(filename); + //} } +/** + * Change the project. + * + * @param path the path of the new current project + */ +void ProjectPerspective::changeProject(const QString& path) { + setPath(path); + int maxEntries = m_mainWindow->workspace()->intValue( + "history.max_projects"); + m_mainWindow->workspace()->addHistoryEntry(Workspace::KEY_HISTORY_PROJECTS, + m_path, ';', maxEntries); + /*
+	 if (m_fileTree == NULL) {
+	 m_fileTree = new ReFileTree(path, m_logger, this);
+	 m_dockProjectTree = new QDockWidget("", this);
+	 m_dockProjectTree->setWidget(m_fileTree);
+	 addDockWidget(Qt::LeftDockWidgetArea, m_dockProjectTree);
+	 }
+	 m_fileTree->setPath(path);
+	 m_dockProjectTree->setWindowTitle(
+	 tr("Project") + " " + ReQStringUtils::nodeOf(path));
+	 
+ */ + +} + +/** + * Opens a file in the project directory. + * + * @param filename the filename relative to the project directory + */ +void ProjectPerspective::openFile(const QString& filename) { + QString full; + if (ReFileUtils::isAbsolutPath(filename)) { + full = filename; + } else { + full = m_path + OS_SEPARATOR_STR + filename; + } + m_editorView->openFile(full); + addHistoryEntry(KEY_HISTORY_OPEN_FILES, full, ';', 1); +} + +/** + * Sets the name of the project directory. + * + * @param path the directory name + */ +void ProjectPerspective::setPath(const QString& path) { + if (!path.endsWith(OS_SEPARATOR_STR)) + ReSettings::setPath(path); + else + ReSettings::setPath(m_path.mid(0, path.size() - 1)); +} + +/** + * Sets the default views of the project perspective. + */ void ProjectPerspective::setDefaultViews() { if (m_views.size() == 0) { - append(new EditorView(m_mainWindow), Qt::NoDockWidgetArea); + m_editorView = new EditorView(m_mainWindow); + append(m_editorView, Qt::NoDockWidgetArea); append(new FileTreeView(QDir::homePath(), m_mainWindow), Qt::LeftDockWidgetArea); } } + diff --git a/appl/reide/views/ProjectPerspective.hpp b/appl/reide/views/ProjectPerspective.hpp index fc55bec..5f18054 100644 --- a/appl/reide/views/ProjectPerspective.hpp +++ b/appl/reide/views/ProjectPerspective.hpp @@ -15,11 +15,22 @@ /** * Manages the aspects of a standard project. */ -class ProjectPerspective: public Perspective { +class ProjectPerspective: public Perspective, public ReSettings { public: - ProjectPerspective(MainWindow* mainWindow); + static const char* NAME; +public: + static const char* KEY_HISTORY_OPEN_FILES; +public: + ProjectPerspective(const QString& path, MainWindow* mainWindow); public: virtual void setDefaultViews(); +public: + void openFile(const QString& filename); + void changeProject(const QString& path); + void setPath(const QString& path); + +private: + EditorView* m_editorView; }; #endif // PROJECTPERSPECTIVE_HPP diff --git a/appl/reide/views/StartPerspective.cpp b/appl/reide/views/StartPerspective.cpp index 9aab7a0..866f16f 100644 --- a/appl/reide/views/StartPerspective.cpp +++ b/appl/reide/views/StartPerspective.cpp @@ -11,18 +11,20 @@ #include "reide.hpp" +const char* StartPerspective::NAME = "Start"; + /** * Constructor. * * @param mainWindow the parent (main window) */ StartPerspective::StartPerspective(MainWindow* mainWindow) : - Perspective("StartPerspective", mainWindow) { + Perspective(NAME, mainWindow) { setDefaultViews(); } void StartPerspective::setDefaultViews() { - if (m_views.size() == 0){ + if (m_views.size() == 0) { append(new StartView(m_mainWindow), Qt::NoDockWidgetArea); } } diff --git a/appl/reide/views/StartPerspective.hpp b/appl/reide/views/StartPerspective.hpp index 269aec9..ef23f8a 100644 --- a/appl/reide/views/StartPerspective.hpp +++ b/appl/reide/views/StartPerspective.hpp @@ -16,6 +16,8 @@ * Manages the aspects of a standard project. */ class StartPerspective: public Perspective { +public: + static const char* NAME; public: StartPerspective(MainWindow* mainWindow); public: diff --git a/appl/reide/views/StartView.cpp b/appl/reide/views/StartView.cpp index 756941a..470c8d7 100644 --- a/appl/reide/views/StartView.cpp +++ b/appl/reide/views/StartView.cpp @@ -7,6 +7,8 @@ */ #include "reide.hpp" +#include +#include #include "ui_startview.h" /** @@ -19,6 +21,23 @@ StartView::StartView(MainWindow* mainWindow) : View("StartView", mainWindow), ui(new Ui::StartView) { 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->lineEditFilterLastFile, SIGNAL(textChanged(QString)), this, + SLOT(textChangedFilterFiles(QString))); + connect(ui->tableWidgetFiles, SIGNAL(cellEntered(int,int)), this, + SLOT(cellEnteredFiles(int, int))); + connect(ui->tableWidgetProjects, SIGNAL(cellEntered(int,int)), this, + SLOT(cellEnteredProjects(int, int))); + Workspace* workspace = mainWindow->workspace(); + buildTableInfo(workspace, Workspace::KEY_HISTORY_FILES, true, m_files); + buildTableInfo(workspace, Workspace::KEY_HISTORY_PROJECTS, false, + m_projects); + buildTable("", m_files, ui->tableWidgetFiles); + buildTable("", m_projects, ui->tableWidgetProjects); } /** @@ -28,11 +47,205 @@ StartView::~StartView() { delete ui; } +/** + * Handles the event cellEntered for the last opened files. + * + * @param row the row of the entered cell + * @param col the column of the entered cell + */ +void StartView::cellEnteredFiles(int row, int col) { + ReUseParameter(col); + QString file = fileOfTable(ui->tableWidgetFiles, row); + ui->lineEditOpen->setText(file); +} + +/** + * Handles the event cellEntered for the last opened projects. + * + * @param row the row of the entered cell + * @param col the column of the entered cell + */ +void StartView::cellEnteredProjects(int row, int col) { + ReUseParameter(col); + QString file = fileOfTable(ui->tableWidgetProjects, row); + ui->lineEditOpen->setText(file); +} + +/** + * Builds the table from the table using a filter expression. + * + * @param filter a filter expression with wildcards '*' + * @param lines the full table info + * @param table OUT: will be filled with all lines matching the filter + */ +void StartView::buildTable(const QString& filter, const QStringList& lines, + QTableWidget* table) { + QStringList::const_iterator it; + int rowCount = 0; + ReMatcher matcher(filter, Qt::CaseInsensitive, true); + for (it = lines.cbegin(); it != lines.cend(); ++it) { + if (matcher.matches(*it)) + rowCount++; + } + table->setRowCount(rowCount); + int row = -1; + for (it = lines.cbegin(); it != lines.cend(); ++it) { + if (matcher.matches(*it)) { + row++; + QStringList cols = it->split('\t'); + for (int col = 0; col < cols.size(); col++) { + QTableWidgetItem* item = table->item(row, col); + if (item != NULL) + item->setText(cols.at(col)); + else { + item = new QTableWidgetItem(cols.at(col)); + table->setItem(row, col, item); + } + } + } + } +} + +/** + * Build the info for a table (last opened files or last opened projects). + * + * Note: the table shows a filtered part of this info. + * + * @param settings the history container + * @param key the name of the history entry + * @param withDate the file's name is part of the info + * @param tableContent OUT: the list containing the table info + */ +void StartView::buildTableInfo(ReSettings* settings, const char* key, + bool withDate, QStringList& tableContent) { + QStringList files; + settings->historyAsList(key, files); + QStringList::const_iterator it; + for (it = files.cbegin(); it != files.cend(); ++it) { + QFileInfo file(*it); + if (file.exists()) { + QString info = file.fileName(); + if (withDate) + info.append("\t").append( + file.lastModified().toString("yyyy.mm.dd/HH:MM:SS")); + info.append("\t").append(file.path()); + tableContent.append(info); + } + } +} + +/** + * Shows an error message. + * + * @param message message to show + */ +void StartView::error(const QString& message) { + QMessageBox dialog(QMessageBox::Critical, "Error", message, + QMessageBox::Close); + dialog.exec(); +} + +/** + * Extracts the full filename of a given table. + * + * The node is the first column, the path the last. + * + * @param table the table from which the filename is taken + * @param row the row where the filename is + * @return the full name of the file in the given row + */ +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(); + return file; +} +/** + * Opens a file or a directory (project directory). + */ +void StartView::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->perspectives().project(true)->openFile(name); + else + m_mainWindow->openFile(name); + close(); + } + } +} + +/** + * Selects a directory (project directory) with an open dialog. + */ +void StartView::selectDir() { + QString name = ui->lineEditOpen->text(); + if (name.isEmpty()) + name = m_mainWindow->perspectives().project()->path(); + 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 StartView::selectFile() { + QString name = ui->lineEditOpen->text(); + name = QFileDialog::getOpenFileName(this, tr("Select File"), name); + if (!name.isEmpty()) { + ui->lineEditOpen->setText(name); + open(); + } +} + +/** + * Handles the filter text change for a given table. + * + * @param text the filter text + * @param table the table which will be filled + * @param lines the full (unfiltered) table info + */ +void StartView::textChanged(const QString& text, QTableWidget* table, + const QStringList& lines) { + buildTable(text, lines, table); + if (table->rowCount() > 0) { + QString file = fileOfTable(table, 0); + ui->lineEditOpen->setText(file); + } +} + +/** + * Handles the event "text changed" of the last opened files. + * + * @param text the new text + */ +void StartView::textChangedFilterFiles(const QString& text) { + textChanged(text, ui->tableWidgetFiles, m_files); +} + +/** + * Handles the event "text changed" of the last opened projects. + * + * @param text the new text + */ +void StartView::textChangedFilterProjects(const QString& text) { + textChanged(text, ui->tableWidgetProjects, m_projects); +} /** * Returns the view specific widget. * * @return the view specific widget */ -QWidget*StartView::widget() { - return NULL; // ui->startWidget +QWidget* StartView::widget() { + return this; } diff --git a/appl/reide/views/StartView.hpp b/appl/reide/views/StartView.hpp index 2cc7fac..375131a 100644 --- a/appl/reide/views/StartView.hpp +++ b/appl/reide/views/StartView.hpp @@ -8,8 +8,7 @@ #ifndef STARTVIEW_HPP #define STARTVIEW_HPP - -#include +#include #include "View.hpp" namespace Ui { class StartView; @@ -29,8 +28,27 @@ public: public: virtual QWidget* widget(); +protected: + void buildTable(const QString& filter, const QStringList& lines, + QTableWidget* table); + void buildTableInfo(ReSettings* settings, const char* key, bool withDate, + QStringList& tableContent); + QString fileOfTable(QTableWidget* table, int row);public slots: + void open(); + void selectDir(); + void selectFile();protected slots: + void textChanged(const QString& text, QTableWidget* table, + const QStringList& lines);protected slots: + void cellEnteredFiles(int row, int col); + void cellEnteredProjects(int row, int col); + void textChangedFilterFiles(const QString& text); + void textChangedFilterProjects(const QString& text); +private: + void error(const QString& message); private: Ui::StartView *ui; + QStringList m_files; + QStringList m_projects; }; #endif // STARTVIEW_HPP diff --git a/appl/reide/views/View.cpp b/appl/reide/views/View.cpp index 86dc497..65cdad0 100644 --- a/appl/reide/views/View.cpp +++ b/appl/reide/views/View.cpp @@ -19,5 +19,19 @@ */ View::View(const char* name, MainWindow* mainWindow) : m_name(name), - m_mainWindow(mainWindow) { + m_mainWindow(mainWindow), + m_rootLayout(NULL) { +} + +/** + * Returns the outermost widget of the view which must be a layout. + * + * @return return m_rootLayout; + */ +QLayout* View::rootLayout() { + if (m_rootLayout == NULL) { + m_rootLayout = new QVBoxLayout; + m_rootLayout->addWidget(widget()); + } + return m_rootLayout; } diff --git a/appl/reide/views/View.hpp b/appl/reide/views/View.hpp index 6ba783c..73d99a2 100644 --- a/appl/reide/views/View.hpp +++ b/appl/reide/views/View.hpp @@ -13,7 +13,12 @@ #define VIEW_HPP class MainWindow; - +#if ! defined REBASE_HPP +#include "base/rebase.hpp" +#endif +#if ! defined REGUI_HPP +#include "gui/regui.hpp" +#endif /** * Base class of the views. * @@ -35,9 +40,11 @@ public: */ virtual QWidget* widget() = 0; + virtual QLayout* rootLayout(); protected: QByteArray m_name; MainWindow* m_mainWindow; + QLayout* m_rootLayout; }; #endif // VIEW_HPP diff --git a/base/ReFileUtils.cpp b/base/ReFileUtils.cpp index 7228f05..6d667f4 100644 --- a/base/ReFileUtils.cpp +++ b/base/ReFileUtils.cpp @@ -17,14 +17,31 @@ enum { LOC_DELETE_TREE_3, // 11803 }; - /** * Constructor. */ ReTreeStatistic::ReTreeStatistic() : - m_files(0), - m_directories(0), - m_fileSizes(0L){ + m_files(0), + m_directories(0), + m_fileSizes(0L) { +} + +/** + * 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 QString& path) { + bool rc; +#ifdef __linux__ + rc = path.startsWith(OS_SEPARATOR); +#else + rc = path.startsWith(OS_SEPARATOR) + || path.length() > 2 && path.at(1) == ':'; +#endif + return rc; } /** @@ -38,53 +55,50 @@ ReTreeStatistic::ReTreeStatistic() : * @return true: all files deleted
* false: at least one deletion failed */ -bool ReFileUtils::deleteTree(const QString& path, bool withBase, ReLogger* logger){ +bool ReFileUtils::deleteTree(const QString& path, bool withBase, + 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); + QStringList names = dir.entryList( + QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs + | QDir::Files); QStringList::const_iterator it; - for (it = names.constBegin(); it != names.constEnd(); ++it){ + for (it = names.constBegin(); it != names.constEnd(); ++it) { QString full(path); full.append(OS_SEPARATOR_STR).append(*it); QFileInfo info(full); if (info.isDir()) { - if (! deleteTree(full, false, logger)) + if (!deleteTree(full, false, logger)) rc = false; - else if (rmdir(full.toUtf8()) != 0){ + else if (rmdir(full.toUtf8()) != 0) { 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)){ + 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()); } } } } - if (withBase && (rmdir(path.toUtf8())) != 0){ + 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; } - - - - /** * Reads a string from a given file. * @@ -92,7 +106,8 @@ bool ReFileUtils::deleteTree(const QString& path, bool withBase, ReLogger* logge * @param buffer OUT: the buffer to write * @return buffer (for chaining) */ -QByteArray& ReFileUtils::readFromFile(const char* filename, QByteArray& buffer) { +QByteArray& ReFileUtils::readFromFile(const char* filename, + QByteArray& buffer) { FILE* fp = fopen(filename, "r"); if (fp != NULL) { struct stat info; @@ -117,7 +132,7 @@ QByteArray& ReFileUtils::readFromFile(const char* filename, QByteArray& buffer) * @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"; @@ -164,7 +179,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 += '/'; @@ -185,7 +200,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/base/ReFileUtils.hpp b/base/ReFileUtils.hpp index 1fe2154..c8844b3 100644 --- a/base/ReFileUtils.hpp +++ b/base/ReFileUtils.hpp @@ -28,14 +28,17 @@ public: */ class ReFileUtils { public: + static bool isAbsolutPath(const QString& path); + static bool isAbsolutPath(const char* path); static QByteArray tempDir(const char* node, const char* parent = NULL, - bool withSeparator = true); + bool withSeparator = true); static QByteArray tempFile(const char* node, const char* parent = NULL, - bool deleteIfExists = true); + bool deleteIfExists = true); static QByteArray& readFromFile(const char* filename, QByteArray& buffer); static void writeToFile(const char* filename, const char* content, - size_t contentLength = (size_t) - 1, const char* mode = "w"); - static bool deleteTree(const QString& path, bool withBase, ReLogger* logger); + size_t contentLength = (size_t) - 1, const char* mode = "w"); + static bool deleteTree(const QString& path, bool withBase, + ReLogger* logger); }; #endif // REFILEUTILS_HPP diff --git a/gui/ReSettings.cpp b/gui/ReSettings.cpp index 2f042b7..12904ee 100644 --- a/gui/ReSettings.cpp +++ b/gui/ReSettings.cpp @@ -102,15 +102,16 @@ bool ReProperty::isValid(const QString& value, QString* error) { * @param path the parent directory for the storage files * @param prefix type of the storage: "proj" or "ws" (workspace) */ -ReSettings::ReSettings(const QString& path, const QString prefix, +ReSettings::ReSettings(const QString& path, const QString& prefix, ReLogger* logger) : - m_path(path), - m_fileHistory(path + OS_SEPARATOR + prefix + ".history"), - m_fileSettings(path + OS_SEPARATOR + prefix + ".settings"), + m_prefix(prefix), + m_path(), + m_fileHistory(), + m_fileSettings(), m_settings(), m_chapters(), m_logger(logger) { - + setPath(path); } /* @@ -127,7 +128,7 @@ ReSettings::ReSettings(const QString& path, const QString prefix, */ void ReSettings::addHistoryEntry(const char* key, const QString& value, char separator, int maxEntries) { - ReStateStorage store(m_fileHistory); + ReStateStorage store(m_fileHistory, m_logger); store.initForRead(); store.addHistoryEntry(key, value, separator, maxEntries); store.close(); @@ -145,7 +146,7 @@ void ReSettings::addHistoryEntry(const char* key, const QString& value, * otherwise: the first item of the history entry */ QString ReSettings::topOfHistory(const char* key, const QString& defaultValue) { - ReStateStorage store(m_fileHistory); + ReStateStorage store(m_fileHistory, m_logger); store.initForRead(); QString rc = store.map().value(key, "\t"); if (rc == "\t") @@ -215,7 +216,7 @@ void ReSettings::changeValue(const char* name, const QString& value) { */ QStringList&ReSettings::historyAsList(const char* key, QStringList& list, const char* form) { - ReStateStorage store(m_fileHistory); + ReStateStorage store(m_fileHistory, m_logger); store.initForRead(); QStringList& rc = store.historyAsList(key, list, form); store.close(); @@ -331,6 +332,17 @@ void ReSettings::readSettings() { } } +/** + * Sets the path containing the settings files. + * + * @param path the new path + */ +void ReSettings::setPath(const QString& path) { + m_path = path; + m_fileHistory = path + OS_SEPARATOR + m_prefix + ".history"; + m_fileSettings = path + OS_SEPARATOR + m_prefix + ".settings"; +} + /** * Returns the value of a string property. * diff --git a/gui/ReSettings.hpp b/gui/ReSettings.hpp index 85fb008..aa85000 100644 --- a/gui/ReSettings.hpp +++ b/gui/ReSettings.hpp @@ -41,7 +41,7 @@ public: static QString TRUE; static QString FALSE; public: - ReSettings(const QString& path, const QString prefix, ReLogger* logger); + ReSettings(const QString& path, const QString& prefix, ReLogger* logger); public: void addHistoryEntry(const char* key, const QString& value, char separator, int maxEntries); @@ -53,10 +53,13 @@ public: int intValue(const char* name); const QString& path() const; void readSettings(); + void setPath(const QString& path); QString stringValue(const char* name); QString topOfHistory(const char* key, const QString& defaultValue = ""); void writeSettings(); + protected: + QString m_prefix; QString m_path; QString m_fileHistory; QString m_fileSettings; diff --git a/gui/ReStateStorage.cpp b/gui/ReStateStorage.cpp index 94a4f38..0a48e3f 100644 --- a/gui/ReStateStorage.cpp +++ b/gui/ReStateStorage.cpp @@ -12,16 +12,21 @@ #include "base/rebase.hpp" #include "gui/regui.hpp" +enum { + LOC_INIT_FOR_WRITE_1 = LOC_FIRST_OF(LOC_STATESTORAGE), // 12001 + LOC_INIT_FOR_READ_1, // 12002 +}; /** * Constructor. * * @param filename filename with path of the storage file */ -ReStateStorage::ReStateStorage(const QString& filename) : +ReStateStorage::ReStateStorage(const QString& filename, ReLogger* logger) : m_filename(filename), m_fp(NULL), m_stream(NULL), - m_form() { + m_form(), + m_logger(logger) { } /** @@ -109,12 +114,13 @@ 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; + if (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(); } - m_stream->flush(); } /** * Returns the name of the current form. @@ -144,7 +150,12 @@ QByteArray ReStateStorage::fullname(const char* name) { */ bool ReStateStorage::initForRead() { if (m_fp == NULL) - m_fp = fopen(m_filename.toUtf8().constData(), "rb"); + 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); + } if (m_fp != NULL && m_stream == NULL) { m_stream = new QTextStream(m_fp, QIODevice::ReadOnly); QString line; @@ -168,7 +179,11 @@ bool ReStateStorage::initForRead() { bool ReStateStorage::initForWrite() { if (m_fp == NULL) m_fp = fopen(m_filename.toUtf8().constData(), "wb"); - if (m_fp != NULL) + 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); + } else m_stream = new QTextStream(m_fp, QIODevice::ReadWrite); return m_stream != NULL; } diff --git a/gui/ReStateStorage.hpp b/gui/ReStateStorage.hpp index ddf2044..529a763 100644 --- a/gui/ReStateStorage.hpp +++ b/gui/ReStateStorage.hpp @@ -17,7 +17,7 @@ class ReStateStorage { public: - ReStateStorage(const QString& filename); + ReStateStorage(const QString& filename, ReLogger* logger); virtual ~ReStateStorage(); public: void addHistoryEntry(const char* key, const QString& value, char separator, @@ -50,6 +50,7 @@ private: QTextStream* m_stream; QByteArray m_form; QMap m_map; + ReLogger* m_logger; }; #endif /* GUI_RESTATESTORAGE_HPP_ */ diff --git a/gui/regui.hpp b/gui/regui.hpp index 129b90b..68df2b2 100644 --- a/gui/regui.hpp +++ b/gui/regui.hpp @@ -9,8 +9,8 @@ * The latest sources: https://github.com/republib */ -#ifndef GUI_REGUI_HPP_ -#define GUI_REGUI_HPP_ +#ifndef REGUI_HPP +#define REGUI_HPP #include "gui/ReStateStorage.hpp" #include "gui/ReGuiValidator.hpp" @@ -58,4 +58,4 @@ inline bool rectContains(const QRect& rect, const QPoint& point, #endif } -#endif /* GUI_REGUI_HPP_ */ +#endif /* REGUI_HPP */ diff --git a/remodules.hpp b/remodules.hpp index 491ccc0..e7d5407 100644 --- a/remodules.hpp +++ b/remodules.hpp @@ -31,6 +31,7 @@ enum { LOC_SETTINGS, LOC_FILE, LOC_FILETREE, + LOC_STATESTORAGE, // 120 }; #define LOC_FIRST_OF(moduleNo) (moduleNo*100+1) class RplModules { -- 2.39.5