Browse Source

support inserting note name as title when creating a note

Le Tan 8 years ago
parent
commit
803af89dde

+ 36 - 7
src/dialog/vfileinfodialog.cpp

@@ -1,16 +1,22 @@
 #include <QtWidgets>
 #include "vfileinfodialog.h"
+#include "vdirectory.h"
+#include "vfile.h"
+#include "vconfigmanager.h"
+
+extern VConfigManager *g_config;
 
 VFileInfoDialog::VFileInfoDialog(const QString &title, const QString &info,
-                                 const QString &defaultName,
+                                 VDirectory *directory, const VFile *file,
                                  QWidget *parent)
-    : QDialog(parent), infoLabel(NULL), title(title), info(info), defaultName(defaultName)
+    : QDialog(parent), infoLabel(NULL), title(title), info(info),
+      m_directory(directory), m_file(file)
 {
     setupUI();
 
-    connect(nameEdit, &QLineEdit::textChanged, this, &VFileInfoDialog::enableOkButton);
+    connect(nameEdit, &QLineEdit::textChanged, this, &VFileInfoDialog::handleInputChanged);
 
-    enableOkButton();
+    handleInputChanged();
 }
 
 void VFileInfoDialog::setupUI()
@@ -19,10 +25,14 @@ void VFileInfoDialog::setupUI()
         infoLabel = new QLabel(info);
     }
     nameLabel = new QLabel(tr("Note &name:"));
-    nameEdit = new QLineEdit(defaultName);
+    nameEdit = new QLineEdit(m_file->getName());
     nameEdit->selectAll();
     nameLabel->setBuddy(nameEdit);
 
+    m_warnLabel = new QLabel();
+    m_warnLabel->setWordWrap(true);
+    m_warnLabel->hide();
+
     // Ok is the default button.
     m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
     connect(m_btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
@@ -41,6 +51,7 @@ void VFileInfoDialog::setupUI()
     }
 
     mainLayout->addLayout(topLayout);
+    mainLayout->addWidget(m_warnLabel);
     mainLayout->addWidget(m_btnBox);
     mainLayout->setSizeConstraint(QLayout::SetFixedSize);
     setLayout(mainLayout);
@@ -48,10 +59,28 @@ void VFileInfoDialog::setupUI()
     setWindowTitle(title);
 }
 
-void VFileInfoDialog::enableOkButton()
+void VFileInfoDialog::handleInputChanged()
 {
+    bool showWarnLabel = false;
+    QString name = nameEdit->text();
+    bool nameOk = !name.isEmpty();
+    if (nameOk && name != m_file->getName()) {
+        // Check if the name conflicts with existing notebook name.
+        // Case-insensitive when creating note.
+        if (m_directory->findFile(name, false)) {
+            nameOk = false;
+            showWarnLabel = true;
+            QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
+                                          "Please choose another name.")
+                                          .arg(g_config->c_warningTextStyle);
+            m_warnLabel->setText(nameConflictText);
+        }
+    }
+
+    m_warnLabel->setVisible(showWarnLabel);
+
     QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
-    okBtn->setEnabled(!nameEdit->text().isEmpty());
+    okBtn->setEnabled(nameOk);
 }
 
 QString VFileInfoDialog::getNameInput() const

+ 9 - 3
src/dialog/vfileinfodialog.h

@@ -7,17 +7,20 @@ class QLabel;
 class QLineEdit;
 class QDialogButtonBox;
 class QString;
