support custom image folder for both global scope and notebook scope

This commit is contained in:
Le Tan 2017-05-24 19:54:58 +08:00
parent 03c0fdc49d
commit 9bf3f9394f
20 changed files with 538 additions and 121 deletions

View File

@ -2,6 +2,7 @@
#include <QDir> #include <QDir>
#include "vnewnotebookdialog.h" #include "vnewnotebookdialog.h"
#include "vconfigmanager.h" #include "vconfigmanager.h"
#include "utils/vutils.h"
extern VConfigManager vconfig; extern VConfigManager vconfig;
@ -18,6 +19,7 @@ VNewNotebookDialog::VNewNotebookDialog(const QString &title, const QString &info
connect(browseBtn, &QPushButton::clicked, this, &VNewNotebookDialog::handleBrowseBtnClicked); connect(browseBtn, &QPushButton::clicked, this, &VNewNotebookDialog::handleBrowseBtnClicked);
enableOkButton(); enableOkButton();
checkRootFolder(pathEdit->text());
} }
void VNewNotebookDialog::setupUI() void VNewNotebookDialog::setupUI()
@ -26,6 +28,7 @@ void VNewNotebookDialog::setupUI()
infoLabel = new QLabel(info); infoLabel = new QLabel(info);
infoLabel->setWordWrap(true); infoLabel->setWordWrap(true);
} }
nameLabel = new QLabel(tr("Notebook &name:")); nameLabel = new QLabel(tr("Notebook &name:"));
nameEdit = new QLineEdit(defaultName); nameEdit = new QLineEdit(defaultName);
nameLabel->setBuddy(nameEdit); nameLabel->setBuddy(nameEdit);
@ -35,9 +38,22 @@ void VNewNotebookDialog::setupUI()
pathLabel->setBuddy(pathEdit); pathLabel->setBuddy(pathEdit);
browseBtn = new QPushButton(tr("&Browse")); browseBtn = new QPushButton(tr("&Browse"));
importCheck = new QCheckBox(tr("Try to import existing notebook"), this); importCheck = new QCheckBox(tr("Import existing notebook"));
importCheck->setChecked(true); importCheck->setToolTip(tr("When checked, VNote will read the configuration file to import an existing notebook"));
importCheck->setToolTip(tr("When checked, VNote won't create a new config file if there already exists one")); connect(importCheck, &QCheckBox::stateChanged,
this, &VNewNotebookDialog::importCheckChanged);
QLabel *imageFolderLabel = new QLabel(tr("&Image folder:"));
m_imageFolderEdit = new QLineEdit();
m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)")
.arg(vconfig.getImageFolder()));
imageFolderLabel->setBuddy(m_imageFolderEdit);
QString imageFolderTip = tr("Set the name of the folder for all the notes of this notebook to store images "
"(empty to use global configuration)");
m_imageFolderEdit->setToolTip(imageFolderTip);
imageFolderLabel->setToolTip(imageFolderTip);
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit);
m_imageFolderEdit->setValidator(validator);
QGridLayout *topLayout = new QGridLayout(); QGridLayout *topLayout = new QGridLayout();
topLayout->addWidget(nameLabel, 0, 0); topLayout->addWidget(nameLabel, 0, 0);
@ -46,28 +62,33 @@ void VNewNotebookDialog::setupUI()
topLayout->addWidget(pathEdit, 1, 1); topLayout->addWidget(pathEdit, 1, 1);
topLayout->addWidget(browseBtn, 1, 2); topLayout->addWidget(browseBtn, 1, 2);
topLayout->addWidget(importCheck, 2, 1); topLayout->addWidget(importCheck, 2, 1);
topLayout->addWidget(imageFolderLabel, 3, 0);
topLayout->addWidget(m_imageFolderEdit, 3, 1);
// Ok is the default button. // Ok is the default button.
m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
// Warning label. // Warning label.
m_warnLabel = new QLabel(tr("<span style=\"%1\">WARNING</span>: The folder you choose is NOT empty! " m_warnLabel = new QLabel(tr("<span style=\"%1\">WARNING</span>: The folder you choose is NOT empty! "
"It is highly recommended to use an EMPTY and EXCLUSIVE folder for a notebook. " "It is highly recommended to use an EMPTY and EXCLUSIVE folder for a notebook. "
"Ignore this warning if you do want to import an existing VNote notebook folder.") "Ignore this warning if you do want to import an existing VNote notebook folder.")
.arg(vconfig.c_warningTextStyle), .arg(vconfig.c_warningTextStyle));
this);
m_warnLabel->setWordWrap(true); m_warnLabel->setWordWrap(true);
m_warnLabel->hide(); m_warnLabel->hide();
QVBoxLayout *mainLayout = new QVBoxLayout(); QVBoxLayout *mainLayout = new QVBoxLayout(this);
if (infoLabel) { if (infoLabel) {
mainLayout->addWidget(infoLabel); mainLayout->addWidget(infoLabel);
} }
mainLayout->addLayout(topLayout); mainLayout->addLayout(topLayout);
mainLayout->addWidget(m_warnLabel); mainLayout->addWidget(m_warnLabel);
mainLayout->addWidget(m_btnBox); mainLayout->addWidget(m_btnBox);
// Will set the parent of above widgets properly.
setLayout(mainLayout); setLayout(mainLayout);
mainLayout->setSizeConstraint(QLayout::SetFixedSize); mainLayout->setSizeConstraint(QLayout::SetFixedSize);
setWindowTitle(title); setWindowTitle(title);
@ -91,11 +112,19 @@ QString VNewNotebookDialog::getPathInput() const
return pathEdit->text(); return pathEdit->text();
} }
QString VNewNotebookDialog::getImageFolder() const
{
return m_imageFolderEdit->text();
}
void VNewNotebookDialog::handleBrowseBtnClicked() void VNewNotebookDialog::handleBrowseBtnClicked()
{ {
QString dirPath = QFileDialog::getExistingDirectory(this, tr("Select Root Folder Of The Notebook"), QString dirPath = QFileDialog::getExistingDirectory(this, tr("Select Root Folder Of The Notebook"),
QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dirPath.isEmpty()) {
pathEdit->setText(dirPath); pathEdit->setText(dirPath);
}
} }
bool VNewNotebookDialog::getImportCheck() const bool VNewNotebookDialog::getImportCheck() const
@ -111,16 +140,36 @@ void VNewNotebookDialog::showEvent(QShowEvent *event)
void VNewNotebookDialog::handlePathChanged(const QString &p_text) void VNewNotebookDialog::handlePathChanged(const QString &p_text)
{ {
if (!p_text.isEmpty()) { enableOkButton();
QDir dir(p_text); checkRootFolder(p_text);
}
void VNewNotebookDialog::importCheckChanged(int p_state)
{
// If import existing notebook, disable setting new configs.
bool checked = p_state == Qt::Checked;
m_imageFolderEdit->setEnabled(!checked);
}
void VNewNotebookDialog::checkRootFolder(const QString &p_path)
{
bool existConfig = false;
if (!p_path.isEmpty()) {
QDir dir(p_path);
QStringList files = dir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden); QStringList files = dir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden);
if (dir.exists() && !files.isEmpty()) { if (!files.isEmpty()) {
m_warnLabel->show(); m_warnLabel->show();
} else { } else {
m_warnLabel->hide(); m_warnLabel->hide();
} }
existConfig = VConfigManager::directoryConfigExist(p_path);
} else { } else {
m_warnLabel->hide(); m_warnLabel->hide();
} }
enableOkButton();
importCheck->setChecked(existConfig);
importCheck->setEnabled(existConfig);
} }

