diff --git a/src/dialog/vsettingsdialog.cpp b/src/dialog/vsettingsdialog.cpp index 8f098498..44d1e326 100644 --- a/src/dialog/vsettingsdialog.cpp +++ b/src/dialog/vsettingsdialog.cpp @@ -283,10 +283,33 @@ VGeneralTab::VGeneralTab(QWidget *p_parent) // Startup pages. QLayout *startupLayout = setupStartupPagesLayout(); + // Quick access. + m_quickAccessEdit = new VLineEdit(this); + m_quickAccessEdit->setPlaceholderText(tr("Path of file to quick access")); + m_quickAccessEdit->setToolTip(tr("Set the path of a file to quick access " + "(absolute or relative to configuration folder)")); + + QPushButton *browseBtn = new QPushButton(tr("Browse"), this); + connect(browseBtn, &QPushButton::clicked, + this, [this]() { + QString filePath = QFileDialog::getOpenFileName(this, + tr("Select File To Quick Access"), + g_config->getDocumentPathOrHomePath()); + + if (!filePath.isEmpty()) { + m_quickAccessEdit->setText(filePath); + } + }); + + QHBoxLayout *qaLayout = new QHBoxLayout(); + qaLayout->addWidget(m_quickAccessEdit); + qaLayout->addWidget(browseBtn); + QFormLayout *optionLayout = new QFormLayout(); optionLayout->addRow(tr("Language:"), m_langCombo); optionLayout->addRow(m_systemTray); optionLayout->addRow(tr("Startup pages:"), startupLayout); + optionLayout->addRow(tr("Quick access:"), qaLayout); QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->addLayout(optionLayout); @@ -363,6 +386,10 @@ bool VGeneralTab::loadConfiguration() return false; } + if (!loadQuickAccess()) { + return false; + } + return true; } @@ -380,6 +407,10 @@ bool VGeneralTab::saveConfiguration() return false; } + if (!saveQuickAccess()) { + return false; + } + return true; } @@ -466,6 +497,18 @@ bool VGeneralTab::saveStartupPageType() return true; } +bool VGeneralTab::loadQuickAccess() +{ + m_quickAccessEdit->setText(g_config->getQuickAccess()); + return true; +} + +bool VGeneralTab::saveQuickAccess() +{ + g_config->setQuickAccess(m_quickAccessEdit->text()); + return true; +} + VLookTab::VLookTab(QWidget *p_parent) : QWidget(p_parent) { diff --git a/src/dialog/vsettingsdialog.h b/src/dialog/vsettingsdialog.h index a4781e36..4d2060aa 100644 --- a/src/dialog/vsettingsdialog.h +++ b/src/dialog/vsettingsdialog.h @@ -37,6 +37,9 @@ private: bool loadStartupPageType(); bool saveStartupPageType(); + bool loadQuickAccess(); + bool saveQuickAccess(); + // Language QComboBox *m_langCombo; @@ -52,6 +55,9 @@ private: // Startup pages add files button. QPushButton *m_startupPagesAddBtn; + // Quick access note path. + VLineEdit *m_quickAccessEdit; + static const QVector c_availableLangs; }; diff --git a/src/resources/icons/quick_access.svg b/src/resources/icons/quick_access.svg new file mode 100644 index 00000000..debb0d2b --- /dev/null +++ b/src/resources/icons/quick_access.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index e8de370f..cb6e4b30 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -194,6 +194,10 @@ vim_exemption_keys=cvx ; Could be absolute path flash_page=flash_page.md +; Path of the quick access note, related to the configuration folder +; Could be absolute path +quick_access= + ; Whether close note before editting with external editor close_before_external_editor=true @@ -214,7 +218,7 @@ search_options=4,2,7,0,0,"" ; Number of items in history ; 0 to disable history -history_size=50 +history_size=100 ; View order of note list ; 0 - configuration file @@ -397,6 +401,8 @@ ActivateNextTab=Ctrl+Tab ActivatePreviousTab=Ctrl+Shift+Tab ; Activate flash page FlashPage=Ctrl+Alt+L +; Quick access note +QuickAccess=Ctrl+Alt+I ; Open via system's default program OpenViaDefaultProgram=F12 ; Full screen diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp index dede68da..adb18caf 100644 --- a/src/utils/vutils.cpp +++ b/src/utils/vutils.cpp @@ -1337,6 +1337,10 @@ bool VUtils::isControlModifierForVim(int p_modifiers) void VUtils::touchFile(const QString &p_file) { + if (p_file.isEmpty()) { + return; + } + QFile file(p_file); if (!file.open(QIODevice::WriteOnly)) { qWarning() << "fail to touch file" << p_file; diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index 3aa0cf04..7fab3605 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -1404,6 +1404,25 @@ const QString &VConfigManager::getFlashPage() const return m_flashPage; } +const QString &VConfigManager::getQuickAccess() const +{ + if (m_quickAccess.isEmpty()) { + VConfigManager *var = const_cast(this); + + var->m_quickAccess = var->getConfigFromSettings("global", + "quick_access").toString(); + if (VUtils::checkFileNameLegal(m_quickAccess)) { + var->m_quickAccess = QDir(getConfigFolder()).filePath(m_quickAccess); + } + } + + if (!m_quickAccess.isEmpty() && !QFileInfo::exists(m_quickAccess)) { + VUtils::touchFile(m_quickAccess); + } + + return m_quickAccess; +} + void VConfigManager::initThemes() { m_themes.clear(); diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index 705f662d..33c18857 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -481,6 +481,9 @@ public: const QString &getFlashPage() const; + const QString &getQuickAccess() const; + void setQuickAccess(const QString &p_path); + // All the themes. QList getThemes() const; @@ -917,6 +920,9 @@ private: // Absolute path of flash page. QString m_flashPage; + // Absolute path of quick access note. + QString m_quickAccess; + // The theme name. QString m_theme; @@ -2597,4 +2603,14 @@ inline void VConfigManager::setInsertNewNoteInFront(bool p_enabled) m_insertNewNoteInFront = p_enabled; setConfigToSettings("global", "insert_new_note_in_front", m_insertNewNoteInFront); } + +inline void VConfigManager::setQuickAccess(const QString &p_path) +{ + if (m_quickAccess == p_path) { + return; + } + + m_quickAccess = p_path; + setConfigToSettings("global", "quick_access", m_quickAccess); +} #endif // VCONFIGMANAGER_H diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp index 766897c2..8a5fa828 100644 --- a/src/veditwindow.cpp +++ b/src/veditwindow.cpp @@ -524,10 +524,10 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) QString folderPath; if (file->getType() == FileType::Note) { - const VNoteFile *tmpFile = dynamic_cast((VFile *)file); + const VNoteFile *tmpFile = static_cast((VFile *)file); folderPath = tmpFile->getNotebook()->getRecycleBinFolderPath(); } else if (file->getType() == FileType::Orphan) { - const VOrphanFile *tmpFile = dynamic_cast((VFile *)file); + const VOrphanFile *tmpFile = static_cast((VFile *)file); folderPath = tmpFile->fetchRecycleBinFolderPath(); } else { Q_ASSERT(false); @@ -598,6 +598,23 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) g_mainWin->showStatusMessage(tr("1 note pinned to History")); }); + QAction *quickAccessAct = new QAction(VIconUtils::menuIcon(":/resources/icons/quick_access.svg"), + tr("Set As Quick Access"), + &menu); + quickAccessAct->setToolTip(tr("Set this note as quick access")); + connect(quickAccessAct, &QAction::triggered, + this, [this](){ + int tab = GET_TAB_FROM_SENDER(); + Q_ASSERT(tab != -1); + + VEditTab *editor = getTab(tab); + QPointer file = editor->getFile(); + Q_ASSERT(file); + QString fp(file->fetchPath()); + g_config->setQuickAccess(fp); + g_mainWin->showStatusMessage(tr("Quick access: %1").arg(fp)); + }); + QAction *noteInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), tr("Note Info"), &menu); @@ -611,7 +628,7 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) QPointer file = editor->getFile(); Q_ASSERT(file); if (file->getType() == FileType::Note) { - VNoteFile *tmpFile = dynamic_cast((VFile *)file); + VNoteFile *tmpFile = static_cast((VFile *)file); g_mainWin->getFileList()->fileInfo(tmpFile); } else if (file->getType() == FileType::Orphan) { g_mainWin->editOrphanFileInfo(file); @@ -620,7 +637,10 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) VEditTab *editor = getTab(tab); VFile *file = editor->getFile(); - if (file->getType() == FileType::Note) { + bool isNote = file->getType() == FileType::Note; + bool isNonSystemOrphan = file->getType() == FileType::Orphan + && !(static_cast(file)->isSystemFile()); + if (isNote) { // Locate to folder. QAction *locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"), tr("Locate To Folder"), @@ -633,7 +653,9 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) menu.addAction(locateAct); menu.addSeparator(); + } + if (isNote || isNonSystemOrphan) { recycleBinAct->setData(tab); menu.addAction(recycleBinAct); @@ -649,24 +671,8 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) pinToHistoryAct->setData(tab); menu.addAction(pinToHistoryAct); - noteInfoAct->setData(tab); - menu.addAction(noteInfoAct); - } else if (file->getType() == FileType::Orphan - && !(dynamic_cast(file)->isSystemFile())) { - recycleBinAct->setData(tab); - menu.addAction(recycleBinAct); - - openLocationAct->setData(tab); - menu.addAction(openLocationAct); - - reloadAct->setData(tab); - menu.addAction(reloadAct); - - addToCartAct->setData(tab); - menu.addAction(addToCartAct); - - pinToHistoryAct->setData(tab); - menu.addAction(pinToHistoryAct); + quickAccessAct->setData(tab); + menu.addAction(quickAccessAct); noteInfoAct->setData(tab); menu.addAction(noteInfoAct); @@ -889,7 +895,7 @@ void VEditWindow::scrollToHeader(const VHeaderPointer &p_header) void VEditWindow::handleTabStatusUpdated(const VEditTabInfo &p_info) { - int idx = indexOf(dynamic_cast(sender())); + int idx = indexOf(static_cast(sender())); if (p_info.m_type == VEditTabInfo::InfoType::All) { updateTabInfo(idx); @@ -904,7 +910,7 @@ void VEditWindow::handleTabStatusUpdated(const VEditTabInfo &p_info) void VEditWindow::handleTabStatusMessage(const QString &p_msg) { - int idx = indexOf(dynamic_cast(sender())); + int idx = indexOf(static_cast(sender())); if (idx == currentIndex()) { emit statusMessage(p_msg); } @@ -912,7 +918,7 @@ void VEditWindow::handleTabStatusMessage(const QString &p_msg) void VEditWindow::handleTabVimStatusUpdated(const VVim *p_vim) { - int idx = indexOf(dynamic_cast(sender())); + int idx = indexOf(static_cast(sender())); if (idx == currentIndex()) { emit vimStatusUpdated(p_vim); } @@ -1149,7 +1155,7 @@ bool VEditWindow::showOpenedFileList() } leftBtn->showMenu(); - VOpenedListMenu *menu = dynamic_cast(leftBtn->menu()); + VOpenedListMenu *menu = static_cast(leftBtn->menu()); return menu->isAccepted(); } diff --git a/src/vfilelist.cpp b/src/vfilelist.cpp index 7add885f..8ec5cc83 100644 --- a/src/vfilelist.cpp +++ b/src/vfilelist.cpp @@ -237,6 +237,17 @@ void VFileList::pinFileToHistory() const .arg(items.size() > 1 ? tr("notes") : tr("note"))); } +void VFileList::setFileQuickAccess() const +{ + QList items = fileList->selectedItems(); + if (items.size() == 1) { + QString fp(getVFile(items[0])->fetchPath()); + + g_config->setQuickAccess(fp); + g_mainWin->showStatusMessage(tr("Quick access: %1").arg(fp)); + } +} + void VFileList::fileInfo(VNoteFile *p_file) { if (!p_file) { @@ -665,6 +676,14 @@ void VFileList::contextMenuRequested(QPoint pos) this, &VFileList::pinFileToHistory); menu.addAction(pinToHistoryAct); + QAction *quickAccessAct = new QAction(VIconUtils::menuIcon(":/resources/icons/quick_access.svg"), + tr("Set As Quick Access"), + &menu); + quickAccessAct->setToolTip(tr("Set current note as quick access")); + connect(quickAccessAct, &QAction::triggered, + this, &VFileList::setFileQuickAccess); + menu.addAction(quickAccessAct); + if (selectedSize == 1) { QAction *fileInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), tr("&Info (Rename)\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)), diff --git a/src/vfilelist.h b/src/vfilelist.h index b5975525..2b6ac9a3 100644 --- a/src/vfilelist.h +++ b/src/vfilelist.h @@ -93,6 +93,8 @@ private slots: // Add selected files to History and pin them. void pinFileToHistory() const; + void setFileQuickAccess() const; + // Copy selected files to clipboard. // Will put a Json string into the clipboard which contains the information // about copied files. diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index 7803d614..8a436e28 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -640,6 +640,20 @@ QToolBar *VMainWindow::initNoteToolBar(QSize p_iconSize) connect(flashPageAct, &QAction::triggered, this, &VMainWindow::openFlashPage); + QAction *quickAccessAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/quick_access.svg"), + tr("Quick Access"), + this); + quickAccessAct->setStatusTip(tr("Open quick access note")); + keySeq = g_config->getShortcutKeySequence("QuickAccess"); + seq = QKeySequence(keySeq); + if (!seq.isEmpty()) { + quickAccessAct->setText(tr("Quick Access\t%1").arg(VUtils::getShortcutText(keySeq))); + quickAccessAct->setShortcut(seq); + } + + connect(quickAccessAct, &QAction::triggered, + this, &VMainWindow::openQuickAccess); + QAction *universalEntryAct = new QAction(VIconUtils::toolButtonIcon(":/resources/icons/universal_entry_tb.svg"), tr("Universal Entry"), this); @@ -656,6 +670,7 @@ QToolBar *VMainWindow::initNoteToolBar(QSize p_iconSize) m_noteToolBar->addWidget(m_attachmentBtn); m_noteToolBar->addAction(flashPageAct); + m_noteToolBar->addAction(quickAccessAct); m_noteToolBar->addAction(universalEntryAct); return m_noteToolBar; @@ -2857,6 +2872,24 @@ void VMainWindow::openFlashPage() true); } +void VMainWindow::openQuickAccess() +{ + const QString &qaPath = g_config->getQuickAccess(); + if (qaPath.isEmpty()) { + VUtils::showMessage(QMessageBox::Information, + tr("Info"), + tr("Quick Access is not set."), + tr("Please specify the note for Quick Access in the settings dialog " + "or the context menu of a note."), + QMessageBox::Ok, + QMessageBox::Ok, + this); + return; + } + + openFiles(QStringList(qaPath), false, g_config->getNoteOpenMode()); +} + void VMainWindow::initHeadingButton(QToolBar *p_tb) { m_headingBtn = new QPushButton(VIconUtils::toolButtonIcon(":/resources/icons/heading.svg"), diff --git a/src/vmainwindow.h b/src/vmainwindow.h index 43ec0392..0751ed10 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -194,6 +194,8 @@ private slots: // Open flash page in edit mode. void openFlashPage(); + void openQuickAccess(); + void customShortcut(); void toggleEditReadMode(); diff --git a/src/vnote.qrc b/src/vnote.qrc index 72567e0f..6edb4a6a 100644 --- a/src/vnote.qrc +++ b/src/vnote.qrc @@ -270,5 +270,6 @@ utils/turndown/turndown.js utils/turndown/turndown-plugin-gfm.js resources/common.css + resources/icons/quick_access.svg