NotebookExplorer: support separated node explorer

This commit is contained in:
Le Tan 2022-01-14 20:33:17 +08:00
parent a4a5dea3d7
commit 2630999acf
18 changed files with 1058 additions and 385 deletions

View File

@ -25,7 +25,7 @@
using namespace vnotex;
#ifndef QT_NO_DEBUG
#define VX_DEBUG_WEB
// #define VX_DEBUG_WEB
#endif
const QString ConfigMgr::c_orgName = "VNote";

View File

@ -119,5 +119,7 @@ QString MainConfig::getVersion(const QJsonObject &p_jobj)
void MainConfig::doVersionSpecificOverride()
{
// In a new version, we may want to change one value by force.
// For 3.12.0.
m_editorConfig->getTextEditorConfig().m_highlightWhitespace = false;
m_editorConfig->getMarkdownEditorConfig().m_imageAlignCenterEnabled = false;
}

View File

@ -211,7 +211,7 @@ namespace vnotex
// Whether enable image width constraint.
bool m_constrainImageWidthEnabled = true;
bool m_imageAlignCenterEnabled = true;
bool m_imageAlignCenterEnabled = false;
// Whether enable in-place preview width constraint.
bool m_constrainInplacePreviewWidthEnabled = false;

View File

@ -222,6 +222,7 @@ QJsonObject SessionConfig::saveStateAndGeometry() const
writeByteArray(obj, QStringLiteral("main_window_geometry"), m_mainWindowStateGeometry.m_mainGeometry);
writeStringList(obj, QStringLiteral("visible_docks_before_expand"), m_mainWindowStateGeometry.m_visibleDocksBeforeExpand);
writeByteArray(obj, QStringLiteral("tag_explorer_state"), m_mainWindowStateGeometry.m_tagExplorerState);
writeByteArray(obj, QStringLiteral("notebook_explorer_state"), m_mainWindowStateGeometry.m_notebookExplorerState);
return obj;
}
@ -353,6 +354,7 @@ void SessionConfig::loadStateAndGeometry(const QJsonObject &p_session)
m_mainWindowStateGeometry.m_mainGeometry = readByteArray(obj, QStringLiteral("main_window_geometry"));
m_mainWindowStateGeometry.m_visibleDocksBeforeExpand = readStringList(obj, QStringLiteral("visible_docks_before_expand"));
m_mainWindowStateGeometry.m_tagExplorerState = readByteArray(obj, QStringLiteral("tag_explorer_state"));
m_mainWindowStateGeometry.m_notebookExplorerState = readByteArray(obj, QStringLiteral("notebook_explorer_state"));
}
QByteArray SessionConfig::getViewAreaSessionAndClear()

View File

@ -37,7 +37,8 @@ namespace vnotex
return m_mainState == p_other.m_mainState
&& m_mainGeometry == p_other.m_mainGeometry
&& m_visibleDocksBeforeExpand == p_other.m_visibleDocksBeforeExpand
&& m_tagExplorerState == p_other.m_tagExplorerState;
&& m_tagExplorerState == p_other.m_tagExplorerState
&& m_notebookExplorerState == p_other.m_notebookExplorerState;
}
QByteArray m_mainState;
@ -47,6 +48,8 @@ namespace vnotex
QStringList m_visibleDocksBeforeExpand;
QByteArray m_tagExplorerState;
QByteArray m_notebookExplorerState;
};
enum OpenGL

View File