View File

@ -19,17 +19,20 @@ public:
QString getNameInput() const; QString getNameInput() const;
QString getPathInput() const; QString getPathInput() const;
bool getImportCheck() const; bool getImportCheck() const;
QString getImageFolder() const;
private slots: private slots:
void enableOkButton(); void enableOkButton();
void handleBrowseBtnClicked(); void handleBrowseBtnClicked();
void handlePathChanged(const QString &p_text); void handlePathChanged(const QString &p_text);
void importCheckChanged(int p_state);
protected: protected:
void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;
private: private:
void setupUI(); void setupUI();
void checkRootFolder(const QString &p_path);
QLabel *infoLabel; QLabel *infoLabel;
QLabel *nameLabel; QLabel *nameLabel;
@ -37,8 +40,9 @@ private:
QLineEdit *pathEdit; QLineEdit *pathEdit;
QCheckBox *importCheck; QCheckBox *importCheck;
QPushButton *browseBtn; QPushButton *browseBtn;
QDialogButtonBox *m_btnBox;
QLabel *m_warnLabel; QLabel *m_warnLabel;
QLineEdit *m_imageFolderEdit;
QDialogButtonBox *m_btnBox;
QString title; QString title;
QString info; QString info;

View File

@ -1,37 +1,55 @@
#include <QtWidgets> #include <QtWidgets>
#include "vnotebookinfodialog.h" #include "vnotebookinfodialog.h"
#include "vnotebook.h"
#include "utils/vutils.h"
#include "vconfigmanager.h"
VNotebookInfoDialog::VNotebookInfoDialog(const QString &title, const QString &info, extern VConfigManager vconfig;
const QString &defaultName, const QString &defaultPath,
QWidget *parent) VNotebookInfoDialog::VNotebookInfoDialog(const QString &p_title, const QString &p_info,
: QDialog(parent), infoLabel(NULL), title(title), info(info), defaultName(defaultName), const VNotebook *p_notebook, QWidget *p_parent)
defaultPath(defaultPath) : QDialog(p_parent), m_notebook(p_notebook), m_infoLabel(NULL)
{ {
setupUI(); setupUI(p_title, p_info);
connect(nameEdit, &QLineEdit::textChanged, this, &VNotebookInfoDialog::enableOkButton); connect(m_nameEdit, &QLineEdit::textChanged,
this, &VNotebookInfoDialog::enableOkButton);
enableOkButton(); enableOkButton();
} }
void VNotebookInfoDialog::setupUI() void VNotebookInfoDialog::setupUI(const QString &p_title, const QString &p_info)
{ {
if (!info.isEmpty()) { if (!p_info.isEmpty()) {
infoLabel = new QLabel(info); m_infoLabel = new QLabel(p_info);
} }
nameLabel = new QLabel(tr("Notebook &name:"));
nameEdit = new QLineEdit(defaultName);
nameEdit->selectAll();
nameLabel->setBuddy(nameEdit);
QLabel *pathLabel = new QLabel(tr("Notebook &path:")); QLabel *nameLabel = new QLabel(tr("Notebook &name:"));
pathEdit = new QLineEdit(defaultPath); m_nameEdit = new QLineEdit(m_notebook->getName());
pathLabel->setBuddy(pathEdit); m_nameEdit->selectAll();
pathEdit->setReadOnly(true); nameLabel->setBuddy(m_nameEdit);
QLabel *pathLabel = new QLabel(tr("Notebook &root folder:"));
m_pathEdit = new QLineEdit(m_notebook->getPath());
pathLabel->setBuddy(m_pathEdit);
m_pathEdit->setReadOnly(true);
QLabel *imageFolderLabel = new QLabel(tr("&Image folder:"));
m_imageFolderEdit = new QLineEdit(m_notebook->getImageFolderConfig());
m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)")
.arg(vconfig.getImageFolder()));
imageFolderLabel->setBuddy(m_imageFolderEdit);
QString imageFolderTip = tr("Set the name of the folder for all the notes of this notebook to store images "
"(empty to use global configuration)");
m_imageFolderEdit->setToolTip(imageFolderTip);
imageFolderLabel->setToolTip(imageFolderTip);
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit);
m_imageFolderEdit->setValidator(validator);
QFormLayout *topLayout = new QFormLayout(); QFormLayout *topLayout = new QFormLayout();
topLayout->addRow(nameLabel, nameEdit); topLayout->addRow(nameLabel, m_nameEdit);
topLayout->addRow(pathLabel, pathEdit); topLayout->addRow(pathLabel, m_pathEdit);
topLayout->addRow(imageFolderLabel, m_imageFolderEdit);
// Ok is the default button. // Ok is the default button.
m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
@ -39,26 +57,38 @@ void VNotebookInfoDialog::setupUI()
connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject); connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3); m_pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
QVBoxLayout *mainLayout = new QVBoxLayout(); QVBoxLayout *mainLayout = new QVBoxLayout();
if (infoLabel) { if (m_infoLabel) {
mainLayout->addWidget(infoLabel); mainLayout->addWidget(m_infoLabel);
} }
mainLayout->addLayout(topLayout); mainLayout->addLayout(topLayout);
mainLayout->addWidget(m_btnBox); mainLayout->addWidget(m_btnBox);
setLayout(mainLayout); setLayout(mainLayout);
mainLayout->setSizeConstraint(QLayout::SetFixedSize); mainLayout->setSizeConstraint(QLayout::SetFixedSize);
setWindowTitle(title); setWindowTitle(p_title);
} }
void VNotebookInfoDialog::enableOkButton() void VNotebookInfoDialog::enableOkButton()
{ {
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok); QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
okBtn->setEnabled(!nameEdit->text().isEmpty()); okBtn->setEnabled(!m_nameEdit->text().isEmpty());
} }
QString VNotebookInfoDialog::getNameInput() const QString VNotebookInfoDialog::getName() const
{ {
return nameEdit->text(); return m_nameEdit->text();
} }
QString VNotebookInfoDialog::getImageFolder() const
{
return m_imageFolderEdit->text();
}
void VNotebookInfoDialog::showEvent(QShowEvent *p_event)
{
m_nameEdit->setFocus();
QDialog::showEvent(p_event);
}