+class VDirectory;
+class VFile;
 
 class VFileInfoDialog : public QDialog
 {
     Q_OBJECT
 public:
-    VFileInfoDialog(const QString &title, const QString &info, const QString &defaultName,
+    VFileInfoDialog(const QString &title, const QString &info,
+                    VDirectory *directory, const VFile *file,
                     QWidget *parent = 0);
     QString getNameInput() const;
 
 private slots:
-    void enableOkButton();
+    void handleInputChanged();
 
 private:
     void setupUI();
@@ -25,11 +28,14 @@ private:
     QLabel *infoLabel;
     QLabel *nameLabel;
     QLineEdit *nameEdit;
+    QLabel *m_warnLabel;
     QDialogButtonBox *m_btnBox;
 
     QString title;
     QString info;
-    QString defaultName;
+
+    VDirectory *m_directory;
+    const VFile *m_file;
 };
 
 #endif // VFILEINFODIALOG_H

+ 58 - 11
src/dialog/vnewfiledialog.cpp

@@ -1,13 +1,21 @@
 #include <QtWidgets>
 #include "vnewfiledialog.h"
+#include "vconfigmanager.h"
+#include "vdirectory.h"
 
-VNewFileDialog::VNewFileDialog(const QString &title, const QString &info, const QString &name,
-                               const QString &defaultName, QWidget *parent)
-    : QDialog(parent), title(title), info(info), name(name), defaultName(defaultName)
+extern VConfigManager *g_config;
+
+VNewFileDialog::VNewFileDialog(const QString &title, const QString &info,
+                               const QString &defaultName, VDirectory *directory,
+                               QWidget *parent)
+    : QDialog(parent), title(title), info(info),
+      defaultName(defaultName), m_directory(directory)
 {
     setupUI();
 
-    connect(nameEdit, &QLineEdit::textChanged, this, &VNewFileDialog::enableOkButton);
+    connect(nameEdit, &QLineEdit::textChanged, this, &VNewFileDialog::handleInputChanged);
+
+    handleInputChanged();
 }
 
 void VNewFileDialog::setupUI()
@@ -17,21 +25,35 @@ void VNewFileDialog::setupUI()
         infoLabel = new QLabel(info);
     }
 
-    nameLabel = new QLabel(name);
+    // Name.
+    QLabel *nameLabel = new QLabel(tr("Note &name:"));
     nameEdit = new QLineEdit(defaultName);
     int dotIndex = defaultName.lastIndexOf('.');
     nameEdit->setSelection(0, (dotIndex == -1) ? defaultName.size() : dotIndex);
     nameLabel->setBuddy(nameEdit);
 
+    // InsertTitle.
+    m_insertTitleCB = new QCheckBox(tr("Insert note name as title (for Markdown only)"));
+    m_insertTitleCB->setToolTip(tr("Insert note name into the new note as a title"));
+    m_insertTitleCB->setChecked(g_config->getInsertTitleFromNoteName());
+    connect(m_insertTitleCB, &QCheckBox::stateChanged,
+            this, [this](int p_state) {
+                g_config->setInsertTitleFromNoteName(p_state == Qt::Checked);
+            });
+
+    QFormLayout *topLayout = new QFormLayout();
+    topLayout->addRow(nameLabel, nameEdit);
+    topLayout->addRow("", m_insertTitleCB);
+
+    m_warnLabel = new QLabel();
+    m_warnLabel->setWordWrap(true);
+    m_warnLabel->hide();
+
     // 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);
 
-    QHBoxLayout *topLayout = new QHBoxLayout();
-    topLayout->addWidget(nameLabel);
-    topLayout->addWidget(nameEdit);
-
     QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
     nameEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
 
@@ -39,7 +61,9 @@ void VNewFileDialog::setupUI()
     if (infoLabel) {
         mainLayout->addWidget(infoLabel);
     }
+
     mainLayout->addLayout(topLayout);
+    mainLayout->addWidget(m_warnLabel);
     mainLayout->addWidget(m_btnBox);
     mainLayout->setSizeConstraint(QLayout::SetFixedSize);
     setLayout(mainLayout);
@@ -47,13 +71,36 @@ void VNewFileDialog::setupUI()
     setWindowTitle(title);
 }
 
-void VNewFileDialog::enableOkButton(const QString &editText)
+void VNewFileDialog::handleInputChanged()
 {
+    bool showWarnLabel = false;
+    QString name = nameEdit->text();
+    bool nameOk = !name.isEmpty();
+    if (nameOk) {
+        // Check if the name conflicts with existing notebook name.
+        // Case-insensitive when creating note.
+        if (m_directory->findFile(name, false)) {
+            nameOk = false;
+            showWarnLabel = true;
+            QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
+                                          "Please choose another name.")
+                                          .arg(g_config->c_warningTextStyle);
+            m_warnLabel->setText(nameConflictText);
+        }
+    }
+
+    m_warnLabel->setVisible(showWarnLabel);
+
     QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
-    okBtn->setEnabled(!editText.isEmpty());
+    okBtn->setEnabled(nameOk);
 }
 
 QString VNewFileDialog::getNameInput() const
 {
     return nameEdit->text();
 }
+
+bool VNewFileDialog::getInsertTitleInput() const
+{
+    return m_insertTitleCB->isChecked();
+}

+ 15 - 6
src/dialog/vnewfiledialog.h

@@ -6,31 +6,40 @@
 class QLabel;
 class QLineEdit;
 class QDialogButtonBox;
