diff --git a/src/resources/icons/flash_page.svg b/src/resources/icons/flash_page.svg
new file mode 100644
index 00000000..8390f3ef
--- /dev/null
+++ b/src/resources/icons/flash_page.svg
@@ -0,0 +1,17 @@
+
+
+
+
diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini
index 4f035cf2..c9bb1dfb 100644
--- a/src/resources/vnote.ini
+++ b/src/resources/vnote.ini
@@ -170,6 +170,10 @@ enable_backup_file=true
; v: Ctrl+V
vim_exemption_keys=cv
+; Path of the flash page, related to the configuration folder
+; Could be absolute path
+flash_page=flash_page.md
+
[web]
; Location and configuration for Mathjax
mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML
@@ -215,6 +219,8 @@ LastClosedFile=Ctrl+Shift+T
ActivateNextTab=Ctrl+Tab
; Activate previous tab
ActivatePreviousTab=Ctrl+Shift+Tab
+; Activate flash page
+FlashPage=Ctrl+Alt+L
[captain_mode_shortcuts]
; Define shortcuts in Captain mode here.
diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp
index 6520fd69..5c22d06f 100644
--- a/src/utils/vutils.cpp
+++ b/src/utils/vutils.cpp
@@ -1055,3 +1055,14 @@ bool VUtils::isControlModifierForVim(int p_modifiers)
return p_modifiers == Qt::ControlModifier;
#endif
}
+
+void VUtils::touchFile(const QString &p_file)
+{
+ QFile file(p_file);
+ if (!file.open(QIODevice::WriteOnly)) {
+ qWarning() << "fail to touch file" << p_file;
+ return;
+ }
+
+ file.close();
+}
diff --git a/src/utils/vutils.h b/src/utils/vutils.h
index 2edc39f7..7a646df9 100644
--- a/src/utils/vutils.h
+++ b/src/utils/vutils.h
@@ -255,6 +255,9 @@ public:
// See if @p_modifiers is Control which is different on macOs and Windows.
static bool isControlModifierForVim(int p_modifiers);
+ // If @p_file does not exists, create an empty file.
+ static void touchFile(const QString &p_file);
+
// Regular expression for image link.
// 
// Captured texts (need to be trimmed):
diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp
index d868e6b4..7143892b 100644
--- a/src/vconfigmanager.cpp
+++ b/src/vconfigmanager.cpp
@@ -1111,8 +1111,8 @@ QHash VConfigManager::readShortcutsFromSettings(QSettings *p_s
bool VConfigManager::isValidKeySequence(const QString &p_seq)
{
- return p_seq.toLower() != "ctrl+q"
- && !QKeySequence(p_seq).isEmpty();
+ return p_seq.isEmpty()
+ || (p_seq.toLower() != "ctrl+q" && !QKeySequence(p_seq).isEmpty());
}
void VConfigManager::readShortcutsFromSettings()
@@ -1143,10 +1143,9 @@ void VConfigManager::readShortcutsFromSettings()
}
if (matched.size() < m_shortcuts.size()) {
+ qDebug() << "override user shortcuts settings using default settings";
writeShortcutsToSettings(userSettings, group, m_shortcuts);
}
-
- qDebug() << "shortcuts:" << m_shortcuts;
}
void VConfigManager::readCaptainShortcutsFromSettings()
@@ -1321,3 +1320,26 @@ QVector> VConfigManager::getExternalEditors() const
return ret;
}
+
+const QString &VConfigManager::getFlashPage() const
+{
+ if (m_flashPage.isEmpty()) {
+ VConfigManager *var = const_cast(this);
+
+ var->m_flashPage = var->getConfigFromSettings("global",
+ "flash_page").toString();
+ if (var->m_flashPage.isEmpty()) {
+ var->m_flashPage = var->resetDefaultConfig("global", "flash_page").toString();
+ }
+
+ if (VUtils::checkFileNameLegal(m_flashPage)) {
+ var->m_flashPage = QDir(getConfigFolder()).filePath(m_flashPage);
+ }
+ }
+
+ if (!QFileInfo::exists(m_flashPage)) {
+ VUtils::touchFile(m_flashPage);
+ }
+
+ return m_flashPage;
+}
diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h
index 9eb0aff4..6f32ff45 100644
--- a/src/vconfigmanager.h
+++ b/src/vconfigmanager.h
@@ -389,6 +389,8 @@ public:
const QString &getVimExemptionKeys() const;
+ const QString &getFlashPage() const;
+
private:
// Look up a config from user and default settings.
QVariant getConfigFromSettings(const QString §ion, const QString &key) const;
@@ -737,6 +739,9 @@ private:
// v: Ctrl+V
QString m_vimExemptionKeys;
+ // Absolute path of flash page.
+ QString m_flashPage;
+
// The name of the config file in each directory, obsolete.
// Use c_dirConfigFile instead.
static const QString c_obsoleteDirConfigFile;
diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp
index e246b76f..5614fb52 100644
--- a/src/vmainwindow.cpp
+++ b/src/vmainwindow.cpp
@@ -71,8 +71,13 @@ VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent)
setupUI();
initMenuBar();
+
initToolBar();
+
+ initShortcuts();
+
initDockWindows();
+
initAvatar();
restoreStateAndGeometry();
@@ -317,7 +322,7 @@ void VMainWindow::initViewToolBar(QSize p_iconSize)
tr("&Single Panel"),
m_viewActGroup);
onePanelViewAct->setStatusTip(tr("Display only the notes list panel"));
- onePanelViewAct->setToolTip(tr("Single Panel (Ctrl+E P)"));
+ onePanelViewAct->setToolTip(tr("Single Panel"));
onePanelViewAct->setCheckable(true);
onePanelViewAct->setData((int)PanelViewState::SinglePanel);
@@ -325,7 +330,7 @@ void VMainWindow::initViewToolBar(QSize p_iconSize)
tr("&Two Panels"),
m_viewActGroup);
twoPanelViewAct->setStatusTip(tr("Display both the folders and notes list panel"));
- twoPanelViewAct->setToolTip(tr("Two Panels (Ctrl+E P)"));
+ twoPanelViewAct->setToolTip(tr("Two Panels"));
twoPanelViewAct->setCheckable(true);
twoPanelViewAct->setData((int)PanelViewState::TwoPanels);
@@ -368,7 +373,7 @@ void VMainWindow::initViewToolBar(QSize p_iconSize)
panelMenu->addAction(compactViewAct);
expandViewAct = new QAction(QIcon(":/resources/icons/expand.svg"),
- tr("Expand (Ctrl+E E)"), this);
+ tr("Expand"), this);
expandViewAct->setStatusTip(tr("Expand the edit area"));
expandViewAct->setCheckable(true);
expandViewAct->setMenu(panelMenu);
@@ -420,7 +425,8 @@ void VMainWindow::initEditToolBar(QSize p_iconSize)
m_editToolBar->addAction(m_headingSequenceAct);
QAction *boldAct = new QAction(QIcon(":/resources/icons/bold.svg"),
- tr("Bold (Ctrl+B)"), this);
+ tr("Bold\t%1").arg(VUtils::getShortcutText("Ctrl+B")),
+ this);
boldAct->setStatusTip(tr("Insert bold text or change selected text to bold"));
connect(boldAct, &QAction::triggered,
this, [this](){
@@ -432,7 +438,8 @@ void VMainWindow::initEditToolBar(QSize p_iconSize)
m_editToolBar->addAction(boldAct);
QAction *italicAct = new QAction(QIcon(":/resources/icons/italic.svg"),
- tr("Italic (Ctrl+I)"), this);
+ tr("Italic\t%1").arg(VUtils::getShortcutText("Ctrl+I")),
+ this);
italicAct->setStatusTip(tr("Insert italic text or change selected text to italic"));
connect(italicAct, &QAction::triggered,
this, [this](){
@@ -444,7 +451,8 @@ void VMainWindow::initEditToolBar(QSize p_iconSize)
m_editToolBar->addAction(italicAct);
QAction *strikethroughAct = new QAction(QIcon(":/resources/icons/strikethrough.svg"),
- tr("Strikethrough (Ctrl+D)"), this);
+ tr("Strikethrough\t%1").arg(VUtils::getShortcutText("Ctrl+D")),
+ this);
strikethroughAct->setStatusTip(tr("Insert strikethrough text or change selected text to strikethroughed"));
connect(strikethroughAct, &QAction::triggered,
this, [this](){
@@ -456,7 +464,8 @@ void VMainWindow::initEditToolBar(QSize p_iconSize)
m_editToolBar->addAction(strikethroughAct);
QAction *inlineCodeAct = new QAction(QIcon(":/resources/icons/inline_code.svg"),
- tr("Inline Code (Ctrl+K)"), this);
+ tr("Inline Code\t%1").arg(VUtils::getShortcutText("Ctrl+K")),
+ this);
inlineCodeAct->setStatusTip(tr("Insert inline-code text or change selected text to inline-coded"));
connect(inlineCodeAct, &QAction::triggered,
this, [this](){
@@ -468,7 +477,7 @@ void VMainWindow::initEditToolBar(QSize p_iconSize)
m_editToolBar->addAction(inlineCodeAct);
QAction *codeBlockAct = new QAction(QIcon(":/resources/icons/code_block.svg"),
- tr("Code Block (Ctrl+M)"),
+ tr("Code Block\t%1").arg(VUtils::getShortcutText("Ctrl+M")),
this);
codeBlockAct->setStatusTip(tr("Insert fenced code block text or wrap selected text into a fenced code block"));
connect(codeBlockAct, &QAction::triggered,
@@ -484,7 +493,8 @@ void VMainWindow::initEditToolBar(QSize p_iconSize)
// Insert link.
QAction *insetLinkAct = new QAction(QIcon(":/resources/icons/link.svg"),
- tr("Insert Link (Ctrl+L)"), this);
+ tr("Insert Link\t%1").arg(VUtils::getShortcutText("Ctrl+L")),
+ this);
insetLinkAct->setStatusTip(tr("Insert a link"));
connect(insetLinkAct, &QAction::triggered,
this, [this]() {
@@ -538,7 +548,18 @@ void VMainWindow::initNoteToolBar(QSize p_iconSize)
m_attachmentBtn->setFocusPolicy(Qt::NoFocus);
m_attachmentBtn->setEnabled(false);
+ QAction *flashPageAct = new QAction(QIcon(":/resources/icons/flash_page.svg"),
+ tr("Flash Page"),
+ this);
+ flashPageAct->setStatusTip(tr("Open the Flash Page to edit"));
+ QString keySeq = g_config->getShortcutKeySequence("FlashPage");
+ qDebug() << "set FlashPage shortcut to" << keySeq;
+ flashPageAct->setShortcut(QKeySequence(keySeq));
+ connect(flashPageAct, &QAction::triggered,
+ this, &VMainWindow::openFlashPage);
+
noteToolBar->addWidget(m_attachmentBtn);
+ noteToolBar->addAction(flashPageAct);
}
void VMainWindow::initFileToolBar(QSize p_iconSize)
@@ -577,13 +598,6 @@ void VMainWindow::initFileToolBar(QSize p_iconSize)
connect(deleteNoteAct, &QAction::triggered,
this, &VMainWindow::deleteCurNote);
- keySeq = g_config->getShortcutKeySequence("CloseNote");
- qDebug() << "set CloseNote shortcut to" << keySeq;
- m_closeNoteShortcut = new QShortcut(QKeySequence(keySeq), this);
- m_closeNoteShortcut->setContext(Qt::WidgetWithChildrenShortcut);
- connect(m_closeNoteShortcut, &QShortcut::activated,
- this, &VMainWindow::closeCurrentFile);
-
editNoteAct = new QAction(QIcon(":/resources/icons/edit_note.svg"),
tr("&Edit"), this);
editNoteAct->setStatusTip(tr("Edit current note"));
@@ -596,7 +610,7 @@ void VMainWindow::initFileToolBar(QSize p_iconSize)
discardExitAct = new QAction(QIcon(":/resources/icons/discard_exit.svg"),
tr("Discard Changes And Read"), this);
discardExitAct->setStatusTip(tr("Discard changes and exit edit mode"));
- discardExitAct->setToolTip(tr("Discard Changes And Read (Ctrl+E Q)"));
+ discardExitAct->setToolTip(tr("Discard Changes And Read"));
connect(discardExitAct, &QAction::triggered,
editArea, &VEditArea::readFile);
@@ -605,7 +619,7 @@ void VMainWindow::initFileToolBar(QSize p_iconSize)
exitEditMenu->addAction(discardExitAct);
saveExitAct = new QAction(QIcon(":/resources/icons/save_exit.svg"),
- tr("Save Changes And Read (Ctrl+T)"), this);
+ tr("Save Changes And Read"), this);
saveExitAct->setStatusTip(tr("Save changes and exit edit mode"));
saveExitAct->setMenu(exitEditMenu);
keySeq = g_config->getShortcutKeySequence("SaveAndRead");
@@ -2424,7 +2438,10 @@ bool VMainWindow::tryOpenInternalFile(const QString &p_filePath)
return false;
}
-void VMainWindow::openFiles(const QStringList &p_files, bool p_forceOrphan)
+void VMainWindow::openFiles(const QStringList &p_files,
+ bool p_forceOrphan,
+ OpenFileMode p_mode,
+ bool p_forceMode)
{
for (int i = 0; i < p_files.size(); ++i) {
VFile *file = NULL;
@@ -2436,7 +2453,7 @@ void VMainWindow::openFiles(const QStringList &p_files, bool p_forceOrphan)
file = vnote->getOrphanFile(p_files[i], true);
}
- editArea->openFile(file, OpenFileMode::Read);
+ editArea->openFile(file, p_mode, p_forceMode);
}
}
@@ -2648,3 +2665,23 @@ void VMainWindow::promptNewNotebookIfEmpty()
notebookSelector->newNotebook();
}
}
+
+void VMainWindow::initShortcuts()
+{
+ QString keySeq = g_config->getShortcutKeySequence("CloseNote");
+ qDebug() << "set CloseNote shortcut to" << keySeq;
+ if (!keySeq.isEmpty()) {
+ QShortcut *closeNoteShortcut = new QShortcut(QKeySequence(keySeq), this);
+ closeNoteShortcut->setContext(Qt::WidgetWithChildrenShortcut);
+ connect(closeNoteShortcut, &QShortcut::activated,
+ this, &VMainWindow::closeCurrentFile);
+ }
+}
+
+void VMainWindow::openFlashPage()
+{
+ openFiles(QStringList() << g_config->getFlashPage(),
+ false,
+ OpenFileMode::Edit,
+ true);
+}
diff --git a/src/vmainwindow.h b/src/vmainwindow.h
index 39a8f0d7..4eb991d0 100644
--- a/src/vmainwindow.h
+++ b/src/vmainwindow.h
@@ -34,7 +34,6 @@ class VTabIndicator;
class VSingleInstanceGuard;
class QTimer;
class QSystemTrayIcon;
-class QShortcut;
class VButtonWithWidget;
class VAttachmentList;
class VSnippetList;
@@ -72,7 +71,10 @@ public:
// Open files @p_files as orphan files or internal note files.
// If @p_forceOrphan is false, for each file, VNote will try to find out if
// it is a note inside VNote. If yes, VNote will open it as internal file.
- void openFiles(const QStringList &p_files, bool p_forceOrphan = false);
+ void openFiles(const QStringList &p_files,
+ bool p_forceOrphan = false,
+ OpenFileMode p_mode = OpenFileMode::Read,
+ bool p_forceMode = false);
// Try to open @p_filePath as internal note.
bool tryOpenInternalFile(const QString &p_filePath);
@@ -173,6 +175,9 @@ private slots:
// Close current note.
void closeCurrentFile();
+ // Open flash page in edit mode.
+ void openFlashPage();
+
protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
@@ -254,6 +259,8 @@ private:
// Only available for writable Markdown file.
bool isHeadingSequenceApplicable() const;
+ void initShortcuts();
+
// Captain mode functions.
// Popup the attachment list if it is enabled.
@@ -353,8 +360,6 @@ private:
// Act group for panel view actions.
QActionGroup *m_viewActGroup;
- QShortcut *m_closeNoteShortcut;
-
// Menus
QMenu *viewMenu;
diff --git a/src/vnote.qrc b/src/vnote.qrc
index d6f7d938..d90e3520 100644
--- a/src/vnote.qrc
+++ b/src/vnote.qrc
@@ -142,5 +142,6 @@
resources/icons/snippet_info.svg
resources/icons/apply_snippet.svg
resources/icons/reading_modified.svg
+ resources/icons/flash_page.svg