View File

@ -7,31 +7,34 @@ class QLabel;
class QLineEdit; class QLineEdit;
class QDialogButtonBox; class QDialogButtonBox;
class QString; class QString;
class VNotebook;
class VNotebookInfoDialog : public QDialog class VNotebookInfoDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
VNotebookInfoDialog(const QString &title, const QString &info, const QString &defaultName, VNotebookInfoDialog(const QString &p_title, const QString &p_info,
const QString &defaultPath, QWidget *parent = 0); const VNotebook *p_notebook, QWidget *p_parent = 0);
QString getNameInput() const;
QString getName() const;
QString getImageFolder() const;
private slots: private slots:
void enableOkButton(); void enableOkButton();
protected:
void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
private: private:
void setupUI(); void setupUI(const QString &p_title, const QString &p_info);
QLabel *infoLabel; const VNotebook *m_notebook;
QLabel *nameLabel;
QLineEdit *nameEdit; QLabel *m_infoLabel;
QLineEdit *pathEdit; QLineEdit *m_nameEdit;
QLineEdit *m_pathEdit;
QLineEdit *m_imageFolderEdit;
QDialogButtonBox *m_btnBox; QDialogButtonBox *m_btnBox;
QString title;
QString info;
QString defaultName;
QString defaultPath;
}; };
#endif // VNOTEBOOKINFODIALOG_H #endif // VNOTEBOOKINFODIALOG_H

View File

@ -1,5 +1,6 @@
#include "vsettingsdialog.h" #include "vsettingsdialog.h"
#include <QtWidgets> #include <QtWidgets>
#include <QRegExp>
#include "vconfigmanager.h" #include "vconfigmanager.h"
#include "utils/vutils.h" #include "utils/vutils.h"
#include "vconstants.h" #include "vconstants.h"
@ -12,6 +13,7 @@ VSettingsDialog::VSettingsDialog(QWidget *p_parent)
m_tabs = new QTabWidget; m_tabs = new QTabWidget;
m_tabs->addTab(new VGeneralTab(), tr("General")); m_tabs->addTab(new VGeneralTab(), tr("General"));
m_tabs->addTab(new VReadEditTab(), tr("Read/Edit")); m_tabs->addTab(new VReadEditTab(), tr("Read/Edit"));
m_tabs->addTab(new VNoteManagementTab(), tr("Note Management"));
m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(m_btnBox, &QDialogButtonBox::accepted, this, &VSettingsDialog::saveConfiguration); connect(m_btnBox, &QDialogButtonBox::accepted, this, &VSettingsDialog::saveConfiguration);
@ -47,6 +49,15 @@ void VSettingsDialog::loadConfiguration()
} }
} }
// Note Management Tab.
{
VNoteManagementTab *noteManagementTab = dynamic_cast<VNoteManagementTab *>(m_tabs->widget(2));
Q_ASSERT(noteManagementTab);
if (!noteManagementTab->loadConfiguration()) {
goto err;
}
}
return; return;
err: err:
VUtils::showMessage(QMessageBox::Warning, tr("Warning"), VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
@ -75,6 +86,15 @@ void VSettingsDialog::saveConfiguration()
} }
} }
// Note Management Tab.
{
VNoteManagementTab *noteManagementTab = dynamic_cast<VNoteManagementTab *>(m_tabs->widget(2));
Q_ASSERT(noteManagementTab);
if (!noteManagementTab->saveConfiguration()) {
goto err;
}
}
accept(); accept();
return; return;
err: err:
@ -231,9 +251,81 @@ bool VReadEditTab::saveWebZoomFactor()
void VReadEditTab::customWebZoomChanged(int p_state) void VReadEditTab::customWebZoomChanged(int p_state)
{ {
if (p_state == Qt::Unchecked) { m_webZoomFactorSpin->setEnabled(p_state == Qt::Checked);
m_webZoomFactorSpin->setEnabled(false); }
VNoteManagementTab::VNoteManagementTab(QWidget *p_parent)
: QWidget(p_parent)
{
// Image folder.
m_customImageFolder = new QCheckBox(tr("Custom image folder"), this);
m_customImageFolder->setToolTip(tr("Set the global name of the image folder to store images "
"of notes (restart VNote to make it work)"));
connect(m_customImageFolder, &QCheckBox::stateChanged,
this, &VNoteManagementTab::customImageFolderChanged);
m_imageFolderEdit = new QLineEdit(this);
m_imageFolderEdit->setPlaceholderText(tr("Name of the image folder"));
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), this);
m_imageFolderEdit->setValidator(validator);
QHBoxLayout *imageFolderLayout = new QHBoxLayout();
imageFolderLayout->addWidget(m_customImageFolder);
imageFolderLayout->addWidget(m_imageFolderEdit);
QFormLayout *mainLayout = new QFormLayout();
mainLayout->addRow(imageFolderLayout);
setLayout(mainLayout);
}
bool VNoteManagementTab::loadConfiguration()
{
if (!loadImageFolder()) {
return false;
}
return true;
}
bool VNoteManagementTab::saveConfiguration()
{
if (!saveImageFolder()) {
return false;
}
return true;
}
bool VNoteManagementTab::loadImageFolder()
{
bool isCustom = vconfig.isCustomImageFolder();
m_customImageFolder->setChecked(isCustom);
m_imageFolderEdit->setText(vconfig.getImageFolder());
m_imageFolderEdit->setEnabled(isCustom);
return true;
}
bool VNoteManagementTab::saveImageFolder()
{
if (m_customImageFolder->isChecked()) {
vconfig.setImageFolder(m_imageFolderEdit->text());
} else { } else {
m_webZoomFactorSpin->setEnabled(true); vconfig.setImageFolder("");
}
return true;
}
void VNoteManagementTab::customImageFolderChanged(int p_state)
{
if (p_state == Qt::Checked) {
m_imageFolderEdit->setEnabled(true);
m_imageFolderEdit->selectAll();
m_imageFolderEdit->setFocus();
} else {
m_imageFolderEdit->setEnabled(false);
} }
} }

