notebooknodeexplorer.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. #ifndef NOTEBOOKNODEEXPLORER_H
  2. #define NOTEBOOKNODEEXPLORER_H
  3. #include <QWidget>
  4. #include <QSharedPointer>
  5. #include <QHash>
  6. #include <QScopedPointer>
  7. #include <QPair>
  8. #include <QStyledItemDelegate>
  9. #include "qtreewidgetstatecache.h"
  10. #include "clipboarddata.h"
  11. #include "navigationmodewrapper.h"
  12. #include "global.h"
  13. #include <notebook/nodevisual.h>
  14. class QSplitter;
  15. class QMenu;
  16. class QPainter;
  17. class QStyleOptionViewItem;
  18. class QModelIndex;
  19. namespace vnotex
  20. {
  21. class Notebook;
  22. class Node;
  23. class TreeWidget;
  24. class ListWidget;
  25. struct FileOpenParameters;
  26. class Event;
  27. class ExternalNode;
  28. /*
  29. * 自定义委托类,用于绘制节点边框
  30. * 支持节点名称,背景颜色,边框颜色,节点名称颜色
  31. * 支持级联修改,包括背景颜色,边框颜色,节点名称颜色
  32. */
  33. class NodeColorDelegate : public QStyledItemDelegate
  34. {
  35. Q_OBJECT
  36. public:
  37. explicit NodeColorDelegate(QObject *parent = nullptr);
  38. protected:
  39. void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
  40. };
  41. class NotebookNodeExplorer : public QWidget
  42. {
  43. Q_OBJECT
  44. public:
  45. // Used for a QTreeWidgetItem to hold the info of a node.
  46. // Make it public since we need to hold it in a QTreeWidgetItem.
  47. class NodeData
  48. {
  49. public:
  50. enum class NodeType { Node, ExternalNode, Invalid };
  51. NodeData();
  52. explicit NodeData(Node *p_node, bool p_loaded);
  53. explicit NodeData(const QSharedPointer<ExternalNode> &p_externalNode);
  54. NodeData(const NodeData &p_other);
  55. ~NodeData();
  56. NodeData &operator=(const NodeData &p_other);
  57. bool isValid() const;
  58. bool isNode() const;
  59. bool isExternalNode() const;
  60. NodeData::NodeType getType() const;
  61. Node *getNode() const;
  62. // Return shared ptr to avoid wild pointer after destruction of item.
  63. const QSharedPointer<ExternalNode> &getExternalNode() const;
  64. void clear();
  65. bool matched(const Node *p_node) const;
  66. bool matched(const QString &p_name) const;
  67. bool isLoaded() const;
  68. private:
  69. NodeType m_type = NodeType::Invalid;
  70. Node *m_node = nullptr;
  71. QSharedPointer<ExternalNode> m_externalNode;
  72. bool m_loaded = false;
  73. };
  74. enum ExploreMode
  75. {
  76. Combined = 0,
  77. SeparateSingle,
  78. SeparateDouble,
  79. ExploreModeMax
  80. };
  81. explicit NotebookNodeExplorer(QWidget *p_parent = nullptr);
  82. void setNotebook(const QSharedPointer<Notebook> &p_notebook);
  83. void setCurrentNode(Node *p_node);
  84. void reload();
  85. void setViewOrder(int p_order);
  86. void setExploreMode(int p_mode);
  87. void setExternalFilesVisible(bool p_visible);
  88. void setAutoImportExternalFiles(bool p_enabled);
  89. Node *currentExploredFolderNode() const;
  90. Node *currentExploredNode() const;
  91. QByteArray saveState() const;
  92. void restoreState(const QByteArray &p_data);
  93. static QString generateToolTip(const Node *p_node);
  94. signals:
  95. void nodeActivated(Node *p_node, const QSharedPointer<FileOpenParameters> &p_paras);
  96. void fileActivated(const QString &p_path, const QSharedPointer<FileOpenParameters> &p_paras);
  97. // @m_response of @p_event: true to continue the move, false to cancel the move.
  98. void nodeAboutToMove(Node *p_node, const QSharedPointer<Event> &p_event);
  99. // @m_response of @p_event: true to continue the removal, false to cancel the removal.
  100. void nodeAboutToRemove(Node *p_node, const QSharedPointer<Event> &p_event);
  101. void nodeAboutToReload(Node *p_node, const QSharedPointer<Event> &p_event);
  102. // @p_filePath is either an external file or a node.
  103. void closeFileRequested(const QString &p_filePath, const QSharedPointer<Event> &p_event);
  104. private:
  105. enum Column { Name = 0 };
  106. enum class Action
  107. {
  108. NewNote,
  109. NewFolder,
  110. Properties,
  111. OpenLocation,
  112. CopyPath,
  113. Copy,
  114. Cut,
  115. Paste,
  116. Delete,
  117. RemoveFromConfig,
  118. Sort,
  119. Reload,
  120. ReloadIndex,
  121. ImportToConfig,
  122. Open,
  123. Edit,
  124. Read,
  125. ExpandAll,
  126. PinToQuickAccess,
  127. Tag,
  128. VisualSettings,
  129. SetBackgroundColor,
  130. SetBorderColor,
  131. SetNameColor,
  132. SetCascadeBackgroundColor,
  133. SetCascadeBorderColor,
  134. ClearCascadeColors,
  135. ClearColors
  136. };
  137. struct CacheData
  138. {
  139. void clear();
  140. QSharedPointer<QTreeWidgetStateCache<Node *>> m_masterStateCache;
  141. QString m_currentSlaveName;
  142. };
  143. void setupUI();
  144. bool isActionFromMaster() const;
  145. void setupShortcuts();
  146. void setupMasterExplorer(QWidget *p_parent = nullptr);
  147. void setupSlaveExplorer();
  148. void generateMasterNodeTree();
  149. void loadRootNode(const Node *p_node) const;
  150. void loadMasterNode(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
  151. void loadMasterNodeChildren(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
  152. void loadMasterItemChildren(QTreeWidgetItem *p_item) const;
  153. void loadMasterExternalNode(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
  154. void fillMasterItem(QTreeWidgetItem *p_item, Node *p_node, bool p_loaded) const;
  155. void fillMasterItem(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
  156. void fillSlaveItem(QListWidgetItem *p_item, Node *p_node) const;
  157. void fillSlaveItem(QListWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
  158. void applyNodeColors(QTreeWidgetItem *p_item, Node *p_node) const;
  159. void applyNodeColors(QListWidgetItem *p_item, Node *p_node) const;
  160. void updateCurrentNodeVisualDirectly(Node *p_node, const NodeVisual &p_visual);
  161. void setCascadeColorRecursively(Node *p_node, const QString &p_backgroundColor, const QString &p_borderColor, const QString &p_nameColor);
  162. QTreeWidgetItem *findCurrentTreeWidgetItem(Node *p_node) const;
  163. QListWidgetItem *findCurrentListWidgetItem(Node *p_node) const;
  164. const QIcon &getIcon(const Node *p_node) const;
  165. const QIcon &getIcon(const ExternalNode *p_node) const;
  166. void initNodeIcons() const;
  167. QTreeWidgetItem *findMasterNode(const Node *p_node) const;
  168. QTreeWidgetItem *findMasterNode(QTreeWidgetItem *p_item, const Node *p_node) const;
  169. QTreeWidgetItem *findMasterNodeInDirectChildren(QTreeWidgetItem *p_item, const Node *p_node) const;
  170. QTreeWidgetItem *findMasterNodeInTopLevelItems(QTreeWidget *p_tree, const Node *p_node) const;
  171. QListWidgetItem *findSlaveNode(const Node *p_node) const;
  172. void cacheState(bool p_saveCurrent);
  173. // Get cache data of current notebook.
  174. CacheData &getCache() const;
  175. void clearCache(const Notebook *p_notebook);
  176. void createMasterContextMenuOnRoot(QMenu *p_menu);
  177. void createContextMenuOnNode(QMenu *p_menu, const Node *p_node, bool p_master);
  178. void createContextMenuOnExternalNode(QMenu *p_menu, const ExternalNode *p_node, bool p_master);
  179. void createSlaveContextMenuOnMasterNode(QMenu *p_menu);
  180. // Factory function to create action.
  181. QAction *createAction(Action p_act, QObject *p_parent, bool p_master);
  182. QAction *createAndAddAction(Action p_act, QMenu *p_menu, bool p_master = true);
  183. void copySelectedNodes(bool p_move, bool p_master);
  184. void pasteNodesFromClipboard();
  185. QPair<QVector<Node *>, QVector<QSharedPointer<ExternalNode>>> getMasterSelectedNodesAndExternalNodes() const;
  186. QPair<QVector<Node *>, QVector<QSharedPointer<ExternalNode>>> getSlaveSelectedNodesAndExternalNodes() const;
  187. void removeSelectedNodes(bool p_master);
  188. void removeSelectedNodesFromConfig(bool p_master);
  189. QVector<Node *> confirmSelectedNodes(const QString &p_title,
  190. const QString &p_text,
  191. const QString &p_info,
  192. bool p_master) const;
  193. static QSharedPointer<ClipboardData> tryFetchClipboardData();
  194. bool isPasteOnNodeAvailable(const Node *p_node) const;
  195. void setMasterNodeExpanded(const Node *p_node, bool p_expanded);
  196. // Select both master and slave nodes.
  197. void selectNodes(const QVector<const Node *> &p_nodes);
  198. void removeNodes(QVector<Node *> p_nodes, bool p_configOnly);
  199. void filterAwayChildrenNodes(QVector<Node *> &p_nodes);
  200. void updateAndExpandNode(Node *p_node);
  201. // Check if all selected items are the same type for operations.
  202. bool isMasterAllSelectedItemsSameType() const;
  203. bool isSlaveAllSelectedItemsSameType() const;
  204. void focusNormalNode();
  205. void sortNodes(QVector<QSharedPointer<Node>> &p_nodes) const;
  206. // [p_start, p_end).
  207. void sortNodes(QVector<QSharedPointer<Node>> &p_nodes, int p_start, int p_end, ViewOrder p_viewOrder) const;
  208. // Sort nodes in config file.
  209. void manualSort(bool p_master);
  210. QSharedPointer<Node> importToIndex(QSharedPointer<ExternalNode> p_node);
  211. void importToIndex(const QVector<QSharedPointer<ExternalNode>> &p_nodes);
  212. // Check whether @p_node is a valid node. Will notify user.
  213. // Return true if it is invalid.
  214. bool checkInvalidNode(Node *p_node) const;
  215. void addOpenWithMenu(QMenu *p_menu, bool p_master);
  216. QStringList getSelectedNodesPath(bool p_master) const;
  217. void openSelectedNodesWithProgram(const QString &p_name, bool p_master);
  218. void openCurrentNodeProperties(bool p_master);
  219. bool belongsToMasterExplorer(const Node *p_node) const;
  220. bool belongsToMasterExplorer(const ExternalNode *p_node) const;
  221. void updateSlaveExplorer();
  222. Node *getCurrentMasterNode() const;
  223. Node *getCurrentSlaveNode() const;
  224. NodeData getCurrentMasterNodeData() const;
  225. NodeData getCurrentSlaveNodeData() const;
  226. Node *getSlaveExplorerMasterNode() const;
  227. bool isCombinedExploreMode() const;
  228. // Update the tree of @p_node if there is any. Or update the node itself if it is in slave explorer.
  229. // If @p_node is null, update the whole tree.
  230. void updateNode(Node *p_node);
  231. void setCurrentMasterNode(Node *p_node);
  232. void setCurrentSlaveNode(const Node *p_node);
  233. void setCurrentSlaveNode(const QString &p_name);
  234. void activateItemNode(const NodeData &p_data);
  235. static NotebookNodeExplorer::NodeData getItemNodeData(const QTreeWidgetItem *p_item);
  236. static NotebookNodeExplorer::NodeData getItemNodeData(const QListWidgetItem *p_item);
  237. static void setItemNodeData(QTreeWidgetItem *p_item, const NodeData &p_data);
  238. static void setItemNodeData(QListWidgetItem *p_item, const NodeData &p_data);
  239. QSplitter *m_splitter = nullptr;
  240. TreeWidget *m_masterExplorer = nullptr;
  241. ListWidget *m_slaveExplorer = nullptr;
  242. QSharedPointer<Notebook> m_notebook;
  243. QHash<const Notebook *, CacheData> m_cache;
  244. QScopedPointer<NavigationModeWrapper<QTreeWidget, QTreeWidgetItem>> m_masterNavigationWrapper;
  245. QScopedPointer<NavigationModeWrapper<QListWidget, QListWidgetItem>> m_slaveNavigationWrapper;
  246. ViewOrder m_viewOrder = ViewOrder::OrderedByConfiguration;
  247. ExploreMode m_exploreMode = ExploreMode::Combined;
  248. bool m_externalFilesVisible = true;
  249. bool m_autoImportExternalFiles = true;
  250. enum NodeIcon
  251. {
  252. FolderNode = 0,
  253. FileNode,
  254. InvalidFolderNode,
  255. InvalidFileNode,
  256. ExternalFolderNode,
  257. ExternalFileNode,
  258. MaxIcons
  259. };
  260. static QIcon s_nodeIcons[NodeIcon::MaxIcons];
  261. };
  262. }
  263. Q_DECLARE_METATYPE(vnotex::NotebookNodeExplorer::NodeData);
  264. #endif // NOTEBOOKNODEEXPLORER_H