@ -31,6 +31,7 @@ void WidgetConfig::init(const QJsonObject &p_app,
{
m_nodeExplorerViewOrder = READINT(QStringLiteral("node_explorer_view_order"));
m_nodeExplorerExploreMode = READINT(QStringLiteral("node_explorer_explore_mode"));
m_nodeExplorerExternalFilesVisible = READBOOL(QStringLiteral("node_explorer_external_files_visible"));
m_nodeExplorerAutoImportExternalFilesEnabled = READBOOL(QStringLiteral("node_explorer_auto_import_external_files_enabled"));
m_nodeExplorerCloseBeforeOpenWithEnabled = READBOOL(QStringLiteral("node_explorer_close_before_open_with_enabled"));
@ -54,6 +55,7 @@ QJsonObject WidgetConfig::toJson() const
obj[QStringLiteral("find_and_replace_options")] = static_cast<int>(m_findAndReplaceOptions);
obj[QStringLiteral("node_explorer_view_order")] = m_nodeExplorerViewOrder;
obj[QStringLiteral("node_explorer_explore_mode")] = m_nodeExplorerExploreMode;
obj[QStringLiteral("node_explorer_external_files_visible")] = m_nodeExplorerExternalFilesVisible;
obj[QStringLiteral("node_explorer_auto_import_external_files_enabled")] = m_nodeExplorerAutoImportExternalFilesEnabled;
obj[QStringLiteral("node_explorer_close_before_open_with_enabled")] = m_nodeExplorerCloseBeforeOpenWithEnabled;
@ -106,6 +108,16 @@ void WidgetConfig::setNodeExplorerViewOrder(int p_viewOrder)
updateConfig(m_nodeExplorerViewOrder, p_viewOrder, this);
}
int WidgetConfig::getNodeExplorerExploreMode() const
{
return m_nodeExplorerExploreMode;
}
void WidgetConfig::setNodeExplorerExploreMode(int p_mode)
{
updateConfig(m_nodeExplorerExploreMode, p_mode, this);
}
bool WidgetConfig::isNodeExplorerExternalFilesVisible() const
{
return m_nodeExplorerExternalFilesVisible;

View File

@ -30,6 +30,9 @@ namespace vnotex
int getNodeExplorerViewOrder() const;
void setNodeExplorerViewOrder(int p_viewOrder);
int getNodeExplorerExploreMode() const;
void setNodeExplorerExploreMode(int p_mode);
bool isNodeExplorerExternalFilesVisible() const;
void setNodeExplorerExternalFilesVisible(bool p_visible);
@ -60,6 +63,8 @@ namespace vnotex
int m_nodeExplorerViewOrder = 0;
int m_nodeExplorerExploreMode = 1;
bool m_nodeExplorerExternalFilesVisible = true;
bool m_nodeExplorerAutoImportExternalFilesEnabled = true;

View File

@ -335,7 +335,7 @@
"section_number_style" : "digdotdigdot",
"//comment" : "Whether enable image width constraint",
"constrain_image_width" : true,
"image_align_center" : true,
"image_align_center" : false,
"//comment" : "Whether enable in-place preview width constraint",
"constrain_inplace_preview_width" : false,
"//comment" : "Zoom factor in read mode",
@ -383,12 +383,14 @@
"outline_section_number_enabled" : false,
"//comment" : "Default find options in FindAndReplace",
"find_and_replace_options" : 16,
"//comment" : "View order of the node explorer",
"//comment" : "View order of the node explorer (NotebookNodeExplorer::ViewOrder)",
"node_explorer_view_order" : 0,
"node_explorer_external_files_visible" : true,
"node_explorer_auto_import_external_files_enabled" : true,
"//comment" : "Whether close the file before opening it with external program",
"node_explorer_close_before_open_with_enabled" : true,
"//comment" : "0 - combined/1 - separate_single/2 - separate_double",
"node_explorer_explore_mode" : 1,
"search_panel_advanced_settings_visible" : true,
"//comment" : "Docks to ignore when expanding content area of main window",
"main_window_keep_docks_expanding_content_area": ["OutlineDock.vnotex"],

View File

@ -30,7 +30,7 @@
},
"IndicatorsBorder" : {
"text-color" : "#8a93a6",
"background-color" : "#2d323b"
"background-color" : "#3c414d"
},
"CurrentLineNumber" : {
"text-color" : "#ccd1d8"

View File

@ -42,6 +42,44 @@ bool ExportHtmlOption::operator==(const ExportHtmlOption &p_other) const
&& m_scrollable == p_other.m_scrollable;
}
static QJsonObject pageLayoutToJsonObject(const QPageLayout &p_layout)
{
QJsonObject obj;
obj["page_size"] = static_cast<int>(p_layout.pageSize().id());
obj["orientation"] = static_cast<int>(p_layout.orientation());
obj["units"] = static_cast<int>(p_layout.units());
{
QStringList marginsStr;
const auto margins = p_layout.margins();
marginsStr << QString::number(margins.left());
marginsStr << QString::number(margins.top());
marginsStr << QString::number(margins.right());
marginsStr << QString::number(margins.bottom());
obj["margins"] = marginsStr.join(QLatin1Char(','));
}
return obj;
}
static void jsonObjectToPageLayout(const QJsonObject &p_obj, QPageLayout &p_layout)
{
const int pageSize = p_obj["page_size"].toInt(static_cast<int>(QPageSize::A4));
p_layout.setPageSize(QPageSize(static_cast<QPageSize::PageSizeId>(pageSize)));
const int orientation = p_obj["orientation"].toInt(static_cast<int>(QPageLayout::Portrait));
p_layout.setOrientation(static_cast<QPageLayout::Orientation>(orientation));
const int units = p_obj["units"].toInt(static_cast<int>(QPageLayout::Millimeter));
p_layout.setUnits(static_cast<QPageLayout::Unit>(units));
auto marginsStr = p_obj["margins"].toString().split(QLatin1Char(','));
if (marginsStr.size() == 4) {
p_layout.setMargins(QMarginsF(marginsStr[0].toDouble(),
marginsStr[1].toDouble(),
marginsStr[2].toDouble(),
marginsStr[3].toDouble()));
}
}
ExportPdfOption::ExportPdfOption()
: m_layout(new QPageLayout(QPageSize(QPageSize::A4),
QPageLayout::Portrait,
@ -58,6 +96,7 @@ QJsonObject ExportPdfOption::toJson() const
obj["all_in_one"] = m_allInOne;
obj["wkhtmltopdf_exe_path"] = m_wkhtmltopdfExePath;
obj["wkhtmltopdf_args"] = m_wkhtmltopdfArgs;
obj["layout"] = pageLayoutToJsonObject(*m_layout);
return obj;
}
@ -72,6 +111,7 @@ void ExportPdfOption::fromJson(const QJsonObject &p_obj)
m_allInOne = p_obj["all_in_one"].toBool();
m_wkhtmltopdfExePath = p_obj["wkhtmltopdf_exe_path"].toString();
m_wkhtmltopdfArgs = p_obj["wkhtmltopdf_args"].toString();
jsonObjectToPageLayout(p_obj["layout"].toObject(), *m_layout);
}
bool ExportPdfOption::operator==(const ExportPdfOption &p_other) const

View File

@ -10,6 +10,7 @@ QAccessibleInterface *FakeAccessible::accessibleFactory(const QString &p_classNa
// Try to fix non-responsible issue caused by Youdao Dict.
if (p_className.startsWith(QStringLiteral("vnotex::"))
|| p_className.startsWith(QStringLiteral("vte::"))) {
// Qt's docs: All interfaces are managed by an internal cache and should not be deleted.
return new FakeAccessibleInterface(p_obj);
}

View File

@ -427,6 +427,7 @@ void MainWindow::saveStateAndGeometry()
sg.m_mainGeometry = saveGeometry();
sg.m_visibleDocksBeforeExpand = m_visibleDocksBeforeExpand;
sg.m_tagExplorerState = m_tagExplorer->saveState();
sg.m_notebookExplorerState = m_notebookExplorer->saveState();
auto& sessionConfig = ConfigMgr::getInst().getSessionConfig();
sessionConfig.setMainWindowStateGeometry(sg);
@ -457,6 +458,10 @@ void MainWindow::loadStateAndGeometry(bool p_stateOnly)
if (!sg.m_tagExplorerState.isEmpty()) {
m_tagExplorer->restoreState(sg.m_tagExplorerState);
}
if (!sg.m_notebookExplorerState.isEmpty()) {
m_notebookExplorer->restoreState(sg.m_notebookExplorerState);
}
}
void MainWindow::resetStateAndGeometry()

View File

@ -82,6 +82,7 @@ void NotebookExplorer::setupUI()
const auto &widgetConfig = ConfigMgr::getInst().getWidgetConfig();
m_nodeExplorer = new NotebookNodeExplorer(this);
m_nodeExplorer->setViewOrder(widgetConfig.getNodeExplorerViewOrder());
m_nodeExplorer->setExploreMode(widgetConfig.getNodeExplorerExploreMode());
m_nodeExplorer->setExternalFilesVisible(widgetConfig.isNodeExplorerExternalFilesVisible());
connect(m_nodeExplorer, &NotebookNodeExplorer::nodeActivated,
&VNoteX::getInst(), &VNoteX::openNodeRequested);
@ -113,11 +114,8 @@ TitleBar *NotebookExplorer::setupTitleBar(QWidget *p_parent)
{
auto viewMenu = WidgetsFactory::createMenu(titleBar);
setupViewMenu(viewMenu);
titleBar->addActionButton(QStringLiteral("view.svg"), tr("View"), viewMenu);
connect(viewMenu, &QMenu::aboutToShow,
this, [this, viewMenu]() {
setupViewMenu(viewMenu);
});
}
{
@ -205,6 +203,8 @@ TitleBar *NotebookExplorer::setupTitleBar(QWidget *p_parent)
act->setChecked(widgetConfig.getNodeExplorerCloseBeforeOpenWithEnabled());
}
setupExploreModeMenu(titleBar);
return titleBar;
}
@ -383,10 +383,6 @@ const QSharedPointer<Notebook> &NotebookExplorer::currentNotebook() const
void NotebookExplorer::setupViewMenu(QMenu *p_menu)
{
if (!p_menu->isEmpty()) {
return;
}
auto ag = new QActionGroup(p_menu);
auto act = ag->addAction(tr("View By Configuration"));
@ -467,6 +463,45 @@ void NotebookExplorer::setupRecycleBinMenu(QMenu *p_menu)
});
}
void NotebookExplorer::setupExploreModeMenu(TitleBar *p_titleBar)
{
auto menu = p_titleBar->addMenuSubMenu(tr("Explore Mode"));
auto ag = new QActionGroup(menu);
auto act = ag->addAction(tr("Combined"));
act->setCheckable(true);
act->setChecked(true);
act->setData(NotebookNodeExplorer::ExploreMode::Combined);
menu->addAction(act);
act = ag->addAction(tr("Separate, Single Column"));
act->setCheckable(true);
act->setChecked(true);
act->setData(NotebookNodeExplorer::ExploreMode::SeparateSingle);
menu->addAction(act);
act = ag->addAction(tr("Separate, Double Columns"));
act->setCheckable(true);
act->setChecked(true);
act->setData(NotebookNodeExplorer::ExploreMode::SeparateDouble);
menu->addAction(act);
int mode = ConfigMgr::getInst().getWidgetConfig().getNodeExplorerExploreMode();
for (const auto &act : ag->actions()) {
if (act->data().toInt() == mode) {
act->setChecked(true);
}
}
connect(ag, &QActionGroup::triggered,
this, [this](QAction *action) {
int mode = action->data().toInt();
ConfigMgr::getInst().getWidgetConfig().setNodeExplorerExploreMode(mode);
m_nodeExplorer->setExploreMode(mode);
});
}
void NotebookExplorer::saveSession()
{
updateSession();
@ -560,3 +595,13 @@ void NotebookExplorer::rebuildDatabase()
}
}
}
QByteArray NotebookExplorer::saveState() const
{
return m_nodeExplorer->saveState();
}
void NotebookExplorer::restoreState(const QByteArray &p_data)
{
m_nodeExplorer->restoreState(p_data);
}