View File

@ -11,6 +11,7 @@ class QComboBox;
class QGroupBox; class QGroupBox;
class QDoubleSpinBox; class QDoubleSpinBox;
class QCheckBox; class QCheckBox;
class QLineEdit;
class VGeneralTab : public QWidget class VGeneralTab : public QWidget
{ {
@ -53,6 +54,26 @@ private:
bool saveWebZoomFactor(); bool saveWebZoomFactor();
}; };
class VNoteManagementTab : public QWidget
{
Q_OBJECT
public:
explicit VNoteManagementTab(QWidget *p_parent = 0);
bool loadConfiguration();
bool saveConfiguration();
// Image folder.
QCheckBox *m_customImageFolder;
QLineEdit *m_imageFolderEdit;
private slots:
void customImageFolderChanged(int p_state);
private:
bool loadImageFolder();
bool saveImageFolder();
};
class VSettingsDialog : public QDialog class VSettingsDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT

View File

@ -39,6 +39,9 @@ enable_image_constraint=true
; Center image and add the alt text as caption ; Center image and add the alt text as caption
enable_image_caption=false enable_image_caption=false
; Image folder name for the notes
image_folder=_v_images
[session] [session]
tools_dock_checked=true tools_dock_checked=true

View File

@ -27,6 +27,8 @@ const QVector<QPair<QString, QString>> VUtils::c_availableLanguages = {QPair<QSt
const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\]]*)\\]\\(([^\\)\"]+)\\s*(\"(\\\\.|[^\"\\)])*\")?\\s*\\)"); const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\]]*)\\]\\(([^\\)\"]+)\\s*(\"(\\\\.|[^\"\\)])*\")?\\s*\\)");
const QString VUtils::c_fileNameRegExp = QString("[^\\\\/:\\*\\?\"<>\\|]*");
VUtils::VUtils() VUtils::VUtils()
{ {
} }

View File

@ -103,6 +103,10 @@ public:
// 4. Unused; // 4. Unused;
static const QString c_imageLinkRegExp; static const QString c_imageLinkRegExp;
// Regular expression for file/directory name.
// Forbidden char: \/:*?"<>|
static const QString c_fileNameRegExp;
private: private:
// <value, name> // <value, name>
static const QVector<QPair<QString, QString>> c_availableLanguages; static const QVector<QPair<QString, QString>> c_availableLanguages;

View File

@ -140,6 +140,9 @@ void VConfigManager::initialize()
m_enableImageCaption = getConfigFromSettings("global", m_enableImageCaption = getConfigFromSettings("global",
"enable_image_caption").toBool(); "enable_image_caption").toBool();
m_imageFolder = getConfigFromSettings("global",
"image_folder").toString();
} }
void VConfigManager::readPredefinedColorsFromSettings() void VConfigManager::readPredefinedColorsFromSettings()
@ -167,6 +170,7 @@ void VConfigManager::readNotebookFromSettings(QVector<VNotebook *> &p_notebooks,
QString name = userSettings->value("name").toString(); QString name = userSettings->value("name").toString();
QString path = userSettings->value("path").toString(); QString path = userSettings->value("path").toString();
VNotebook *notebook = new VNotebook(name, path, parent); VNotebook *notebook = new VNotebook(name, path, parent);
notebook->readConfig();
p_notebooks.append(notebook); p_notebooks.append(notebook);
} }
userSettings->endArray(); userSettings->endArray();
@ -193,7 +197,7 @@ void VConfigManager::writeNotebookToSettings(const QVector<VNotebook *> &p_noteb
<< "notebook items in [notebooks] section"; << "notebook items in [notebooks] section";
} }
QVariant VConfigManager::getConfigFromSettings(const QString &section, const QString &key) QVariant VConfigManager::getConfigFromSettings(const QString &section, const QString &key) const
{ {
QString fullKey = section + "/" + key; QString fullKey = section + "/" + key;
// First, look up the user-scoped config file // First, look up the user-scoped config file
@ -204,9 +208,7 @@ QVariant VConfigManager::getConfigFromSettings(const QString &section, const QSt
} }
// Second, look up the default config file // Second, look up the default config file
value = defaultSettings->value(fullKey); return getDefaultConfig(section, key);
qDebug() << "default config:" << fullKey << value.toString();
return value;
} }
void VConfigManager::setConfigToSettings(const QString &section, const QString &key, const QVariant &value) void VConfigManager::setConfigToSettings(const QString &section, const QString &key, const QVariant &value)
@ -217,6 +219,24 @@ void VConfigManager::setConfigToSettings(const QString &section, const QString &
qDebug() << "set user config:" << fullKey << value.toString(); qDebug() << "set user config:" << fullKey << value.toString();
} }
QVariant VConfigManager::getDefaultConfig(const QString &p_section, const QString &p_key) const
{
QString fullKey = p_section + "/" + p_key;
QVariant value = defaultSettings->value(fullKey);
qDebug() << "default config:" << fullKey << value.toString();
return value;
}
QVariant VConfigManager::resetDefaultConfig(const QString &p_section, const QString &p_key)
{
QVariant defaultValue = getDefaultConfig(p_section, p_key);
setConfigToSettings(p_section, p_key, defaultValue);
return defaultValue;
}
QString VConfigManager::fetchDirConfigFilePath(const QString &p_path) QString VConfigManager::fetchDirConfigFilePath(const QString &p_path)
{ {
QDir dir(p_path); QDir dir(p_path);
@ -230,8 +250,9 @@ QString VConfigManager::fetchDirConfigFilePath(const QString &p_path)
qDebug() << "rename old directory config file:" << fileName; qDebug() << "rename old directory config file:" << fileName;
} }
qDebug() << "use directory config file:" << fileName; QString filePath = QDir::cleanPath(dir.filePath(fileName));
return dir.filePath(fileName); qDebug() << "use directory config file:" << filePath;
return filePath;
} }
QJsonObject VConfigManager::readDirectoryConfig(const QString &path) QJsonObject VConfigManager::readDirectoryConfig(const QString &path)
@ -251,9 +272,7 @@ QJsonObject VConfigManager::readDirectoryConfig(const QString &path)
bool VConfigManager::directoryConfigExist(const QString &path) bool VConfigManager::directoryConfigExist(const QString &path)
{ {
QString configFile = fetchDirConfigFilePath(path); return QFileInfo::exists(fetchDirConfigFilePath(path));
QFile config(configFile);
return config.exists();
} }
bool VConfigManager::writeDirectoryConfig(const QString &path, const QJsonObject &configJson) bool VConfigManager::writeDirectoryConfig(const QString &path, const QJsonObject &configJson)

