From 8ee65772dcb4695d997f9d926874c5e7f77447e0 Mon Sep 17 00:00:00 2001 From: hama Date: Sun, 30 Aug 2015 13:00:57 +0200 Subject: [PATCH] View "Project Tree" * new ReFileTree * changeProject() opens dock "project tree" * fix: filename in "open files/projects" project table --- appl/reditor/mainwindow.cpp | 20 +++++++++++--- appl/reditor/mainwindow.hpp | 4 ++- appl/reditor/project.cpp | 22 ++++++++++++++-- appl/reditor/project.hpp | 11 +++++++- appl/reditor/projectselection.cpp | 2 +- appl/reditor/reditor.hpp | 1 + appl/reditor/reditor.pro | 1 + cunit/cuReSettings.cpp | 14 ++++++++++ gui/ReFileTree.cpp | 44 +++++++++++++++++++++++++++++++ gui/ReFileTree.hpp | 33 +++++++++++++++++++++++ gui/ReSettings.cpp | 33 ++++++++++++++++++++++- gui/ReSettings.hpp | 3 ++- gui/regui.hpp | 7 ++--- remodules.hpp | 1 + 14 files changed, 183 insertions(+), 13 deletions(-) create mode 100644 gui/ReFileTree.cpp create mode 100644 gui/ReFileTree.hpp diff --git a/appl/reditor/mainwindow.cpp b/appl/reditor/mainwindow.cpp index 98d5175..17e4bda 100644 --- a/appl/reditor/mainwindow.cpp +++ b/appl/reditor/mainwindow.cpp @@ -19,7 +19,9 @@ MainWindow::MainWindow(const char* workspace, const char* project, ui(new Ui::MainWindow), m_project(NULL), m_workspace(NULL), - m_logger(logger) { + m_logger(logger), + m_fileTree(NULL), + m_dockProjectTree(NULL) { if (workspace == NULL) workspace = QDir::homePath().toUtf8(); changeWorkspace(workspace == NULL ? QDir::homePath() : workspace); @@ -60,12 +62,24 @@ MainWindow::~MainWindow() { * * @param path the directory containing the project data */ -void MainWindow::changeProject(const QString& path) { +void MainWindow::changeProject(QString path) { delete m_project; - m_project = new Project(path, m_logger); + 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)); + } /** diff --git a/appl/reditor/mainwindow.hpp b/appl/reditor/mainwindow.hpp index b9485f6..d80c6f9 100644 --- a/appl/reditor/mainwindow.hpp +++ b/appl/reditor/mainwindow.hpp @@ -27,7 +27,7 @@ public: explicit MainWindow(const char* workspace, const char* project, ReLogger* logger, QWidget *parent = 0); ~MainWindow(); - void changeProject(const QString& path); + void changeProject(QString path); void changeWorkspace(const QString& path); void closeProject(); void openFile(const QString& name); @@ -43,6 +43,8 @@ private: Project* m_project; Workspace* m_workspace; ReLogger* m_logger; + ReFileTree* m_fileTree; + QDockWidget* m_dockProjectTree; }; #endif // MAINWINDOW_HPP diff --git a/appl/reditor/project.cpp b/appl/reditor/project.cpp index 52629d8..ffda4ee 100644 --- a/appl/reditor/project.cpp +++ b/appl/reditor/project.cpp @@ -11,13 +11,31 @@ #include "reditor.hpp" +const char* Project::KEY_HISTORY_OPEN_FILES = "openFiles"; /** * Constructor. * * @param path the directory containing the configuration * @param logger the logger */ -Project::Project(const QString& path, ReLogger* logger) : - ReSettings(path, ".reditor.proj", logger) { +Project::Project(const QString& path, MainWindow* mainWindow) : + ReSettings(path, ".reditor.proj", mainWindow->logger()), + m_mainWindow(mainWindow) { + QString filename = topOfHistory(KEY_HISTORY_OPEN_FILES); + QFileInfo info(filename); + if (!filename.isEmpty() && info.exists() && !info.isDir()) { + m_mainWindow->openFile(filename); + } +} + +/** + * Opens a file in the project directory. + * + * @param filename the filename relative to the project directory + */ +void Project::openFile(const QString& filename) { + QString full = m_path + OS_SEPARATOR_STR + filename; + addHistoryEntry(KEY_HISTORY_OPEN_FILES, filename, ';', 1); + m_mainWindow->openFile(full); } diff --git a/appl/reditor/project.hpp b/appl/reditor/project.hpp index 6bca375..dc0b267 100644 --- a/appl/reditor/project.hpp +++ b/appl/reditor/project.hpp @@ -12,9 +12,18 @@ #ifndef PROJECT_HPP #define PROJECT_HPP +class MainWindow; + class Project: public ReSettings { public: - Project(const QString& path, ReLogger* logger); + static const char* KEY_HISTORY_OPEN_FILES; +public: + Project(const QString& path, MainWindow* mainWindow); +public: + void openFile(const QString& filename); + +private: + MainWindow* m_mainWindow; }; #endif // PROJECT_HPP diff --git a/appl/reditor/projectselection.cpp b/appl/reditor/projectselection.cpp index df22c55..1d7fd72 100644 --- a/appl/reditor/projectselection.cpp +++ b/appl/reditor/projectselection.cpp @@ -41,7 +41,7 @@ ProjectSelection::ProjectSelection(MainWindow* mainWindow, QWidget *parent) : buildTableInfo(workspace, Workspace::KEY_HISTORY_PROJECTS, false, m_projects); buildTable("", m_files, ui->tableWidgetFiles); - buildTable(QString(""), m_projects, ui->tableWidgetProjects); + buildTable("", m_projects, ui->tableWidgetProjects); } /** diff --git a/appl/reditor/reditor.hpp b/appl/reditor/reditor.hpp index 2088b69..e606072 100644 --- a/appl/reditor/reditor.hpp +++ b/appl/reditor/reditor.hpp @@ -11,6 +11,7 @@ #ifndef REDITOR_HPP #define REDITOR_HPP +#include #include "base/rebase.hpp" #include "gui/regui.hpp" #include "workspace.hpp" diff --git a/appl/reditor/reditor.pro b/appl/reditor/reditor.pro index 2d6441f..a47db11 100644 --- a/appl/reditor/reditor.pro +++ b/appl/reditor/reditor.pro @@ -18,6 +18,7 @@ SOURCES += \ ../../gui/ReStateStorage.cpp \ ../../gui/ReSettings.cpp \ ../../base/ReFile.cpp \ + ../../gui/ReFileTree.cpp \ mainwindow.cpp \ ../../base/ReLogger.cpp \ ../../base/ReQStringUtils.cpp \ diff --git a/cunit/cuReSettings.cpp b/cunit/cuReSettings.cpp index 6f96ead..4900459 100644 --- a/cunit/cuReSettings.cpp +++ b/cunit/cuReSettings.cpp @@ -85,7 +85,21 @@ public: checkEqu("pretty woman", settings.stringValue("level2.strVal")); } + void testTopOfHistory() { + QByteArray dir(ReFile::tempDir("resettings", NULL, false)); + ReFile::deleteTree((QString) dir, false, &m_logger); + { + ReSettings settings(dir, "test", &m_logger); + settings.addHistoryEntry("fluid", "beer", ' ', 3); + settings.addHistoryEntry("fluid", "wine", ' ', 3); + } + ReSettings settings(dir, "test", &m_logger); + checkEqu("wine", settings.topOfHistory("fluid")); + checkEqu("???", settings.topOfHistory("unknown", "???")); + } + virtual void run() { + testTopOfHistory(); testBasic(); testAddHistoryEntry(); } diff --git a/gui/ReFileTree.cpp b/gui/ReFileTree.cpp new file mode 100644 index 0000000..ea589d3 --- /dev/null +++ b/gui/ReFileTree.cpp @@ -0,0 +1,44 @@ +/* + * storage.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 + */ + +#include "base/rebase.hpp" +#include "gui/regui.hpp" + +enum { + LOC_BOOL_VALUE_1 = LOC_FIRST_OF(LOC_FILETREE), // 11901 +}; + +/** + * Constructor. + * + * @param path + * @param logger + * @param parent + */ +ReFileTree::ReFileTree(const QString& path, ReLogger* logger, QWidget* parent) : + QTreeView(parent), + m_path(path), + m_logger(logger), + m_model() { + setPath(path); + setModel(&m_model); +} + +/** + * Sets the directory path of the widget. + * + * @param path the path of the base directory shown in the tree widget + */ +void ReFileTree::setPath(const QString& path) { + m_model.setRootPath(path); + QModelIndex idx = m_model.index(path); + setRootIndex(idx); +} diff --git a/gui/ReFileTree.hpp b/gui/ReFileTree.hpp new file mode 100644 index 0000000..8af9ec0 --- /dev/null +++ b/gui/ReFileTree.hpp @@ -0,0 +1,33 @@ +/* + * storage.hpp + * + * 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 + */ + +#ifndef REFILETREE_HPP +#define REFILETREE_HPP +#include +#include + +/** + * Displays a directory with its files and subdirectories in a tree view. + */ +class ReFileTree: public QTreeView { +public: + ReFileTree(const QString& path, ReLogger* logger, QWidget* parent = NULL); + +public: + void setPath(const QString& path); + +protected: + QString m_path; + ReLogger* m_logger; + QFileSystemModel m_model; +}; + +#endif // REFILETREE_HPP diff --git a/gui/ReSettings.cpp b/gui/ReSettings.cpp index fcea3be..2f042b7 100644 --- a/gui/ReSettings.cpp +++ b/gui/ReSettings.cpp @@ -134,6 +134,37 @@ void ReSettings::addHistoryEntry(const char* key, const QString& value, store.flushMap(); } +/* + * Returns the first item of a history entry. + * + * A history entry contains a list of items. + * + * @param key the key in the map + * @param defaultValue if the key does not exist this value is returned + * @return defaultValue: the key does not exist
+ * otherwise: the first item of the history entry + */ +QString ReSettings::topOfHistory(const char* key, const QString& defaultValue) { + ReStateStorage store(m_fileHistory); + store.initForRead(); + QString rc = store.map().value(key, "\t"); + if (rc == "\t") + rc = defaultValue; + else if (rc.isEmpty()) + rc = ""; + else { + QChar separator = rc.at(0); + int end = rc.indexOf(separator, 1); + if (end < 0) + rc = rc.mid(1); + else + rc = rc.mid(1, end - 1); + } + store.close(); + store.flushMap(); + return rc; +} + /** * Returns the value of a boolean property. * @@ -233,7 +264,7 @@ int ReSettings::intValue(const char* name) { * * @return the name of the storage's directory */ -QString ReSettings::path() const { +const QString& ReSettings::path() const { return m_path; } diff --git a/gui/ReSettings.hpp b/gui/ReSettings.hpp index 3523d1f..85fb008 100644 --- a/gui/ReSettings.hpp +++ b/gui/ReSettings.hpp @@ -51,9 +51,10 @@ public: const char* form = NULL); void insertProperty(ReProperty* property); int intValue(const char* name); - QString path() const; + const QString& path() const; void readSettings(); QString stringValue(const char* name); + QString topOfHistory(const char* key, const QString& defaultValue = ""); void writeSettings(); protected: QString m_path; diff --git a/gui/regui.hpp b/gui/regui.hpp index f5dc636..129b90b 100644 --- a/gui/regui.hpp +++ b/gui/regui.hpp @@ -16,6 +16,7 @@ #include "gui/ReGuiValidator.hpp" #include "gui/ReEdit.hpp" #include "gui/ReSettings.hpp" +#include "gui/ReFileTree.hpp" /** * Tests whether a point is inside the rectangle (including border). * @param rect rectangle to test @@ -23,12 +24,12 @@ * @return true: the point lays inside the rectangle */ inline bool rectContains(const QRect& rect, const QPoint& point, - const char* what = "") { + const char* what = "") { #if 1 ReUseParameter(what); return point.x() >= rect.x() && point.y() >= rect.y() - && point.x() < rect.x() + rect.width() - && point.y() < rect.y() + rect.height(); + && point.x() < rect.x() + rect.width() + && point.y() < rect.y() + rect.height(); #else bool rc = point.x() >= rect.x(); char reason = ' '; diff --git a/remodules.hpp b/remodules.hpp index af5562c..491ccc0 100644 --- a/remodules.hpp +++ b/remodules.hpp @@ -30,6 +30,7 @@ enum { LOC_TRAVERSER, LOC_SETTINGS, LOC_FILE, + LOC_FILETREE, }; #define LOC_FIRST_OF(moduleNo) (moduleNo*100+1) class RplModules { -- 2.39.5