TreePath.hpp
1 #pragma once
2 #include <score/model/tree/InvisibleRootNode.hpp>
4 #include <score/serialization/JSONVisitor.hpp>
5 
6 #include <QModelIndex>
7 
8 #include <vector>
9 template <typename T>
10 using ref = T&;
11 template <typename T>
12 using cref = const T&;
13 
14 enum class InsertMode
15 {
16  AsSibling,
17  AsChild
18 };
19 
31 // Sadly we can't have a non-const interface
32 // because of QList<Node*> in Node::children...
33 class TreePath : public std::vector<int>
34 {
35 private:
36  using impl_type = std::vector<int>;
37 
38 public:
39  TreePath() = default;
40  TreePath(const impl_type& other)
41  : impl_type(other)
42  {
43  }
44 
45  TreePath(QModelIndex index)
46  {
47  QModelIndex iter = index;
48 
49  if(iter.isValid())
50  reserve(4);
51 
52  while(iter.isValid())
53  {
54  prepend(iter.row());
55  iter = iter.parent();
56  }
57  }
58 
59  template <typename T>
60  TreePath(const T& node)
61  {
62  // We have to take care of the root node.
63  if(!node.parent())
64  return;
65 
66  auto iter = &node;
67  while(iter && iter->parent())
68  {
69  prepend(iter->parent()->indexOfChild(iter));
70  iter = iter->parent();
71  }
72  }
73 
74  void prepend(int val) { this->insert(this->begin(), val); }
75 
76  template <typename T>
77  const T* toNode(const T* iter) const
78  {
79  const int pathSize = size();
80 
81  for(int i = 0; i < pathSize; ++i)
82  {
83  if(at(i) < iter->childCount())
84  {
85  iter = &iter->childAt(at(i));
86  }
87  else
88  {
89  return nullptr;
90  }
91  }
92 
93  return iter;
94  }
95 
96  template <typename T>
97  T* toNode(T* iter) const
98  {
99  const int pathSize = size();
100 
101  for(int i = 0; i < pathSize; ++i)
102  {
103  if(at(i) < iter->childCount())
104  {
105  iter = &iter->childAt(at(i));
106  }
107  else
108  {
109  return nullptr;
110  }
111  }
112 
113  return iter;
114  }
115 };
116 
117 template <>
118 struct is_custom_serialized<TreePath> : std::true_type
119 {
120 };
121 
122 template <>
123 struct TSerializer<DataStream, TreePath> : TSerializer<DataStream, std::vector<int>>
124 {
125  static void readFrom(DataStream::Serializer& s, const TreePath& path)
126  {
128  s, static_cast<const std::vector<int>&>(path));
129  }
130 
131  static void writeTo(DataStream::Deserializer& s, TreePath& path)
132  {
134  s, static_cast<std::vector<int>&>(path));
135  }
136 };
137 
138 template <>
140 {
141  static void readFrom(JSONObject::Serializer& s, const TreePath& path)
142  {
143  s.obj[s.strings.Path] = static_cast<const std::vector<int>&>(path);
144  }
145 
146  static void writeTo(JSONObject::Deserializer& s, TreePath& path)
147  {
148  static_cast<std::vector<int>&>(path) <<= s.obj[s.strings.Path];
149  }
150 };
Definition: VisitorInterface.hpp:53
Definition: DataStreamVisitor.hpp:27
Definition: DataStreamVisitor.hpp:202
Definition: VisitorInterface.hpp:61
Definition: JSONVisitor.hpp:52
Definition: JSONVisitor.hpp:423
Path in a tree of QAbstractItemModel objects.
Definition: TreePath.hpp:34
Definition: VisitorInterface.hpp:13