mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
support custom image folder for both global scope and notebook scope
This commit is contained in:
parent
03c0fdc49d
commit
9bf3f9394f
@ -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,12 +112,20 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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 §ion, const QString &key)
|
QVariant VConfigManager::getConfigFromSettings(const QString §ion, 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 §ion, 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 §ion, const QString &key, const QVariant &value)
|
void VConfigManager::setConfigToSettings(const QString §ion, const QString &key, const QVariant &value)
|
||||||
@ -217,6 +219,24 @@ void VConfigManager::setConfigToSettings(const QString §ion, 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)
|
||||||
|
@ -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 §ion, const QString &key);
|
QVariant getConfigFromSettings(const QString §ion, const QString &key) const;
|
||||||
void setConfigToSettings(const QString §ion, const QString &key, const QVariant &value);
|
void setConfigToSettings(const QString §ion, 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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user