more user friendly messages

This commit is contained in:
Le Tan 2017-04-27 19:43:16 +08:00
parent 8899a374a8
commit d0e43db5ad
13 changed files with 157 additions and 38 deletions

View File

@ -1,5 +1,8 @@
#include <QtWidgets>
#include "vdeletenotebookdialog.h"
#include "vconfigmanager.h"
extern VConfigManager vconfig;
VDeleteNotebookDialog::VDeleteNotebookDialog(const QString &p_title, const QString &p_name,
const QString &p_path, QWidget *p_parent)
@ -10,21 +13,26 @@ VDeleteNotebookDialog::VDeleteNotebookDialog(const QString &p_title, const QStri
void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_name)
{
QLabel *infoLabel = new QLabel(tr("Are you sure to delete notebook: %1 ?").arg(p_name));
QLabel *infoLabel = new QLabel(tr("Are you sure to delete notebook <span style=\"%1\">%2</span>?")
.arg(vconfig.c_dataTextStyle).arg(p_name));
m_warningLabel = new QLabel();
m_warningLabel->setWordWrap(true);
m_notDeleteCheck = new QCheckBox(tr("Do not delete files from disk."), this);
m_notDeleteCheck->setChecked(false);
m_notDeleteCheck->setChecked(true);
m_notDeleteCheck->setToolTip(tr("When checked, VNote just removes the notebook instead of deleting files from disk"));
connect(m_notDeleteCheck, &QCheckBox::stateChanged, this, &VDeleteNotebookDialog::notDeleteCheckChanged);
notDeleteCheckChanged(false);
notDeleteCheckChanged(true);
// Ok is the default button.
m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
okBtn->setProperty("DangerBtn", true);
// Standard Warning icon.
QLabel *iconLabel = new QLabel();
QPixmap pixmap = standardIcon(QMessageBox::Warning);
@ -41,8 +49,8 @@ void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_nam
QVBoxLayout *infoLayout = new QVBoxLayout();
infoLayout->addWidget(infoLabel);
infoLayout->addWidget(m_warningLabel);
infoLayout->addWidget(m_notDeleteCheck);
infoLayout->addWidget(m_warningLabel);
QHBoxLayout *topLayout = new QHBoxLayout();
topLayout->addLayout(iconLayout);
@ -99,8 +107,12 @@ QPixmap VDeleteNotebookDialog::standardIcon(QMessageBox::Icon p_icon)
void VDeleteNotebookDialog::notDeleteCheckChanged(int p_state)
{
if (p_state) {
m_warningLabel->setText(tr("VNote won't delete files under this directory: %1 .").arg(m_path));
m_warningLabel->setText(tr("VNote won't delete files under directory <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(m_path));
} else {
m_warningLabel->setText(tr("This will delete any files under this directory: %1 !").arg(m_path));
m_warningLabel->setText(tr("<span style=\"%1\">WARNING</span>: "
"VNote will delete <b>ANY</b> files under directory <span style=\"%2\">%3</span>! "
"It may be UNRECOVERABLE!")
.arg(vconfig.c_warningTextStyle).arg(vconfig.c_dataTextStyle).arg(m_path));
}
}

View File

@ -1,6 +1,9 @@
#include <QtWidgets>
#include <QDir>
#include "vnewnotebookdialog.h"
#include "vconfigmanager.h"
extern VConfigManager vconfig;
VNewNotebookDialog::VNewNotebookDialog(const QString &title, const QString &info,
const QString &defaultName, const QString &defaultPath,
@ -11,7 +14,7 @@ VNewNotebookDialog::VNewNotebookDialog(const QString &title, const QString &info
setupUI();
connect(nameEdit, &QLineEdit::textChanged, this, &VNewNotebookDialog::enableOkButton);
connect(pathEdit, &QLineEdit::textChanged, this, &VNewNotebookDialog::enableOkButton);
connect(pathEdit, &QLineEdit::textChanged, this, &VNewNotebookDialog::handlePathChanged);
connect(browseBtn, &QPushButton::clicked, this, &VNewNotebookDialog::handleBrowseBtnClicked);
enableOkButton();
@ -21,17 +24,18 @@ void VNewNotebookDialog::setupUI()
{
if (!info.isEmpty()) {
infoLabel = new QLabel(info);
infoLabel->setWordWrap(true);
}
nameLabel = new QLabel(tr("Notebook &name:"));
nameEdit = new QLineEdit(defaultName);
nameLabel->setBuddy(nameEdit);
QLabel *pathLabel = new QLabel(tr("Notebook &path:"));
QLabel *pathLabel = new QLabel(tr("Notebook &root folder:"));
pathEdit = new QLineEdit(defaultPath);
pathLabel->setBuddy(pathEdit);
browseBtn = new QPushButton(tr("&Browse"));
importCheck = new QCheckBox(tr("Import existing notebook"), this);
importCheck = new QCheckBox(tr("Try to import existing notebook"), this);
importCheck->setChecked(true);
importCheck->setToolTip(tr("When checked, VNote won't create a new config file if there already exists one"));
@ -48,11 +52,21 @@ void VNewNotebookDialog::setupUI()
connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(m_btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
// Warning label.
m_warnLabel = new QLabel(tr("<span style=\"%1\">WARNING</span>: The folder you choose is NOT empty! "
"It is highly recommended to use an EMPTY and EXCLUSIVE folder for a notebook. "
"Ignore this warning if you do want to import an existing VNote notebook folder.")
.arg(vconfig.c_warningTextStyle),
this);
m_warnLabel->setWordWrap(true);
m_warnLabel->hide();
QVBoxLayout *mainLayout = new QVBoxLayout();
if (infoLabel) {
mainLayout->addWidget(infoLabel);
}
mainLayout->addLayout(topLayout);
mainLayout->addWidget(m_warnLabel);
mainLayout->addWidget(m_btnBox);
setLayout(mainLayout);
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
@ -62,7 +76,9 @@ void VNewNotebookDialog::setupUI()
void VNewNotebookDialog::enableOkButton()
{
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
okBtn->setEnabled(!pathEdit->text().isEmpty() && !nameEdit->text().isEmpty());
okBtn->setEnabled(!pathEdit->text().isEmpty()
&& !nameEdit->text().isEmpty()
&& QDir(pathEdit->text()).exists());
}
QString VNewNotebookDialog::getNameInput() const
@ -77,7 +93,7 @@ QString VNewNotebookDialog::getPathInput() const
void VNewNotebookDialog::handleBrowseBtnClicked()
{
QString dirPath = QFileDialog::getExistingDirectory(this, tr("Select A Directory For The Notebook"),
QString dirPath = QFileDialog::getExistingDirectory(this, tr("Select Root Folder Of The Notebook"),
QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
pathEdit->setText(dirPath);
}
@ -92,3 +108,19 @@ void VNewNotebookDialog::showEvent(QShowEvent *event)
nameEdit->setFocus();
QDialog::showEvent(event);
}
void VNewNotebookDialog::handlePathChanged(const QString &p_text)
{
if (!p_text.isEmpty()) {
QDir dir(p_text);
QStringList files = dir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden);
if (dir.exists() && !files.isEmpty()) {
m_warnLabel->show();
} else {
m_warnLabel->hide();
}
} else {
m_warnLabel->hide();
}
enableOkButton();
}

View File

@ -23,6 +23,7 @@ public:
private slots:
void enableOkButton();
void handleBrowseBtnClicked();
void handlePathChanged(const QString &p_text);
protected:
void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;
@ -37,6 +38,7 @@ private:
QCheckBox *importCheck;
QPushButton *browseBtn;
QDialogButtonBox *m_btnBox;
QLabel *m_warnLabel;
QString title;
QString info;

View File

@ -63,6 +63,18 @@ QPushButton[TitleBtn="true"]::focus {
background-color: @focus-color;
}
QPushButton[DangerBtn="true"] {
color: #fff;
border-color: #d43f3a;
background-color: #d9534f;
}
QPushButton[DangerBtn="true"]::hover {
color: #fff;
border-color: #ac2925;
background-color: #c9302c;
}
QToolBar {
border: none;
}

View File

@ -15,6 +15,7 @@
#include <QScreen>
#include <cmath>
#include <QLocale>
#include <QPushButton>
#include "vconfigmanager.h"
@ -265,11 +266,19 @@ bool VUtils::copyDirectory(const QString &p_srcDirPath, const QString &p_destDir
}
int VUtils::showMessage(QMessageBox::Icon p_icon, const QString &p_title, const QString &p_text, const QString &p_infoText,
QMessageBox::StandardButtons p_buttons, QMessageBox::StandardButton p_defaultBtn, QWidget *p_parent)
QMessageBox::StandardButtons p_buttons, QMessageBox::StandardButton p_defaultBtn, QWidget *p_parent,
MessageBoxType p_type)
{
QMessageBox msgBox(p_icon, p_title, p_text, p_buttons, p_parent);
msgBox.setInformativeText(p_infoText);
msgBox.setDefaultButton(p_defaultBtn);
if (p_type == MessageBoxType::Danger) {
QPushButton *okBtn = dynamic_cast<QPushButton *>(msgBox.button(QMessageBox::Ok));
if (okBtn) {
okBtn->setStyleSheet(vconfig.c_dangerBtnStyle);
}
}
return msgBox.exec();
}

View File

@ -16,6 +16,12 @@ class QKeyEvent;
#define V_ASSERT(cond) ((!(cond)) ? qt_assert(#cond, __FILE__, __LINE__) : qt_noop())
#endif
enum class MessageBoxType
{
Normal = 0,
Danger = 1
};
class VUtils
{
public:
@ -41,7 +47,8 @@ public:
static bool copyDirectory(const QString &p_srcDirPath, const QString &p_destDirPath, bool p_isCut);
static int showMessage(QMessageBox::Icon p_icon, const QString &p_title, const QString &p_text,
const QString &p_infoText, QMessageBox::StandardButtons p_buttons,
QMessageBox::StandardButton p_defaultBtn, QWidget *p_parent);
QMessageBox::StandardButton p_defaultBtn, QWidget *p_parent,
MessageBoxType p_type = MessageBoxType::Normal);
static const QVector<QPair<QString, QString> > &getAvailableLanguages();
static bool isValidLanguage(const QString &p_lang);
static bool isImageURL(const QUrl &p_url);

View File

@ -21,6 +21,10 @@ const QString VConfigManager::c_defaultCssFile = QString(":/resources/styles/def
const QString VConfigManager::c_defaultMdhlFile = QString(":/resources/styles/default.mdhl");
const QString VConfigManager::c_solarizedDarkMdhlFile = QString(":/resources/styles/solarized-dark.mdhl");
const QString VConfigManager::c_solarizedLightMdhlFile = QString(":/resources/styles/solarized-light.mdhl");
const QString VConfigManager::c_warningTextStyle = QString("color: red; font: bold");
const QString VConfigManager::c_dataTextStyle = QString("font: bold");
const QString VConfigManager::c_dangerBtnStyle = QString("QPushButton {color: #fff; border-color: #d43f3a; background-color: #d9534f;}"
"QPushButton::hover {color: #fff; border-color: #ac2925; background-color: #c9302c;}");
VConfigManager::VConfigManager()
: userSettings(NULL), defaultSettings(NULL)

View File

@ -44,6 +44,15 @@ public:
static const QString appName;
static const QString c_version;
// CSS style for Warning texts.
static const QString c_warningTextStyle;
// CSS style for data in label.
static const QString c_dataTextStyle;
// QStylesheet for danger button. Should keep identical with DangerBtn in QSS.
static const QString c_dangerBtnStyle;
inline QFont getMdEditFont() const;
inline QPalette getMdEditPalette() const;

View File

@ -7,7 +7,9 @@
#include "vdirectory.h"
#include "utils/vutils.h"
#include "veditarea.h"
#include "vconfigmanager.h"
extern VConfigManager vconfig;
extern VNote *g_vnote;
VDirectoryTree::VDirectoryTree(VNote *vnote, QWidget *parent)
@ -95,7 +97,8 @@ void VDirectoryTree::setNotebook(VNotebook *p_notebook)
}
if (!m_notebook->open()) {
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Fail to open notebook %1.").arg(m_notebook->getName()), "",
tr("Fail to open notebook <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(m_notebook->getName()), "",
QMessageBox::Ok, QMessageBox::Ok, this);
clear();
return;
@ -138,7 +141,8 @@ void VDirectoryTree::updateDirectoryTreeOne(QTreeWidgetItem *p_parent, int depth
VDirectory *dir = getVDirectory(p_parent);
if (!dir->open()) {
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Fail to open directory %1.").arg(dir->getName()), "",
tr("Fail to open directory <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(dir->getName()), "",
QMessageBox::Ok, QMessageBox::Ok, this);
return;
}
@ -300,7 +304,8 @@ void VDirectoryTree::newSubDirectory()
}
VDirectory *curDir = getVDirectory(curItem);
QString info = tr("Create sub-directory under %1.").arg(curDir->getName());
QString info = tr("Create sub-directory under <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(curDir->getName());
QString text(tr("Directory &name:"));
QString defaultText("new_directory");
@ -309,14 +314,16 @@ void VDirectoryTree::newSubDirectory()
if (dialog.exec() == QDialog::Accepted) {
QString name = dialog.getNameInput();
if (curDir->findSubDirectory(name)) {
info = tr("Name already exists under %1. Please choose another name.").arg(curDir->getName());
info = tr("Name already exists under <span style=\"%1\">%2</span>. Please choose another name.")
.arg(vconfig.c_dataTextStyle).arg(curDir->getName());
defaultText = name;
continue;
}
VDirectory *subDir = curDir->createSubDirectory(name);
if (!subDir) {
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Fail to create directory %1.").arg(name), "",
tr("Fail to create directory <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(name), "",
QMessageBox::Ok, QMessageBox::Ok, this);
return;
}
@ -332,7 +339,8 @@ void VDirectoryTree::newRootDirectory()
if (!m_notebook) {
return;
}
QString info = tr("Create root directory in notebook %1.").arg(m_notebook->getName());
QString info = tr("Create root directory in notebook <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(m_notebook->getName());
QString text(tr("Directory &name:"));
QString defaultText("new_directory");
VDirectory *rootDir = m_notebook->getRootDir();
@ -341,14 +349,16 @@ void VDirectoryTree::newRootDirectory()
if (dialog.exec() == QDialog::Accepted) {
QString name = dialog.getNameInput();
if (rootDir->findSubDirectory(name)) {
info = tr("Name already exists in notebook %1. Please choose another name.").arg(m_notebook->getName());
info = tr("Name already exists in notebook <span style=\"%1\">%2</span>. Please choose another name.")
.arg(vconfig.c_dataTextStyle).arg(m_notebook->getName());
defaultText = name;
continue;
}
VDirectory *subDir = rootDir->createSubDirectory(name);
if (!subDir) {
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Fail to create directory %1.").arg(name), "",
tr("Fail to create directory <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(name), "",
QMessageBox::Ok, QMessageBox::Ok, this);
return;
}
@ -367,9 +377,15 @@ void VDirectoryTree::deleteDirectory()
}
VDirectory *curDir = getVDirectory(curItem);
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Are you sure to delete directory %1?").arg(curDir->getName()),
tr("This will delete any files under this directory."), QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Ok, this);
tr("Are you sure to delete directory <span style=\"%1\">%2</span>?")
.arg(vconfig.c_dataTextStyle).arg(curDir->getName()),
tr("<span style=\"%1\">WARNING</span>: "
"VNote will delete the whole directory (<b>ANY</b> files) "
"<span style=\"%2\">%3</span>."
"<br>It may be UNRECOVERABLE!")
.arg(vconfig.c_warningTextStyle).arg(vconfig.c_dataTextStyle).arg(curDir->retrivePath()),
QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Ok, this, MessageBoxType::Danger);
if (ret == QMessageBox::Ok) {
m_editArea->closeFile(curDir, true);
VDirectory *parentDir = curDir->getParentDirectory();
@ -415,7 +431,8 @@ void VDirectoryTree::editDirectoryInfo()
}
if (!curDir->rename(name)) {
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Fail to rename directory %1.").arg(curName), "",
tr("Fail to rename directory <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(curName), "",
QMessageBox::Ok, QMessageBox::Ok, this);
return;
}
@ -593,7 +610,8 @@ bool VDirectoryTree::copyDirectory(VDirectory *p_destDir, const QString &p_destN
emit directoryUpdated(destDir);
} else {
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Fail to copy directory %1.").arg(srcName),
tr("Fail to copy directory <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(srcName),
tr("Please check if there already exists a directory with the same name."),
QMessageBox::Ok, QMessageBox::Ok, this);
}

View File

@ -223,7 +223,8 @@ void VEditTab::readFile()
if (m_textEditor && m_textEditor->isModified()) {
// Prompt to save the changes
int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"),
tr("Note %1 has been modified.").arg(m_file->getName()),
tr("Note <span style=\"%1\">%2</span> has been modified.")
.arg(vconfig.c_dataTextStyle).arg(m_file->getName()),
tr("Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
QMessageBox::Save, this);
@ -263,7 +264,8 @@ bool VEditTab::saveFile()
if (!QFile(filePath).exists()) {
qWarning() << filePath << "being written has been removed";
VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."),
tr("%1 being written has been removed.").arg(filePath),
tr("File <span style=\"%1\">%2</span> being written has been removed.")
.arg(vconfig.c_dataTextStyle).arg(filePath),
QMessageBox::Ok, QMessageBox::Ok, this);
return false;
}

View File

@ -8,7 +8,9 @@
#include "veditarea.h"
#include "utils/vutils.h"
#include "vfile.h"
#include "vconfigmanager.h"
extern VConfigManager vconfig;
extern VNote *g_vnote;
VFileList::VFileList(QWidget *parent)
@ -175,8 +177,9 @@ void VFileList::newFile()
if (!m_directory) {
return;
}
QString info = tr("Create a note in %1.").arg(m_directory->getName());
info = info + "\n" + tr("Note with name ending with \".md\" will be treated as Markdown type.");
QString info = tr("Create a note in <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(m_directory->getName());
info = info + "<br>" + tr("Note with name ending with \".md\" will be treated as Markdown type.");
QString text(tr("Note &name:"));
QString defaultText("new_note.md");
do {
@ -191,7 +194,8 @@ void VFileList::newFile()
VFile *file = m_directory->createFile(name);
if (!file) {
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Fail to create note %1.").arg(name), "",
tr("Fail to create note <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(name), "",
QMessageBox::Ok, QMessageBox::Ok, this);
return;
}
@ -248,10 +252,13 @@ void VFileList::deleteFile(VFile *p_file)
VDirectory *dir = p_file->getDirectory();
QString fileName = p_file->getName();
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Are you sure to delete note %1?").arg(fileName),
tr("This may be unrecoverable!"),
tr("Are you sure to delete note <span style=\"%1\">%2</span>?")
.arg(vconfig.c_dataTextStyle).arg(fileName),
tr("<span style=\"%1\">WARNING</span>: The files (including images) "
"deleted may be UNRECOVERABLE!")
.arg(vconfig.c_warningTextStyle),
QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Ok, this);
QMessageBox::Ok, this, MessageBoxType::Danger);
if (ret == QMessageBox::Ok) {
editArea->closeFile(p_file, true);
@ -417,7 +424,8 @@ void VFileList::pasteFiles(VDirectory *p_destDir)
nrPasted++;
} else {
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Fail to copy note %1.").arg(srcFile->getName()),
tr("Fail to copy note <span style=\"%1\">%2</span>.")
.arg(vconfig.c_dataTextStyle).arg(srcFile->getName()),
tr("Please check if there already exists a file with the same name in the target directory."),
QMessageBox::Ok, QMessageBox::Ok, this);
}
@ -442,7 +450,8 @@ bool VFileList::copyFile(VDirectory *p_destDir, const QString &p_destName, VFile
if (editArea->isFileOpened(p_file)) {
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("The renaming will change the note type."),
tr("You should close the note %1 before continue.").arg(p_file->getName()),
tr("You should close the note <span style=\"%1\">%2</span> before continue.")
.arg(vconfig.c_dataTextStyle).arg(p_file->getName()),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok, this);
if (QMessageBox::Ok == ret) {
if (!editArea->closeFile(p_file, false)) {

View File

@ -160,7 +160,10 @@ void VNotebookSelector::update()
bool VNotebookSelector::newNotebook()
{
QString info;
QString info(tr("Please type the name of the notebook and "
"choose an existing directory as Root Folder of the notebook.\n"
"The root folder should be used EXCLUSIVELY by VNote and "
"it is recommended to be EMPTY."));
QString defaultName("new_notebook");
QString defaultPath;