Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : */
8 :
9 : #include "confignode.hpp"
10 : #include "treeviewmodel.hpp"
11 :
12 : using namespace kdb;
13 :
14 0 : ConfigNode::ConfigNode (QString name, QString path, const Key & key, TreeViewModel * parentModel)
15 0 : : m_name (std::move (name)), m_path (std::move (path)), m_key (key), m_children (new TreeViewModel), m_metaData (nullptr),
16 0 : m_parentModel (parentModel), m_isExpanded (false), m_isDirty (false)
17 : {
18 0 : setValue ();
19 :
20 0 : if (m_key)
21 : {
22 0 : m_metaData = new TreeViewModel;
23 0 : populateMetaModel ();
24 : }
25 :
26 0 : connect (m_children, SIGNAL (expandNode (bool)), this, SLOT (setIsExpanded (bool)));
27 : connect (this, SIGNAL (showMessage (QString, QString, QString)), parentModel,
28 0 : SLOT (showConfigNodeMessage (QString, QString, QString)));
29 0 : }
30 :
31 0 : ConfigNode::ConfigNode (const ConfigNode & other)
32 : : QObject (), m_name (other.m_name), m_path (other.m_path), m_value (other.m_value), m_key (other.m_key.dup ()),
33 0 : m_children (new TreeViewModel), m_metaData (nullptr), m_parentModel (nullptr), m_isExpanded (other.m_isExpanded), m_isDirty (false)
34 : {
35 0 : if (other.m_children)
36 : {
37 0 : foreach (ConfigNodePtr node, other.m_children->model ())
38 : {
39 0 : m_children->append (ConfigNodePtr (new ConfigNode (*node)));
40 : }
41 : }
42 :
43 0 : if (other.m_metaData)
44 : {
45 0 : m_metaData = new TreeViewModel;
46 0 : foreach (ConfigNodePtr node, other.m_metaData->model ())
47 : {
48 0 : m_metaData->append (ConfigNodePtr (new ConfigNode (*node)));
49 : }
50 : }
51 :
52 0 : connect (m_children, SIGNAL (expandNode (bool)), this, SLOT (setIsExpanded (bool)));
53 0 : }
54 :
55 0 : ConfigNode::ConfigNode () : m_children (nullptr), m_metaData (nullptr), m_parentModel (nullptr), m_isExpanded (false), m_isDirty (false)
56 : {
57 : // this constructor is used to create metanodes
58 0 : }
59 :
60 0 : ConfigNode::~ConfigNode ()
61 : {
62 0 : delete m_children;
63 0 : delete m_metaData;
64 0 : }
65 :
66 0 : int ConfigNode::getChildCount () const
67 : {
68 0 : if (m_children) return m_children->rowCount ();
69 : return 0;
70 : }
71 :
72 0 : QString ConfigNode::getName () const
73 : {
74 0 : return m_name;
75 : }
76 :
77 0 : QString ConfigNode::getPath () const
78 : {
79 0 : return m_path;
80 : }
81 :
82 0 : QVariant ConfigNode::getValue () const
83 : {
84 0 : return m_value;
85 : }
86 :
87 0 : void ConfigNode::setName (const QString & name)
88 : {
89 0 : int index = m_path.lastIndexOf ("/");
90 :
91 0 : if (index != -1)
92 : {
93 0 : m_path.replace (index, m_path.length () - index, "/" + name);
94 : }
95 :
96 0 : if (!m_key)
97 0 : m_key = Key (m_path.toStdString (), KEY_END);
98 : else
99 0 : m_key = m_key.dup ();
100 :
101 : try
102 : {
103 0 : if (m_key.getBaseName ().compare (name.toStdString ()) != 0) m_key.setBaseName (name.toStdString ());
104 : }
105 0 : catch (KeyInvalidName const & ex)
106 : {
107 0 : emit showMessage (tr ("Error"), tr ("Could not set name because Keyname \"%1\" is invalid.").arg (name), ex.what ());
108 : return;
109 : }
110 :
111 0 : m_name = name;
112 : }
113 :
114 0 : void ConfigNode::setValue (const QVariant & value)
115 : {
116 0 : if (!m_key)
117 0 : m_key = Key (m_path.toStdString (), KEY_END);
118 : else
119 0 : m_key = m_key.dup ();
120 :
121 : try
122 : {
123 0 : if (m_key.getString ().compare (value.toString ().toStdString ()) != 0)
124 : {
125 0 : m_key.setString (value.toString ().toStdString ());
126 0 : m_value = value;
127 : }
128 : }
129 0 : catch (KeyTypeMismatch const & ex)
130 : {
131 0 : emit showMessage (tr ("Error"), tr ("Creating/Editing binary keys is not yet supported."), ex.what ());
132 : return;
133 : }
134 : }
135 :
136 :
137 0 : void ConfigNode::setMeta (const QString & name, const QVariant & value)
138 : {
139 0 : if (!m_key)
140 0 : m_key = Key (m_path.toStdString (), KEY_END);
141 : else
142 0 : m_key = m_key.dup ();
143 :
144 0 : m_key.setMeta (name.toStdString (), value.toString ().toStdString ());
145 0 : m_name = name;
146 0 : m_value = value;
147 0 : }
148 :
149 :
150 0 : void ConfigNode::setMeta (const QVariantMap & metaData)
151 : {
152 0 : if (m_metaData)
153 : {
154 : // delete old metadata in key
155 0 : for (auto & elem : m_metaData->model ())
156 : {
157 0 : elem->deleteMeta (elem->getName ());
158 : }
159 : // delete old metadata in model
160 0 : m_metaData->clearMetaModel ();
161 : }
162 : else
163 0 : m_metaData = new TreeViewModel;
164 :
165 : // create new metadata nodes in model
166 0 : for (int i = 0; i < metaData.size (); i++)
167 : {
168 0 : m_metaData->insertMetaRow (i, m_key, m_name);
169 : }
170 :
171 0 : int counter = 0;
172 : // set new metadata
173 0 : for (QVariantMap::const_iterator iter = metaData.begin (); iter != metaData.end (); iter++)
174 : {
175 0 : QVariantList tmp;
176 0 : tmp << iter.key () << iter.value ();
177 0 : m_metaData->setData (m_metaData->index (counter), tmp, TreeViewModel::MetaValueRole);
178 0 : counter++;
179 : }
180 0 : }
181 :
182 0 : void ConfigNode::deleteMeta (const QString & name)
183 : {
184 0 : if (m_key) m_key.delMeta (name.toStdString ());
185 0 : }
186 :
187 0 : void ConfigNode::accept (Visitor & visitor)
188 : {
189 0 : visitor.visit (*this);
190 :
191 0 : if (m_children)
192 : {
193 0 : foreach (ConfigNodePtr node, m_children->model ())
194 0 : node->accept (visitor);
195 : }
196 0 : }
197 :
198 0 : Key ConfigNode::getKey () const
199 : {
200 0 : return m_key;
201 : }
202 :
203 0 : int ConfigNode::getChildIndexByName (const QString & name)
204 : {
205 0 : if (m_children)
206 : {
207 0 : for (int i = 0; i < m_children->rowCount (); i++)
208 : {
209 0 : if (m_children->model ().at (i)->getName () == name) return i;
210 : }
211 : }
212 :
213 : return -1;
214 : }
215 :
216 0 : TreeViewModel * ConfigNode::getParentModel ()
217 : {
218 0 : return m_parentModel;
219 : }
220 :
221 0 : void ConfigNode::setParentModel (TreeViewModel * parentModel)
222 : {
223 0 : m_parentModel = parentModel;
224 0 : }
225 :
226 0 : bool ConfigNode::isExpanded () const
227 : {
228 0 : return m_isExpanded;
229 : }
230 0 : bool ConfigNode::isDirty () const
231 : {
232 0 : return m_isDirty;
233 : }
234 :
235 0 : void ConfigNode::setIsDirty (bool dirty)
236 : {
237 0 : m_isDirty = dirty;
238 0 : }
239 :
240 0 : void ConfigNode::updateNode (Key key)
241 : {
242 0 : m_key = key;
243 0 : setValue ();
244 0 : populateMetaModel ();
245 0 : }
246 :
247 0 : void ConfigNode::setIsExpanded (bool value)
248 : {
249 0 : m_isExpanded = value;
250 0 : }
251 :
252 0 : void ConfigNode::populateMetaModel ()
253 : {
254 0 : if (m_key)
255 : {
256 0 : m_key.rewindMeta ();
257 0 : m_metaData->clearMetaModel ();
258 :
259 0 : while (m_key.nextMeta ())
260 : {
261 0 : ConfigNodePtr node (new ConfigNode ());
262 :
263 0 : node->setName (QString::fromStdString (m_key.getName ()));
264 0 : node->setKey (m_key);
265 0 : node->setMeta (QString::fromStdString (m_key.currentMeta ().getName ()),
266 0 : QVariant::fromValue (QString::fromStdString (m_key.currentMeta ().getString ())));
267 :
268 0 : m_metaData->insertRow (m_metaData->rowCount (), node, false);
269 : }
270 : }
271 0 : }
272 :
273 0 : void ConfigNode::setValue ()
274 : {
275 0 : if (m_key && m_key.isString ())
276 0 : m_value = QVariant::fromValue (QString::fromStdString (m_key.getString ()));
277 0 : else if (m_key && m_key.isBinary ())
278 0 : m_value = QVariant::fromValue (QString::fromStdString (m_key.getBinary ()));
279 0 : }
280 :
281 0 : void ConfigNode::setKey (Key key)
282 : {
283 0 : m_key = key;
284 0 : }
285 :
286 0 : void ConfigNode::setKeyName (const QString & name)
287 : {
288 0 : if (m_key)
289 : {
290 : try
291 : {
292 0 : m_key.setName (name.toStdString ());
293 : }
294 0 : catch (KeyInvalidName const & ex)
295 : {
296 0 : emit showMessage (tr ("Error"), tr ("Could not set name because Keyname \"%1\" is invalid.").arg (name),
297 0 : ex.what ());
298 : return;
299 : }
300 : }
301 : }
302 :
303 0 : void ConfigNode::appendChild (ConfigNodePtr node)
304 : {
305 0 : m_children->append (node);
306 0 : }
307 :
308 0 : bool ConfigNode::hasChild (const QString & name) const
309 : {
310 0 : if (m_children)
311 : {
312 0 : foreach (ConfigNodePtr node, m_children->model ())
313 : {
314 0 : if (node->getName () == name)
315 : {
316 0 : return true;
317 : }
318 : }
319 : }
320 :
321 : return false;
322 : }
323 :
324 0 : TreeViewModel * ConfigNode::getChildren () const
325 : {
326 0 : return m_children;
327 : }
328 :
329 0 : TreeViewModel * ConfigNode::getMetaKeys () const
330 : {
331 0 : return m_metaData;
332 : }
333 :
334 0 : ConfigNodePtr ConfigNode::getChildByName (QString & name) const
335 : {
336 0 : if (m_children)
337 : {
338 0 : foreach (ConfigNodePtr node, m_children->model ())
339 : {
340 0 : if (node->getName () == name)
341 : {
342 0 : return node;
343 : }
344 : }
345 : }
346 :
347 : return ConfigNodePtr ();
348 : }
349 :
350 0 : ConfigNodePtr ConfigNode::getChildByIndex (int index) const
351 : {
352 0 : if (m_children)
353 : {
354 0 : if (index >= 0 && index < m_children->model ().length ()) return m_children->model ().at (index);
355 : }
356 :
357 : return ConfigNodePtr ();
358 : }
359 :
360 0 : void ConfigNode::setPath (const QString & path)
361 : {
362 0 : m_path = path;
363 0 : setKeyName (path);
364 :
365 0 : if (m_children)
366 : {
367 0 : foreach (ConfigNodePtr node, m_children->model ())
368 : {
369 0 : node->setPath (m_path + "/" + node->getName ());
370 : }
371 : }
372 0 : }
373 :
374 0 : bool ConfigNode::childrenHaveNoChildren () const
375 : {
376 0 : int childcount = 0;
377 :
378 0 : if (m_children)
379 : {
380 0 : foreach (ConfigNodePtr node, m_children->model ())
381 : {
382 0 : childcount += node->getChildCount ();
383 : }
384 : }
385 :
386 0 : return childcount == 0;
387 0 : }
|