00001
00006 #include <float.h>
00007
00008
00009 #include <iostream>
00010 using std::cout;
00011 using std::cerr;
00012
00013 #include "kchart_part.h"
00014 #include "kchart_view.h"
00015 #include "kchart_factory.h"
00016 #include "kchartWizard.h"
00017 #include "kchart_params.h"
00018 #include "kdchart/KDChart.h"
00019 #include "kdchart/KDChartTable.h"
00020
00021 #include <KoTemplateChooseDia.h>
00022 #include <KoDom.h>
00023 #include <KoXmlNS.h>
00024 #include <KoXmlWriter.h>
00025 #include <KoOasisStore.h>
00026 #include <KoOasisLoadingContext.h>
00027
00028 #include <kstandarddirs.h>
00029 #include <kglobal.h>
00030 #include <kdebug.h>
00031
00032 #include <qdom.h>
00033 #include <qtextstream.h>
00034 #include <qbuffer.h>
00035 #include <qpainter.h>
00036
00037 using namespace std;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 namespace KChart
00051 {
00052
00053 KChartPart::KChartPart( QWidget *parentWidget, const char *widgetName,
00054 QObject* parent, const char* name,
00055 bool singleViewMode )
00056 : KoChart::Part( parentWidget, widgetName, parent, name, singleViewMode ),
00057 m_params( 0 ),
00058 m_parentWidget( parentWidget ),
00059 m_rowLabels(), m_colLabels()
00060 {
00061 kdDebug(35001) << "Constructor started!" << endl;
00062
00063 setInstance( KChartFactory::global(), false );
00064 setTemplateType( "kchart_template" );
00065
00066
00067 {
00068
00069
00070 m_params = new KChartParams( this );
00071 m_params->setChartType( KChartParams::Bar );
00072 m_params->setBarChartSubType( KChartParams::BarNormal );
00073 m_params->setThreeDBars( true );
00074
00075
00076
00077
00078
00079
00080
00081
00082 m_params->setDataDirection( KChartParams::DataColumns );
00083 }
00084
00085 (void)new WizardExt( this );
00086 m_bCanChangeValue = true;
00087
00088
00089 m_displayData = m_currentData;
00090
00091
00092 initEmpty();
00093 }
00094
00095
00096 KChartPart::~KChartPart()
00097 {
00098
00099 delete m_params;
00100 }
00101
00102
00103
00104
00105 bool KChartPart::initDoc(InitDocFlags flags, QWidget* parentWidget)
00106 {
00107
00108 #if 0
00109 kdDebug(35001) << "================================================================" << endl;
00110 kdDebug(35001) << "InitDOC: flags = " << flags << endl;
00111 kdDebug(35001) << "================================================================" << endl;
00112 #endif
00113
00114 QString f;
00115
00116
00117
00118
00119
00120 if (flags == KoDocument::InitDocEmbedded) {
00121 initEmpty();
00122 return true;
00123 }
00124
00125
00126 if (flags == KoDocument::InitDocEmpty) {
00127 initEmpty();
00128 return true;
00129 }
00130
00131 KoTemplateChooseDia::ReturnType ret;
00132 KoTemplateChooseDia::DialogType dlgtype;
00133
00134
00135
00136
00137 if (flags == KoDocument::InitDocFileNew )
00138 dlgtype = KoTemplateChooseDia::OnlyTemplates;
00139 else
00140 dlgtype = KoTemplateChooseDia::Everything;
00141 ret = KoTemplateChooseDia::choose( KChartFactory::global(), f,
00142 dlgtype, "kchart_template",
00143 parentWidget );
00144
00145 if ( ret == KoTemplateChooseDia::File ) {
00146 KURL url( f );
00147 return openURL( url );
00148 }
00149 else if ( ret == KoTemplateChooseDia::Empty ) {
00150 initEmpty();
00151 return true;
00152 }
00153 else if ( ret == KoTemplateChooseDia::Template ) {
00154
00155
00156
00157
00158
00159 QFileInfo fileInfo( f );
00160 QString fileName( fileInfo.dirPath( true ) + "/" +
00161 fileInfo.baseName() + ".chrt" );
00162
00163 resetURL();
00164 bool ok = loadNativeFormat( fileName );
00165 if ( !ok )
00166 showLoadingErrorDialog();
00167 setEmpty();
00168
00169 return ok;
00170 }
00171
00172 return false;
00173 }
00174
00175 void KChartPart::initEmpty()
00176 {
00177 initNullChart();
00178
00179 resetURL();
00180 setEmpty();
00181 }
00182
00183
00184
00185
00186
00187 void KChartPart::initNullChart()
00188 {
00189
00190
00191
00192
00193
00194 m_currentData.expand(2, 2);
00195 m_params->setFirstRowAsLabel(false);
00196 m_params->setFirstColAsLabel(false);
00197
00198
00199 m_colLabels << QString("");
00200 m_rowLabels << QString("");
00201
00202 setChartDefaults();
00203
00204 m_params->setDrawSolidExcessArrows(true);
00205 }
00206
00207
00208 void KChartPart::generateBarChartTemplate()
00209 {
00210 int col;
00211 int row;
00212
00213 kdDebug()<<"KChartPart::initTestChart()\n";
00214
00215
00216 if (m_currentData.rows() == 0) {
00217
00218 m_currentData.expand( 4, 4 );
00219 m_currentData.setUsedRows( 4 );
00220 m_currentData.setUsedCols( 4 );
00221 for (row = 0; row < 4; row++) {
00222 for (col = 0; col < 4; col++) {
00223 m_currentData.setCell(row, col,
00224 static_cast <double> (row + col));
00225
00226
00227 if (row == 0) {
00228 m_colLabels << i18n("Column %1").arg(col + 1);
00229 }
00230 }
00231
00232
00233 m_rowLabels << i18n("Row %1").arg(row + 1);
00234 }
00235 }
00236
00237 setChartDefaults();
00238
00239 m_params->setDrawSolidExcessArrows(true);
00240 }
00241
00242
00243 KoView* KChartPart::createViewInstance( QWidget* parent, const char* name )
00244 {
00245 return new KChartView( this, parent, name );
00246 }
00247
00248
00249
00250
00251
00252
00253 void KChartPart::paintContent( QPainter& painter, const QRect& rect,
00254 bool ,
00255 double , double )
00256 {
00257 int numDatasets;
00258
00259
00260 Q_ASSERT( m_params != 0 );
00261
00262 KDChartAxisParams xAxisParms;
00263 xAxisParms = m_params->axisParams( KDChartAxisParams::AxisPosBottom );
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 numDatasets = createDisplayData();
00275
00276
00277 QStringList longLabels;
00278 QStringList shortLabels;
00279 createLabelsAndLegend(longLabels, shortLabels);
00280
00281
00282 xAxisParms.setAxisLabelStringLists( &longLabels, &shortLabels );
00283 m_params->setAxisParams(KDChartAxisParams::AxisPosBottom, xAxisParms);
00284
00285
00286
00287
00288
00289 if ( m_params->chartType() == KChartParams::Bar) {
00290 if ( m_params->barNumLines() > 0 ) {
00291
00292
00293
00294
00295
00296
00297 m_params->setAdditionalChartType( KDChartParams::Line );
00298
00299 const int numBarDatasets = numDatasets - m_params->barNumLines();
00300
00301
00302 m_params->setChartSourceMode( KDChartParams::DataEntry,
00303 0, numBarDatasets - 1,
00304 0 );
00305 m_params->setChartSourceMode( KDChartParams::DataEntry,
00306 numBarDatasets, numDatasets - 1,
00307 1 );
00308 }
00309 else {
00310
00311 m_params->setAdditionalChartType( KDChartParams::NoType );
00312 }
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 if ( m_bufferPixmap.width() < rect.width()
00327 || m_bufferPixmap.height() < rect.height() )
00328 {
00329 m_bufferPixmap.resize( rect.size() );
00330 }
00331
00332 QPainter bufferPainter( &m_bufferPixmap );
00333
00334
00335 KDChart::paint( &bufferPainter, m_params, &m_displayData, 0, &rect );
00336
00337
00338
00339
00340
00341
00342
00343 painter.drawPixmap( 0, 0, m_bufferPixmap );
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 int KChartPart::createDisplayData()
00364 {
00365 int rowOffset = 0;
00366 int colOffset = 0;
00367 int numDatasets = 0;
00368
00369 if ( !canChangeValue() ) {
00370 if ( m_params->firstRowAsLabel() )
00371 rowOffset++;
00372 if ( m_params->firstColAsLabel() )
00373 colOffset++;
00374 }
00375
00376
00377
00378
00379 QVariant value1;
00380 QVariant value2;
00381 int prop;
00382 if (m_params->dataDirection() == KChartParams::DataRows) {
00383
00384
00385 numDatasets = m_currentData.usedRows() - rowOffset;
00386 m_displayData.expand( numDatasets,
00387 m_currentData.usedCols() - colOffset );
00388
00389
00390 for (uint row = rowOffset; row < m_currentData.usedRows(); row++) {
00391 for (uint col = colOffset; col < m_currentData.usedCols(); col++) {
00392 if ( m_currentData.cellContent( row, col,
00393 value1, value2, prop ) ) {
00394 m_displayData.setCell(row - rowOffset, col - colOffset,
00395 value1, value2);
00396 m_displayData.setProp(row - rowOffset, col - colOffset,
00397 prop);
00398 }
00399 }
00400 }
00401 }
00402 else {
00403
00404
00405
00406
00407 numDatasets = m_currentData.usedCols() - colOffset;
00408 m_displayData.expand( numDatasets,
00409 m_currentData.usedRows() - rowOffset );
00410
00411
00412 for (uint row = colOffset; row < m_currentData.usedCols(); row++) {
00413 for (uint col = rowOffset; col < m_currentData.usedRows(); col++) {
00414 if ( m_currentData.cellContent( col, row,
00415 value1, value2, prop ) ) {
00416 m_displayData.setCell(row - colOffset, col - rowOffset,
00417 value1, value2);
00418 m_displayData.setProp(row - colOffset, col - rowOffset,
00419 prop);
00420 }
00421 }
00422 }
00423 }
00424
00425
00426
00427
00428
00429
00430 if (m_params->chartType() == KChartParams::HiLo) {
00431 KDChartTableData tmpData = m_displayData;
00432
00433
00434 m_displayData.expand(tmpData.usedRows(), 4);
00435 for (uint row = 0; row < tmpData.usedRows(); row++) {
00436 double minVal = DBL_MAX;
00437 double maxVal = -DBL_MAX;
00438
00439
00440
00441
00442
00443 for (uint col = 0; col < tmpData.usedCols(); col++) {
00444 double data = tmpData.cellVal(row, col).toDouble();
00445
00446 if (data < minVal)
00447 minVal = data;
00448 if (data > maxVal)
00449 maxVal = data;
00450 }
00451 m_displayData.setCell(row, 0, minVal);
00452 m_displayData.setCell(row, 1, maxVal);
00453 m_displayData.setCell(row, 2, tmpData.cellVal(row, 0).toDouble());
00454 m_displayData.setCell(row, 3,
00455 tmpData.cellVal(row, tmpData.usedCols() - 1).toDouble());
00456 }
00457 }
00458
00459 return numDatasets;
00460 }
00461
00462
00463 void KChartPart::createLabelsAndLegend( QStringList &longLabels,
00464 QStringList &shortLabels )
00465 {
00466 longLabels.clear();
00467 shortLabels.clear();
00468
00469 const uint dataColumnCount = m_currentData.cols();
00470 const uint dataRowCount = m_currentData.rows();
00471 const uint columnLabelCount = m_colLabels.count();
00472 const uint rowLabelCount = m_rowLabels.count();
00473
00474
00475 if (m_params->chartType() == KChartParams::HiLo) {
00476
00477
00478
00479
00480
00481 longLabels.clear();
00482 shortLabels.clear();
00483 if (m_params->dataDirection() == KChartParams::DataRows) {
00484
00485
00486
00487 for ( uint row = 0; row < dataRowCount ; row++ ) {
00488
00489 QString label = (row < rowLabelCount) ? m_rowLabels[row] : QString::null;
00490
00491 longLabels << label;
00492 shortLabels << label.left( 3 );
00493 }
00494 }
00495 else {
00496
00497
00498 for ( uint col = 0; col < dataColumnCount; col++ ) {
00499
00500 QString label = (col < columnLabelCount) ? m_colLabels[col] : QString::null;
00501
00502 longLabels << m_colLabels[col];
00503 shortLabels << m_colLabels[col].left( 3 );
00504 }
00505 }
00506 }
00507 else if (m_params->dataDirection() == KChartParams::DataRows) {
00508
00509
00510
00511 for ( uint col = 0; col < dataColumnCount; col++ ) {
00512
00513 QString label = (col < columnLabelCount) ? m_colLabels[col] : QString::null;
00514
00515 longLabels << label;
00516 shortLabels << label.left( 3 );
00517 }
00518
00519
00520 for ( uint row = 0; row < dataRowCount; row++ ) {
00521 QString label = (row < rowLabelCount) ? m_rowLabels[row] : QString::null;
00522
00523 m_params->setLegendText( row, label );
00524 }
00525 }
00526 else {
00527
00528
00529
00530 for ( uint row = 0; row < dataRowCount; row++ ) {
00531
00532 QString label = (row < rowLabelCount) ? m_rowLabels[row] : QString::null;
00533
00534 longLabels << label;
00535 shortLabels << label.left( 3 );
00536 }
00537
00538
00539 for ( uint col = 0; col < dataColumnCount ; col++ ) {
00540 QString label = (col < columnLabelCount) ? m_colLabels[col] : QString::null;
00541
00542 m_params->setLegendText( col, label );
00543 }
00544 }
00545 }
00546
00547
00548
00549
00550
00551
00552 void KChartPart::analyzeHeaders()
00553 {
00554 #if 0
00555 analyzeHeaders( m_currentData );
00556 #else
00557 doSetData( m_currentData,
00558 m_params->firstRowAsLabel(), m_params->firstColAsLabel());
00559 #endif
00560 }
00561
00562
00563
00564
00565
00566
00567 void KChartPart::analyzeHeaders( const KDChartTableData& data )
00568 {
00569
00570
00571 bool isStringTopLeft = (data.cellVal( 0, 0 ).type() == QVariant::String);
00572
00573
00574 bool isStringFirstRow = true;
00575 for ( uint col = 1; isStringFirstRow && col < data.cols(); col++ ) {
00576 isStringFirstRow = (data.cellVal( 0, col ).type() == QVariant::String);
00577 }
00578
00579
00580
00581
00582
00583
00584 #if 1
00585 if ( data.rows() == 1 )
00586 isStringFirstRow = false;
00587 #endif
00588
00589
00590 bool isStringFirstCol = true;
00591 for ( uint row = 1; isStringFirstCol && row < data.rows(); row++ ) {
00592 isStringFirstCol = (data.cellVal( row, 0 ).type() == QVariant::String);
00593 }
00594
00595
00596
00597 #if 1
00598 if ( data.cols() == 1 )
00599 isStringFirstRow = FALSE;
00600 #endif
00601
00602 bool hasColHeader = false;
00603 bool hasRowHeader = false;
00604
00605
00606 if ( isStringFirstCol && isStringTopLeft
00607 || isStringFirstCol && isStringFirstRow )
00608 hasColHeader = true;
00609
00610
00611 if ( isStringFirstRow && isStringTopLeft
00612 || isStringFirstCol && isStringFirstRow )
00613 hasRowHeader = true;
00614
00615 m_params->setFirstRowAsLabel( hasRowHeader );
00616 m_params->setFirstColAsLabel( hasColHeader );
00617
00618 doSetData(data, hasRowHeader, hasColHeader);
00619 }
00620
00621
00622
00623 void KChartPart::doSetData( const KDChartTableData& data,
00624 bool firstRowHeader,
00625 bool firstColHeader )
00626 {
00627 uint rowStart = 0;
00628 uint colStart = 0;
00629 uint col;
00630 uint row;
00631
00632
00633
00634
00635
00636 if (firstRowHeader)
00637 rowStart = 1;
00638 if (firstColHeader)
00639 colStart = 1;
00640
00641
00642 m_rowLabels.clear();
00643 if ( firstColHeader ) {
00644 for( row = rowStart; row < data.rows(); row++ ) {
00645 m_rowLabels << data.cellVal( row, 0 ).toString();
00646 }
00647 }
00648 else {
00649 for( row = rowStart; row < data.rows(); row++ )
00650 m_rowLabels << "";
00651
00652
00653
00654 m_params->setLegendSource( KDChartParams::LegendAutomatic );
00655 }
00656
00657
00658 m_colLabels.clear();
00659 if ( firstRowHeader ) {
00660 for( col = colStart; col < data.cols(); col++ ) {
00661 m_colLabels << data.cellVal( 0, col ).toString();
00662 }
00663 }
00664 else {
00665 for( col = colStart; col < data.cols(); col++ )
00666 m_colLabels << "";
00667 }
00668
00669
00670 m_currentData = data;
00671
00672
00673
00674 emit docChanged();
00675 }
00676
00677
00678 void KChartPart::resizeData( int rows, int cols )
00679 {
00680 m_currentData.expand( rows, cols );
00681 m_currentData.setUsedRows( rows );
00682 m_currentData.setUsedCols( cols );
00683 }
00684
00685
00686 void KChartPart::setCellData( int row, int column, const QVariant &val)
00687 {
00688 m_currentData.setCell( row, column, val );
00689 }
00690
00691
00692 bool KChartPart::showWizard( QString &dataArea )
00693 {
00694 KChartWizard *wizard = new KChartWizard( this, m_parentWidget, "wizard" );
00695
00696 connect( wizard, SIGNAL(finished()), this, SLOT(slotModified()) );
00697
00698 wizard->setDataArea( dataArea );
00699
00700 bool ret = wizard->exec();
00701
00702 delete wizard;
00703 return ret;
00704 }
00705
00706
00707 void KChartPart::initLabelAndLegend()
00708 {
00709
00710
00711 }
00712
00713
00714
00715
00716
00717
00718 void KChartPart::setChartDefaults()
00719 {
00720
00721
00722
00723 KDChartAxisParams yAxis;
00724 yAxis = m_params->axisParams( KDChartAxisParams::AxisPosLeft );
00725
00726
00727 yAxis.setAxisLabelsRadix( KGlobal::locale()->decimalSymbol(),
00728 KGlobal::locale()->thousandsSeparator() );
00729
00730 m_params->setAxisParams( KDChartAxisParams::AxisPosLeft, yAxis );
00731
00732
00733
00734
00735 KDChartAxisParams xAxis;
00736 xAxis = m_params->axisParams( KDChartAxisParams::AxisPosBottom );
00737
00738
00739 xAxis.setAxisFirstLabelText();
00740 xAxis.setAxisLastLabelText();
00741
00742 m_params->setAxisParams( KDChartAxisParams::AxisPosBottom, xAxis );
00743
00744
00745 m_params->setLineColor();
00746
00747
00748 KDFrame frame;
00749 frame.setBackground( QBrush( QColor( 230, 222, 222 ) ) );
00750 m_params->setFrame( KDChartEnums::AreaInnermost, frame, 0, 0, 0, 0 );
00751 }
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 void KChartPart::loadConfig( KConfig *conf )
00764 {
00765 conf->setGroup("ChartParameters");
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 m_params->setLineMarker(conf->readBoolEntry("lineMarker",
00802 m_params->lineMarker()));
00803 m_params->setThreeDBarDepth( conf->readDoubleNumEntry("_3d_depth",
00804 m_params->threeDBarDepth() ) );
00805 m_params->setThreeDBarAngle( conf->readNumEntry( "_3d_angle",
00806 m_params->threeDBarAngle() ) );
00807
00808 KDChartAxisParams leftparams;
00809 leftparams = m_params->axisParams( KDChartAxisParams::AxisPosLeft );
00810 KDChartAxisParams rightparams;
00811 rightparams = m_params->axisParams( KDChartAxisParams::AxisPosRight );
00812 KDChartAxisParams bottomparams;
00813 bottomparams = m_params->axisParams( KDChartAxisParams::AxisPosBottom );
00814
00815 bottomparams.setAxisLineColor( conf->readColorEntry( "XTitleColor", 0 ) );
00816 leftparams.setAxisLineColor( conf->readColorEntry( "YTitleColor", 0 ) );
00817 rightparams.setAxisLineColor( conf->readColorEntry( "YTitle2Color", 0 ) );
00818 bottomparams.setAxisLabelsColor( conf->readColorEntry( "XLabelColor", 0 ) );
00819 leftparams.setAxisLabelsColor( conf->readColorEntry( "YLabelColor", 0 ) );
00820 rightparams.setAxisLabelsColor( conf->readColorEntry( "YLabel2Color", 0 ) );
00821 leftparams.setAxisGridColor( conf->readColorEntry( "GridColor", 0 ) );
00822 m_params->setOutlineDataColor( conf->readColorEntry( "LineColor", 0 ) );
00823 m_params->setAxisParams( KDChartAxisParams::AxisPosLeft,
00824 leftparams );
00825 m_params->setAxisParams( KDChartAxisParams::AxisPosRight,
00826 rightparams );
00827 m_params->setAxisParams( KDChartAxisParams::AxisPosBottom,
00828 bottomparams );
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 m_params->setChartType( (KChartParams::ChartType)conf->readNumEntry( "type", m_params->chartType() ) );
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 }
00864
00865
00866 void KChartPart::defaultConfig( )
00867 {
00868 delete m_params;
00869 m_params = new KChartParams( this );
00870 setChartDefaults();
00871 }
00872
00873
00874 void KChartPart::saveConfig( KConfig *conf )
00875 {
00876 conf->setGroup("ChartParameters");
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 conf->writeEntry( "_3d_depth", m_params->threeDBarDepth() );
00905 conf->writeEntry( "_3d_angle", m_params->threeDBarAngle() );
00906
00907 KDChartAxisParams leftparams;
00908 leftparams = m_params->axisParams( KDChartAxisParams::AxisPosLeft );
00909 KDChartAxisParams rightparams;
00910 rightparams = m_params->axisParams( KDChartAxisParams::AxisPosRight );
00911 KDChartAxisParams bottomparams;
00912 bottomparams = m_params->axisParams( KDChartAxisParams::AxisPosBottom );
00913 conf->writeEntry( "LineColor", m_params->outlineDataColor() );
00914 conf->writeEntry( "XTitleColor", bottomparams.axisLineColor() );
00915 conf->writeEntry( "YTitleColor", leftparams.axisLineColor() );
00916 conf->writeEntry( "YTitle2Color", rightparams.axisLineColor() );
00917 conf->writeEntry( "XLabelColor", bottomparams.axisLabelsColor() );
00918 conf->writeEntry( "YLabelColor", leftparams.axisLabelsColor() );
00919 conf->writeEntry( "YLabel2Color", rightparams.axisLabelsColor() );
00920 conf->writeEntry( "GridColor", leftparams.axisGridColor() );
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 conf->writeEntry( "type", (int) m_params->chartType() );
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956 conf->writeEntry( "lineMarker", (int) m_params->lineMarker());
00957 }
00958
00959
00960
00961
00962
00963
00964 bool KChartPart::loadOasis( const QDomDocument& doc,
00965 KoOasisStyles& oasisStyles,
00966 const QDomDocument& ,
00967 KoStore *store )
00968 {
00969 kdDebug(35001) << "kchart loadOasis called" << endl;
00970
00971
00972 setChartDefaults();
00973
00974 QDomElement content = doc.documentElement();
00975 QDomElement bodyElem ( KoDom::namedItemNS( content,
00976 KoXmlNS::office, "body" ) );
00977 if ( bodyElem.isNull() ) {
00978 kdError(32001) << "No office:body found!" << endl;
00979 setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No office:body tag found." ) );
00980 return false;
00981 }
00982
00983
00984 QDomElement officeChartElem = KoDom::namedItemNS( bodyElem,
00985 KoXmlNS::office, "chart" );
00986 if ( officeChartElem.isNull() ) {
00987 kdError(32001) << "No office:chart found!" << endl;
00988 QDomElement childElem;
00989 QString localName;
00990 forEachElement( childElem, bodyElem ) {
00991 localName = childElem.localName();
00992 }
00993
00994 if ( localName.isEmpty() )
00995 setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No tag found inside office:body." ) );
00996 else
00997 setErrorMessage( i18n( "This document is not a chart, but %1. Please try opening it with the appropriate application." ).arg( KoDocument::tagNameToDocumentType( localName ) ) );
00998
00999 return false;
01000 }
01001
01002 QDomElement chartElem = KoDom::namedItemNS( officeChartElem,
01003 KoXmlNS::chart, "chart" );
01004 if ( chartElem.isNull() ) {
01005 setErrorMessage( i18n( "Invalid OASIS OpenDocument file. No chart:chart tag found." ) );
01006 return false;
01007 }
01008
01009
01010 KoOasisLoadingContext loadingContext( this, oasisStyles, store );
01011
01012
01013 #if 0 // Example code!!
01014
01015 styleStack.save();
01016 styleStack.setTypeProperties( "chart" );
01017 loadingContext.fillStyleStack( chartElem, KoXmlNS::chart, "style-name" );
01018
01019 const QString fillColor = styleStack.attributeNS( KoXmlNS::draw, "fill-color" );
01020 kdDebug() << "fillColor=" << fillColor << endl;
01021
01022 styleStack.restore();
01023 #endif
01024
01025
01026
01027 QString errorMessage;
01028 bool ok = m_params->loadOasis( chartElem, loadingContext, errorMessage,
01029 store);
01030 if ( !ok ) {
01031 setErrorMessage( errorMessage );
01032 return false;
01033 }
01034
01035
01036
01037
01038 QDomElement tableElem = KoDom::namedItemNS( chartElem,
01039 KoXmlNS::table, "table" );
01040 if ( !tableElem.isNull() ) {
01041 ok = loadOasisData( tableElem );
01042 if ( !ok )
01043 return false;
01044 }
01045
01046 return true;
01047 }
01048
01049
01050 bool KChartPart::loadOasisData( const QDomElement& tableElem )
01051 {
01052 int numberHeaderColumns = 0;
01053 QDomElement tableHeaderColumns = KoDom::namedItemNS( tableElem,
01054 KoXmlNS::table,
01055 "table-header-columns" );
01056
01057 QDomElement elem;
01058 forEachElement( elem, tableHeaderColumns ) {
01059 if ( elem.localName() == "table-column" ) {
01060 int repeated = elem.attributeNS( KoXmlNS::table, "number-columns-repeated", QString::null ).toInt();
01061 numberHeaderColumns += QMAX( 1, repeated );
01062 }
01063 }
01064
01065
01066 Q_ASSERT( numberHeaderColumns == 1 );
01067
01068 int numberDataColumns = 0;
01069 QDomElement tableColumns = KoDom::namedItemNS( tableElem, KoXmlNS::table, "table-columns" );
01070 forEachElement( elem, tableColumns ) {
01071 if ( elem.localName() == "table-column" ) {
01072 int repeated = elem.attributeNS( KoXmlNS::table, "number-columns-repeated", QString::null ).toInt();
01073 numberDataColumns += QMAX( 1, repeated );
01074 }
01075 }
01076
01077
01078 m_colLabels.clear();
01079 QDomElement tableHeaderRows = KoDom::namedItemNS( tableElem, KoXmlNS::table, "table-header-rows" );
01080 if ( tableHeaderRows.isNull() )
01081 kdWarning(35001) << "No table-header-rows element found!" << endl;
01082 QDomElement tableHeaderRow = KoDom::namedItemNS( tableHeaderRows, KoXmlNS::table, "table-row" );
01083 if ( tableHeaderRow.isNull() )
01084 kdWarning(35001) << "No table-row inside table-header-rows!" << endl;
01085
01086 int cellNum = 0;
01087 forEachElement( elem, tableHeaderRow ) {
01088 if ( elem.localName() == "table-cell" ) {
01089 ++cellNum;
01090 if ( cellNum > numberHeaderColumns ) {
01091 QDomElement pElem = KoDom::namedItemNS( elem, KoXmlNS::text, "p" );
01092 m_colLabels.append( pElem.text() );
01093 }
01094 }
01095 }
01096 numberDataColumns = QMAX( numberDataColumns, cellNum - numberHeaderColumns );
01097 if ( (int)m_colLabels.count() != numberDataColumns )
01098 kdWarning(35001) << "Got " << m_colLabels.count()
01099 << " column titles, expected " << numberDataColumns
01100 << endl;
01101
01102
01103 int numberDataRows = 0;
01104 QDomElement tableRows = KoDom::namedItemNS( tableElem, KoXmlNS::table, "table-rows" );
01105
01106 m_rowLabels.clear();
01107 forEachElement( elem, tableRows ) {
01108 if ( elem.localName() == "table-row" ) {
01109 int repeated = elem.attributeNS( KoXmlNS::table, "number-rows-repeated", QString::null ).toInt();
01110 Q_ASSERT( repeated <= 1 );
01111 numberDataRows += QMAX( 1, repeated );
01112 if ( numberHeaderColumns > 0 ) {
01113 QDomElement firstCell = KoDom::namedItemNS( elem, KoXmlNS::table, "table-cell" );
01114 QDomElement pElem = KoDom::namedItemNS( firstCell, KoXmlNS::text, "p" );
01115 m_rowLabels.append( pElem.text() );
01116 }
01117 }
01118 }
01119
01120 kdDebug(35001) << "numberHeaderColumns=" << numberHeaderColumns
01121 << " numberDataColumns=" << numberDataColumns
01122 << " numberDataRows=" << numberDataRows << endl;
01123
01124 if ( (int)m_rowLabels.count() != numberDataRows)
01125 kdWarning(35001) << "Got " << m_rowLabels.count()
01126 << " row labels, expected " << numberDataRows << endl;
01127
01128 m_currentData.expand( numberDataRows, numberDataColumns );
01129 m_currentData.setUsedCols( numberDataColumns );
01130 m_currentData.setUsedRows( numberDataRows );
01131
01132
01133 int row = 0;
01134 QDomElement rowElem;
01135 forEachElement( rowElem, tableRows ) {
01136 if ( rowElem.localName() == "table-row" ) {
01137 int col = 0;
01138 int cellNum = 0;
01139 QDomElement cellElem;
01140 forEachElement( cellElem, rowElem ) {
01141 if ( cellElem.localName() == "table-cell" ) {
01142 ++cellNum;
01143 if ( cellNum > numberHeaderColumns ) {
01144 QString valueType = cellElem.attributeNS( KoXmlNS::office, "value-type", QString::null );
01145 if ( valueType != "float" )
01146 kdWarning(35001) << "Don't know how to handle value-type " << valueType << endl;
01147 else {
01148 QString value = cellElem.attributeNS( KoXmlNS::office, "value", QString::null );
01149 double val = value.toDouble();
01150
01151 m_currentData.setCell( row, col, val );
01152 }
01153 ++col;
01154 }
01155 }
01156 }
01157 ++row;
01158 }
01159 }
01160
01161 return true;
01162 }
01163
01164
01165 bool KChartPart::saveOasis( KoStore* store, KoXmlWriter* manifestWriter )
01166 {
01167 manifestWriter->addManifestEntry( "content.xml", "text/xml" );
01168 KoOasisStore oasisStore( store );
01169
01170 KoXmlWriter* contentWriter = oasisStore.contentWriter();
01171 if ( !contentWriter )
01172 return false;
01173
01174 KoGenStyles mainStyles;
01175
01176 KoXmlWriter* bodyWriter = oasisStore.bodyWriter();
01177 bodyWriter->startElement( "office:body" );
01178 bodyWriter->startElement( "office:chart" );
01179 bodyWriter->startElement( "chart:chart" );
01180
01181
01182 {
01183
01184 m_params->saveOasis( bodyWriter, mainStyles );
01185
01186
01187 saveOasisData( bodyWriter, mainStyles );
01188 }
01189
01190 bodyWriter->endElement();
01191 bodyWriter->endElement();
01192 bodyWriter->endElement();
01193
01194 contentWriter->startElement( "office:automatic-styles" );
01195 writeAutomaticStyles( *contentWriter, mainStyles );
01196 contentWriter->endElement();
01197
01198 oasisStore.closeContentWriter();
01199
01200
01201
01202 #if 0
01203 if ( !store->open( "styles.xml" ) )
01204 return false;
01205 manifestWriter->addManifestEntry( "styles.xml", "text/xml" );
01206 saveOasisDocumentStyles( store, mainStyles, savingContext, saveFlag,
01207 headerFooterContent );
01208 if ( !store->close() )
01209 return false;
01210 #endif
01211
01212 return true;
01213 }
01214
01215
01216 void KChartPart::saveOasisData( KoXmlWriter* bodyWriter,
01217 KoGenStyles& mainStyles ) const
01218 {
01219 Q_UNUSED( mainStyles );
01220
01221 const int cols = m_currentData.usedCols()
01222 ? QMIN(m_currentData.usedCols(), m_currentData.cols())
01223 : m_currentData.cols();
01224 const int rows = m_currentData.usedRows()
01225 ? QMIN(m_currentData.usedRows(), m_currentData.rows())
01226 : m_currentData.rows();
01227
01228 bodyWriter->startElement( "table:table" );
01229 bodyWriter->addAttribute( "table:name", "local-table" );
01230
01231
01232 bodyWriter->startElement( "table:table-header-columns" );
01233 bodyWriter->startElement( "table:table-column" );
01234 bodyWriter->endElement();
01235 bodyWriter->endElement();
01236
01237
01238 bodyWriter->startElement( "table:table-columns" );
01239 bodyWriter->startElement( "table:table-column" );
01240 bodyWriter->addAttribute( "table:number-columns-repeated", cols );
01241 bodyWriter->endElement();
01242 bodyWriter->endElement();
01243
01244
01245 bodyWriter->startElement( "table:table-header-rows" );
01246 bodyWriter->startElement( "table:table-row" );
01247
01248
01249 bodyWriter->startElement( "table:table-cell" );
01250 bodyWriter->addAttribute( "office:value-type", "string" );
01251 bodyWriter->startElement( "text:p" );
01252 bodyWriter->endElement();
01253 bodyWriter->endElement();
01254
01255
01256
01257
01258
01259 QStringList::const_iterator colLabelIt = m_colLabels.begin();
01260 for ( int col = 0; col < cols ; ++col ) {
01261 if ( colLabelIt != m_colLabels.end() ) {
01262 bodyWriter->startElement( "table:table-cell" );
01263 bodyWriter->addAttribute( "office:value-type", "string" );
01264 bodyWriter->startElement( "text:p" );
01265 bodyWriter->addTextNode( *colLabelIt );
01266 bodyWriter->endElement();
01267 bodyWriter->endElement();
01268 ++colLabelIt;
01269 }
01270 }
01271
01272 bodyWriter->endElement();
01273 bodyWriter->endElement();
01274 bodyWriter->startElement( "table:table-rows" );
01275
01276 QStringList::const_iterator rowLabelIt = m_rowLabels.begin();
01277 for ( int row = 0; row < rows ; ++row ) {
01278 bodyWriter->startElement( "table:table-row" );
01279
01280 if ( rowLabelIt != m_rowLabels.end() ) {
01281
01282 bodyWriter->startElement( "table:table-cell" );
01283 bodyWriter->addAttribute( "office:value-type", "string" );
01284
01285 bodyWriter->startElement( "text:p" );
01286 bodyWriter->addTextNode( *rowLabelIt );
01287 bodyWriter->endElement();
01288
01289 bodyWriter->endElement();
01290 ++rowLabelIt;
01291 }
01292
01293 for ( int col = 0; col < cols; ++col ) {
01294 QVariant value( m_currentData.cellVal( row, col ) );
01295 QString valType;
01296 QString valStr;
01297
01298 switch ( value.type() ) {
01299 case QVariant::Invalid:
01300 break;
01301 case QVariant::String:
01302 valType = "string";
01303 valStr = value.toString();
01304 break;
01305 case QVariant::Double:
01306 valType = "float";
01307 valStr = QString::number( value.toDouble(), 'g', DBL_DIG );
01308 break;
01309 case QVariant::DateTime:
01310 valType = "date";
01311 valStr = "";
01312 break;
01313 default: {
01314 kdDebug(35001) << "ERROR: cell " << row << "," << col
01315 << " has unknown type." << endl;
01316 }
01317 }
01318
01319
01320 bodyWriter->startElement( "table:table-cell" );
01321 if ( !valType.isEmpty() ) {
01322 bodyWriter->addAttribute( "office:value-type", valType );
01323 if ( value.type() == QVariant::Double )
01324 bodyWriter->addAttribute( "office:value", valStr );
01325
01326 bodyWriter->startElement( "text:p" );
01327 bodyWriter->addTextNode( valStr );
01328 bodyWriter->endElement();
01329 }
01330 bodyWriter->endElement();
01331 }
01332 bodyWriter->endElement();
01333 }
01334
01335 bodyWriter->endElement();
01336 bodyWriter->endElement();
01337 }
01338
01339 void KChartPart::writeAutomaticStyles( KoXmlWriter& contentWriter, KoGenStyles& mainStyles ) const
01340 {
01341 QValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( KoGenStyle::STYLE_AUTO );
01342 QValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin();
01343 for ( ; it != styles.end() ; ++it ) {
01344 (*it).style->writeStyle( &contentWriter, mainStyles, "style:style", (*it).name, "style:chart-properties" );
01345 }
01346
01347 }
01348
01349
01350
01351
01352
01353 QDomDocument KChartPart::saveXML()
01354 {
01355 QDomElement tmpElem;
01356
01357
01358
01359
01360
01361 QDomDocument doc = m_params->saveXML( false );
01362
01363
01364
01365
01366 QDomElement docRoot = doc.documentElement();
01367
01368
01369 QDomElement aux = doc.createElement( "KChartAuxiliary" );
01370 docRoot.appendChild( aux );
01371
01372
01373 tmpElem = doc.createElement( "direction" );
01374 tmpElem.setAttribute( "value", (int) m_params->dataDirection() );
01375 aux.appendChild( tmpElem );
01376
01377 tmpElem = doc.createElement( "dataaslabel" );
01378 tmpElem.setAttribute( "firstrow",
01379 m_params->firstRowAsLabel() ? "true" : "false" );
01380 tmpElem.setAttribute( "firstcol",
01381 m_params->firstColAsLabel() ? "true" : "false" );
01382 aux.appendChild( tmpElem );
01383
01384 tmpElem = doc.createElement( "barnumlines" );
01385 tmpElem.setAttribute( "value", (int) m_params->barNumLines() );
01386 aux.appendChild( tmpElem );
01387
01388
01389 QDomElement data = doc.createElement( "data" );
01390 docRoot.appendChild( data );
01391
01392 int cols = m_currentData.usedCols()
01393 ? QMIN(m_currentData.usedCols(), m_currentData.cols())
01394 : m_currentData.cols();
01395 int rows = m_currentData.usedRows()
01396 ? QMIN(m_currentData.usedRows(), m_currentData.rows())
01397 : m_currentData.rows();
01398 data.setAttribute( "cols", cols );
01399 data.setAttribute( "rows", rows );
01400 kdDebug(35001) << " writing " << cols << "," << rows << " (cols,rows)." << endl;
01401
01402 for (int i=0; i!=rows; ++i) {
01403 for (int j=0; j!=cols; ++j) {
01404 QDomElement e = doc.createElement( "cell" );
01405 data.appendChild( e );
01406 QString valType;
01407 QVariant value( m_currentData.cellVal( i,j ) );
01408 switch ( value.type() ) {
01409 case QVariant::Invalid: valType = "NoValue"; break;
01410 case QVariant::String: valType = "String"; break;
01411 case QVariant::Double: valType = "Double"; break;
01412 case QVariant::DateTime: valType = "DateTime"; break;
01413 default: {
01414 valType = "(unknown)";
01415 kdDebug(35001) << "ERROR: cell " << i << "," << j
01416 << " has unknown type." << endl;
01417 }
01418 }
01419
01420 e.setAttribute( "valType", valType );
01421
01422
01423 switch ( value.type() ) {
01424 case QVariant::String: e.setAttribute( "value", value.toString() );
01425 break;
01426 case QVariant::Double: e.setAttribute( "value", QString::number( value.toDouble() ) );
01427 break;
01428 case QVariant::DateTime:e.setAttribute( "value", "" );
01429 break;
01430 default: {
01431 e.setAttribute( "value", "" );
01432 if( QVariant::Invalid != value.type() )
01433 kdDebug(35001) << "ERROR: cell " << i << "," << j
01434 << " has unknown type." << endl;
01435 }
01436 }
01437 }
01438 }
01439
01440 return doc;
01441 }
01442
01443
01444 bool KChartPart::loadXML( QIODevice*, const QDomDocument& doc )
01445 {
01446 kdDebug(35001) << "kchart loadXML called" << endl;
01447
01448
01449 setChartDefaults();
01450
01451
01452 bool result = m_params->loadXML( doc );
01453
01454
01455 if (result) {
01456 result = loadAuxiliary(doc) && loadData( doc, m_currentData );
01457 }
01458 else {
01459
01460 result = loadOldXML( doc );
01461 }
01462
01463
01464 if (result) {
01465 QStringList legendLabels;
01466 KDChartAxisParams params;
01467 params = m_params->axisParams( KDChartAxisParams::AxisPosBottom );
01468
01469
01470 QString str;
01471 uint index = 0;
01472 while ((str = m_params->legendText(index++)) != QString::null)
01473 legendLabels << str;
01474
01475 if (m_params->dataDirection() == KChartParams::DataRows) {
01476 m_colLabels = params.axisLabelStringList();
01477 m_rowLabels = legendLabels;
01478 }
01479 else {
01480 m_colLabels = legendLabels;
01481 m_rowLabels = params.axisLabelStringList();
01482 }
01483
01484 }
01485
01486 m_params->setDrawSolidExcessArrows(true);
01487
01488 return result;
01489 }
01490
01491
01492
01493
01494
01495
01496 bool KChartPart::loadAuxiliary( const QDomDocument& doc )
01497 {
01498 QDomElement chart = doc.documentElement();
01499 QDomElement aux = chart.namedItem("KChartAuxiliary").toElement();
01500
01501
01502
01503 if (aux.isNull())
01504 return true;
01505
01506 QDomNode node = aux.firstChild();
01507
01508
01509 while (!node.isNull()) {
01510
01511 QDomElement e = node.toElement();
01512 if (e.isNull()) {
01513
01514 node = node.nextSibling();
01515 continue;
01516 }
01517
01518
01519 if ( e.tagName() == "direction" ) {
01520 if ( e.hasAttribute("value") ) {
01521 bool ok;
01522
01523
01524 int dir = e.attribute("value").toInt(&ok);
01525 if ( !ok )
01526 dir = (int) KChartParams::DataColumns;
01527
01528
01529 m_params->setDataDirection( (KChartParams::DataDirection) dir );
01530 }
01531 else {
01532 kdDebug(35001) << "Error in direction tag." << endl;
01533 }
01534 }
01535
01536
01537 else if ( e.tagName() == "dataaslabel" ) {
01538 QString val;
01539
01540 if ( e.hasAttribute("firstrow") ) {
01541
01542 val = e.attribute("firstrow");
01543 if ( val == "true" )
01544 m_params->setFirstRowAsLabel( true );
01545 else
01546 m_params->setFirstRowAsLabel( false );
01547 }
01548 else {
01549 kdDebug(35001) << "Error in barnumlines tag." << endl;
01550 m_params->setFirstRowAsLabel( false );
01551 }
01552
01553 if ( e.hasAttribute("firstcol") ) {
01554
01555 val = e.attribute("firstcol");
01556 if ( val == "true" )
01557 m_params->setFirstColAsLabel( true );
01558 else
01559 m_params->setFirstColAsLabel( false );
01560 }
01561 else {
01562 kdDebug(35001) << "Error in barnumlines tag." << endl;
01563 m_params->setFirstColAsLabel( false );
01564 }
01565 }
01566
01567
01568 else if ( e.tagName() == "barnumlines" ) {
01569 if ( e.hasAttribute("value") ) {
01570 bool ok;
01571
01572
01573 int barNumLines = e.attribute("value").toInt(&ok);
01574 if ( !ok )
01575 barNumLines = 0;
01576
01577
01578
01579 m_params->setBarNumLines( barNumLines );
01580 }
01581 else {
01582 kdDebug(35001) << "Error in barnumlines tag." << endl;
01583 }
01584 }
01585 #if 0
01586
01587 else if ( e.tagName() == "..." ) {
01588 }
01589 and so on...
01590 #endif
01591
01592 node = node.nextSibling();
01593 }
01594
01595 return true;
01596 }
01597
01598
01599 bool KChartPart::loadData( const QDomDocument& doc,
01600 KDChartTableData& m_currentData )
01601 {
01602 kdDebug(35001) << "kchart loadData called" << endl;
01603
01604 QDomElement chart = doc.documentElement();
01605 QDomElement data = chart.namedItem("data").toElement();
01606 bool ok;
01607 int cols = data.attribute("cols").toInt(&ok);
01608 kdDebug(35001) << "cols readed as:" << cols << endl;
01609 if ( !ok ){
01610 return false;
01611 }
01612
01613 int rows = data.attribute("rows").toInt(&ok);
01614 if ( !ok ){
01615 return false;
01616 }
01617
01618 kdDebug(35001) << rows << " x " << cols << endl;
01619 m_currentData.expand(rows, cols);
01620 m_currentData.setUsedCols( cols );
01621 m_currentData.setUsedRows( rows );
01622 kdDebug(35001) << "Expanded!" << endl;
01623 QDomNode n = data.firstChild();
01624
01625
01626 for (int i=0; i!=rows; i++) {
01627 for (int j=0; j!=cols; j++) {
01628 if (n.isNull()) {
01629 kdDebug(35001) << "Some problems, there is less data than it should be!" << endl;
01630 break;
01631 }
01632 QDomElement e = n.toElement();
01633 if ( !e.isNull() && e.tagName() == "cell" ) {
01634
01635 QVariant t;
01636 if ( e.hasAttribute("value") && e.hasAttribute("valType") ) {
01637 QString valueType = e.attribute("valType").lower();
01638 if ( "string" == valueType ) {
01639 t = e.attribute("value");
01640 }
01641 else if ( "double" == valueType ) {
01642 bool bOk;
01643 double val = e.attribute("value").toDouble(&bOk);
01644 if ( !bOk )
01645 val = 0.0;
01646 t = val;
01647
01648
01649
01650
01651 } else {
01652 t.clear();
01653 if ( "novalue" != valueType )
01654 kdDebug(35001) << "ERROR: cell " << i << "," << j << " has unknown type '" << valueType << "'." << endl;
01655 }
01656 } else
01657 t.clear();
01658
01659 m_currentData.setCell(i,j, t );
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678 n = n.nextSibling();
01679 }
01680 }
01681 }
01682
01683
01684
01685
01686 return true;
01687 }
01688
01689
01690
01691
01692
01693
01694 bool KChartPart::loadOldXML( const QDomDocument& doc )
01695 {
01696 kdDebug(35001) << "kchart loadOldXML called" << endl;
01697 if ( doc.doctype().name() != "chart" )
01698 return false;
01699
01700 kdDebug(35001) << "Ok, it is a chart" << endl;
01701
01702 QDomElement chart = doc.documentElement();
01703 if ( chart.attribute( "mime" ) != "application/x-kchart" && chart.attribute( "mime" ) != "application/vnd.kde.kchart" )
01704 return false;
01705
01706 kdDebug(35001) << "Mimetype ok" << endl;
01707
01708 #if 0
01709 QDomElement data = chart.namedItem("data").toElement();
01710 bool ok;
01711 int cols = data.attribute("cols").toInt(&ok);
01712 kdDebug(35001) << "cols readed as:" << cols << endl;
01713 if (!ok) { return false; }
01714 int rows = data.attribute("rows").toInt(&ok);
01715 if (!ok) { return false; }
01716 kdDebug(35001) << rows << " x " << cols << endl;
01717 m_currentData.expand(rows, cols);
01718 kdDebug(35001) << "Expanded!" << endl;
01719 QDomNode n = data.firstChild();
01720 QArray<int> tmpExp(rows*cols);
01721 QArray<bool> tmpMissing(rows*cols);
01722
01723 for (int i=0; i!=rows; i++) {
01724 for (int j=0; j!=cols; j++) {
01725 if (n.isNull()) {
01726 kdDebug(35001) << "Some problems, there is less data than it should be!" << endl;
01727 break;
01728 }
01729
01730 QDomElement e = n.toElement();
01731 if ( !e.isNull() && e.tagName() == "cell" ) {
01732
01733 double val = e.attribute("value").toDouble(&ok);
01734 if (!ok) { return false; }
01735 kdDebug(35001) << i << " " << j << "=" << val << endl;
01736 KoChart::Value t( val );
01737
01738 m_currentData.setCell(i,j,t);
01739 if ( e.hasAttribute( "hide" ) ) {
01740 tmpMissing[cols*j+i] = (bool)e.attribute("hide").toInt( &ok );
01741 if ( !ok )
01742 return false;
01743 } else {
01744 tmpMissing[cols*j+i] = false;
01745 }
01746 if ( e.hasAttribute( "dist" ) ) {
01747 tmpExp[cols*j+i] = e.attribute("dist").toInt( &ok );
01748 if ( !ok )
01749 return false;
01750 } else {
01751 tmpExp[cols*j+i] = 0;
01752 }
01753
01754 n = n.nextSibling();
01755 }
01756 }
01757 }
01758 m_params->missing=tmpMissing;
01759 m_params->explode=tmpExp;
01760 #endif
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785 bool ok;
01786 QDomElement params = chart.namedItem( "params" ).toElement();
01787 if ( params.hasAttribute( "type" ) ) {
01788 int type=params.attribute("type").toInt( &ok );
01789 if ( !ok )
01790 return false;
01791 switch(type)
01792 {
01793 case 1:
01794 m_params->setChartType(KChartParams::Line);
01795 break;
01796 case 2:
01797 m_params->setChartType(KChartParams::Area);
01798 break;
01799 case 3:
01800 m_params->setChartType(KChartParams::Bar);
01801 break;
01802 case 4:
01803 m_params->setChartType(KChartParams::HiLo);
01804 break;
01805 case 5:
01806 case 6:
01807 case 7:
01808 case 8:
01809
01810
01811
01812
01813
01814
01815 m_params->setChartType(KChartParams::Line);
01816 break;
01817 case 9:
01818 m_params->setChartType(KChartParams::HiLo);
01819 break;
01820 case 10:
01821 m_params->setChartType(KChartParams::Bar);
01822 break;
01823 case 11:
01824 m_params->setChartType(KChartParams::Area);
01825 break;
01826 case 12:
01827 m_params->setChartType(KChartParams::Bar);
01828 break;
01829 case 13:
01830 m_params->setChartType(KChartParams::Area);
01831 break;
01832 case 14:
01833 m_params->setChartType(KChartParams::Bar);
01834 break;
01835 case 15:
01836 m_params->setChartType(KChartParams::Area);
01837 break;
01838 case 16:
01839 m_params->setChartType(KChartParams::Line);
01840 break;
01841 case 17:
01842 case 18:
01843 m_params->setChartType(KChartParams::Pie);
01844 break;
01845
01846 }
01847 if ( !ok )
01848 return false;
01849 }
01850 #if 0
01851 if ( params.hasAttribute( "subtype" ) ) {
01852 m_params->stack_type = (KChartStackType)params.attribute("subtype").toInt( &ok );
01853 if ( !ok )
01854 return false;
01855 }
01856 if ( params.hasAttribute( "hlc_style" ) ) {
01857 m_params->hlc_style = (KChartHLCStyle)params.attribute("hlc_style").toInt( &ok );
01858 if ( !ok )
01859 return false;
01860 }
01861 if ( params.hasAttribute( "hlc_cap_width" ) ) {
01862 m_params->hlc_cap_width = (short)params.attribute( "hlc_cap_width" ).toShort( &ok );
01863 if ( !ok )
01864 return false;
01865 }
01866
01867 QDomElement title = params.namedItem( "title" ).toElement();
01868 if ( !title.isNull()) {
01869 QString t = title.text();
01870 m_params->title=t;
01871 }
01872 QDomElement titlefont = params.namedItem( "titlefont" ).toElement();
01873 if ( !titlefont.isNull()) {
01874 QDomElement font = titlefont.namedItem( "font" ).toElement();
01875 if ( !font.isNull() )
01876 m_params->setTitleFont(toFont(font));
01877 }
01878 QDomElement xtitle = params.namedItem( "xtitle" ).toElement();
01879 if ( !xtitle.isNull()) {
01880 QString t = xtitle.text();
01881 m_params->xtitle=t;
01882 }
01883 QDomElement xtitlefont = params.namedItem( "xtitlefont" ).toElement();
01884 if ( !xtitlefont.isNull()) {
01885 QDomElement font = xtitlefont.namedItem( "font" ).toElement();
01886 if ( !font.isNull() )
01887 m_params->setXTitleFont(toFont(font));
01888 }
01889 QDomElement ytitle = params.namedItem( "ytitle" ).toElement();
01890 if ( !ytitle.isNull()) {
01891 QString t = ytitle.text();
01892 m_params->ytitle=t;
01893 }
01894 QDomElement ytitle2 = params.namedItem( "ytitle2" ).toElement();
01895 if ( !ytitle2.isNull()) {
01896 QString t = ytitle2.text();
01897 m_params->ytitle2=t;
01898 }
01899 QDomElement ytitlefont = params.namedItem( "ytitlefont" ).toElement();
01900 if ( !ytitlefont.isNull()) {
01901 QDomElement font = ytitlefont.namedItem( "font" ).toElement();
01902 if ( !font.isNull() )
01903 m_params->setYTitleFont(toFont(font));
01904 }
01905 QDomElement ylabelfmt = params.namedItem( "ylabelfmt" ).toElement();
01906 if ( !ylabelfmt.isNull()) {
01907 QString t = ylabelfmt.text();
01908 m_params->ylabel_fmt=t;
01909 }
01910 QDomElement ylabel2fmt = params.namedItem( "ylabel2fmt" ).toElement();
01911 if ( !ylabel2fmt.isNull()) {
01912 QString t = ylabel2fmt.text();
01913 m_params->ylabel2_fmt=t;
01914 }
01915 QDomElement labelfont = params.namedItem( "labelfont" ).toElement();
01916 if ( !labelfont.isNull()) {
01917 QDomElement font = labelfont.namedItem( "font" ).toElement();
01918 if ( !font.isNull() )
01919 m_params->setLabelFont(toFont(font));
01920 }
01921
01922 QDomElement yaxisfont = params.namedItem( "yaxisfont" ).toElement();
01923 if ( !yaxisfont.isNull()) {
01924 QDomElement font = yaxisfont.namedItem( "font" ).toElement();
01925 if ( !font.isNull() )
01926 m_params->setYAxisFont(toFont(font));
01927 }
01928
01929 QDomElement xaxisfont = params.namedItem( "xaxisfont" ).toElement();
01930 if ( !xaxisfont.isNull()) {
01931 QDomElement font = xaxisfont.namedItem( "font" ).toElement();
01932 if ( !font.isNull() )
01933 m_params->setXAxisFont(toFont(font));
01934 }
01935 QDomElement annotationFont = params.namedItem("annotationfont").toElement();
01936 if ( !annotationFont.isNull()) {
01937 QDomElement font = annotationFont.namedItem( "font" ).toElement();
01938 if ( !font.isNull() )
01939 m_params->setAnnotationFont(toFont(font));
01940 }
01941
01942 QDomElement yaxis = params.namedItem( "yaxis" ).toElement();
01943 if ( !yaxis.isNull()) {
01944 if (yaxis.hasAttribute( "yinterval" )) {
01945 m_params->requested_yinterval= yaxis.attribute("yinterval").toDouble( &ok );
01946 if ( !ok ) return false;
01947 }
01948 if (yaxis.hasAttribute( "ymin" )) {
01949 m_params->requested_ymin= yaxis.attribute("ymin").toDouble( &ok );
01950 if ( !ok ) return false;
01951 }
01952 if (yaxis.hasAttribute( "ymax" ) ) {
01953 m_params->requested_ymax= yaxis.attribute("ymax").toDouble( &ok );
01954 if ( !ok ) return false;
01955 }
01956 }
01957 #endif
01958
01959 QDomElement graph = params.namedItem( "graph" ).toElement();
01960 if (!graph.isNull()) {
01961 if (graph.hasAttribute( "grid" )) {
01962 bool b=(bool) graph.attribute("grid").toInt( &ok );
01963 m_params->setAxisShowGrid(KDChartAxisParams::AxisPosLeft,b );
01964 m_params->setAxisShowGrid(KDChartAxisParams::AxisPosBottom,b );
01965 if (!ok) return false;
01966 }
01967 if (graph.hasAttribute( "xaxis" )) {
01968 bool b=(bool) graph.attribute("xaxis").toInt( &ok );
01969 if (!ok) return false;
01970 m_params->setAxisVisible(KDChartAxisParams::AxisPosBottom,b);
01971 }
01972 if (graph.hasAttribute( "yaxis" )) {
01973 bool b=(bool) graph.attribute("yaxis").toInt( &ok );
01974 if (!ok) return false;
01975 m_params->setAxisVisible(KDChartAxisParams::AxisPosLeft,b);
01976 }
01977 #if 0
01978
01979 if (graph.hasAttribute( "shelf" )) {
01980 m_params->shelf=(bool) graph.attribute("shelf").toInt( &ok );
01981 if (!ok) return false;
01982 }
01983 #endif
01984 if (graph.hasAttribute( "yaxis2" )) {
01985 bool b=(bool) graph.attribute("yaxis2").toInt( &ok );
01986 if (!ok) return false;
01987 m_params->setAxisVisible(KDChartAxisParams::AxisPosRight,b);
01988 }
01989
01990 #if 0
01991
01992 if (graph.hasAttribute( "ystyle" )) {
01993 m_params->yval_style=(bool) graph.attribute("ystyle").toInt( &ok );
01994 if (!ok) return false;
01995 }
01996 if (graph.hasAttribute( "border" )) {
01997 m_params->border=(bool) graph.attribute("border").toInt( &ok );
01998 if (!ok) return false;
01999 }
02000 if (graph.hasAttribute( "transbg" )) {
02001 m_params->transparent_bg=(bool) graph.attribute("transbg").toInt( &ok );
02002 if (!ok) return false;
02003 }
02004 if (graph.hasAttribute( "xlabel" )) {
02005 m_params->hasxlabel=(bool) graph.attribute("xlabel").toInt( &ok );
02006 if (!ok) return false;
02007 }
02008 if ( graph.hasAttribute( "xlabel_spacing" ) ) {
02009 m_params->xlabel_spacing = (short)graph.attribute( "xlabel_spacing" ).toShort( &ok );
02010 if ( !ok )
02011 return false;
02012 }
02013 if ( graph.hasAttribute( "ylabel_density" ) ) {
02014 m_params->ylabel_density = (short)graph.attribute( "ylabel_density" ).toShort( &ok );
02015 if ( !ok )
02016 return false;
02017 }
02018 if (graph.hasAttribute( "line")) {
02019 m_params->label_line=(bool) graph.attribute("line").toInt( &ok );
02020 if (!ok) return false;
02021 }
02022 if (graph.hasAttribute( "percent")) {
02023 m_params->percent_labels=(KChartPercentType) graph.attribute("percent").toInt( &ok );
02024 if (!ok) return false;
02025 }
02026 if (graph.hasAttribute("cross")) {
02027 m_params->cross=(bool) graph.attribute("cross").toInt( &ok );
02028 if (!ok) return false;
02029 }
02030 if (graph.hasAttribute("thumbnail")) {
02031 m_params->thumbnail=(bool) graph.attribute("thumbnail").toInt( &ok );
02032 if (!ok) return false;
02033 }
02034 if (graph.hasAttribute("thumblabel")) {
02035 m_params->thumblabel= graph.attribute("thumblabel");
02036 }
02037 if (graph.hasAttribute("thumbval")) {
02038 m_params->thumbval=(bool) graph.attribute("thumbval").toDouble( &ok );
02039 if (!ok)
02040 return false;
02041 }
02042 #endif
02043 }
02044
02045 #if 0
02046 QDomElement graphparams = params.namedItem( "graphparams" ).toElement();
02047 if (!graphparams.isNull()) {
02048 if (graphparams.hasAttribute( "dept3d" )) {
02049 m_params->_3d_depth=graphparams.attribute("dept3d").toDouble( &ok );
02050 if (!ok) return false;
02051 }
02052 if (graphparams.hasAttribute( "angle3d" )) {
02053 m_params->_3d_angle=graphparams.attribute("angle3d").toShort( &ok );
02054 if (!ok) return false;
02055 }
02056 if (graphparams.hasAttribute( "barwidth" )) {
02057 m_params->bar_width=graphparams.attribute("barwidth").toShort( &ok );
02058 if (!ok) return false;
02059 }
02060 if (graphparams.hasAttribute( "colpie" )) {
02061 m_params->colPie=graphparams.attribute("colpie").toInt( &ok );
02062 if (!ok) return false;
02063 }
02064 if (graphparams.hasAttribute( "other_threshold" )) {
02065 m_params->other_threshold=graphparams.attribute("other_threshold").toShort( &ok );
02066 if (!ok)
02067 return false;
02068 }
02069 if (graphparams.hasAttribute( "offsetCol" )) {
02070 m_params->offsetCol = graphparams.attribute("offsetCol").toInt( &ok );
02071 if (!ok)
02072 return false;
02073 }
02074 if (graphparams.hasAttribute( "hard_size" )) {
02075 m_params->hard_size = (bool)graphparams.attribute("hard_size").toInt( &ok );
02076 if (!ok)
02077 return false;
02078 }
02079 if (graphparams.hasAttribute( "hard_graphheight" )) {
02080 m_params->hard_graphheight = graphparams.attribute("hard_graphheight").toInt( &ok );
02081 if (!ok)
02082 return false;
02083 }
02084 if (graphparams.hasAttribute( "hard_graphwidth" )) {
02085 m_params->hard_graphwidth = graphparams.attribute("hard_graphwidth").toInt( &ok );
02086 if (!ok)
02087 return false;
02088 }
02089 if (graphparams.hasAttribute( "hard_xorig" )) {
02090 m_params->hard_xorig = graphparams.attribute("hard_xorig").toInt( &ok );
02091 if (!ok)
02092 return false;
02093 }
02094 if (graphparams.hasAttribute( "hard_yorig" )) {
02095 m_params->hard_yorig = graphparams.attribute("hard_yorig").toInt( &ok );
02096 if (!ok)
02097 return false;
02098 }
02099 if (graphparams.hasAttribute( "labeldist" )) {
02100 m_params->label_dist=graphparams.attribute("labeldist").toInt( &ok );
02101 if (!ok) return false;
02102 }
02103 }
02104
02105 QDomElement graphcolor = params.namedItem( "graphcolor" ).toElement();
02106 if (!graphcolor.isNull()) {
02107 if (graphcolor.hasAttribute( "bgcolor" )) {
02108 m_params->BGColor= QColor( graphcolor.attribute( "bgcolor" ) );
02109 }
02110 if (graphcolor.hasAttribute( "gridcolor" )) {
02111 m_params->GridColor= QColor( graphcolor.attribute( "gridcolor" ) );
02112 }
02113 if (graphcolor.hasAttribute( "linecolor" )) {
02114 m_params->LineColor= QColor( graphcolor.attribute( "linecolor" ) );
02115 }
02116 if (graphcolor.hasAttribute( "plotcolor" )) {
02117 m_params->PlotColor= QColor( graphcolor.attribute( "plotcolor" ) );
02118 }
02119 if (graphcolor.hasAttribute( "volcolor" )) {
02120 m_params->VolColor= QColor( graphcolor.attribute( "volcolor" ) );
02121 }
02122 if (graphcolor.hasAttribute( "titlecolor" )) {
02123 m_params->TitleColor= QColor( graphcolor.attribute( "titlecolor" ) );
02124 }
02125 if (graphcolor.hasAttribute( "xtitlecolor" )) {
02126 m_params->XTitleColor= QColor( graphcolor.attribute( "xtitlecolor" ) );
02127 }
02128 if (graphcolor.hasAttribute( "ytitlecolor" )) {
02129 m_params->YTitleColor= QColor( graphcolor.attribute( "ytitlecolor" ) );
02130 }
02131 if (graphcolor.hasAttribute( "ytitle2color" )) {
02132 m_params->YTitle2Color= QColor( graphcolor.attribute( "ytitle2color" ) );
02133 }
02134 if (graphcolor.hasAttribute( "xlabelcolor" )) {
02135 m_params->XLabelColor= QColor( graphcolor.attribute( "xlabelcolor" ) );
02136 }
02137 if (graphcolor.hasAttribute( "ylabelcolor" )) {
02138 m_params->YLabelColor= QColor( graphcolor.attribute( "ylabelcolor" ) );
02139 }
02140 if (graphcolor.hasAttribute( "ylabel2color" )) {
02141 m_params->YLabel2Color= QColor( graphcolor.attribute( "ylabel2color" ) );
02142 }
02143 }
02144
02145 QDomElement annotation = params.namedItem( "annotation" ).toElement();
02146 if (!annotation.isNull()) {
02147 m_params->annotation=new KChartAnnotationType;
02148 if (annotation.hasAttribute( "color" )) {
02149 m_params->annotation->color= QColor( annotation.attribute( "color" ) );
02150 }
02151 if (annotation.hasAttribute( "point" )) {
02152 m_params->annotation->point=annotation.attribute("point").toDouble( &ok );
02153 if (!ok) return false;
02154 }
02155 }
02156
02157 QDomElement note = params.namedItem( "note" ).toElement();
02158 if ( !note.isNull()) {
02159 QString t = note.text();
02160 m_params->annotation->note=t;
02161 }
02162
02163 QDomElement scatter = params.namedItem( "scatter" ).toElement();
02164 if ( !scatter.isNull() ) {
02165 m_params->scatter = new KChartScatterType;
02166 if ( scatter.hasAttribute( "point" ) ) {
02167 m_params->scatter->point = scatter.attribute( "point" ).toDouble( &ok );
02168 if ( !ok )
02169 return false;
02170 }
02171 if ( scatter.hasAttribute( "val" ) ) {
02172 m_params->scatter->val = scatter.attribute( "val" ).toDouble( &ok );
02173 if ( !ok )
02174 return false;
02175 }
02176 if ( scatter.hasAttribute( "width" ) ) {
02177 m_params->scatter->width = scatter.attribute( "val" ).toUShort( &ok );
02178 if ( !ok )
02179 return false;
02180 }
02181 if ( scatter.hasAttribute( "color" )) {
02182 m_params->scatter->color= QColor( scatter.attribute( "color" ) );
02183 }
02184 if ( scatter.hasAttribute( "ind" ) ) {
02185 m_params->scatter->ind = (KChartScatterIndType)scatter.attribute( "ind" ).toInt( &ok );
02186 if ( !ok )
02187 return false;
02188 }
02189 }
02190
02191 QDomElement legend = chart.namedItem("legend").toElement();
02192 if (!legend.isNull()) {
02193 int number = legend.attribute("number").toInt(&ok);
02194 if (!ok) { return false; }
02195 QDomNode name = legend.firstChild();
02196 m_params->legend.clear();
02197 for(int i=0; i<number; i++) {
02198 if (name.isNull()) {
02199 kdDebug(35001) << "Some problems, there is less data than it should be!" << endl;
02200 break;
02201 }
02202 QDomElement element = name.toElement();
02203 if ( !element.isNull() && element.tagName() == "name" ) {
02204 QString t = element.text();
02205 m_params->legend+=t;
02206 name = name.nextSibling();
02207 }
02208 }
02209 }
02210
02211 QDomElement xlbl = chart.namedItem("xlbl").toElement();
02212 if (!xlbl.isNull()) {
02213 int number = xlbl.attribute("number").toInt(&ok);
02214 if (!ok) { return false; }
02215 QDomNode label = xlbl.firstChild();
02216 m_params->xlbl.clear();
02217 for (int i=0; i<number; i++) {
02218 if (label.isNull()) {
02219 kdDebug(35001) << "Some problems, there is less data than it should be!" << endl;
02220 break;
02221 }
02222 QDomElement element = label.toElement();
02223 if ( !element.isNull() && element.tagName() == "label" ) {
02224 QString t = element.text();
02225 m_params->xlbl+=t;
02226 label = label.nextSibling();
02227 }
02228 }
02229 }
02230
02231 QDomElement backgroundPixmap = chart.namedItem( "backgroundPixmap" ).toElement();
02232 if ( !backgroundPixmap.isNull() ) {
02233 if ( backgroundPixmap.hasAttribute( "name" ) )
02234 m_params->backgroundPixmapName = backgroundPixmap.attribute( "name" );
02235 if ( backgroundPixmap.hasAttribute( "isDirty" ) ) {
02236 m_params->backgroundPixmapIsDirty = (bool)backgroundPixmap.attribute( "isDirty" ).toInt( &ok );
02237 if ( !ok )
02238 return false;
02239 }
02240 if ( backgroundPixmap.hasAttribute( "scaled" ) ) {
02241 m_params->backgroundPixmapScaled = (bool)backgroundPixmap.attribute( "scaled" ).toInt( &ok );
02242 if ( !ok )
02243 return false;
02244 }
02245 if ( backgroundPixmap.hasAttribute( "centered" ) ) {
02246 m_params->backgroundPixmapCentered = (bool)backgroundPixmap.attribute( "centered" ).toInt( &ok );
02247 if ( !ok )
02248 return false;
02249 }
02250 if ( backgroundPixmap.hasAttribute( "intensity" ) ) {
02251 m_params->backgroundPixmapIntensity = backgroundPixmap.attribute( "intensity" ).toFloat( &ok );
02252 if ( !ok )
02253 return false;
02254 }
02255 }
02256
02257 QDomElement extcolor = chart.namedItem("extcolor").toElement();
02258 if (!extcolor.isNull()) {
02259 unsigned int number = extcolor.attribute("number").toInt(&ok);
02260 if (!ok) { return false; }
02261 QDomNode color = extcolor.firstChild();
02262
02263 for (unsigned int i=0; i<number; i++) {
02264 if (color.isNull()) {
02265 kdDebug(35001) << "Some problems, there is less data than it should be!" << endl;
02266 break;
02267 }
02268 QDomElement element = color.toElement();
02269 if ( !element.isNull()) {
02270 if (element.hasAttribute( "name" )) {
02271 m_params->ExtColor.setColor(i,QColor( element.attribute( "name" ) ));
02272 }
02273 color = color.nextSibling();
02274 }
02275 }
02276 }
02277
02278 if ( !m_params->backgroundPixmapName.isNull() ) {
02279 m_params->backgroundPixmap.load( locate( "wallpaper",
02280 m_params->backgroundPixmapName ));
02281 m_params->backgroundPixmapIsDirty = true;
02282 }
02283 #endif
02284 return true;
02285 }
02286
02287
02288
02289 void KChartPart::slotModified()
02290 {
02291 kdDebug(35001) << "slotModified called!" << endl;
02292
02293 setModified(true);
02294 }
02295
02296
02297 bool KChartPart::showEmbedInitDialog(QWidget* )
02298 {
02299
02300 return true;
02301 }
02302
02303
02304 }
02305
02306 #include "kchart_part.moc"