View File

@ -23,7 +23,7 @@ enum MarkdownConverterType
struct VColor struct VColor
{ {
QString name; QString name;
QString rgb; // 'FFFFFF', ithout '#' QString rgb; // 'FFFFFF', without '#'
}; };
class VConfigManager class VConfigManager
@ -33,9 +33,10 @@ public:
~VConfigManager(); ~VConfigManager();
void initialize(); void initialize();
// Static helper functions // Read config from the directory config json file into a QJsonObject.
// Read config from the directory config json file into a QJsonObject // @path is the directory containing the config json file.
static QJsonObject readDirectoryConfig(const QString &path); static QJsonObject readDirectoryConfig(const QString &path);
static bool writeDirectoryConfig(const QString &path, const QJsonObject &configJson); static bool writeDirectoryConfig(const QString &path, const QJsonObject &configJson);
static bool directoryConfigExist(const QString &path); static bool directoryConfigExist(const QString &path);
static bool deleteDirectoryConfig(const QString &path); static bool deleteDirectoryConfig(const QString &path);
@ -172,6 +173,13 @@ public:
inline bool getEnableImageCaption() const; inline bool getEnableImageCaption() const;
inline void setEnableImageCaption(bool p_enabled); inline void setEnableImageCaption(bool p_enabled);
inline const QString &getImageFolder() const;
// Empty string to reset the default folder.
inline void setImageFolder(const QString &p_folder);
inline bool isCustomImageFolder() const;
// Get the folder the ini file exists. // Get the folder the ini file exists.
QString getConfigFolder() const; QString getConfigFolder() const;
@ -185,14 +193,23 @@ public:
QVector<QString> getEditorStyles() const; QVector<QString> getEditorStyles() const;
private: private:
QVariant getConfigFromSettings(const QString &section, const QString &key); QVariant getConfigFromSettings(const QString &section, const QString &key) const;
void setConfigToSettings(const QString &section, const QString &key, const QVariant &value); void setConfigToSettings(const QString &section, const QString &key, const QVariant &value);
// Get default config from vnote.ini.
QVariant getDefaultConfig(const QString &p_section, const QString &p_key) const;
// Reset user config to default config and return the default config value.
QVariant resetDefaultConfig(const QString &p_section, const QString &p_key);
void readNotebookFromSettings(QVector<VNotebook *> &p_notebooks, QObject *parent); void readNotebookFromSettings(QVector<VNotebook *> &p_notebooks, QObject *parent);
void writeNotebookToSettings(const QVector<VNotebook *> &p_notebooks); void writeNotebookToSettings(const QVector<VNotebook *> &p_notebooks);
void readPredefinedColorsFromSettings(); void readPredefinedColorsFromSettings();
// 1. Update styles common in HTML and Markdown; // 1. Update styles common in HTML and Markdown;
// 2. Update styles for Markdown. // 2. Update styles for Markdown.
void updateEditStyle(); void updateEditStyle();
void updateMarkdownEditStyle(); void updateMarkdownEditStyle();
// Migrate ini file from tamlok/vnote.ini to vnote/vnote.ini. // Migrate ini file from tamlok/vnote.ini to vnote/vnote.ini.
@ -291,6 +308,10 @@ private:
// Center image and add the alt text as caption. // Center image and add the alt text as caption.
bool m_enableImageCaption; bool m_enableImageCaption;
// Global default folder name to store images of all the notes.
// Each notebook can specify its custom folder.
QString m_imageFolder;
// The name of the config file in each directory, obsolete. // The name of the config file in each directory, obsolete.
// Use c_dirConfigFile instead. // Use c_dirConfigFile instead.
static const QString c_obsoleteDirConfigFile; static const QString c_obsoleteDirConfigFile;
@ -779,4 +800,30 @@ inline void VConfigManager::setEnableImageCaption(bool p_enabled)
m_enableImageCaption); m_enableImageCaption);
} }
inline const QString &VConfigManager::getImageFolder() const
{
return m_imageFolder;
}
inline void VConfigManager::setImageFolder(const QString &p_folder)
{
if (p_folder.isEmpty()) {
// Reset the default folder.
m_imageFolder = resetDefaultConfig("global", "image_folder").toString();
return;
}
if (m_imageFolder == p_folder) {
return;
}
m_imageFolder = p_folder;
setConfigToSettings("global", "image_folder", m_imageFolder);
}
inline bool VConfigManager::isCustomImageFolder() const
{
return m_imageFolder != getDefaultConfig("global", "image_folder").toString();
}
#endif // VCONFIGMANAGER_H #endif // VCONFIGMANAGER_H

