| 42 QVariant data(const QModelIndex& index, int role) const override; |
42 QVariant data(const QModelIndex& index, int role) const override; |
| 43 QVariant getHeaderProperty(const HeaderProperty property); |
43 QVariant getHeaderProperty(const HeaderProperty property); |
| 44 const QString& getName() const; |
44 const QString& getName() const; |
| 45 QVariant getObjectProperty(const int index, const ldraw::Property property) const; |
45 QVariant getObjectProperty(const int index, const ldraw::Property property) const; |
| 46 std::vector<gl::Polygon> getPolygons(class DocumentManager* documents) const; |
46 std::vector<gl::Polygon> getPolygons(class DocumentManager* documents) const; |
| 47 QModelIndex lookup(ldraw::Id id) const; |
47 QModelIndex lookup(ldraw::id_t id) const; |
| 48 ldraw::Id resolve(const QModelIndex& index) const; |
48 ldraw::id_t resolve(const QModelIndex& index) const; |
| |
49 template<typename R> |
| |
50 ldraw::Id<R> checkType(ldraw::id_t id) const; |
| |
51 template<typename R> |
| |
52 const R* get(ldraw::Id<R> id) const; |
| 49 signals: |
53 signals: |
| 50 void objectAdded(ldraw::Id id, int position); |
54 void objectAdded(ldraw::id_t id, int position); |
| 51 private: |
55 private: |
| 52 using ModelObjectPointer = std::unique_ptr<ldraw::Object>; |
56 using ModelObjectPointer = std::unique_ptr<ldraw::Object>; |
| 53 template<typename T, typename... Args> |
57 template<typename T, typename... Args> |
| 54 ldraw::Id append(Args&&... args); |
58 ldraw::Id<T> append(Args&&... args); |
| 55 void append(ModelObjectPointer&& object); |
59 void append(ModelObjectPointer&& object); |
| 56 template<typename T, typename... Args> |
60 template<typename T, typename... Args> |
| 57 ldraw::Id insert(int position, Args&&... args); |
61 ldraw::Id<T> insert(int position, Args&&... args); |
| 58 ldraw::Object* objectAt(const QModelIndex& index); |
62 ldraw::Object* objectAt(const QModelIndex& index); |
| 59 const ldraw::Object* objectAt(const QModelIndex& index) const; |
63 const ldraw::Object* objectAt(const QModelIndex& index) const; |
| |
64 template<typename T> |
| |
65 T* objectAt(ldraw::Id<T> id) |
| |
66 { |
| |
67 return static_cast<T*>(this->objectAt(this->lookup(id))); |
| |
68 } |
| |
69 template<typename T> |
| |
70 const T* objectAt(ldraw::Id<T> id) const |
| |
71 { |
| |
72 return static_cast<const T*>(this->objectAt(this->lookup(id))); |
| |
73 } |
| 60 void getObjectPolygons( |
74 void getObjectPolygons( |
| 61 const int index, |
75 const int index, |
| 62 std::vector<gl::Polygon>& polygons_out, |
76 std::vector<gl::Polygon>& polygons_out, |
| 63 ldraw::GetPolygonsContext* context) const; |
77 ldraw::GetPolygonsContext* context) const; |
| 64 bool modified = false; |
78 bool modified = false; |
| 65 QString path; |
79 QString path; |
| 66 LDHeader header; |
80 LDHeader header; |
| 67 std::vector<ModelObjectPointer> body; |
81 std::vector<ModelObjectPointer> body; |
| 68 std::map<ldraw::Id, ldraw::Object*> objectsById; |
82 std::map<ldraw::id_t, ldraw::Object*> objectsById; |
| 69 mutable std::vector<gl::Polygon> cachedPolygons; |
83 mutable std::vector<gl::Polygon> cachedPolygons; |
| 70 mutable bool needRecache = true; |
84 mutable bool needRecache = true; |
| 71 }; |
85 }; |
| 72 |
86 |
| |
87 /** |
| |
88 * \brief Checks type of object behind id |
| |
89 * Checks whether the specified id refers to an object of the specified type. |
| |
90 * \returns id casted to subclass if appropriate, null id otherwise |
| |
91 */ |
| |
92 template<typename R> |
| |
93 ldraw::Id<R> Model::checkType(ldraw::id_t id) const |
| |
94 { |
| |
95 if (dynamic_cast<const R*>(this->objectAt(this->lookup(id))) != nullptr) |
| |
96 { |
| |
97 return ldraw::Id<R>{id.value}; |
| |
98 } |
| |
99 else |
| |
100 { |
| |
101 return ldraw::NULL_ID; |
| |
102 } |
| |
103 } |
| |
104 |
| 73 template<typename T, typename... Args> |
105 template<typename T, typename... Args> |
| 74 ldraw::Id Model::append(Args&&... args) |
106 ldraw::Id<T> Model::append(Args&&... args) |
| 75 { |
107 { |
| 76 emit layoutAboutToBeChanged(); |
108 emit layoutAboutToBeChanged(); |
| 77 this->body.push_back(std::make_unique<T>(args...)); |
109 this->body.push_back(std::make_unique<T>(args...)); |
| 78 ldraw::Object* pointer = this->body.back().get(); |
110 ldraw::Object* pointer = this->body.back().get(); |
| 79 this->objectsById[pointer->id] = pointer; |
111 this->objectsById[pointer->id] = pointer; |
| 80 emit objectAdded(pointer->id, this->body.size() - 1); |
112 emit objectAdded(pointer->id, this->body.size() - 1); |
| 81 emit layoutChanged(); |
113 emit layoutChanged(); |
| 82 return pointer->id; |
114 return ldraw::Id<T>{pointer->id}; |
| 83 } |
115 } |
| 84 |
116 |
| 85 template<typename T, typename... Args> |
117 template<typename T, typename... Args> |
| 86 ldraw::Id Model::insert(int position, Args&&... args) |
118 ldraw::Id<T> Model::insert(int position, Args&&... args) |
| 87 { |
119 { |
| 88 emit layoutAboutToBeChanged(); |
120 emit layoutAboutToBeChanged(); |
| 89 this->body.insert(position, std::make_unique<T>(args...)); |
121 this->body.insert(position, std::make_unique<T>(args...)); |
| 90 ldraw::Object* pointer = this->body[position].get(); |
122 ldraw::Object* pointer = this->body[position].get(); |
| 91 this->objectsById[pointer->id] = pointer; |
123 this->objectsById[pointer->id] = pointer; |
| 92 emit objectAdded(pointer->id, position); |
124 emit objectAdded(pointer->id, position); |
| 93 emit layoutChanged(); |
125 emit layoutChanged(); |
| 94 return pointer->id; |
126 return ldraw::Id<T>{pointer->id}; |
| 95 } |
127 } |
| |
128 |
| |
129 template<typename R> |
| |
130 const R* Model::get(ldraw::Id<R> id) const |
| |
131 { |
| |
132 return this->objectAt(id); |
| |
133 } |