1
0

notebook.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. #include "notebook.h"
  2. #include <QFileInfo>
  3. #include <versioncontroller/iversioncontroller.h>
  4. #include <notebookbackend/inotebookbackend.h>
  5. #include <notebookconfigmgr/inotebookconfigmgr.h>
  6. #include <utils/pathutils.h>
  7. #include <utils/fileutils.h>
  8. #include "exception.h"
  9. using namespace vnotex;
  10. const QString Notebook::c_defaultAttachmentFolder = QStringLiteral("vx_attachments");
  11. const QString Notebook::c_defaultImageFolder = QStringLiteral("vx_images");
  12. static vnotex::ID generateNotebookID()
  13. {
  14. static vnotex::ID id = Notebook::InvalidId;
  15. return ++id;
  16. }
  17. Notebook::Notebook(const NotebookParameters &p_paras,
  18. QObject *p_parent)
  19. : QObject(p_parent),
  20. m_id(generateNotebookID()),
  21. m_type(p_paras.m_type),
  22. m_name(p_paras.m_name),
  23. m_description(p_paras.m_description),
  24. m_rootFolderPath(p_paras.m_rootFolderPath),
  25. m_icon(p_paras.m_icon),
  26. m_imageFolder(p_paras.m_imageFolder),
  27. m_attachmentFolder(p_paras.m_attachmentFolder),
  28. m_createdTimeUtc(p_paras.m_createdTimeUtc),
  29. m_backend(p_paras.m_notebookBackend),
  30. m_versionController(p_paras.m_versionController),
  31. m_configMgr(p_paras.m_notebookConfigMgr)
  32. {
  33. if (m_imageFolder.isEmpty()) {
  34. m_imageFolder = c_defaultImageFolder;
  35. }
  36. if (m_attachmentFolder.isEmpty()) {
  37. m_attachmentFolder = c_defaultAttachmentFolder;
  38. }
  39. m_configMgr->setNotebook(this);
  40. }
  41. Notebook::~Notebook()
  42. {
  43. }
  44. vnotex::ID Notebook::getId() const
  45. {
  46. return m_id;
  47. }
  48. const QString &Notebook::getType() const
  49. {
  50. return m_type;
  51. }
  52. const QString &Notebook::getName() const
  53. {
  54. return m_name;
  55. }
  56. void Notebook::setName(const QString &p_name)
  57. {
  58. m_name = p_name;
  59. }
  60. void Notebook::updateName(const QString &p_name)
  61. {
  62. Q_ASSERT(!p_name.isEmpty());
  63. if (p_name == m_name) {
  64. return;
  65. }
  66. m_name = p_name;
  67. updateNotebookConfig();
  68. emit updated();
  69. }
  70. const QString &Notebook::getDescription() const
  71. {
  72. return m_description;
  73. }
  74. void Notebook::setDescription(const QString &p_description)
  75. {
  76. m_description = p_description;
  77. }
  78. void Notebook::updateDescription(const QString &p_description)
  79. {
  80. if (p_description == m_description) {
  81. return;
  82. }
  83. m_description = p_description;
  84. updateNotebookConfig();
  85. emit updated();
  86. }
  87. const QString &Notebook::getRootFolderPath() const
  88. {
  89. return m_rootFolderPath;
  90. }
  91. QString Notebook::getRootFolderAbsolutePath() const
  92. {
  93. return PathUtils::absolutePath(m_rootFolderPath);
  94. }
  95. const QIcon &Notebook::getIcon() const
  96. {
  97. return m_icon;
  98. }
  99. void Notebook::setIcon(const QIcon &p_icon)
  100. {
  101. m_icon = p_icon;
  102. }
  103. const QString &Notebook::getImageFolder() const
  104. {
  105. return m_imageFolder;
  106. }
  107. const QString &Notebook::getAttachmentFolder() const
  108. {
  109. return m_attachmentFolder;
  110. }
  111. const QSharedPointer<INotebookBackend> &Notebook::getBackend() const
  112. {
  113. return m_backend;
  114. }
  115. const QSharedPointer<IVersionController> &Notebook::getVersionController() const
  116. {
  117. return m_versionController;
  118. }
  119. const QSharedPointer<INotebookConfigMgr> &Notebook::getConfigMgr() const
  120. {
  121. return m_configMgr;
  122. }
  123. const QSharedPointer<Node> &Notebook::getRootNode() const
  124. {
  125. if (!m_root) {
  126. const_cast<Notebook *>(this)->m_root = m_configMgr->loadRootNode();
  127. Q_ASSERT(m_root->isRoot());
  128. }
  129. return m_root;
  130. }
  131. QSharedPointer<Node> Notebook::getRecycleBinNode() const
  132. {
  133. auto root = getRootNode();
  134. const auto &children = root->getChildrenRef();
  135. auto it = std::find_if(children.begin(),
  136. children.end(),
  137. [this](const QSharedPointer<Node> &p_node) {
  138. return isRecycleBinNode(p_node.data());
  139. });
  140. if (it != children.end()) {
  141. return *it;
  142. }
  143. return nullptr;
  144. }
  145. QSharedPointer<Node> Notebook::newNode(Node *p_parent, Node::Flags p_flags, const QString &p_name)
  146. {
  147. return m_configMgr->newNode(p_parent, p_flags, p_name);
  148. }
  149. const QDateTime &Notebook::getCreatedTimeUtc() const
  150. {
  151. return m_createdTimeUtc;
  152. }
  153. QSharedPointer<Node> Notebook::loadNodeByPath(const QString &p_path)
  154. {
  155. if (!PathUtils::pathContains(m_rootFolderPath, p_path)) {
  156. return nullptr;
  157. }
  158. QString relativePath;
  159. QFileInfo fi(p_path);
  160. if (fi.isAbsolute()) {
  161. if (!fi.exists()) {
  162. return nullptr;
  163. }
  164. relativePath = PathUtils::relativePath(m_rootFolderPath, p_path);
  165. } else {
  166. relativePath = p_path;
  167. }
  168. return m_configMgr->loadNodeByPath(getRootNode(), relativePath);
  169. }
  170. QSharedPointer<Node> Notebook::copyNodeAsChildOf(const QSharedPointer<Node> &p_src, Node *p_dest, bool p_move)
  171. {
  172. Q_ASSERT(p_src != p_dest);
  173. Q_ASSERT(p_dest->getNotebook() == this);
  174. if (Node::isAncestor(p_src.data(), p_dest)) {
  175. Exception::throwOne(Exception::Type::InvalidArgument,
  176. QString("source (%1) is the ancestor of destination (%2)")
  177. .arg(p_src->fetchPath(), p_dest->fetchPath()));
  178. return nullptr;
  179. }
  180. if (p_src->getParent() == p_dest && p_move) {
  181. return p_src;
  182. }
  183. return m_configMgr->copyNodeAsChildOf(p_src, p_dest, p_move);
  184. }
  185. void Notebook::removeNode(const QSharedPointer<Node> &p_node, bool p_force, bool p_configOnly)
  186. {
  187. Q_ASSERT(p_node && !p_node->isRoot());
  188. Q_ASSERT(p_node->getNotebook() == this);
  189. m_configMgr->removeNode(p_node, p_force, p_configOnly);
  190. }
  191. void Notebook::removeNode(Node *p_node, bool p_force, bool p_configOnly)
  192. {
  193. Q_ASSERT(p_node);
  194. removeNode(p_node->sharedFromThis(), p_force, p_configOnly);
  195. }
  196. bool Notebook::isRecycleBinNode(const Node *p_node) const
  197. {
  198. return p_node && p_node->getUse() == Node::Use::RecycleBin;
  199. }
  200. bool Notebook::isNodeInRecycleBin(const Node *p_node) const
  201. {
  202. if (p_node) {
  203. p_node = p_node->getParent();
  204. while (p_node) {
  205. if (isRecycleBinNode(p_node)) {
  206. return true;
  207. }
  208. p_node = p_node->getParent();
  209. }
  210. }
  211. return false;
  212. }
  213. void Notebook::moveNodeToRecycleBin(Node *p_node)
  214. {
  215. moveNodeToRecycleBin(p_node->sharedFromThis());
  216. }
  217. void Notebook::moveNodeToRecycleBin(const QSharedPointer<Node> &p_node)
  218. {
  219. Q_ASSERT(p_node && !p_node->isRoot());
  220. auto destNode = getOrCreateRecycleBinDateNode();
  221. copyNodeAsChildOf(p_node, destNode.data(), true);
  222. }
  223. QSharedPointer<Node> Notebook::getOrCreateRecycleBinDateNode()
  224. {
  225. // Name after date.
  226. auto dateNodeName = QDate::currentDate().toString(QStringLiteral("yyyyMMdd"));
  227. auto recycleBinNode = getRecycleBinNode();
  228. auto dateNode = recycleBinNode->findChild(dateNodeName,
  229. FileUtils::isPlatformNameCaseSensitive());
  230. if (!dateNode) {
  231. // Create a date node.
  232. dateNode = newNode(recycleBinNode.data(), Node::Flag::Container, dateNodeName);
  233. }
  234. return dateNode;
  235. }
  236. void Notebook::emptyNode(const Node *p_node, bool p_force)
  237. {
  238. // Copy the children.
  239. auto children = p_node->getChildren();
  240. for (const auto &child : children) {
  241. removeNode(child, p_force);
  242. }
  243. }
  244. void Notebook::moveFileToRecycleBin(const QString &p_filePath)
  245. {
  246. auto node = getOrCreateRecycleBinDateNode();
  247. auto destFilePath = PathUtils::concatenateFilePath(node->fetchPath(),
  248. PathUtils::fileName(p_filePath));
  249. destFilePath = getBackend()->renameIfExistsCaseInsensitive(destFilePath);
  250. m_backend->copyFile(p_filePath, destFilePath);
  251. getBackend()->removeFile(p_filePath);
  252. emit nodeUpdated(node.data());
  253. }
  254. void Notebook::moveDirToRecycleBin(const QString &p_dirPath)
  255. {
  256. auto node = getOrCreateRecycleBinDateNode();
  257. auto destDirPath = PathUtils::concatenateFilePath(node->fetchPath(),
  258. PathUtils::fileName(p_dirPath));
  259. destDirPath = getBackend()->renameIfExistsCaseInsensitive(destDirPath);
  260. m_backend->copyDir(p_dirPath, destDirPath);
  261. getBackend()->removeDir(p_dirPath);
  262. emit nodeUpdated(node.data());
  263. }
  264. QSharedPointer<Node> Notebook::addAsNode(Node *p_parent,
  265. Node::Flags p_flags,
  266. const QString &p_name,
  267. const NodeParameters &p_paras)
  268. {
  269. return m_configMgr->addAsNode(p_parent, p_flags, p_name, p_paras);
  270. }
  271. bool Notebook::isBuiltInFile(const Node *p_node, const QString &p_name) const
  272. {
  273. return m_configMgr->isBuiltInFile(p_node, p_name);
  274. }
  275. bool Notebook::isBuiltInFolder(const Node *p_node, const QString &p_name) const
  276. {
  277. return m_configMgr->isBuiltInFolder(p_node, p_name);
  278. }
  279. QSharedPointer<Node> Notebook::copyAsNode(Node *p_parent,
  280. Node::Flags p_flags,
  281. const QString &p_path)
  282. {
  283. return m_configMgr->copyAsNode(p_parent, p_flags, p_path);
  284. }
  285. void Notebook::reloadNodes()
  286. {
  287. m_root.clear();
  288. getRootNode();
  289. }