node.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. #include "node.h"
  2. #include <QDir>
  3. #include <notebookconfigmgr/inotebookconfigmgr.h>
  4. #include <notebookbackend/inotebookbackend.h>
  5. #include <utils/pathutils.h>
  6. #include <core/exception.h>
  7. #include "notebook.h"
  8. using namespace vnotex;
  9. Node::Node(Flags p_flags,
  10. ID p_id,
  11. const QString &p_name,
  12. const QDateTime &p_createdTimeUtc,
  13. const QDateTime &p_modifiedTimeUtc,
  14. const QStringList &p_tags,
  15. const QString &p_attachmentFolder,
  16. Notebook *p_notebook,
  17. Node *p_parent)
  18. : m_notebook(p_notebook),
  19. m_loaded(true),
  20. m_flags(p_flags),
  21. m_id(p_id),
  22. m_name(p_name),
  23. m_createdTimeUtc(p_createdTimeUtc),
  24. m_modifiedTimeUtc(p_modifiedTimeUtc),
  25. m_tags(p_tags),
  26. m_attachmentFolder(p_attachmentFolder),
  27. m_parent(p_parent)
  28. {
  29. Q_ASSERT(m_notebook);
  30. }
  31. Node::Node(Flags p_flags,
  32. const QString &p_name,
  33. Notebook *p_notebook,
  34. Node *p_parent)
  35. : m_notebook(p_notebook),
  36. m_flags(p_flags),
  37. m_name(p_name),
  38. m_parent(p_parent)
  39. {
  40. Q_ASSERT(m_notebook);
  41. }
  42. Node::~Node()
  43. {
  44. }
  45. bool Node::isLoaded() const
  46. {
  47. return m_loaded;
  48. }
  49. void Node::loadCompleteInfo(ID p_id,
  50. const QDateTime &p_createdTimeUtc,
  51. const QDateTime &p_modifiedTimeUtc,
  52. const QStringList &p_tags,
  53. const QVector<QSharedPointer<Node>> &p_children)
  54. {
  55. Q_ASSERT(!m_loaded);
  56. m_id = p_id;
  57. m_createdTimeUtc = p_createdTimeUtc;
  58. m_modifiedTimeUtc = p_modifiedTimeUtc;
  59. m_tags = p_tags;
  60. m_children = p_children;
  61. m_loaded = true;
  62. }
  63. bool Node::isRoot() const
  64. {
  65. return !m_parent && m_use == Use::Root;
  66. }
  67. const QString &Node::getName() const
  68. {
  69. return m_name;
  70. }
  71. void Node::setName(const QString &p_name)
  72. {
  73. m_name = p_name;
  74. }
  75. void Node::updateName(const QString &p_name)
  76. {
  77. if (m_name == p_name) {
  78. return;
  79. }
  80. getConfigMgr()->renameNode(this, p_name);
  81. Q_ASSERT(m_name == p_name);
  82. emit m_notebook->nodeUpdated(this);
  83. }
  84. bool Node::containsChild(const QString &p_name, bool p_caseSensitive) const
  85. {
  86. return findChild(p_name, p_caseSensitive) != nullptr;
  87. }
  88. bool Node::containsChild(const QSharedPointer<Node> &p_node) const
  89. {
  90. return m_children.indexOf(p_node) != -1;
  91. }
  92. QSharedPointer<Node> Node::findChild(const QString &p_name, bool p_caseSensitive) const
  93. {
  94. auto targetName = p_caseSensitive ? p_name : p_name.toLower();
  95. for (const auto &child : m_children) {
  96. if (p_caseSensitive ? child->getName() == targetName
  97. : child->getName().toLower() == targetName) {
  98. return child;
  99. }
  100. }
  101. return nullptr;
  102. }
  103. void Node::setParent(Node *p_parent)
  104. {
  105. m_parent = p_parent;
  106. }
  107. Node *Node::getParent() const
  108. {
  109. return m_parent;
  110. }
  111. Node::Flags Node::getFlags() const
  112. {
  113. return m_flags;
  114. }
  115. Node::Use Node::getUse() const
  116. {
  117. return m_use;
  118. }
  119. void Node::setUse(Node::Use p_use)
  120. {
  121. m_use = p_use;
  122. }
  123. ID Node::getId() const
  124. {
  125. return m_id;
  126. }
  127. const QDateTime &Node::getCreatedTimeUtc() const
  128. {
  129. return m_createdTimeUtc;
  130. }
  131. const QDateTime &Node::getModifiedTimeUtc() const
  132. {
  133. return m_modifiedTimeUtc;
  134. }
  135. void Node::setModifiedTimeUtc()
  136. {
  137. m_modifiedTimeUtc = QDateTime::currentDateTimeUtc();
  138. }
  139. const QVector<QSharedPointer<Node>> &Node::getChildrenRef() const
  140. {
  141. return m_children;
  142. }
  143. QVector<QSharedPointer<Node>> Node::getChildren() const
  144. {
  145. return m_children;
  146. }
  147. int Node::getChildrenCount() const
  148. {
  149. return m_children.size();
  150. }
  151. void Node::addChild(const QSharedPointer<Node> &p_node)
  152. {
  153. insertChild(m_children.size(), p_node);
  154. }
  155. void Node::insertChild(int p_idx, const QSharedPointer<Node> &p_node)
  156. {
  157. Q_ASSERT(isContainer());
  158. p_node->setParent(this);
  159. m_children.insert(p_idx, p_node);
  160. }
  161. void Node::removeChild(const QSharedPointer<Node> &p_child)
  162. {
  163. if (m_children.removeOne(p_child)) {
  164. p_child->setParent(nullptr);
  165. }
  166. }
  167. Notebook *Node::getNotebook() const
  168. {
  169. return m_notebook;
  170. }
  171. bool Node::isAncestor(const Node *p_ancestor, const Node *p_child)
  172. {
  173. if (!p_ancestor || !p_child) {
  174. return false;
  175. }
  176. while (p_child) {
  177. p_child = p_child->getParent();
  178. if (p_child == p_ancestor) {
  179. return true;
  180. }
  181. }
  182. return false;
  183. }
  184. const QStringList &Node::getTags() const
  185. {
  186. return m_tags;
  187. }
  188. bool Node::isReadOnly() const
  189. {
  190. return m_flags & Flag::ReadOnly;
  191. }
  192. void Node::setReadOnly(bool p_readOnly)
  193. {
  194. if (p_readOnly) {
  195. m_flags |= Flag::ReadOnly;
  196. } else {
  197. m_flags &= ~Flag::ReadOnly;
  198. }
  199. }
  200. QString Node::fetchPath() const
  201. {
  202. if (!m_parent) {
  203. return QString();
  204. } else {
  205. return PathUtils::concatenateFilePath(m_parent->fetchPath(), m_name);
  206. }
  207. }
  208. bool Node::isContainer() const
  209. {
  210. return m_flags & Flag::Container;
  211. }
  212. bool Node::hasContent() const
  213. {
  214. return m_flags & Flag::Content;
  215. }
  216. QDir Node::toDir() const
  217. {
  218. if (isContainer()) {
  219. return QDir(fetchAbsolutePath());
  220. }
  221. Q_ASSERT(false);
  222. return QDir();
  223. }
  224. void Node::load()
  225. {
  226. if (isLoaded()) {
  227. return;
  228. }
  229. getConfigMgr()->loadNode(this);
  230. }
  231. void Node::save()
  232. {
  233. getConfigMgr()->saveNode(this);
  234. }
  235. INotebookConfigMgr *Node::getConfigMgr() const
  236. {
  237. return m_notebook->getConfigMgr().data();
  238. }
  239. const QString &Node::getAttachmentFolder() const
  240. {
  241. return m_attachmentFolder;
  242. }
  243. void Node::setAttachmentFolder(const QString &p_attachmentFolder)
  244. {
  245. m_attachmentFolder = p_attachmentFolder;
  246. }
  247. QString Node::fetchAttachmentFolderPath()
  248. {
  249. return getConfigMgr()->fetchNodeAttachmentFolderPath(this);
  250. }
  251. INotebookBackend *Node::getBackend() const
  252. {
  253. return m_notebook->getBackend().data();
  254. }
  255. bool Node::canRename(const QString &p_newName) const
  256. {
  257. if (p_newName == m_name) {
  258. return true;
  259. }
  260. if (p_newName.isEmpty()) {
  261. return false;
  262. }
  263. Q_ASSERT(m_parent);
  264. if (p_newName.toLower() == m_name.toLower()) {
  265. if (m_parent->containsChild(p_newName, true)) {
  266. return false;
  267. } else {
  268. return true;
  269. }
  270. }
  271. if (m_parent->containsChild(p_newName, false)) {
  272. return false;
  273. }
  274. return true;
  275. }
  276. void Node::sortChildren(const QVector<int> &p_beforeIdx, const QVector<int> &p_afterIdx)
  277. {
  278. Q_ASSERT(isContainer());
  279. Q_ASSERT(p_beforeIdx.size() == p_afterIdx.size());
  280. if (p_beforeIdx == p_afterIdx) {
  281. return;
  282. }
  283. auto ori = m_children;
  284. for (int i = 0; i < p_beforeIdx.size(); ++i) {
  285. if (p_beforeIdx[i] != p_afterIdx[i]) {
  286. m_children[p_beforeIdx[i]] = ori[p_afterIdx[i]];
  287. }
  288. }
  289. save();
  290. }
  291. QVector<QSharedPointer<ExternalNode>> Node::fetchExternalChildren() const
  292. {
  293. return getConfigMgr()->fetchExternalChildren(const_cast<Node *>(this));
  294. }
  295. bool Node::containsContainerChild(const QString &p_name) const
  296. {
  297. // TODO: we assume that m_children is sorted first the container children.
  298. for (auto &child : m_children) {
  299. if (!child->isContainer()) {
  300. break;
  301. }
  302. if (child->getName() == p_name) {
  303. return true;
  304. }
  305. }
  306. return false;
  307. }
  308. bool Node::containsContentChild(const QString &p_name) const
  309. {
  310. // TODO: we assume that m_children is sorted: first the container children then content children.
  311. for (int i = m_children.size() - 1; i >= 0; --i) {
  312. if (m_children[i]->isContainer()) {
  313. break;
  314. }
  315. if (m_children[i]->getName() == p_name) {
  316. return true;
  317. }
  318. }
  319. return false;
  320. }
  321. bool Node::exists() const
  322. {
  323. return m_flags & Flag::Exists;
  324. }
  325. void Node::setExists(bool p_exists)
  326. {
  327. if (p_exists) {
  328. m_flags |= Flag::Exists;
  329. } else {
  330. m_flags &= ~Flag::Exists;
  331. }
  332. }