View File

@ -18,4 +18,13 @@ static const int c_tabSequenceBase = 1;
// HTML and JS. // HTML and JS.
static const QString c_htmlJSHolder = "JS_PLACE_HOLDER"; static const QString c_htmlJSHolder = "JS_PLACE_HOLDER";
static const QString c_htmlExtraHolder = "<!-- EXTRA_PLACE_HOLDER -->"; static const QString c_htmlExtraHolder = "<!-- EXTRA_PLACE_HOLDER -->";
// Directory Config file items.
namespace DirConfig
{
static const QString c_version = "version";
static const QString c_subDirectories = "sub_directories";
static const QString c_files = "files";
static const QString c_imageFolder = "image_folder";
}
#endif #endif

View File

@ -105,15 +105,36 @@ QString VDirectory::retriveRelativePath(const VDirectory *p_dir) const
} }
} }
QJsonObject VDirectory::createDirectoryJson() QJsonObject VDirectory::toConfigJson() const
{ {
QJsonObject dirJson; QJsonObject dirJson;
dirJson["version"] = "1"; dirJson[DirConfig::c_version] = "1";
dirJson["sub_directories"] = QJsonArray();
dirJson["files"] = QJsonArray(); QJsonArray subDirs;
for (int i = 0; i < m_subDirs.size(); ++i) {
subDirs.append(m_subDirs[i]->getName());
}
dirJson[DirConfig::c_subDirectories] = subDirs;
QJsonArray files;
for (int i = 0; i < m_files.size(); ++i) {
files.append(m_files[i]->getName());
}
dirJson[DirConfig::c_files] = files;
return dirJson; return dirJson;
} }
bool VDirectory::readConfig()
{
return true;
}
bool VDirectory::writeToConfig() const
{
return VConfigManager::writeDirectoryConfig(retrivePath(), toConfigJson());
}
VDirectory *VDirectory::createSubDirectory(const QString &p_name) VDirectory *VDirectory::createSubDirectory(const QString &p_name)
{ {
Q_ASSERT(!p_name.isEmpty()); Q_ASSERT(!p_name.isEmpty());
@ -128,19 +149,21 @@ VDirectory *VDirectory::createSubDirectory(const QString &p_name)
return NULL; return NULL;
} }
QJsonObject subJson = createDirectoryJson(); VDirectory *ret = new VDirectory(m_notebook, p_name, this);
if (!VConfigManager::writeDirectoryConfig(QDir::cleanPath(QDir(path).filePath(p_name)), subJson)) { if (!VConfigManager::writeDirectoryConfig(QDir::cleanPath(QDir(path).filePath(p_name)),
ret->toConfigJson())) {
dir.rmdir(p_name); dir.rmdir(p_name);
delete ret;
return NULL; return NULL;
} }
if (!createSubDirectoryInConfig(p_name)) { if (!createSubDirectoryInConfig(p_name)) {
VConfigManager::deleteDirectoryConfig(QDir(path).filePath(p_name)); VConfigManager::deleteDirectoryConfig(QDir(path).filePath(p_name));
dir.rmdir(p_name); dir.rmdir(p_name);
delete ret;
return NULL; return NULL;
} }
VDirectory *ret = new VDirectory(m_notebook, p_name, this);
m_subDirs.append(ret); m_subDirs.append(ret);
return ret; return ret;
} }

View File

@ -65,7 +65,15 @@ public:
void reorderFiles(int p_first, int p_last, int p_destStart); void reorderFiles(int p_first, int p_last, int p_destStart);
bool reorderFilesInConfig(int p_first, int p_last, int p_destStart); bool reorderFilesInConfig(int p_first, int p_last, int p_destStart);
static QJsonObject createDirectoryJson(); // Serialize current instance to json.
QJsonObject toConfigJson() const;
// Read configurations (excluding "sub_directories" and "files" section)
// from config file.
bool readConfig();
// Write current instance to config file.
bool writeToConfig() const;
private: private:
// Get the path of @p_dir recursively // Get the path of @p_dir recursively

View File