-class QString;
+class QCheckBox;
+class VDirectory;
 
 class VNewFileDialog : public QDialog
 {
     Q_OBJECT
 public:
-    VNewFileDialog(const QString &title, const QString &info, const QString &name,
-                   const QString &defaultName, QWidget *parent = 0);
+    VNewFileDialog(const QString &title, const QString &info,
+                   const QString &defaultName, VDirectory *directory,
+                   QWidget *parent = 0);
+
     QString getNameInput() const;
 
+    bool getInsertTitleInput() const;
+
 private slots:
-    void enableOkButton(const QString &editText);
+    void handleInputChanged();
 
 private:
     void setupUI();
 
-    QLabel *nameLabel;
     QLineEdit *nameEdit;
+    QCheckBox *m_insertTitleCB;
+
     QPushButton *okBtn;
     QDialogButtonBox *m_btnBox;
 
+    QLabel *m_warnLabel;
+
     QString title;
     QString info;
-    QString name;
     QString defaultName;
+
+    VDirectory *m_directory;
 };
 
 #endif // VNEWFILEDIALOG_H

+ 3 - 0
src/resources/vnote.ini

@@ -76,6 +76,9 @@ markdown_highlight_interval=400
 ; Adds specified height between lines (in pixels)
 line_distance_height=3
 
+; Whether insert the note name as a title when creating a new note
+insert_title_from_note_name=true
+
 [session]
 tools_dock_checked=true
 

+ 3 - 0
src/vconfigmanager.cpp

@@ -163,6 +163,9 @@ void VConfigManager::initialize()
 
     m_lineDistanceHeight = getConfigFromSettings("global",
                                                  "line_distance_height").toInt();
+
+    m_insertTitleFromNoteName = getConfigFromSettings("global",
+                                                      "insert_title_from_note_name").toBool();
 }
 
 void VConfigManager::readPredefinedColorsFromSettings()

+ 22 - 0
src/vconfigmanager.h

@@ -225,6 +225,9 @@ public:
 
     int getLineDistanceHeight() const;
 
+    bool getInsertTitleFromNoteName() const;
+    void setInsertTitleFromNoteName(bool p_enabled);
+
     // Return the configured key sequence of @p_operation.
     // Return empty if there is no corresponding config.
     QString getShortcutKeySequence(const QString &p_operation) const;
@@ -456,6 +459,9 @@ private:
     // Line distance height in pixel.
     int m_lineDistanceHeight;
 
+    // Whether insert the note name as a title when creating a new note.
+    bool m_insertTitleFromNoteName;
+
     // The name of the config file in each directory, obsolete.
     // Use c_dirConfigFile instead.
     static const QString c_obsoleteDirConfigFile;
@@ -1159,4 +1165,20 @@ inline int VConfigManager::getLineDistanceHeight() const
     return m_lineDistanceHeight;
 }
 
+inline bool VConfigManager::getInsertTitleFromNoteName() const
+{
+    return m_insertTitleFromNoteName;
+}
+
+inline void VConfigManager::setInsertTitleFromNoteName(bool p_enabled)
+{
+    if (p_enabled == m_insertTitleFromNoteName) {
+        return;
+    }
+
+    m_insertTitleFromNoteName = p_enabled;
+    setConfigToSettings("global", "insert_title_from_note_name",
+                        m_insertTitleFromNoteName);
+}
+
 #endif // VCONFIGMANAGER_H

+ 59 - 64
src/vfilelist.cpp

@@ -178,46 +178,35 @@ void VFileList::fileInfo(VFile *p_file)
     if (!p_file) {
         return;
     }