View File

@ -30,6 +30,10 @@ namespace vnotex
Node *currentExploredNode() const;
QByteArray saveState() const;
void restoreState(const QByteArray &p_data);
public slots:
void newNotebook();
@ -71,6 +75,8 @@ namespace vnotex
void setupRecycleBinMenu(QMenu *p_menu);
void setupExploreModeMenu(TitleBar *p_titleBar);
void saveSession();
void loadSession();

File diff suppressed because it is too large Load Diff

View File

@ -12,8 +12,6 @@
#include "navigationmodewrapper.h"
class QSplitter;
class QTreeWidget;
class QTreeWidgetItem;
class QMenu;
namespace vnotex
@ -21,6 +19,7 @@ namespace vnotex
class Notebook;
class Node;
class TreeWidget;
class ListWidget;
struct FileOpenParameters;
class Event;
class ExternalNode;
@ -65,6 +64,8 @@ namespace vnotex
bool matched(const Node *p_node) const;
bool matched(const QString &p_name) const;
bool isLoaded() const;
private:
@ -89,22 +90,26 @@ namespace vnotex
ViewOrderMax
};
enum ExploreMode
{
Combined = 0,
SeparateSingle,
SeparateDouble,
ExploreModeMax
};
explicit NotebookNodeExplorer(QWidget *p_parent = nullptr);
void setNotebook(const QSharedPointer<Notebook> &p_notebook);
Node *getCurrentNode() const;
// Update the tree of @p_node.
// If @p_node is null, update the whole tree.
void updateNode(Node *p_node);
void setCurrentNode(Node *p_node);
void reload();
void setViewOrder(int p_order);
void setExploreMode(int p_mode);
void setExternalFilesVisible(bool p_visible);
void setAutoImportExternalFiles(bool p_enabled);
@ -113,6 +118,10 @@ namespace vnotex
Node *currentExploredNode() const;
QByteArray saveState() const;
void restoreState(const QByteArray &p_data);
static QString generateToolTip(const Node *p_node);
signals:
@ -156,81 +165,103 @@ namespace vnotex
Tag
};
struct CacheData
{
void clear();
QSharedPointer<QTreeWidgetStateCache<Node *>> m_masterStateCache;
QString m_currentSlaveName;
};
void setupUI();
void setupShortcuts();
void setupMasterExplorer(QWidget *p_parent = nullptr);
void clearExplorer();
void setupSlaveExplorer();
void generateNodeTree();
void generateMasterNodeTree();
void loadRootNode(const Node *p_node) const;
void loadNode(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
void loadMasterNode(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
void loadChildren(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
void loadMasterNodeChildren(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
void loadItemChildren(QTreeWidgetItem *p_item) const;
void loadMasterItemChildren(QTreeWidgetItem *p_item) const;
void loadNode(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
void loadMasterExternalNode(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
void fillTreeItem(QTreeWidgetItem *p_item, Node *p_node, bool p_loaded) const;
void fillMasterItem(QTreeWidgetItem *p_item, Node *p_node, bool p_loaded) const;
void fillTreeItem(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
void fillMasterItem(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
const QIcon &getNodeItemIcon(const Node *p_node) const;
void fillSlaveItem(QListWidgetItem *p_item, Node *p_node) const;
const QIcon &getNodeItemIcon(const ExternalNode *p_node) const;
void fillSlaveItem(QListWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
const QIcon &getIcon(const Node *p_node) const;
const QIcon &getIcon(const ExternalNode *p_node) const;
void initNodeIcons() const;
QTreeWidgetItem *findNode(const Node *p_node) const;
QTreeWidgetItem *findMasterNode(const Node *p_node) const;
QTreeWidgetItem *findNode(QTreeWidgetItem *p_item, const Node *p_node) const;
QTreeWidgetItem *findMasterNode(QTreeWidgetItem *p_item, const Node *p_node) const;
QTreeWidgetItem *findNodeChild(QTreeWidgetItem *p_item, const Node *p_node) const;
QTreeWidgetItem *findMasterNodeInDirectChildren(QTreeWidgetItem *p_item, const Node *p_node) const;
QTreeWidgetItem *findNodeTopLevelItem(QTreeWidget *p_tree, const Node *p_node) const;
QTreeWidgetItem *findMasterNodeInTopLevelItems(QTreeWidget *p_tree, const Node *p_node) const;
void saveNotebookTreeState(bool p_saveCurrentItem = true);
QListWidgetItem *findSlaveNode(const Node *p_node) const;
QSharedPointer<QTreeWidgetStateCache<Node *>> stateCache() const;
void cacheState(bool p_saveCurrent);
void clearStateCache(const Notebook *p_notebook);
// Get cache data of current notebook.
CacheData &getCache() const;
void createContextMenuOnRoot(QMenu *p_menu);
void clearCache(const Notebook *p_notebook);
void createContextMenuOnNode(QMenu *p_menu, const Node *p_node);
void createMasterContextMenuOnRoot(QMenu *p_menu);
void createContextMenuOnExternalNode(QMenu *p_menu, const ExternalNode *p_node);
void createContextMenuOnNode(QMenu *p_menu, const Node *p_node, bool p_master);
void createContextMenuOnExternalNode(QMenu *p_menu, const ExternalNode *p_node, bool p_master);
void createSlaveContextMenuOnMasterNode(QMenu *p_menu);
// Factory function to create action.
QAction *createAction(Action p_act, QObject *p_parent);
QAction *createAction(Action p_act, QObject *p_parent, bool p_master);
QAction *createAndAddAction(Action p_act, QMenu *p_menu);
QAction *createAndAddAction(Action p_act, QMenu *p_menu, bool p_master = true);
void copySelectedNodes(bool p_move);
void copySelectedNodes(bool p_move, bool p_master);
void pasteNodesFromClipboard();
QPair<QVector<Node *>, QVector<QSharedPointer<ExternalNode>>> getSelectedNodes() const;
QPair<QVector<Node *>, QVector<QSharedPointer<ExternalNode>>> getMasterSelectedNodesAndExternalNodes() const;
void removeSelectedNodes();
QPair<QVector<Node *>, QVector<QSharedPointer<ExternalNode>>> getSlaveSelectedNodesAndExternalNodes() const;
void removeSelectedNodesFromConfig();
void removeSelectedNodes(bool p_master);
void removeSelectedNodesFromConfig(bool p_master);
QVector<Node *> confirmSelectedNodes(const QString &p_title,
const QString &p_text,
const QString &p_info) const;
const QString &p_info,
bool p_master) const;
static QSharedPointer<ClipboardData> tryFetchClipboardData();
bool isPasteOnNodeAvailable(const Node *p_node) const;
void setNodeExpanded(const Node *p_node, bool p_expanded);
void setMasterNodeExpanded(const Node *p_node, bool p_expanded);
// Select both master and slave nodes.
void selectNodes(const QVector<const Node *> &p_nodes);
void removeNodes(QVector<Node *> p_nodes, bool p_configOnly);
@ -240,19 +271,19 @@ namespace vnotex
void updateAndExpandNode(Node *p_node);
// Check if all selected items are the same type for operations.
bool allSelectedItemsSameType() const;
bool isMasterAllSelectedItemsSameType() const;
bool isSlaveAllSelectedItemsSameType() const;
void focusNormalNode();
void sortNodes(QVector<QSharedPointer<Node>> &p_nodes) const;
// [p_start, p_end).
void sortNodes(QVector<QSharedPointer<Node>> &p_nodes, int p_start, int p_end, int p_viewOrder) const;
void sortNodes(QVector<QSharedPointer<Node>> &p_nodes, int p_start, int p_end, ViewOrder p_viewOrder) const;
// Sort nodes in config file.
void manualSort();
void openSelectedNodes();
void manualSort(bool p_master);
QSharedPointer<Node> importToIndex(QSharedPointer<ExternalNode> p_node);
@ -262,33 +293,67 @@ namespace vnotex
// Return true if it is invalid.
bool checkInvalidNode(Node *p_node) const;
void expandCurrentNodeAll();
void addOpenWithMenu(QMenu *p_menu, bool p_master);
void expandItemRecursively(QTreeWidgetItem *p_item);
QStringList getSelectedNodesPath(bool p_master) const;
void addOpenWithMenu(QMenu *p_menu);
void openSelectedNodesWithCommand(const QString &p_command, bool p_master);
QStringList getSelectedNodesPath() const;
bool belongsToMasterExplorer(const Node *p_node) const;
void openSelectedNodesWithDefaultProgram();
bool belongsToMasterExplorer(const ExternalNode *p_node) const;
void openSelectedNodesWithExternalProgram(const QString &p_command);
void updateSlaveExplorer();
Node *getCurrentMasterNode() const;
Node *getCurrentSlaveNode() const;
NodeData getCurrentMasterNodeData() const;
NodeData getCurrentSlaveNodeData() const;
Node *getSlaveExplorerMasterNode() const;
bool isCombinedExploreMode() const;
// Update the tree of @p_node if there is any. Or update the node itself if it is in slave explorer.
// If @p_node is null, update the whole tree.
void updateNode(Node *p_node);
void setCurrentMasterNode(Node *p_node);
void setCurrentSlaveNode(const Node *p_node);
void setCurrentSlaveNode(const QString &p_name);
void activateItemNode(const NodeData &p_data);
static NotebookNodeExplorer::NodeData getItemNodeData(const QTreeWidgetItem *p_item);
static NotebookNodeExplorer::NodeData getItemNodeData(const QListWidgetItem *p_item);
static void setItemNodeData(QTreeWidgetItem *p_item, const NodeData &p_data);
static void setItemNodeData(QListWidgetItem *p_item, const NodeData &p_data);
QSplitter *m_splitter = nullptr;
TreeWidget *m_masterExplorer = nullptr;
ListWidget *m_slaveExplorer = nullptr;
QSharedPointer<Notebook> m_notebook;
QHash<const Notebook *, QSharedPointer<QTreeWidgetStateCache<Node *>>> m_stateCache;
QHash<const Notebook *, CacheData> m_cache;
QScopedPointer<NavigationModeWrapper<QTreeWidget, QTreeWidgetItem>> m_navigationWrapper;
QScopedPointer<NavigationModeWrapper<QTreeWidget, QTreeWidgetItem>> m_masterNavigationWrapper;
int m_viewOrder = ViewOrder::OrderedByConfiguration;
QScopedPointer<NavigationModeWrapper<QListWidget, QListWidgetItem>> m_slaveNavigationWrapper;
ViewOrder m_viewOrder = ViewOrder::OrderedByConfiguration;
ExploreMode m_exploreMode = ExploreMode::Combined;
bool m_externalFilesVisible = true;

View File

@ -265,3 +265,20 @@ void TreeWidget::unmark(QTreeWidgetItem *p_item, int p_column)
p_item->setData(p_column, Qt::ForegroundRole, QVariant());
p_item->setData(p_column, Qt::BackgroundRole, QVariant());
}
void TreeWidget::expandRecursively(QTreeWidgetItem *p_item)
{
if (!p_item) {
return;
}
p_item->setExpanded(true);
const int cnt = p_item->childCount();
if (cnt == 0) {
return;
}
for (int i = 0; i < cnt; ++i) {
expandRecursively(p_item->child(i));
}
}

View File

@ -42,6 +42,8 @@ namespace vnotex
// @p_func: return false to abort the iteration.
static void forEachItem(const QTreeWidget *p_widget, const std::function<bool(QTreeWidgetItem *p_item)> &p_func);
static void expandRecursively(QTreeWidgetItem *p_item);
signals:
// Emit when single item is selected and Drag&Drop to move internally.
void itemMoved(QTreeWidgetItem *p_item);