@ -142,7 +142,6 @@ void VDirectoryTree::updateDirectoryTree()
bool VDirectoryTree::restoreCurrentItem() bool VDirectoryTree::restoreCurrentItem()
{ {
qDebug() << m_notebook << m_notebookCurrentDirMap;
auto it = m_notebookCurrentDirMap.find(m_notebook); auto it = m_notebookCurrentDirMap.find(m_notebook);
if (it != m_notebookCurrentDirMap.end()) { if (it != m_notebookCurrentDirMap.end()) {
bool rootDirectory; bool rootDirectory;

View File

@ -455,8 +455,7 @@ void VMainWindow::initFileMenu()
fileMenu->addSeparator(); fileMenu->addSeparator();
// Export as PDF. // Export as PDF.
m_exportAsPDFAct = new QAction(QIcon(":/resources/icons/export_pdf.svg"), m_exportAsPDFAct = new QAction(tr("Export As &PDF"), this);
tr("Export As &PDF"), this);
m_exportAsPDFAct->setToolTip(tr("Export current note as PDF file")); m_exportAsPDFAct->setToolTip(tr("Export current note as PDF file"));
connect(m_exportAsPDFAct, &QAction::triggered, connect(m_exportAsPDFAct, &QAction::triggered,
this, &VMainWindow::exportAsPDF); this, &VMainWindow::exportAsPDF);

View File

@ -6,10 +6,10 @@
#include "vconfigmanager.h" #include "vconfigmanager.h"
#include "vfile.h" #include "vfile.h"
const QString VNotebook::c_defaultImageFolder = "_v_images"; extern VConfigManager vconfig;
VNotebook::VNotebook(const QString &name, const QString &path, QObject *parent) VNotebook::VNotebook(const QString &name, const QString &path, QObject *parent)
: QObject(parent), m_name(name), m_imageFolder(c_defaultImageFolder) : QObject(parent), m_name(name)
{ {
m_path = QDir::cleanPath(path); m_path = QDir::cleanPath(path);
m_rootDir = new VDirectory(this, VUtils::directoryNameFromPath(path)); m_rootDir = new VDirectory(this, VUtils::directoryNameFromPath(path));
@ -20,6 +20,54 @@ VNotebook::~VNotebook()
delete m_rootDir; delete m_rootDir;
} }
bool VNotebook::readConfig()
{
QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path);
if (configJson.isEmpty()) {
qWarning() << "fail to read notebook configuration" << m_path;
return false;
}
// [image_folder] section.
auto it = configJson.find(DirConfig::c_imageFolder);
if (it != configJson.end()) {
m_imageFolder = it.value().toString();
}
return true;
}
QJsonObject VNotebook::toConfigJson() const
{
QJsonObject json = m_rootDir->toConfigJson();
// [image_folder] section.
json[DirConfig::c_imageFolder] = m_imageFolder;
return json;
}
bool VNotebook::writeToConfig() const
{
return VConfigManager::writeDirectoryConfig(m_path, toConfigJson());
}
bool VNotebook::writeConfig() const
{
QJsonObject json = toConfigJson();
QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path);
if (configJson.isEmpty()) {
qWarning() << "fail to read notebook configuration" << m_path;
return false;
}
json[DirConfig::c_subDirectories] = configJson[DirConfig::c_subDirectories];
json[DirConfig::c_files] = configJson[DirConfig::c_files];
return VConfigManager::writeDirectoryConfig(m_path, json);
}
QString VNotebook::getName() const QString VNotebook::getName() const
{ {
return m_name; return m_name;
@ -41,25 +89,24 @@ bool VNotebook::open()
} }
VNotebook *VNotebook::createNotebook(const QString &p_name, const QString &p_path, VNotebook *VNotebook::createNotebook(const QString &p_name, const QString &p_path,
bool p_import, QObject *p_parent) bool p_import, const QString &p_imageFolder,
QObject *p_parent)
{ {
VNotebook *nb = new VNotebook(p_name, p_path, p_parent); VNotebook *nb = new VNotebook(p_name, p_path, p_parent);
if (!nb) { nb->setImageFolder(p_imageFolder);
return nb;
}
// Check if there alread exists a config file. // Check if there alread exists a config file.
if (p_import && VConfigManager::directoryConfigExist(p_path)) { if (p_import && VConfigManager::directoryConfigExist(p_path)) {
qDebug() << "import existing notebook"; qDebug() << "import existing notebook";
nb->readConfig();
return nb; return nb;
} }
// Create directory config in @p_path if (!nb->writeToConfig()) {
QJsonObject configJson = VDirectory::createDirectoryJson();
if (!VConfigManager::writeDirectoryConfig(p_path, configJson)) {
delete nb; delete nb;
return NULL; return NULL;
} }
return nb; return nb;
} }
@ -112,6 +159,7 @@ void VNotebook::rename(const QString &p_name)
if (p_name == m_name || p_name.isEmpty()) { if (p_name == m_name || p_name.isEmpty()) {
return; return;
} }
m_name = p_name; m_name = p_name;
} }
@ -121,6 +169,20 @@ bool VNotebook::containsFile(const VFile *p_file) const
} }
const QString &VNotebook::getImageFolder() const const QString &VNotebook::getImageFolder() const
{
if (m_imageFolder.isEmpty()) {
return vconfig.getImageFolder();
} else {
return m_imageFolder;
}
}
void VNotebook::setImageFolder(const QString &p_imageFolder)
{
m_imageFolder = p_imageFolder;
}
const QString &VNotebook::getImageFolderConfig() const
{ {
return m_imageFolder; return m_imageFolder;
} }

View File

@ -16,9 +16,11 @@ public:
// Open the root directory to load contents // Open the root directory to load contents
bool open(); bool open();
// Close all the directory and files of this notebook. // Close all the directory and files of this notebook.
// Please make sure all files belonging to this notebook have been closed in the tab. // Please make sure all files belonging to this notebook have been closed in the tab.
void close(); void close();
bool containsFile(const VFile *p_file) const; bool containsFile(const VFile *p_file) const;
QString getName() const; QString getName() const;
@ -26,26 +28,47 @@ public:
inline VDirectory *getRootDir(); inline VDirectory *getRootDir();
void rename(const QString &p_name); void rename(const QString &p_name);
static VNotebook *createNotebook(const QString &p_name, const QString &p_path, bool p_import, static VNotebook *createNotebook(const QString &p_name, const QString &p_path,
bool p_import, const QString &p_imageFolder,
QObject *p_parent = 0); QObject *p_parent = 0);
static bool deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles); static bool deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles);
// Get the image folder for this notebook to use (not exactly the same as
// m_imageFolder if it is empty).
const QString &getImageFolder() const; const QString &getImageFolder() const;
// Return m_imageFolder.
const QString &getImageFolderConfig() const;
void setImageFolder(const QString &p_imageFolder);
// Read configurations (excluding "sub_directories" and "files" section)
// from root directory config file.
bool readConfig();
// Write configurations (excluding "sub_directories" and "files" section)
// to root directory config file.
bool writeConfig() const;
signals: signals:
void contentChanged(); void contentChanged();
private: private:
// Serialize current instance to json.
QJsonObject toConfigJson() const;
// Write current instance to config file.
bool writeToConfig() const;
QString m_name; QString m_name;
QString m_path; QString m_path;
// Folder name to store images. // Folder name to store images.
// VNote will store images in this folder within the same directory of the note. // If not empty, VNote will store images in this folder within the same directory of the note.
// Otherwise, VNote will use the global configured folder.
QString m_imageFolder; QString m_imageFolder;
// Default folder name to store images of all the notes within this notebook.
static const QString c_defaultImageFolder;
// Parent is NULL for root directory // Parent is NULL for root directory
VDirectory *m_rootDir; VDirectory *m_rootDir;
}; };

