mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
MainWindow: support Navigation mode for dock widgets
This commit is contained in:
parent
d8635e957c
commit
8973f40020
@ -228,6 +228,7 @@ void NotebookMgr::readNotebooksFromConfig()
|
||||
qCritical("failed to read notebook (%s) from config (%s)",
|
||||
item.m_rootFolderPath.toStdString().c_str(),
|
||||
p_e.what());
|
||||
m_notebooksFailedToLoad.push_back(item.m_rootFolderPath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,3 +387,14 @@ QSharedPointer<Node> NotebookMgr::loadNodeByPath(const QString &p_path)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const QStringList &NotebookMgr::getNotebooksFailedToLoad() const
|
||||
{
|
||||
return m_notebooksFailedToLoad;
|
||||
}
|
||||
|
||||
void NotebookMgr::clearNotebooksFailedToLoad()
|
||||
{
|
||||
m_notebooksFailedToLoad.clear();
|
||||
saveNotebooksToConfig();
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "sessionconfig.h"
|
||||
#include "global.h"
|
||||
#include "notebook/notebook.h"
|
||||
#include "noncopyable.h"
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
@ -23,7 +24,7 @@ namespace vnotex
|
||||
class NotebookParameters;
|
||||
class Node;
|
||||
|
||||
class NotebookMgr : public QObject
|
||||
class NotebookMgr : public QObject, private Noncopyable
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -71,6 +72,10 @@ namespace vnotex
|
||||
// Try to load @p_path as a node if it is within one notebook.
|
||||
QSharedPointer<Node> loadNodeByPath(const QString &p_path);
|
||||
|
||||
const QStringList &getNotebooksFailedToLoad() const;
|
||||
|
||||
void clearNotebooksFailedToLoad();
|
||||
|
||||
public slots:
|
||||
void setCurrentNotebook(ID p_notebookId);
|
||||
|
||||
@ -116,6 +121,8 @@ namespace vnotex
|
||||
QVector<QSharedPointer<Notebook>> m_notebooks;
|
||||
|
||||
ID m_currentNotebookId = 0;
|
||||
|
||||
QStringList m_notebooksFailedToLoad;
|
||||
};
|
||||
} // ns vnotex
|
||||
|
||||
|
@ -25,7 +25,8 @@
|
||||
<file>icons/settings_menu.svg</file>
|
||||
<file>icons/whatsthis.svg</file>
|
||||
<file>icons/help_menu.svg</file>
|
||||
<file>icons/import_export_menu.svg</file>
|
||||
<file>icons/import_menu.svg</file>
|
||||
<file>icons/export_menu.svg</file>
|
||||
<file>icons/flash_page_menu.svg</file>
|
||||
<file>icons/quick_access_menu.svg</file>
|
||||
<file>icons/native_notebook_default.svg</file>
|
||||
|
1
src/data/core/icons/export_menu.svg
Normal file
1
src/data/core/icons/export_menu.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1630411117653" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4795" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M840.533333 938.666667H183.466667C128 938.666667 85.333333 896 85.333333 840.533333V183.466667C85.333333 128 128 85.333333 183.466667 85.333333h354.133333c12.8 0 21.333333 8.533333 21.333333 21.333334s-8.533333 21.333333-21.333333 21.333333H183.466667C151.466667 128 128 151.466667 128 183.466667v659.2C128 872.533333 151.466667 896 183.466667 896h659.2c29.866667 0 55.466667-23.466667 55.466666-55.466667V490.666667c0-12.8 8.533333-21.333333 21.333334-21.333334s21.333333 8.533333 21.333333 21.333334v349.866666C938.666667 896 896 938.666667 840.533333 938.666667z" p-id="4796" fill="#000000"></path><path d="M405.333333 640h-4.266666c-8.533333-2.133333-17.066667-10.666667-17.066667-19.2-8.533333-153.6 25.6-270.933333 102.4-349.866667 70.4-74.666667 157.866667-91.733333 196.266667-98.133333V106.666667c0-8.533333 4.266667-17.066667 12.8-19.2 8.533333-2.133333 17.066667-2.133333 23.466666 4.266666l213.333334 192c4.266667 4.266667 6.4 10.666667 6.4 14.933334s-2.133333 12.8-6.4 14.933333l-213.333334 192c-6.4 6.4-14.933333 6.4-23.466666 4.266667-8.533333-2.133333-12.8-10.666667-12.8-19.2v-85.333334c-42.666667 2.133333-153.6 25.6-258.133334 224-4.266667 6.4-10.666667 10.666667-19.2 10.666667zM725.333333 155.733333V192c0 12.8-8.533333 21.333333-21.333333 21.333333 0 0-108.8 2.133333-187.733333 85.333334-53.333333 57.6-83.2 136.533333-89.6 241.066666 134.4-202.666667 275.2-177.066667 281.6-177.066666 10.666667 2.133333 17.066667 10.666667 17.066666 21.333333v59.733333l160-145.066666L725.333333 155.733333z" p-id="4797" fill="#000000"></path></svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1607931217887" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1738" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M344.352 403.072l-160.8 0 243.296 243.264 243.296-243.264-157.376 0c8.832-338.976-299.168-376.736-491.424-198.88 130.528-72.096 329.664-84.192 323.04 198.88l0 0zM937.76 66.24l-524.896 0c26.976 13.92 51.232 31.904 72.512 53.76 27.872 28.576 49.536 55.456 68.128 120.448l395.04 0 0 701.088-827.104 0 0-683.936c0 0-16.768-20.128-52.96-2.496l0 680.448c0 35.904 29.088 64.864 64.928 64.864l804.384 0c35.872 0 64.896-28.96 64.896-64.864l0-804.384c0-35.84-29.024-64.928-64.928-64.928l0 0z" p-id="1739" fill="#000000"></path></svg>
|
Before Width: | Height: | Size: 900 B |
1
src/data/core/icons/import_menu.svg
Normal file
1
src/data/core/icons/import_menu.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1630411129695" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5009" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M840.533333 938.666667H183.466667C128 938.666667 85.333333 896 85.333333 840.533333V405.333333c0-12.8 8.533333-21.333333 21.333334-21.333333s21.333333 8.533333 21.333333 21.333333v435.2C128 872.533333 151.466667 896 183.466667 896h659.2c29.866667 0 55.466667-23.466667 55.466666-55.466667V183.466667C896 151.466667 872.533333 128 840.533333 128H529.066667c-12.8 0-21.333333-8.533333-21.333334-21.333333s8.533333-21.333333 21.333334-21.333334h311.466666C896 85.333333 938.666667 128 938.666667 183.466667v659.2c0 53.333333-42.666667 96-98.133334 96z" p-id="5010" fill="#000000"></path><path d="M426.666667 640c-6.4 0-12.8-2.133333-14.933334-6.4l-192-213.333333c-6.4-6.4-6.4-14.933333-4.266666-23.466667s10.666667-12.8 19.2-12.8h87.466666c-2.133333-42.666667-25.6-153.6-224-258.133333-10.666667-4.266667-14.933333-12.8-12.8-23.466667 2.133333-8.533333 10.666667-14.933333 21.333334-17.066667 153.6-8.533333 270.933333 25.6 349.866666 102.4 74.666667 70.4 91.733333 157.866667 98.133334 196.266667h64c8.533333 0 17.066667 4.266667 19.2 12.8 4.266667 8.533333 2.133333 17.066667-4.266667 23.466667l-192 213.333333c-2.133333 4.266667-8.533333 6.4-14.933333 6.4z m-145.066667-213.333333l145.066667 160 145.066666-160H533.333333c-12.8 0-21.333333-8.533333-21.333333-21.333334 0 0-2.133333-108.8-85.333333-187.733333C369.066667 164.266667 290.133333 134.4 185.6 128c202.666667 134.4 177.066667 275.2 177.066667 281.6-2.133333 10.666667-10.666667 17.066667-21.333334 17.066667h-59.733333z" p-id="5011" fill="#000000"></path></svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -2,7 +2,7 @@
|
||||
1. All the keys without special notice are **case insensitive**;
|
||||
2. On macOS, `Ctrl` corresponds to `Command` except in Vi mode;
|
||||
3. The key sequence `Ctrl+G, I` means that first press both `Ctrl` and `G` simultaneously, release them, then press `I` and release;
|
||||
4. For a complete shortcuts list, please view the `vnotex.json` configuration file.
|
||||
4. For a **complete shortcuts list**, please view the `vnotex.json` configuration file.
|
||||
|
||||
## General
|
||||
- `Ctrl+G E`
|
||||
@ -23,10 +23,6 @@ Recover last closed file.
|
||||
Open Flash Page.
|
||||
- `Ctrl+Alt+I`
|
||||
Open Quick Access.
|
||||
- `Ctrl+G 1`
|
||||
Focus the Navigation dock.
|
||||
- `Ctrl+G 2`
|
||||
Focus the Outline dock.
|
||||
- `Ctrl+G X`
|
||||
Close current tab.
|
||||
- `Ctrl+G D`
|
||||
|
@ -2,7 +2,7 @@
|
||||
1. 以下按键除特别说明外,都不区分大小写;
|
||||
2. 在 macOS 下,`Ctrl` 对应于 `Command`,在 Vi 模式下除外;
|
||||
3. 按键序列 `Ctrl+G, I` 表示先同时按下 `Ctrl` 和 `G`,释放,然后按下 `I` 并释放;
|
||||
4. 可以通过查看配置文件 `vnotex.json` 来获取一个完整的快捷键列表。
|
||||
4. 可以通过查看配置文件 `vnotex.json` 来获取一个**完整的快捷键列表**。
|
||||
|
||||
## 通用
|
||||
- `Ctrl+G E`
|
||||
@ -23,10 +23,6 @@ VNote 的很多部件均支持`Ctrl+J`和`Ctrl+K`导航。
|
||||
打开灵犀页。
|
||||
- `Ctrl+Alt+I`
|
||||
打开快速访问。
|
||||
- `Ctrl+G 1`
|
||||
跳转到导航停靠窗口。
|
||||
- `Ctrl+G 2`
|
||||
跳转到大纲停靠窗口。
|
||||
- `Ctrl+G X`
|
||||
关闭当前标签页。
|
||||
- `Ctrl+G D`
|
||||
|
@ -457,8 +457,8 @@ QLineEdit:disabled {
|
||||
color: @widgets#qlineedit#disabled#fg;
|
||||
}
|
||||
|
||||
/* QPlainTextEdit */
|
||||
QPlainTextEdit[ConsoleTextEdit="true"] {
|
||||
/* QPlainTextEdit and QTextEdit */
|
||||
QPlainTextEdit, QTextEdit {
|
||||
color: @widgets#qlineedit#fg;
|
||||
background-color: @widgets#qlineedit#bg;
|
||||
selection-color: @widgets#qlineedit#selection#fg;
|
||||
|
@ -457,8 +457,8 @@ QLineEdit:disabled {
|
||||
color: @widgets#qlineedit#disabled#fg;
|
||||
}
|
||||
|
||||
/* QPlainTextEdit */
|
||||
QPlainTextEdit[ConsoleTextEdit="true"] {
|
||||
/* QPlainTextEdit and QTextEdit */
|
||||
QPlainTextEdit, QTextEdit {
|
||||
color: @widgets#qlineedit#fg;
|
||||
background-color: @widgets#qlineedit#bg;
|
||||
selection-color: @widgets#qlineedit#selection#fg;
|
||||
|
@ -7,12 +7,13 @@
|
||||
#include <QDockWidget>
|
||||
|
||||
#include <widgets/widgetsfactory.h>
|
||||
#include <widgets/mainwindow.h>
|
||||
#include <core/sessionconfig.h>
|
||||
#include <core/coreconfig.h>
|
||||
#include <core/widgetconfig.h>
|
||||
#include <core/configmgr.h>
|
||||
#include <utils/widgetutils.h>
|
||||
#include <widgets/mainwindow.h>
|
||||
#include <widgets/propertydefs.h>
|
||||
#include <core/vnotex.h>
|
||||
|
||||
using namespace vnotex;
|
||||
@ -59,7 +60,7 @@ void AppearancePage::setupUI()
|
||||
auto layout = new QVBoxLayout();
|
||||
|
||||
for (int i = 0; i < docks.size(); ++i) {
|
||||
m_keepDocksExpandingContentArea[i].first = WidgetsFactory::createCheckBox(docks[i]->property(MainWindow::c_propertyDockTitle).toString(), this);
|
||||
m_keepDocksExpandingContentArea[i].first = WidgetsFactory::createCheckBox(docks[i]->property(PropertyDefs::c_dockWidgetTitle).toString(), this);
|
||||
m_keepDocksExpandingContentArea[i].second = docks[i]->objectName();
|
||||
layout->addWidget(m_keepDocksExpandingContentArea[i].first);
|
||||
connect(m_keepDocksExpandingContentArea[i].first, &QCheckBox::stateChanged,
|
||||
|
505
src/widgets/dockwidgethelper.cpp
Normal file
505
src/widgets/dockwidgethelper.cpp
Normal file
@ -0,0 +1,505 @@
|
||||
#include "dockwidgethelper.h"
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QTabBar>
|
||||
#include <QBitArray>
|
||||
#include <QHelpEvent>
|
||||
#include <QToolTip>
|
||||
#include <QShortcut>
|
||||
|
||||
#include <core/vnotex.h>
|
||||
#include <core/thememgr.h>
|
||||
#include <core/configmgr.h>
|
||||
#include <core/coreconfig.h>
|
||||
#include <core/widgetconfig.h>
|
||||
#include <utils/iconutils.h>
|
||||
#include <utils/widgetutils.h>
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "propertydefs.h"
|
||||
#include "notebookexplorer.h"
|
||||
#include "outlineviewer.h"
|
||||
#include "locationlist.h"
|
||||
#include "searchpanel.h"
|
||||
#include "snippetpanel.h"
|
||||
#include "historypanel.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
DockWidgetHelper::NavigationItemInfo::NavigationItemInfo(QTabBar *p_tabBar, int p_tabIndex, int p_dockIndex)
|
||||
: m_tabBar(p_tabBar),
|
||||
m_tabIndex(p_tabIndex),
|
||||
m_dockIndex(p_dockIndex)
|
||||
{
|
||||
}
|
||||
|
||||
DockWidgetHelper::NavigationItemInfo::NavigationItemInfo(int p_dockIndex)
|
||||
: m_dockIndex(p_dockIndex)
|
||||
{
|
||||
}
|
||||
|
||||
DockWidgetHelper::DockWidgetHelper(MainWindow *p_mainWindow)
|
||||
: QObject(p_mainWindow),
|
||||
NavigationMode(NavigationMode::Type::DoubleKeys, p_mainWindow),
|
||||
m_mainWindow(p_mainWindow)
|
||||
{
|
||||
}
|
||||
|
||||
static int rotationAngle(Qt::DockWidgetArea p_area)
|
||||
{
|
||||
switch (p_area) {
|
||||
case Qt::LeftDockWidgetArea:
|
||||
return 90;
|
||||
|
||||
case Qt::RightDockWidgetArea:
|
||||
return 270;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
QString DockWidgetHelper::iconFileName(DockIndex p_dockIndex)
|
||||
{
|
||||
switch (p_dockIndex) {
|
||||
case DockIndex::NavigationDock:
|
||||
return "navigation_dock.svg";
|
||||
case DockIndex::OutlineDock:
|
||||
return "outline_dock.svg";
|
||||
case DockIndex::HistoryDock:
|
||||
return "history_dock.svg";
|
||||
case DockIndex::SearchDock:
|
||||
return "search_dock.svg";
|
||||
case DockIndex::SnippetDock:
|
||||
return "snippet_dock.svg";
|
||||
case DockIndex::LocationListDock:
|
||||
return "location_list_dock.svg";
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
void DockWidgetHelper::setupDocks()
|
||||
{
|
||||
m_mainWindow->setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::West);
|
||||
m_mainWindow->setTabPosition(Qt::RightDockWidgetArea, QTabWidget::East);
|
||||
m_mainWindow->setTabPosition(Qt::TopDockWidgetArea, QTabWidget::North);
|
||||
m_mainWindow->setTabPosition(Qt::BottomDockWidgetArea, QTabWidget::North);
|
||||
m_mainWindow->setDockNestingEnabled(true);
|
||||
|
||||
m_dockIcons.resize(DockIndex::MaxDock);
|
||||
|
||||
// The order of m_docks should be identical with enum DockIndex.
|
||||
setupNavigationDock();
|
||||
|
||||
setupOutlineDock();
|
||||
|
||||
setupHistoryDock();
|
||||
|
||||
setupSearchDock();
|
||||
|
||||
setupSnippetDock();
|
||||
|
||||
for (int i = 1; i < m_docks.size(); ++i) {
|
||||
m_mainWindow->tabifyDockWidget(m_docks[i - 1], m_docks[i]);
|
||||
}
|
||||
|
||||
// Following are non-tabfieid docks.
|
||||
setupLocationListDock();
|
||||
|
||||
setupShortcuts();
|
||||
}
|
||||
|
||||
void DockWidgetHelper::setupNavigationDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::NavigationDock, tr("Navigation"), m_mainWindow);
|
||||
|
||||
dock->setObjectName(QStringLiteral("NavigationDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
dock->setWidget(m_mainWindow->m_notebookExplorer);
|
||||
dock->setFocusProxy(m_mainWindow->m_notebookExplorer);
|
||||
m_mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
}
|
||||
|
||||
void DockWidgetHelper::setupOutlineDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::OutlineDock, tr("Outline"), m_mainWindow);
|
||||
|
||||
dock->setObjectName(QStringLiteral("OutlineDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
dock->setWidget(m_mainWindow->m_outlineViewer);
|
||||
dock->setFocusProxy(m_mainWindow->m_outlineViewer);
|
||||
m_mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
}
|
||||
|
||||
void DockWidgetHelper::setupSearchDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::SearchDock, tr("Search"), m_mainWindow);
|
||||
|
||||
dock->setObjectName(QStringLiteral("SearchDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
dock->setWidget(m_mainWindow->m_searchPanel);
|
||||
dock->setFocusProxy(m_mainWindow->m_searchPanel);
|
||||
m_mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
}
|
||||
|
||||
void DockWidgetHelper::setupSnippetDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::SnippetDock, tr("Snippets"), m_mainWindow);
|
||||
|
||||
dock->setObjectName(QStringLiteral("SnippetDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
dock->setWidget(m_mainWindow->m_snippetPanel);
|
||||
dock->setFocusProxy(m_mainWindow->m_snippetPanel);
|
||||
m_mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
}
|
||||
|
||||
void DockWidgetHelper::setupHistoryDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::HistoryDock, tr("History"), m_mainWindow);
|
||||
|
||||
dock->setObjectName(QStringLiteral("HistoryDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
dock->setWidget(m_mainWindow->m_historyPanel);
|
||||
dock->setFocusProxy(m_mainWindow->m_historyPanel);
|
||||
m_mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
}
|
||||
|
||||
void DockWidgetHelper::setupLocationListDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::LocationListDock, tr("Location List"), m_mainWindow);
|
||||
|
||||
dock->setObjectName(QStringLiteral("LocationListDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
dock->setWidget(m_mainWindow->m_locationList);
|
||||
dock->setFocusProxy(m_mainWindow->m_locationList);
|
||||
m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dock);
|
||||
dock->hide();
|
||||
}
|
||||
|
||||
QDockWidget *DockWidgetHelper::createDockWidget(DockIndex p_dockIndex, const QString &p_title, QWidget *p_parent)
|
||||
{
|
||||
auto dock = new QDockWidget(p_title, p_parent);
|
||||
dock->setToolTip(p_title);
|
||||
dock->setProperty(PropertyDefs::c_dockWidgetIndex, p_dockIndex);
|
||||
dock->setProperty(PropertyDefs::c_dockWidgetTitle, p_title);
|
||||
m_docks.push_back(dock);
|
||||
return dock;
|
||||
}
|
||||
|
||||
void DockWidgetHelper::activateDock(DockIndex p_dockIndex)
|
||||
{
|
||||
Q_ASSERT(p_dockIndex < DockIndex::MaxDock);
|
||||
activateDock(getDock(p_dockIndex));
|
||||
}
|
||||
|
||||
void DockWidgetHelper::activateDock(QDockWidget *p_dock)
|
||||
{
|
||||
p_dock->show();
|
||||
Q_FOREACH(QTabBar* tabBar, m_mainWindow->findChildren<QTabBar*>(QString(), Qt::FindDirectChildrenOnly)) {
|
||||
bool found = false;
|
||||
for (int i = 0; i < tabBar->count(); ++i) {
|
||||
if (p_dock == reinterpret_cast<QWidget *>(tabBar->tabData(i).toULongLong())) {
|
||||
tabBar->setCurrentIndex(i);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
p_dock->setFocus();
|
||||
}
|
||||
|
||||
const QVector<QDockWidget *> &DockWidgetHelper::getDocks() const
|
||||
{
|
||||
return m_docks;
|
||||
}
|
||||
|
||||
QDockWidget *DockWidgetHelper::getDock(DockIndex p_dockIndex) const
|
||||
{
|
||||
Q_ASSERT(p_dockIndex < DockIndex::MaxDock);
|
||||
return m_docks[p_dockIndex];
|
||||
}
|
||||
|
||||
void DockWidgetHelper::setupShortcuts()
|
||||
{
|
||||
const auto &coreConfig = ConfigMgr::getInst().getCoreConfig();
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::NavigationDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::NavigationDock));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::OutlineDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::OutlineDock));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::HistoryDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::HistoryDock));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::SearchDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::SearchDock));
|
||||
// Extra shortcut for SearchDock.
|
||||
setupDockActivateShortcut(m_docks[DockIndex::SearchDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::Search));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::LocationListDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::LocationListDock));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::SnippetDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::SnippetDock));
|
||||
}
|
||||
|
||||
void DockWidgetHelper::setupDockActivateShortcut(QDockWidget *p_dock, const QString &p_keys)
|
||||
{
|
||||
auto shortcut = WidgetUtils::createShortcut(p_keys, m_mainWindow);
|
||||
if (shortcut) {
|
||||
p_dock->setToolTip(QString("%1\t%2").arg(p_dock->windowTitle(),
|
||||
QKeySequence(p_keys).toString(QKeySequence::NativeText)));
|
||||
connect(shortcut, &QShortcut::activated,
|
||||
this, [this, p_dock]() {
|
||||
activateDock(p_dock);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void DockWidgetHelper::postSetup()
|
||||
{
|
||||
updateDockWidgetTabBar();
|
||||
|
||||
for (const auto dock : m_docks) {
|
||||
connect(dock, &QDockWidget::dockLocationChanged,
|
||||
this, &DockWidgetHelper::updateDockWidgetTabBar);
|
||||
connect(dock, &QDockWidget::topLevelChanged,
|
||||
this, &DockWidgetHelper::updateDockWidgetTabBar);
|
||||
}
|
||||
}
|
||||
|
||||
void DockWidgetHelper::updateDockWidgetTabBar()
|
||||
{
|
||||
QBitArray tabifiedDocks(m_docks.size(), false);
|
||||
Q_FOREACH(QTabBar* tabBar, m_mainWindow->findChildren<QTabBar*>(QString(), Qt::FindDirectChildrenOnly)) {
|
||||
if (!m_tabBarsMonitored.contains(tabBar)) {
|
||||
m_tabBarsMonitored.insert(tabBar);
|
||||
tabBar->installEventFilter(this);
|
||||
}
|
||||
|
||||
tabBar->setDrawBase(false);
|
||||
|
||||
const int sz = ConfigMgr::getInst().getCoreConfig().getDocksTabBarIconSize();
|
||||
tabBar->setIconSize(QSize(sz, sz));
|
||||
|
||||
auto tabShape = tabBar->shape();
|
||||
bool iconOnly = tabShape == QTabBar::RoundedWest || tabShape == QTabBar::RoundedEast
|
||||
|| tabShape == QTabBar::TriangularWest || tabShape == QTabBar::TriangularEast;
|
||||
const int cnt = tabBar->count();
|
||||
if (cnt == 1) {
|
||||
iconOnly = false;
|
||||
}
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
auto dock = reinterpret_cast<QDockWidget *>(tabBar->tabData(i).toULongLong());
|
||||
if (!dock) {
|
||||
continue;
|
||||
}
|
||||
int dockIdx = dock->property(PropertyDefs::c_dockWidgetIndex).toInt();
|
||||
tabifiedDocks.setBit(dockIdx);
|
||||
if (iconOnly) {
|
||||
dock->setWindowTitle(QString());
|
||||
} else if (dock->windowTitle().isEmpty()) {
|
||||
dock->setWindowTitle(dock->property(PropertyDefs::c_dockWidgetTitle).toString());
|
||||
}
|
||||
tabBar->setTabIcon(i, getDockIcon(static_cast<DockIndex>(dockIdx)));
|
||||
}
|
||||
}
|
||||
|
||||
// Non-tabified docks.
|
||||
for (int i = 0; i < m_docks.size(); ++i) {
|
||||
if (!tabifiedDocks[i] && m_docks[i]->windowTitle().isEmpty()) {
|
||||
m_docks[i]->setWindowTitle(m_docks[i]->property(PropertyDefs::c_dockWidgetTitle).toString());
|
||||
}
|
||||
}
|
||||
|
||||
emit m_mainWindow->layoutChanged();
|
||||
}
|
||||
|
||||
bool DockWidgetHelper::eventFilter(QObject *p_obj, QEvent *p_event)
|
||||
{
|
||||
if (p_event->type() == QEvent::ToolTip) {
|
||||
// The QTabBar of the tabified dock widgets does not show tooltip due to Qt's internal implementation.
|
||||
auto helpEve = static_cast<QHelpEvent *>(p_event);
|
||||
auto tabBar = static_cast<QTabBar *>(p_obj);
|
||||
int idx = tabBar->tabAt(helpEve->pos());
|
||||
bool done = false;
|
||||
if (idx > -1) {
|
||||
auto dock = reinterpret_cast<QDockWidget *>(tabBar->tabData(idx).toULongLong());
|
||||
if (dock) {
|
||||
done = true;
|
||||
QToolTip::showText(helpEve->globalPos(), dock->property(PropertyDefs::c_dockWidgetTitle).toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
QToolTip::hideText();
|
||||
p_event->ignore();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return QObject::eventFilter(p_obj, p_event);
|
||||
}
|
||||
|
||||
QStringList DockWidgetHelper::getVisibleDocks() const
|
||||
{
|
||||
QStringList visibleDocks;
|
||||
for (const auto dock : m_docks) {
|
||||
if (dock->isVisible()) {
|
||||
visibleDocks.push_back(dock->objectName());
|
||||
}
|
||||
}
|
||||
return visibleDocks;
|
||||
}
|
||||
|
||||
QStringList DockWidgetHelper::hideDocks()
|
||||
{
|
||||
const auto &keepDocks = ConfigMgr::getInst().getWidgetConfig().getMainWindowKeepDocksExpandingContentArea();
|
||||
QStringList visibleDocks;
|
||||
for (const auto dock : m_docks) {
|
||||
const auto objName = dock->objectName();
|
||||
if (dock->isVisible()) {
|
||||
visibleDocks.push_back(objName);
|
||||
}
|
||||
|
||||
if (dock->isFloating() || keepDocks.contains(objName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dock->setVisible(false);
|
||||
}
|
||||
|
||||
return visibleDocks;
|
||||
}
|
||||
|
||||
void DockWidgetHelper::restoreDocks(const QStringList &p_visibleDocks)
|
||||
{
|
||||
const auto &keepDocks = ConfigMgr::getInst().getWidgetConfig().getMainWindowKeepDocksExpandingContentArea();
|
||||
bool hasVisible = false;
|
||||
for (const auto dock : m_docks) {
|
||||
const auto objName = dock->objectName();
|
||||
if (dock->isFloating() || keepDocks.contains(objName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool visible = p_visibleDocks.contains(objName);
|
||||
hasVisible = hasVisible || visible;
|
||||
|
||||
dock->setVisible(visible);
|
||||
}
|
||||
|
||||
if (!hasVisible) {
|
||||
// At least make one visible.
|
||||
getDock(DockIndex::NavigationDock)->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool DockWidgetHelper::isAnyDockVisible() const
|
||||
{
|
||||
const auto &keepDocks = ConfigMgr::getInst().getWidgetConfig().getMainWindowKeepDocksExpandingContentArea();
|
||||
for (const auto dock : m_docks) {
|
||||
if (!dock->isFloating() && dock->isVisible() && !keepDocks.contains(dock->objectName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVector<void *> DockWidgetHelper::getVisibleNavigationItems()
|
||||
{
|
||||
m_navigationItems.clear();
|
||||
|
||||
QBitArray tabifiedDocks(m_docks.size(), false);
|
||||
Q_FOREACH(QTabBar* tabBar, m_mainWindow->findChildren<QTabBar*>(QString(), Qt::FindDirectChildrenOnly)) {
|
||||
if (!tabBar->isVisible()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const int cnt = tabBar->count();
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
auto dock = reinterpret_cast<QDockWidget *>(tabBar->tabData(i).toULongLong());
|
||||
if (!dock) {
|
||||
continue;
|
||||
}
|
||||
int dockIdx = dock->property(PropertyDefs::c_dockWidgetIndex).toInt();
|
||||
tabifiedDocks.setBit(dockIdx);
|
||||
|
||||
m_navigationItems.push_back(NavigationItemInfo(tabBar, i, dockIdx));
|
||||
}
|
||||
}
|
||||
|
||||
// Non-tabified docks.
|
||||
for (int i = 0; i < m_docks.size(); ++i) {
|
||||
if (!tabifiedDocks[i] && m_docks[i]->isVisible()) {
|
||||
m_navigationItems.push_back(NavigationItemInfo(i));
|
||||
}
|
||||
}
|
||||
|
||||
QVector<void *> items;
|
||||
for (auto &item : m_navigationItems) {
|
||||
items.push_back(&item);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
const QIcon &DockWidgetHelper::getDockIcon(DockIndex p_dockIndex)
|
||||
{
|
||||
static const auto fg = VNoteX::getInst().getThemeMgr().paletteColor("widgets#mainwindow#dockwidget_tabbar#icon#fg");
|
||||
static const auto selectedFg = VNoteX::getInst().getThemeMgr().paletteColor("widgets#mainwindow#dockwidget_tabbar#icon#selected#fg");
|
||||
|
||||
const auto area = m_mainWindow->dockWidgetArea(m_docks[p_dockIndex]);
|
||||
const int newAngle = rotationAngle(area);
|
||||
if (m_dockIcons[p_dockIndex].m_rotationAngle != newAngle && area != Qt::NoDockWidgetArea) {
|
||||
QVector<IconUtils::OverriddenColor> colors;
|
||||
colors.push_back(IconUtils::OverriddenColor(fg, QIcon::Normal));
|
||||
// FIXME: the Selected Mode is not used by the selected tab of a QTabBar.
|
||||
colors.push_back(IconUtils::OverriddenColor(selectedFg, QIcon::Selected));
|
||||
|
||||
auto iconFile = VNoteX::getInst().getThemeMgr().getIconFile(iconFileName(p_dockIndex));
|
||||
m_dockIcons[p_dockIndex].m_icon = IconUtils::fetchIcon(iconFile, colors, newAngle);
|
||||
m_dockIcons[p_dockIndex].m_rotationAngle = newAngle;
|
||||
}
|
||||
|
||||
return m_dockIcons[p_dockIndex].m_icon;
|
||||
}
|
||||
|
||||
void DockWidgetHelper::placeNavigationLabel(int p_idx, void *p_item, QLabel *p_label)
|
||||
{
|
||||
Q_UNUSED(p_idx);
|
||||
auto info = static_cast<NavigationItemInfo *>(p_item);
|
||||
if (info->m_tabBar) {
|
||||
auto pos = info->m_tabBar->tabRect(info->m_tabIndex).topLeft();
|
||||
pos = info->m_tabBar->mapToGlobal(pos);
|
||||
p_label->move(m_mainWindow->mapFromGlobal(pos));
|
||||
} else {
|
||||
p_label->setParent(m_docks[info->m_dockIndex]);
|
||||
p_label->move(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void DockWidgetHelper::handleTargetHit(void *p_item)
|
||||
{
|
||||
auto info = static_cast<NavigationItemInfo *>(p_item);
|
||||
activateDock(static_cast<DockIndex>(info->m_dockIndex));
|
||||
}
|
||||
|
||||
void DockWidgetHelper::clearNavigation()
|
||||
{
|
||||
NavigationMode::clearNavigation();
|
||||
|
||||
m_navigationItems.clear();
|
||||
}
|
132
src/widgets/dockwidgethelper.h
Normal file
132
src/widgets/dockwidgethelper.h
Normal file
@ -0,0 +1,132 @@
|
||||
#ifndef DOCKWIDGETHELPER_H
|
||||
#define DOCKWIDGETHELPER_H
|
||||
|
||||
#include <QVector>
|
||||
#include <QIcon>
|
||||
#include <QSet>
|
||||
#include <QPair>
|
||||
|
||||
#include "navigationmode.h"
|
||||
|
||||
class QDockWidget;
|
||||
class QTabBar;
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
class MainWindow;
|
||||
|
||||
// Dock widget helper for MainWindow.
|
||||
class DockWidgetHelper : public QObject, public NavigationMode
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Index in m_docks.
|
||||
enum DockIndex
|
||||
{
|
||||
NavigationDock = 0,
|
||||
OutlineDock,
|
||||
HistoryDock,
|
||||
SearchDock,
|
||||
SnippetDock,
|
||||
LocationListDock,
|
||||
MaxDock
|
||||
};
|
||||
Q_ENUM(DockIndex)
|
||||
|
||||
explicit DockWidgetHelper(MainWindow *p_mainWindow);
|
||||
|
||||
void setupDocks();
|
||||
|
||||
void postSetup();
|
||||
|
||||
void activateDock(DockIndex p_dockIndex);
|
||||
|
||||
QDockWidget *getDock(DockIndex p_dockIndex) const;
|
||||
|
||||
const QVector<QDockWidget *> &getDocks() const;
|
||||
|
||||
void updateDockWidgetTabBar();
|
||||
|
||||
QStringList getVisibleDocks() const;
|
||||
|
||||
QStringList hideDocks();
|
||||
|
||||
void restoreDocks(const QStringList &p_visibleDocks);
|
||||
|
||||
// If there is any dock that does not belong to keep docks visible.
|
||||
bool isAnyDockVisible() const;
|
||||
|
||||
// NavigationMode.
|
||||
protected:
|
||||
QVector<void *> getVisibleNavigationItems() Q_DECL_OVERRIDE;
|
||||
|
||||
void placeNavigationLabel(int p_idx, void *p_item, QLabel *p_label) Q_DECL_OVERRIDE;
|
||||
|
||||
void handleTargetHit(void *p_item) Q_DECL_OVERRIDE;
|
||||
|
||||
void clearNavigation() Q_DECL_OVERRIDE;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
struct NavigationItemInfo
|
||||
{
|
||||
NavigationItemInfo() = default;
|
||||
|
||||
NavigationItemInfo(QTabBar *p_tabBar, int p_tabIndex, int p_dockIndex);
|
||||
|
||||
NavigationItemInfo(int p_dockIndex);
|
||||
|
||||
QTabBar *m_tabBar = nullptr;
|
||||
|
||||
int m_tabIndex = -1;
|
||||
|
||||
int m_dockIndex = -1;
|
||||
};
|
||||
|
||||
struct IconInfo
|
||||
{
|
||||
QIcon m_icon;
|
||||
|
||||
int m_rotationAngle = INT_MIN;
|
||||
};
|
||||
|
||||
void setupNavigationDock();
|
||||
|
||||
void setupOutlineDock();
|
||||
|
||||
void setupSearchDock();
|
||||
|
||||
void setupSnippetDock();
|
||||
|
||||
void setupHistoryDock();
|
||||
|
||||
void setupLocationListDock();
|
||||
|
||||
QDockWidget *createDockWidget(DockIndex p_dockIndex, const QString &p_title, QWidget *p_parent);
|
||||
|
||||
void setupShortcuts();
|
||||
|
||||
void activateDock(QDockWidget *p_dock);
|
||||
|
||||
void setupDockActivateShortcut(QDockWidget *p_dock, const QString &p_keys);
|
||||
|
||||
const QIcon &getDockIcon(DockIndex p_dockIndex);
|
||||
|
||||
static QString iconFileName(DockIndex p_dockIndex);
|
||||
|
||||
MainWindow *m_mainWindow = nullptr;
|
||||
|
||||
QVector<IconInfo> m_dockIcons;
|
||||
|
||||
QVector<QDockWidget *> m_docks;
|
||||
|
||||
// We need to install event filter to the tabbar of tabified dock widgets.
|
||||
QSet<QTabBar *> m_tabBarsMonitored;
|
||||
|
||||
QVector<NavigationItemInfo> m_navigationItems;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOCKWIDGETHELPER_H
|
@ -18,9 +18,6 @@
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QWindowStateChangeEvent>
|
||||
#include <QTimer>
|
||||
#include <QBitArray>
|
||||
#include <QHelpEvent>
|
||||
#include <QToolTip>
|
||||
|
||||
#include "toolbox.h"
|
||||
#include "notebookexplorer.h"
|
||||
@ -57,11 +54,11 @@
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
const char *MainWindow::c_propertyDockIndex = "DockIndex";
|
||||
const char *MainWindow::c_propertyDockTitle = "DockTitle";
|
||||
|
||||
MainWindow::MainWindow(QWidget *p_parent)
|
||||
: QMainWindow(p_parent)
|
||||
: QMainWindow(p_parent),
|
||||
m_toolBarHelper(this),
|
||||
m_statusBarHelper(this),
|
||||
m_dockWidgetHelper(this)
|
||||
{
|
||||
VNoteX::getInst().setMainWindow(this);
|
||||
|
||||
@ -73,14 +70,7 @@ MainWindow::MainWindow(QWidget *p_parent)
|
||||
|
||||
loadStateAndGeometry();
|
||||
|
||||
{
|
||||
updateDockWidgetTabBar();
|
||||
|
||||
for (auto dock : m_docks) {
|
||||
connect(dock, &QDockWidget::visibilityChanged,
|
||||
this, &MainWindow::updateDockWidgetTabBar);
|
||||
}
|
||||
}
|
||||
m_dockWidgetHelper.postSetup();
|
||||
|
||||
// The signal is particularly useful if your application has to do some last-second cleanup.
|
||||
// Note that no user interaction is possible in this state.
|
||||
@ -113,6 +103,8 @@ void MainWindow::kickOffOnStart(const QStringList &p_paths)
|
||||
|
||||
emit layoutChanged();
|
||||
|
||||
checkNotebooksFailedToLoad();
|
||||
|
||||
demoWidget();
|
||||
|
||||
openFiles(p_paths);
|
||||
@ -148,12 +140,12 @@ void MainWindow::setupUI()
|
||||
setupTipsArea();
|
||||
setupSystemTray();
|
||||
|
||||
activateDock(m_docks[DockIndex::NavigationDock]);
|
||||
m_dockWidgetHelper.activateDock(DockWidgetHelper::NavigationDock);
|
||||
}
|
||||
|
||||
void MainWindow::setupStatusBar()
|
||||
{
|
||||
m_statusBarHelper.setupStatusBar(this);
|
||||
m_statusBarHelper.setupStatusBar();
|
||||
connect(&VNoteX::getInst(), &VNoteX::statusMessageRequested,
|
||||
statusBar(), &QStatusBar::showMessage);
|
||||
}
|
||||
@ -213,12 +205,12 @@ void MainWindow::setupCentralWidget()
|
||||
});
|
||||
|
||||
{
|
||||
auto notebookMgr = &VNoteX::getInst().getNotebookMgr();
|
||||
connect(notebookMgr, &NotebookMgr::notebookAboutToClose,
|
||||
auto ¬ebookMgr = VNoteX::getInst().getNotebookMgr();
|
||||
connect(¬ebookMgr, &NotebookMgr::notebookAboutToClose,
|
||||
this, [this](const Notebook *p_notebook) {
|
||||
m_viewArea->close(p_notebook, true);
|
||||
});
|
||||
connect(notebookMgr, &NotebookMgr::notebookAboutToRemove,
|
||||
connect(¬ebookMgr, &NotebookMgr::notebookAboutToRemove,
|
||||
this, [this](const Notebook *p_notebook) {
|
||||
m_viewArea->close(p_notebook, true);
|
||||
});
|
||||
@ -229,120 +221,21 @@ void MainWindow::setupCentralWidget()
|
||||
|
||||
void MainWindow::setupDocks()
|
||||
{
|
||||
setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::West);
|
||||
setTabPosition(Qt::RightDockWidgetArea, QTabWidget::East);
|
||||
setTabPosition(Qt::TopDockWidgetArea, QTabWidget::North);
|
||||
setTabPosition(Qt::BottomDockWidgetArea, QTabWidget::North);
|
||||
setDockNestingEnabled(true);
|
||||
|
||||
// Init docks icon.
|
||||
{
|
||||
m_dockIcons.resize(DockIndex::MaxDock);
|
||||
|
||||
const auto &themeMgr = VNoteX::getInst().getThemeMgr();
|
||||
const auto fg = themeMgr.paletteColor("widgets#mainwindow#dockwidget_tabbar#icon#fg");
|
||||
const auto selectedFg = themeMgr.paletteColor("widgets#mainwindow#dockwidget_tabbar#icon#selected#fg");
|
||||
|
||||
QVector<IconUtils::OverriddenColor> colors;
|
||||
colors.push_back(IconUtils::OverriddenColor(fg, QIcon::Normal));
|
||||
// FIXME: the Selected Mode is not used by the selected tab of a QTabBar.
|
||||
colors.push_back(IconUtils::OverriddenColor(selectedFg, QIcon::Selected));
|
||||
|
||||
auto iconFile = themeMgr.getIconFile("navigation_dock.svg");
|
||||
m_dockIcons[DockIndex::NavigationDock] = IconUtils::fetchIcon(iconFile, colors, 90);
|
||||
|
||||
iconFile = themeMgr.getIconFile("outline_dock.svg");
|
||||
m_dockIcons[DockIndex::OutlineDock] = IconUtils::fetchIcon(iconFile, colors, 90);
|
||||
|
||||
iconFile = themeMgr.getIconFile("history_dock.svg");
|
||||
m_dockIcons[DockIndex::HistoryDock] = IconUtils::fetchIcon(iconFile, colors, 90);
|
||||
|
||||
iconFile = themeMgr.getIconFile("search_dock.svg");
|
||||
m_dockIcons[DockIndex::SearchDock] = IconUtils::fetchIcon(iconFile, colors, 90);
|
||||
|
||||
iconFile = themeMgr.getIconFile("snippet_dock.svg");
|
||||
m_dockIcons[DockIndex::SnippetDock] = IconUtils::fetchIcon(iconFile, colors, 90);
|
||||
|
||||
iconFile = themeMgr.getIconFile("location_list_dock.svg");
|
||||
m_dockIcons[DockIndex::LocationListDock] = IconUtils::fetchIcon(iconFile, colors, 90);
|
||||
}
|
||||
|
||||
// The order of m_docks should be identical with enum DockIndex.
|
||||
setupNavigationDock();
|
||||
|
||||
setupOutlineDock();
|
||||
|
||||
setupHistoryDock();
|
||||
|
||||
setupSearchDock();
|
||||
|
||||
setupSnippetDock();
|
||||
|
||||
for (int i = 1; i < m_docks.size(); ++i) {
|
||||
tabifyDockWidget(m_docks[i - 1], m_docks[i]);
|
||||
}
|
||||
|
||||
// Following are non-tabfieid docks.
|
||||
setupLocationListDock();
|
||||
}
|
||||
|
||||
void MainWindow::activateDock(QDockWidget *p_dock)
|
||||
{
|
||||
p_dock->show();
|
||||
Q_FOREACH(QTabBar* tabBar, this->findChildren<QTabBar*>(QString(), Qt::FindDirectChildrenOnly)) {
|
||||
bool found = false;
|
||||
for (int i = 0; i < tabBar->count(); ++i) {
|
||||
if (p_dock == reinterpret_cast<QWidget *>(tabBar->tabData(i).toULongLong())) {
|
||||
tabBar->setCurrentIndex(i);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
p_dock->setFocus();
|
||||
}
|
||||
|
||||
void MainWindow::setupNavigationDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::NavigationDock, tr("Navigation"), this);
|
||||
|
||||
dock->setObjectName(QStringLiteral("NavigationDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
setupNotebookExplorer(this);
|
||||
dock->setWidget(m_notebookExplorer);
|
||||
dock->setFocusProxy(m_notebookExplorer);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
}
|
||||
|
||||
void MainWindow::setupOutlineDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::OutlineDock, tr("Outline"), this);
|
||||
|
||||
dock->setObjectName(QStringLiteral("OutlineDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
setupOutlineViewer();
|
||||
dock->setWidget(m_outlineViewer);
|
||||
dock->setFocusProxy(m_outlineViewer);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
}
|
||||
|
||||
void MainWindow::setupSearchDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::SearchDock, tr("Search"), this);
|
||||
|
||||
dock->setObjectName(QStringLiteral("SearchDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
setupHistoryPanel();
|
||||
|
||||
setupSearchPanel();
|
||||
dock->setWidget(m_searchPanel);
|
||||
dock->setFocusProxy(m_searchPanel);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
|
||||
setupSnippetPanel();
|
||||
|
||||
setupLocationList();
|
||||
|
||||
m_dockWidgetHelper.setupDocks();
|
||||
|
||||
NavigationModeMgr::getInst().registerNavigationTarget(&m_dockWidgetHelper);
|
||||
}
|
||||
|
||||
void MainWindow::setupSearchPanel()
|
||||
@ -355,19 +248,6 @@ void MainWindow::setupSearchPanel()
|
||||
m_searchPanel->setObjectName("SearchPanel.vnotex");
|
||||
}
|
||||
|
||||
void MainWindow::setupSnippetDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::SnippetDock, tr("Snippets"), this);
|
||||
|
||||
dock->setObjectName(QStringLiteral("SnippetDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
setupSnippetPanel();
|
||||
dock->setWidget(m_snippetPanel);
|
||||
dock->setFocusProxy(m_snippetPanel);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
}
|
||||
|
||||
void MainWindow::setupSnippetPanel()
|
||||
{
|
||||
m_snippetPanel = new SnippetPanel(this);
|
||||
@ -382,39 +262,12 @@ void MainWindow::setupSnippetPanel()
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupHistoryDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::HistoryDock, tr("History"), this);
|
||||
|
||||
dock->setObjectName(QStringLiteral("HistoryDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
setupHistoryPanel();
|
||||
dock->setWidget(m_historyPanel);
|
||||
dock->setFocusProxy(m_historyPanel);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
}
|
||||
|
||||
void MainWindow::setupHistoryPanel()
|
||||
{
|
||||
m_historyPanel = new HistoryPanel(this);
|
||||
m_historyPanel->setObjectName("HistoryPanel.vnotex");
|
||||
}
|
||||
|
||||
void MainWindow::setupLocationListDock()
|
||||
{
|
||||
auto dock = createDockWidget(DockIndex::LocationListDock, tr("Location List"), this);
|
||||
|
||||
dock->setObjectName(QStringLiteral("LocationListDock.vnotex"));
|
||||
dock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
|
||||
setupLocationList();
|
||||
dock->setWidget(m_locationList);
|
||||
dock->setFocusProxy(m_locationList);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, dock);
|
||||
dock->hide();
|
||||
}
|
||||
|
||||
void MainWindow::setupLocationList()
|
||||
{
|
||||
m_locationList = new LocationList(this);
|
||||
@ -444,19 +297,19 @@ void MainWindow::setupNotebookExplorer(QWidget *p_parent)
|
||||
m_notebookExplorer, &NotebookExplorer::importLegacyNotebook);
|
||||
connect(&VNoteX::getInst(), &VNoteX::locateNodeRequested,
|
||||
this, [this](Node *p_node) {
|
||||
activateDock(m_docks[DockIndex::NavigationDock]);
|
||||
m_dockWidgetHelper.activateDock(DockWidgetHelper::NavigationDock);
|
||||
m_notebookExplorer->locateNode(p_node);
|
||||
});
|
||||
|
||||
auto notebookMgr = &VNoteX::getInst().getNotebookMgr();
|
||||
connect(notebookMgr, &NotebookMgr::notebooksUpdated,
|
||||
auto ¬ebookMgr = VNoteX::getInst().getNotebookMgr();
|
||||
connect(¬ebookMgr, &NotebookMgr::notebooksUpdated,
|
||||
m_notebookExplorer, &NotebookExplorer::loadNotebooks);
|
||||
connect(notebookMgr, &NotebookMgr::notebookUpdated,
|
||||
connect(¬ebookMgr, &NotebookMgr::notebookUpdated,
|
||||
m_notebookExplorer, &NotebookExplorer::reloadNotebook);
|
||||
connect(notebookMgr, &NotebookMgr::currentNotebookChanged,
|
||||
connect(¬ebookMgr, &NotebookMgr::currentNotebookChanged,
|
||||
m_notebookExplorer, &NotebookExplorer::setCurrentNotebook);
|
||||
connect(m_notebookExplorer, &NotebookExplorer::notebookActivated,
|
||||
notebookMgr, &NotebookMgr::setCurrentNotebook);
|
||||
¬ebookMgr, &NotebookMgr::setCurrentNotebook);
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *p_event)
|
||||
@ -550,11 +403,7 @@ void MainWindow::loadStateAndGeometry(bool p_stateOnly)
|
||||
m_visibleDocksBeforeExpand = sg.m_visibleDocksBeforeExpand;
|
||||
if (m_visibleDocksBeforeExpand.isEmpty()) {
|
||||
// Init (or init again if there is no visible dock).
|
||||
for (int i = 0; i < m_docks.size(); ++i) {
|
||||
if (m_docks[i]->isVisible()) {
|
||||
m_visibleDocksBeforeExpand.push_back(m_docks[i]->objectName());
|
||||
}
|
||||
}
|
||||
m_visibleDocksBeforeExpand = m_dockWidgetHelper.getVisibleDocks();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -573,54 +422,18 @@ void MainWindow::resetStateAndGeometry()
|
||||
|
||||
void MainWindow::setContentAreaExpanded(bool p_expanded)
|
||||
{
|
||||
const auto &keepDocks = ConfigMgr::getInst().getWidgetConfig().getMainWindowKeepDocksExpandingContentArea();
|
||||
|
||||
if (p_expanded) {
|
||||
// Store the state and hide.
|
||||
m_visibleDocksBeforeExpand.clear();
|
||||
for (int i = 0; i < m_docks.size(); ++i) {
|
||||
const auto objName = m_docks[i]->objectName();
|
||||
if (m_docks[i]->isVisible()) {
|
||||
m_visibleDocksBeforeExpand.push_back(objName);
|
||||
}
|
||||
|
||||
if (m_docks[i]->isFloating() || keepDocks.contains(objName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_docks[i]->setVisible(false);
|
||||
}
|
||||
m_visibleDocksBeforeExpand = m_dockWidgetHelper.hideDocks();
|
||||
} else {
|
||||
// Restore the state.
|
||||
bool hasVisible = false;
|
||||
for (int i = 0; i < m_docks.size(); ++i) {
|
||||
const auto objName = m_docks[i]->objectName();
|
||||
if (m_docks[i]->isFloating() || keepDocks.contains(objName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool visible = m_visibleDocksBeforeExpand.contains(objName);
|
||||
hasVisible = hasVisible || visible;
|
||||
|
||||
m_docks[i]->setVisible(visible);
|
||||
}
|
||||
|
||||
if (!hasVisible) {
|
||||
// At least make one visible.
|
||||
m_docks[DockIndex::NavigationDock]->setVisible(true);
|
||||
}
|
||||
m_dockWidgetHelper.restoreDocks(m_visibleDocksBeforeExpand);
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::isContentAreaExpanded() const
|
||||
{
|
||||
const auto &keepDocks = ConfigMgr::getInst().getWidgetConfig().getMainWindowKeepDocksExpandingContentArea();
|
||||
for (auto dock : m_docks) {
|
||||
if (!dock->isFloating() && dock->isVisible() && !keepDocks.contains(dock->objectName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return !m_dockWidgetHelper.isAnyDockVisible();
|
||||
}
|
||||
|
||||
void MainWindow::demoWidget()
|
||||
@ -656,7 +469,7 @@ void MainWindow::setupOutlineViewer()
|
||||
|
||||
const QVector<QDockWidget *> &MainWindow::getDocks() const
|
||||
{
|
||||
return m_docks;
|
||||
return m_dockWidgetHelper.getDocks();
|
||||
}
|
||||
|
||||
void MainWindow::focusViewArea()
|
||||
@ -680,7 +493,7 @@ void MainWindow::setupToolBar()
|
||||
|
||||
auto toolBar = new TitleToolBar(tr("Global"), this);
|
||||
toolBar->setIconSize(iconSize);
|
||||
m_toolBarHelper.setupToolBars(this, toolBar);
|
||||
m_toolBarHelper.setupToolBars(toolBar);
|
||||
toolBar->addTitleBarIcons(ToolBarHelper::generateIcon(QStringLiteral("minimize.svg")),
|
||||
ToolBarHelper::generateIcon(QStringLiteral("maximize.svg")),
|
||||
ToolBarHelper::generateIcon(QStringLiteral("maximize_restore.svg")),
|
||||
@ -688,7 +501,7 @@ void MainWindow::setupToolBar()
|
||||
} else {
|
||||
auto toolBar = new QToolBar(tr("Global"), this);
|
||||
toolBar->setIconSize(iconSize);
|
||||
m_toolBarHelper.setupToolBars(this, toolBar);
|
||||
m_toolBarHelper.setupToolBars(toolBar);
|
||||
}
|
||||
|
||||
// Disable the context menu above tool bar.
|
||||
@ -703,41 +516,6 @@ void MainWindow::closeOnQuit()
|
||||
|
||||
void MainWindow::setupShortcuts()
|
||||
{
|
||||
const auto &coreConfig = ConfigMgr::getInst().getCoreConfig();
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::NavigationDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::NavigationDock));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::OutlineDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::OutlineDock));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::HistoryDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::HistoryDock));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::SearchDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::SearchDock));
|
||||
// Extra shortcut for SearchDock.
|
||||
setupDockActivateShortcut(m_docks[DockIndex::SearchDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::Search));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::LocationListDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::LocationListDock));
|
||||
|
||||
setupDockActivateShortcut(m_docks[DockIndex::SnippetDock],
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::SnippetDock));
|
||||
}
|
||||
|
||||
void MainWindow::setupDockActivateShortcut(QDockWidget *p_dock, const QString &p_keys)
|
||||
{
|
||||
auto shortcut = WidgetUtils::createShortcut(p_keys, this);
|
||||
if (shortcut) {
|
||||
p_dock->setToolTip(QString("%1\t%2").arg(p_dock->windowTitle(),
|
||||
QKeySequence(p_keys).toString(QKeySequence::NativeText)));
|
||||
connect(shortcut, &QShortcut::activated,
|
||||
this, [this, p_dock]() {
|
||||
activateDock(p_dock);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setStayOnTop(bool p_enabled)
|
||||
@ -806,50 +584,7 @@ void MainWindow::quitApp()
|
||||
|
||||
void MainWindow::updateDockWidgetTabBar()
|
||||
{
|
||||
QBitArray tabifiedDocks(m_docks.size(), false);
|
||||
Q_FOREACH(QTabBar* tabBar, this->findChildren<QTabBar*>(QString(), Qt::FindDirectChildrenOnly)) {
|
||||
if (!m_tabBarsMonitored.contains(tabBar)) {
|
||||
m_tabBarsMonitored.insert(tabBar);
|
||||
tabBar->installEventFilter(this);
|
||||
}
|
||||
|
||||
tabBar->setDrawBase(false);
|
||||
|
||||
const int sz = ConfigMgr::getInst().getCoreConfig().getDocksTabBarIconSize();
|
||||
tabBar->setIconSize(QSize(sz, sz));
|
||||
|
||||
auto tabShape = tabBar->shape();
|
||||
bool iconOnly = tabShape == QTabBar::RoundedWest || tabShape == QTabBar::RoundedEast
|
||||
|| tabShape == QTabBar::TriangularWest || tabShape == QTabBar::TriangularEast;
|
||||
const int cnt = tabBar->count();
|
||||
if (cnt == 1) {
|
||||
iconOnly = false;
|
||||
}
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
auto dock = reinterpret_cast<QDockWidget *>(tabBar->tabData(i).toULongLong());
|
||||
if (!dock) {
|
||||
continue;
|
||||
}
|
||||
int dockIdx = dock->property(c_propertyDockIndex).toInt();
|
||||
tabifiedDocks.setBit(dockIdx);
|
||||
if (iconOnly) {
|
||||
dock->setWindowTitle(QString());
|
||||
tabBar->setTabIcon(i, m_dockIcons[dockIdx]);
|
||||
} else if (dock->windowTitle().isEmpty()) {
|
||||
dock->setWindowTitle(dock->property(c_propertyDockTitle).toString());
|
||||
tabBar->setTabIcon(i, QIcon());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Non-tabified docks.
|
||||
for (int i = 0; i < m_docks.size(); ++i) {
|
||||
if (!tabifiedDocks[i] && m_docks[i]->windowTitle().isEmpty()) {
|
||||
m_docks[i]->setWindowTitle(m_docks[i]->property(c_propertyDockTitle).toString());
|
||||
}
|
||||
}
|
||||
|
||||
emit layoutChanged();
|
||||
m_dockWidgetHelper.updateDockWidgetTabBar();
|
||||
}
|
||||
|
||||
void MainWindow::exportNotes()
|
||||
@ -926,15 +661,15 @@ LocationList *MainWindow::getLocationList() const
|
||||
void MainWindow::setLocationListVisible(bool p_visible)
|
||||
{
|
||||
if (p_visible) {
|
||||
activateDock(m_docks[DockIndex::LocationListDock]);
|
||||
m_dockWidgetHelper.activateDock(DockWidgetHelper::LocationListDock);
|
||||
} else {
|
||||
m_docks[DockIndex::LocationListDock]->hide();
|
||||
m_dockWidgetHelper.getDock(DockWidgetHelper::LocationListDock)->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::toggleLocationListVisible()
|
||||
{
|
||||
bool visible = m_docks[DockIndex::LocationListDock]->isVisible();
|
||||
bool visible = m_dockWidgetHelper.getDock(DockWidgetHelper::LocationListDock)->isVisible();
|
||||
setLocationListVisible(!visible);
|
||||
}
|
||||
|
||||
@ -945,16 +680,6 @@ void MainWindow::setupSpellCheck()
|
||||
QStringList() << configMgr.getUserDictsFolder() << configMgr.getAppDictsFolder());
|
||||
}
|
||||
|
||||
QDockWidget *MainWindow::createDockWidget(DockIndex p_dockIndex, const QString &p_title, QWidget *p_parent)
|
||||
{
|
||||
auto dock = new QDockWidget(p_title, p_parent);
|
||||
dock->setToolTip(p_title);
|
||||
dock->setProperty(c_propertyDockIndex, p_dockIndex);
|
||||
dock->setProperty(c_propertyDockTitle, p_title);
|
||||
m_docks.push_back(dock);
|
||||
return dock;
|
||||
}
|
||||
|
||||
void MainWindow::checkForUpdates()
|
||||
{
|
||||
Updater::checkForUpdates(this, [this](bool p_hasUpdate, const QString &p_version, const QString &p_errMsg) {
|
||||
@ -966,29 +691,22 @@ void MainWindow::checkForUpdates()
|
||||
});
|
||||
}
|
||||
|
||||
bool MainWindow::eventFilter(QObject *p_obj, QEvent *p_event)
|
||||
void MainWindow::checkNotebooksFailedToLoad()
|
||||
{
|
||||
if (p_event->type() == QEvent::ToolTip) {
|
||||
// The QTabBar of the tabified dock widgets does not show tooltip due to Qt's internal implementation.
|
||||
auto helpEve = static_cast<QHelpEvent *>(p_event);
|
||||
auto tabBar = static_cast<QTabBar *>(p_obj);
|
||||
int idx = tabBar->tabAt(helpEve->pos());
|
||||
bool done = false;
|
||||
if (idx > -1) {
|
||||
auto dock = reinterpret_cast<QDockWidget *>(tabBar->tabData(idx).toULongLong());
|
||||
if (dock) {
|
||||
done = true;
|
||||
QToolTip::showText(helpEve->globalPos(), dock->property(c_propertyDockTitle).toString());
|
||||
}
|
||||
auto ¬ebookMgr = VNoteX::getInst().getNotebookMgr();
|
||||
const auto ¬ebooks = notebookMgr.getNotebooksFailedToLoad();
|
||||
if (notebooks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
QToolTip::hideText();
|
||||
p_event->ignore();
|
||||
int ret = MessageBoxHelper::questionYesNo(MessageBoxHelper::Warning,
|
||||
tr("Failed to load %n notebook(s).", "", notebooks.size()),
|
||||
tr("These notebooks may be moved or deleted. It is recommended to remove "
|
||||
"them from configuration and open them with the correct root folder path later.\n"
|
||||
"Remove them from the configuration?"),
|
||||
notebooks.join(QLatin1Char('\n')),
|
||||
this);
|
||||
if (ret == QMessageBox::Yes) {
|
||||
notebookMgr.clearNotebooksFailedToLoad();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return QMainWindow::eventFilter(p_obj, p_event);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QSet>
|
||||
|
||||
#include "toolbarhelper.h"
|
||||
#include "dockwidgethelper.h"
|
||||
#include "statusbarhelper.h"
|
||||
|
||||
class QDockWidget;
|
||||
@ -32,6 +33,8 @@ namespace vnotex
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
friend class DockWidgetHelper;
|
||||
|
||||
explicit MainWindow(QWidget *p_parent = nullptr);
|
||||
|
||||
~MainWindow();
|
||||
@ -69,10 +72,6 @@ namespace vnotex
|
||||
|
||||
void updateDockWidgetTabBar();
|
||||
|
||||
static const char *c_propertyDockIndex;
|
||||
|
||||
static const char *c_propertyDockTitle;
|
||||
|
||||
signals:
|
||||
void mainWindowStarted();
|
||||
|
||||
@ -89,8 +88,6 @@ namespace vnotex
|
||||
|
||||
void changeEvent(QEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
void closeOnQuit();
|
||||
|
||||
@ -99,42 +96,18 @@ namespace vnotex
|
||||
void showTips(const QString &p_message, int p_timeoutMilliseconds);
|
||||
|
||||
private:
|
||||
// Index in m_docks.
|
||||
enum DockIndex
|
||||
{
|
||||
NavigationDock = 0,
|
||||
OutlineDock,
|
||||
HistoryDock,
|
||||
SearchDock,
|
||||
SnippetDock,
|
||||
LocationListDock,
|
||||
MaxDock
|
||||
};
|
||||
|
||||
void setupUI();
|
||||
|
||||
void setupCentralWidget();
|
||||
|
||||
void setupOutlineViewer();
|
||||
|
||||
void setupNavigationDock();
|
||||
|
||||
void setupOutlineDock();
|
||||
|
||||
void setupSearchDock();
|
||||
|
||||
void setupSearchPanel();
|
||||
|
||||
void setupLocationListDock();
|
||||
|
||||
void setupLocationList();
|
||||
|
||||
void setupSnippetDock();
|
||||
|
||||
void setupSnippetPanel();
|
||||
|
||||
void setupHistoryDock();
|
||||
|
||||
void setupHistoryPanel();
|
||||
|
||||
void setupNotebookExplorer(QWidget *p_parent = nullptr);
|
||||
@ -156,8 +129,6 @@ namespace vnotex
|
||||
|
||||
QString getViewAreaTitle() const;
|
||||
|
||||
void activateDock(QDockWidget *p_dock);
|
||||
|
||||
void setupToolBar();
|
||||
|
||||
void setupShortcuts();
|
||||
@ -166,18 +137,18 @@ namespace vnotex
|
||||
|
||||
void setTipsAreaVisible(bool p_visible);
|
||||
|
||||
void setupDockActivateShortcut(QDockWidget *p_dock, const QString &p_keys);
|
||||
|
||||
void setupSpellCheck();
|
||||
|
||||
QDockWidget *createDockWidget(DockIndex p_dockIndex, const QString &p_title, QWidget *p_parent);
|
||||
|
||||
void checkForUpdates();
|
||||
|
||||
void checkNotebooksFailedToLoad();
|
||||
|
||||
ToolBarHelper m_toolBarHelper;
|
||||
|
||||
StatusBarHelper m_statusBarHelper;
|
||||
|
||||
DockWidgetHelper m_dockWidgetHelper;
|
||||
|
||||
ToolBox *m_navigationToolBox = nullptr;
|
||||
|
||||
NotebookExplorer *m_notebookExplorer = nullptr;
|
||||
@ -196,10 +167,6 @@ namespace vnotex
|
||||
|
||||
HistoryPanel *m_historyPanel = nullptr;
|
||||
|
||||
QVector<QDockWidget *> m_docks;
|
||||
|
||||
QVector<QIcon> m_dockIcons;
|
||||
|
||||
bool m_layoutReset = false;
|
||||
|
||||
// -1: do not request to quit;
|
||||
@ -215,9 +182,6 @@ namespace vnotex
|
||||
QTimer *m_tipsTimer = nullptr;
|
||||
|
||||
QStringList m_visibleDocksBeforeExpand;
|
||||
|
||||
// We need to install event filter to the tabbar of tabified dock widgets.
|
||||
QSet<QTabBar *> m_tabBarsMonitored;
|
||||
};
|
||||
} // ns vnotex
|
||||
|
||||
|
@ -54,7 +54,7 @@ namespace vnotex
|
||||
|
||||
virtual QVector<void *> getVisibleNavigationItems();
|
||||
|
||||
// @p_idx: -1 for SingleKey and the major stage of StagedDoubleKeys.
|
||||
// @p_idx: will be -1 for SingleKey case and the major stage of StagedDoubleKeys case.
|
||||
virtual void placeNavigationLabel(int p_idx, void * p_item, QLabel *p_label) = 0;
|
||||
|
||||
virtual void showNavigationWithDoubleKeys();
|
||||
|
@ -21,3 +21,7 @@ const char *PropertyDefs::c_viewWindowToolBar = "ViewWindowToolBar";
|
||||
const char *PropertyDefs::c_consoleTextEdit = "ConsoleTextEdit";
|
||||
|
||||
const char *PropertyDefs::c_embeddedLineEdit = "EmbeddedLineEdit";
|
||||
|
||||
const char *PropertyDefs::c_dockWidgetIndex = "DockIndex";
|
||||
|
||||
const char *PropertyDefs::c_dockWidgetTitle = "DockTitle";
|
||||
|
@ -29,6 +29,10 @@ namespace vnotex
|
||||
|
||||
// Values: info/warning/error.
|
||||
static const char *c_state;
|
||||
|
||||
static const char *c_dockWidgetIndex;
|
||||
|
||||
static const char *c_dockWidgetTitle;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,13 @@
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
void StatusBarHelper::setupStatusBar(MainWindow *p_win)
|
||||
StatusBarHelper::StatusBarHelper(MainWindow *p_mainWindow)
|
||||
: m_mainWindow(p_mainWindow)
|
||||
{
|
||||
m_statusBar = new QStatusBar(p_win);
|
||||
p_win->setStatusBar(m_statusBar);
|
||||
}
|
||||
|
||||
void StatusBarHelper::setupStatusBar()
|
||||
{
|
||||
m_statusBar = new QStatusBar(m_mainWindow);
|
||||
m_mainWindow->setStatusBar(m_statusBar);
|
||||
}
|
||||
|
@ -11,13 +11,13 @@ namespace vnotex
|
||||
class StatusBarHelper
|
||||
{
|
||||
public:
|
||||
StatusBarHelper()
|
||||
{
|
||||
}
|
||||
explicit StatusBarHelper(MainWindow *p_mainWindow);
|
||||
|
||||
void setupStatusBar(MainWindow *p_win);
|
||||
void setupStatusBar();
|
||||
|
||||
private:
|
||||
MainWindow *m_mainWindow = nullptr;
|
||||
|
||||
QStatusBar *m_statusBar;
|
||||
};
|
||||
} // ns vnotex
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "vnotex.h"
|
||||
#include <core/vnotex.h>
|
||||
#include "widgetsfactory.h"
|
||||
#include <utils/iconutils.h>
|
||||
#include <utils/widgetutils.h>
|
||||
@ -29,6 +29,11 @@
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
ToolBarHelper::ToolBarHelper(MainWindow *p_mainWindow)
|
||||
: m_mainWindow(p_mainWindow)
|
||||
{
|
||||
}
|
||||
|
||||
static QToolBar *createToolBar(MainWindow *p_win, const QString &p_title, const QString &p_name)
|
||||
{
|
||||
auto tb = p_win->addToolBar(p_title);
|
||||
@ -147,12 +152,13 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar
|
||||
tb->addWidget(newBtn);
|
||||
}
|
||||
|
||||
// Import and export.
|
||||
// Import.
|
||||
{
|
||||
auto act = tb->addAction(generateIcon("import_export_menu.svg"), MainWindow::tr("Import/Export"));
|
||||
auto act = tb->addAction(generateIcon("import_menu.svg"), MainWindow::tr("Import"));
|
||||
|
||||
auto btn = dynamic_cast<QToolButton *>(tb->widgetForAction(act));
|
||||
Q_ASSERT(btn);
|
||||
btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
btn->setPopupMode(QToolButton::InstantPopup);
|
||||
btn->setProperty(PropertyDefs::c_toolButtonWithoutMenuIndicator, true);
|
||||
|
||||
@ -172,16 +178,24 @@ QToolBar *ToolBarHelper::setupFileToolBar(MainWindow *p_win, QToolBar *p_toolBar
|
||||
[]() {
|
||||
emit VNoteX::getInst().importFolderRequested();
|
||||
});
|
||||
}
|
||||
|
||||
newMenu->addSeparator();
|
||||
|
||||
auto exportAct = newMenu->addAction(MainWindow::tr("Export (Convert Format)"),
|
||||
newMenu,
|
||||
// Export.
|
||||
{
|
||||
auto exportAct = tb->addAction(generateIcon("export_menu.svg"),
|
||||
MainWindow::tr("Export (Convert Format)"),
|
||||
[]() {
|
||||
emit VNoteX::getInst().exportRequested();
|
||||
});
|
||||
|
||||
WidgetUtils::addActionShortcut(exportAct,
|
||||
coreConfig.getShortcut(CoreConfig::Shortcut::Export));
|
||||
|
||||
// To hide the shortcut text shown in button.
|
||||
auto toolBtn = dynamic_cast<QToolButton *>(tb->widgetForAction(exportAct));
|
||||
Q_ASSERT(toolBtn);
|
||||
toolBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
toolBtn->setText(MainWindow::tr("Export"));
|
||||
}
|
||||
|
||||
return tb;
|
||||
@ -579,31 +593,31 @@ QIcon ToolBarHelper::generateDangerousIcon(const QString &p_iconName)
|
||||
return IconUtils::fetchIcon(iconFile, colors);
|
||||
}
|
||||
|
||||
void ToolBarHelper::setupToolBars(MainWindow *p_win)
|
||||
void ToolBarHelper::setupToolBars()
|
||||
{
|
||||
m_toolBars.clear();
|
||||
|
||||
auto fileTab = setupFileToolBar(p_win, nullptr);
|
||||
auto fileTab = setupFileToolBar(m_mainWindow, nullptr);
|
||||
m_toolBars.insert(fileTab->objectName(), fileTab);
|
||||
|
||||
auto quickAccessTb = setupQuickAccessToolBar(p_win, nullptr);
|
||||
auto quickAccessTb = setupQuickAccessToolBar(m_mainWindow, nullptr);
|
||||
m_toolBars.insert(quickAccessTb->objectName(), quickAccessTb);
|
||||
|
||||
auto settingsToolBar = setupSettingsToolBar(p_win, nullptr);
|
||||
auto settingsToolBar = setupSettingsToolBar(m_mainWindow, nullptr);
|
||||
m_toolBars.insert(settingsToolBar->objectName(), settingsToolBar);
|
||||
}
|
||||
|
||||
void ToolBarHelper::setupToolBars(MainWindow *p_win, QToolBar *p_toolBar)
|
||||
void ToolBarHelper::setupToolBars(QToolBar *p_toolBar)
|
||||
{
|
||||
m_toolBars.clear();
|
||||
|
||||
p_toolBar->setObjectName(QStringLiteral("UnifiedToolBar"));
|
||||
p_toolBar->setMovable(false);
|
||||
p_win->addToolBar(p_toolBar);
|
||||
m_mainWindow->addToolBar(p_toolBar);
|
||||
|
||||
setupFileToolBar(p_win, p_toolBar);
|
||||
setupQuickAccessToolBar(p_win, p_toolBar);
|
||||
setupSettingsToolBar(p_win, p_toolBar);
|
||||
setupFileToolBar(m_mainWindow, p_toolBar);
|
||||
setupQuickAccessToolBar(m_mainWindow, p_toolBar);
|
||||
setupSettingsToolBar(m_mainWindow, p_toolBar);
|
||||
m_toolBars.insert(p_toolBar->objectName(), p_toolBar);
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,13 @@ namespace vnotex
|
||||
class ToolBarHelper
|
||||
{
|
||||
public:
|
||||
explicit ToolBarHelper(MainWindow *p_mainWindow);
|
||||
|
||||
// Setup all tool bars of main window.
|
||||
void setupToolBars(MainWindow *p_win);
|
||||
void setupToolBars();
|
||||
|
||||
// Setup tool bars of main window into one unified tool bar.
|
||||
void setupToolBars(MainWindow *p_win, QToolBar *p_toolBar);
|
||||
void setupToolBars(QToolBar *p_toolBar);
|
||||
|
||||
static QIcon generateIcon(const QString &p_iconName);
|
||||
|
||||
@ -33,6 +35,8 @@ namespace vnotex
|
||||
|
||||
static QToolBar *setupSettingsToolBar(MainWindow *p_win, QToolBar *p_toolBar);
|
||||
|
||||
MainWindow *m_mainWindow = nullptr;
|
||||
|
||||
QHash<QString, QToolBar *> m_toolBars;
|
||||
};
|
||||
} // ns vnotex
|
||||
|
@ -35,6 +35,7 @@ SOURCES += \
|
||||
$$PWD/dialogs/sortdialog.cpp \
|
||||
$$PWD/dialogs/tableinsertdialog.cpp \
|
||||
$$PWD/dialogs/updater.cpp \
|
||||
$$PWD/dockwidgethelper.cpp \
|
||||
$$PWD/dragdropareaindicator.cpp \
|
||||
$$PWD/editors/editormarkdownvieweradapter.cpp \
|
||||
$$PWD/editors/graphhelper.cpp \
|
||||
@ -151,6 +152,7 @@ HEADERS += \
|
||||
$$PWD/dialogs/sortdialog.h \
|
||||
$$PWD/dialogs/tableinsertdialog.h \
|
||||
$$PWD/dialogs/updater.h \
|
||||
$$PWD/dockwidgethelper.h \
|
||||
$$PWD/dragdropareaindicator.h \
|
||||
$$PWD/editors/editormarkdownvieweradapter.h \
|
||||
$$PWD/editors/graphhelper.h \
|
||||
|
Loading…
x
Reference in New Issue
Block a user