2
KDChart - a multi-platform charting engine
5
/****************************************************************************
6
** Copyright (C) 2001-2003 Klaralvdalens Datakonsult AB. All rights reserved.
8
** This file is part of the KDChart library.
10
** This file may be used under the terms of the GNU General Public
11
** License versions 2.0 or 3.0 as published by the Free Software
12
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
13
** included in the packaging of this file. Alternatively you may (at
14
** your option) use any later version of the GNU General Public
15
** License if such license has been publicly approved by
16
** Klarälvdalens Datakonsult AB (or its successors, if any).
18
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
19
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
20
** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights
21
** not expressly granted herein.
23
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26
**********************************************************************/
28
#include <KDChartDiagramsSerializer>
29
#include <KDChartDiagramsSerializer_p.h>
31
#include <KDChartSerializeCollector>
32
#include <KDChartCoordPlanesSerializer>
33
#include <KDChartAxesSerializer>
34
#include <KDChartAttributesModelSerializer>
38
#include <KDChartLineDiagram>
39
#include <KDChartBarDiagram>
40
#include <KDChartPieDiagram>
41
#include <KDChartPolarDiagram>
42
#include <KDChartRingDiagram>
43
#include <KDChartSerializer>
44
#include <KDChartAbstractSerializerFactory>
47
#include <QMessageBox>
48
#include <QMetaObject>
49
// #include <QDomNodeList>
50
#include <QMetaProperty>
54
using namespace KDChart;
56
static const char* TagNameQtProperties = "properties";
58
\class KDChart::DiagramsSerializer KDChartDiagramsSerializer.h
60
\brief Auxiliary methods reading/saving KD Chart data and configuration in streams.
63
DiagramsSerializer::Private::Private( DiagramsSerializer* qq )
65
m_haveOwnCoordS( false ),
72
DiagramsSerializer::Private::~Private() {}
75
DiagramsSerializer::DiagramsSerializer( CoordPlanesSerializer* coordS )
76
: _d( new Private( this ) )
79
d->m_haveOwnCoordS = ( d->m_coordS == 0 );
80
if( d->m_haveOwnCoordS )
81
d->m_coordS = new CoordPlanesSerializer();
82
d->m_axesS = new AxesSerializer();
83
d->m_attrModelS = new AttributesModelSerializer();
84
d->m_globalList = "kdchart:diagrams"; // default value, can be
85
// overwritten by the title passed to DiagramsSerializer::saveDiagrams()
88
DiagramsSerializer::~DiagramsSerializer()
90
delete d->m_attrModelS;
92
if( d->m_haveOwnCoordS )
98
void DiagramsSerializer::init()
102
void DiagramsSerializer::saveDiagrams(
105
const ConstAbstractDiagramList& diags,
106
const QString& title )const
108
if( ! title.isEmpty() )
109
d->m_globalList = title;
111
// access (or append, resp.) the global list
112
QDomElement* diagsList =
113
SerializeCollector::instance()->findOrMakeElement( doc, d->m_globalList );
115
// create the local list holding names pointing into the global list
116
QDomElement pointersList =
117
SerializeCollector::createPointersList( doc, e, d->m_globalList );
119
Q_FOREACH ( const AbstractDiagram* p, diags )
122
QDomElement diagElement =
123
SerializeCollector::findOrMakeChild(
128
p->metaObject()->className(),
132
const AbstractSerializerFactory* factory
133
= Serializer::elementSerializerFactory( p );
135
factory->instance( p->metaObject()->className() )->saveElement( doc, diagElement, p );
137
qDebug() << "\nProblem: Can not store diagram:" << p->metaObject()->className();
144
bool DiagramsSerializer::parseDiagram(
145
const QDomNode& rootNode,
146
const QDomNode& pointerNode,
147
AbstractDiagram*& diagramPtr )const
155
const bool pointerFound =
156
AttributesSerializer::parseQObjectPointerNode(
158
ptrName, wasParsed, true ) && ptr;
160
if( ptrName.isEmpty() ){
161
qDebug()<< "Could not parse diagram. Global pointer node is invalid.";
165
diagramPtr = dynamic_cast<AbstractDiagram*>(ptr);
167
qDebug()<< "Could not parse diagram. Global pointer"
168
<< ptrName << "is no AbstractDiagram-ptr.";
172
qDebug()<< "Could not parse diagram. Global pointer"
173
<< ptrName << "is no AbstractDiagram-ptr.";
179
if( bOK && wasParsed ) return true;
182
QDomElement container;
184
container = SerializeCollector::findStoredGlobalElement(
185
rootNode, ptrName, "kdchart:diagrams" );
186
bOK = ! container.tagName().isEmpty();
190
SerializeCollector::instance()->setWasParsed( diagramPtr, true );
192
const AbstractSerializerFactory* const f = Serializer::elementSerializerFactory( diagramPtr );
195
bOK = f->instance( diagramPtr->metaObject()->className() )->parseElement( container, ptr );
200
bool DiagramsSerializer::Private::doParseDiagram(
201
const QDomElement& container,
202
AbstractDiagram*& diagramPtr )const
206
LineDiagram* lineDiag = qobject_cast< LineDiagram* >( diagramPtr );
207
BarDiagram* barDiag = qobject_cast< BarDiagram* >( diagramPtr );
208
PieDiagram* pieDiag = qobject_cast< PieDiagram* >( diagramPtr );
209
PolarDiagram* polarDiag = qobject_cast< PolarDiagram* >( diagramPtr );
210
RingDiagram* ringDiag = qobject_cast< RingDiagram* >( diagramPtr );
211
Plotter* plotDiag = qobject_cast< Plotter* >( diagramPtr );
214
result = parseLineDiagram( container, *lineDiag );
216
result = parseBarDiagram( container, *barDiag );
218
result = parsePieDiagram( container, *pieDiag );
220
result = parsePolarDiagram( container, *polarDiag );
222
result = parseRingDiagram( container, *ringDiag );
224
result = parsePlotter( container, *plotDiag );
229
void DiagramsSerializer::saveElement( QDomDocument& doc, QDomElement& e, const QObject* obj ) const
231
d->saveDiagram( doc, e, qobject_cast< const AbstractDiagram* >( obj ) );
234
bool DiagramsSerializer::parseElement( const QDomElement& container, QObject* ptr ) const
236
AbstractDiagram* diag = qobject_cast< AbstractDiagram* >( ptr );
237
return d->doParseDiagram( container, diag );
240
void DiagramsSerializer::Private::saveDiagram(
243
const AbstractDiagram* p )const
248
const LineDiagram* lineDiag = dynamic_cast<const LineDiagram*> ( p );
249
const BarDiagram* barDiag = dynamic_cast<const BarDiagram*> ( p );
250
const PieDiagram* pieDiag = dynamic_cast<const PieDiagram*> ( p );
251
const PolarDiagram* polarDiag = dynamic_cast<const PolarDiagram*> ( p );
252
const RingDiagram* ringDiag = dynamic_cast<const RingDiagram*> ( p );
255
saveLineDiagram( doc, e, *lineDiag );
257
saveBarDiagram( doc, e, *barDiag );
259
savePieDiagram( doc, e, *pieDiag );
261
savePolarDiagram( doc, e, *polarDiag );
263
saveRingDiagram( doc, e, *ringDiag );
266
bool DiagramsSerializer::Private::parseAbstractDiagram(
267
const QDomElement& container, AbstractDiagram& diagram )const
272
//TODO(khz): Find a way to serialize the Model data!
274
// pass #1: assign the data model to the diagram
276
// This will be done to set the correct model first, so that
277
// setting a RootIndex will use the right model then.
279
node = container.firstChild();
280
while( !node.isNull() ) {
281
QDomElement element = node.toElement();
282
if( !element.isNull() ) { // was really an element
283
QString tagName = element.tagName();
284
if( tagName == "Model" ) {
285
QDomNode node2 = element.firstChild();
286
if( ! node2.isNull() ) {
287
QDomElement ele2 = node2.toElement();
288
if( ! ele2.isNull() ) { // was really an element
290
if( AttributesSerializer::parseQObjectPointerNode( ele2, ptr ) ){
291
QAbstractItemModel *model = dynamic_cast<QAbstractItemModel*>(ptr);
293
diagram.setModel( model );
295
qDebug()<< "Could not parse AbstractDiagram. Global pointer"
296
<< ele2.tagName() << "is not a KDChart::QAbstractItemModel-ptr.";
304
node = node.nextSibling();
306
if( ! bOK ) return false;
310
// pass #2: retrieve all of the other settings, assuming that
311
// the data model has been set correctly to the diagram
313
// note: ATM pass #1 just is not done, so we can not set any RootIndex yet
314
// (khz, 2007 April 12)
316
node = container.firstChild();
317
while( !node.isNull() ) {
318
QDomElement element = node.toElement();
319
if( !element.isNull() ) { // was really an element
320
QString tagName = element.tagName();
321
if( tagName == "AttributesModel" ) {
322
QDomNode node2 = element.firstChild();
323
if( ! node2.isNull() ) {
324
QDomElement ele2 = node2.toElement();
325
if( ! ele2.isNull() ) { // was really an element
326
AttributesModel* model=0;
330
const bool isExternalModel =
331
AttributesSerializer::parseQObjectPointerNode(
333
ptrName, wasParsed, false ) && ptr;
334
if( ptrName.isEmpty() ){
335
qDebug()<< "Could not parse AbstractDiagram. Global pointer node"
336
<< ele2.tagName() << "is invalid.";
339
if( isExternalModel ){
340
model = dynamic_cast<AttributesModel*>(ptr);
342
qDebug()<< "Could not parse AbstractDiagram. Global pointer"
343
<< ptrName << "is no AttributesModel-ptr.";
347
// If no external model stored
348
// use the built-in attributes-model
349
model = diagram.attributesModel();
353
if( bOK && ! wasParsed ){
354
SerializeCollector::instance()->setWasParsed( model, true );
356
bOK = m_attrModelS->parseAttributesModel(
357
container.ownerDocument().firstChild(),
362
if( isExternalModel )
363
diagram.setAttributesModel( model );
365
diagram.attributesModel()->initFrom( model );
367
qDebug()<< "Could not parse AbstractDiagram / AttributesModel"
372
qDebug()<< "Could not parse AbstractDiagram. Node does not contain a valid element.";
376
qDebug()<< "Could not parse AbstractDiagram. Node does not contain a valid element.";
379
} else if( tagName == "RootIndex" ) {
382
if( KDXML::readModelIndexNode( element, isValid, column, row ) &&
386
qDebug()<< "RootIndex(" << column << "," << row << ") was stored for AbstractDiagram in\n "
387
<< AttributesSerializer::showDomPath( container.parentNode().parentNode().toElement() ) << "\n"
388
" Make sure to adjust it via setRootIndex() after you have called setModel().";
390
} else if( tagName == "CoodinatePlane" ) {
391
AbstractCoordinatePlane* plane;
392
if( m_coordS->parsePlane( container.ownerDocument().firstChild(), element.firstChild(), plane ) ){
393
diagram.setCoordinatePlane( plane );
395
// We do *not* report an error, since this is no bug:
396
// The coordinate plane will be set when the diagram is added to the plane.
397
// qDebug()<< "Could not parse AbstractDiagram / CoodinatePlane. Global pointer is not a KDChart::AbstractCoordinatePlane-ptr.";
400
} else if( tagName == "AllowOverlappingDataValueTexts" ) {
402
if( KDXML::readBoolNode( element, b ) ){
403
diagram.setAllowOverlappingDataValueTexts( b );
405
qDebug()<< "Could not parse AbstractDiagram. Element"
406
<< tagName << "has invalid content.";
408
} else if( tagName == "AntiAliasing" ) {
410
if( KDXML::readBoolNode( element, b ) ){
411
diagram.setAntiAliasing( b );
413
qDebug()<< "Could not parse AbstractDiagram. Element"
414
<< tagName << "has invalid content.";
416
} else if( tagName == "PercentMode" ) {
418
if( KDXML::readBoolNode( element, b ) ){
419
diagram.setPercentMode( b );
421
qDebug()<< "Could not parse AbstractDiagram. Element"
422
<< tagName << "has invalid content.";
424
} else if( tagName == "DatasetDimension" ) {
426
if( KDXML::readIntNode( element, i ) ){
427
diagram.setDatasetDimension( i );
429
qDebug()<< "Could not parse AbstractDiagram. Element"
430
<< tagName << "has invalid content.";
432
} else if ( tagName == TagNameQtProperties ) {
433
// now parse parent class properties:
434
if ( ! parseQtProperties( container, diagram ) ) {
435
qDebug() << "Could not parse base class Qt properties. Element"
436
<< tagName << "has invalid content.";
440
qDebug() << "Unknown subelement of AbstractDiagram found:" << tagName;
444
node = node.nextSibling();
449
void DiagramsSerializer::Private::saveAbstractDiagram(
452
const AbstractDiagram& diagram,
453
const QString& title )const
455
QDomElement diagElement =
456
doc.createElement( title );
457
e.appendChild( diagElement );
459
// save the attributes model
460
m_attrModelS->saveAttributesModel(
463
diagram.attributesModel(),
464
diagram.usesExternalAttributesModel() );
466
// save the root index
467
if( diagram.rootIndex().isValid() &&
468
(diagram.rootIndex().column() || diagram.rootIndex().row()) )
469
KDXML::createModelIndexNode( doc, diagElement, "RootIndex",
470
diagram.rootIndex() );
472
// save the pointer to the associated coordinate plane,
473
// and save the plane in the global structure if not there yet
474
const CartesianCoordinatePlane* coordPlane =
475
static_cast<const CartesianCoordinatePlane*>( diagram.coordinatePlane() );
476
if( coordPlane && m_coordS ){
477
QDomElement coordPlanePtrElement =
478
doc.createElement( "CoodinatePlane" );
479
diagElement.appendChild( coordPlanePtrElement );
480
// access (or append, resp.) the global list
481
QDomElement* planesList = SerializeCollector::instance()->findOrMakeElement( doc, m_coordS->globalList() );
484
QDomElement globalListElement =
485
SerializeCollector::findOrMakeChild(
488
coordPlanePtrElement,
489
"kdchart:coordinate-plane",
490
coordPlane->metaObject()->className(),
494
// Since the diagram is stored in the global structure anyway,
495
// it is save to store it right now.
496
// So it will not be forgotten, in case it is not embedded in any
497
// of the coordinate planes.
498
// The wasFound test makes sure it will not be stored twice.
499
const AbstractSerializerFactory* factory = Serializer::elementSerializerFactory( coordPlane );
500
const QObject* const obj = coordPlane;
502
factory->instance( coordPlane->metaObject()->className() )->saveElement( doc, globalListElement, obj );
506
KDXML::createBoolNode( doc, diagElement, "AllowOverlappingDataValueTexts",
507
diagram.allowOverlappingDataValueTexts() );
508
KDXML::createBoolNode( doc, diagElement, "AntiAliasing",
509
diagram.antiAliasing() );
510
KDXML::createBoolNode( doc, diagElement, "PercentMode",
511
diagram.percentMode() );
512
KDXML::createIntNode( doc, diagElement, "DatasetDimension",
513
diagram.datasetDimension() );
514
// serialize Qt properties inherited from superclasses:
515
saveQtProperties( doc, diagElement, diagram );
519
bool DiagramsSerializer::Private::parseCartCoordDiagram(
520
const QDomElement& container, AbstractCartesianDiagram& diagram )const
523
AbstractCartesianDiagram *refDiag=0;
524
QPointF refDiagOffset(0.0, 0.0);
525
QDomNode node = container.firstChild();
526
while( !node.isNull() ) {
527
QDomElement element = node.toElement();
528
if( !element.isNull() ) { // was really an element
529
QString tagName = element.tagName();
530
if( tagName == "kdchart:abstract-diagram" ) {
531
if( ! parseAbstractDiagram( element, diagram ) ){
532
qDebug() << "Could not parse base class of AbstractCartesianDiagram.";
535
} else if( tagName == "kdchart:axes:pointers" ) {
536
QDomNode node2 = element.firstChild();
537
while( ! node2.isNull() ) {
539
if( m_axesS->parseAxis( container.ownerDocument().firstChild(), node2, axis )
540
&& qobject_cast< CartesianAxis * >(axis) )
542
diagram.addAxis( qobject_cast< CartesianAxis * >(axis) );
544
qDebug()<< "Could not parse element of AbstractCartesianDiagram / kdchart:axes:pointers.";
547
node2 = node2.nextSibling();
549
} else if( tagName == "ReferenceDiagram" ) {
550
AbstractDiagram* diag;
552
if( q->parseDiagram( container.ownerDocument().firstChild(), element.firstChild(), diag ) )
553
refDiag = dynamic_cast<AbstractCartesianDiagram *>(diag);
555
qDebug()<< "Could not parse AbstractCartesianDiagram. Reference-diagram of"
556
<< container.tagName() << "is not a KDChart::AbstractCartesianDiagram-ptr.";
559
} else if( tagName == "Offset" ) {
561
if( KDXML::readPointFNode( element, pt ) ){
564
qDebug()<< "Could not parse AbstractCartesianDiagram. Element \"Offset\" is not a QPointF node.";
567
qDebug() << "Unknown subelement of AbstractCartesianDiagram found:" << tagName;
571
node = node.nextSibling();
574
diagram.setReferenceDiagram( refDiag, refDiagOffset );
578
void DiagramsSerializer::Private::saveCartCoordDiagram(
581
const AbstractCartesianDiagram& diagram,
582
const QString& title )const
584
QDomElement diagElement =
585
doc.createElement( title );
586
e.appendChild( diagElement );
588
// first save the information hold by the base class
589
saveAbstractDiagram( doc, diagElement, diagram,
590
"kdchart:abstract-diagram" );
592
// then save what is stored in the derived class
595
QList< const AbstractAxis* > abstractAxes;
596
CartesianAxisList axes = diagram.axes();
597
Q_FOREACH( const AbstractAxis* ax, axes )
599
m_axesS->saveAxes( doc, diagElement, abstractAxes, "kdchart:axes" );
601
// save the reference diagram(-pointer) and the respective offset, if any
602
const AbstractCartesianDiagram* refDiag = diagram.referenceDiagram();
604
QDomElement refDiagPtrElement =
605
doc.createElement( "ReferenceDiagram" );
606
diagElement.appendChild( refDiagPtrElement );
607
// access (or append, resp.) the global list
608
QDomElement* diagsList = SerializeCollector::instance()->findOrMakeElement( doc, m_globalList );
611
QDomElement globalListElement =
612
SerializeCollector::findOrMakeChild(
617
refDiag->metaObject()->className(),
621
// Since the diagram is stored in the global structure anyway,
622
// it is save to store it right now.
623
// So it will not be forgotten, in case it is not embedded in any
624
// of the coordinate planes.
625
// The wasFound test makes sure it will not be stored twice.
626
saveDiagram( doc, globalListElement, refDiag );
628
KDXML::createPointFNode(
629
doc, refDiagPtrElement, "Offset", diagram.referenceDiagramOffset() );
634
bool DiagramsSerializer::Private::parsePolCoordDiagram(
635
const QDomElement& container, AbstractPolarDiagram& diagram )const
638
QDomNode node = container.firstChild();
639
while( !node.isNull() ) {
640
QDomElement element = node.toElement();
641
if( !element.isNull() ) { // was really an element
642
QString tagName = element.tagName();
643
if( tagName == "kdchart:abstract-diagram" ) {
644
if( ! parseAbstractDiagram( element, diagram ) ){
645
qDebug() << "Could not parse base class of AbstractPolarDiagram.";
649
qDebug() << "Unknown subelement of AbstractPolarDiagram found:" << tagName;
653
node = node.nextSibling();
658
void DiagramsSerializer::Private::savePolCoordDiagram(
661
const AbstractPolarDiagram& diagram,
662
const QString& title )const
664
QDomElement diagElement =
665
doc.createElement( title );
666
e.appendChild( diagElement );
668
// first save the information hold by the base class
669
saveAbstractDiagram( doc, diagElement, diagram,
670
"kdchart:abstract-diagram" );
671
// that's all, there is no to-be-saved information in this class
675
bool DiagramsSerializer::Private::parseLineDiagram(
676
const QDomElement& container, LineDiagram& diagram )const
678
//qDebug() << "-------->" << container.tagName();
681
if( !container.isNull() ) {
682
//qDebug() << "\n DiagramsSerializer::parseLineDiagram() processing" << diagName;
683
QDomNode node = container.firstChild();
684
while( !node.isNull() ) {
685
QDomElement element = node.toElement();
686
if( !element.isNull() ) { // was really an element
687
QString tagName = element.tagName();
688
if( tagName == "kdchart:cartesian-coordinate-diagram" ) {
689
if( ! parseCartCoordDiagram( element, diagram ) ){
690
qDebug() << "Could not parse base class of LineDiagram.";
693
} else if( tagName == "LineType" ) {
695
if( KDXML::readStringNode( element, s ) ){
696
if( s.compare("Normal", Qt::CaseInsensitive) == 0 )
697
diagram.setType( LineDiagram::Normal );
698
else if( s.compare("Stacked", Qt::CaseInsensitive) == 0 )
699
diagram.setType( LineDiagram::Stacked );
700
else if( s.compare("Percent", Qt::CaseInsensitive) == 0 )
701
diagram.setType( LineDiagram::Percent );
704
Q_ASSERT( false ); // all of the types need to be handled
710
qDebug() << "Unknown subelement of LineDiagram found:" << tagName;
714
node = node.nextSibling();
720
void DiagramsSerializer::Private::saveLineDiagram(
722
QDomElement& diagElement,
723
const LineDiagram& diagram )const
725
// first save the information hold by the base class
726
saveCartCoordDiagram( doc, diagElement, diagram,
727
"kdchart:cartesian-coordinate-diagram" );
728
// then save what is stored in the derived class
730
switch( diagram.type() ){
731
case LineDiagram::Normal:
734
case LineDiagram::Stacked:
737
case LineDiagram::Percent:
741
Q_ASSERT( false ); // all of the types need to be handled
744
KDXML::createStringNode( doc, diagElement, "LineType", s );
747
bool DiagramsSerializer::Private::parsePlotter(
748
const QDomElement& container, Plotter& diagram )const
750
//qDebug() << "-------->" << container.tagName();
753
if( !container.isNull() ) {
754
//qDebug() << "\n DiagramsSerializer::parsePlotter() processing" << diagName;
755
QDomNode node = container.firstChild();
756
while( !node.isNull() ) {
757
QDomElement element = node.toElement();
758
if( !element.isNull() ) { // was really an element
759
QString tagName = element.tagName();
760
if( tagName == "kdchart:cartesian-coordinate-diagram" ) {
761
if( ! parseCartCoordDiagram( element, diagram ) ){
762
qDebug() << "Could not parse base class of Platter.";
765
} else if( tagName == "PlotType" ) {
767
if( KDXML::readStringNode( element, s ) ){
768
if( s.compare("Normal", Qt::CaseInsensitive) == 0 )
769
diagram.setType( Plotter::Normal );
772
Q_ASSERT( false ); // all of the types need to be handled
778
qDebug() << "Unknown subelement of Plotter found:" << tagName;
782
node = node.nextSibling();
788
void DiagramsSerializer::Private::savePlotter(
790
QDomElement& diagElement,
791
const Plotter& diagram )const
793
// first save the information hold by the base class
794
saveCartCoordDiagram( doc, diagElement, diagram,
795
"kdchart:cartesian-coordinate-diagram" );
796
// then save what is stored in the derived class
798
switch( diagram.type() ){
799
case Plotter::Normal:
803
Q_ASSERT( false ); // all of the types need to be handled
806
KDXML::createStringNode( doc, diagElement, "PlotType", s );
809
bool DiagramsSerializer::Private::parseBarDiagram(
810
const QDomElement& container, BarDiagram& diagram )const
813
if( !container.isNull() ) {
814
//qDebug() << "\n DiagramsSerializer::parseBarDiagram() processing" << diagName;
815
QDomNode node = container.firstChild();
816
while( !node.isNull() ) {
817
QDomElement element = node.toElement();
818
if( !element.isNull() ) { // was really an element
819
QString tagName = element.tagName();
820
if( tagName == "kdchart:cartesian-coordinate-diagram" ) {
821
if( ! parseCartCoordDiagram( element, diagram ) ){
822
qDebug() << "Could not parse base class of BarDiagram.";
825
} else if( tagName == "BarType" ) {
827
if( KDXML::readStringNode( element, s ) ){
828
if( s.compare("Normal", Qt::CaseInsensitive) == 0 )
829
diagram.setType( BarDiagram::Normal );
830
else if( s.compare("Stacked", Qt::CaseInsensitive) == 0 )
831
diagram.setType( BarDiagram::Stacked );
832
else if( s.compare("Percent", Qt::CaseInsensitive) == 0 )
833
diagram.setType( BarDiagram::Percent );
834
else if( s.compare("Rows", Qt::CaseInsensitive) == 0 )
835
diagram.setType( BarDiagram::Rows );
838
Q_ASSERT( false ); // all of the types need to be handled
844
qDebug() << "Unknown subelement of BarDiagram found:" << tagName;
848
node = node.nextSibling();
854
void DiagramsSerializer::Private::saveBarDiagram(
856
QDomElement& diagElement,
857
const BarDiagram& diagram )const
859
// first save the information hold by the base class
860
saveCartCoordDiagram( doc, diagElement, diagram,
861
"kdchart:cartesian-coordinate-diagram" );
863
// then save what is stored in the derived class
865
switch( diagram.type() )
867
case BarDiagram::Normal:
870
case BarDiagram::Stacked:
873
case BarDiagram::Percent:
876
case BarDiagram::Rows:
880
Q_ASSERT( false ); // all of the types need to be handled
883
KDXML::createStringNode( doc, diagElement, "BarType", s );
887
bool DiagramsSerializer::Private::parseAbstractPieDiagram(
888
const QDomElement& container, AbstractPieDiagram& diagram )const
891
QDomNode node = container.firstChild();
892
while( !node.isNull() ) {
893
QDomElement element = node.toElement();
894
if( !element.isNull() ) { // was really an element
895
QString tagName = element.tagName();
896
if( tagName == "kdchart:polar-coordinate-diagram" ) {
897
if( ! parsePolCoordDiagram( element, diagram ) ){
898
qDebug() << "Could not parse base class of AbstractPieDiagram.";
901
} else if( tagName == "Granularity" ) {
903
if( KDXML::readRealNode( element, r ) ){
904
diagram.setGranularity( r );
906
qDebug()<< "Could not parse AbstractPieDiagram. Element"
907
<< tagName << "has invalid content.";
909
} else if( tagName == "StartPosition" ) {
910
// setStartPosition is deprecated!
913
if( KDXML::readIntNode( element, i ) ){
914
diagram.setStartPosition( i );
916
qDebug()<< "Could not parse AbstractPieDiagram. Element"
917
<< tagName << "has invalid content.";
921
qDebug() << "Unknown subelement of AbstractPieDiagram found:" << tagName;
925
node = node.nextSibling();
930
void DiagramsSerializer::Private::saveAbstractPieDiagram(
933
const AbstractPieDiagram& diagram,
934
const QString& title )const
936
QDomElement diagElement =
937
doc.createElement( title );
938
e.appendChild( diagElement );
940
// first save the information hold by the base class
941
savePolCoordDiagram( doc, diagElement, diagram,
942
"kdchart:polar-coordinate-diagram" );
944
// then save what is stored in the derived class
945
KDXML::createRealNode( doc, diagElement, "Granularity", diagram.granularity() );
946
// setStartPosition is deprecated!
947
//KDXML::createIntNode( doc, diagElement, "StartPosition", diagram.startPosition() );
951
bool DiagramsSerializer::Private::parsePieDiagram(
952
const QDomElement& container, PieDiagram& diagram )const
955
if( !container.isNull() ) {
956
//qDebug() << "\n DiagramsSerializer::parsePieDiagram() processing" << diagName;
957
QDomNode node = container.firstChild();
958
while( !node.isNull() ) {
959
QDomElement element = node.toElement();
960
if( !element.isNull() ) { // was really an element
961
QString tagName = element.tagName();
962
if( tagName == "kdchart:abstract-pie-diagram" ) {
963
if( ! parseAbstractPieDiagram( element, diagram ) ){
964
qDebug() << "Could not parse base class of PieDiagram.";
968
qDebug() << "Unknown subelement of PieDiagram found:" << tagName;
972
node = node.nextSibling();
978
void DiagramsSerializer::Private::savePieDiagram(
980
QDomElement& diagElement,
981
const PieDiagram& diagram )const
983
// first save the information hold by the base class
984
saveAbstractPieDiagram( doc, diagElement, diagram,
985
"kdchart:abstract-pie-diagram" );
986
// that's all, there is no to-be-saved information in this class
990
bool DiagramsSerializer::Private::parsePolarDiagram(
991
const QDomElement& container, PolarDiagram& diagram )const
994
if( !container.isNull() ) {
995
//qDebug() << "\n DiagramsSerializer::parsePolarDiagram() processing" << diagName;
996
QDomNode node = container.firstChild();
997
while( !node.isNull() ) {
998
QDomElement element = node.toElement();
999
if( !element.isNull() ) { // was really an element
1000
QString tagName = element.tagName();
1001
if( tagName == "kdchart:polar-coordinate-diagram" ) {
1002
if( ! parsePolCoordDiagram( element, diagram ) ){
1003
qDebug() << "Could not parse base class of PolarDiagram.";
1006
} else if( tagName == "ZeroDegreePosition" ) {
1008
if( KDXML::readIntNode( element, i ) ){
1009
diagram.setZeroDegreePosition( i );
1011
qDebug()<< "Could not parse PolarDiagram. Element"
1012
<< tagName << "has invalid content.";
1014
} else if( tagName == "RotateCircularLabels" ) {
1016
if( KDXML::readBoolNode( element, b ) ){
1017
diagram.setRotateCircularLabels( b );
1019
qDebug()<< "Could not parse PolarDiagram. Element"
1020
<< tagName << "has invalid content.";
1022
} else if( tagName == "CloseDatasets" ) {
1024
if( KDXML::readBoolNode( element, b ) ){
1025
diagram.setCloseDatasets( b );
1027
qDebug()<< "Could not parse PolarDiagram. Element"
1028
<< tagName << "has invalid content.";
1030
} else if( tagName == "ShowDelimitersAtPosition" ) {
1031
bool unknown = false;
1032
bool center = false;
1033
bool northWest = false;
1035
bool northEast = false;
1037
bool southEast = false;
1039
bool southWest = false;
1041
bool floating = false;
1042
if( KDXML::readPositionBooleansNode(
1045
northWest, north, northEast,
1046
east, southEast, south, southWest, west,
1049
diagram.setShowDelimitersAtPosition( Position::Unknown, unknown );
1050
diagram.setShowDelimitersAtPosition( Position::Center, center );
1051
diagram.setShowDelimitersAtPosition( Position::NorthWest,northWest );
1052
diagram.setShowDelimitersAtPosition( Position::North, north );
1053
diagram.setShowDelimitersAtPosition( Position::NorthEast,northEast );
1054
diagram.setShowDelimitersAtPosition( Position::East, east );
1055
diagram.setShowDelimitersAtPosition( Position::SouthEast,southEast );
1056
diagram.setShowDelimitersAtPosition( Position::South, south );
1057
diagram.setShowDelimitersAtPosition( Position::SouthWest,southWest );
1058
diagram.setShowDelimitersAtPosition( Position::West, west );
1059
diagram.setShowDelimitersAtPosition( Position::Floating, floating );
1061
qDebug()<< "Could not parse PolarDiagram. Element"
1062
<< tagName << "has invalid content.";
1064
} else if( tagName == "ShowLabelsAtPosition" ) {
1065
bool unknown = false;
1066
bool center = false;
1067
bool northWest = false;
1069
bool northEast = false;
1071
bool southEast = false;
1073
bool southWest = false;
1075
bool floating = false;
1076
if( KDXML::readPositionBooleansNode(
1079
northWest, north, northEast,
1080
east, southEast, south, southWest, west,
1083
diagram.setShowLabelsAtPosition( Position::Unknown, unknown );
1084
diagram.setShowLabelsAtPosition( Position::Center, center );
1085
diagram.setShowLabelsAtPosition( Position::NorthWest,northWest );
1086
diagram.setShowLabelsAtPosition( Position::North, north );
1087
diagram.setShowLabelsAtPosition( Position::NorthEast,northEast );
1088
diagram.setShowLabelsAtPosition( Position::East, east );
1089
diagram.setShowLabelsAtPosition( Position::SouthEast,southEast );
1090
diagram.setShowLabelsAtPosition( Position::South, south );
1091
diagram.setShowLabelsAtPosition( Position::SouthWest,southWest );
1092
diagram.setShowLabelsAtPosition( Position::West, west );
1093
diagram.setShowLabelsAtPosition( Position::Floating, floating );
1095
qDebug()<< "Could not parse PolarDiagram. Element"
1096
<< tagName << "has invalid content.";
1099
qDebug() << "Unknown subelement of PolarDiagram found:" << tagName;
1103
node = node.nextSibling();
1109
void DiagramsSerializer::Private::savePolarDiagram(
1111
QDomElement& diagElement,
1112
const PolarDiagram& diagram )const
1114
// first save the information hold by the base class
1115
savePolCoordDiagram( doc, diagElement, diagram,
1116
"kdchart:polar-coordinate-diagram" );
1118
// then save what is stored in the derived class
1119
KDXML::createIntNode( doc, diagElement, "ZeroDegreePosition", diagram.zeroDegreePosition() );
1120
KDXML::createBoolNode( doc, diagElement, "RotateCircularLabels", diagram.rotateCircularLabels() );
1121
KDXML::createBoolNode( doc, diagElement, "CloseDatasets", diagram.closeDatasets() );
1122
KDXML::createPositionBooleansNode(
1123
doc, diagElement, "ShowDelimitersAtPosition",
1124
diagram.showDelimitersAtPosition( Position::Unknown ),
1125
diagram.showDelimitersAtPosition( Position::Center ),
1126
diagram.showDelimitersAtPosition( Position::NorthWest ),
1127
diagram.showDelimitersAtPosition( Position::North ),
1128
diagram.showDelimitersAtPosition( Position::NorthEast ),
1129
diagram.showDelimitersAtPosition( Position::East ),
1130
diagram.showDelimitersAtPosition( Position::SouthEast ),
1131
diagram.showDelimitersAtPosition( Position::South ),
1132
diagram.showDelimitersAtPosition( Position::SouthWest ),
1133
diagram.showDelimitersAtPosition( Position::West ),
1134
diagram.showDelimitersAtPosition( Position::Floating ) );
1135
KDXML::createPositionBooleansNode(
1136
doc, diagElement, "ShowLabelsAtPosition",
1137
diagram.showLabelsAtPosition( Position::Unknown ),
1138
diagram.showLabelsAtPosition( Position::Center ),
1139
diagram.showLabelsAtPosition( Position::NorthWest ),
1140
diagram.showLabelsAtPosition( Position::North ),
1141
diagram.showLabelsAtPosition( Position::NorthEast ),
1142
diagram.showLabelsAtPosition( Position::East ),
1143
diagram.showLabelsAtPosition( Position::SouthEast ),
1144
diagram.showLabelsAtPosition( Position::South ),
1145
diagram.showLabelsAtPosition( Position::SouthWest ),
1146
diagram.showLabelsAtPosition( Position::West ),
1147
diagram.showLabelsAtPosition( Position::Floating ) );
1150
bool DiagramsSerializer::Private::parseRingDiagram(
1151
const QDomElement& container, RingDiagram& diagram )const
1154
if( !container.isNull() ) {
1155
//qDebug() << "\n DiagramsSerializer::parseRingDiagram() processing" << diagName;
1156
QDomNode node = container.firstChild();
1157
while( !node.isNull() ) {
1158
QDomElement element = node.toElement();
1159
if( !element.isNull() ) { // was really an element
1160
QString tagName = element.tagName();
1161
if( tagName == "kdchart:abstract-pie-diagram" ) {
1162
if( ! parseAbstractPieDiagram( element, diagram ) ){
1163
qDebug() << "Could not parse base class of RingDiagram.";
1166
} else if( tagName == "RelativeThickness" ) {
1168
if( KDXML::readBoolNode( element, b ) ){
1169
diagram.setRelativeThickness( b );
1171
qDebug()<< "Could not parse RingDiagram. Element"
1172
<< tagName << "has invalid content.";
1175
qDebug() << "Unknown subelement of RingDiagram found:" << tagName;
1179
node = node.nextSibling();
1185
void DiagramsSerializer::Private::saveRingDiagram(
1187
QDomElement& diagElement,
1188
const RingDiagram& diagram )const
1190
// first save the information hold by the base class
1191
saveAbstractPieDiagram( doc, diagElement, diagram,
1192
"kdchart:abstract-pie-diagram" );
1194
// then save what is stored in the derived class
1195
KDXML::createBoolNode( doc, diagElement, "RelativeThickness", diagram.relativeThickness() );
1198
void DiagramsSerializer::Private::saveQtProperties(
1201
const AbstractDiagram& diagram ) const
1202
{ // this function saves all properties of a QObject that are in the
1203
// white list, creating a element for the properties and one child
1204
// element per property
1205
static const QStringList SerializedPropertyWhiteList
1206
( QStringList() << "frameStyle" << "lineWidth" << "midLineWidth" );
1208
QDomElement element = doc.createElement( TagNameQtProperties );
1209
e.appendChild( element );
1210
for ( int i = 0; i < diagram.metaObject()->propertyCount(); ++i ) {
1211
QMetaProperty p = diagram.metaObject()->property( i );
1212
if ( SerializedPropertyWhiteList.contains( p.name() ) ) {
1213
QVariant value = diagram.property( p.name() );
1214
KDXML::createQVariantNode( doc, element, p.name(), value );
1219
bool DiagramsSerializer::Private::parseQtProperties(
1220
const QDomElement& container,
1221
AbstractDiagram& diagram ) const
1224
QDomNodeList elements = container.elementsByTagName( "properties" );
1225
if ( elements.size() != 1 ) {
1226
qDebug() << "DiagramsSerializer::Private::parseQtProperties: XML syntax error, more than one properties elements";
1229
if ( elements.size() > 0 ) {
1230
QDomElement properties = elements.at(0).toElement();
1232
QDomNode n = properties.firstChild();
1233
while ( !n.isNull() ) {
1234
QDomElement e = n.toElement();
1235
if ( !e.isNull() ) {
1238
if ( ! KDXML::readQVariantNode( e, value, name ) ) {
1239
qDebug() << "DiagramsSerializer::Private::parseQtProperties: error parsing property" << e.tagName();
1242
diagram.setProperty( qPrintable( name ), value );
1245
n = n.nextSibling();