View File

@ -163,7 +163,7 @@ void VNotebookSelector::update()
bool VNotebookSelector::newNotebook() bool VNotebookSelector::newNotebook()
{ {
QString info(tr("Please type the name of the notebook and " QString info(tr("Please type the name of the notebook and "
"choose an existing directory as Root Folder of the notebook.")); "choose an existing folder as Root Folder of the notebook."));
info += "\n"; info += "\n";
info += tr("The root folder should be used EXCLUSIVELY by VNote and " info += tr("The root folder should be used EXCLUSIVELY by VNote and "
"it is recommended to be EMPTY."); "it is recommended to be EMPTY.");
@ -171,23 +171,25 @@ bool VNotebookSelector::newNotebook()
QString defaultName("new_notebook"); QString defaultName("new_notebook");
QString defaultPath; QString defaultPath;
do {
VNewNotebookDialog dialog(tr("Add Notebook"), info, defaultName, VNewNotebookDialog dialog(tr("Add Notebook"), info, defaultName,
defaultPath, this); defaultPath, this);
do {
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
QString name = dialog.getNameInput(); QString name = dialog.getNameInput();
QString path = dialog.getPathInput(); QString path = dialog.getPathInput();
if (findNotebook(name)) { if (findNotebook(name)) {
info = tr("Name already exists. Please choose another name."); VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
defaultName = name; tr("Name already exists. Please choose another name."), "",
defaultPath = path; QMessageBox::Ok, QMessageBox::Ok, this);
continue; continue;
} }
createNotebook(name, path, dialog.getImportCheck());
createNotebook(name, path, dialog.getImportCheck(), dialog.getImageFolder());
return true; return true;
} }
break; break;
} while (true); } while (true);
return false; return false;
} }
@ -201,9 +203,13 @@ VNotebook *VNotebookSelector::findNotebook(const QString &p_name)
return NULL; return NULL;
} }
void VNotebookSelector::createNotebook(const QString &p_name, const QString &p_path, bool p_import) void VNotebookSelector::createNotebook(const QString &p_name,
const QString &p_path,
bool p_import,
const QString &p_imageFolder)
{ {
VNotebook *nb = VNotebook::createNotebook(p_name, p_path, p_import, m_vnote); VNotebook *nb = VNotebook::createNotebook(p_name, p_path, p_import,
p_imageFolder, m_vnote);
m_notebooks.append(nb); m_notebooks.append(nb);
vconfig.setNotebooks(m_notebooks); vconfig.setNotebooks(m_notebooks);
@ -251,7 +257,7 @@ void VNotebookSelector::deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles
int cho = VUtils::showMessage(QMessageBox::Information, tr("Delete Notebook Folder From Disk"), int cho = VUtils::showMessage(QMessageBox::Information, tr("Delete Notebook Folder From Disk"),
tr("Fail to delete the root folder of notebook " tr("Fail to delete the root folder of notebook "
"<span style=\"%1\">%2</span> from disk. You may open " "<span style=\"%1\">%2</span> from disk. You may open "
"the directory and check it manually.") "the folder and check it manually.")
.arg(vconfig.c_dataTextStyle).arg(name), "", .arg(vconfig.c_dataTextStyle).arg(name), "",
QMessageBox::Open | QMessageBox::Ok, QMessageBox::Open | QMessageBox::Ok,
QMessageBox::Ok, this); QMessageBox::Ok, this);
@ -285,28 +291,38 @@ void VNotebookSelector::editNotebookInfo()
int index = indexOfListItem(item); int index = indexOfListItem(item);
VNotebook *notebook = getNotebookFromComboIndex(index); VNotebook *notebook = getNotebookFromComboIndex(index);
QString info;
QString curName = notebook->getName(); QString curName = notebook->getName();
QString defaultPath = notebook->getPath();
QString defaultName(curName); VNotebookInfoDialog dialog(tr("Notebook Information"), "", notebook, this);
do { do {
VNotebookInfoDialog dialog(tr("Notebook Information"), info, defaultName,
defaultPath, this);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
QString name = dialog.getNameInput(); bool updated = false;
if (name == curName) { QString name = dialog.getName();
return; if (name != curName) {
}
if (findNotebook(name)) { if (findNotebook(name)) {
info = "Name already exists. Please choose another name."; VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
defaultName = name; tr("Name already exists. Please choose another name."), "",
QMessageBox::Ok, QMessageBox::Ok, this);
continue; continue;
} }
updated = true;
notebook->rename(name); notebook->rename(name);
updateComboBoxItem(index, name); updateComboBoxItem(index, name);
vconfig.setNotebooks(m_notebooks); vconfig.setNotebooks(m_notebooks);
}
QString imageFolder = dialog.getImageFolder();
if (imageFolder != notebook->getImageFolderConfig()) {
updated = true;
notebook->setImageFolder(imageFolder);
notebook->writeConfig();
}
if (updated) {
emit notebookUpdated(notebook); emit notebookUpdated(notebook);
} }
}
break; break;
} while (true); } while (true);
} }

View File

@ -55,8 +55,12 @@ private:
VNotebook *findNotebook(const QString &p_name); VNotebook *findNotebook(const QString &p_name);
// Return the index of @p_notebook in m_noteboks. // Return the index of @p_notebook in m_noteboks.
int indexOfNotebook(const VNotebook *p_notebook); int indexOfNotebook(const VNotebook *p_notebook);
// if @p_import is true, we will use the existing config file.
void createNotebook(const QString &p_name, const QString &p_path, bool p_import); // If @p_import is true, we will use the existing config file.
// If @p_imageFolder is empty, we will use the global one.
void createNotebook(const QString &p_name, const QString &p_path,
bool p_import, const QString &p_imageFolder);
void deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles); void deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles);
void addNotebookItem(const QString &p_name); void addNotebookItem(const QString &p_name);
// @p_index is the index of m_notebooks, NOT of QComboBox. // @p_index is the index of m_notebooks, NOT of QComboBox.