mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-06 14:29:54 +08:00
support meta word
- Add VLineEdit as a QLineEdit with meta data support; - support custom magic words through [magic_words]; - add %help% for all magic words information;
This commit is contained in:
parent
f1f6980921
commit
787c61a5af
@ -2,6 +2,7 @@
|
|||||||
#include "vdirinfodialog.h"
|
#include "vdirinfodialog.h"
|
||||||
#include "vdirectory.h"
|
#include "vdirectory.h"
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
|
#include "vlineedit.h"
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
@ -16,7 +17,7 @@ VDirInfoDialog::VDirInfoDialog(const QString &title,
|
|||||||
{
|
{
|
||||||
setupUI();
|
setupUI();
|
||||||
|
|
||||||
connect(nameEdit, &QLineEdit::textChanged, this, &VDirInfoDialog::handleInputChanged);
|
connect(m_nameEdit, &QLineEdit::textChanged, this, &VDirInfoDialog::handleInputChanged);
|
||||||
|
|
||||||
handleInputChanged();
|
handleInputChanged();
|
||||||
}
|
}
|
||||||
@ -28,15 +29,18 @@ void VDirInfoDialog::setupUI()
|
|||||||
infoLabel = new QLabel(info);
|
infoLabel = new QLabel(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
nameEdit = new QLineEdit(m_directory->getName());
|
m_nameEdit = new VLineEdit(m_directory->getName());
|
||||||
nameEdit->selectAll();
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
||||||
|
m_nameEdit);
|
||||||
|
m_nameEdit->setValidator(validator);
|
||||||
|
m_nameEdit->selectAll();
|
||||||
|
|
||||||
// Created time.
|
// Created time.
|
||||||
QString createdTimeStr = VUtils::displayDateTime(m_directory->getCreatedTimeUtc().toLocalTime());
|
QString createdTimeStr = VUtils::displayDateTime(m_directory->getCreatedTimeUtc().toLocalTime());
|
||||||
QLabel *createdTimeLabel = new QLabel(createdTimeStr);
|
QLabel *createdTimeLabel = new QLabel(createdTimeStr);
|
||||||
|
|
||||||
QFormLayout *topLayout = new QFormLayout();
|
QFormLayout *topLayout = new QFormLayout();
|
||||||
topLayout->addRow(tr("Folder &name:"), nameEdit);
|
topLayout->addRow(tr("Folder &name:"), m_nameEdit);
|
||||||
topLayout->addRow(tr("Created time:"), createdTimeLabel);
|
topLayout->addRow(tr("Created time:"), createdTimeLabel);
|
||||||
|
|
||||||
m_warnLabel = new QLabel();
|
m_warnLabel = new QLabel();
|
||||||
@ -49,7 +53,7 @@ void VDirInfoDialog::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);
|
||||||
nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
|
m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout();
|
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||||
if (infoLabel) {
|
if (infoLabel) {
|
||||||
@ -67,19 +71,35 @@ void VDirInfoDialog::setupUI()
|
|||||||
void VDirInfoDialog::handleInputChanged()
|
void VDirInfoDialog::handleInputChanged()
|
||||||
{
|
{
|
||||||
bool showWarnLabel = false;
|
bool showWarnLabel = false;
|
||||||
QString name = nameEdit->text();
|
QString name = m_nameEdit->getEvaluatedText();
|
||||||
bool nameOk = !name.isEmpty();
|
bool nameOk = !name.isEmpty();
|
||||||
if (nameOk && name != m_directory->getName()) {
|
if (nameOk && name != m_directory->getName()) {
|
||||||
// Check if the name conflicts with existing directory name.
|
// Check if the name conflicts with existing directory name.
|
||||||
// Case-insensitive when creating note.
|
// Case-insensitive when creating note.
|
||||||
const VDirectory *directory = m_parentDirectory->findSubDirectory(name, false);
|
const VDirectory *directory = m_parentDirectory->findSubDirectory(name, false);
|
||||||
|
QString warnText;
|
||||||
if (directory && directory != m_directory) {
|
if (directory && directory != m_directory) {
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name (case-insensitive) <span style=\"%2\">%3</span> already exists. "
|
||||||
|
"Please choose another name.")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
} else if (!VUtils::checkFileNameLegal(name)) {
|
||||||
|
// Check if evaluated name contains illegal characters.
|
||||||
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name <span style=\"%2\">%3</span> contains illegal characters "
|
||||||
|
"(after magic word evaluation).")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nameOk) {
|
||||||
showWarnLabel = true;
|
showWarnLabel = true;
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
m_warnLabel->setText(warnText);
|
||||||
"Please choose another name.")
|
|
||||||
.arg(g_config->c_warningTextStyle);
|
|
||||||
m_warnLabel->setText(nameConflictText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,5 +111,5 @@ void VDirInfoDialog::handleInputChanged()
|
|||||||
|
|
||||||
QString VDirInfoDialog::getNameInput() const
|
QString VDirInfoDialog::getNameInput() const
|
||||||
{
|
{
|
||||||
return nameEdit->text();
|
return m_nameEdit->getEvaluatedText();
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class VLineEdit;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
class QString;
|
class QString;
|
||||||
class VDirectory;
|
class VDirectory;
|
||||||
@ -27,7 +27,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
|
|
||||||
QLineEdit *nameEdit;
|
VLineEdit *m_nameEdit;
|
||||||
QLabel *m_warnLabel;
|
QLabel *m_warnLabel;
|
||||||
QDialogButtonBox *m_btnBox;
|
QDialogButtonBox *m_btnBox;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "vnotefile.h"
|
#include "vnotefile.h"
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
|
#include "vlineedit.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ VFileInfoDialog::VFileInfoDialog(const QString &title,
|
|||||||
{
|
{
|
||||||
setupUI(title, info);
|
setupUI(title, info);
|
||||||
|
|
||||||
connect(nameEdit, &QLineEdit::textChanged, this, &VFileInfoDialog::handleInputChanged);
|
connect(m_nameEdit, &QLineEdit::textChanged, this, &VFileInfoDialog::handleInputChanged);
|
||||||
|
|
||||||
handleInputChanged();
|
handleInputChanged();
|
||||||
}
|
}
|
||||||
@ -30,7 +31,10 @@ void VFileInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
|
|
||||||
// File name.
|
// File name.
|
||||||
QString name = m_file->getName();
|
QString name = m_file->getName();
|
||||||
nameEdit = new QLineEdit(name);
|
m_nameEdit = new VLineEdit(name);
|
||||||
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
||||||
|
m_nameEdit);
|
||||||
|
m_nameEdit->setValidator(validator);
|
||||||
int baseStart = 0, baseLength = name.size();
|
int baseStart = 0, baseLength = name.size();
|
||||||
int dotIdx = name.lastIndexOf('.');
|
int dotIdx = name.lastIndexOf('.');
|
||||||
if (dotIdx != -1) {
|
if (dotIdx != -1) {
|
||||||
@ -38,7 +42,7 @@ void VFileInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Select without suffix.
|
// Select without suffix.
|
||||||
nameEdit->setSelection(baseStart, baseLength);
|
m_nameEdit->setSelection(baseStart, baseLength);
|
||||||
|
|
||||||
// Attachment folder.
|
// Attachment folder.
|
||||||
QLineEdit *attachmentFolderEdit = new QLineEdit(m_file->getAttachmentFolder());
|
QLineEdit *attachmentFolderEdit = new QLineEdit(m_file->getAttachmentFolder());
|
||||||
@ -56,7 +60,7 @@ void VFileInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
modifiedTimeLabel->setToolTip(tr("Last modified time within VNote"));
|
modifiedTimeLabel->setToolTip(tr("Last modified time within VNote"));
|
||||||
|
|
||||||
QFormLayout *topLayout = new QFormLayout();
|
QFormLayout *topLayout = new QFormLayout();
|
||||||
topLayout->addRow(tr("Note &name:"), nameEdit);
|
topLayout->addRow(tr("Note &name:"), m_nameEdit);
|
||||||
topLayout->addRow(tr("Attachment folder:"), attachmentFolderEdit);
|
topLayout->addRow(tr("Attachment folder:"), attachmentFolderEdit);
|
||||||
topLayout->addRow(tr("Created time:"), createdTimeLabel);
|
topLayout->addRow(tr("Created time:"), createdTimeLabel);
|
||||||
topLayout->addRow(tr("Modified time:"), modifiedTimeLabel);
|
topLayout->addRow(tr("Modified time:"), modifiedTimeLabel);
|
||||||
@ -71,7 +75,7 @@ void VFileInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
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);
|
||||||
nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
|
m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout();
|
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||||
if (infoLabel) {
|
if (infoLabel) {
|
||||||
@ -90,28 +94,43 @@ void VFileInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
void VFileInfoDialog::handleInputChanged()
|
void VFileInfoDialog::handleInputChanged()
|
||||||
{
|
{
|
||||||
bool showWarnLabel = false;
|
bool showWarnLabel = false;
|
||||||
QString name = nameEdit->text();
|
QString name = m_nameEdit->getEvaluatedText();
|
||||||
bool nameOk = !name.isEmpty();
|
bool nameOk = !name.isEmpty();
|
||||||
if (nameOk && name != m_file->getName()) {
|
if (nameOk && name != m_file->getName()) {
|
||||||
// Check if the name conflicts with existing note name.
|
// Check if the name conflicts with existing note name.
|
||||||
// Case-insensitive when creating note.
|
// Case-insensitive when creating note.
|
||||||
const VNoteFile *file = m_directory->findFile(name, false);
|
const VNoteFile *file = m_directory->findFile(name, false);
|
||||||
|
QString warnText;
|
||||||
if (file && file != m_file) {
|
if (file && file != m_file) {
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
showWarnLabel = true;
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
"Name (case-insensitive) <span style=\"%2\">%3</span> already exists. "
|
||||||
"Please choose another name.")
|
"Please choose another name.")
|
||||||
.arg(g_config->c_warningTextStyle);
|
.arg(g_config->c_warningTextStyle)
|
||||||
m_warnLabel->setText(nameConflictText);
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
} else if (m_file->getDocType() != DocType::Unknown
|
} else if (m_file->getDocType() != DocType::Unknown
|
||||||
&& VUtils::docTypeFromName(name) != m_file->getDocType()) {
|
&& VUtils::docTypeFromName(name) != m_file->getDocType()) {
|
||||||
// Check if the name change the doc type.
|
// Check if the name change the doc type.
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Changing type of the note is not supported. "
|
||||||
|
"Please use the same suffix as the old one.")
|
||||||
|
.arg(g_config->c_warningTextStyle);
|
||||||
|
} else if (!VUtils::checkFileNameLegal(name)) {
|
||||||
|
// Check if evaluated name contains illegal characters.
|
||||||
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name <span style=\"%2\">%3</span> contains illegal characters "
|
||||||
|
"(after magic word evaluation).")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nameOk) {
|
||||||
showWarnLabel = true;
|
showWarnLabel = true;
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Changing type of the note is not supported. "
|
m_warnLabel->setText(warnText);
|
||||||
"Please use the same suffix as the old one.")
|
|
||||||
.arg(g_config->c_warningTextStyle);
|
|
||||||
m_warnLabel->setText(nameConflictText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,5 +142,5 @@ void VFileInfoDialog::handleInputChanged()
|
|||||||
|
|
||||||
QString VFileInfoDialog::getNameInput() const
|
QString VFileInfoDialog::getNameInput() const
|
||||||
{
|
{
|
||||||
return nameEdit->text();
|
return m_nameEdit->getEvaluatedText();
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class VLineEdit;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
class QString;
|
class QString;
|
||||||
class VDirectory;
|
class VDirectory;
|
||||||
@ -29,7 +29,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void setupUI(const QString &p_title, const QString &p_info);
|
void setupUI(const QString &p_title, const QString &p_info);
|
||||||
|
|
||||||
QLineEdit *nameEdit;
|
VLineEdit *m_nameEdit;
|
||||||
QLabel *m_warnLabel;
|
QLabel *m_warnLabel;
|
||||||
QDialogButtonBox *m_btnBox;
|
QDialogButtonBox *m_btnBox;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include "vinsertimagedialog.h"
|
#include "vinsertimagedialog.h"
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
|
#include "vlineedit.h"
|
||||||
|
|
||||||
VInsertImageDialog::VInsertImageDialog(const QString &title, const QString &defaultImageTitle,
|
VInsertImageDialog::VInsertImageDialog(const QString &title, const QString &defaultImageTitle,
|
||||||
const QString &defaultPath, QWidget *parent)
|
const QString &defaultPath, QWidget *parent)
|
||||||
@ -11,9 +12,12 @@ VInsertImageDialog::VInsertImageDialog(const QString &title, const QString &defa
|
|||||||
{
|
{
|
||||||
setupUI();
|
setupUI();
|
||||||
|
|
||||||
connect(imageTitleEdit, &QLineEdit::textChanged, this, &VInsertImageDialog::enableOkButton);
|
connect(m_imageTitleEdit, &QLineEdit::textChanged,
|
||||||
connect(pathEdit, &QLineEdit::textChanged, this, &VInsertImageDialog::enableOkButton);
|
this, &VInsertImageDialog::enableOkButton);
|
||||||
connect(browseBtn, &QPushButton::clicked, this, &VInsertImageDialog::handleBrowseBtnClicked);
|
connect(pathEdit, &QLineEdit::textChanged,
|
||||||
|
this, &VInsertImageDialog::enableOkButton);
|
||||||
|
connect(browseBtn, &QPushButton::clicked,
|
||||||
|
this, &VInsertImageDialog::handleBrowseBtnClicked);
|
||||||
|
|
||||||
enableOkButton();
|
enableOkButton();
|
||||||
}
|
}
|
||||||
@ -34,19 +38,19 @@ void VInsertImageDialog::setupUI()
|
|||||||
browseBtn = new QPushButton(tr("&Browse"));
|
browseBtn = new QPushButton(tr("&Browse"));
|
||||||
|
|
||||||
imageTitleLabel = new QLabel(tr("&Image title:"));
|
imageTitleLabel = new QLabel(tr("&Image title:"));
|
||||||
imageTitleEdit = new QLineEdit(defaultImageTitle);
|
m_imageTitleEdit = new VLineEdit(defaultImageTitle);
|
||||||
imageTitleEdit->selectAll();
|
m_imageTitleEdit->selectAll();
|
||||||
imageTitleLabel->setBuddy(imageTitleEdit);
|
imageTitleLabel->setBuddy(m_imageTitleEdit);
|
||||||
QRegExp regExp("[\\w\\(\\)@#%\\*\\-\\+=\\?<>\\,\\.\\s]+");
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_imageTitleRegExp),
|
||||||
QValidator *validator = new QRegExpValidator(regExp, this);
|
m_imageTitleEdit);
|
||||||
imageTitleEdit->setValidator(validator);
|
m_imageTitleEdit->setValidator(validator);
|
||||||
|
|
||||||
QGridLayout *topLayout = new QGridLayout();
|
QGridLayout *topLayout = new QGridLayout();
|
||||||
topLayout->addWidget(pathLabel, 0, 0);
|
topLayout->addWidget(pathLabel, 0, 0);
|
||||||
topLayout->addWidget(pathEdit, 0, 1);
|
topLayout->addWidget(pathEdit, 0, 1);
|
||||||
topLayout->addWidget(browseBtn, 0, 2);
|
topLayout->addWidget(browseBtn, 0, 2);
|
||||||
topLayout->addWidget(imageTitleLabel, 1, 0);
|
topLayout->addWidget(imageTitleLabel, 1, 0);
|
||||||
topLayout->addWidget(imageTitleEdit, 1, 1, 1, 2);
|
topLayout->addWidget(m_imageTitleEdit, 1, 1, 1, 2);
|
||||||
topLayout->setColumnStretch(0, 0);
|
topLayout->setColumnStretch(0, 0);
|
||||||
topLayout->setColumnStretch(1, 1);
|
topLayout->setColumnStretch(1, 1);
|
||||||
topLayout->setColumnStretch(2, 0);
|
topLayout->setColumnStretch(2, 0);
|
||||||
@ -67,22 +71,25 @@ void VInsertImageDialog::setupUI()
|
|||||||
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
|
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
setWindowTitle(title);
|
setWindowTitle(title);
|
||||||
|
|
||||||
imageTitleEdit->setFocus();
|
m_imageTitleEdit->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VInsertImageDialog::enableOkButton()
|
void VInsertImageDialog::enableOkButton()
|
||||||
{
|
{
|
||||||
bool enabled = true;
|
QString title = m_imageTitleEdit->getEvaluatedText();
|
||||||
if (imageTitleEdit->text().isEmpty() || !image) {
|
bool titleOk = !title.isEmpty();
|
||||||
enabled = false;
|
if (titleOk) {
|
||||||
|
QRegExp reg(VUtils::c_imageTitleRegExp);
|
||||||
|
titleOk = reg.exactMatch(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
|
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
|
||||||
okBtn->setEnabled(enabled);
|
okBtn->setEnabled(titleOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VInsertImageDialog::getImageTitleInput() const
|
QString VInsertImageDialog::getImageTitleInput() const
|
||||||
{
|
{
|
||||||
return imageTitleEdit->text();
|
return m_imageTitleEdit->getEvaluatedText();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VInsertImageDialog::getPathInput() const
|
QString VInsertImageDialog::getPathInput() const
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
|
class VLineEdit;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ private:
|
|||||||
void setupUI();
|
void setupUI();
|
||||||
|
|
||||||
QLabel *imageTitleLabel;
|
QLabel *imageTitleLabel;
|
||||||
QLineEdit *imageTitleEdit;
|
VLineEdit *m_imageTitleEdit;
|
||||||
QLabel *pathLabel;
|
QLabel *pathLabel;
|
||||||
QLineEdit *pathEdit;
|
QLineEdit *pathEdit;
|
||||||
QPushButton *browseBtn;
|
QPushButton *browseBtn;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#include "vnewdirdialog.h"
|
#include "vnewdirdialog.h"
|
||||||
#include "vdirectory.h"
|
#include "vdirectory.h"
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
|
#include "vlineedit.h"
|
||||||
|
#include "utils/vutils.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ VNewDirDialog::VNewDirDialog(const QString &title,
|
|||||||
{
|
{
|
||||||
setupUI();
|
setupUI();
|
||||||
|
|
||||||
connect(nameEdit, &QLineEdit::textChanged, this, &VNewDirDialog::handleInputChanged);
|
connect(m_nameEdit, &QLineEdit::textChanged, this, &VNewDirDialog::handleInputChanged);
|
||||||
|
|
||||||
handleInputChanged();
|
handleInputChanged();
|
||||||
}
|
}
|
||||||
@ -29,9 +31,12 @@ void VNewDirDialog::setupUI()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QLabel *nameLabel = new QLabel(tr("Folder &name:"));
|
QLabel *nameLabel = new QLabel(tr("Folder &name:"));
|
||||||
nameEdit = new QLineEdit(defaultName);
|
m_nameEdit = new VLineEdit(defaultName);
|
||||||
nameEdit->selectAll();
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
||||||
nameLabel->setBuddy(nameEdit);
|
m_nameEdit);
|
||||||
|
m_nameEdit->setValidator(validator);
|
||||||
|
m_nameEdit->selectAll();
|
||||||
|
nameLabel->setBuddy(m_nameEdit);
|
||||||
|
|
||||||
m_warnLabel = new QLabel();
|
m_warnLabel = new QLabel();
|
||||||
m_warnLabel->setWordWrap(true);
|
m_warnLabel->setWordWrap(true);
|
||||||
@ -44,10 +49,10 @@ void VNewDirDialog::setupUI()
|
|||||||
|
|
||||||
QHBoxLayout *topLayout = new QHBoxLayout();
|
QHBoxLayout *topLayout = new QHBoxLayout();
|
||||||
topLayout->addWidget(nameLabel);
|
topLayout->addWidget(nameLabel);
|
||||||
topLayout->addWidget(nameEdit);
|
topLayout->addWidget(m_nameEdit);
|
||||||
|
|
||||||
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
|
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
|
||||||
nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
|
m_nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout();
|
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||||
if (infoLabel) {
|
if (infoLabel) {
|
||||||
@ -64,18 +69,34 @@ void VNewDirDialog::setupUI()
|
|||||||
void VNewDirDialog::handleInputChanged()
|
void VNewDirDialog::handleInputChanged()
|
||||||
{
|
{
|
||||||
bool showWarnLabel = false;
|
bool showWarnLabel = false;
|
||||||
QString name = nameEdit->text();
|
QString name = m_nameEdit->getEvaluatedText();
|
||||||
bool nameOk = !name.isEmpty();
|
bool nameOk = !name.isEmpty();
|
||||||
if (nameOk) {
|
if (nameOk) {
|
||||||
// Check if the name conflicts with existing directory name.
|
// Check if the name conflicts with existing directory name.
|
||||||
// Case-insensitive when creating folder.
|
// Case-insensitive when creating folder.
|
||||||
|
QString warnText;
|
||||||
if (m_directory->findSubDirectory(name, false)) {
|
if (m_directory->findSubDirectory(name, false)) {
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name (case-insensitive) <span style=\"%2\">%3</span> already exists. "
|
||||||
|
"Please choose another name.")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
} else if (!VUtils::checkFileNameLegal(name)) {
|
||||||
|
// Check if evaluated name contains illegal characters.
|
||||||
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name <span style=\"%2\">%3</span> contains illegal characters "
|
||||||
|
"(after magic word evaluation).")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nameOk) {
|
||||||
showWarnLabel = true;
|
showWarnLabel = true;
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
m_warnLabel->setText(warnText);
|
||||||
"Please choose another name.")
|
|
||||||
.arg(g_config->c_warningTextStyle);
|
|
||||||
m_warnLabel->setText(nameConflictText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,5 +108,5 @@ void VNewDirDialog::handleInputChanged()
|
|||||||
|
|
||||||
QString VNewDirDialog::getNameInput() const
|
QString VNewDirDialog::getNameInput() const
|
||||||
{
|
{
|
||||||
return nameEdit->text();
|
return m_nameEdit->getEvaluatedText();
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class VLineEdit;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
class QString;
|
class QString;
|
||||||
class VDirectory;
|
class VDirectory;
|
||||||
@ -27,7 +27,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
|
|
||||||
QLineEdit *nameEdit;
|
VLineEdit *m_nameEdit;
|
||||||
QDialogButtonBox *m_btnBox;
|
QDialogButtonBox *m_btnBox;
|
||||||
|
|
||||||
QLabel *m_warnLabel;
|
QLabel *m_warnLabel;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#include "vnewfiledialog.h"
|
#include "vnewfiledialog.h"
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
#include "vdirectory.h"
|
#include "vdirectory.h"
|
||||||
|
#include "vlineedit.h"
|
||||||
|
#include "utils/vutils.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
@ -13,7 +15,7 @@ VNewFileDialog::VNewFileDialog(const QString &title, const QString &info,
|
|||||||
{
|
{
|
||||||
setupUI();
|
setupUI();
|
||||||
|
|
||||||
connect(nameEdit, &QLineEdit::textChanged, this, &VNewFileDialog::handleInputChanged);
|
connect(m_nameEdit, &VLineEdit::textChanged, this, &VNewFileDialog::handleInputChanged);
|
||||||
|
|
||||||
handleInputChanged();
|
handleInputChanged();
|
||||||
}
|
}
|
||||||
@ -27,10 +29,13 @@ void VNewFileDialog::setupUI()
|
|||||||
|
|
||||||
// Name.
|
// Name.
|
||||||
QLabel *nameLabel = new QLabel(tr("Note &name:"));
|
QLabel *nameLabel = new QLabel(tr("Note &name:"));
|
||||||
nameEdit = new QLineEdit(defaultName);
|
m_nameEdit = new VLineEdit(defaultName);
|
||||||
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
||||||
|
m_nameEdit);
|
||||||
|
m_nameEdit->setValidator(validator);
|
||||||
int dotIndex = defaultName.lastIndexOf('.');
|
int dotIndex = defaultName.lastIndexOf('.');
|
||||||
nameEdit->setSelection(0, (dotIndex == -1) ? defaultName.size() : dotIndex);
|
m_nameEdit->setSelection(0, (dotIndex == -1) ? defaultName.size() : dotIndex);
|
||||||
nameLabel->setBuddy(nameEdit);
|
nameLabel->setBuddy(m_nameEdit);
|
||||||
|
|
||||||
// InsertTitle.
|
// InsertTitle.
|
||||||
m_insertTitleCB = new QCheckBox(tr("Insert note name as title (for Markdown only)"));
|
m_insertTitleCB = new QCheckBox(tr("Insert note name as title (for Markdown only)"));
|
||||||
@ -42,10 +47,10 @@ void VNewFileDialog::setupUI()
|
|||||||
});
|
});
|
||||||
|
|
||||||
QFormLayout *topLayout = new QFormLayout();
|
QFormLayout *topLayout = new QFormLayout();
|
||||||
topLayout->addRow(nameLabel, nameEdit);
|
topLayout->addRow(nameLabel, m_nameEdit);
|
||||||
topLayout->addWidget(m_insertTitleCB);
|
topLayout->addWidget(m_insertTitleCB);
|
||||||
|
|
||||||
nameEdit->setMinimumWidth(m_insertTitleCB->sizeHint().width());
|
m_nameEdit->setMinimumWidth(m_insertTitleCB->sizeHint().width());
|
||||||
|
|
||||||
m_warnLabel = new QLabel();
|
m_warnLabel = new QLabel();
|
||||||
m_warnLabel->setWordWrap(true);
|
m_warnLabel->setWordWrap(true);
|
||||||
@ -73,18 +78,34 @@ void VNewFileDialog::setupUI()
|
|||||||
void VNewFileDialog::handleInputChanged()
|
void VNewFileDialog::handleInputChanged()
|
||||||
{
|
{
|
||||||
bool showWarnLabel = false;
|
bool showWarnLabel = false;
|
||||||
QString name = nameEdit->text();
|
QString name = m_nameEdit->getEvaluatedText();
|
||||||
bool nameOk = !name.isEmpty();
|
bool nameOk = !name.isEmpty();
|
||||||
if (nameOk) {
|
if (nameOk) {
|
||||||
// Check if the name conflicts with existing note name.
|
// Check if the name conflicts with existing note name.
|
||||||
// Case-insensitive when creating note.
|
// Case-insensitive when creating note.
|
||||||
|
QString warnText;
|
||||||
if (m_directory->findFile(name, false)) {
|
if (m_directory->findFile(name, false)) {
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name (case-insensitive) <span style=\"%2\">%3</span> already exists. "
|
||||||
|
"Please choose another name.")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
} else if (!VUtils::checkFileNameLegal(name)) {
|
||||||
|
// Check if evaluated name contains illegal characters.
|
||||||
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name <span style=\"%2\">%3</span> contains illegal characters "
|
||||||
|
"(after magic word evaluation).")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nameOk) {
|
||||||
showWarnLabel = true;
|
showWarnLabel = true;
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
m_warnLabel->setText(warnText);
|
||||||
"Please choose another name.")
|
|
||||||
.arg(g_config->c_warningTextStyle);
|
|
||||||
m_warnLabel->setText(nameConflictText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +117,7 @@ void VNewFileDialog::handleInputChanged()
|
|||||||
|
|
||||||
QString VNewFileDialog::getNameInput() const
|
QString VNewFileDialog::getNameInput() const
|
||||||
{
|
{
|
||||||
return nameEdit->text();
|
return m_nameEdit->getEvaluatedText();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VNewFileDialog::getInsertTitleInput() const
|
bool VNewFileDialog::getInsertTitleInput() const
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class VLineEdit;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class VDirectory;
|
class VDirectory;
|
||||||
@ -27,7 +27,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
|
|
||||||
QLineEdit *nameEdit;
|
VLineEdit *m_nameEdit;
|
||||||
QCheckBox *m_insertTitleCB;
|
QCheckBox *m_insertTitleCB;
|
||||||
|
|
||||||
QPushButton *okBtn;
|
QPushButton *okBtn;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
#include "vnotebook.h"
|
#include "vnotebook.h"
|
||||||
|
#include "vlineedit.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ VNewNotebookDialog::VNewNotebookDialog(const QString &title, const QString &info
|
|||||||
{
|
{
|
||||||
setupUI(title, info);
|
setupUI(title, info);
|
||||||
|
|
||||||
connect(nameEdit, &QLineEdit::textChanged, this, &VNewNotebookDialog::handleInputChanged);
|
connect(m_nameEdit, &QLineEdit::textChanged, this, &VNewNotebookDialog::handleInputChanged);
|
||||||
connect(pathEdit, &QLineEdit::textChanged, this, &VNewNotebookDialog::handleInputChanged);
|
connect(pathEdit, &QLineEdit::textChanged, this, &VNewNotebookDialog::handleInputChanged);
|
||||||
connect(browseBtn, &QPushButton::clicked, this, &VNewNotebookDialog::handleBrowseBtnClicked);
|
connect(browseBtn, &QPushButton::clicked, this, &VNewNotebookDialog::handleBrowseBtnClicked);
|
||||||
|
|
||||||
@ -34,8 +35,11 @@ void VNewNotebookDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QLabel *nameLabel = new QLabel(tr("Notebook &name:"));
|
QLabel *nameLabel = new QLabel(tr("Notebook &name:"));
|
||||||
nameEdit = new QLineEdit(defaultName);
|
m_nameEdit = new VLineEdit(defaultName);
|
||||||
nameLabel->setBuddy(nameEdit);
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
||||||
|
m_nameEdit);
|
||||||
|
m_nameEdit->setValidator(validator);
|
||||||
|
nameLabel->setBuddy(m_nameEdit);
|
||||||
|
|
||||||
QLabel *pathLabel = new QLabel(tr("Notebook &root folder:"));
|
QLabel *pathLabel = new QLabel(tr("Notebook &root folder:"));
|
||||||
pathEdit = new QLineEdit(defaultPath);
|
pathEdit = new QLineEdit(defaultPath);
|
||||||
@ -50,7 +54,7 @@ void VNewNotebookDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
m_imageFolderEdit->setToolTip(tr("Set the name of the folder to hold images of all the notes in this notebook "
|
m_imageFolderEdit->setToolTip(tr("Set the name of the folder to hold images of all the notes in this notebook "
|
||||||
"(empty to use global configuration)"));
|
"(empty to use global configuration)"));
|
||||||
imageFolderLabel->setToolTip(m_imageFolderEdit->toolTip());
|
imageFolderLabel->setToolTip(m_imageFolderEdit->toolTip());
|
||||||
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit);
|
validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit);
|
||||||
m_imageFolderEdit->setValidator(validator);
|
m_imageFolderEdit->setValidator(validator);
|
||||||
|
|
||||||
QLabel *attachmentFolderLabel = new QLabel(tr("&Attachment folder:"));
|
QLabel *attachmentFolderLabel = new QLabel(tr("&Attachment folder:"));
|
||||||
@ -66,7 +70,7 @@ void VNewNotebookDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
|
|
||||||
QGridLayout *topLayout = new QGridLayout();
|
QGridLayout *topLayout = new QGridLayout();
|
||||||
topLayout->addWidget(nameLabel, 0, 0);
|
topLayout->addWidget(nameLabel, 0, 0);
|
||||||
topLayout->addWidget(nameEdit, 0, 1, 1, 2);
|
topLayout->addWidget(m_nameEdit, 0, 1, 1, 2);
|
||||||
topLayout->addWidget(pathLabel, 1, 0);
|
topLayout->addWidget(pathLabel, 1, 0);
|
||||||
topLayout->addWidget(pathEdit, 1, 1);
|
topLayout->addWidget(pathEdit, 1, 1);
|
||||||
topLayout->addWidget(browseBtn, 1, 2);
|
topLayout->addWidget(browseBtn, 1, 2);
|
||||||
@ -104,7 +108,7 @@ void VNewNotebookDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
|
|
||||||
QString VNewNotebookDialog::getNameInput() const
|
QString VNewNotebookDialog::getNameInput() const
|
||||||
{
|
{
|
||||||
return nameEdit->text();
|
return m_nameEdit->getEvaluatedText();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VNewNotebookDialog::getPathInput() const
|
QString VNewNotebookDialog::getPathInput() const
|
||||||
@ -161,7 +165,7 @@ bool VNewNotebookDialog::isImportExistingNotebook() const
|
|||||||
|
|
||||||
void VNewNotebookDialog::showEvent(QShowEvent *event)
|
void VNewNotebookDialog::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
nameEdit->setFocus();
|
m_nameEdit->setFocus();
|
||||||
QDialog::showEvent(event);
|
QDialog::showEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +187,7 @@ void VNewNotebookDialog::handleInputChanged()
|
|||||||
m_manualPath = true;
|
m_manualPath = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameEdit->isModified()) {
|
if (m_nameEdit->isModified()) {
|
||||||
m_manualName = true;
|
m_manualName = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +252,7 @@ void VNewNotebookDialog::handleInputChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString name = nameEdit->text();
|
QString name = m_nameEdit->getEvaluatedText();
|
||||||
bool nameOk = !name.isEmpty();
|
bool nameOk = !name.isEmpty();
|
||||||
if (pathOk && nameOk) {
|
if (pathOk && nameOk) {
|
||||||
// Check if the name conflicts with existing notebook name.
|
// Check if the name conflicts with existing notebook name.
|
||||||
@ -260,13 +264,29 @@ void VNewNotebookDialog::handleInputChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString warnText;
|
||||||
if (idx < m_notebooks.size()) {
|
if (idx < m_notebooks.size()) {
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name (case-insensitive) <span style=\"%2\">%3</span> already exists. "
|
||||||
|
"Please choose another name.")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
} else if (!VUtils::checkFileNameLegal(name)) {
|
||||||
|
// Check if evaluated name contains illegal characters.
|
||||||
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name <span style=\"%2\">%3</span> contains illegal characters "
|
||||||
|
"(after magic word evaluation).")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nameOk) {
|
||||||
showWarnLabel = true;
|
showWarnLabel = true;
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
m_warnLabel->setText(warnText);
|
||||||
"Please choose another name.")
|
|
||||||
.arg(g_config->c_warningTextStyle);
|
|
||||||
m_warnLabel->setText(nameConflictText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +301,8 @@ void VNewNotebookDialog::handleInputChanged()
|
|||||||
|
|
||||||
bool VNewNotebookDialog::autoComplete()
|
bool VNewNotebookDialog::autoComplete()
|
||||||
{
|
{
|
||||||
|
QString nameText = m_nameEdit->getEvaluatedText();
|
||||||
|
|
||||||
if (m_manualPath) {
|
if (m_manualPath) {
|
||||||
if (m_manualName) {
|
if (m_manualName) {
|
||||||
return false;
|
return false;
|
||||||
@ -290,8 +312,8 @@ bool VNewNotebookDialog::autoComplete()
|
|||||||
QString pathText = pathEdit->text();
|
QString pathText = pathEdit->text();
|
||||||
if (!pathText.isEmpty()) {
|
if (!pathText.isEmpty()) {
|
||||||
QString autoName = VUtils::directoryNameFromPath(pathText);
|
QString autoName = VUtils::directoryNameFromPath(pathText);
|
||||||
if (autoName != nameEdit->text()) {
|
if (autoName != nameText) {
|
||||||
nameEdit->setText(autoName);
|
m_nameEdit->setText(autoName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,7 +329,6 @@ bool VNewNotebookDialog::autoComplete()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
QString nameText = nameEdit->text();
|
|
||||||
if (nameText.isEmpty()) {
|
if (nameText.isEmpty()) {
|
||||||
if (m_manualName) {
|
if (m_manualName) {
|
||||||
return false;
|
return false;
|
||||||
@ -316,7 +337,7 @@ bool VNewNotebookDialog::autoComplete()
|
|||||||
// Get a folder name under vnoteFolder and set it as the name of the notebook.
|
// Get a folder name under vnoteFolder and set it as the name of the notebook.
|
||||||
QString name = "vnotebook";
|
QString name = "vnotebook";
|
||||||
name = VUtils::getDirNameWithSequence(vnoteFolder, name);
|
name = VUtils::getDirNameWithSequence(vnoteFolder, name);
|
||||||
nameEdit->setText(name);
|
m_nameEdit->setText(name);
|
||||||
ret = true;
|
ret = true;
|
||||||
} else {
|
} else {
|
||||||
// Use the name as the folder name under vnoteFolder.
|
// Use the name as the folder name under vnoteFolder.
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
|
class VLineEdit;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
class VNotebook;
|
class VNotebook;
|
||||||
@ -52,7 +53,7 @@ private:
|
|||||||
// Returns true if name or path is modified.
|
// Returns true if name or path is modified.
|
||||||
bool autoComplete();
|
bool autoComplete();
|
||||||
|
|
||||||
QLineEdit *nameEdit;
|
VLineEdit *m_nameEdit;
|
||||||
QLineEdit *pathEdit;
|
QLineEdit *pathEdit;
|
||||||
QPushButton *browseBtn;
|
QPushButton *browseBtn;
|
||||||
QLabel *m_warnLabel;
|
QLabel *m_warnLabel;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "vnotebook.h"
|
#include "vnotebook.h"
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
|
#include "vlineedit.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
@ -29,7 +30,10 @@ void VNotebookInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
infoLabel = new QLabel(p_info);
|
infoLabel = new QLabel(p_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nameEdit = new QLineEdit(m_notebook->getName());
|
m_nameEdit = new VLineEdit(m_notebook->getName());
|
||||||
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
||||||
|
m_nameEdit);
|
||||||
|
m_nameEdit->setValidator(validator);
|
||||||
m_nameEdit->selectAll();
|
m_nameEdit->selectAll();
|
||||||
|
|
||||||
m_pathEdit = new QLineEdit(m_notebook->getPath());
|
m_pathEdit = new QLineEdit(m_notebook->getPath());
|
||||||
@ -41,7 +45,7 @@ void VNotebookInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
.arg(g_config->getImageFolder()));
|
.arg(g_config->getImageFolder()));
|
||||||
m_imageFolderEdit->setToolTip(tr("Set the name of the folder to hold images of all the notes in this notebook "
|
m_imageFolderEdit->setToolTip(tr("Set the name of the folder to hold images of all the notes in this notebook "
|
||||||
"(empty to use global configuration)"));
|
"(empty to use global configuration)"));
|
||||||
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit);
|
validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit);
|
||||||
m_imageFolderEdit->setValidator(validator);
|
m_imageFolderEdit->setValidator(validator);
|
||||||
|
|
||||||
// Attachment folder.
|
// Attachment folder.
|
||||||
@ -98,7 +102,7 @@ void VNotebookInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
|
|
||||||
void VNotebookInfoDialog::handleInputChanged()
|
void VNotebookInfoDialog::handleInputChanged()
|
||||||
{
|
{
|
||||||
QString name = m_nameEdit->text();
|
QString name = m_nameEdit->getEvaluatedText();
|
||||||
bool nameOk = !name.isEmpty();
|
bool nameOk = !name.isEmpty();
|
||||||
bool showWarnLabel = false;
|
bool showWarnLabel = false;
|
||||||
|
|
||||||
@ -112,13 +116,29 @@ void VNotebookInfoDialog::handleInputChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString warnText;
|
||||||
if (idx < m_notebooks.size() && m_notebooks[idx] != m_notebook) {
|
if (idx < m_notebooks.size() && m_notebooks[idx] != m_notebook) {
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name (case-insensitive) <span style=\"%2\">%3</span> already exists. "
|
||||||
|
"Please choose another name.")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
} else if (!VUtils::checkFileNameLegal(name)) {
|
||||||
|
// Check if evaluated name contains illegal characters.
|
||||||
|
nameOk = false;
|
||||||
|
warnText = tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"Name <span style=\"%2\">%3</span> contains illegal characters "
|
||||||
|
"(after magic word evaluation).")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nameOk) {
|
||||||
showWarnLabel = true;
|
showWarnLabel = true;
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
m_warnLabel->setText(warnText);
|
||||||
"Please choose another name.")
|
|
||||||
.arg(g_config->c_warningTextStyle);
|
|
||||||
m_warnLabel->setText(nameConflictText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +150,7 @@ void VNotebookInfoDialog::handleInputChanged()
|
|||||||
|
|
||||||
QString VNotebookInfoDialog::getName() const
|
QString VNotebookInfoDialog::getName() const
|
||||||
{
|
{
|
||||||
return m_nameEdit->text();
|
return m_nameEdit->getEvaluatedText();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VNotebookInfoDialog::getImageFolder() const
|
QString VNotebookInfoDialog::getImageFolder() const
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
|
class VLineEdit;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
class QString;
|
class QString;
|
||||||
class VNotebook;
|
class VNotebook;
|
||||||
@ -38,7 +39,7 @@ private:
|
|||||||
|
|
||||||
const VNotebook *m_notebook;
|
const VNotebook *m_notebook;
|
||||||
|
|
||||||
QLineEdit *m_nameEdit;
|
VLineEdit *m_nameEdit;
|
||||||
QLineEdit *m_pathEdit;
|
QLineEdit *m_pathEdit;
|
||||||
QLineEdit *m_imageFolderEdit;
|
QLineEdit *m_imageFolderEdit;
|
||||||
// Read-only.
|
// Read-only.
|
||||||
|
@ -25,7 +25,6 @@ void VOrphanFileInfoDialog::setupUI()
|
|||||||
QLabel *fileLabel = new QLabel(m_file->fetchPath());
|
QLabel *fileLabel = new QLabel(m_file->fetchPath());
|
||||||
topLayout->addRow(tr("File:"), fileLabel);
|
topLayout->addRow(tr("File:"), fileLabel);
|
||||||
|
|
||||||
QLabel *imageFolderLabel = new QLabel(tr("Image folder:"));
|
|
||||||
m_imageFolderEdit = new QLineEdit(m_file->getImageFolder());
|
m_imageFolderEdit = new QLineEdit(m_file->getImageFolder());
|
||||||
m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)")
|
m_imageFolderEdit->setPlaceholderText(tr("Use global configuration (%1)")
|
||||||
.arg(g_config->getImageFolderExt()));
|
.arg(g_config->getImageFolderExt()));
|
||||||
@ -33,9 +32,8 @@ void VOrphanFileInfoDialog::setupUI()
|
|||||||
"of this file.\nIf absolute path is used, "
|
"of this file.\nIf absolute path is used, "
|
||||||
"VNote will not manage those images."
|
"VNote will not manage those images."
|
||||||
"(empty to use global configuration)");
|
"(empty to use global configuration)");
|
||||||
imageFolderLabel->setToolTip(imgFolderTip);
|
|
||||||
m_imageFolderEdit->setToolTip(imgFolderTip);
|
m_imageFolderEdit->setToolTip(imgFolderTip);
|
||||||
topLayout->addRow(imageFolderLabel, m_imageFolderEdit);
|
topLayout->addRow(tr("&Image folder:"), 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);
|
||||||
|
@ -78,7 +78,9 @@ SOURCES += main.cpp\
|
|||||||
vattachmentlist.cpp \
|
vattachmentlist.cpp \
|
||||||
dialog/vsortdialog.cpp \
|
dialog/vsortdialog.cpp \
|
||||||
vfilesessioninfo.cpp \
|
vfilesessioninfo.cpp \
|
||||||
vtableofcontent.cpp
|
vtableofcontent.cpp \
|
||||||
|
utils/vmetawordmanager.cpp \
|
||||||
|
vlineedit.cpp
|
||||||
|
|
||||||
HEADERS += vmainwindow.h \
|
HEADERS += vmainwindow.h \
|
||||||
vdirectorytree.h \
|
vdirectorytree.h \
|
||||||
@ -144,7 +146,9 @@ HEADERS += vmainwindow.h \
|
|||||||
vattachmentlist.h \
|
vattachmentlist.h \
|
||||||
dialog/vsortdialog.h \
|
dialog/vsortdialog.h \
|
||||||
vfilesessioninfo.h \
|
vfilesessioninfo.h \
|
||||||
vtableofcontent.h
|
vtableofcontent.h \
|
||||||
|
utils/vmetawordmanager.h \
|
||||||
|
vlineedit.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
vnote.qrc \
|
vnote.qrc \
|
||||||
|
593
src/utils/vmetawordmanager.cpp
Normal file
593
src/utils/vmetawordmanager.cpp
Normal file
@ -0,0 +1,593 @@
|
|||||||
|
#include "vmetawordmanager.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QToolTip>
|
||||||
|
|
||||||
|
#include "vconfigmanager.h"
|
||||||
|
|
||||||
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
|
|
||||||
|
// Used as the function template for some date/time related meta words.
|
||||||
|
static QString formattedDateTime(const VMetaWord *p_metaWord,
|
||||||
|
const QString &p_format)
|
||||||
|
{
|
||||||
|
return p_metaWord->getManager()->getDateTime().toString(p_format);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString allMetaWordsInfo(const VMetaWord *p_metaWord)
|
||||||
|
{
|
||||||
|
QString msg = QObject::tr("All magic words:");
|
||||||
|
|
||||||
|
const VMetaWordManager *mgr = p_metaWord->getManager();
|
||||||
|
QList<QString> keys = mgr->getAllMetaWords().keys();
|
||||||
|
keys.sort(Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
for (auto const & key : keys) {
|
||||||
|
const VMetaWord *word = mgr->findMetaWord(key);
|
||||||
|
Q_ASSERT(word);
|
||||||
|
msg += QString("\n%1:\t%2").arg(word->getWord()).arg(word->getDefinition());
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *focusWid = QApplication::focusWidget();
|
||||||
|
if (focusWid) {
|
||||||
|
QPoint pos = focusWid->mapToGlobal(QPoint(0, focusWid->height()));
|
||||||
|
QToolTip::showText(pos, msg, focusWid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just return the same word.
|
||||||
|
return QString("%1help%1").arg(VMetaWordManager::c_delimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QChar VMetaWordManager::c_delimiter = '%';
|
||||||
|
|
||||||
|
VMetaWordManager::VMetaWordManager(QObject *p_parent)
|
||||||
|
: QObject(p_parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMetaWordManager::init()
|
||||||
|
{
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
// %d%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"d",
|
||||||
|
tr("the day as number without a leading zero (`1` to `31`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "d"));
|
||||||
|
|
||||||
|
// %dd%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"dd",
|
||||||
|
tr("the day as number with a leading zero (`01` to `31`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "dd"));
|
||||||
|
|
||||||
|
// %ddd%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"ddd",
|
||||||
|
tr("the abbreviated localized day name (e.g. `Mon` to `Sun`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "ddd"));
|
||||||
|
|
||||||
|
// %dddd%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"dddd",
|
||||||
|
tr("the long localized day name (e.g. `Monday` to `Sunday`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "dddd"));
|
||||||
|
|
||||||
|
// %M%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"M",
|
||||||
|
tr("the month as number without a leading zero (`1` to `12`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "M"));
|
||||||
|
|
||||||
|
// %MM%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"MM",
|
||||||
|
tr("the month as number with a leading zero (`01` to `12`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "MM"));
|
||||||
|
|
||||||
|
// %MMM%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"MMM",
|
||||||
|
tr("the abbreviated localized month name (e.g. `Jan` to `Dec`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "MMM"));
|
||||||
|
|
||||||
|
// %MMMM%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"MMMM",
|
||||||
|
tr("the long localized month name (e.g. `January` to `December`"),
|
||||||
|
std::bind(formattedDateTime, _1, "MMMM"));
|
||||||
|
|
||||||
|
// %yy%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"yy",
|
||||||
|
tr("the year as two digit number (`00` to `99`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "yy"));
|
||||||
|
|
||||||
|
// %yyyy%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"yyyy",
|
||||||
|
tr("the year as four digit number"),
|
||||||
|
std::bind(formattedDateTime, _1, "yyyy"));
|
||||||
|
|
||||||
|
// %h%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"h",
|
||||||
|
tr("the hour without a leading zero (`0` to `23` or `1` to `12` if AM/PM display"),
|
||||||
|
std::bind(formattedDateTime, _1, "h"));
|
||||||
|
|
||||||
|
// %hh%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"hh",
|
||||||
|
tr("the hour with a leading zero (`00` to `23` or `01` to `12` if AM/PM display"),
|
||||||
|
std::bind(formattedDateTime, _1, "hh"));
|
||||||
|
|
||||||
|
// %H%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"H",
|
||||||
|
tr("the hour without a leading zero (`0` to `23` even with AM/PM display"),
|
||||||
|
std::bind(formattedDateTime, _1, "H"));
|
||||||
|
|
||||||
|
// %HH%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"HH",
|
||||||
|
tr("the hour with a leading zero (`00` to `23` even with AM/PM display"),
|
||||||
|
std::bind(formattedDateTime, _1, "HH"));
|
||||||
|
|
||||||
|
// %m%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"m",
|
||||||
|
tr("the minute without a leading zero (`0` to `59`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "m"));
|
||||||
|
|
||||||
|
// %mm%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"mm",
|
||||||
|
tr("the minute with a leading zero (`00` to `59`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "mm"));
|
||||||
|
|
||||||
|
// %s%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"s",
|
||||||
|
tr("the second without a leading zero (`0` to `59`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "s"));
|
||||||
|
|
||||||
|
// %ss%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"ss",
|
||||||
|
tr("the second with a leading zero (`00` to `59`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "ss"));
|
||||||
|
|
||||||
|
// %z%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"z",
|
||||||
|
tr("the milliseconds without leading zeroes (`0` to `999`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "z"));
|
||||||
|
|
||||||
|
// %zzz%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"zzz",
|
||||||
|
tr("the milliseconds with leading zeroes (`000` to `999`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "zzz"));
|
||||||
|
|
||||||
|
// %AP%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"AP",
|
||||||
|
tr("use AM/PM display (`AM` or `PM`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "AP"));
|
||||||
|
|
||||||
|
// %A%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"A",
|
||||||
|
tr("use AM/PM display (`AM` or `PM`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "A"));
|
||||||
|
|
||||||
|
// %ap%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"ap",
|
||||||
|
tr("use am/pm display (`am` or `pm`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "ap"));
|
||||||
|
|
||||||
|
// %a%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"a",
|
||||||
|
tr("use am/pm display (`am` or `pm`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "a"));
|
||||||
|
|
||||||
|
// %t%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"t",
|
||||||
|
tr("the timezone (e.g. `CEST`)"),
|
||||||
|
std::bind(formattedDateTime, _1, "t"));
|
||||||
|
|
||||||
|
// %random%.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"random",
|
||||||
|
tr("a random number"),
|
||||||
|
[](const VMetaWord *) {
|
||||||
|
return QString::number(qrand());
|
||||||
|
});
|
||||||
|
|
||||||
|
// %random_d%.
|
||||||
|
addMetaWord(MetaWordType::Dynamic,
|
||||||
|
"random_d",
|
||||||
|
tr("dynamic version of `random`"),
|
||||||
|
[](const VMetaWord *) {
|
||||||
|
return QString::number(qrand());
|
||||||
|
});
|
||||||
|
|
||||||
|
// %date%.
|
||||||
|
addMetaWord(MetaWordType::Compound,
|
||||||
|
"date",
|
||||||
|
QString("%1yyyy%1-%1MM%1-%1dd%1").arg(c_delimiter));
|
||||||
|
|
||||||
|
// %da%.
|
||||||
|
addMetaWord(MetaWordType::Compound,
|
||||||
|
"da",
|
||||||
|
QString("%1yyyy%1%1MM%1%1dd%1").arg(c_delimiter));
|
||||||
|
|
||||||
|
// %time%.
|
||||||
|
addMetaWord(MetaWordType::Compound,
|
||||||
|
"time",
|
||||||
|
QString("%1hh%1:%1mm%1:%1ss%1").arg(c_delimiter));
|
||||||
|
|
||||||
|
// %datetime%.
|
||||||
|
addMetaWord(MetaWordType::Compound,
|
||||||
|
"datetime",
|
||||||
|
QString("%1date%1 %1time%1").arg(c_delimiter));
|
||||||
|
|
||||||
|
// Custom meta words.
|
||||||
|
initCustomMetaWords();
|
||||||
|
|
||||||
|
// %help% to print all metaword info.
|
||||||
|
addMetaWord(MetaWordType::FunctionBased,
|
||||||
|
"help",
|
||||||
|
tr("information about all defined magic words"),
|
||||||
|
allMetaWordsInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMetaWordManager::initCustomMetaWords()
|
||||||
|
{
|
||||||
|
QVector<VMagicWord> words = g_config->getCustomMagicWords();
|
||||||
|
for (auto const & item : words) {
|
||||||
|
addMetaWord(MetaWordType::Compound,
|
||||||
|
item.m_name,
|
||||||
|
item.m_definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VMetaWordManager::evaluate(const QString &p_text) const
|
||||||
|
{
|
||||||
|
if (p_text.isEmpty()) {
|
||||||
|
return p_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update datetime for later parse.
|
||||||
|
const_cast<VMetaWordManager *>(this)->m_dateTime = QDateTime::currentDateTime();
|
||||||
|
|
||||||
|
// Treat the text as a Compound meta word.
|
||||||
|
const QString tmpWord("vnote_tmp_metaword");
|
||||||
|
Q_ASSERT(!contains(tmpWord));
|
||||||
|
VMetaWord metaWord(this,
|
||||||
|
MetaWordType::Compound,
|
||||||
|
tmpWord,
|
||||||
|
p_text);
|
||||||
|
if (metaWord.isValid()) {
|
||||||
|
return metaWord.evaluate();
|
||||||
|
} else {
|
||||||
|
return p_text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VMetaWordManager::contains(const QString &p_word) const
|
||||||
|
{
|
||||||
|
return m_metaWords.contains(p_word);
|
||||||
|
}
|
||||||
|
|
||||||
|
const VMetaWord *VMetaWordManager::findMetaWord(const QString &p_word) const
|
||||||
|
{
|
||||||
|
auto it = m_metaWords.find(p_word);
|
||||||
|
if (it != m_metaWords.end()) {
|
||||||
|
return &it.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMetaWordManager::addMetaWord(MetaWordType p_type,
|
||||||
|
const QString &p_word,
|
||||||
|
const QString &p_definition,
|
||||||
|
MetaWordFunc p_function)
|
||||||
|
{
|
||||||
|
if (p_word.isEmpty() || contains(p_word)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VMetaWord metaWord(this,
|
||||||
|
p_type,
|
||||||
|
p_word,
|
||||||
|
p_definition,
|
||||||
|
p_function);
|
||||||
|
|
||||||
|
if (metaWord.isValid()) {
|
||||||
|
m_metaWords.insert(p_word, metaWord);
|
||||||
|
qDebug() << QString("MetaWord %1%2%1[%3] added")
|
||||||
|
.arg(c_delimiter).arg(p_word).arg(p_definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VMetaWord::VMetaWord(const VMetaWordManager *p_manager,
|
||||||
|
MetaWordType p_type,
|
||||||
|
const QString &p_word,
|
||||||
|
const QString &p_definition,
|
||||||
|
MetaWordFunc p_function)
|
||||||
|
: m_manager(p_manager),
|
||||||
|
m_type(p_type),
|
||||||
|
m_word(p_word),
|
||||||
|
m_definition(p_definition),
|
||||||
|
m_valid(false)
|
||||||
|
{
|
||||||
|
m_function = p_function;
|
||||||
|
|
||||||
|
if (checkType(MetaWordType::Simple)
|
||||||
|
|| checkType(MetaWordType::Compound)) {
|
||||||
|
Q_ASSERT(!m_function);
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(m_function);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAndParseDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VMetaWord::checkType(MetaWordType p_type)
|
||||||
|
{
|
||||||
|
return m_type == p_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMetaWord::checkAndParseDefinition()
|
||||||
|
{
|
||||||
|
if (m_word.contains(VMetaWordManager::c_delimiter)) {
|
||||||
|
m_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_valid = true;
|
||||||
|
m_tokens.clear();
|
||||||
|
|
||||||
|
// We do not accept \n and \t in the definition.
|
||||||
|
QRegExp defReg("[\\S ]*");
|
||||||
|
if (!defReg.exactMatch(m_definition)) {
|
||||||
|
m_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkType(MetaWordType::FunctionBased)
|
||||||
|
|| checkType(MetaWordType::Dynamic)) {
|
||||||
|
if (!m_function) {
|
||||||
|
m_valid = false;
|
||||||
|
}
|
||||||
|
} else if (checkType(MetaWordType::Compound)) {
|
||||||
|
m_tokens = parseToTokens(m_definition);
|
||||||
|
if (m_tokens.isEmpty()) {
|
||||||
|
m_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const & to : m_tokens) {
|
||||||
|
if (to.isMetaWord()) {
|
||||||
|
if (!m_manager->contains(to.m_value)) {
|
||||||
|
// Dependency not defined.
|
||||||
|
m_valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VMetaWord::isValid() const
|
||||||
|
{
|
||||||
|
return m_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VMetaWord::evaluate() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_valid);
|
||||||
|
qDebug() << "evaluate meta word" << m_word;
|
||||||
|
switch (m_type) {
|
||||||
|
case MetaWordType::Simple:
|
||||||
|
return m_definition;
|
||||||
|
|
||||||
|
case MetaWordType::FunctionBased:
|
||||||
|
case MetaWordType::Dynamic:
|
||||||
|
return m_function(this);
|
||||||
|
|
||||||
|
case MetaWordType::Compound:
|
||||||
|
{
|
||||||
|
QHash<QString, QString> cache;
|
||||||
|
return evaluateTokens(m_tokens, cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWordType VMetaWord::getType() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &VMetaWord::getWord() const
|
||||||
|
{
|
||||||
|
return m_word;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &VMetaWord::getDefinition() const
|
||||||
|
{
|
||||||
|
return m_definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VMetaWordManager *VMetaWord::getManager() const
|
||||||
|
{
|
||||||
|
return m_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString VMetaWord::toString() const
|
||||||
|
{
|
||||||
|
QChar typeChar('U');
|
||||||
|
switch (m_type) {
|
||||||
|
case MetaWordType::Simple:
|
||||||
|
typeChar = 'S';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaWordType::FunctionBased:
|
||||||
|
typeChar = 'F';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaWordType::Dynamic:
|
||||||
|
typeChar = 'D';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MetaWordType::Compound:
|
||||||
|
typeChar = 'C';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString("%1%2%1[%3]: %4").arg(VMetaWordManager::c_delimiter)
|
||||||
|
.arg(m_word)
|
||||||
|
.arg(typeChar)
|
||||||
|
.arg(m_definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<VMetaWord::Token> VMetaWord::parseToTokens(const QString &p_text)
|
||||||
|
{
|
||||||
|
QVector<Token> tokens;
|
||||||
|
|
||||||
|
TokenType type = TokenType::Raw;
|
||||||
|
QString value;
|
||||||
|
value.reserve(p_text.size());
|
||||||
|
for (int idx = 0; idx < p_text.size(); ++idx) {
|
||||||
|
const QChar &ch = p_text[idx];
|
||||||
|
if (ch == VMetaWordManager::c_delimiter) {
|
||||||
|
// Check if it is single or double.
|
||||||
|
int next = idx + 1;
|
||||||
|
if (next == p_text.size()
|
||||||
|
|| p_text[next] != VMetaWordManager::c_delimiter) {
|
||||||
|
// Single delimiter.
|
||||||
|
if (type == TokenType::Raw) {
|
||||||
|
// End of a raw token, begin of a MetaWord token.
|
||||||
|
if (!value.isEmpty()) {
|
||||||
|
tokens.push_back(Token(type, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
type = TokenType::MetaWord;
|
||||||
|
} else {
|
||||||
|
// End of a MetaWord token, begin of a Raw token.
|
||||||
|
Q_ASSERT(!value.isEmpty());
|
||||||
|
|
||||||
|
tokens.push_back(Token(type, value));
|
||||||
|
type = TokenType::Raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
value.clear();
|
||||||
|
} else {
|
||||||
|
// Double delimiter.
|
||||||
|
// If now is parsing a MetaWord token, treat the first delimiter
|
||||||
|
// as the end of a token.
|
||||||
|
// Otherwise, store one single delimiter in value and skip next char.
|
||||||
|
if (type == TokenType::MetaWord) {
|
||||||
|
Q_ASSERT(!value.isEmpty());
|
||||||
|
tokens.push_back(Token(type, value));
|
||||||
|
type = TokenType::Raw;
|
||||||
|
value.clear();
|
||||||
|
} else {
|
||||||
|
value.push_back(ch);
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Push ch in value.
|
||||||
|
value.push_back(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value.isEmpty()) {
|
||||||
|
if (type == TokenType::Raw) {
|
||||||
|
tokens.push_back(Token(type, value));
|
||||||
|
} else {
|
||||||
|
// An imcomplete metaword token.
|
||||||
|
// Treat it as raw.
|
||||||
|
tokens.push_back(Token(TokenType::Raw, "%" + value));
|
||||||
|
}
|
||||||
|
|
||||||
|
value.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VMetaWord::evaluateTokens(const QVector<VMetaWord::Token> &p_tokens,
|
||||||
|
QHash<QString, QString> &p_cache) const
|
||||||
|
{
|
||||||
|
QString val;
|
||||||
|
|
||||||
|
for (auto const & to : p_tokens) {
|
||||||
|
switch (to.m_type) {
|
||||||
|
case TokenType::Raw:
|
||||||
|
val += to.m_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TokenType::MetaWord:
|
||||||
|
{
|
||||||
|
const VMetaWord *metaWord = m_manager->findMetaWord(to.m_value);
|
||||||
|
if (!metaWord) {
|
||||||
|
// Invalid meta word. Treat it as literal value.
|
||||||
|
val += VMetaWordManager::c_delimiter + to.m_value + VMetaWordManager::c_delimiter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString wordVal;
|
||||||
|
switch (metaWord->getType()) {
|
||||||
|
case MetaWordType::FunctionBased:
|
||||||
|
{
|
||||||
|
auto it = p_cache.find(metaWord->getWord());
|
||||||
|
if (it != p_cache.end()) {
|
||||||
|
// Find it in the cache.
|
||||||
|
wordVal = it.value();
|
||||||
|
} else {
|
||||||
|
// First evaluate this meta word.
|
||||||
|
wordVal = metaWord->evaluate();
|
||||||
|
p_cache.insert(metaWord->getWord(), wordVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MetaWordType::Compound:
|
||||||
|
wordVal = evaluateTokens(metaWord->m_tokens, p_cache);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wordVal = metaWord->evaluate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
val += wordVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
202
src/utils/vmetawordmanager.h
Normal file
202
src/utils/vmetawordmanager.h
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
#ifndef VMETAWORDMANAGER_H
|
||||||
|
#define VMETAWORDMANAGER_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
|
||||||
|
enum class MetaWordType
|
||||||
|
{
|
||||||
|
// Definition is plain text.
|
||||||
|
Simple = 0,
|
||||||
|
|
||||||
|
// Definition is a function call to get the value.
|
||||||
|
FunctionBased,
|
||||||
|
|
||||||
|
// Like FunctionBased, but should re-evaluate the value for each occurence.
|
||||||
|
Dynamic,
|
||||||
|
|
||||||
|
// Consists of other meta words.
|
||||||
|
Compound,
|
||||||
|
|
||||||
|
Invalid
|
||||||
|
};
|
||||||
|
|
||||||
|
// We call meta word "magic word" in user interaction.
|
||||||
|
struct VMagicWord
|
||||||
|
{
|
||||||
|
QString m_name;
|
||||||
|
QString m_definition;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VMetaWordManager;
|
||||||
|
class VMetaWord;
|
||||||
|
|
||||||
|
typedef std::function<QString(const VMetaWord *)> MetaWordFunc;
|
||||||
|
|
||||||
|
// A Meta Word is surrounded by %.
|
||||||
|
// - Use %% for an escaped %;
|
||||||
|
// - Built-in or user-defined;
|
||||||
|
// - A meta word could contain other meta words as definition.
|
||||||
|
class VMetaWord
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VMetaWord(const VMetaWordManager *p_manager,
|
||||||
|
MetaWordType p_type,
|
||||||
|
const QString &p_word,
|
||||||
|
const QString &p_definition,
|
||||||
|
MetaWordFunc p_function = nullptr);
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
|
QString evaluate() const;
|
||||||
|
|
||||||
|
MetaWordType getType() const;
|
||||||
|
|
||||||
|
const QString &getWord() const;
|
||||||
|
|
||||||
|
const QString &getDefinition() const;
|
||||||
|
|
||||||
|
const VMetaWordManager *getManager() const;
|
||||||
|
|
||||||
|
QString toString() const;
|
||||||
|
|
||||||
|
enum class TokenType
|
||||||
|
{
|
||||||
|
Raw = 0,
|
||||||
|
MetaWord
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Token
|
||||||
|
{
|
||||||
|
Token()
|
||||||
|
: m_type(TokenType::Raw)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Token(VMetaWord::TokenType p_type, const QString &p_value)
|
||||||
|
: m_type(p_type),
|
||||||
|
m_value(p_value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString toString() const
|
||||||
|
{
|
||||||
|
return QString("token %1[%2]").arg(m_type == TokenType::Raw
|
||||||
|
? "Raw" : "MetaWord")
|
||||||
|
.arg(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isRaw() const
|
||||||
|
{
|
||||||
|
return m_type == TokenType::Raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMetaWord() const
|
||||||
|
{
|
||||||
|
return m_type == TokenType::MetaWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenType m_type;
|
||||||
|
|
||||||
|
// For Raw type, m_value is the raw string of this token;
|
||||||
|
// For MetaWord type, m_value is the word of the meta word pointed to by
|
||||||
|
// this token.
|
||||||
|
QString m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Check if m_type is @p_type.
|
||||||
|
bool checkType(MetaWordType p_type);
|
||||||
|
|
||||||
|
// Parse children word from definition.
|
||||||
|
// Children word MUST be defined in m_manager already.
|
||||||
|
void checkAndParseDefinition();
|
||||||
|
|
||||||
|
// Parse @p_text to a list of tokens.
|
||||||
|
static QVector<VMetaWord::Token> parseToTokens(const QString &p_text);
|
||||||
|
|
||||||
|
// Used for Compound meta word with cache @p_cache.
|
||||||
|
// @p_cache: value cache for FunctionBased Token.
|
||||||
|
// For a meta word occuring more than once, we should evaluate it once for
|
||||||
|
// FunctionBased meta word.
|
||||||
|
QString evaluateTokens(const QVector<VMetaWord::Token> &p_tokens,
|
||||||
|
QHash<QString, QString> &p_cache) const;
|
||||||
|
|
||||||
|
const VMetaWordManager *m_manager;
|
||||||
|
|
||||||
|
MetaWordType m_type;
|
||||||
|
|
||||||
|
// Word could contains spaces but no %.
|
||||||
|
QString m_word;
|
||||||
|
|
||||||
|
// For Simple/Compound meta word, this contains the definition;
|
||||||
|
// For FunctionBased/Dynamic meta word, this makes no sense and is used
|
||||||
|
// for description.
|
||||||
|
QString m_definition;
|
||||||
|
|
||||||
|
// For FunctionBased and Dynamic meta word.
|
||||||
|
MetaWordFunc m_function;
|
||||||
|
|
||||||
|
bool m_valid;
|
||||||
|
|
||||||
|
// Tokens used for Compound meta word.
|
||||||
|
QVector<Token> m_tokens;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Manager of meta word.
|
||||||
|
class VMetaWordManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit VMetaWordManager(QObject *p_parent = nullptr);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
// Expand meta words in @p_text and return the expanded text.
|
||||||
|
QString evaluate(const QString &p_text) const;
|
||||||
|
|
||||||
|
const VMetaWord *findMetaWord(const QString &p_word) const;
|
||||||
|
|
||||||
|
bool contains(const QString &p_word) const;
|
||||||
|
|
||||||
|
const QDateTime &getDateTime() const;
|
||||||
|
|
||||||
|
const QHash<QString, VMetaWord> &getAllMetaWords() const;
|
||||||
|
|
||||||
|
// % by default.
|
||||||
|
static const QChar c_delimiter;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addMetaWord(MetaWordType p_type,
|
||||||
|
const QString &p_word,
|
||||||
|
const QString &p_definition,
|
||||||
|
MetaWordFunc p_function = nullptr);
|
||||||
|
|
||||||
|
void initCustomMetaWords();
|
||||||
|
|
||||||
|
// Map using word as key.
|
||||||
|
QHash<QString, VMetaWord> m_metaWords;
|
||||||
|
|
||||||
|
// Used for data/time related evaluate.
|
||||||
|
// Will be updated before each evaluation.
|
||||||
|
QDateTime m_dateTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const QDateTime &VMetaWordManager::getDateTime() const
|
||||||
|
{
|
||||||
|
return m_dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const QHash<QString, VMetaWord> &VMetaWordManager::getAllMetaWords() const
|
||||||
|
{
|
||||||
|
return m_metaWords;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // VMETAWORDMANAGER_H
|
@ -33,6 +33,8 @@ QVector<QPair<QString, QString>> VUtils::s_availableLanguages;
|
|||||||
|
|
||||||
const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\]]*)\\]\\(([^\\)\"]+)\\s*(\"(\\\\.|[^\"\\)])*\")?\\s*\\)");
|
const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\]]*)\\]\\(([^\\)\"]+)\\s*(\"(\\\\.|[^\"\\)])*\")?\\s*\\)");
|
||||||
|
|
||||||
|
const QString VUtils::c_imageTitleRegExp = QString("[\\w\\(\\)@#%\\*\\-\\+=\\?<>\\,\\.\\s]+");
|
||||||
|
|
||||||
const QString VUtils::c_fileNameRegExp = QString("[^\\\\/:\\*\\?\"<>\\|]*");
|
const QString VUtils::c_fileNameRegExp = QString("[^\\\\/:\\*\\?\"<>\\|]*");
|
||||||
|
|
||||||
const QString VUtils::c_fencedCodeBlockStartRegExp = QString("^(\\s*)```([^`\\s]*)\\s*[^`]*$");
|
const QString VUtils::c_fencedCodeBlockStartRegExp = QString("^(\\s*)```([^`\\s]*)\\s*[^`]*$");
|
||||||
@ -725,6 +727,16 @@ bool VUtils::checkPathLegal(const QString &p_path)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VUtils::checkFileNameLegal(const QString &p_name)
|
||||||
|
{
|
||||||
|
if (p_name.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegExp exp(c_fileNameRegExp);
|
||||||
|
return exp.exactMatch(p_name);
|
||||||
|
}
|
||||||
|
|
||||||
bool VUtils::equalPath(const QString &p_patha, const QString &p_pathb)
|
bool VUtils::equalPath(const QString &p_patha, const QString &p_pathb)
|
||||||
{
|
{
|
||||||
QString a = QDir::cleanPath(p_patha);
|
QString a = QDir::cleanPath(p_patha);
|
||||||
|
@ -177,6 +177,9 @@ public:
|
|||||||
// Try to check if @p_path is legal.
|
// Try to check if @p_path is legal.
|
||||||
static bool checkPathLegal(const QString &p_path);
|
static bool checkPathLegal(const QString &p_path);
|
||||||
|
|
||||||
|
// Check if file/folder name is legal.
|
||||||
|
static bool checkFileNameLegal(const QString &p_name);
|
||||||
|
|
||||||
// Returns true if @p_patha and @p_pathb points to the same file/directory.
|
// Returns true if @p_patha and @p_pathb points to the same file/directory.
|
||||||
static bool equalPath(const QString &p_patha, const QString &p_pathb);
|
static bool equalPath(const QString &p_patha, const QString &p_pathb);
|
||||||
|
|
||||||
@ -248,6 +251,9 @@ public:
|
|||||||
// 4. Unused;
|
// 4. Unused;
|
||||||
static const QString c_imageLinkRegExp;
|
static const QString c_imageLinkRegExp;
|
||||||
|
|
||||||
|
// Regular expression for image title.
|
||||||
|
static const QString c_imageTitleRegExp;
|
||||||
|
|
||||||
// Regular expression for file/directory name.
|
// Regular expression for file/directory name.
|
||||||
// Forbidden char: \/:*?"<>|
|
// Forbidden char: \/:*?"<>|
|
||||||
static const QString c_fileNameRegExp;
|
static const QString c_fileNameRegExp;
|
||||||
|
@ -5,13 +5,12 @@
|
|||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
#include "vbuttonwithwidget.h"
|
#include "vbuttonwithwidget.h"
|
||||||
#include "vnote.h"
|
|
||||||
#include "vmainwindow.h"
|
#include "vmainwindow.h"
|
||||||
#include "dialog/vconfirmdeletiondialog.h"
|
#include "dialog/vconfirmdeletiondialog.h"
|
||||||
#include "dialog/vsortdialog.h"
|
#include "dialog/vsortdialog.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
extern VNote *g_vnote;
|
extern VMainWindow *g_mainWin;
|
||||||
|
|
||||||
VAttachmentList::VAttachmentList(QWidget *p_parent)
|
VAttachmentList::VAttachmentList(QWidget *p_parent)
|
||||||
: QWidget(p_parent), m_file(NULL)
|
: QWidget(p_parent), m_file(NULL)
|
||||||
@ -53,7 +52,7 @@ void VAttachmentList::setupUI()
|
|||||||
.arg(m_file->fetchAttachmentFolderPath()),
|
.arg(m_file->fetchAttachmentFolderPath()),
|
||||||
QMessageBox::Ok | QMessageBox::Cancel,
|
QMessageBox::Ok | QMessageBox::Cancel,
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
g_vnote->getMainWindow(),
|
g_mainWin,
|
||||||
MessageBoxType::Danger);
|
MessageBoxType::Danger);
|
||||||
if (ret == QMessageBox::Ok) {
|
if (ret == QMessageBox::Ok) {
|
||||||
if (!m_file->deleteAttachments()) {
|
if (!m_file->deleteAttachments()) {
|
||||||
@ -66,7 +65,7 @@ void VAttachmentList::setupUI()
|
|||||||
"maintain the configuration file manually."),
|
"maintain the configuration file manually."),
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
g_vnote->getMainWindow());
|
g_mainWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_attachmentList->clear();
|
m_attachmentList->clear();
|
||||||
@ -204,7 +203,7 @@ void VAttachmentList::addAttachment()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static QString lastPath = QDir::homePath();
|
static QString lastPath = QDir::homePath();
|
||||||
QStringList files = QFileDialog::getOpenFileNames(g_vnote->getMainWindow(),
|
QStringList files = QFileDialog::getOpenFileNames(g_mainWin,
|
||||||
tr("Select Files As Attachments"),
|
tr("Select Files As Attachments"),
|
||||||
lastPath);
|
lastPath);
|
||||||
if (files.isEmpty()) {
|
if (files.isEmpty()) {
|
||||||
@ -236,16 +235,16 @@ void VAttachmentList::addAttachments(const QStringList &p_files)
|
|||||||
"",
|
"",
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
g_vnote->getMainWindow());
|
g_mainWin);
|
||||||
} else {
|
} else {
|
||||||
++addedFiles;
|
++addedFiles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addedFiles > 0) {
|
if (addedFiles > 0) {
|
||||||
g_vnote->getMainWindow()->showStatusMessage(tr("%1 %2 added as attachments")
|
g_mainWin->showStatusMessage(tr("%1 %2 added as attachments")
|
||||||
.arg(addedFiles)
|
.arg(addedFiles)
|
||||||
.arg(addedFiles > 1 ? tr("files") : tr("file")));
|
.arg(addedFiles > 1 ? tr("files") : tr("file")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +329,7 @@ void VAttachmentList::deleteSelectedItems()
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
g_vnote->getMainWindow());
|
g_mainWin);
|
||||||
if (dialog.exec()) {
|
if (dialog.exec()) {
|
||||||
items = dialog.getConfirmedItems();
|
items = dialog.getConfirmedItems();
|
||||||
|
|
||||||
@ -349,7 +348,7 @@ void VAttachmentList::deleteSelectedItems()
|
|||||||
"maintain the configuration file manually."),
|
"maintain the configuration file manually."),
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
g_vnote->getMainWindow());
|
g_mainWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
@ -370,7 +369,7 @@ void VAttachmentList::sortItems()
|
|||||||
"in the configuration file.")
|
"in the configuration file.")
|
||||||
.arg(g_config->c_dataTextStyle)
|
.arg(g_config->c_dataTextStyle)
|
||||||
.arg(m_file->getName()),
|
.arg(m_file->getName()),
|
||||||
g_vnote->getMainWindow());
|
g_mainWin);
|
||||||
QTreeWidget *tree = dialog.getTreeWidget();
|
QTreeWidget *tree = dialog.getTreeWidget();
|
||||||
tree->clear();
|
tree->clear();
|
||||||
tree->setColumnCount(1);
|
tree->setColumnCount(1);
|
||||||
@ -624,7 +623,7 @@ void VAttachmentList::checkAttachments()
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
g_vnote->getMainWindow());
|
g_mainWin);
|
||||||
if (dialog.exec()) {
|
if (dialog.exec()) {
|
||||||
items = dialog.getConfirmedItems();
|
items = dialog.getConfirmedItems();
|
||||||
|
|
||||||
@ -643,7 +642,7 @@ void VAttachmentList::checkAttachments()
|
|||||||
"maintain the configuration file manually."),
|
"maintain the configuration file manually."),
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
g_vnote->getMainWindow());
|
g_mainWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
|
@ -1152,3 +1152,21 @@ void VConfigManager::setLastOpenedFiles(const QVector<VFileSessionInfo> &p_files
|
|||||||
<< "items in [last_opened_files] section";
|
<< "items in [last_opened_files] section";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<VMagicWord> VConfigManager::getCustomMagicWords()
|
||||||
|
{
|
||||||
|
QVector<VMagicWord> words;
|
||||||
|
int size = userSettings->beginReadArray("magic_words");
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
userSettings->setArrayIndex(i);
|
||||||
|
|
||||||
|
VMagicWord word;
|
||||||
|
word.m_name = userSettings->value("name").toString();
|
||||||
|
word.m_definition = userSettings->value("definition").toString();
|
||||||
|
words.push_back(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
userSettings->endArray();
|
||||||
|
|
||||||
|
return words;
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "vmarkdownconverter.h"
|
#include "vmarkdownconverter.h"
|
||||||
#include "vconstants.h"
|
#include "vconstants.h"
|
||||||
#include "vfilesessioninfo.h"
|
#include "vfilesessioninfo.h"
|
||||||
|
#include "utils/vmetawordmanager.h"
|
||||||
|
|
||||||
|
|
||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
@ -326,6 +327,9 @@ public:
|
|||||||
// Write last opened files to [last_opened_files] of session.ini.
|
// Write last opened files to [last_opened_files] of session.ini.
|
||||||
void setLastOpenedFiles(const QVector<VFileSessionInfo> &p_files);
|
void setLastOpenedFiles(const QVector<VFileSessionInfo> &p_files);
|
||||||
|
|
||||||
|
// Read custom magic words from [magic_words] section.
|
||||||
|
QVector<VMagicWord> getCustomMagicWords();
|
||||||
|
|
||||||
// Return the configured key sequence of @p_operation.
|
// Return the configured key sequence of @p_operation.
|
||||||
// Return empty if there is no corresponding config.
|
// Return empty if there is no corresponding config.
|
||||||
QString getShortcutKeySequence(const QString &p_operation) const;
|
QString getShortcutKeySequence(const QString &p_operation) const;
|
||||||
|
@ -12,9 +12,10 @@
|
|||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
extern VNote *g_vnote;
|
extern VNote *g_vnote;
|
||||||
|
|
||||||
VEditArea::VEditArea(VNote *vnote, QWidget *parent)
|
VEditArea::VEditArea(QWidget *parent)
|
||||||
: QWidget(parent), VNavigationMode(),
|
: QWidget(parent),
|
||||||
vnote(vnote), curWindowIndex(-1)
|
VNavigationMode(),
|
||||||
|
curWindowIndex(-1)
|
||||||
{
|
{
|
||||||
setupUI();
|
setupUI();
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ void VEditArea::setupUI()
|
|||||||
|
|
||||||
void VEditArea::insertSplitWindow(int idx)
|
void VEditArea::insertSplitWindow(int idx)
|
||||||
{
|
{
|
||||||
VEditWindow *win = new VEditWindow(vnote, this);
|
VEditWindow *win = new VEditWindow(this);
|
||||||
splitter->insertWidget(idx, win);
|
splitter->insertWidget(idx, win);
|
||||||
connect(win, &VEditWindow::tabStatusUpdated,
|
connect(win, &VEditWindow::tabStatusUpdated,
|
||||||
this, &VEditArea::handleWindowTabStatusUpdated);
|
this, &VEditArea::handleWindowTabStatusUpdated);
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "veditwindow.h"
|
#include "veditwindow.h"
|
||||||
#include "vnavigationmode.h"
|
#include "vnavigationmode.h"
|
||||||
|
|
||||||
class VNote;
|
|
||||||
class VFile;
|
class VFile;
|
||||||
class VDirectory;
|
class VDirectory;
|
||||||
class VFindReplaceDialog;
|
class VFindReplaceDialog;
|
||||||
@ -25,7 +24,7 @@ class VEditArea : public QWidget, public VNavigationMode
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit VEditArea(VNote *vnote, QWidget *parent = 0);
|
explicit VEditArea(QWidget *parent = 0);
|
||||||
|
|
||||||
// Whether @p_file has been opened in edit area.
|
// Whether @p_file has been opened in edit area.
|
||||||
bool isFileOpened(const VFile *p_file);
|
bool isFileOpened(const VFile *p_file);
|
||||||
@ -161,7 +160,6 @@ private:
|
|||||||
// Update status of current window.
|
// Update status of current window.
|
||||||
void updateWindowStatus();
|
void updateWindowStatus();
|
||||||
|
|
||||||
VNote *vnote;
|
|
||||||
int curWindowIndex;
|
int curWindowIndex;
|
||||||
|
|
||||||
// Splitter holding multiple split windows
|
// Splitter holding multiple split windows
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include "veditwindow.h"
|
#include "veditwindow.h"
|
||||||
#include "vedittab.h"
|
#include "vedittab.h"
|
||||||
#include "vnote.h"
|
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
#include "vorphanfile.h"
|
#include "vorphanfile.h"
|
||||||
#include "vmainwindow.h"
|
#include "vmainwindow.h"
|
||||||
@ -13,12 +12,14 @@
|
|||||||
#include "vfilelist.h"
|
#include "vfilelist.h"
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
|
|
||||||
extern VNote *g_vnote;
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
extern VMainWindow *g_mainWin;
|
||||||
|
|
||||||
VEditWindow::VEditWindow(VNote *vnote, VEditArea *editArea, QWidget *parent)
|
VEditWindow::VEditWindow(VEditArea *editArea, QWidget *parent)
|
||||||
: QTabWidget(parent), vnote(vnote), m_editArea(editArea),
|
: QTabWidget(parent),
|
||||||
m_curTabWidget(NULL), m_lastTabWidget(NULL)
|
m_editArea(editArea),
|
||||||
|
m_curTabWidget(NULL),
|
||||||
|
m_lastTabWidget(NULL)
|
||||||
{
|
{
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
initTabActions();
|
initTabActions();
|
||||||
@ -137,9 +138,9 @@ void VEditWindow::initTabActions()
|
|||||||
Q_ASSERT(file);
|
Q_ASSERT(file);
|
||||||
if (file->getType() == FileType::Note) {
|
if (file->getType() == FileType::Note) {
|
||||||
VNoteFile *tmpFile = dynamic_cast<VNoteFile *>((VFile *)file);
|
VNoteFile *tmpFile = dynamic_cast<VNoteFile *>((VFile *)file);
|
||||||
g_vnote->getMainWindow()->getFileList()->fileInfo(tmpFile);
|
g_mainWin->getFileList()->fileInfo(tmpFile);
|
||||||
} else if (file->getType() == FileType::Orphan) {
|
} else if (file->getType() == FileType::Orphan) {
|
||||||
g_vnote->getMainWindow()->editOrphanFileInfo(file);
|
g_mainWin->editOrphanFileInfo(file);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -817,7 +818,7 @@ void VEditWindow::handleLocateAct()
|
|||||||
VEditTab *editor = getTab(tab);
|
VEditTab *editor = getTab(tab);
|
||||||
QPointer<VFile> file = editor->getFile();
|
QPointer<VFile> file = editor->getFile();
|
||||||
if (file->getType() == FileType::Note) {
|
if (file->getType() == FileType::Note) {
|
||||||
vnote->getMainWindow()->locateFile(file);
|
g_mainWin->locateFile(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1022,7 +1023,7 @@ void VEditWindow::dropEvent(QDropEvent *p_event)
|
|||||||
|
|
||||||
if (!files.isEmpty()) {
|
if (!files.isEmpty()) {
|
||||||
focusWindow();
|
focusWindow();
|
||||||
g_vnote->getMainWindow()->openFiles(files);
|
g_mainWin->openFiles(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_event->acceptProposedAction();
|
p_event->acceptProposedAction();
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "vconstants.h"
|
#include "vconstants.h"
|
||||||
#include "vnotefile.h"
|
#include "vnotefile.h"
|
||||||
|
|
||||||
class VNote;
|
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QActionGroup;
|
class QActionGroup;
|
||||||
class VEditArea;
|
class VEditArea;
|
||||||
@ -20,7 +19,7 @@ class VEditWindow : public QTabWidget
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit VEditWindow(VNote *vnote, VEditArea *editArea, QWidget *parent = 0);
|
explicit VEditWindow(VEditArea *editArea, QWidget *parent = 0);
|
||||||
int findTabByFile(const VFile *p_file) const;
|
int findTabByFile(const VFile *p_file) const;
|
||||||
int openFile(VFile *p_file, OpenFileMode p_mode);
|
int openFile(VFile *p_file, OpenFileMode p_mode);
|
||||||
bool closeFile(const VFile *p_file, bool p_forced);
|
bool closeFile(const VFile *p_file, bool p_forced);
|
||||||
@ -160,7 +159,6 @@ private:
|
|||||||
// Connect the signals of VEditTab to this VEditWindow.
|
// Connect the signals of VEditTab to this VEditWindow.
|
||||||
void connectEditTab(const VEditTab *p_tab);
|
void connectEditTab(const VEditTab *p_tab);
|
||||||
|
|
||||||
VNote *vnote;
|
|
||||||
VEditArea *m_editArea;
|
VEditArea *m_editArea;
|
||||||
|
|
||||||
// These two members are only used for alternateTab().
|
// These two members are only used for alternateTab().
|
||||||
|
46
src/vlineedit.cpp
Normal file
46
src/vlineedit.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "vlineedit.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QToolTip>
|
||||||
|
|
||||||
|
#include "utils/vmetawordmanager.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern VMetaWordManager *g_mwMgr;
|
||||||
|
|
||||||
|
VLineEdit::VLineEdit(QWidget *p_parent)
|
||||||
|
: QLineEdit(p_parent)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
VLineEdit::VLineEdit(const QString &p_contents, QWidget *p_parent)
|
||||||
|
: QLineEdit(p_contents, p_parent)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VLineEdit::handleTextChanged(const QString &p_text)
|
||||||
|
{
|
||||||
|
m_evaluatedText = g_mwMgr->evaluate(p_text);
|
||||||
|
qDebug() << "evaluate text:" << m_evaluatedText;
|
||||||
|
|
||||||
|
if (m_evaluatedText == p_text) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display tooltip at bottom-left.
|
||||||
|
QPoint pos = mapToGlobal(QPoint(0, height()));
|
||||||
|
QToolTip::showText(pos, m_evaluatedText, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VLineEdit::init()
|
||||||
|
{
|
||||||
|
connect(this, &QLineEdit::textChanged,
|
||||||
|
this, &VLineEdit::handleTextChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString VLineEdit::getEvaluatedText() const
|
||||||
|
{
|
||||||
|
return m_evaluatedText;
|
||||||
|
}
|
29
src/vlineedit.h
Normal file
29
src/vlineedit.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef VLINEEDIT_H
|
||||||
|
#define VLINEEDIT_H
|
||||||
|
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
|
||||||
|
// QLineEdit with meta word support.
|
||||||
|
class VLineEdit : public QLineEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit VLineEdit(QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
|
VLineEdit(const QString &p_contents, QWidget *p_parent = Q_NULLPTR);
|
||||||
|
|
||||||
|
// Return the evaluated text.
|
||||||
|
const QString getEvaluatedText() const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleTextChanged(const QString &p_text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init();
|
||||||
|
|
||||||
|
// We should keep the evaluated text identical with what's displayed.
|
||||||
|
QString m_evaluatedText;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VLINEEDIT_H
|
@ -45,6 +45,8 @@ VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent)
|
|||||||
: QMainWindow(p_parent), m_guard(p_guard),
|
: QMainWindow(p_parent), m_guard(p_guard),
|
||||||
m_windowOldState(Qt::WindowNoState), m_requestQuit(false)
|
m_windowOldState(Qt::WindowNoState), m_requestQuit(false)
|
||||||
{
|
{
|
||||||
|
qsrand(QDateTime::currentDateTime().toTime_t());
|
||||||
|
|
||||||
setWindowIcon(QIcon(":/resources/icons/vnote.ico"));
|
setWindowIcon(QIcon(":/resources/icons/vnote.ico"));
|
||||||
vnote = new VNote(this);
|
vnote = new VNote(this);
|
||||||
g_vnote = vnote;
|
g_vnote = vnote;
|
||||||
@ -110,7 +112,7 @@ void VMainWindow::setupUI()
|
|||||||
m_fileList = new VFileList();
|
m_fileList = new VFileList();
|
||||||
m_fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
m_fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
||||||
|
|
||||||
editArea = new VEditArea(vnote);
|
editArea = new VEditArea();
|
||||||
editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
m_findReplaceDialog = editArea->getFindReplaceDialog();
|
m_findReplaceDialog = editArea->getFindReplaceDialog();
|
||||||
m_fileList->setEditArea(editArea);
|
m_fileList->setEditArea(editArea);
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
|
// Meta word manager.
|
||||||
|
VMetaWordManager *g_mwMgr;
|
||||||
|
|
||||||
|
|
||||||
QString VNote::s_markdownTemplate;
|
QString VNote::s_markdownTemplate;
|
||||||
QString VNote::s_markdownTemplatePDF;
|
QString VNote::s_markdownTemplatePDF;
|
||||||
|
|
||||||
@ -53,10 +57,15 @@ const QString VNote::c_markdownGuideDocFile_en = ":/resources/docs/markdown_guid
|
|||||||
const QString VNote::c_markdownGuideDocFile_zh = ":/resources/docs/markdown_guide_zh.md";
|
const QString VNote::c_markdownGuideDocFile_zh = ":/resources/docs/markdown_guide_zh.md";
|
||||||
|
|
||||||
VNote::VNote(QObject *parent)
|
VNote::VNote(QObject *parent)
|
||||||
: QObject(parent), m_mainWindow(dynamic_cast<VMainWindow *>(parent))
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
initTemplate();
|
initTemplate();
|
||||||
|
|
||||||
g_config->getNotebooks(m_notebooks, this);
|
g_config->getNotebooks(m_notebooks, this);
|
||||||
|
|
||||||
|
m_metaWordMgr.init();
|
||||||
|
|
||||||
|
g_mwMgr = &m_metaWordMgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNote::initPalette(QPalette palette)
|
void VNote::initPalette(QPalette palette)
|
||||||
|
12
src/vnote.h
12
src/vnote.h
@ -12,11 +12,12 @@
|
|||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include "vnotebook.h"
|
#include "vnotebook.h"
|
||||||
#include "vconstants.h"
|
#include "vconstants.h"
|
||||||
|
#include "utils/vmetawordmanager.h"
|
||||||
|
|
||||||
class VMainWindow;
|
|
||||||
class VOrphanFile;
|
class VOrphanFile;
|
||||||
class VNoteFile;
|
class VNoteFile;
|
||||||
|
|
||||||
|
|
||||||
class VNote : public QObject
|
class VNote : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -74,7 +75,6 @@ public:
|
|||||||
const QVector<QPair<QString, QString> > &getPalette() const;
|
const QVector<QPair<QString, QString> > &getPalette() const;
|
||||||
void initPalette(QPalette palette);
|
void initPalette(QPalette palette);
|
||||||
QString getColorFromPalette(const QString &p_name) const;
|
QString getColorFromPalette(const QString &p_name) const;
|
||||||
VMainWindow *getMainWindow() const;
|
|
||||||
|
|
||||||
QString getNavigationLabelStyle(const QString &p_str) const;
|
QString getNavigationLabelStyle(const QString &p_str) const;
|
||||||
|
|
||||||
@ -106,7 +106,8 @@ private:
|
|||||||
// Maintain all the notebooks. Other holder should use QPointer.
|
// Maintain all the notebooks. Other holder should use QPointer.
|
||||||
QVector<VNotebook *> m_notebooks;
|
QVector<VNotebook *> m_notebooks;
|
||||||
QVector<QPair<QString, QString> > m_palette;
|
QVector<QPair<QString, QString> > m_palette;
|
||||||
VMainWindow *m_mainWindow;
|
|
||||||
|
VMetaWordManager m_metaWordMgr;
|
||||||
|
|
||||||
// Hold all external file: Orphan File.
|
// Hold all external file: Orphan File.
|
||||||
// Need to clean up periodly.
|
// Need to clean up periodly.
|
||||||
@ -118,9 +119,4 @@ inline const QVector<QPair<QString, QString> >& VNote::getPalette() const
|
|||||||
return m_palette;
|
return m_palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VMainWindow *VNote::getMainWindow() const
|
|
||||||
{
|
|
||||||
return m_mainWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // VNOTE_H
|
#endif // VNOTE_H
|
||||||
|
@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
|
||||||
#include "vnote.h"
|
|
||||||
#include "vmainwindow.h"
|
#include "vmainwindow.h"
|
||||||
|
|
||||||
extern VNote *g_vnote;
|
extern VMainWindow *g_mainWin;
|
||||||
|
|
||||||
VPreviewPage::VPreviewPage(QWidget *parent) : QWebEnginePage(parent)
|
VPreviewPage::VPreviewPage(QWidget *parent) : QWebEnginePage(parent)
|
||||||
{
|
{
|
||||||
@ -21,7 +20,7 @@ bool VPreviewPage::acceptNavigationRequest(const QUrl &p_url,
|
|||||||
|
|
||||||
if (p_url.isLocalFile()) {
|
if (p_url.isLocalFile()) {
|
||||||
QString filePath = p_url.toLocalFile();
|
QString filePath = p_url.toLocalFile();
|
||||||
if (g_vnote->getMainWindow()->tryOpenInternalFile(filePath)) {
|
if (g_mainWin->tryOpenInternalFile(filePath)) {
|
||||||
qDebug() << "internal notes jump" << filePath;
|
qDebug() << "internal notes jump" << filePath;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user