mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
Outline: support increase/decrease the expanded level
Add config [global]/outline_expanded_level (6 by default).
This commit is contained in:
parent
4f4652dc3a
commit
5ebc7b8243
9
src/resources/icons/decrease_outline_level.svg
Normal file
9
src/resources/icons/decrease_outline_level.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path style="fill:#000000" d="M213.7,256L213.7,256L213.7,256L380.9,81.9c4.2-4.3,4.1-11.4-0.2-15.8l-29.9-30.6c-4.3-4.4-11.3-4.5-15.5-0.2L131.1,247.9
|
||||
c-2.2,2.2-3.2,5.2-3,8.1c-0.1,3,0.9,5.9,3,8.1l204.2,212.7c4.2,4.3,11.2,4.2,15.5-0.2l29.9-30.6c4.3-4.4,4.4-11.5,0.2-15.8
|
||||
L213.7,256z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 768 B |
9
src/resources/icons/increase_outline_level.svg
Normal file
9
src/resources/icons/increase_outline_level.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path style="fill:#000000" d="M298.3,256L298.3,256L298.3,256L131.1,81.9c-4.2-4.3-4.1-11.4,0.2-15.8l29.9-30.6c4.3-4.4,11.3-4.5,15.5-0.2l204.2,212.7
|
||||
c2.2,2.2,3.2,5.2,3,8.1c0.1,3-0.9,5.9-3,8.1L176.7,476.8c-4.2,4.3-11.2,4.2-15.5-0.2L131.3,446c-4.3-4.4-4.4-11.5-0.2-15.8
|
||||
L298.3,256z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 767 B |
@ -229,6 +229,10 @@ history_size=50
|
||||
; 6 - modified time reverse
|
||||
note_list_view_order=0
|
||||
|
||||
; Level of the heading the outline should be expanded to
|
||||
; 1 - 6
|
||||
outline_expanded_level=6
|
||||
|
||||
[export]
|
||||
; Path of the wkhtmltopdf tool
|
||||
wkhtmltopdf=wkhtmltopdf
|
||||
|
@ -300,6 +300,9 @@ void VConfigManager::initialize()
|
||||
if (m_historySize < 0) {
|
||||
m_historySize = 0;
|
||||
}
|
||||
|
||||
m_outlineExpandedLevel = getConfigFromSettings("global",
|
||||
"outline_expanded_level").toInt();
|
||||
}
|
||||
|
||||
void VConfigManager::initSettings()
|
||||
|
@ -519,6 +519,9 @@ public:
|
||||
int getNoteListViewOrder() const;
|
||||
void setNoteListViewOrder(int p_order);
|
||||
|
||||
int getOutlineExpandedLevel() const;
|
||||
void setOutlineExpandedLevel(int p_level);
|
||||
|
||||
private:
|
||||
// Look up a config from user and default settings.
|
||||
QVariant getConfigFromSettings(const QString §ion, const QString &key) const;
|
||||
@ -935,6 +938,9 @@ private:
|
||||
// Whether user has reset the configurations.
|
||||
bool m_hasReset;
|
||||
|
||||
// Expanded level of outline.
|
||||
int m_outlineExpandedLevel;
|
||||
|
||||
// The name of the config file in each directory.
|
||||
static const QString c_dirConfigFile;
|
||||
|
||||
@ -2433,4 +2439,19 @@ inline QString VConfigManager::fetchDirConfigFilePath(const QString &p_path)
|
||||
{
|
||||
return QDir(p_path).filePath(c_dirConfigFile);
|
||||
}
|
||||
|
||||
inline int VConfigManager::getOutlineExpandedLevel() const
|
||||
{
|
||||
return m_outlineExpandedLevel;
|
||||
}
|
||||
|
||||
inline void VConfigManager::setOutlineExpandedLevel(int p_level)
|
||||
{
|
||||
if (m_outlineExpandedLevel == p_level) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_outlineExpandedLevel = p_level;
|
||||
setConfigToSettings("global", "outline_expanded_level", m_outlineExpandedLevel);
|
||||
}
|
||||
#endif // VCONFIGMANAGER_H
|
||||
|
@ -263,5 +263,7 @@
|
||||
<file>resources/icons/tag.svg</file>
|
||||
<file>resources/view_image.js</file>
|
||||
<file>resources/view_image.css</file>
|
||||
<file>resources/icons/decrease_outline_level.svg</file>
|
||||
<file>resources/icons/increase_outline_level.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
201
src/voutline.cpp
201
src/voutline.cpp
@ -1,27 +1,111 @@
|
||||
#include <QVector>
|
||||
#include <QString>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QCoreApplication>
|
||||
#include "voutline.h"
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "utils/vutils.h"
|
||||
#include "vnote.h"
|
||||
#include "vfile.h"
|
||||
#include "vtreewidget.h"
|
||||
#include "utils/viconutils.h"
|
||||
#include "vconfigmanager.h"
|
||||
#include "vmainwindow.h"
|
||||
|
||||
extern VNote *g_vnote;
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
extern VMainWindow *g_mainWin;
|
||||
|
||||
#define STATIC_EXPANDED_LEVEL 6
|
||||
|
||||
VOutline::VOutline(QWidget *parent)
|
||||
: VTreeWidget(parent),
|
||||
: QWidget(parent),
|
||||
VNavigationMode(),
|
||||
m_muted(false)
|
||||
{
|
||||
setColumnCount(1);
|
||||
setHeaderHidden(true);
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
setupUI();
|
||||
|
||||
m_expandTimer = new QTimer(this);
|
||||
m_expandTimer->setSingleShot(true);
|
||||
m_expandTimer->setInterval(1000);
|
||||
connect(m_expandTimer, &QTimer::timeout,
|
||||
this, [this]() {
|
||||
// Auto adjust items after current header change.
|
||||
int level = g_config->getOutlineExpandedLevel();
|
||||
if (level == STATIC_EXPANDED_LEVEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
expandTree(level);
|
||||
|
||||
QTreeWidgetItem *curItem = m_tree->currentItem();
|
||||
if (curItem) {
|
||||
m_tree->scrollToItem(curItem);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void VOutline::setupUI()
|
||||
{
|
||||
m_deLevelBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/decrease_outline_level.svg"),
|
||||
"",
|
||||
this);
|
||||
m_deLevelBtn->setToolTip(tr("Decrease Expanded Level"));
|
||||
m_deLevelBtn->setProperty("FlatBtn", true);
|
||||
m_deLevelBtn->setEnabled(false);
|
||||
connect(m_deLevelBtn, &QPushButton::clicked,
|
||||
this, [this]() {
|
||||
int level = g_config->getOutlineExpandedLevel() - 1;
|
||||
if (level <= 0) {
|
||||
level = 1;
|
||||
} else {
|
||||
g_config->setOutlineExpandedLevel(level);
|
||||
expandTree(level);
|
||||
}
|
||||
|
||||
g_mainWin->showStatusMessage(tr("Set Outline Expanded Level to %1").arg(level));
|
||||
});
|
||||
|
||||
m_inLevelBtn = new QPushButton(VIconUtils::buttonIcon(":/resources/icons/increase_outline_level.svg"),
|
||||
"",
|
||||
this);
|
||||
m_inLevelBtn->setToolTip(tr("Increase Expanded Level"));
|
||||
m_inLevelBtn->setProperty("FlatBtn", true);
|
||||
m_inLevelBtn->setEnabled(false);
|
||||
connect(m_inLevelBtn, &QPushButton::clicked,
|
||||
this, [this]() {
|
||||
int level = g_config->getOutlineExpandedLevel() + 1;
|
||||
if (level >= 7) {
|
||||
level = 6;
|
||||
} else {
|
||||
g_config->setOutlineExpandedLevel(level);
|
||||
expandTree(level);
|
||||
}
|
||||
|
||||
g_mainWin->showStatusMessage(tr("Set Outline Expanded Level to %1").arg(level));
|
||||
});
|
||||
|
||||
QHBoxLayout *btnLayout = new QHBoxLayout();
|
||||
btnLayout->addStretch();
|
||||
btnLayout->addWidget(m_deLevelBtn);
|
||||
btnLayout->addWidget(m_inLevelBtn);
|
||||
btnLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_tree = new VTreeWidget(this);
|
||||
m_tree->setColumnCount(1);
|
||||
m_tree->setHeaderHidden(true);
|
||||
m_tree->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
// TODO: jump to the header when user click the same item twice.
|
||||
connect(this, &VOutline::currentItemChanged,
|
||||
connect(m_tree, &QTreeWidget::currentItemChanged,
|
||||
this, &VOutline::handleCurrentItemChanged);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
layout->addLayout(btnLayout);
|
||||
layout->addWidget(m_tree);
|
||||
layout->setContentsMargins(3, 0, 3, 0);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void VOutline::updateOutline(const VTableOfContent &p_outline)
|
||||
@ -35,9 +119,11 @@ void VOutline::updateOutline(const VTableOfContent &p_outline)
|
||||
|
||||
m_outline = p_outline;
|
||||
|
||||
updateTreeFromOutline(this, m_outline);
|
||||
updateTreeFromOutline(m_tree, m_outline);
|
||||
|
||||
expandTree();
|
||||
updateButtonsState();
|
||||
|
||||
expandTree(g_config->getOutlineExpandedLevel());
|
||||
}
|
||||
|
||||
void VOutline::updateTreeFromOutline(QTreeWidget *p_treeWidget,
|
||||
@ -94,13 +180,42 @@ void VOutline::fillItem(QTreeWidgetItem *p_item, const VTableOfContentItem &p_he
|
||||
}
|
||||
}
|
||||
|
||||
void VOutline::expandTree()
|
||||
void VOutline::expandTree(int p_expandedLevel)
|
||||
{
|
||||
if (topLevelItemCount() == 0) {
|
||||
int topCount = m_tree->topLevelItemCount();
|
||||
if (topCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
expandAll();
|
||||
m_tree->collapseAll();
|
||||
|
||||
// Get the base level.
|
||||
const VTableOfContentItem *header = getHeaderFromItem(m_tree->topLevelItem(0), m_outline);
|
||||
if (!header) {
|
||||
return;
|
||||
}
|
||||
|
||||
int baseLevel = header->m_level;
|
||||
int levelToBeExpanded = p_expandedLevel - baseLevel;
|
||||
|
||||
for (int i = 0; i < topCount; ++i) {
|
||||
expandTreeOne(m_tree->topLevelItem(i), levelToBeExpanded);
|
||||
}
|
||||
}
|
||||
|
||||
void VOutline::expandTreeOne(QTreeWidgetItem *p_item, int p_levelToBeExpanded)
|
||||
{
|
||||
if (p_levelToBeExpanded <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Expand this item.
|
||||
p_item->setExpanded(true);
|
||||
|
||||
int nrChild = p_item->childCount();
|
||||
for (int i = 0; i < nrChild; ++i) {
|
||||
expandTreeOne(p_item->child(i), p_levelToBeExpanded - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void VOutline::handleCurrentItemChanged(QTreeWidgetItem *p_curItem,
|
||||
@ -131,8 +246,10 @@ void VOutline::updateCurrentHeader(const VHeaderPointer &p_header)
|
||||
// Item change should not emit the signal.
|
||||
m_muted = true;
|
||||
m_currentHeader = p_header;
|
||||
selectHeader(this, m_outline, m_currentHeader);
|
||||
selectHeader(m_tree, m_outline, m_currentHeader);
|
||||
m_muted = false;
|
||||
|
||||
m_expandTimer->start();
|
||||
}
|
||||
|
||||
void VOutline::selectHeader(QTreeWidget *p_treeWidget,
|
||||
@ -184,59 +301,35 @@ bool VOutline::selectHeaderOne(QTreeWidget *p_treeWidget,
|
||||
|
||||
void VOutline::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
int key = event->key();
|
||||
int modifiers = event->modifiers();
|
||||
|
||||
switch (key) {
|
||||
switch (event->key()) {
|
||||
case Qt::Key_Return:
|
||||
V_FALLTHROUGH;
|
||||
case Qt::Key_Enter:
|
||||
{
|
||||
QTreeWidgetItem *item = currentItem();
|
||||
QTreeWidgetItem *item = m_tree->currentItem();
|
||||
if (item) {
|
||||
item->setExpanded(!item->isExpanded());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_J:
|
||||
{
|
||||
if (modifiers == Qt::ControlModifier) {
|
||||
event->accept();
|
||||
QKeyEvent *downEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down,
|
||||
Qt::NoModifier);
|
||||
QCoreApplication::postEvent(this, downEvent);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_K:
|
||||
{
|
||||
if (modifiers == Qt::ControlModifier) {
|
||||
event->accept();
|
||||
QKeyEvent *upEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up,
|
||||
Qt::NoModifier);
|
||||
QCoreApplication::postEvent(this, upEvent);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
VTreeWidget::keyPressEvent(event);
|
||||
QWidget::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void VOutline::showNavigation()
|
||||
{
|
||||
VNavigationMode::showNavigation(this);
|
||||
VNavigationMode::showNavigation(m_tree);
|
||||
}
|
||||
|
||||
bool VOutline::handleKeyNavigation(int p_key, bool &p_succeed)
|
||||
{
|
||||
static bool secondKey = false;
|
||||
return VNavigationMode::handleKeyNavigation(this,
|
||||
return VNavigationMode::handleKeyNavigation(m_tree,
|
||||
secondKey,
|
||||
p_key,
|
||||
p_succeed);
|
||||
@ -248,3 +341,17 @@ const VTableOfContentItem *VOutline::getHeaderFromItem(QTreeWidgetItem *p_item,
|
||||
int index = p_item->data(0, Qt::UserRole).toInt();
|
||||
return p_outline.getItem(index);
|
||||
}
|
||||
|
||||
void VOutline::focusInEvent(QFocusEvent *p_event)
|
||||
{
|
||||
QWidget::focusInEvent(p_event);
|
||||
|
||||
m_tree->setFocus();
|
||||
}
|
||||
|
||||
void VOutline::updateButtonsState()
|
||||
{
|
||||
bool empty = m_outline.isEmpty();
|
||||
m_deLevelBtn->setEnabled(!empty);
|
||||
m_inLevelBtn->setEnabled(!empty);
|
||||
}
|
||||
|
@ -1,19 +1,22 @@
|
||||
#ifndef VOUTLINE_H
|
||||
#define VOUTLINE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVector>
|
||||
#include <QMap>
|
||||
#include <QChar>
|
||||
|
||||
#include "vtreewidget.h"
|
||||
#include "vtableofcontent.h"
|
||||
#include "vnavigationmode.h"
|
||||
|
||||
class QLabel;
|
||||
class VTreeWidget;
|
||||
class QPushButton;
|
||||
class QTimer;
|
||||
|
||||
// Display table of content as a tree and enable user to click an item to
|
||||
// jump to that header.
|
||||
class VOutline : public VTreeWidget, public VNavigationMode
|
||||
class VOutline : public QWidget, public VNavigationMode
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -52,12 +55,22 @@ public slots:
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
// Handle current item change even of the tree.
|
||||
// Do not response if m_muted is true.
|
||||
void handleCurrentItemChanged(QTreeWidgetItem *p_curItem, QTreeWidgetItem *p_preItem);
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
|
||||
void expandTree(int p_expandedLevel = 6);
|
||||
|
||||
void expandTreeOne(QTreeWidgetItem *p_item, int p_levelToBeExpanded);
|
||||
|
||||
void updateButtonsState();
|
||||
|
||||
// @index: the index in @headers.
|
||||
static void updateTreeByLevel(QTreeWidget *p_treeWidget,
|
||||
const QVector<VTableOfContentItem> &p_headers,
|
||||
@ -69,8 +82,6 @@ private:
|
||||
// Fill the info of @p_item.
|
||||
static void fillItem(QTreeWidgetItem *p_item, const VTableOfContentItem &p_header);
|
||||
|
||||
void expandTree();
|
||||
|
||||
static bool selectHeaderOne(QTreeWidget *p_treeWidget,
|
||||
QTreeWidgetItem *p_item,
|
||||
const VTableOfContent &p_outline,
|
||||
@ -82,6 +93,12 @@ private:
|
||||
|
||||
// When true, won't emit outlineItemActivated().
|
||||
bool m_muted;
|
||||
|
||||
QTimer *m_expandTimer;
|
||||
|
||||
QPushButton *m_deLevelBtn;
|
||||
QPushButton *m_inLevelBtn;
|
||||
VTreeWidget *m_tree;
|
||||
};
|
||||
|
||||
#endif // VOUTLINE_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user