support compact mode in main window

Add enable_compact_mode config.
This commit is contained in:
Le Tan 2017-10-04 15:07:31 +08:00
parent 2f61ded269
commit ace96c7ce2
10 changed files with 316 additions and 98 deletions

View File

@ -54,7 +54,8 @@ Utilizing Qt, VNote could run on **Linux**, **Windows**, and **macOS** (due to t
- Supports infinite levels of folders; - Supports infinite levels of folders;
- Supports multiple tabs and splitting windows; - 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 [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) ![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! 5. Now you got the bundle `path/to/project/build/src/VNote.app`. Enjoy yourself!
# Dependencies # 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) - [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License)
- [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License) - [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License)
- [Marked](https://github.com/chjj/marked) (MIT License) - [Marked](https://github.com/chjj/marked) (MIT License)

View File

@ -54,8 +54,9 @@ VNote不是一个简单的Markdown编辑器。通过提供笔记管理功能V
- 支持Vim模式以及一系列强大的快捷键 - 支持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) ![VNote Edit](screenshots/vnote_edit.gif)
@ -203,7 +204,7 @@ sudo make install
5. 此时得到VNote的Bundle `path/to/project/build/src/VNote.app`,打开即可。 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) - [PEG Markdown Highlight](http://hasseg.org/peg-markdown-highlight/) (MIT License)
- [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License) - [Hoedown 3.0.7](https://github.com/hoedown/hoedown/) (ISC License)
- [Marked](https://github.com/chjj/marked) (MIT License) - [Marked](https://github.com/chjj/marked) (MIT License)

View File

@ -0,0 +1,10 @@
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<title>one_panel</title>
<g>
<title>Layer 1</title>
<rect fill="none" stroke="#000000" stroke-width="40" x="58" y="57" width="395" height="395" id="svg_1"/>
<line fill="none" stroke="#000000" stroke-width="40" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" x1="193" y1="61" x2="193" y2="455" id="svg_4"/>
<line stroke="#000000" transform="rotate(-90 125.49999237060548,220.1999969482422) " id="svg_2" fill="none" stroke-width="40" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" x1="125.49999" y1="169.7" x2="125.49999" y2="270.7"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 780 B

View File

@ -135,6 +135,9 @@ confirm_reload_folder=true
; Whether double click on a tab to close it ; Whether double click on a tab to close it
double_click_close_tab=true double_click_close_tab=true
; Whether put folder and note panel in one vertical column
enable_compact_mode=false
[web] [web]
; Location and configuration for Mathjax ; Location and configuration for Mathjax
mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML

View File

@ -276,7 +276,7 @@ bool VCaptain::handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers)
m_mainWindow->editArea->removeCurrentWindow(); m_mainWindow->editArea->removeCurrentWindow();
QWidget *nextFocus = m_mainWindow->editArea->currentEditTab(); QWidget *nextFocus = m_mainWindow->editArea->currentEditTab();
m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->fileList; m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->getFileList();
break; 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. // m_widgetBeforeCaptain may be the closed tab which will cause crash.
QWidget *nextFocus = m_mainWindow->editArea->currentEditTab(); QWidget *nextFocus = m_mainWindow->editArea->currentEditTab();
m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->fileList; m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->getFileList();
break; break;
} }

View File

@ -95,6 +95,7 @@ void VConfigManager::initialize()
m_mainWindowGeometry = getConfigFromSettings("session", "main_window_geometry").toByteArray(); m_mainWindowGeometry = getConfigFromSettings("session", "main_window_geometry").toByteArray();
m_mainWindowState = getConfigFromSettings("session", "main_window_state").toByteArray(); m_mainWindowState = getConfigFromSettings("session", "main_window_state").toByteArray();
m_mainSplitterState = getConfigFromSettings("session", "main_splitter_state").toByteArray(); m_mainSplitterState = getConfigFromSettings("session", "main_splitter_state").toByteArray();
m_naviSplitterState = getConfigFromSettings("session", "navi_splitter_state").toByteArray();
m_findCaseSensitive = getConfigFromSettings("global", m_findCaseSensitive = getConfigFromSettings("global",
"find_case_sensitive").toBool(); "find_case_sensitive").toBool();
@ -227,6 +228,9 @@ void VConfigManager::initialize()
m_doubleClickCloseTab = getConfigFromSettings("global", m_doubleClickCloseTab = getConfigFromSettings("global",
"double_click_close_tab").toBool(); "double_click_close_tab").toBool();
m_enableCompactMode = getConfigFromSettings("global",
"enable_compact_mode").toBool();
} }
void VConfigManager::readPredefinedColorsFromSettings() void VConfigManager::readPredefinedColorsFromSettings()

