5
5
#include < QSettings>
6
6
#include < QTextStream>
7
7
#include < QList>
8
+ #include < QMap>
8
9
#include < QMessageBox>
9
10
#include < QFileDialog>
10
11
#include < QMenu>
14
15
#include < QSvgWidget>
15
16
#include < QShortcut>
16
17
#include < QTabBar>
18
+ #include < QXmlStreamWriter>
17
19
#include < QDesktopServices>
18
20
#include < QInputDialog>
19
21
#include < nodes/Node>
@@ -466,7 +468,6 @@ QString MainWindow::saveToXML() const
466
468
continue ;
467
469
}
468
470
469
-
470
471
QDomElement node = doc.createElement ( QString::fromStdString (toStr (model.type )) );
471
472
472
473
if ( !node.isNull () )
@@ -487,7 +488,105 @@ QString MainWindow::saveToXML() const
487
488
root.appendChild (root_models);
488
489
root.appendChild ( doc.createComment (COMMENT_SEPARATOR) );
489
490
490
- return doc.toString (4 );
491
+ return xmlDocumentToString (doc);
492
+ }
493
+
494
+ QString MainWindow::xmlDocumentToString (const QDomDocument &document) const
495
+ {
496
+ QString output_string;
497
+
498
+ QXmlStreamWriter stream (&output_string);
499
+
500
+ stream.setAutoFormatting (true );
501
+ stream.setAutoFormattingIndent (4 );
502
+
503
+ stream.writeStartDocument ();
504
+
505
+ auto root_element = document.documentElement ();
506
+
507
+ stream.writeStartElement (root_element.tagName ());
508
+
509
+ streamElementAttributes (stream, root_element);
510
+
511
+ auto next_node = root_element.firstChild ();
512
+
513
+ while ( !next_node.isNull () )
514
+ {
515
+ recursivelySaveNodeCanonically (stream, next_node);
516
+
517
+ if ( stream.hasError () )
518
+ {
519
+ break ;
520
+ }
521
+ next_node = next_node.nextSibling ();
522
+ }
523
+
524
+ stream.writeEndElement ();
525
+ stream.writeEndDocument ();
526
+
527
+ return output_string;
528
+ }
529
+
530
+ void MainWindow::streamElementAttributes (QXmlStreamWriter &stream, const QDomElement &element) const
531
+ {
532
+ if (element.hasAttributes ())
533
+ {
534
+ QMap<QString, QString> attributes;
535
+ const QDomNamedNodeMap attributes_map = element.attributes ();
536
+
537
+ for (int i = 0 ; i < attributes_map.count (); ++i)
538
+ {
539
+ auto attribute = attributes_map.item (i);
540
+ attributes.insert (attribute.nodeName (), attribute.nodeValue ());
541
+ }
542
+
543
+ auto i = attributes.constBegin ();
544
+ while (i != attributes.constEnd ())
545
+ {
546
+ stream.writeAttribute (i.key (), i.value ());
547
+ ++i;
548
+ }
549
+ }
550
+ }
551
+
552
+ void MainWindow::recursivelySaveNodeCanonically (QXmlStreamWriter &stream, const QDomNode &parent_node) const
553
+ {
554
+ if ( stream.hasError () )
555
+ {
556
+ return ;
557
+ }
558
+
559
+ if ( parent_node.isElement () )
560
+ {
561
+ const QDomElement parent_element = parent_node.toElement ();
562
+
563
+ if ( !parent_element.isNull () )
564
+ {
565
+ stream.writeStartElement (parent_element.tagName ());
566
+
567
+ streamElementAttributes (stream, parent_element);
568
+
569
+ if (parent_element.hasChildNodes ())
570
+ {
571
+ auto child = parent_element.firstChild ();
572
+ while ( !child.isNull () )
573
+ {
574
+ recursivelySaveNodeCanonically (stream, child);
575
+ child = child.nextSibling ();
576
+ }
577
+ }
578
+
579
+ stream.writeEndElement ();
580
+ }
581
+ }
582
+ else if (parent_node.isComment ())
583
+ {
584
+ stream.writeComment (parent_node.nodeValue ());
585
+ }
586
+ else if (parent_node.isText ())
587
+ {
588
+ stream.writeCharacters (parent_node.nodeValue ());
589
+ }
491
590
}
492
591
493
592
void MainWindow::on_actionSave_triggered ()
0 commit comments