notebooknodeexplorer.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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 "qtreewidgetstatecache.h"
  9. #include "clipboarddata.h"
  10. #include "navigationmodewrapper.h"
  11. class QSplitter;
  12. class QTreeWidget;
  13. class QTreeWidgetItem;
  14. class QMenu;
  15. namespace vnotex
  16. {
  17. class Notebook;
  18. class Node;
  19. class TreeWidget;
  20. struct FileOpenParameters;
  21. class Event;
  22. class ExternalNode;
  23. class NotebookNodeExplorer : public QWidget
  24. {
  25. Q_OBJECT
  26. public:
  27. // Used for a QTreeWidgetItem to hold the info of a node.
  28. // Make it public since we need to hold it in a QTreeWidgetItem.
  29. class NodeData
  30. {
  31. public:
  32. enum class NodeType { Node, ExternalNode, Invalid };
  33. NodeData();
  34. explicit NodeData(Node *p_node, bool p_loaded);
  35. explicit NodeData(const QSharedPointer<ExternalNode> &p_externalNode);
  36. NodeData(const NodeData &p_other);
  37. ~NodeData();
  38. NodeData &operator=(const NodeData &p_other);
  39. bool isValid() const;
  40. bool isNode() const;
  41. bool isExternalNode() const;
  42. NodeData::NodeType getType() const;
  43. Node *getNode() const;
  44. // Return shared ptr to avoid wild pointer after destruction of item.
  45. const QSharedPointer<ExternalNode> &getExternalNode() const;
  46. void clear();
  47. bool matched(const Node *p_node) const;
  48. bool isLoaded() const;
  49. private:
  50. NodeType m_type = NodeType::Invalid;
  51. Node *m_node = nullptr;
  52. QSharedPointer<ExternalNode> m_externalNode;
  53. bool m_loaded = false;
  54. };
  55. enum ViewOrder
  56. {
  57. OrderedByConfiguration = 0,
  58. OrderedByName,
  59. OrderedByNameReversed,
  60. OrderedByCreatedTime,
  61. OrderedByCreatedTimeReversed,
  62. OrderedByModifiedTime,
  63. OrderedByModifiedTimeReversed,
  64. ViewOrderMax
  65. };
  66. explicit NotebookNodeExplorer(QWidget *p_parent = nullptr);
  67. void setNotebook(const QSharedPointer<Notebook> &p_notebook);
  68. Node *getCurrentNode() const;
  69. // Update the tree of @p_node.
  70. // If @p_node is null, update the whole tree.
  71. void updateNode(Node *p_node);
  72. void setCurrentNode(Node *p_node);
  73. void reload();
  74. void setRecycleBinNodeVisible(bool p_visible);
  75. void setViewOrder(int p_order);
  76. void setExternalFilesVisible(bool p_visible);
  77. void setAutoImportExternalFiles(bool p_enabled);
  78. Node *currentExploredFolderNode() const;
  79. Node *currentExploredNode() const;
  80. static QString generateToolTip(const Node *p_node);
  81. signals:
  82. void nodeActivated(Node *p_node, const QSharedPointer<FileOpenParameters> &p_paras);
  83. void fileActivated(const QString &p_path, const QSharedPointer<FileOpenParameters> &p_paras);
  84. // @m_response of @p_event: true to continue the move, false to cancel the move.
  85. void nodeAboutToMove(Node *p_node, const QSharedPointer<Event> &p_event);
  86. // @m_response of @p_event: true to continue the removal, false to cancel the removal.
  87. void nodeAboutToRemove(Node *p_node, const QSharedPointer<Event> &p_event);
  88. void nodeAboutToReload(Node *p_node, const QSharedPointer<Event> &p_event);
  89. // @p_filePath is either an external file or a node.
  90. void closeFileRequested(const QString &p_filePath, const QSharedPointer<Event> &p_event);
  91. private:
  92. enum Column { Name = 0 };
  93. enum class Action
  94. {
  95. NewNote,
  96. NewFolder,
  97. Properties,
  98. OpenLocation,
  99. CopyPath,
  100. Copy,
  101. Cut,
  102. Paste,
  103. EmptyRecycleBin,
  104. Delete,
  105. DeleteFromRecycleBin,
  106. RemoveFromConfig,
  107. Sort,
  108. Reload,
  109. ReloadIndex,
  110. ImportToConfig,
  111. Open,
  112. ExpandAll,
  113. PinToQuickAccess,
  114. Tag
  115. };
  116. void setupUI();
  117. void setupShortcuts();
  118. void setupMasterExplorer(QWidget *p_parent = nullptr);
  119. void clearExplorer();
  120. void generateNodeTree();
  121. void loadRootNode(const Node *p_node) const;
  122. void loadNode(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
  123. void loadChildren(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
  124. void loadItemChildren(QTreeWidgetItem *p_item) const;
  125. void loadNode(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
  126. void loadRecycleBinNode(Node *p_node) const;
  127. void loadRecycleBinNode(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
  128. void fillTreeItem(QTreeWidgetItem *p_item, Node *p_node, bool p_loaded) const;
  129. void fillTreeItem(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
  130. const QIcon &getNodeItemIcon(const Node *p_node) const;
  131. const QIcon &getNodeItemIcon(const ExternalNode *p_node) const;
  132. void initNodeIcons() const;
  133. QTreeWidgetItem *findNode(const Node *p_node) const;
  134. QTreeWidgetItem *findNode(QTreeWidgetItem *p_item, const Node *p_node) const;
  135. QTreeWidgetItem *findNodeChild(QTreeWidgetItem *p_item, const Node *p_node) const;
  136. QTreeWidgetItem *findNodeTopLevelItem(QTreeWidget *p_tree, const Node *p_node) const;
  137. void saveNotebookTreeState(bool p_saveCurrentItem = true);
  138. QSharedPointer<QTreeWidgetStateCache<Node *>> stateCache() const;
  139. void clearStateCache(const Notebook *p_notebook);
  140. void createContextMenuOnRoot(QMenu *p_menu);
  141. void createContextMenuOnNode(QMenu *p_menu, const Node *p_node);
  142. void createContextMenuOnExternalNode(QMenu *p_menu, const ExternalNode *p_node);
  143. // Factory function to create action.
  144. QAction *createAction(Action p_act, QObject *p_parent);
  145. QAction *createAndAddAction(Action p_act, QMenu *p_menu);
  146. void copySelectedNodes(bool p_move);
  147. void pasteNodesFromClipboard();
  148. QPair<QVector<Node *>, QVector<QSharedPointer<ExternalNode>>> getSelectedNodes() const;
  149. void removeSelectedNodes(bool p_skipRecycleBin);
  150. void removeSelectedNodesFromConfig();
  151. QVector<Node *> confirmSelectedNodes(const QString &p_title,
  152. const QString &p_text,
  153. const QString &p_info) const;
  154. static QSharedPointer<ClipboardData> tryFetchClipboardData();
  155. bool isPasteOnNodeAvailable(const Node *p_node) const;
  156. void setNodeExpanded(const Node *p_node, bool p_expanded);
  157. void selectNodes(const QVector<const Node *> &p_nodes);
  158. // @p_skipRecycleBin is irrelevant if @p_configOnly is true.
  159. void removeNodes(QVector<Node *> p_nodes, bool p_skipRecycleBin, bool p_configOnly);
  160. void filterAwayChildrenNodes(QVector<Node *> &p_nodes);
  161. void updateAndExpandNode(Node *p_node);
  162. // Check if all selected items are the same type for operations.
  163. bool allSelectedItemsSameType() const;
  164. // Skip the recycle bin node if possible.
  165. void focusNormalNode();
  166. void sortNodes(QVector<QSharedPointer<Node>> &p_nodes) const;
  167. // [p_start, p_end).
  168. void sortNodes(QVector<QSharedPointer<Node>> &p_nodes, int p_start, int p_end, int p_viewOrder) const;
  169. // Sort nodes in config file.
  170. void manualSort();
  171. void openSelectedNodes();
  172. QSharedPointer<Node> importToIndex(QSharedPointer<ExternalNode> p_node);
  173. void importToIndex(const QVector<QSharedPointer<ExternalNode>> &p_nodes);
  174. // Check whether @p_node is a valid node. Will notify user.
  175. // Return true if it is invalid.
  176. bool checkInvalidNode(Node *p_node) const;
  177. void expandCurrentNodeAll();
  178. void expandItemRecursively(QTreeWidgetItem *p_item);
  179. void addOpenWithMenu(QMenu *p_menu);
  180. QStringList getSelectedNodesPath() const;
  181. void openSelectedNodesWithDefaultProgram();
  182. void openSelectedNodesWithExternalProgram(const QString &p_command);
  183. static NotebookNodeExplorer::NodeData getItemNodeData(const QTreeWidgetItem *p_item);
  184. static void setItemNodeData(QTreeWidgetItem *p_item, const NodeData &p_data);
  185. QSplitter *m_splitter = nullptr;
  186. TreeWidget *m_masterExplorer = nullptr;
  187. QSharedPointer<Notebook> m_notebook;
  188. QHash<const Notebook *, QSharedPointer<QTreeWidgetStateCache<Node *>>> m_stateCache;
  189. QScopedPointer<NavigationModeWrapper<QTreeWidget, QTreeWidgetItem>> m_navigationWrapper;
  190. bool m_recycleBinNodeVisible = false;
  191. int m_viewOrder = ViewOrder::OrderedByConfiguration;
  192. bool m_externalFilesVisible = true;
  193. bool m_autoImportExternalFiles = true;
  194. enum NodeIcon
  195. {
  196. FolderNode = 0,
  197. FileNode,
  198. InvalidFolderNode,
  199. InvalidFileNode,
  200. RecycleBinNode,
  201. ExternalFolderNode,
  202. ExternalFileNode,
  203. MaxIcons
  204. };
  205. static QIcon s_nodeIcons[NodeIcon::MaxIcons];
  206. };
  207. }
  208. Q_DECLARE_METATYPE(vnotex::NotebookNodeExplorer::NodeData);
  209. #endif // NOTEBOOKNODEEXPLORER_H