00001
00007 #include <qfile.h>
00008 #include <qpainter.h>
00009 #include <qcursor.h>
00010 #include <qpopupmenu.h>
00011 #include <qpaintdevicemetrics.h>
00012 #include <qcstring.h>
00013
00014 #include <kaction.h>
00015 #include <kglobal.h>
00016 #include <klocale.h>
00017 #include <kiconloader.h>
00018 #include <kdebug.h>
00019 #include <kprinter.h>
00020 #include <kstandarddirs.h>
00021 #include <ktempfile.h>
00022 #include <dcopobject.h>
00023 #include <kxmlguifactory.h>
00024 #include <kfiledialog.h>
00025 #include <kmessagebox.h>
00026
00027 #include <KoTemplateCreateDia.h>
00028
00029 #include "kdchart/KDChart.h"
00030 #include "kchart_view.h"
00031 #include "kchart_factory.h"
00032 #include "kchart_part.h"
00033 #include "kchart_params.h"
00034 #include "kchartWizard.h"
00035 #include "kchartDataEditor.h"
00036 #include "kchartConfigDialog.h"
00037 #include "KChartViewIface.h"
00038 #include "kchartPageLayout.h"
00039 #include "kchartPrinterDlg.h"
00040 #include "csvimportdialog.h"
00041
00042
00043 using namespace std;
00044
00045
00046
00047
00048 namespace KChart
00049 {
00050
00051
00052 KChartView::KChartView( KChartPart* part, QWidget* parent, const char* name )
00053 : KoView( part, parent, name )
00054 {
00055
00056
00057 setBackgroundMode( Qt::NoBackground );
00058
00059 setInstance( KChartFactory::global() );
00060 if ( koDocument()->isReadWrite() )
00061 setXMLFile( "kchart.rc" );
00062 else
00063 setXMLFile( "kchart_readonly.rc" );
00064 m_dcop = 0;
00065 dcopObject();
00066
00067 m_importData = new KAction( i18n( "Import Data..." ), 0,
00068 this, SLOT( importData() ),
00069 actionCollection(), "import_data" );
00070 #if 0
00071 KAction * actionExtraCreateTemplate =
00072 #endif
00073 new KAction( i18n( "&Create Template From Document..." ), 0,
00074 this, SLOT( extraCreateTemplate() ),
00075 actionCollection(), "extra_template" );
00076
00077 m_wizard = new KAction( i18n("Customize with &Wizard..."),
00078 "wizard", 0,
00079 this, SLOT( wizard() ),
00080 actionCollection(), "wizard");
00081 m_edit = new KAction( i18n("Edit &Data..."), "edit", 0,
00082 this, SLOT( editData() ),
00083 actionCollection(), "editdata");
00084 m_config = new KAction( i18n( "&Chart..." ), "configure", 0,
00085
00086 this, SLOT( slotConfig() ),
00087 actionCollection(), "config" );
00088
00089
00090 m_chartbars = new KToggleAction( i18n("&Bar"), "chart_bar_3d", 0, this,
00091 SLOT( barsChart() ), actionCollection(),
00092 "barschart");
00093 m_chartbars->setExclusiveGroup( "charttypes" );
00094 m_chartbars->setChecked( true );
00095
00096 m_chartline = new KToggleAction( i18n("&Line"), "chart_line", 0, this,
00097 SLOT( lineChart() ), actionCollection(),
00098 "linechart");
00099 m_chartline->setExclusiveGroup( "charttypes" );
00100
00101 m_chartareas = new KToggleAction( i18n("&Area"), "chart_area", 0, this,
00102 SLOT( areasChart() ), actionCollection(),
00103 "areaschart");
00104 m_chartareas->setExclusiveGroup( "charttypes" );
00105
00106 m_charthilo = new KToggleAction( i18n("&HiLo"), "chart_hilo", 0, this,
00107 SLOT( hiLoChart() ), actionCollection(),
00108 "hilochart");
00109 m_charthilo->setExclusiveGroup( "charttypes" );
00110
00111 m_chartbw = new KToggleAction( i18n("Bo&x && Whiskers"), "chart_boxwhisker", 0, this,
00112 SLOT( bwChart() ), actionCollection(),
00113 "bwchart");
00114 m_chartbw->setExclusiveGroup( "charttypes" );
00115
00116 m_chartpie = new KToggleAction( i18n("&Pie"), "chart_pie", 0, this,
00117 SLOT( pieChart() ), actionCollection(),
00118 "piechart");
00119 m_chartpie->setExclusiveGroup( "charttypes" );
00120
00121 m_chartring = new KToggleAction( i18n("&Ring"), "chart_ring", 0, this,
00122 SLOT( ringChart() ), actionCollection(),
00123 "ringchart");
00124 m_chartring->setExclusiveGroup( "charttypes" );
00125
00126 m_chartpolar = new KToggleAction( i18n("&Polar"), "chart_polar", 0, this,
00127 SLOT( polarChart() ), actionCollection(),
00128 "polarchart");
00129 m_chartpolar->setExclusiveGroup( "charttypes" );
00130
00131
00132 m_colorConfig = new KAction( i18n( "&Colors..." ), 0,
00133 this, SLOT( slotConfigColor() ),
00134 actionCollection(), "color_config" );
00135
00136 m_fontConfig = new KAction( i18n( "&Font..." ), 0,
00137 this, SLOT( slotConfigFont() ),
00138 actionCollection(), "font_config" );
00139
00140 m_backConfig = new KAction( i18n( "&Background..." ), 0,
00141 this, SLOT( slotConfigBack() ),
00142 actionCollection(), "back_config" );
00143
00144 m_legendConfig = new KAction( i18n( "&Legend..." ), 0,
00145 this, SLOT( slotConfigLegend() ),
00146 actionCollection(), "legend_config" );
00147
00148 m_subTypeChartConfig = new KAction( i18n( "Chart &Sub-type..." ), 0,
00149 this, SLOT( slotConfigSubTypeChart() ),
00150 actionCollection(), "legend_subtype" );
00151
00152 m_dataFormatConfig = new KAction( i18n( "&Data Format..." ), 0,
00153 this, SLOT( slotConfigDataFormat() ),
00154 actionCollection(), "data_format" );
00155
00156 m_headerFooterConfig = new KAction( i18n( "&Header && Footer..." ), 0,
00157 this, SLOT( slotConfigHeaderFooterChart() ),
00158 actionCollection(), "headerfooter_subtype" );
00159
00160 m_pageLayoutConfig = new KAction( i18n( "Page Layout..." ), 0,
00161 this, SLOT( slotConfigPageLayout() ),
00162 actionCollection(), "page_layout" );
00163
00164
00165
00166
00167
00168
00169 if (!((KChartPart*)koDocument())->canChangeValue()) {
00170 m_edit->setEnabled(false);
00171 m_importData->setEnabled(false);
00172 }
00173
00174 updateGuiTypeOfChart();
00175 }
00176
00177
00178 KChartView::~KChartView()
00179 {
00180 delete m_dcop;
00181 }
00182
00183
00184 DCOPObject* KChartView::dcopObject()
00185 {
00186 if ( !m_dcop )
00187 m_dcop = new KChartViewIface( this );
00188
00189 return m_dcop;
00190 }
00191
00192
00193 void KChartView::paintEvent( QPaintEvent* )
00194 {
00195 QPainter painter( this );
00196
00197
00198
00199
00200
00201 koDocument()->paintEverything( painter, rect(), false, this );
00202 }
00203
00204
00205 void KChartView::updateReadWrite( bool )
00206 {
00207 #ifdef __GNUC__
00208 #warning TODO
00209 #endif
00210 }
00211
00212
00213
00214
00215
00216
00217 void KChartView::editData()
00218 {
00219 kchartDataEditor ed(this);
00220 KChartParams *params = ((KChartPart*)koDocument())->params();
00221 KDChartTableData *dat = ((KChartPart*)koDocument())->data();
00222
00223 kdDebug(35001) << "***Before calling editor: cols =" << dat->cols()
00224 << " , rows = " << dat->rows()
00225 << " , usedCols = " << dat->usedCols()
00226 << " usedRows = " << dat->usedRows() << endl;
00227
00228 ed.setData( params, dat );
00229 ed.setRowLabels(((KChartPart*)koDocument())->rowLabelTexts());
00230 ed.setColLabels(((KChartPart*)koDocument())->colLabelTexts());
00231
00232
00233 connect(&ed, SIGNAL(applyClicked(kchartDataEditor *)),
00234 this, SLOT(applyEdit(kchartDataEditor *)));
00235
00236
00237 if ( ed.exec() != QDialog::Accepted ) {
00238 return;
00239 }
00240 if (!ed.modified())
00241 return;
00242
00243
00244 ed.getData(params, dat);
00245 ed.getRowLabels(((KChartPart*)koDocument())->rowLabelTexts());
00246 ed.getColLabels(((KChartPart*)koDocument())->colLabelTexts());
00247 ((KChartPart*)koDocument())->setModified(true);
00248
00249 kdDebug(35001) << "***After calling editor: cols =" << dat->cols()
00250 << " , rows = " << dat->rows()
00251 << " , usedCols = " << dat->usedCols()
00252 << " usedRows = " << dat->usedRows() << endl;
00253 update();
00254 }
00255
00256
00257 void KChartView::applyEdit(kchartDataEditor *ed)
00258 {
00259 if (!ed->modified())
00260 return;
00261
00262 ed->getData( ((KChartPart*)koDocument())->params(),
00263 ((KChartPart*)koDocument())->data() );
00264 ed->getRowLabels(((KChartPart*)koDocument())->rowLabelTexts());
00265 ed->getColLabels(((KChartPart*)koDocument())->colLabelTexts());
00266
00267 ((KChartPart*)koDocument())->setModified(true);
00268
00269 update();
00270 }
00271
00272
00273 void KChartView::wizard()
00274 {
00275 kdDebug(35001) << "Wizard called" << endl;
00276 KChartWizard *wiz = new KChartWizard((KChartPart*)koDocument(), this,
00277 "KChart Wizard", true);
00278 kdDebug(35001) << "Executed. Now, display it" << endl;
00279 if (wiz->exec()) {
00280 ((KChartPart*)koDocument())->setModified(true);
00281 update();
00282 updateGuiTypeOfChart();
00283 kdDebug(35001) << "Ok, executed..." << endl;
00284 }
00285 }
00286
00287
00288 void KChartView::updateGuiTypeOfChart()
00289 {
00290 KDChartParams* params = ((KChartPart*)koDocument())->params();
00291
00292 switch(params->chartType()) {
00293 case KDChartParams::Bar:
00294 m_chartbars->setChecked(true);
00295 break;
00296 case KDChartParams::Line:
00297 m_chartline->setChecked(true);
00298 break;
00299 case KDChartParams::Area:
00300 m_chartareas->setChecked(true);
00301 break;
00302 case KDChartParams::Pie:
00303 m_chartpie->setChecked(true);
00304 break;
00305 case KDChartParams::HiLo:
00306 m_charthilo->setChecked(true);
00307 break;
00308 case KDChartParams::Ring:
00309 m_chartring->setChecked(true);
00310 break;
00311 case KDChartParams::Polar:
00312 m_chartpolar->setChecked(true);
00313 break;
00314 case KDChartParams::BoxWhisker:
00315 m_chartbw->setChecked( true );
00316 break;
00317 default:
00318
00319 break;
00320 }
00321
00322
00323 updateButton();
00324 }
00325
00326
00327 void KChartView::slotConfig()
00328 {
00329 config(KChartConfigDialog::KC_ALL);
00330 }
00331
00332
00333 void KChartView::config(int flags)
00334 {
00335
00336 KChartParams *params = ((KChartPart*)koDocument())->params();
00337 KDChartTableData *dat = ((KChartPart*)koDocument())->data();
00338
00339 KChartConfigDialog *d = new KChartConfigDialog( params, this, flags,
00340 dat );
00341
00342 connect( d, SIGNAL( dataChanged() ),
00343 this, SLOT( slotRepaint() ) );
00344 d->exec();
00345 delete d;
00346 }
00347
00348
00349 void KChartView::slotRepaint()
00350 {
00351 ((KChartPart*)koDocument())->setModified(true);
00352 update();
00353 }
00354
00355
00356 void KChartView::saveConfig()
00357 {
00358 kdDebug(35001) << "Save config..." << endl;
00359 ((KChartPart*)koDocument())->saveConfig( KGlobal::config() );
00360 }
00361
00362
00363 void KChartView::loadConfig()
00364 {
00365 kdDebug(35001) << "Load config..." << endl;
00366
00367 KGlobal::config()->reparseConfiguration();
00368 ((KChartPart*)koDocument())->loadConfig( KGlobal::config() );
00369
00370 updateGuiTypeOfChart();
00371
00372 update();
00373 }
00374
00375
00376 void KChartView::defaultConfig()
00377 {
00378 ((KChartPart*)koDocument())->defaultConfig( );
00379 updateGuiTypeOfChart();
00380 update();
00381 }
00382
00383
00384 void KChartView::pieChart()
00385 {
00386 if ( m_chartpie->isChecked() ) {
00387 forceAxisParams(false);
00388 KChartParams *params = ((KChartPart*)koDocument())->params();
00389
00390 params->setChartType( KChartParams::Pie );
00391 params->setThreeDPies(params->threeDBars());
00392 params->setExplodeFactor( 0 );
00393 params->setExplode( true );
00394
00395 updateButton();
00396 update();
00397 ((KChartPart*)koDocument())->setModified(true);
00398 }
00399 else
00400 m_chartpie->setChecked( true );
00401 }
00402
00403 void KChartView::forceAxisParams(bool lineMode) {
00404 KChartParams *params = ((KChartPart*)koDocument())->params();
00405 KDChartAxisParams axisParams;
00406 axisParams = params->axisParams( KDChartAxisParams::AxisPosLeft );
00407 if(params->chartType() == KChartParams::Line)
00408 m_logarithmicScale = axisParams.axisCalcMode();
00409 if(lineMode) {
00410 if(m_logarithmicScale)
00411 axisParams.setAxisCalcMode(KDChartAxisParams::AxisCalcLogarithmic);
00412 } else
00413 axisParams.setAxisCalcMode(KDChartAxisParams::AxisCalcLinear);
00414 params->setAxisParams( KDChartAxisParams::AxisPosLeft, axisParams );
00415 }
00416
00417 void KChartView::lineChart()
00418 {
00419 if ( m_chartline->isChecked() ) {
00420 forceAxisParams(true);
00421 KChartParams* params = ((KChartPart*)koDocument())->params();
00422
00423 params->setChartType( KChartParams::Line );
00424 params->setLineChartSubType( KDChartParams::LineNormal );
00425
00426 updateButton();
00427 update();
00428 ((KChartPart*)koDocument())->setModified(true);
00429 }
00430 else
00431 m_chartline->setChecked( true );
00432
00433 }
00434
00435
00436 void KChartView::barsChart()
00437 {
00438 if ( m_chartbars->isChecked() ) {
00439 forceAxisParams(false);
00440 KChartParams* params = ((KChartPart*)koDocument())->params();
00441
00442 params->setChartType( KChartParams::Bar );
00443 params->setBarChartSubType( KDChartParams::BarNormal );
00444
00445 updateButton();
00446 params->setThreeDBars( params->threeDPies() );
00447 update();
00448 ((KChartPart*)koDocument())->setModified(true);
00449 }
00450 else
00451 m_chartbars->setChecked( true );
00452 }
00453
00454
00455 void KChartView::areasChart()
00456 {
00457 if ( m_chartareas->isChecked() ) {
00458 forceAxisParams(false);
00459 KChartParams* params = ((KChartPart*)koDocument())->params();
00460
00461 params->setChartType( KChartParams::Area );
00462 params->setAreaChartSubType( KDChartParams::AreaNormal );
00463
00464 updateButton();
00465 update();
00466 ((KChartPart*)koDocument())->setModified(true);
00467 }
00468 else
00469 m_chartareas->setChecked( true );
00470
00471 }
00472
00473
00474 void KChartView::hiLoChart()
00475 {
00476 if ( m_charthilo->isChecked() ) {
00477 forceAxisParams(false);
00478 KChartParams* params = ((KChartPart*)koDocument())->params();
00479
00480 params->setChartType( KChartParams::HiLo );
00481 params->setHiLoChartSubType( KDChartParams::HiLoNormal );
00482
00483 updateButton();
00484 update();
00485 ((KChartPart*)koDocument())->setModified(true);
00486 }
00487 else
00488 m_charthilo->setChecked( true );
00489 }
00490
00491
00492 void KChartView::ringChart()
00493 {
00494 if ( m_chartring->isChecked() ) {
00495 forceAxisParams(false);
00496 KChartParams* params = ((KChartPart*)koDocument())->params();
00497
00498 params->setChartType( KChartParams::Ring );
00499
00500 updateButton();
00501 update();
00502 ((KChartPart*)koDocument())->setModified(true);
00503 }
00504 else
00505 m_chartring->setChecked( true );
00506
00507 }
00508
00509
00510 void KChartView::polarChart()
00511 {
00512 if ( m_chartpolar->isChecked() ) {
00513 forceAxisParams(false);
00514 KDChartParams* params = ((KChartPart*)koDocument())->params();
00515
00516 params->setChartType( KDChartParams::Polar );
00517 params->setPolarChartSubType( KDChartParams::PolarNormal );
00518
00519 update();
00520 ((KChartPart*)koDocument())->setModified(true);
00521 }
00522 else
00523 m_chartpolar->setChecked( true );
00524 }
00525
00526
00527 void KChartView::bwChart()
00528 {
00529 if ( m_chartbw->isChecked() ) {
00530 forceAxisParams(false);
00531 KDChartParams* params = ((KChartPart*)koDocument())->params();
00532
00533 params->setChartType( KDChartParams::BoxWhisker );
00534 params->setBWChartSubType( KDChartParams::BWNormal );
00535
00536 update();
00537 ((KChartPart*)koDocument())->setModified(true);
00538 }
00539 else
00540 m_chartbw->setChecked( true );
00541 }
00542
00543
00544 void KChartView::mousePressEvent ( QMouseEvent *e )
00545 {
00546 if (!koDocument()->isReadWrite() || !factory())
00547 return;
00548 if ( e->button() == RightButton )
00549 ((QPopupMenu*)factory()->container("action_popup",this))->popup(QCursor::pos());
00550 }
00551
00552
00553 void KChartView::slotConfigColor()
00554 {
00555 config(KChartConfigDialog::KC_COLORS);
00556 }
00557
00558
00559 void KChartView::slotConfigFont()
00560 {
00561 config(KChartConfigDialog::KC_FONT);
00562 }
00563
00564
00565 void KChartView::slotConfigBack()
00566 {
00567 config(KChartConfigDialog::KC_BACK);
00568 }
00569
00570
00571 void KChartView::slotConfigLegend()
00572 {
00573 config(KChartConfigDialog::KC_LEGEND);
00574 }
00575
00576 void KChartView::slotConfigDataFormat()
00577 {
00578 config(KChartConfigDialog::KC_DATAFORMAT);
00579 }
00580
00581 void KChartView::slotConfigSubTypeChart()
00582 {
00583 config(KChartConfigDialog::KC_SUBTYPE);
00584 }
00585
00586
00587 void KChartView::slotConfigHeaderFooterChart()
00588 {
00589 config(KChartConfigDialog::KC_HEADERFOOTER);
00590 }
00591
00592
00593
00594 void KChartView::updateButton()
00595 {
00596
00597 KChartParams* params = ((KChartPart*)koDocument())->params();
00598
00599 bool state=(params->chartType()==KChartParams::Bar ||
00600 params->chartType()==KChartParams::Area ||
00601 params->chartType()==KChartParams::Line ||
00602 params->chartType()==KChartParams::HiLo ||
00603 params->chartType()==KChartParams::Polar);
00604 m_subTypeChartConfig->setEnabled(state);
00605 }
00606
00607
00608 void KChartView::slotConfigPageLayout()
00609 {
00610 KChartParams *params = ((KChartPart*)koDocument())->params();
00611 KChartPageLayout *dialog = new KChartPageLayout(params, this,
00612 "Page Layout");
00613
00614 connect( dialog, SIGNAL( dataChanged() ),
00615 this, SLOT( slotRepaint() ) );
00616
00617 dialog->exec();
00618 delete dialog;
00619 }
00620
00621
00622 void KChartView::setupPrinter( KPrinter &printer )
00623 {
00624 if ( !printer.previewOnly() )
00625 printer.addDialogPage( new KChartPrinterDlg( 0, "KChart page" ) );
00626 }
00627
00628
00629 void KChartView::print(KPrinter &printer)
00630 {
00631 printer.setFullPage( false );
00632
00633 QPainter painter;
00634 painter.begin(&printer);
00635 QPaintDeviceMetrics pdm( &printer );
00636
00637 int height;
00638 int width;
00639 if ( !printer.previewOnly() ) {
00640 int const scalex = printer.option("kde-kchart-printsizex").toInt();
00641 int const scaley = printer.option("kde-kchart-printsizey").toInt();
00642
00643 width = pdm.width() * scalex / 100;
00644 height = pdm.height() * scaley / 100;
00645 }
00646 else {
00647
00648 width = pdm.width();
00649 height = pdm.height();
00650 }
00651
00652 QRect rect(0, 0, width, height);
00653 KDChart::print(&painter,
00654 ((KChartPart*)koDocument())->params(),
00655 ((KChartPart*)koDocument())->data(),
00656 0,
00657 &rect);
00658
00659 painter.end();
00660 }
00661
00662
00663
00664
00665
00666 void KChartView::importData()
00667 {
00668
00669 QString filename = KFileDialog::getOpenFileName(QString::null,
00670 QString::null,
00671 0,
00672 i18n("Import Data"));
00673 kdDebug(35001) << "Filename = <" << filename << ">" << endl;
00674 if (filename.isEmpty())
00675 return;
00676
00677
00678 QFile inFile(filename);
00679 if (!inFile.open(IO_ReadOnly)) {
00680 KMessageBox::sorry( 0, i18n("The file %1 could not be read.")
00681 .arg(filename) );
00682 inFile.close();
00683 return;
00684 }
00685
00686
00687 QByteArray inData( inFile.readAll() );
00688 inFile.close();
00689 CSVImportDialog *dialog = new CSVImportDialog(0L, inData);
00690
00691 if ( !dialog->exec() ) {
00692 kdDebug(35001) << "Cancel was pressed" << endl;
00693 return;
00694 }
00695
00696 kdDebug(35001) << "OK was pressed" << endl;
00697
00698 uint rows = dialog->rows();
00699 uint cols = dialog->cols();
00700
00701 kdDebug(35001) << "Rows: " << rows << " Cols: " << cols << endl;
00702
00703 bool hasRowHeaders = ( rows > 1 && dialog->firstRowContainHeaders() );
00704 bool hasColHeaders = ( cols > 1 && dialog->firstColContainHeaders() );
00705
00706 KDChartTableData data( rows, cols );
00707 data.setUsedRows( rows );
00708 data.setUsedCols( cols );
00709 for (uint row = 0; row < rows; row++) {
00710 for (uint col = 0; col < cols; col++) {
00711 bool ok;
00712 QString tmp;
00713 double val;
00714
00715
00716 tmp = dialog->text( row, col );
00717 if ( ( row == 0 && hasRowHeaders )
00718 || ( col == 0 && hasColHeaders ) ) {
00719 kdDebug(35001) << "Setting header (" << row << "," << col
00720 << ") to value " << tmp << endl;
00721 data.setCell( row, col, tmp );
00722 }
00723 else {
00724 val = tmp.toDouble(&ok);
00725 if (!ok)
00726 val = 0.0;
00727
00728 kdDebug(35001) << "Setting (" << row << "," << col
00729 << ") to value " << val << endl;
00730
00731
00732 data.setCell( row, col, val );
00733 }
00734 }
00735 }
00736
00737 ((KChartPart*)koDocument())->doSetData( data,
00738 hasRowHeaders, hasColHeaders );
00739 }
00740
00741
00742 void KChartView::extraCreateTemplate()
00743 {
00744 int width = 60;
00745 int height = 60;
00746 QPixmap pix = koDocument()->generatePreview(QSize(width, height));
00747
00748 KTempFile tempFile( QString::null, ".chrt" );
00749 tempFile.setAutoDelete(true);
00750
00751 koDocument()->saveNativeFormat( tempFile.name() );
00752
00753 KoTemplateCreateDia::createTemplate( "kchart_template", KChartFactory::global(),
00754 tempFile.name(), pix, this );
00755
00756 KChartFactory::global()->dirs()->addResourceType("kchart_template",
00757 KStandardDirs::kde_default( "data" ) +
00758 "kchart/templates/");
00759 }
00760
00761
00762 }
00763
00764 #include "kchart_view.moc"