View File

@ -153,6 +153,9 @@ public:
const QByteArray &getMainSplitterState() const; const QByteArray &getMainSplitterState() const;
void setMainSplitterState(const QByteArray &p_state); void setMainSplitterState(const QByteArray &p_state);
const QByteArray &getNaviSplitterState() const;
void setNaviSplitterState(const QByteArray &p_state);
bool getFindCaseSensitive() const; bool getFindCaseSensitive() const;
void setFindCaseSensitive(bool p_enabled); void setFindCaseSensitive(bool p_enabled);
@ -291,6 +294,9 @@ public:
// Whether user specify template_code_block_css_url directly. // Whether user specify template_code_block_css_url directly.
bool getUserSpecifyTemplateCodeBlockCssUrl() const; bool getUserSpecifyTemplateCodeBlockCssUrl() const;
bool getEnableCompactMode() const;
void setEnableCompactMode(bool p_enabled);
// Return the configured key sequence of @p_operation. // Return the configured key sequence of @p_operation.
// Return empty if there is no corresponding config. // Return empty if there is no corresponding config.
QString getShortcutKeySequence(const QString &p_operation) const; QString getShortcutKeySequence(const QString &p_operation) const;
@ -429,6 +435,7 @@ private:
QByteArray m_mainWindowGeometry; QByteArray m_mainWindowGeometry;
QByteArray m_mainWindowState; QByteArray m_mainWindowState;
QByteArray m_mainSplitterState; QByteArray m_mainSplitterState;
QByteArray m_naviSplitterState;
// Find/Replace dialog options // Find/Replace dialog options
bool m_findCaseSensitive; bool m_findCaseSensitive;
@ -600,6 +607,9 @@ private:
// Whether double click on a tab to close it. // Whether double click on a tab to close it.
bool m_doubleClickCloseTab; 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. // The name of the config file in each directory, obsolete.
// Use c_dirConfigFile instead. // Use c_dirConfigFile instead.
static const QString c_obsoleteDirConfigFile; static const QString c_obsoleteDirConfigFile;
@ -609,8 +619,10 @@ private:
// The name of the default configuration file // The name of the default configuration file
static const QString defaultConfigFilePath; static const QString defaultConfigFilePath;
// QSettings for the user configuration // QSettings for the user configuration
QSettings *userSettings; QSettings *userSettings;
// Qsettings for @defaultConfigFileName // Qsettings for @defaultConfigFileName
QSettings *defaultSettings; QSettings *defaultSettings;
@ -899,6 +911,17 @@ inline void VConfigManager::setMainSplitterState(const QByteArray &p_state)
setConfigToSettings("session", "main_splitter_state", m_mainSplitterState); 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 inline bool VConfigManager::getFindCaseSensitive() const
{ {
return m_findCaseSensitive; return m_findCaseSensitive;
@ -1570,4 +1593,19 @@ inline bool VConfigManager::getUserSpecifyTemplateCodeBlockCssUrl() const
return !m_templateCodeBlockCssUrl.isEmpty(); 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 #endif // VCONFIGMANAGER_H

View File

@ -41,7 +41,7 @@ extern QFile g_logFile;
#endif #endif
VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent) 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) m_windowOldState(Qt::WindowNoState), m_requestQuit(false)
{ {
setWindowIcon(QIcon(":/resources/icons/vnote.ico")); setWindowIcon(QIcon(":/resources/icons/vnote.ico"));
@ -50,6 +50,12 @@ VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent)
vnote->initPalette(palette()); vnote->initPalette(palette());
initPredefinedColorPixmaps(); initPredefinedColorPixmaps();
if (g_config->getEnableCompactMode()) {
m_panelViewState = PanelViewState::CompactMode;
} else {
m_panelViewState = PanelViewState::TwoPanels;
}
setupUI(); setupUI();
initMenuBar(); initMenuBar();
@ -58,6 +64,9 @@ VMainWindow::VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent)
initAvatar(); initAvatar();
restoreStateAndGeometry(); restoreStateAndGeometry();
changePanelView(m_panelViewState);
setContextMenuPolicy(Qt::NoContextMenu); setContextMenuPolicy(Qt::NoContextMenu);
notebookSelector->update(); notebookSelector->update();
@ -88,7 +97,7 @@ void VMainWindow::initCaptain()
m_captain->registerNavigationTarget(notebookSelector); m_captain->registerNavigationTarget(notebookSelector);
m_captain->registerNavigationTarget(directoryTree); m_captain->registerNavigationTarget(directoryTree);
m_captain->registerNavigationTarget(fileList); m_captain->registerNavigationTarget(m_fileList);
m_captain->registerNavigationTarget(editArea); m_captain->registerNavigationTarget(editArea);
m_captain->registerNavigationTarget(outline); m_captain->registerNavigationTarget(outline);
} }
@ -97,29 +106,29 @@ void VMainWindow::setupUI()
{ {
QWidget *directoryPanel = setupDirectoryPanel(); QWidget *directoryPanel = setupDirectoryPanel();
fileList = new VFileList(); m_fileList = new VFileList();
fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); m_fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
editArea = new VEditArea(vnote); editArea = new VEditArea(vnote);
editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_findReplaceDialog = editArea->getFindReplaceDialog(); m_findReplaceDialog = editArea->getFindReplaceDialog();
fileList->setEditArea(editArea); m_fileList->setEditArea(editArea);
directoryTree->setEditArea(editArea); directoryTree->setEditArea(editArea);
notebookSelector->setEditArea(editArea); notebookSelector->setEditArea(editArea);
// Main Splitter // Main Splitter
mainSplitter = new QSplitter(); m_mainSplitter = new QSplitter();
mainSplitter->setObjectName("MainSplitter"); m_mainSplitter->setObjectName("MainSplitter");
mainSplitter->addWidget(directoryPanel); m_mainSplitter->addWidget(directoryPanel);
mainSplitter->addWidget(fileList); m_mainSplitter->addWidget(m_fileList);
mainSplitter->addWidget(editArea); m_mainSplitter->addWidget(editArea);
mainSplitter->setStretchFactor(0, 0); m_mainSplitter->setStretchFactor(0, 0);
mainSplitter->setStretchFactor(1, 0); m_mainSplitter->setStretchFactor(1, 0);
mainSplitter->setStretchFactor(2, 1); m_mainSplitter->setStretchFactor(2, 1);
// Signals // Signals
connect(directoryTree, &VDirectoryTree::currentDirectoryChanged, connect(directoryTree, &VDirectoryTree::currentDirectoryChanged,
fileList, &VFileList::setDirectory); m_fileList, &VFileList::setDirectory);
connect(directoryTree, &VDirectoryTree::directoryUpdated, connect(directoryTree, &VDirectoryTree::directoryUpdated,
editArea, &VEditArea::handleDirectoryUpdated); editArea, &VEditArea::handleDirectoryUpdated);
@ -133,11 +142,11 @@ void VMainWindow::setupUI()
} }
}); });
connect(fileList, &VFileList::fileClicked, connect(m_fileList, &VFileList::fileClicked,
editArea, &VEditArea::openFile); editArea, &VEditArea::openFile);
connect(fileList, &VFileList::fileCreated, connect(m_fileList, &VFileList::fileCreated,
editArea, &VEditArea::openFile); editArea, &VEditArea::openFile);
connect(fileList, &VFileList::fileUpdated, connect(m_fileList, &VFileList::fileUpdated,
editArea, &VEditArea::handleFileUpdated); editArea, &VEditArea::handleFileUpdated);
connect(editArea, &VEditArea::tabStatusUpdated, connect(editArea, &VEditArea::tabStatusUpdated,
this, &VMainWindow::handleAreaTabStatusUpdated); this, &VMainWindow::handleAreaTabStatusUpdated);
@ -148,7 +157,7 @@ void VMainWindow::setupUI()
connect(m_findReplaceDialog, &VFindReplaceDialog::findTextChanged, connect(m_findReplaceDialog, &VFindReplaceDialog::findTextChanged,
this, &VMainWindow::handleFindDialogTextChanged); this, &VMainWindow::handleFindDialogTextChanged);
setCentralWidget(mainSplitter); setCentralWidget(m_mainSplitter);
m_vimIndicator = new VVimIndicator(this); m_vimIndicator = new VVimIndicator(this);
m_vimIndicator->hide(); m_vimIndicator->hide();
@ -165,26 +174,49 @@ void VMainWindow::setupUI()
QWidget *VMainWindow::setupDirectoryPanel() QWidget *VMainWindow::setupDirectoryPanel()
{ {
// Notebook selector.
notebookLabel = new QLabel(tr("Notebooks")); notebookLabel = new QLabel(tr("Notebooks"));
notebookLabel->setProperty("TitleLabel", true); notebookLabel->setProperty("TitleLabel", true);
notebookLabel->setProperty("NotebookPanel", true); notebookLabel->setProperty("NotebookPanel", true);
directoryLabel = new QLabel(tr("Folders"));
directoryLabel->setProperty("TitleLabel", true);
directoryLabel->setProperty("NotebookPanel", true);
notebookSelector = new VNotebookSelector(vnote); notebookSelector = new VNotebookSelector(vnote);
notebookSelector->setObjectName("NotebookSelector"); notebookSelector->setObjectName("NotebookSelector");
notebookSelector->setProperty("NotebookPanel", true); notebookSelector->setProperty("NotebookPanel", true);
notebookSelector->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); notebookSelector->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
// Navigation panel.
directoryLabel = new QLabel(tr("Folders"));
directoryLabel->setProperty("TitleLabel", true);
directoryLabel->setProperty("NotebookPanel", true);
directoryTree = new VDirectoryTree; directoryTree = new VDirectoryTree;
directoryTree->setProperty("NotebookPanel", true); 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; QVBoxLayout *nbLayout = new QVBoxLayout;
nbLayout->addWidget(notebookLabel); nbLayout->addWidget(notebookLabel);
nbLayout->addWidget(notebookSelector); nbLayout->addWidget(notebookSelector);
nbLayout->addWidget(directoryLabel); nbLayout->addWidget(m_naviSplitter);
nbLayout->addWidget(directoryTree);
nbLayout->setContentsMargins(0, 0, 0, 0); nbLayout->setContentsMargins(0, 0, 0, 0);
nbLayout->setSpacing(0); nbLayout->setSpacing(0);
QWidget *nbContainer = new QWidget(); QWidget *nbContainer = new QWidget();
@ -226,24 +258,62 @@ void VMainWindow::initViewToolBar(QSize p_iconSize)
viewToolBar->setIconSize(p_iconSize); viewToolBar->setIconSize(p_iconSize);
} }
m_viewActGroup = new QActionGroup(this);
QAction *onePanelViewAct = new QAction(QIcon(":/resources/icons/one_panel.svg"), 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->setStatusTip(tr("Display only the notes list panel"));
onePanelViewAct->setToolTip(tr("Single Panel (Ctrl+E P)")); onePanelViewAct->setToolTip(tr("Single Panel (Ctrl+E P)"));
connect(onePanelViewAct, &QAction::triggered, onePanelViewAct->setCheckable(true);
this, &VMainWindow::onePanelView); onePanelViewAct->setData((int)PanelViewState::SinglePanel);
QAction *twoPanelViewAct = new QAction(QIcon(":/resources/icons/two_panels.svg"), 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->setStatusTip(tr("Display both the folders and notes list panel"));
twoPanelViewAct->setToolTip(tr("Two Panels (Ctrl+E P)")); twoPanelViewAct->setToolTip(tr("Two Panels (Ctrl+E P)"));
connect(twoPanelViewAct, &QAction::triggered, twoPanelViewAct->setCheckable(true);
this, &VMainWindow::twoPanelView); 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); QMenu *panelMenu = new QMenu(this);
panelMenu->setToolTipsVisible(true); panelMenu->setToolTipsVisible(true);
panelMenu->addAction(onePanelViewAct); panelMenu->addAction(onePanelViewAct);
panelMenu->addAction(twoPanelViewAct); panelMenu->addAction(twoPanelViewAct);
panelMenu->addAction(compactViewAct);
expandViewAct = new QAction(QIcon(":/resources/icons/expand.svg"), expandViewAct = new QAction(QIcon(":/resources/icons/expand.svg"),
tr("Expand (Ctrl+E E)"), this); tr("Expand (Ctrl+E E)"), this);
@ -251,7 +321,11 @@ void VMainWindow::initViewToolBar(QSize p_iconSize)
expandViewAct->setCheckable(true); expandViewAct->setCheckable(true);
expandViewAct->setMenu(panelMenu); expandViewAct->setMenu(panelMenu);
connect(expandViewAct, &QAction::triggered, 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); viewToolBar->addAction(expandViewAct);
} }
@ -378,7 +452,7 @@ void VMainWindow::initFileToolBar(QSize p_iconSize)
qDebug() << "set NewNote shortcut to" << keySeq; qDebug() << "set NewNote shortcut to" << keySeq;
newNoteAct->setShortcut(QKeySequence(keySeq)); newNoteAct->setShortcut(QKeySequence(keySeq));
connect(newNoteAct, &QAction::triggered, connect(newNoteAct, &QAction::triggered,
fileList, &VFileList::newFile); m_fileList, &VFileList::newFile);
noteInfoAct = new QAction(QIcon(":/resources/icons/note_info_tb.svg"), noteInfoAct = new QAction(QIcon(":/resources/icons/note_info_tb.svg"),
tr("Note &Info"), this); tr("Note &Info"), this);
@ -1064,7 +1138,7 @@ void VMainWindow::importNoteFromFile()
lastPath = QFileInfo(files[0]).path(); lastPath = QFileInfo(files[0]).path();
QString msg; QString msg;
if (!fileList->importFiles(files, &msg)) { if (!m_fileList->importFiles(files, &msg)) {
VUtils::showMessage(QMessageBox::Warning, VUtils::showMessage(QMessageBox::Warning,
tr("Warning"), tr("Warning"),
tr("Fail to create notes for all the files."), tr("Fail to create notes for all the files."),
@ -1694,65 +1768,119 @@ void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info)
void VMainWindow::onePanelView() void VMainWindow::onePanelView()
{ {
changeSplitterView(1); m_panelViewState = PanelViewState::SinglePanel;
expandViewAct->setChecked(false); g_config->setEnableCompactMode(false);
m_onePanel = true; changePanelView(m_panelViewState);
} }
void VMainWindow::twoPanelView() void VMainWindow::twoPanelView()
{ {
changeSplitterView(2); m_panelViewState = PanelViewState::TwoPanels;
expandViewAct->setChecked(false); g_config->setEnableCompactMode(false);
m_onePanel = false; changePanelView(m_panelViewState);
} }
void VMainWindow::toggleOnePanelView() void VMainWindow::toggleOnePanelView()
{ {
if (m_onePanel) { if (m_panelViewState == PanelViewState::TwoPanels) {
twoPanelView();
} else {
onePanelView(); onePanelView();
} else {
twoPanelView();
} }
} }
void VMainWindow::expandPanelView(bool p_checked) void VMainWindow::enableCompactMode(bool p_enabled)
{ {
int nrSplits = 0; const int fileListIdx = 1;
if (p_checked) { bool isCompactMode = m_naviSplitter->indexOf(m_fileList) != -1;
nrSplits = 0; 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 { } else {
if (m_onePanel) { // Disable compact mode and go back to two panels view.
nrSplits = 1; 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<QAction *> acts = m_viewActGroup->actions();
for (auto & act : acts) {
if (act->data().toInt() == (int)p_state) {
act->setChecked(true);
} else { } else {
nrSplits = 2; act->setChecked(false);
} }
} }
changeSplitterView(nrSplits);
}
void VMainWindow::changeSplitterView(int nrPanel) if (p_state != PanelViewState::ExpandMode) {
{ expandViewAct->setChecked(false);
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;
} }
} }
@ -1772,7 +1900,7 @@ void VMainWindow::curEditFileInfo()
if (m_curFile->getType() == FileType::Note) { if (m_curFile->getType() == FileType::Note) {
VNoteFile *file = dynamic_cast<VNoteFile *>((VFile *)m_curFile); VNoteFile *file = dynamic_cast<VNoteFile *>((VFile *)m_curFile);
Q_ASSERT(file); Q_ASSERT(file);
fileList->fileInfo(file); m_fileList->fileInfo(file);
} else if (m_curFile->getType() == FileType::Orphan) { } else if (m_curFile->getType() == FileType::Orphan) {
VOrphanFile *file = dynamic_cast<VOrphanFile *>((VFile *)m_curFile); VOrphanFile *file = dynamic_cast<VOrphanFile *>((VFile *)m_curFile);
Q_ASSERT(file); Q_ASSERT(file);
@ -1789,7 +1917,7 @@ void VMainWindow::deleteCurNote()
} }
VNoteFile *file = dynamic_cast<VNoteFile *>((VFile *)m_curFile); VNoteFile *file = dynamic_cast<VNoteFile *>((VFile *)m_curFile);
fileList->deleteFile(file); m_fileList->deleteFile(file);
} }
void VMainWindow::closeEvent(QCloseEvent *event) void VMainWindow::closeEvent(QCloseEvent *event)
@ -1843,14 +1971,17 @@ void VMainWindow::closeEvent(QCloseEvent *event)
void VMainWindow::saveStateAndGeometry() 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->setMainWindowGeometry(saveGeometry());
g_config->setMainWindowState(saveState()); g_config->setMainWindowState(saveState());
g_config->setToolsDockChecked(toolDock->isVisible()); 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() void VMainWindow::restoreStateAndGeometry()
@ -1864,9 +1995,15 @@ void VMainWindow::restoreStateAndGeometry()
restoreState(state); restoreState(state);
} }
toolDock->setVisible(g_config->getToolsDockChecked()); toolDock->setVisible(g_config->getToolsDockChecked());
const QByteArray &splitterState = g_config->getMainSplitterState(); const QByteArray &splitterState = g_config->getMainSplitterState();
if (!splitterState.isEmpty()) { 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() void VMainWindow::repositionAvatar()
{ {
int diameter = mainSplitter->pos().y(); int diameter = m_mainSplitter->pos().y();
int x = width() - diameter - 5; int x = width() - diameter - 5;
int y = 0; int y = 0;
qDebug() << "avatar:" << diameter << x << y; qDebug() << "avatar:" << diameter << x << y;
@ -1942,13 +2079,13 @@ bool VMainWindow::locateFile(VFile *p_file)
VDirectory *dir = file->getDirectory(); VDirectory *dir = file->getDirectory();
if (directoryTree->locateDirectory(dir)) { if (directoryTree->locateDirectory(dir)) {
while (fileList->currentDirectory() != dir) { while (m_fileList->currentDirectory() != dir) {
QCoreApplication::sendPostedEvents(); QCoreApplication::sendPostedEvents();
} }
if (fileList->locateFile(file)) { if (m_fileList->locateFile(file)) {
ret = true; ret = true;
fileList->setFocus(); m_fileList->setFocus();
} }
} }
} }

View File

@ -38,6 +38,15 @@ class QShortcut;
class VButtonWithWidget; class VButtonWithWidget;
class VAttachmentList; class VAttachmentList;
enum class PanelViewState
{
ExpandMode,
SinglePanel,
TwoPanels,
CompactMode,
Invalid
};
class VMainWindow : public QMainWindow class VMainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
@ -105,7 +114,6 @@ private slots:
void changeHighlightTrailingSapce(bool p_checked); void changeHighlightTrailingSapce(bool p_checked);
void onePanelView(); void onePanelView();
void twoPanelView(); void twoPanelView();
void expandPanelView(bool p_checked);
void curEditFileInfo(); void curEditFileInfo();
void deleteCurNote(); void deleteCurNote();
void handleCurrentDirectoryChanged(const VDirectory *p_dir); void handleCurrentDirectoryChanged(const VDirectory *p_dir);
@ -127,6 +135,9 @@ private slots:
void printNote(); void printNote();
void exportAsPDF(); void exportAsPDF();
// Set the panel view properly.
void enableCompactMode(bool p_enabled);
// Handle Vim status updated. // Handle Vim status updated.
void handleVimStatusUpdated(const VVim *p_vim); void handleVimStatusUpdated(const VVim *p_vim);
@ -186,7 +197,6 @@ private:
void initEditorLineNumberMenu(QMenu *p_menu); void initEditorLineNumberMenu(QMenu *p_menu);
void initEditorStyleMenu(QMenu *p_emnu); void initEditorStyleMenu(QMenu *p_emnu);
void changeSplitterView(int nrPanel);
void updateWindowTitle(const QString &str); void updateWindowTitle(const QString &str);
void updateActionStateFromTabStatusChange(const VFile *p_file, void updateActionStateFromTabStatusChange(const VFile *p_file,
bool p_editMode); bool p_editMode);
@ -213,6 +223,10 @@ private:
// Init system tray icon and correspondign context menu. // Init system tray icon and correspondign context menu.
void initTrayIcon(); void initTrayIcon();
// Change the panel view according to @p_state.
// Will not change m_panelViewState.
void changePanelView(PanelViewState p_state);
VNote *vnote; VNote *vnote;
QPointer<VFile> m_curFile; QPointer<VFile> m_curFile;
QPointer<VEditTab> m_curTab; QPointer<VEditTab> m_curTab;
@ -222,9 +236,16 @@ private:
QLabel *notebookLabel; QLabel *notebookLabel;
QLabel *directoryLabel; QLabel *directoryLabel;
VNotebookSelector *notebookSelector; VNotebookSelector *notebookSelector;
VFileList *fileList; VFileList *m_fileList;
VDirectoryTree *directoryTree; 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; VEditArea *editArea;
QDockWidget *toolDock; QDockWidget *toolDock;
QToolBox *toolBox; QToolBox *toolBox;
@ -234,8 +255,7 @@ private:
VVimIndicator *m_vimIndicator; VVimIndicator *m_vimIndicator;
VTabIndicator *m_tabIndicator; VTabIndicator *m_tabIndicator;
// Whether it is one panel or two panles. PanelViewState m_panelViewState;
bool m_onePanel;
// Actions // Actions
QAction *newRootDirAct; QAction *newRootDirAct;
@ -269,6 +289,9 @@ private:
// Act group for code block render styles. // Act group for code block render styles.
QActionGroup *m_codeBlockStyleActs; QActionGroup *m_codeBlockStyleActs;
// Act group for panel view actions.
QActionGroup *m_viewActGroup;
QShortcut *m_closeNoteShortcut; QShortcut *m_closeNoteShortcut;
// Menus // Menus
@ -306,7 +329,7 @@ private:
inline VFileList *VMainWindow::getFileList() const inline VFileList *VMainWindow::getFileList() const
{ {
return fileList; return m_fileList;
} }
#endif // VMAINWINDOW_H #endif // VMAINWINDOW_H

View File

@ -130,5 +130,6 @@
<file>resources/icons/delete_attachment.svg</file> <file>resources/icons/delete_attachment.svg</file>
<file>resources/icons/sort.svg</file> <file>resources/icons/sort.svg</file>
<file>resources/icons/create_subdir.svg</file> <file>resources/icons/create_subdir.svg</file>
<file>resources/icons/compact_mode.svg</file>
</qresource> </qresource>
</RCC> </RCC>