From 09f6415536ef5f19d649937bd3d5cb2fc5c178ed Mon Sep 17 00:00:00 2001 From: Le Tan Date: Wed, 5 Oct 2016 11:38:17 +0800 Subject: [PATCH] implement VDirectoryTree logics Signed-off-by: Le Tan --- VNote.pro | 6 +- vdirectorytree.cpp | 454 ++++++++++++++++++++++++++++++++++++++++++++- vdirectorytree.h | 48 ++++- vmainwindow.cpp | 10 +- vnewdirdialog.cpp | 64 +++++++ vnewdirdialog.h | 40 ++++ vnote.cpp | 1 + vnote.h | 8 +- 8 files changed, 620 insertions(+), 11 deletions(-) create mode 100644 vnewdirdialog.cpp create mode 100644 vnewdirdialog.h diff --git a/VNote.pro b/VNote.pro index 0d30f0d0..b955d779 100644 --- a/VNote.pro +++ b/VNote.pro @@ -16,12 +16,14 @@ SOURCES += main.cpp\ vmainwindow.cpp \ vdirectorytree.cpp \ vnote.cpp \ - vnotebook.cpp + vnotebook.cpp \ + vnewdirdialog.cpp HEADERS += vmainwindow.h \ vdirectorytree.h \ vnote.h \ - vnotebook.h + vnotebook.h \ + vnewdirdialog.h RESOURCES += \ vnote.qrc diff --git a/vdirectorytree.cpp b/vdirectorytree.cpp index 1b5e3be7..69209844 100644 --- a/vdirectorytree.cpp +++ b/vdirectorytree.cpp @@ -1,12 +1,462 @@ -#include +#include +#include #include "vdirectorytree.h" +#include "vnewdirdialog.h" -VDirectoryTree::VDirectoryTree(QWidget *parent) : QTreeWidget(parent) +VDirectoryTree::VDirectoryTree(const QString &dirConfigFileName, QWidget *parent) + : QTreeWidget(parent), dirConfigFileName(dirConfigFileName) { + setColumnCount(1); + setHeaderHidden(true); + setContextMenuPolicy(Qt::CustomContextMenu); + initialActions(); + + connect(this, SIGNAL(itemExpanded(QTreeWidgetItem*)), + this, SLOT(updateItemSubtree(QTreeWidgetItem*))); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(contextMenuRequested(QPoint))); +} + +void VDirectoryTree::initialActions() +{ + newRootDirAct = new QAction(tr("New &root directory"), this); + newRootDirAct->setStatusTip(tr("Create a new root directory in current notebook")); + connect(newRootDirAct, &QAction::triggered, + this, &VDirectoryTree::newRootDirectory); + + newSiblingDirAct = new QAction(tr("New &sibling directory"), this); + newSiblingDirAct->setStatusTip(tr("Create a new sibling directory at current level")); + connect(newSiblingDirAct, &QAction::triggered, + this, &VDirectoryTree::newSiblingDirectory); + + newSubDirAct = new QAction(tr("&New sub-directory"), this); + newSubDirAct->setStatusTip(tr("Create a new sub-directory")); + connect(newSubDirAct, &QAction::triggered, + this, &VDirectoryTree::newSubDirectory); } void VDirectoryTree::setTreePath(const QString& path) { + if (path == treePath) { + return; + } + treePath = path; qDebug() << "set directory tree path:" << path; + + updateDirectoryTree(); +} + +bool VDirectoryTree::validatePath(const QString &path) +{ + QDir dir(path); + if (!dir.exists()) { + return false; + } + + QString configFile = dir.filePath(dirConfigFileName); + QFileInfo fileInfo(configFile); + return fileInfo.exists() && fileInfo.isFile(); +} + +void VDirectoryTree::updateDirectoryTree() +{ + updateDirectoryTreeTopLevel(); + + int nrTopLevelItems = topLevelItemCount(); + for (int i = 0; i < nrTopLevelItems; ++i) { + QTreeWidgetItem *item = topLevelItem(i); + Q_ASSERT(item); + updateDirectoryTreeOne(*item, 1); + } +} + +// QJsonObject stored in each item's data[UserRole]: +// 1. @item's related item in its parent's [sub_directories] section; +// 2. "relative_path": the path where this item exists, relative to the treePath. +void VDirectoryTree::fillDirectoryTreeItem(QTreeWidgetItem &item, QJsonObject itemJson, const QString &relativePath) +{ + item.setText(0, itemJson["name"].toString()); + QString description = itemJson["description"].toString(); + if (!description.isEmpty()) { + item.setToolTip(0, description); + } + itemJson["relative_path"] = relativePath; + item.setData(0, Qt::UserRole, itemJson); +} + +QTreeWidgetItem* VDirectoryTree::insertDirectoryTreeItem(QTreeWidgetItem *parent, QTreeWidgetItem *preceding, + const QJsonObject &newItem) +{ + QTreeWidgetItem *item; + QString relativePath; + if (parent) { + if (preceding) { + item = new QTreeWidgetItem(parent, preceding); + } else { + item = new QTreeWidgetItem(parent); + } + QJsonObject parentJson = parent->data(0, Qt::UserRole).toJsonObject(); + Q_ASSERT(!parentJson.isEmpty()); + QString parentRelativePath = parentJson["relative_path"].toString(); + QString parentName = parentJson["name"].toString(); + relativePath = QDir(parentRelativePath).filePath(parentName); + } else { + if (preceding) { + item = new QTreeWidgetItem(this, preceding); + } else { + item = new QTreeWidgetItem(this); + } + relativePath = ""; + } + + fillDirectoryTreeItem(*item, newItem, relativePath); + qDebug() << "insert new Item name:" << newItem["name"].toString() + << "relative_path:" << relativePath; + return item; +} + +void VDirectoryTree::updateDirectoryTreeTopLevel() +{ + const QString &path = treePath; + + clear(); + + if (!validatePath(path)) { + qDebug() << "invalid notebook path:" << path; + QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), tr("Invalid notebook path.")); + msgBox.setInformativeText(QString("Notebook path \"%1\" either does not exist or is not valid.") + .arg(path)); + msgBox.exec(); + return; + } + + QJsonObject configJson = readDirectoryConfig(path); + if (!validateDirConfigFile(configJson)) { + qDebug() << "invalid notebook configuration for path:" << path; + QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), tr("Invalid notebook configuration.")); + msgBox.setInformativeText(QString("Notebook path \"%1\" does not contain a valid configuration file.") + .arg(path)); + msgBox.exec(); + return; + } + + // Handle sub_directories section + QJsonArray dirJson = configJson["sub_directories"].toArray(); + QTreeWidgetItem *preItem = NULL; + for (int i = 0; i < dirJson.size(); ++i) { + QJsonObject dirItem = dirJson[i].toObject(); + QTreeWidgetItem *treeItem = insertDirectoryTreeItem(NULL, preItem, dirItem); + preItem = treeItem; + } + + qDebug() << "updated" << dirJson.size() << "top-level items"; +} + +void VDirectoryTree::updateDirectoryTreeOne(QTreeWidgetItem &parent, int depth) +{ + Q_ASSERT(parent.childCount() == 0); + // Going deep enough + if (depth <= 0) { + return; + } + QJsonObject parentJson = parent.data(0, Qt::UserRole).toJsonObject(); + QString relativePath = QDir(parentJson["relative_path"].toString()).filePath(parentJson["name"].toString()); + QString path(QDir::cleanPath(treePath + QDir::separator() + relativePath)); + if (!validatePath(path)) { + qDebug() << "invalide notebook directory:" << path; + QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), tr("Invalid notebook directory.")); + msgBox.setInformativeText(QString("Notebook directory \"%1\" either does not exist or is not a valid notebook directory.") + .arg(path)); + msgBox.exec(); + return; + } + + QJsonObject configJson = readDirectoryConfig(path); + if (!validateDirConfigFile(configJson)) { + qDebug() << "invalid notebook configuration for directory:" << path; + QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), tr("Invalid notebook directory configuration.")); + msgBox.setInformativeText(QString("Notebook path \"%1\" does not contain a valid configuration file.") + .arg(path)); + msgBox.exec(); + return; + } + + // Handle sub_directories section + QJsonArray dirJson = configJson["sub_directories"].toArray(); + QTreeWidgetItem *preItem = NULL; + for (int i = 0; i < dirJson.size(); ++i) { + QJsonObject dirItem = dirJson[i].toObject(); + QTreeWidgetItem *treeItem = insertDirectoryTreeItem(&parent, preItem, dirItem); + preItem = treeItem; + + // Update its sub-directory recursively + updateDirectoryTreeOne(*treeItem, depth - 1); + } +} + +QJsonObject VDirectoryTree::readDirectoryConfig(const QString &path) +{ + QString configFile = QDir(path).filePath(dirConfigFileName); + + qDebug() << "read config file:" << configFile; + QFile config(configFile); + if (!config.open(QIODevice::ReadOnly)) { + qWarning() << "error: fail to read directory configuration file:" + << configFile; + QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), + QString("Could not read directory configuration file \"%1\"") + .arg(dirConfigFileName)); + msgBox.setInformativeText(QString("Notebook directory \"%1\" may be corrupted").arg(path)); + msgBox.exec(); + return QJsonObject(); + } + + QByteArray configData = config.readAll(); + return QJsonDocument::fromJson(configData).object(); +} + +bool VDirectoryTree::writeDirectoryConfig(const QString &path, const QJsonObject &configJson) +{ + QString configFile = QDir(path).filePath(dirConfigFileName); + + qDebug() << "write config file:" << configFile; + QFile config(configFile); + if (!config.open(QIODevice::WriteOnly)) { + qWarning() << "error: fail to open directory configuration file for write:" + << configFile; + QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), + QString("Could not write directory configuration file \"%1\"") + .arg(dirConfigFileName)); + msgBox.exec(); + return false; + } + + QJsonDocument configDoc(configJson); + config.write(configDoc.toJson()); + return true; +} + +bool VDirectoryTree::deleteDirectoryConfig(const QString &path) +{ + QString configFile = QDir(path).filePath(dirConfigFileName); + + QFile config(configFile); + if (!config.remove()) { + qWarning() << "error: fail to delete directory configuration file:" + << configFile; + return false; + } + qDebug() << "delete config file:" << configFile; + return true; +} + +bool VDirectoryTree::validateDirConfigFile(const QJsonObject &configJson) +{ + if (configJson.isEmpty()) { + return false; + } + if (!configJson.contains("version") || !configJson.contains("name")) { + return false; + } + return true; +} + +void VDirectoryTree::updateItemSubtree(QTreeWidgetItem *item) +{ + QJsonObject itemJson = item->data(0, Qt::UserRole).toJsonObject(); + Q_ASSERT(!itemJson.isEmpty()); + int nrChild = item->childCount(); + if (nrChild == 0) { + updateDirectoryTreeOne(*item, 2); + } else { + for (int i = 0; i < nrChild; ++i) { + QTreeWidgetItem *childItem = item->child(i); + if (childItem->childCount() > 0) { + continue; + } + updateDirectoryTreeOne(*childItem, 1); + } + } +} + +void VDirectoryTree::contextMenuRequested(QPoint pos) +{ + QTreeWidgetItem *item = itemAt(pos); + QMenu menu(this); + + if (!item) { + // Context menu on the free space of the QTreeWidget + menu.addAction(newRootDirAct); + } else { + // Context menu on a QTreeWidgetItem + if (item->parent()) { + // Low-level item + menu.addAction(newSubDirAct); + menu.addAction(newSiblingDirAct); + } else { + // Top-level item + menu.addAction(newRootDirAct); + menu.addAction(newSubDirAct); + } + } + menu.exec(mapToGlobal(pos)); +} + +void VDirectoryTree::newSiblingDirectory() +{ + QTreeWidgetItem *parentItem = currentItem()->parent(); + Q_ASSERT(parentItem); + QJsonObject parentItemJson = parentItem->data(0, Qt::UserRole).toJsonObject(); + QString parentItemName = parentItemJson["name"].toString(); + + QString text("&Directory name:"); + QString defaultText("new_directory"); + QString defaultDescription(""); + do { + VNewDirDialog dialog(QString("Create a new directory under %1").arg(parentItemName), text, + defaultText, tr("&Description:"), defaultDescription, this); + if (dialog.exec() == QDialog::Accepted) { + QString name = dialog.getNameInput(); + QString description = dialog.getDescriptionInput(); + if (isConflictNameWithChildren(parentItem, name)) { + text = "Name already exists.\nPlease choose another name:"; + defaultText = name; + defaultDescription = description; + continue; + } + QTreeWidgetItem *newItem = createDirectoryAndUpdateTree(parentItem, name, description); + if (newItem) { + this->setCurrentItem(newItem); + } + } + break; + } while (true); +} + +void VDirectoryTree::newSubDirectory() +{ + QTreeWidgetItem *curItem = currentItem(); + QJsonObject curItemJson = curItem->data(0, Qt::UserRole).toJsonObject(); + QString curItemName = curItemJson["name"].toString(); + + QString text("&Directory name:"); + QString defaultText("new_directory"); + QString defaultDescription(""); + do { + VNewDirDialog dialog(QString("Create a new directory under %1").arg(curItemName), text, + defaultText, tr("&Description:"), defaultDescription, this); + if (dialog.exec() == QDialog::Accepted) { + QString name = dialog.getNameInput(); + QString description = dialog.getDescriptionInput(); + if (isConflictNameWithChildren(curItem, name)) { + text = "Name already exists.\nPlease choose another name:"; + defaultText = name; + defaultDescription = description; + continue; + } + QTreeWidgetItem *newItem = createDirectoryAndUpdateTree(curItem, name, description); + if (newItem) { + this->setCurrentItem(newItem); + } + } + break; + } while (true); +} + +void VDirectoryTree::newRootDirectory() +{ + QString text("&Directory name:"); + QString defaultText("new_directory"); + QString defaultDescription(""); + do { + VNewDirDialog dialog(tr("Create a new root directory"), text, + defaultText, tr("&Description:"), defaultDescription, this); + if (dialog.exec() == QDialog::Accepted) { + QString name = dialog.getNameInput(); + QString description = dialog.getDescriptionInput(); + if (isConflictNameWithChildren(NULL, name)) { + text = "Name already exists.\nPlease choose another name:"; + defaultText = name; + defaultDescription = description; + continue; + } + QTreeWidgetItem *newItem = createDirectoryAndUpdateTree(NULL, name, description); + if (newItem) { + this->setCurrentItem(newItem); + } + } + break; + } while (true); +} + +QTreeWidgetItem* VDirectoryTree::createDirectoryAndUpdateTree(QTreeWidgetItem *parent, + const QString &name, const QString &description) +{ + QString relativePath(""); + QJsonObject parentJson; + if (parent) { + parentJson = parent->data(0, Qt::UserRole).toJsonObject(); + relativePath = QDir(parentJson["relative_path"].toString()).filePath(parentJson["name"].toString()); + } + QString path = QDir(treePath).filePath(relativePath); + QDir dir(path); + if (!dir.mkdir(name)) { + qDebug() << "warning: fail to create directory" << name << "under" << path; + QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), QString("Could not create directory \"%1\" under \"%2\".") + .arg(name).arg(path)); + msgBox.setInformativeText(QString("Please check if there already exists a directory named \"%1\".").arg(name)); + msgBox.exec(); + return NULL; + } + + QJsonObject configJson; + configJson["version"] = "1"; + configJson["name"] = name; + configJson["sub_directories"] = QJsonArray(); + configJson["files"] = QJsonArray(); + + if (!writeDirectoryConfig(QDir(path).filePath(name), configJson)) { + return NULL; + } + + // Update parent's config file to include this new directory + configJson = readDirectoryConfig(path); + QJsonObject itemJson; + itemJson["name"] = name; + itemJson["description"] = description; + QJsonArray subDirArray = configJson["sub_directories"].toArray(); + subDirArray.append(itemJson); + configJson["sub_directories"] = subDirArray; + if (!writeDirectoryConfig(path, configJson)) { + deleteDirectoryConfig(QDir(path).filePath(name)); + dir.rmdir(name); + return NULL; + } + + return insertDirectoryTreeItem(parent, NULL, itemJson); +} + +bool VDirectoryTree::isConflictNameWithChildren(const QTreeWidgetItem *parent, const QString &name) +{ + if (parent) { + int nrChild = parent->childCount(); + for (int i = 0; i < nrChild; ++i) { + QJsonObject childItemJson = parent->child(i)->data(0, Qt::UserRole).toJsonObject(); + Q_ASSERT(!childItemJson.isEmpty()); + if (childItemJson["name"].toString() == name) { + return true; + } + } + } else { + int nrTopLevelItems = topLevelItemCount(); + for (int i = 0; i < nrTopLevelItems; ++i) { + QJsonObject itemJson = topLevelItem(i)->data(0, Qt::UserRole).toJsonObject(); + Q_ASSERT(!itemJson.isEmpty()); + if (itemJson["name"].toString() == name) { + return true; + } + } + } + return false; } diff --git a/vdirectorytree.h b/vdirectorytree.h index ae421374..d195122c 100644 --- a/vdirectorytree.h +++ b/vdirectorytree.h @@ -3,20 +3,66 @@ #include +class QJsonObject; + class VDirectoryTree : public QTreeWidget { Q_OBJECT public: - explicit VDirectoryTree(QWidget *parent = 0); + VDirectoryTree(const QString &dirConfigFileName, QWidget *parent = 0); signals: public slots: void setTreePath(const QString& path); +private slots: + // Read config file and pdate the subtree of @item in the directory tree. + // If @item has no child, we will call updateDirectoryTreeOne() to update it. + // Otherwise, we will loop all its direct-children and try to populate it if + // it has not been populated yet. + void updateItemSubtree(QTreeWidgetItem *item); + void contextMenuRequested(QPoint pos); + void newSiblingDirectory(); + void newSubDirectory(); + void newRootDirectory(); + private: + // Clean and pdate the TreeWidget according to treePath + void updateDirectoryTree(); + // Update the top-level items of the directory tree. Will not clean the tree at first. + void updateDirectoryTreeTopLevel(); + // Update one directory, going into @depth levels. Not cleaning the tree item at first, + // so you must ensure @parent has no child before calling this function. + void updateDirectoryTreeOne(QTreeWidgetItem &parent, int depth); + // Validate if a directory is valid + bool validatePath(const QString &path); + // Validate if a directory config file is valid + bool validateDirConfigFile(const QJsonObject &configJson); + // Fill the QTreeWidgetItem according to its QJsonObject. + // @relative_path is the path related to treePath. + void fillDirectoryTreeItem(QTreeWidgetItem &item, QJsonObject itemJson, const QString &relativePath); + void initialActions(); + QTreeWidgetItem* createDirectoryAndUpdateTree(QTreeWidgetItem *parent, const QString &name, + const QString &description); + // If @name conflict with the children's names of @parent. + bool isConflictNameWithChildren(const QTreeWidgetItem *parent, const QString &name); + // Read config from the directory config json file into a QJsonObject + QJsonObject readDirectoryConfig(const QString &path); + bool writeDirectoryConfig(const QString &path, const QJsonObject &configJson); + bool deleteDirectoryConfig(const QString &path); + QTreeWidgetItem* insertDirectoryTreeItem(QTreeWidgetItem *parent, QTreeWidgetItem *preceding, + const QJsonObject &newItem); + // The path of the directory tree root QString treePath; + // The name of the config file in each subdirectory + QString dirConfigFileName; + + // Actions + QAction *newRootDirAct; + QAction *newSiblingDirAct; + QAction *newSubDirAct; }; #endif // VDIRECTORYTREE_H diff --git a/vmainwindow.cpp b/vmainwindow.cpp index d2c4a9cf..fb1e1afb 100644 --- a/vmainwindow.cpp +++ b/vmainwindow.cpp @@ -1,4 +1,4 @@ -#include +#include #include "vmainwindow.h" #include "vdirectorytree.h" #include "vnote.h" @@ -23,7 +23,7 @@ void VMainWindow::setupUI() // Notebook directory browser tree notebookLabel = new QLabel(tr("Notebook")); notebookComboBox = new QComboBox(); - directoryTree = new VDirectoryTree(); + directoryTree = new VDirectoryTree(VNote::dirConfigFileName); QHBoxLayout *nbTopLayout = new QHBoxLayout; notebookComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); @@ -46,6 +46,7 @@ void VMainWindow::setupUI() // Editor tab widget editorTabWidget = new QTabWidget(); editorTabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + editorTabWidget->setTabBarAutoHide(true); QFile welcomeFile(":/resources/welcome.html"); QString welcomeText("Welcome to VNote!"); if (welcomeFile.open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -72,6 +73,8 @@ void VMainWindow::setupUI() SLOT(setTreePath(const QString&))); setCentralWidget(mainSplitter); + // Create and show the status bar + statusBar(); } void VMainWindow::updateNotebookComboBox() @@ -83,10 +86,9 @@ void VMainWindow::updateNotebookComboBox() notebookComboBox->addItem(notebooks[i].getName()); } - notebookComboBox->setCurrentIndex(vnote->getCurNotebookIndex()); - qDebug() << "update notebook combobox with" << notebookComboBox->count() << "items"; + notebookComboBox->setCurrentIndex(vnote->getCurNotebookIndex()); } void VMainWindow::setCurNotebookIndex(int index) diff --git a/vnewdirdialog.cpp b/vnewdirdialog.cpp new file mode 100644 index 00000000..c0bd8759 --- /dev/null +++ b/vnewdirdialog.cpp @@ -0,0 +1,64 @@ +#include +#include "vnewdirdialog.h" + +VNewDirDialog::VNewDirDialog(const QString &title, const QString &name, const QString &defaultName, + const QString &description, const QString &defaultDescription, + QWidget *parent) + : QDialog(parent), title(title), name(name), defaultName(defaultName), + description(description), defaultDescription(defaultDescription) +{ + setupUI(); + + connect(nameEdit, &QLineEdit::textChanged, this, &VNewDirDialog::enableOkButton); + connect(okBtn, &QPushButton::clicked, this, &VNewDirDialog::accept); + connect(cancelBtn, &QPushButton::clicked, this, &VNewDirDialog::reject); +} + +void VNewDirDialog::setupUI() +{ + nameLabel = new QLabel(name); + nameEdit = new QLineEdit(defaultName); + nameEdit->selectAll(); + nameLabel->setBuddy(nameEdit); + + descriptionLabel = new QLabel(description); + descriptionEdit = new QLineEdit(defaultDescription); + descriptionLabel->setBuddy(descriptionEdit); + + okBtn = new QPushButton(tr("&OK")); + okBtn->setDefault(true); + cancelBtn = new QPushButton(tr("&Cancel")); + + QVBoxLayout *topLayout = new QVBoxLayout(); + topLayout->addWidget(nameLabel); + topLayout->addWidget(nameEdit); + topLayout->addWidget(descriptionLabel); + topLayout->addWidget(descriptionEdit); + + QHBoxLayout *btmLayout = new QHBoxLayout(); + btmLayout->addStretch(); + btmLayout->addWidget(okBtn); + btmLayout->addWidget(cancelBtn); + + QVBoxLayout *mainLayout = new QVBoxLayout(); + mainLayout->addLayout(topLayout); + mainLayout->addLayout(btmLayout); + setLayout(mainLayout); + + setWindowTitle(title); +} + +void VNewDirDialog::enableOkButton(const QString &editText) +{ + okBtn->setEnabled(!editText.isEmpty()); +} + +QString VNewDirDialog::getNameInput() const +{ + return nameEdit->text(); +} + +QString VNewDirDialog::getDescriptionInput() const +{ + return descriptionEdit->text(); +} diff --git a/vnewdirdialog.h b/vnewdirdialog.h new file mode 100644 index 00000000..ba6bc55c --- /dev/null +++ b/vnewdirdialog.h @@ -0,0 +1,40 @@ +#ifndef VNEWDIRDIALOG_H +#define VNEWDIRDIALOG_H + +#include + +class QLabel; +class QLineEdit; +class QPushButton; +class QString; + +class VNewDirDialog : public QDialog +{ + Q_OBJECT +public: + VNewDirDialog(const QString &title, const QString &name, const QString &defaultName, + const QString &description, const QString &defaultDescription, QWidget *parent = 0); + QString getNameInput() const; + QString getDescriptionInput() const; + +private slots: + void enableOkButton(const QString &editText); + +private: + void setupUI(); + + QLabel *nameLabel; + QLabel *descriptionLabel; + QLineEdit *nameEdit; + QLineEdit *descriptionEdit; + QPushButton *okBtn; + QPushButton *cancelBtn; + + QString title; + QString name; + QString defaultName; + QString description; + QString defaultDescription; +}; + +#endif // VNEWDIRDIALOG_H diff --git a/vnote.cpp b/vnote.cpp index 2b486524..297ad8ce 100644 --- a/vnote.cpp +++ b/vnote.cpp @@ -4,6 +4,7 @@ const QString VNote::orgName = QString("tamlok"); const QString VNote::appName = QString("VNote"); +const QString VNote::dirConfigFileName = QString(".vnote.json"); VNote::VNote() : curNotebookIndex(0) diff --git a/vnote.h b/vnote.h index 4b03d856..b15ca59e 100644 --- a/vnote.h +++ b/vnote.h @@ -16,6 +16,12 @@ public: const QVector& getNotebooks(); int getCurNotebookIndex() const; void setCurNotebookIndex(int index); + + // The name of the config file in each subdirectory + static const QString dirConfigFileName; + static const QString orgName; + static const QString appName; + private: // Write notebooks section of global config void writeGlobalConfigNotebooks(QSettings &settings); @@ -24,8 +30,6 @@ private: QVector notebooks; int curNotebookIndex; - static const QString orgName; - static const QString appName; }; #endif // VNOTE_H