-    VDirectory *dir = p_file->getDirectory();
-    QString info;
-    QString defaultName = p_file->getName();
-    QString curName = defaultName;
-    do {
-        VFileInfoDialog dialog(tr("Note Information"), info, defaultName, this);
-        if (dialog.exec() == QDialog::Accepted) {
-            QString name = dialog.getNameInput();
-            if (name == curName) {
-                return;
-            }
 
-            // Case-insensitive when creating note.
-            if (dir->findFile(name, false)) {
-                info = "Name (case-insensitive) already exists. Please choose another name.";
-                defaultName = name;
-                continue;
-            }
-
-            if (!promptForDocTypeChange(p_file, QDir(p_file->retriveBasePath()).filePath(name))) {
-                return;
-            }
+    VDirectory *dir = p_file->getDirectory();
+    QString curName = p_file->getName();
+    VFileInfoDialog dialog(tr("Note Information"), "", dir, p_file, this);
+    if (dialog.exec() == QDialog::Accepted) {
+        QString name = dialog.getNameInput();
+        if (name == curName) {
+            return;
+        }
 
-            if (!p_file->rename(name)) {
-                VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
-                                    tr("Fail to rename note <span style=\"%1\">%2</span>.")
-                                      .arg(g_config->c_dataTextStyle).arg(curName), "",
-                                    QMessageBox::Ok, QMessageBox::Ok, this);
-                return;
-            }
+        if (!promptForDocTypeChange(p_file, QDir(p_file->retriveBasePath()).filePath(name))) {
+            return;
+        }
 
-            QListWidgetItem *item = findItem(p_file);
-            if (item) {
-                fillItem(item, p_file);
-            }
+        if (!p_file->rename(name)) {
+            VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
+                                tr("Fail to rename note <span style=\"%1\">%2</span>.")
+                                  .arg(g_config->c_dataTextStyle).arg(curName), "",
+                                QMessageBox::Ok, QMessageBox::Ok, this);
+            return;
+        }
 
-            emit fileUpdated(p_file);
+        QListWidgetItem *item = findItem(p_file);
+        if (item) {
+            fillItem(item, p_file);
         }
-        break;
-    } while (true);
+
+        emit fileUpdated(p_file);
+    }
 }
 
 void VFileList::fillItem(QListWidgetItem *p_item, const VFile *p_file)
@@ -277,38 +266,44 @@ void VFileList::newFile()
                      .arg(g_config->c_dataTextStyle).arg(m_directory->getName());
     info = info + "<br>" + tr("Note with name ending with \"%1\" will be treated as Markdown type.")
                              .arg(suffixStr);
-    QString text(tr("Note &name:"));
-    QString defaultText = QString("new_note.%1").arg(defaultSuf);
-    do {
-        VNewFileDialog dialog(tr("Create Note"), info, text, defaultText, this);
-        if (dialog.exec() == QDialog::Accepted) {
-            QString name = dialog.getNameInput();
-            // Case-insensitive when creating note.
-            if (m_directory->findFile(name, false)) {
-                info = tr("Name (case-insensitive) already exists. Please choose another name.");
-                defaultText = name;
-                continue;
-            }
+    QString defaultName = QString("new_note.%1").arg(defaultSuf);
+    defaultName = VUtils::getFileNameWithSequence(m_directory->retrivePath(), defaultName);
+    VNewFileDialog dialog(tr("Create Note"), info, defaultName, m_directory, this);
+    if (dialog.exec() == QDialog::Accepted) {
+        VFile *file = m_directory->createFile(dialog.getNameInput());
+        if (!file) {
+            VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
+                                tr("Fail to create note <span style=\"%1\">%2</span>.")
+                                  .arg(g_config->c_dataTextStyle).arg(dialog.getNameInput()), "",
+                                QMessageBox::Ok, QMessageBox::Ok, this);
+            return;
+        }
+
+        // Write title if needed.
+        if (dialog.getInsertTitleInput()) {
+            if (!file->open()) {
+                qWarning() << "fail to open newly-created note" << file->getName();
+            } else {
+                Q_ASSERT(file->getContent().isEmpty());
+                QString content = QString("# %1\n").arg(QFileInfo(file->getName()).baseName());
+                file->setContent(content);
+                if (!file->save()) {
+                    qWarning() << "fail to write to newly-created note" << file->getName();
+                }
 
-            VFile *file = m_directory->createFile(name);
-            if (!file) {
-                VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
-                                    tr("Fail to create note <span style=\"%1\">%2</span>.")
-                                      .arg(g_config->c_dataTextStyle).arg(name), "",
-                                    QMessageBox::Ok, QMessageBox::Ok, this);
-                return;
+                file->close();
             }
-            QVector<QListWidgetItem *> items = updateFileListAdded();
-            Q_ASSERT(items.size() == 1);
-            fileList->setCurrentItem(items[0], QItemSelectionModel::ClearAndSelect);
-            // Qt seems not to update the QListWidget correctly. Manually force it to repaint.
-            fileList->update();
-
-            // Open it in edit mode
-            emit fileCreated(file, OpenFileMode::Edit);
         }
-        break;
-    } while (true);
+
+        QVector<QListWidgetItem *> items = updateFileListAdded();
+        Q_ASSERT(items.size() == 1);
+        fileList->setCurrentItem(items[0], QItemSelectionModel::ClearAndSelect);
+        // Qt seems not to update the QListWidget correctly. Manually force it to repaint.
+        fileList->update();
+
+        // Open it in edit mode
+        emit fileCreated(file, OpenFileMode::Edit);
+    }
 }
 
 QVector<QListWidgetItem *> VFileList::updateFileListAdded()