1 /*
2 Copyright 2006-2019 The QElectroTech Team
3 This file is part of QElectroTech.
4
5 QElectroTech is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 QElectroTech is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "xmlelementcollection.h"
19 #include "nameslist.h"
20 #include "qetxml.h"
21 #include "elementslocation.h"
22 #include "qetproject.h"
23
24 /**
25 * @brief XmlElementCollection::XmlElementCollection
26 * Build an empty collection.
27 * The collection start by :
28 * <collection>
29 * <category name="import>
30 * </category>
31 * </collection>
32 * All elements and category are stored as child of <category name="import>
33 * @param project : the project of this collection
34 */
XmlElementCollection(QETProject * project)35 XmlElementCollection::XmlElementCollection(QETProject *project) :
36 QObject(project),
37 m_project(project)
38 {
39 QDomElement collection = m_dom_document.createElement("collection");
40 m_dom_document.appendChild(collection);
41 QDomElement import = m_dom_document.createElement("category");
42 import.setAttribute("name", "import");
43 collection.appendChild(import);
44
45 NamesList names;
46
47 const QChar russian_data[24] = { 0x0418, 0x043C, 0x043F, 0x043E, 0x0440, 0x0442, 0x0438, 0x0440, 0x043E, 0x0432, 0x0430, 0x043D, 0x043D, 0x044B, 0x0435, 0x0020, 0x044D, 0x043B, 0x0435, 0x043C, 0x0435, 0x043D, 0x0442, 0x044B };
48 const QChar greek_data[18] = { 0x0395, 0x03b9, 0x03c3, 0x03b7, 0x03b3, 0x03bc, 0x03ad, 0x03bd, 0x03b1, 0x0020, 0x03c3, 0x03c4, 0x03bf, 0x03b9, 0x03c7, 0x03b5, 0x03af, 0x03b1 };
49 const QChar turkish_data[12] ={ 0x0130, 0x0074, 0x0068, 0x0061, 0x006C, 0x0020, 0x00F6, 0x011F, 0x0065, 0x006C, 0x0065, 0x0072 };
50 names.addName("fr", "Éléments importés");
51 names.addName("en", "Imported elements");
52 names.addName("de", "Importierte elemente");
53 names.addName("es", "Elementos importados");
54 names.addName("ru", QString(russian_data, 24));
55 names.addName("cs", "Zavedené prvky");
56 names.addName("pl", "Elementy importowane");
57 names.addName("pt", "elementos importados");
58 names.addName("it", "Elementi importati");
59 names.addName("el", QString(greek_data, 18));
60 names.addName("nl", "Elementen geïmporteerd");
61 names.addName("hr", "Uvezeni elementi");
62 names.addName("ca", "Elements importats");
63 names.addName("ro", "Elemente importate");
64 names.addName("tr", QString(turkish_data, 12));
65 names.addName("da", "Importerede elementer");
66 names.addName("hr", "Uvezeni elementi");
67 names.addName("sl", "Uvoženi elementi");
68
69
70 import.appendChild(names.toXml(m_dom_document));
71 }
72
73 /**
74 * @brief XmlElementCollection::XmlElementCollection
75 * Constructor with an collection. The tagName of @dom_element must be "collection"
76 * @param dom_element -the collection in a dom_element (the dom element in cloned)
77 * @param project : the project of this collection
78 */
XmlElementCollection(const QDomElement & dom_element,QETProject * project)79 XmlElementCollection::XmlElementCollection(const QDomElement &dom_element, QETProject *project) :
80 QObject(project),
81 m_project(project)
82 {
83 if (dom_element.tagName() == "collection")
84 m_dom_document.appendChild(m_dom_document.importNode(dom_element, true));
85 else
86 qDebug() << "XmlElementCollection : tagName of dom_element is not collection";
87 }
88
89 /**
90 * @brief XmlElementCollection::root
91 * The root is the first DOM-Element the xml collection, the tag name
92 * of the dom element is : collection
93 * @return The root QDomElement of the collection
94 */
root() const95 QDomElement XmlElementCollection::root() const {
96 return m_dom_document.documentElement();
97 }
98
99 /**
100 * @brief XmlElementCollection::importCategory
101 * @return The QDomElement import (the begining of a xml collection) or
102 * a null QDomElement if doesn't exist.
103 */
importCategory() const104 QDomElement XmlElementCollection::importCategory() const {
105 return root().firstChildElement("category");
106 }
107
108 /**
109 * @brief XmlElementCollection::childs
110 * @param parent_element
111 * @return All childs element in the @parent_element tree
112 */
childs(const QDomElement & parent_element) const113 QDomNodeList XmlElementCollection::childs(const QDomElement &parent_element) const
114 {
115 if (parent_element.ownerDocument() != m_dom_document) return QDomNodeList();
116 return parent_element.childNodes();
117 }
118
119 /**
120 * @brief XmlElementCollection::child
121 * If parent_element have child element with an attribute name = @child_name, return it, else return a null QDomElement.
122 * Only search for element with tag-name "category" and "element" (if child_name end with ".elmt")
123 * @param parent_element : the parent DomElement where we search for child.
124 * @parent_element must be a child node of this XmlElementCollection.
125 * @param child_name : name of child to search.
126 * @return The child QDomElement or a null QDomElement if not found
127 */
child(const QDomElement & parent_element,const QString & child_name) const128 QDomElement XmlElementCollection::child(const QDomElement &parent_element, const QString &child_name) const
129 {
130 if (parent_element.ownerDocument() != m_dom_document) return QDomElement();
131
132 //Get all childs element of parent_element
133 QDomNodeList child_list = parent_element.childNodes();
134 QString tag_name(child_name.endsWith(".elmt")? "element" : "category");
135 QList <QDomElement> found_dom_element;
136 for (int i=0 ; i<child_list.length() ; i++)
137 {
138 QDomElement child_element = child_list.item(i).toElement();
139 if (child_element.tagName() == tag_name) found_dom_element << child_element;
140 }
141
142 if (found_dom_element.isEmpty()) return QDomElement();
143
144 foreach (QDomElement elmt, found_dom_element)
145 if (elmt.attribute("name") == child_name)
146 return elmt;
147
148 return QDomElement();
149 }
150
151 /**
152 * @brief XmlElementCollection::child
153 * @param path
154 * @return the DomElement at path if exist, else return a null QDomElement
155 */
child(const QString & path) const156 QDomElement XmlElementCollection::child(const QString &path) const
157 {
158 QStringList path_list = path.split("/");
159 if (path_list.isEmpty()) return QDomElement();
160
161 QDomElement parent_element = root();
162 foreach (QString str, path_list)
163 {
164 QDomElement child_element = child(parent_element, str);
165
166 if (child_element.isNull())
167 return QDomElement();
168 else
169 parent_element = child_element;
170 }
171
172 return parent_element;
173 }
174
175 /**
176 * @brief XmlElementCollection::directories
177 * @param parent_element
178 * @return A list of directory stored in @parent_element
179 */
directories(const QDomElement & parent_element) const180 QList<QDomElement> XmlElementCollection::directories(const QDomElement &parent_element) const
181 {
182 QList <QDomElement> directory_list;
183 QDomNodeList node_list = childs(parent_element);
184 if (node_list.isEmpty()) return directory_list;
185
186 for (int i=0 ; i < node_list.count() ; i++)
187 {
188 QDomNode node = node_list.at(i);
189 if (node.isElement() && node.toElement().tagName() == "category")
190 directory_list << node.toElement();
191 }
192
193 return directory_list;
194 }
195
196 /**
197 * @brief XmlElementCollection::directoriesNames
198 * @param parent_element
199 * @return a list of names for every child directories of @parent_element
200 */
directoriesNames(const QDomElement & parent_element) const201 QStringList XmlElementCollection::directoriesNames(const QDomElement &parent_element) const
202 {
203 QList <QDomElement> childs = directories(parent_element);
204 QStringList names;
205
206 foreach (QDomElement child, childs)
207 {
208 QString name = child.attribute("name");
209 if (!name.isEmpty())
210 names.append(name);
211 }
212
213 return names;
214 }
215
216 /**
217 * @brief XmlElementCollection::elements
218 * @param parent_element
219 * @return A list of element stored in @parent_element
220 */
elements(const QDomElement & parent_element) const221 QList<QDomElement> XmlElementCollection::elements(const QDomElement &parent_element) const
222 {
223 QList <QDomElement> element_list;
224 QDomNodeList node_list = childs(parent_element);
225 if (node_list.isEmpty()) return element_list;
226
227 for (int i=0 ; i < node_list.count() ; i++)
228 {
229 QDomNode node = node_list.at(i);
230 if (node.isElement() && node.toElement().tagName() == "element")
231 element_list << node.toElement();
232 }
233
234 return element_list;
235 }
236
237 /**
238 * @brief XmlElementCollection::elementsNames
239 * @param parent_element
240 * @return A list of names fr every childs element of @parent_element
241 */
elementsNames(const QDomElement & parent_element) const242 QStringList XmlElementCollection::elementsNames(const QDomElement &parent_element) const
243 {
244 QList <QDomElement> childs = elements(parent_element);
245 QStringList names;
246
247 foreach (QDomElement child, childs)
248 {
249 QString name = child.attribute("name");
250 if (!name.isEmpty())
251 names.append(name);
252 }
253
254 return names;
255 }
256
257 /**
258 * @brief XmlElementCollection::element
259 * @param path : path of the element in this collection
260 * @return the QDomElement that represent the element at path @path
261 * or a null QDomElement if not found or doesn't represent an element
262 */
element(const QString & path) const263 QDomElement XmlElementCollection::element(const QString &path) const
264 {
265 if (!path.endsWith(".elmt")) return QDomElement();
266
267 QDomElement element = child(path);
268
269 if (element.tagName() == "element")
270 return element;
271 else
272 return QDomElement();
273 }
274
275 /**
276 * @brief XmlElementCollection::directory
277 * @param path : path of the directory in this collection
278 * @return the QDomElement that represent the directory at path @path
279 * or a null QDomElement if not found.
280 */
directory(const QString & path) const281 QDomElement XmlElementCollection::directory(const QString &path) const
282 {
283 QDomElement directory = child(path);
284
285 if (directory.tagName() == "category")
286 return directory;
287 else
288 return QDomElement();
289 }
290
291 /**
292 * @brief XmlElementCollection::addElement
293 * Add the element at location to this collection.
294 * The element is copied in this collection in "import" dir with the same path, in other word
295 * if the path is dir1/dir2/dir3/myElement.elmt, myElement is copied to this collection at the path : import/dir1/dir2/dir3/myElement.elmt
296 * If the path doesn't exist, he was created.
297 * If the element already exist, do nothing.
298 * @param location, location of the element
299 * @return the collection path of the added item or a null QString if element can't be added.
300 */
addElement(ElementsLocation & location)301 QString XmlElementCollection::addElement(ElementsLocation &location)
302 {
303 //location must be an element and exist
304 if (!(location.exist() && location.isElement()))
305 return QString();
306
307 //Add an element from this collection to this collection have no sense
308 if (location.isProject() && location.projectCollection() == this)
309 return QString();
310
311 //First we check if this location exist in this collection if so, we do nothing
312 if ( exist("import/" + location.collectionPath(false)) )
313 return QString();
314
315 //Get the import dir of this collection
316 QDomElement parent_element = importCategory();
317 if (parent_element.isNull())
318 return QString();
319
320 QString integrated_path = parent_element.attribute("name");
321
322 //Split the path
323 QStringList splitted_path = location.collectionPath(false).split("/");
324 if (splitted_path.isEmpty())
325 return QString();
326
327 if (location.isFileSystem()) {
328 //Get the root dir of the filesystem collection
329 QDir dir(location.fileSystemPath().remove(location.collectionPath(false)));
330 if (!dir.exists())
331 return QString();
332
333 foreach(QString str, splitted_path) {
334 QDomElement child_element = child(parent_element, str);
335
336 //Child doesn't exist, we create it
337 if (child_element.isNull()) {
338 QDomElement created_child;
339
340 //str is the path of an element, we integrate an element
341 if (str.endsWith(".elmt")) {
342 QFile element_file(dir.filePath(str));
343 if (!element_file.exists())
344 return QString();
345
346 created_child = QETXML::fileSystemElementToXmlCollectionElement(m_dom_document, element_file);
347 }
348
349 //str is the path of a directory, we integrate a directory.
350 else {
351 //Dir doesn't exist.
352 if (!dir.cd(str))
353 return QString();
354
355 created_child = QETXML::fileSystemDirToXmlCollectionDir(m_dom_document, dir);
356 }
357
358 if(created_child.isNull())
359 return QString();
360
361 parent_element.appendChild(created_child);
362 parent_element = created_child;
363 }
364 //Child exist
365 else {
366 if (!dir.cd(str))
367 return QString();
368
369 parent_element = child_element;
370 }
371
372 integrated_path.append("/"+str);
373 }
374 }
375 else if (location.isProject()) {
376 QString path;
377 foreach(QString str, splitted_path) {
378 if (path.isEmpty())
379 path = str;
380 else
381 path = path + "/" + str;
382
383 QDomElement child_element = child(parent_element, str);
384
385 //Child doesn't exist, we create it
386 if (child_element.isNull()) {
387 QDomElement created_child;
388
389 //str is the path of an element, we integrate an element
390 if (str.endsWith(".elmt")) {
391 created_child = m_dom_document.createElement("element");
392 created_child.setAttribute("name", str);
393
394 created_child.appendChild(location.xml().cloneNode(true));
395 }
396
397 //str is the path of a directory, we integrate a directory.
398 else {
399 created_child = m_dom_document.createElement("category");
400 created_child.setAttribute("name", str);
401
402 ElementsLocation sub_dir_location(path, location.project());
403 QDomElement names_element = sub_dir_location.nameList().toXml(m_dom_document);
404 created_child.appendChild(names_element);
405 }
406
407 if(created_child.isNull())
408 return QString();
409
410 parent_element.appendChild(created_child);
411 parent_element = created_child;
412 }
413 //Child exist
414 else
415 parent_element = child_element;
416
417 integrated_path.append("/"+str);
418 }
419 }
420
421 emit elementAdded(integrated_path);
422 return integrated_path;
423 }
424
425 /**
426 * @brief XmlElementCollection::addElementDefinition
427 * Add the élément defintion @xml_definition in the directory at path @dir_path with the name @elmt_name.
428 * @param dir_path : the path of the directory where we must add the element.
429 * The path must be an existing directory of this collection.
430 * @param elmt_name : The name used to store the element (the name must end with .elmt, if not, .elmt will be append to @elmt_name)
431 * @param xml_definition : The xml definition of the element.
432 * The tag name of @xml_definition must be "definition".
433 * @return True if the element is added with success.
434 */
addElementDefinition(const QString & dir_path,const QString & elmt_name,const QDomElement & xml_definition)435 bool XmlElementCollection::addElementDefinition(const QString &dir_path, const QString &elmt_name, const QDomElement &xml_definition)
436 {
437 QDomElement dom_dir = directory(dir_path);
438 if (dom_dir.isNull()) {
439 qDebug() << "XmlElementCollection::addElementDefinition : No directory at path : " << dir_path;
440 return false;
441 }
442
443 if (xml_definition.tagName() != "definition") {
444 qDebug() << "XmlElementCollection::addElementDefinition : xml_defintion tag name is not \"definition\"";
445 return false;
446 }
447
448 QString name = elmt_name;
449 if (!name.endsWith(".elmt")) {
450 name += ".elmt";
451 }
452
453 QDomElement dom_elmt = m_dom_document.createElement("element");
454 dom_elmt.setAttribute("name", name);
455 dom_elmt.appendChild(xml_definition.cloneNode(true));
456 dom_dir.appendChild(dom_elmt);
457
458 emit elementAdded(dir_path + "/" + name);
459
460 return true;
461 }
462
463 /**
464 * @brief XmlElementCollection::removeElement
465 * Remove the element at path @path.
466 * @param path
467 * @return True if element is removed and emit the signal elementRemoved.
468 * else false.
469 */
removeElement(const QString & path)470 bool XmlElementCollection::removeElement(const QString& path)
471 {
472 QDomElement elmt = element(path);
473
474 if (!elmt.isNull()) {
475 elmt.parentNode().removeChild(elmt);
476 emit elementRemoved(path);
477 return true;
478 }
479
480 return false;
481 }
482
483 /**
484 * @brief XmlElementCollection::copy
485 * Copy the content represented by source (an element or a directory) to destination.
486 * Destination must be a directory of this collection.
487 * If the destination already have an item at the same path of source, he will be replaced by source.
488 * @param source : content to copy
489 * @param destination : destination of the copy, must be a directory of this collection
490 * @param rename : rename the copy with @rename else use the name of source
491 * @param deep_copy : if true copy all childs of source (only if source is directory)
492 * @return the ElementLocation that represent the copy, if copy failed return a null ElementLocation
493 */
copy(ElementsLocation & source,ElementsLocation & destination,const QString & rename,bool deep_copy)494 ElementsLocation XmlElementCollection::copy(ElementsLocation &source, ElementsLocation &destination, const QString& rename, bool deep_copy)
495 {
496 if (!(source.exist() && destination.isDirectory() && destination.isProject() && destination.projectCollection() == this))
497 return ElementsLocation();
498
499 if (source.isElement())
500 return copyElement(source, destination, rename);
501 else
502 return copyDirectory(source, destination, rename, deep_copy);
503 }
504
505 /**
506 * @brief XmlElementCollection::exist
507 * Return true if the path @path exist in this collection
508 * @param path
509 * @return
510 */
exist(const QString & path) const511 bool XmlElementCollection::exist(const QString &path) const
512 {
513 if (child(path).isNull())
514 return false;
515 else
516 return true;
517 }
518
519 /**
520 * @brief XmlElementCollection::createDir
521 * Create a child directorie at path @path with the name @name.
522 * Emit directorieAdded if success.
523 * @param path : path of parent diectorie
524 * @param name : name of the directori to create.
525 * @param name_list : translation of the directorie name.
526 * @return true if creation success, if directorie already exist return true.
527 */
createDir(const QString & path,const QString & name,const NamesList & name_list)528 bool XmlElementCollection::createDir(const QString& path, const QString& name, const NamesList &name_list)
529 {
530 QString new_dir_path = path + "/" + name;
531
532 if (!directory(new_dir_path).isNull()) {
533 return true;
534 }
535
536 QDomElement parent_dir = directory(path);
537 if (parent_dir.isNull()) {
538 qDebug() << "XmlElementCollection::createDir : directorie at path doesn't exist";
539 return false;
540 }
541
542 QDomElement new_dir = m_dom_document.createElement("category");
543 new_dir.setAttribute("name", name);
544 new_dir.appendChild(name_list.toXml(m_dom_document));
545
546 parent_dir.appendChild(new_dir);
547
548 emit directorieAdded(new_dir_path);
549
550 return true;
551 }
552
553 /**
554 * @brief XmlElementCollection::removeDir
555 * Remove the directory at path @path.
556 * @param path
557 * @return true if successfuly removed and emit directoryRemoved(QString),
558 * else false.
559 */
removeDir(const QString & path)560 bool XmlElementCollection::removeDir(const QString& path)
561 {
562 QDomElement dir = directory(path);
563 if (!dir.isNull()) {
564 dir.parentNode().removeChild(dir);
565 emit directoryRemoved(path);
566 return true;
567 }
568 return false;
569 }
570
571 /**
572 * @brief XmlElementCollection::elementsLocation
573 * Return all locations stored in dom_element (element and directory).
574 * If dom_element is null, return all location owned by this collection
575 * dom_element must be a child of this collection.
576 * @param dom_element : dom_element where we must to search location.
577 * @param childs = if true return all childs location of dom_element, if false, only return the direct childs location of dom_element.
578 * @return
579 */
elementsLocation(QDomElement dom_element,bool childs) const580 QList<ElementsLocation> XmlElementCollection::elementsLocation(QDomElement dom_element, bool childs) const
581 {
582 QList <ElementsLocation> location_list;
583
584 if (dom_element.isNull())
585 dom_element = m_dom_document.documentElement();
586
587 if (dom_element.ownerDocument() != m_dom_document)
588 return location_list;
589
590 //get element childs
591 QList <QDomElement> element_list = elements(dom_element);
592
593 foreach (QDomElement elmt, element_list) {
594 ElementsLocation location = domToLocation(elmt);
595 if (location.exist())
596 location_list << location;
597 }
598
599 //get directory childs
600 QList <QDomElement> directory_list = directories(dom_element);
601
602 foreach (QDomElement dir, directory_list) {
603 ElementsLocation location = domToLocation(dir);
604 if (location.exist())
605 location_list << location;
606
607 if (childs)
608 location_list.append(elementsLocation(dir, childs));
609 }
610
611 return location_list;
612 }
613
614 /**
615 * @brief XmlElementCollection::domToLocation
616 * Return the element location who represent the xml element : dom_element
617 * dom_element must be owned by this collection
618 * @param dom_element : the dom_element of this collection that represent an element.
619 * The tag name of dom_element must be "element"
620 * @return the element location, location can be null if fail.
621 */
domToLocation(QDomElement dom_element) const622 ElementsLocation XmlElementCollection::domToLocation(QDomElement dom_element) const
623 {
624 if (dom_element.ownerDocument() == m_dom_document) {
625 QString path = dom_element.attribute("name");
626
627 while (!dom_element.parentNode().isNull() && dom_element.parentNode().isElement()) {
628 dom_element = dom_element.parentNode().toElement();
629
630 if (dom_element.tagName() == "category")
631 path.prepend(dom_element.attribute("name") + "/");
632 }
633
634 return ElementsLocation(path, m_project);
635 }
636 else
637 return ElementsLocation();
638 }
639
640 /**
641 * @brief XmlElementCollection::cleanUnusedElement
642 * Remove elements in this collection which is not used in the owner project
643 */
cleanUnusedElement()644 void XmlElementCollection::cleanUnusedElement()
645 {
646 foreach (ElementsLocation loc, m_project->unusedElements())
647 removeElement(loc.collectionPath(false));
648 }
649
650 /**
651 * @brief XmlElementCollection::cleanUnusedDirectory
652 * Remove the empty directories of this collection
653 */
cleanUnusedDirectory()654 void XmlElementCollection::cleanUnusedDirectory()
655 {
656 QDomNodeList lst = importCategory().elementsByTagName("category");
657
658 for(int i=0 ; i<lst.size() ; i++) {
659 QDomElement dir = lst.item(i).toElement();
660 //elmt haven't got child node "element" or "category", so he is emty, we can remove it
661 if (dir.elementsByTagName("element").isEmpty() && dir.elementsByTagName("category").isEmpty()) {
662 if (removeDir(domToLocation(dir).collectionPath(false)))
663 i=-1;
664 }
665 }
666 }
667
668 /**
669 * @brief XmlElementCollection::copyDirectory
670 * Copy the directory represented by source to destination.
671 * if destination have a directory with the same name as source, then this directory is removed
672 * @param source : directory to copy
673 * @param destination : destination of the copy
674 * @param rename : rename the copy with @rename else use the name of source
675 * @param deep_copy :if true copy all childs of source
676 * @return the ElementLocation that represent the copy, if copy failed return a null ElementLocation
677 */
copyDirectory(ElementsLocation & source,ElementsLocation & destination,const QString & rename,bool deep_copy)678 ElementsLocation XmlElementCollection::copyDirectory(ElementsLocation &source, ElementsLocation &destination, const QString& rename, bool deep_copy)
679 {
680 QString new_dir_name = rename.isEmpty() ? source.fileName() : rename;
681
682 //Get the xml directory where the new directory must be added
683 QDomElement parent_dir_dom = directory(destination.collectionPath(false));
684 if (parent_dir_dom.isNull()) return ElementsLocation();
685
686 //Remove the previous directory with the same path
687 QDomElement element = child(destination.collectionPath(false) + "/" + new_dir_name);
688 if (!element.isNull()) {
689 element.parentNode().removeChild(element);
690 emit directoryRemoved(destination.collectionPath(false) + "/" + new_dir_name);
691 }
692
693 ElementsLocation created_location;
694
695 //Copy with a file system collection source
696 if (source.isFileSystem())
697 {
698 QDir source_dir(source.fileSystemPath());
699 if (!source_dir.exists()) return ElementsLocation();
700
701
702 QDir dir(source.fileSystemPath());
703 QDomElement elmt_dom = QETXML::fileSystemDirToXmlCollectionDir(m_dom_document, dir, new_dir_name);
704 if (elmt_dom.isNull()) return ElementsLocation();
705
706 parent_dir_dom.appendChild(elmt_dom);
707
708 created_location.setPath(destination.projectCollectionPath() + "/" + new_dir_name);
709
710 if (deep_copy)
711 {
712 //Append all directories of source to the new created directory
713 foreach(QString str, source_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name))
714 {
715 ElementsLocation sub_source(source.fileSystemPath() + "/" + str);
716 copyDirectory(sub_source, created_location);
717 }
718
719 //Append all elements of source to the new created directory
720 source_dir.setNameFilters(QStringList() << "*.elmt");
721 foreach(QString str, source_dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name))
722 {
723 ElementsLocation sub_source(source.fileSystemPath() + "/" + str);
724 copyElement(sub_source, created_location);
725 }
726 }
727 }
728
729 //Copy with a xml collection source
730 else
731 {
732 if (!source.projectCollection()) return ElementsLocation();
733
734 QDomNode other_collection_node = source.projectCollection()->child(source.collectionPath(false)).cloneNode(deep_copy);
735
736 //We don't make a deep copy, but we must to get the local names of the copied directory
737 if (!deep_copy) {
738 QDomNode names = source.projectCollection()->child(source.collectionPath(false)).namedItem("names");
739 if (!names.isNull() && names.isElement())
740 other_collection_node.appendChild(names.cloneNode(true));
741 }
742
743 if (other_collection_node.isNull()) return ElementsLocation();
744
745 QDomElement other_collection_dom_dir = other_collection_node.toElement();
746 other_collection_dom_dir.setAttribute("name", new_dir_name);
747 parent_dir_dom.appendChild(other_collection_dom_dir);
748
749 created_location.setPath(destination.projectCollectionPath() + "/" + new_dir_name);
750 }
751
752 emit directorieAdded(created_location.collectionPath(false));
753 return created_location;
754 }
755
756 /**
757 * @brief XmlElementCollection::copyElement
758 * Copy the element represented by source to destination (must be a directory)
759 * If element already exist in destination he will be replaced by the new.
760 * @param source : element to copy
761 * @param destination : destination of the copy
762 * @param rename : rename the copy with @rename else use the name of source
763 * @return The ElementsLocation of the copy
764 */
copyElement(ElementsLocation & source,ElementsLocation & destination,const QString & rename)765 ElementsLocation XmlElementCollection::copyElement(ElementsLocation &source, ElementsLocation &destination, const QString& rename)
766 {
767 QString new_elmt_name = rename.isEmpty() ? source.fileName() : rename;
768
769 QDomElement elmt_dom;
770
771 //Copy with a file system collection source
772 if (source.isFileSystem())
773 {
774 QFile file(source.fileSystemPath());
775 elmt_dom = QETXML::fileSystemElementToXmlCollectionElement(m_dom_document, file, new_elmt_name);
776 if (elmt_dom.isNull()) return ElementsLocation();
777 }
778 //Copy with a xml collection source
779 else
780 {
781 QDomElement other_collection = source.xml();
782 elmt_dom = m_dom_document.createElement("element");
783 elmt_dom.setAttribute("name", new_elmt_name);
784 elmt_dom.appendChild(other_collection.cloneNode());
785 }
786
787
788 //Remove the previous element with the same path
789 QDomElement element = child(destination.collectionPath(false) + "/" + new_elmt_name);
790 bool removed = false;
791 if (!element.isNull()) {
792 element.parentNode().removeChild(element);
793 removed = true;
794 }
795
796 //Get the xml directory where the new element must be added
797 QDomElement dir_dom = directory(destination.collectionPath(false));
798 if (dir_dom.isNull()) return ElementsLocation();
799 dir_dom.appendChild(elmt_dom);
800
801 ElementsLocation copy_loc(destination.projectCollectionPath() + "/" + new_elmt_name);
802
803 if (removed) {
804 emit elementChanged(copy_loc.collectionPath(false));
805 }
806 else {
807 emit elementAdded(copy_loc.collectionPath(false));
808 }
809
810 return copy_loc;
811 }
812