From ace96c7ce235e9993ba95d17363d8b6b2fa90e2d Mon Sep 17 00:00:00 2001 From: Le Tan Date: Wed, 4 Oct 2017 15:07:31 +0800 Subject: [PATCH] support compact mode in main window Add enable_compact_mode config. --- README.md | 5 +- README_zh.md | 5 +- src/resources/icons/compact_mode.svg | 10 + src/resources/vnote.ini | 3 + src/vcaptain.cpp | 4 +- src/vconfigmanager.cpp | 4 + src/vconfigmanager.h | 38 ++++ src/vmainwindow.cpp | 307 +++++++++++++++++++-------- src/vmainwindow.h | 37 +++- src/vnote.qrc | 1 + 10 files changed, 316 insertions(+), 98 deletions(-) create mode 100644 src/resources/icons/compact_mode.svg diff --git a/README.md b/README.md index 84de95a3..6a5689e6 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,8 @@ Utilizing Qt, VNote could run on **Linux**, **Windows**, and **macOS** (due to t - Supports infinite levels of folders; - Supports multiple tabs and splitting windows; - Supports [Mermaid](http://knsv.github.io/mermaid/), [Flowchart.js](http://flowchart.js.org/), and [MathJax](https://www.mathjax.org/); -- Supports HiDPI. +- Supports HiDPI; +- Supports attachments of notes. ![VNote Edit](screenshots/vnote_edit.gif) @@ -199,7 +200,7 @@ If you prefer command line on macOS, you could follow these steps. 5. Now you got the bundle `path/to/project/build/src/VNote.app`. Enjoy yourself! # Dependencies -- [Qt 5.7](http://qt-project.org) (L-GPL v3) +- [Qt 5.9](http://qt-project.org) (L-GPL v3) - [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License) - [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License) - [Marked](https://github.com/chjj/marked) (MIT License) diff --git a/README_zh.md b/README_zh.md index e7a149ef..df101c69 100644 --- a/README_zh.md +++ b/README_zh.md @@ -54,8 +54,9 @@ VNote不是一个简单的Markdown编辑器。通过提供笔记管理功能,V - 支持Vim模式以及一系列强大的快捷键; - 支持无限层级的文件夹; - 支持多个标签页和窗口分割; -- 支持[Mermaid](http://knsv.github.io/mermaid/), [Flowchart.js](http://flowchart.js.org/) 和 [MathJax](https://www.mathjax.org/); +- 支持[Mermaid](http://knsv.github.io/mermaid/), [Flowchart.js](http://flowchart.js.org/) 和 [MathJax](https://www.mathjax.org/); - 支持高分辨率; +- 支持笔记附件。 ![VNote Edit](screenshots/vnote_edit.gif) @@ -203,7 +204,7 @@ sudo make install 5. 此时得到VNote的Bundle `path/to/project/build/src/VNote.app`,打开即可。 # 依赖 -- [Qt 5.7](http://qt-project.org) (L-GPL v3) +- [Qt 5.9](http://qt-project.org) (L-GPL v3) - [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License) - [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License) - [Marked](https://github.com/chjj/marked) (MIT License) diff --git a/src/resources/icons/compact_mode.svg b/src/resources/icons/compact_mode.svg new file mode 100644 index 00000000..6cc49aa2 --- /dev/null +++ b/src/resources/icons/compact_mode.svg @@ -0,0 +1,10 @@ + + + one_panel + + Layer 1 + + + + + diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 564adf03..d373b72e 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -135,6 +135,9 @@ confirm_reload_folder=true ; Whether double click on a tab to close it double_click_close_tab=true +; Whether put folder and note panel in one vertical column +enable_compact_mode=false + [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 diff --git a/src/vcaptain.cpp b/src/vcaptain.cpp index 9fc49504..093f1e6f 100644 --- a/src/vcaptain.cpp +++ b/src/vcaptain.cpp @@ -276,7 +276,7 @@ bool VCaptain::handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers) m_mainWindow->editArea->removeCurrentWindow(); QWidget *nextFocus = m_mainWindow->editArea->currentEditTab(); - m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->fileList; + m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->getFileList(); break; } @@ -305,7 +305,7 @@ bool VCaptain::handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers) // m_widgetBeforeCaptain may be the closed tab which will cause crash. QWidget *nextFocus = m_mainWindow->editArea->currentEditTab(); - m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->fileList; + m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->getFileList(); break; } diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index 7a9de545..84426b18 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -95,6 +95,7 @@ void VConfigManager::initialize() m_mainWindowGeometry = getConfigFromSettings("session", "main_window_geometry").toByteArray(); m_mainWindowState = getConfigFromSettings("session", "main_window_state").toByteArray(); m_mainSplitterState = getConfigFromSettings("session", "main_splitter_state").toByteArray(); + m_naviSplitterState = getConfigFromSettings("session", "navi_splitter_state").toByteArray(); m_findCaseSensitive = getConfigFromSettings("global", "find_case_sensitive").toBool(); @@ -227,6 +228,9 @@ void VConfigManager::initialize() m_doubleClickCloseTab = getConfigFromSettings("global", "double_click_close_tab").toBool(); + + m_enableCompactMode = getConfigFromSettings("global", + "enable_compact_mode").toBool(); } void VConfigManager::readPredefinedColorsFromSettings() diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index 5212c4a0..7485ff0d 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -153,6 +153,9 @@ public: const QByteArray &getMainSplitterState() const; void setMainSplitterState(const QByteArray &p_state); + const QByteArray &getNaviSplitterState() const; + void setNaviSplitterState(const QByteArray &p_state); + bool getFindCaseSensitive() const; void setFindCaseSensitive(bool p_enabled); @@ -291,6 +294,9 @@ public: // Whether user specify template_code_block_css_url directly. bool getUserSpecifyTemplateCodeBlockCssUrl() const; + bool getEnableCompactMode() const; + void setEnableCompactMode(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; @@ -429,6 +435,7 @@ private: QByteArray m_mainWindowGeometry; QByteArray m_mainWindowState; QByteArray m_mainSplitterState; + QByteArray m_naviSplitterState; // Find/Replace dialog options bool m_findCaseSensitive; @@ -600,6 +607,9 @@ private: // Whether double click on a tab to close it. bool m_doubleClickCloseTab; + // Whether put folder and note panel in one single column. + bool m_enableCompactMode; + // The name of the config file in each directory, obsolete. // Use c_dirConfigFile instead. static const QString c_obsoleteDirConfigFile; @@ -609,8 +619,10 @@ private: // The name of the default configuration file static const QString defaultConfigFilePath; + // QSettings for the user configuration QSettings *userSettings; + // Qsettings for @defaultConfigFileName QSettings *defaultSettings; @@ -899,6 +911,17 @@ inline void VConfigManager::setMainSplitterState(const QByteArray &p_state) setConfigToSettings("session", "main_splitter_state", m_mainSplitterState); } +inline const QByteArray& VConfigManager::getNaviSplitterState() const +{ + return m_naviSplitterState; +} + +inline void VConfigManager::setNaviSplitterState(const QByteArray &p_state) +{ + m_naviSplitterState = p_state; + setConfigToSettings("session", "navi_splitter_state", m_naviSplitterState); +} + inline bool VConfigManager::getFindCaseSensitive() const { return m_findCaseSensitive; @@ -1570,4 +1593,19 @@ inline bool VConfigManager::getUserSpecifyTemplateCodeBlockCssUrl() const return !m_templateCodeBlockCssUrl.isEmpty(); } +inline bool VConfigManager::getEnableCompactMode() const +{ + return m_enableCompactMode; +} + +inline void VConfigManager::setEnableCompactMode(bool p_enabled) +{ + if (m_enableCompactMode == p_enabled) { + return; + } + + m_enableCompactMode = p_enabled; + setConfigToSettings("global", "enable_compact_mode", m_enableCompactMode); +} + #endif // VCONFIGMANAGER_H diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index fe1a0eec..9e70fc90 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -41,7 +41,7 @@ extern QFile g_logFile; #endif VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent) - : QMainWindow(p_parent), m_onePanel(false), m_guard(p_guard), + : QMainWindow(p_parent), m_guard(p_guard), m_windowOldState(Qt::WindowNoState), m_requestQuit(false) { setWindowIcon(QIcon(":/resources/icons/vnote.ico")); @@ -50,6 +50,12 @@ VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent) vnote->initPalette(palette()); initPredefinedColorPixmaps(); + if (g_config->getEnableCompactMode()) { + m_panelViewState = PanelViewState::CompactMode; + } else { + m_panelViewState = PanelViewState::TwoPanels; + } + setupUI(); initMenuBar(); @@ -58,6 +64,9 @@ VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent) initAvatar(); restoreStateAndGeometry(); + + changePanelView(m_panelViewState); + setContextMenuPolicy(Qt::NoContextMenu); notebookSelector->update(); @@ -88,7 +97,7 @@ void VMainWindow::initCaptain() m_captain->registerNavigationTarget(notebookSelector); m_captain->registerNavigationTarget(directoryTree); - m_captain->registerNavigationTarget(fileList); + m_captain->registerNavigationTarget(m_fileList); m_captain->registerNavigationTarget(editArea); m_captain->registerNavigationTarget(outline); } @@ -97,29 +106,29 @@ void VMainWindow::setupUI() { QWidget *directoryPanel = setupDirectoryPanel(); - fileList = new VFileList(); - fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); + m_fileList = new VFileList(); + m_fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); editArea = new VEditArea(vnote); editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_findReplaceDialog = editArea->getFindReplaceDialog(); - fileList->setEditArea(editArea); + m_fileList->setEditArea(editArea); directoryTree->setEditArea(editArea); notebookSelector->setEditArea(editArea); // Main Splitter - mainSplitter = new QSplitter(); - mainSplitter->setObjectName("MainSplitter"); - mainSplitter->addWidget(directoryPanel); - mainSplitter->addWidget(fileList); - mainSplitter->addWidget(editArea); - mainSplitter->setStretchFactor(0, 0); - mainSplitter->setStretchFactor(1, 0); - mainSplitter->setStretchFactor(2, 1); + m_mainSplitter = new QSplitter(); + m_mainSplitter->setObjectName("MainSplitter"); + m_mainSplitter->addWidget(directoryPanel); + m_mainSplitter->addWidget(m_fileList); + m_mainSplitter->addWidget(editArea); + m_mainSplitter->setStretchFactor(0, 0); + m_mainSplitter->setStretchFactor(1, 0); + m_mainSplitter->setStretchFactor(2, 1); // Signals connect(directoryTree, &VDirectoryTree::currentDirectoryChanged, - fileList, &VFileList::setDirectory); + m_fileList, &VFileList::setDirectory); connect(directoryTree, &VDirectoryTree::directoryUpdated, editArea, &VEditArea::handleDirectoryUpdated); @@ -133,11 +142,11 @@ void VMainWindow::setupUI() } }); - connect(fileList, &VFileList::fileClicked, + connect(m_fileList, &VFileList::fileClicked, editArea, &VEditArea::openFile); - connect(fileList, &VFileList::fileCreated, + connect(m_fileList, &VFileList::fileCreated, editArea, &VEditArea::openFile); - connect(fileList, &VFileList::fileUpdated, + connect(m_fileList, &VFileList::fileUpdated, editArea, &VEditArea::handleFileUpdated); connect(editArea, &VEditArea::tabStatusUpdated, this, &VMainWindow::handleAreaTabStatusUpdated); @@ -148,7 +157,7 @@ void VMainWindow::setupUI() connect(m_findReplaceDialog, &VFindReplaceDialog::findTextChanged, this, &VMainWindow::handleFindDialogTextChanged); - setCentralWidget(mainSplitter); + setCentralWidget(m_mainSplitter); m_vimIndicator = new VVimIndicator(this); m_vimIndicator->hide(); @@ -165,26 +174,49 @@ void VMainWindow::setupUI() QWidget *VMainWindow::setupDirectoryPanel() { + // Notebook selector. notebookLabel = new QLabel(tr("Notebooks")); notebookLabel->setProperty("TitleLabel", true); notebookLabel->setProperty("NotebookPanel", true); - directoryLabel = new QLabel(tr("Folders")); - directoryLabel->setProperty("TitleLabel", true); - directoryLabel->setProperty("NotebookPanel", true); notebookSelector = new VNotebookSelector(vnote); notebookSelector->setObjectName("NotebookSelector"); notebookSelector->setProperty("NotebookPanel", true); notebookSelector->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); + // Navigation panel. + directoryLabel = new QLabel(tr("Folders")); + directoryLabel->setProperty("TitleLabel", true); + directoryLabel->setProperty("NotebookPanel", true); + directoryTree = new VDirectoryTree; directoryTree->setProperty("NotebookPanel", true); + QVBoxLayout *naviLayout = new QVBoxLayout; + naviLayout->addWidget(directoryLabel); + naviLayout->addWidget(directoryTree); + naviLayout->setContentsMargins(0, 0, 0, 0); + naviLayout->setSpacing(0); + QWidget *naviWidget = new QWidget(); + naviWidget->setLayout(naviLayout); + + QWidget *tmpWidget = new QWidget(); + + // Compact splitter. + m_naviSplitter = new QSplitter(); + m_naviSplitter->setOrientation(Qt::Vertical); + m_naviSplitter->setObjectName("NaviSplitter"); + m_naviSplitter->addWidget(naviWidget); + m_naviSplitter->addWidget(tmpWidget); + m_naviSplitter->setStretchFactor(0, 0); + m_naviSplitter->setStretchFactor(1, 1); + + tmpWidget->hide(); + QVBoxLayout *nbLayout = new QVBoxLayout; nbLayout->addWidget(notebookLabel); nbLayout->addWidget(notebookSelector); - nbLayout->addWidget(directoryLabel); - nbLayout->addWidget(directoryTree); + nbLayout->addWidget(m_naviSplitter); nbLayout->setContentsMargins(0, 0, 0, 0); nbLayout->setSpacing(0); QWidget *nbContainer = new QWidget(); @@ -226,24 +258,62 @@ void VMainWindow::initViewToolBar(QSize p_iconSize) viewToolBar->setIconSize(p_iconSize); } + m_viewActGroup = new QActionGroup(this); QAction *onePanelViewAct = new QAction(QIcon(":/resources/icons/one_panel.svg"), - tr("&Single Panel"), this); + tr("&Single Panel"), + m_viewActGroup); onePanelViewAct->setStatusTip(tr("Display only the notes list panel")); onePanelViewAct->setToolTip(tr("Single Panel (Ctrl+E P)")); - connect(onePanelViewAct, &QAction::triggered, - this, &VMainWindow::onePanelView); + onePanelViewAct->setCheckable(true); + onePanelViewAct->setData((int)PanelViewState::SinglePanel); QAction *twoPanelViewAct = new QAction(QIcon(":/resources/icons/two_panels.svg"), - tr("&Two Panels"), this); + tr("&Two Panels"), + m_viewActGroup); twoPanelViewAct->setStatusTip(tr("Display both the folders and notes list panel")); twoPanelViewAct->setToolTip(tr("Two Panels (Ctrl+E P)")); - connect(twoPanelViewAct, &QAction::triggered, - this, &VMainWindow::twoPanelView); + twoPanelViewAct->setCheckable(true); + twoPanelViewAct->setData((int)PanelViewState::TwoPanels); + + QAction *compactViewAct = new QAction(QIcon(":/resources/icons/compact_mode.svg"), + tr("&Compact Mode"), + m_viewActGroup); + compactViewAct->setStatusTip(tr("Integrate the folders and notes list panel in one column")); + compactViewAct->setCheckable(true); + compactViewAct->setData((int)PanelViewState::CompactMode); + + connect(m_viewActGroup, &QActionGroup::triggered, + this, [this](QAction *p_action) { + if (!p_action) { + return; + } + + int act = p_action->data().toInt(); + switch (act) { + case (int)PanelViewState::SinglePanel: + onePanelView(); + break; + + case (int)PanelViewState::TwoPanels: + twoPanelView(); + break; + + case (int)PanelViewState::CompactMode: + m_panelViewState = PanelViewState::CompactMode; + g_config->setEnableCompactMode(true); + changePanelView(m_panelViewState); + break; + + default: + break; + } + }); QMenu *panelMenu = new QMenu(this); panelMenu->setToolTipsVisible(true); panelMenu->addAction(onePanelViewAct); panelMenu->addAction(twoPanelViewAct); + panelMenu->addAction(compactViewAct); expandViewAct = new QAction(QIcon(":/resources/icons/expand.svg"), tr("Expand (Ctrl+E E)"), this); @@ -251,7 +321,11 @@ void VMainWindow::initViewToolBar(QSize p_iconSize) expandViewAct->setCheckable(true); expandViewAct->setMenu(panelMenu); connect(expandViewAct, &QAction::triggered, - this, &VMainWindow::expandPanelView); + this, [this](bool p_checked) { + // Recover m_panelViewState or change to expand mode. + changePanelView(p_checked ? PanelViewState::ExpandMode + : m_panelViewState); + }); viewToolBar->addAction(expandViewAct); } @@ -378,7 +452,7 @@ void VMainWindow::initFileToolBar(QSize p_iconSize) qDebug() << "set NewNote shortcut to" << keySeq; newNoteAct->setShortcut(QKeySequence(keySeq)); connect(newNoteAct, &QAction::triggered, - fileList, &VFileList::newFile); + m_fileList, &VFileList::newFile); noteInfoAct = new QAction(QIcon(":/resources/icons/note_info_tb.svg"), tr("Note &Info"), this); @@ -1064,7 +1138,7 @@ void VMainWindow::importNoteFromFile() lastPath = QFileInfo(files[0]).path(); QString msg; - if (!fileList->importFiles(files, &msg)) { + if (!m_fileList->importFiles(files, &msg)) { VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to create notes for all the files."), @@ -1694,65 +1768,119 @@ void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info) void VMainWindow::onePanelView() { - changeSplitterView(1); - expandViewAct->setChecked(false); - m_onePanel = true; + m_panelViewState = PanelViewState::SinglePanel; + g_config->setEnableCompactMode(false); + changePanelView(m_panelViewState); } void VMainWindow::twoPanelView() { - changeSplitterView(2); - expandViewAct->setChecked(false); - m_onePanel = false; + m_panelViewState = PanelViewState::TwoPanels; + g_config->setEnableCompactMode(false); + changePanelView(m_panelViewState); } void VMainWindow::toggleOnePanelView() { - if (m_onePanel) { - twoPanelView(); - } else { + if (m_panelViewState == PanelViewState::TwoPanels) { onePanelView(); + } else { + twoPanelView(); } } -void VMainWindow::expandPanelView(bool p_checked) +void VMainWindow::enableCompactMode(bool p_enabled) { - int nrSplits = 0; - if (p_checked) { - nrSplits = 0; + const int fileListIdx = 1; + bool isCompactMode = m_naviSplitter->indexOf(m_fileList) != -1; + if (p_enabled) { + // Change to compact mode. + if (isCompactMode) { + return; + } + + // Take m_fileList out of m_mainSplitter. + QWidget *tmpWidget = new QWidget(this); + Q_ASSERT(fileListIdx == m_mainSplitter->indexOf(m_fileList)); + m_fileList->hide(); + m_mainSplitter->replaceWidget(fileListIdx, tmpWidget); + tmpWidget->hide(); + + // Insert m_fileList into m_naviSplitter. + QWidget *wid = m_naviSplitter->replaceWidget(fileListIdx, m_fileList); + delete wid; + + m_fileList->show(); } else { - if (m_onePanel) { - nrSplits = 1; + // Disable compact mode and go back to two panels view. + if (!isCompactMode) { + return; + } + + // Take m_fileList out of m_naviSplitter. + Q_ASSERT(fileListIdx == m_naviSplitter->indexOf(m_fileList)); + QWidget *tmpWidget = new QWidget(this); + m_fileList->hide(); + m_naviSplitter->replaceWidget(fileListIdx, tmpWidget); + tmpWidget->hide(); + + // Insert m_fileList into m_mainSplitter. + QWidget *wid = m_mainSplitter->replaceWidget(fileListIdx, m_fileList); + delete wid; + + m_fileList->show(); + } +} + +void VMainWindow::changePanelView(PanelViewState p_state) +{ + switch (p_state) { + case PanelViewState::ExpandMode: + m_mainSplitter->widget(0)->hide(); + m_mainSplitter->widget(1)->hide(); + m_mainSplitter->widget(2)->show(); + break; + + case PanelViewState::SinglePanel: + enableCompactMode(false); + + m_mainSplitter->widget(0)->hide(); + m_mainSplitter->widget(1)->show(); + m_mainSplitter->widget(2)->show(); + break; + + case PanelViewState::TwoPanels: + enableCompactMode(false); + + m_mainSplitter->widget(0)->show(); + m_mainSplitter->widget(1)->show(); + m_mainSplitter->widget(2)->show(); + break; + + case PanelViewState::CompactMode: + m_mainSplitter->widget(0)->show(); + m_mainSplitter->widget(1)->hide(); + m_mainSplitter->widget(2)->show(); + + enableCompactMode(true); + break; + + default: + break; + } + + // Change the action state. + QList acts = m_viewActGroup->actions(); + for (auto & act : acts) { + if (act->data().toInt() == (int)p_state) { + act->setChecked(true); } else { - nrSplits = 2; + act->setChecked(false); } } - changeSplitterView(nrSplits); -} -void VMainWindow::changeSplitterView(int nrPanel) -{ - switch (nrPanel) { - case 0: - // Expand - mainSplitter->widget(0)->hide(); - mainSplitter->widget(1)->hide(); - mainSplitter->widget(2)->show(); - break; - case 1: - // Single panel - mainSplitter->widget(0)->hide(); - mainSplitter->widget(1)->show(); - mainSplitter->widget(2)->show(); - break; - case 2: - // Two panels - mainSplitter->widget(0)->show(); - mainSplitter->widget(1)->show(); - mainSplitter->widget(2)->show(); - break; - default: - qWarning() << "invalid panel number" << nrPanel; + if (p_state != PanelViewState::ExpandMode) { + expandViewAct->setChecked(false); } } @@ -1772,7 +1900,7 @@ void VMainWindow::curEditFileInfo() if (m_curFile->getType() == FileType::Note) { VNoteFile *file = dynamic_cast((VFile *)m_curFile); Q_ASSERT(file); - fileList->fileInfo(file); + m_fileList->fileInfo(file); } else if (m_curFile->getType() == FileType::Orphan) { VOrphanFile *file = dynamic_cast((VFile *)m_curFile); Q_ASSERT(file); @@ -1789,7 +1917,7 @@ void VMainWindow::deleteCurNote() } VNoteFile *file = dynamic_cast((VFile *)m_curFile); - fileList->deleteFile(file); + m_fileList->deleteFile(file); } void VMainWindow::closeEvent(QCloseEvent *event) @@ -1843,14 +1971,17 @@ void VMainWindow::closeEvent(QCloseEvent *event) void VMainWindow::saveStateAndGeometry() { - // In one panel view, it will save the wrong state that the directory tree - // panel has a width of zero. - twoPanelView(); - g_config->setMainWindowGeometry(saveGeometry()); g_config->setMainWindowState(saveState()); g_config->setToolsDockChecked(toolDock->isVisible()); - g_config->setMainSplitterState(mainSplitter->saveState()); + + // In one panel view, it will save the wrong state that the directory tree + // panel has a width of zero. + changePanelView(PanelViewState::TwoPanels); + g_config->setMainSplitterState(m_mainSplitter->saveState()); + + changePanelView(PanelViewState::CompactMode); + g_config->setNaviSplitterState(m_naviSplitter->saveState()); } void VMainWindow::restoreStateAndGeometry() @@ -1864,9 +1995,15 @@ void VMainWindow::restoreStateAndGeometry() restoreState(state); } toolDock->setVisible(g_config->getToolsDockChecked()); + const QByteArray &splitterState = g_config->getMainSplitterState(); if (!splitterState.isEmpty()) { - mainSplitter->restoreState(splitterState); + m_mainSplitter->restoreState(splitterState); + } + + const QByteArray &naviSplitterState = g_config->getNaviSplitterState(); + if (!naviSplitterState.isEmpty()) { + m_naviSplitter->restoreState(naviSplitterState); } } @@ -1908,7 +2045,7 @@ void VMainWindow::keyPressEvent(QKeyEvent *event) void VMainWindow::repositionAvatar() { - int diameter = mainSplitter->pos().y(); + int diameter = m_mainSplitter->pos().y(); int x = width() - diameter - 5; int y = 0; qDebug() << "avatar:" << diameter << x << y; @@ -1942,13 +2079,13 @@ bool VMainWindow::locateFile(VFile *p_file) VDirectory *dir = file->getDirectory(); if (directoryTree->locateDirectory(dir)) { - while (fileList->currentDirectory() != dir) { + while (m_fileList->currentDirectory() != dir) { QCoreApplication::sendPostedEvents(); } - if (fileList->locateFile(file)) { + if (m_fileList->locateFile(file)) { ret = true; - fileList->setFocus(); + m_fileList->setFocus(); } } } diff --git a/src/vmainwindow.h b/src/vmainwindow.h index a0e1bc61..60a2740f 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -38,6 +38,15 @@ class QShortcut; class VButtonWithWidget; class VAttachmentList; +enum class PanelViewState +{ + ExpandMode, + SinglePanel, + TwoPanels, + CompactMode, + Invalid +}; + class VMainWindow : public QMainWindow { Q_OBJECT @@ -105,7 +114,6 @@ private slots: void changeHighlightTrailingSapce(bool p_checked); void onePanelView(); void twoPanelView(); - void expandPanelView(bool p_checked); void curEditFileInfo(); void deleteCurNote(); void handleCurrentDirectoryChanged(const VDirectory *p_dir); @@ -127,6 +135,9 @@ private slots: void printNote(); void exportAsPDF(); + // Set the panel view properly. + void enableCompactMode(bool p_enabled); + // Handle Vim status updated. void handleVimStatusUpdated(const VVim *p_vim); @@ -186,7 +197,6 @@ private: void initEditorLineNumberMenu(QMenu *p_menu); void initEditorStyleMenu(QMenu *p_emnu); - void changeSplitterView(int nrPanel); void updateWindowTitle(const QString &str); void updateActionStateFromTabStatusChange(const VFile *p_file, bool p_editMode); @@ -213,6 +223,10 @@ private: // Init system tray icon and correspondign context menu. void initTrayIcon(); + // Change the panel view according to @p_state. + // Will not change m_panelViewState. + void changePanelView(PanelViewState p_state); + VNote *vnote; QPointer m_curFile; QPointer m_curTab; @@ -222,9 +236,16 @@ private: QLabel *notebookLabel; QLabel *directoryLabel; VNotebookSelector *notebookSelector; - VFileList *fileList; + VFileList *m_fileList; VDirectoryTree *directoryTree; - QSplitter *mainSplitter; + + // Splitter for directory | files | edit. + QSplitter *m_mainSplitter; + + // Splitter for directory | files. + // Move directory and file panel in one compact vertical split. + QSplitter *m_naviSplitter; + VEditArea *editArea; QDockWidget *toolDock; QToolBox *toolBox; @@ -234,8 +255,7 @@ private: VVimIndicator *m_vimIndicator; VTabIndicator *m_tabIndicator; - // Whether it is one panel or two panles. - bool m_onePanel; + PanelViewState m_panelViewState; // Actions QAction *newRootDirAct; @@ -269,6 +289,9 @@ private: // Act group for code block render styles. QActionGroup *m_codeBlockStyleActs; + // Act group for panel view actions. + QActionGroup *m_viewActGroup; + QShortcut *m_closeNoteShortcut; // Menus @@ -306,7 +329,7 @@ private: inline VFileList *VMainWindow::getFileList() const { - return fileList; + return m_fileList; } #endif // VMAINWINDOW_H diff --git a/src/vnote.qrc b/src/vnote.qrc index 5783fc0b..267d34c7 100644 --- a/src/vnote.qrc +++ b/src/vnote.qrc @@ -130,5 +130,6 @@ resources/icons/delete_attachment.svg resources/icons/sort.svg resources/icons/create_subdir.svg + resources/icons/compact_mode.svg