File indexing completed on 2024-05-12 16:33:35
0001 /* This file is part of the KDE project 0002 0003 Copyright 2007-2008 Johannes Simon <johannes.simon@gmail.com> 0004 Copyright 2009 Inge Wallin <inge@lysator.liu.se> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 Boston, MA 02110-1301, USA. 0020 */ 0021 0022 // Own 0023 #include "PlotAreaConfigWidget.h" 0024 #include "ui_PlotAreaConfigWidget.h" 0025 0026 // Qt 0027 #include <QButtonGroup> 0028 #include <QComboBox> 0029 #include <QGridLayout> 0030 #include <QHBoxLayout> 0031 #include <QVBoxLayout> 0032 #include <QToolButton> 0033 #include <QMenu> 0034 #include <QPair> 0035 #include <QLatin1String> 0036 0037 // KF5 0038 #include <klocalizedstring.h> 0039 #include <kmessagebox.h> 0040 #include <kfontchooser.h> 0041 0042 // Calligra 0043 #include <interfaces/KoChartModel.h> 0044 #include <KoIcon.h> 0045 0046 // KChart 0047 #include <KChartChart> 0048 #include <KChartPosition> 0049 #include <KChartCartesianAxis> 0050 #include <KChartGridAttributes> 0051 #include <KChartPieAttributes> 0052 #include <KChartAbstractCartesianDiagram> 0053 #include <KChartLegend> 0054 #include <KChartDataValueAttributes> 0055 #include <KChartTextAttributes> 0056 #include <KChartMarkerAttributes> 0057 #include <KChartMeasure> 0058 0059 // KoChart 0060 #include "ChartProxyModel.h" 0061 #include "PlotArea.h" 0062 #include "Legend.h" 0063 #include "DataSet.h" 0064 #include "Axis.h" 0065 #include "ui_ChartTableEditor.h" 0066 #include "NewAxisDialog.h" 0067 #include "AxisScalingDialog.h" 0068 #include "FontEditorDialog.h" 0069 #include "FormatErrorBarDialog.h" 0070 #include "CellRegionDialog.h" 0071 #include "TableEditorDialog.h" 0072 #include "PieDataEditor.h" 0073 #include "BubbleDataEditor.h" 0074 #include "ScatterDataEditor.h" 0075 #include "StockDataEditor.h" 0076 #include "commands/ChartTypeCommand.h" 0077 #include "CellRegionStringValidator.h" 0078 #include "ChartTableModel.h" 0079 #include "TableSource.h" 0080 #include "AxesConfigWidget.h" 0081 #include "DataSetConfigWidget.h" 0082 #include "PieConfigWidget.h" 0083 #include "RingConfigWidget.h" 0084 #include "StockConfigWidget.h" 0085 #include "RadarDataSetConfigWidget.h" 0086 #include "ConfigSubWidgetBase.h" 0087 #include "ChartDebug.h" 0088 0089 using namespace KoChart; 0090 0091 class PlotAreaConfigWidget::Private 0092 { 0093 public: 0094 Private(PlotAreaConfigWidget *parent); 0095 ~Private(); 0096 0097 PlotAreaConfigWidget *q; 0098 0099 // Basic properties of the chart. 0100 ChartType type; 0101 ChartSubtype subtype; 0102 bool threeDMode; 0103 0104 Ui::PlotAreaConfigWidget ui; 0105 bool isExternalDataSource; 0106 0107 // Menus 0108 QMenu *dataSetBarChartMenu; 0109 QMenu *dataSetLineChartMenu; 0110 QMenu *dataSetAreaChartMenu; 0111 QMenu *dataSetRadarChartMenu; 0112 QMenu *dataSetStockChartMenu; 0113 0114 // chart type selection actions 0115 QAction *normalBarChartAction; 0116 QAction *stackedBarChartAction; 0117 QAction *percentBarChartAction; 0118 0119 QAction *normalLineChartAction; 0120 QAction *stackedLineChartAction; 0121 QAction *percentLineChartAction; 0122 0123 QAction *normalAreaChartAction; 0124 QAction *stackedAreaChartAction; 0125 QAction *percentAreaChartAction; 0126 0127 QAction *circleChartAction; 0128 QAction *ringChartAction; 0129 QAction *radarChartAction; 0130 QAction *filledRadarChartAction; 0131 0132 QAction *scatterChartAction; 0133 QAction *bubbleChartAction; 0134 0135 QAction *hlcStockChartAction; 0136 QAction *ohlcStockChartAction; 0137 QAction *candlestickStockChartAction; 0138 0139 QAction *surfaceChartAction; 0140 QAction *ganttChartAction; 0141 0142 // chart type selection actions for datasets 0143 QAction *dataSetNormalBarChartAction; 0144 QAction *dataSetStackedBarChartAction; 0145 QAction *dataSetPercentBarChartAction; 0146 0147 QAction *dataSetNormalLineChartAction; 0148 QAction *dataSetStackedLineChartAction; 0149 QAction *dataSetPercentLineChartAction; 0150 0151 QAction *dataSetNormalAreaChartAction; 0152 QAction *dataSetStackedAreaChartAction; 0153 QAction *dataSetPercentAreaChartAction; 0154 0155 QAction *dataSetCircleChartAction; 0156 QAction *dataSetRingChartAction; 0157 QAction *dataSetRadarChartAction; 0158 QAction *dataSetFilledRadarChartAction; 0159 QAction *dataSetScatterChartAction; 0160 QAction *dataSetBubbleChartAction; 0161 0162 QAction *dataSetHLCStockChartAction; 0163 QAction *dataSetOHLCStockChartAction; 0164 QAction *dataSetCandlestickStockChartAction; 0165 0166 QAction *dataSetSurfaceChartAction; 0167 QAction *dataSetGanttChartAction; 0168 0169 // Table Editor (a.k.a. the data editor) 0170 TableEditorDialog *tableEditorDialog; 0171 // Source containing all tables the chart uses (name/model pairs) 0172 TableSource *tableSource; 0173 0174 0175 QList<DataSet*> dataSets; 0176 int selectedDataSet; 0177 int selectedDataSet_CellRegionDialog; 0178 0179 0180 // Dialogs 0181 CellRegionDialog *cellRegionDialog; 0182 0183 CellRegionStringValidator *cellRegionStringValidator; 0184 }; 0185 0186 0187 PlotAreaConfigWidget::Private::Private(PlotAreaConfigWidget *parent) 0188 : q(parent) 0189 , tableEditorDialog(0) 0190 , cellRegionDialog(0) 0191 { 0192 selectedDataSet = 0; 0193 tableSource = 0; 0194 0195 type = KoChart::LastChartType; 0196 subtype = KoChart::NoChartSubtype; 0197 threeDMode = false; 0198 0199 isExternalDataSource = false; 0200 cellRegionStringValidator = 0; 0201 0202 dataSetBarChartMenu = 0; 0203 dataSetLineChartMenu = 0; 0204 dataSetAreaChartMenu = 0; 0205 dataSetRadarChartMenu = 0; 0206 dataSetStockChartMenu = 0; 0207 dataSetNormalBarChartAction = 0; 0208 dataSetStackedBarChartAction = 0; 0209 dataSetPercentBarChartAction = 0; 0210 dataSetNormalLineChartAction = 0; 0211 dataSetStackedLineChartAction = 0; 0212 dataSetPercentLineChartAction = 0; 0213 dataSetNormalAreaChartAction = 0; 0214 dataSetStackedAreaChartAction = 0; 0215 dataSetPercentAreaChartAction = 0; 0216 dataSetCircleChartAction = 0; 0217 dataSetRingChartAction = 0; 0218 dataSetScatterChartAction = 0; 0219 dataSetRadarChartAction = 0; 0220 dataSetFilledRadarChartAction = 0; 0221 dataSetHLCStockChartAction = 0; 0222 dataSetOHLCStockChartAction = 0; 0223 dataSetCandlestickStockChartAction = 0; 0224 dataSetBubbleChartAction = 0; 0225 dataSetSurfaceChartAction = 0; 0226 dataSetGanttChartAction = 0; 0227 } 0228 0229 PlotAreaConfigWidget::Private::~Private() 0230 { 0231 } 0232 0233 0234 // ================================================================ 0235 // class PlotAreaConfigWidget 0236 0237 PlotAreaConfigWidget::PlotAreaConfigWidget() 0238 : d(new Private(this)) 0239 { 0240 setObjectName("PlotArea"); 0241 d->ui.setupUi(this); 0242 0243 setupWidgets(); 0244 // Chart type button with its associated menu 0245 QMenu *chartTypeMenu = new QMenu(i18n("Chart Type"), this); 0246 chartTypeMenu->setIcon(ICON1(BarChartType)); 0247 0248 // Bar charts 0249 QMenu *barChartMenu = chartTypeMenu->addMenu(ICON1(BarChartType), i18n("Bar Chart")); 0250 d->normalBarChartAction = barChartMenu->addAction(ICON2(BarChartType, NormalChartSubtype), i18n("Normal")); 0251 d->stackedBarChartAction = barChartMenu->addAction(ICON2(BarChartType, StackedChartSubtype), i18n("Stacked")); 0252 d->percentBarChartAction = barChartMenu->addAction(ICON2(BarChartType, PercentChartSubtype), i18n("Percent")); 0253 0254 // Line charts 0255 QMenu *lineChartMenu = chartTypeMenu->addMenu(ICON1(LineChartType), i18n("Line Chart")); 0256 d->normalLineChartAction = lineChartMenu->addAction(ICON2(LineChartType, NormalChartSubtype), i18n("Normal")); 0257 d->stackedLineChartAction = lineChartMenu->addAction(ICON2(LineChartType, StackedChartSubtype), i18n("Stacked")); 0258 d->percentLineChartAction = lineChartMenu->addAction(ICON2(LineChartType, PercentChartSubtype), i18n("Percent")); 0259 0260 // Area charts 0261 QMenu *areaChartMenu = chartTypeMenu->addMenu(ICON1(AreaChartType), i18n("Area Chart")); 0262 d->normalAreaChartAction = areaChartMenu->addAction(ICON2(AreaChartType, NormalChartSubtype), i18n("Normal")); 0263 d->stackedAreaChartAction = areaChartMenu->addAction(ICON2(AreaChartType, StackedChartSubtype), i18n("Stacked")); 0264 d->percentAreaChartAction = areaChartMenu->addAction(ICON2(AreaChartType, PercentChartSubtype), i18n("Percent")); 0265 0266 chartTypeMenu->addSeparator(); 0267 0268 // Circular charts: pie and ring 0269 d->circleChartAction = chartTypeMenu->addAction(ICON1(CircleChartType), i18n("Pie Chart")); 0270 d->ringChartAction = chartTypeMenu->addAction(ICON1(RingChartType), i18n("Ring Chart")); 0271 0272 chartTypeMenu->addSeparator(); 0273 0274 // Polar charts: radar 0275 QMenu *radarChartMenu = chartTypeMenu->addMenu(ICON1(RadarChartType), i18n("Polar Chart")); 0276 d->radarChartAction = radarChartMenu->addAction(ICON2(RadarChartType, NoChartSubtype), i18n("Normal")); 0277 d->filledRadarChartAction = radarChartMenu->addAction(ICON2(FilledRadarChartType, NoChartSubtype), i18n("Filled")); // Whay is Filled... not subtype? 0278 0279 chartTypeMenu->addSeparator(); 0280 0281 // X/Y charts: scatter and bubble 0282 d->scatterChartAction = chartTypeMenu->addAction(ICON1(ScatterChartType), i18n("Scatter Chart")); 0283 d->bubbleChartAction = chartTypeMenu->addAction(ICON1(BubbleChartType), i18n("Bubble Chart")); 0284 0285 chartTypeMenu->addSeparator(); 0286 0287 // Stock Charts 0288 QMenu *stockChartMenu = chartTypeMenu->addMenu(ICON1(StockChartType), i18n("Stock Chart")); 0289 d->candlestickStockChartAction = stockChartMenu->addAction(ICON2(StockChartType, CandlestickChartSubtype), i18n("Candlestick")); 0290 d->ohlcStockChartAction = stockChartMenu->addAction(ICON2(StockChartType, OpenHighLowCloseChartSubtype), i18n("OpenHighLowClose")); 0291 d->hlcStockChartAction = stockChartMenu->addAction(ICON2(StockChartType, HighLowCloseChartSubtype), i18n("HighLowClose")); 0292 0293 // Not supported 0294 d->surfaceChartAction = chartTypeMenu->addAction(i18n("Surface Chart")); 0295 d->surfaceChartAction->setEnabled(false); 0296 d->ganttChartAction = chartTypeMenu->addAction(i18n("Gantt Chart")); 0297 d->ganttChartAction->setEnabled(false); 0298 0299 d->ui.chartTypeMenu->setMenu(chartTypeMenu); 0300 d->ui.chartTypeMenu->setIconSize(QSize(32, 32)); 0301 0302 connect(chartTypeMenu, SIGNAL(triggered(QAction*)), 0303 this, SLOT(chartTypeSelected(QAction*))); 0304 0305 0306 connect(d->ui.threeDLook, SIGNAL(toggled(bool)), 0307 this, SLOT(setThreeDMode(bool))); 0308 0309 connect(d->ui.chartOrientation, SIGNAL(currentIndexChanged(int)), this, SLOT(ui_chartOrientationChanged(int))); 0310 0311 setupDialogs(); 0312 createActions(); 0313 0314 } 0315 0316 PlotAreaConfigWidget::~PlotAreaConfigWidget() 0317 { 0318 deactivate(); 0319 delete d; 0320 } 0321 0322 AxesConfigWidget *PlotAreaConfigWidget::cartesianAxesConfigWidget() const 0323 { 0324 return d->ui.cartesianAxes; 0325 } 0326 0327 DataSetConfigWidget *PlotAreaConfigWidget::cartesianDataSetConfigWidget() const 0328 { 0329 return d->ui.cartesianDataSets; 0330 } 0331 0332 PieConfigWidget *PlotAreaConfigWidget::pieConfigWidget() const 0333 { 0334 return d->ui.pieConfigWidget; 0335 } 0336 0337 RingConfigWidget *PlotAreaConfigWidget::ringConfigWidget() const 0338 { 0339 return d->ui.ringConfigWidget; 0340 } 0341 0342 StockConfigWidget *PlotAreaConfigWidget::stockConfigWidget() const 0343 { 0344 return d->ui.stockConfigWidget; 0345 } 0346 0347 AxesConfigWidget *PlotAreaConfigWidget::stockAxesConfigWidget() const 0348 { 0349 return d->ui.stockAxes; 0350 } 0351 0352 RadarDataSetConfigWidget *PlotAreaConfigWidget::radarDataSetConfigWidget() const 0353 { 0354 return d->ui.radarDataSets; 0355 } 0356 0357 void PlotAreaConfigWidget::deleteSubDialogs(ChartType type) 0358 { 0359 if (!chart->usesInternalModelOnly()) { 0360 switch (type) { 0361 case BarChartType: 0362 case LineChartType: 0363 case AreaChartType: 0364 case RingChartType: 0365 case RadarChartType: 0366 case FilledRadarChartType: 0367 case ScatterChartType: 0368 case SurfaceChartType: 0369 case StockChartType: 0370 case CircleChartType: 0371 delete d->cellRegionDialog; 0372 d->cellRegionDialog = 0; 0373 break; 0374 // case BubbleChartType: 0375 // delete findChildren<ExternalBubbleDataEditor*>().value(0); 0376 // break; 0377 default: 0378 delete d->cellRegionDialog; 0379 d->cellRegionDialog = 0; 0380 // delete findChildren<ExternalBubbleDataEditor*>().value(0); 0381 break; 0382 } 0383 } else { 0384 switch (type) { 0385 case BarChartType: 0386 case LineChartType: 0387 case AreaChartType: 0388 case RingChartType: 0389 case RadarChartType: 0390 case FilledRadarChartType: 0391 case SurfaceChartType: 0392 case StockChartType: 0393 delete findChildren<StockDataEditor*>().value(0); 0394 break; 0395 case CircleChartType: 0396 delete findChildren<PieDataEditor*>().value(0); 0397 break; 0398 case BubbleChartType: 0399 delete findChildren<BubbleDataEditor*>().value(0); 0400 break; 0401 case ScatterChartType: 0402 delete findChildren<ScatterDataEditor*>().value(0); 0403 break; 0404 default: 0405 delete d->tableEditorDialog; 0406 d->tableEditorDialog = 0; 0407 delete findChildren<PieDataEditor*>().value(0); 0408 delete findChildren<BubbleDataEditor*>().value(0); 0409 delete findChildren<ScatterDataEditor*>().value(0); 0410 delete findChildren<StockDataEditor*>().value(0); 0411 break; 0412 } 0413 } 0414 } 0415 0416 void PlotAreaConfigWidget::deactivate() 0417 { 0418 debugChartUiPlotArea; 0419 disconnect(d->ui.editData); 0420 d->tableSource = 0; 0421 ConfigWidgetBase::deactivate(); 0422 } 0423 void PlotAreaConfigWidget::open(KoShape* shape) 0424 { 0425 debugChartUiPlotArea; 0426 ConfigWidgetBase::open(shape); 0427 if (!chart) { 0428 return; 0429 } 0430 for (ConfigSubWidgetBase *w : findChildren<ConfigSubWidgetBase*>()) { 0431 w->open(chart); 0432 } 0433 0434 d->tableSource = chart->tableSource(); 0435 0436 connect(d->ui.editData, &QPushButton::clicked, this, &PlotAreaConfigWidget::slotShowTableEditor); 0437 updateData(); 0438 } 0439 0440 void PlotAreaConfigWidget::setupWidgets() 0441 { 0442 QList<ChartType> types; 0443 types << BarChartType << LineChartType << AreaChartType << BubbleChartType << ScatterChartType; 0444 cartesianAxesConfigWidget()->setChartTypes(types); 0445 cartesianDataSetConfigWidget()->setChartTypes(types); 0446 0447 pieConfigWidget()->setChartTypes(QList<ChartType>()<<CircleChartType); 0448 ringConfigWidget()->setChartTypes(QList<ChartType>()<<RingChartType); 0449 stockConfigWidget()->setChartTypes(QList<ChartType>()<<StockChartType); 0450 stockAxesConfigWidget()->setChartTypes(QList<ChartType>()<<StockChartType); 0451 radarDataSetConfigWidget()->setChartTypes(QList<ChartType>() << RadarChartType << FilledRadarChartType); 0452 } 0453 0454 QAction *PlotAreaConfigWidget::createAction() 0455 { 0456 return 0; 0457 } 0458 0459 void PlotAreaConfigWidget::chartTypeSelected(QAction *action) 0460 { 0461 ChartType type = LastChartType; 0462 ChartSubtype subtype = NoChartSubtype; 0463 0464 // Bar charts 0465 if (action == d->normalBarChartAction) { 0466 type = BarChartType; 0467 subtype = NormalChartSubtype; 0468 } else if (action == d->stackedBarChartAction) { 0469 type = BarChartType; 0470 subtype = StackedChartSubtype; 0471 } else if (action == d->percentBarChartAction) { 0472 type = BarChartType; 0473 subtype = PercentChartSubtype; 0474 } 0475 0476 // Line charts 0477 else if (action == d->normalLineChartAction) { 0478 type = LineChartType; 0479 subtype = NormalChartSubtype; 0480 } else if (action == d->stackedLineChartAction) { 0481 type = LineChartType; 0482 subtype = StackedChartSubtype; 0483 } else if (action == d->percentLineChartAction) { 0484 type = LineChartType; 0485 subtype = PercentChartSubtype; 0486 } 0487 0488 // Area charts 0489 else if (action == d->normalAreaChartAction) { 0490 type = AreaChartType; 0491 subtype = NormalChartSubtype; 0492 } else if (action == d->stackedAreaChartAction) { 0493 type = AreaChartType; 0494 subtype = StackedChartSubtype; 0495 } else if (action == d->percentAreaChartAction) { 0496 type = AreaChartType; 0497 subtype = PercentChartSubtype; 0498 } 0499 0500 // also known as polar chart. 0501 else if (action == d->radarChartAction) { 0502 type = RadarChartType; 0503 subtype = NormalChartSubtype; 0504 } 0505 else if (action == d->filledRadarChartAction) { 0506 type = FilledRadarChartType; 0507 subtype = NormalChartSubtype; 0508 } 0509 0510 // Also known as pie chart 0511 else if (action == d->circleChartAction) { 0512 type = CircleChartType; 0513 subtype = NoChartSubtype; 0514 } 0515 else if (action == d->ringChartAction) { 0516 type = RingChartType; 0517 subtype = NoChartSubtype; 0518 } 0519 0520 else if (action == d->scatterChartAction) { 0521 type = ScatterChartType; 0522 subtype = NoChartSubtype; 0523 } 0524 0525 // Stock charts 0526 else if (action == d->hlcStockChartAction) { 0527 type = StockChartType; 0528 subtype = HighLowCloseChartSubtype; 0529 } 0530 0531 else if (action == d->ohlcStockChartAction) { 0532 type = StockChartType; 0533 subtype = OpenHighLowCloseChartSubtype; 0534 } 0535 0536 else if (action == d->candlestickStockChartAction) { 0537 type = StockChartType; 0538 subtype = CandlestickChartSubtype; 0539 } 0540 0541 else if (action == d->bubbleChartAction) { 0542 type = BubbleChartType; 0543 subtype = NoChartSubtype; 0544 } 0545 0546 else if (action == d->surfaceChartAction) { 0547 type = SurfaceChartType; 0548 subtype = NoChartSubtype; 0549 } 0550 0551 else if (action == d->ganttChartAction) { 0552 type = GanttChartType; 0553 subtype = NoChartSubtype; 0554 } 0555 0556 emit chartTypeChanged(type, subtype); 0557 updateData(); 0558 } 0559 0560 void PlotAreaConfigWidget::setThreeDMode(bool threeD) 0561 { 0562 d->threeDMode = threeD; 0563 emit threeDModeToggled(threeD); 0564 0565 updateData(); 0566 } 0567 0568 void PlotAreaConfigWidget::ui_chartOrientationChanged(int value) 0569 { 0570 emit chartOrientationChanged(static_cast<Qt::Orientation>(value+1)); 0571 } 0572 0573 /** 0574 * Only some chart types support a 3D mode in KD Chart. 0575 */ 0576 static bool supportsThreeD(ChartType type) 0577 { 0578 switch (type) { 0579 case BarChartType: 0580 case LineChartType: 0581 case AreaChartType: 0582 case CircleChartType: 0583 case BubbleChartType: 0584 return true; 0585 default: 0586 break; 0587 } 0588 return false; 0589 } 0590 0591 0592 void PlotAreaConfigWidget::updateData() 0593 { 0594 if (!chart) { 0595 return; 0596 } 0597 if (chart->chartType() != d->type) { 0598 deleteSubDialogs(chart->chartType()); 0599 } 0600 switch (chart->chartType()) { 0601 case CircleChartType: 0602 d->ui.stackedWidget->setCurrentIndex(1); 0603 break; 0604 case StockChartType: 0605 d->ui.stackedWidget->setCurrentIndex(2); 0606 break; 0607 case RadarChartType: 0608 case FilledRadarChartType: 0609 d->ui.stackedWidget->setCurrentIndex(3); 0610 break; 0611 case RingChartType: 0612 d->ui.stackedWidget->setCurrentIndex(4); 0613 break; 0614 default: 0615 d->ui.stackedWidget->setCurrentIndex(0); 0616 break; 0617 } 0618 blockSignals(true); 0619 debugChartUiPlotArea<<"chart:"<<chart->chartType()<<','<<chart->chartSubType()<<"current:"<<d->type<<','<<d->subtype; 0620 if (d->type != chart->chartType() || d->subtype != chart->chartSubType()) { 0621 // Set the chart type icon in the chart type button. 0622 const QLatin1String iconName = chartTypeIconName(chart->chartType(), chart->chartSubType()); 0623 debugChartUiPlotArea<<iconName; 0624 if (iconName.size() > 0) { 0625 d->ui.chartTypeMenu->setIcon(QIcon::fromTheme(iconName)); 0626 } 0627 d->type = chart->chartType(); 0628 d->subtype = chart->chartSubType(); 0629 } 0630 // Only bar chart has orientation 0631 d->ui.chartOrientation->setVisible(d->type == BarChartType); 0632 d->ui.chartOrientation->setCurrentIndex(chart->plotArea()->isVertical() ? 1 : 0); 0633 // If the "3D" checkbox is checked, then adapt the chart to that. 0634 bool enableThreeDOption = supportsThreeD(d->type); 0635 d->threeDMode = enableThreeDOption && chart->isThreeD(); 0636 chart->setThreeD(d->threeDMode); 0637 d->ui.threeDLook->setChecked(d->threeDMode); 0638 d->ui.threeDLook->setEnabled(enableThreeDOption); 0639 0640 if (d->cellRegionDialog) { 0641 int idx = d->cellRegionDialog->dataSets->currentIndex(); 0642 if (d->dataSets != chart->plotArea()->dataSets()) { 0643 blockSignals(d->cellRegionDialog, true); 0644 idx = 0; 0645 d->dataSets = chart->plotArea()->dataSets(); 0646 d->cellRegionDialog->dataSets->clear(); 0647 int i = 1; 0648 foreach (DataSet *dataSet, d->dataSets) { 0649 QString title = dataSet->labelData().toString(); 0650 if (title.isEmpty()) 0651 title = i18n("Data Set %1", i++); 0652 d->cellRegionDialog->dataSets->addItem(title); 0653 } 0654 blockSignals(d->cellRegionDialog, false); 0655 } 0656 ui_dataSetSelectionChanged_CellRegionDialog(idx); 0657 } 0658 blockSignals(false); 0659 0660 for (ConfigSubWidgetBase *w : findChildren<ConfigSubWidgetBase*>()) { 0661 w->updateData(d->type, d->subtype); 0662 } 0663 } 0664 0665 0666 void PlotAreaConfigWidget::slotShowTableEditor() 0667 { 0668 if (!chart->usesInternalModelOnly()) { 0669 debugChartUiPlotArea<<"external"; 0670 switch (chart->chartType()) { 0671 // case BubbleChartType: { 0672 // ExternalBubbleDataEditor *dlg = findChildren<ExternalBubbleDataEditor*>().value(0); 0673 // if (!dlg) { 0674 // dlg = new ExternalBubbleDataEditor(chart, this); 0675 // connect(dlg, SIGNAL(finished()), dlg, SLOT(hide())); 0676 // connect(dlg, &ExternalBubbleDataEditor::xDataChanged, this, &PlotAreaConfigWidget::dataSetXDataRegionChanged); 0677 // connect(dlg, &ExternalBubbleDataEditor::yDataChanged, this, &PlotAreaConfigWidget::dataSetYDataRegionChanged); 0678 // connect(dlg, &ExternalBubbleDataEditor::bubbleDataChanged, this, &PlotAreaConfigWidget::dataSetCustomDataRegionChanged); 0679 // } 0680 // dlg->show(); 0681 // dlg->raise(); 0682 // return; 0683 // } 0684 default: { 0685 if (!d->cellRegionDialog) { 0686 d->cellRegionDialog = new CellRegionDialog; 0687 // FIXME: CellRegion itself together with a TableSource should now be used 0688 // to validate the correctness of a table range address. 0689 #if 0 0690 d->cellRegionStringValidator = new CellRegionStringValidator(spreadSheetModel); 0691 d->cellRegionDialog->labelDataRegion->setValidator(d->cellRegionStringValidator); 0692 d->cellRegionDialog->xDataRegion->setValidator(d->cellRegionStringValidator); 0693 d->cellRegionDialog->yDataRegion->setValidator(d->cellRegionStringValidator); 0694 d->cellRegionDialog->categoryDataRegion->setValidator(d->cellRegionStringValidator); 0695 #endif 0696 d->dataSets = chart->plotArea()->dataSets(); 0697 d->cellRegionDialog->dataSets->clear(); 0698 int i = 1; 0699 foreach (DataSet *dataSet, d->dataSets) { 0700 QString title = dataSet->labelData().toString(); 0701 if (title.isEmpty()) 0702 title = i18n("Data Set %1", i++); 0703 d->cellRegionDialog->dataSets->addItem(title); 0704 } 0705 ui_dataSetSelectionChanged_CellRegionDialog(0); 0706 0707 debugChartUiPlotArea<<"external data source"; 0708 connect(d->cellRegionDialog->xDataRegion, SIGNAL(editingFinished()), 0709 this, SLOT(ui_dataSetXDataRegionChanged())); 0710 connect(d->cellRegionDialog->yDataRegion, SIGNAL(editingFinished()), 0711 this, SLOT(ui_dataSetYDataRegionChanged())); 0712 connect(d->cellRegionDialog->labelDataRegion, SIGNAL(editingFinished()), 0713 this, SLOT(ui_dataSetLabelDataRegionChanged())); 0714 // connect(d->cellRegionDialog->bubbleDataRegion, SIGNAL(textEdited(QString)), 0715 // this, SLOT(ui_dataSetCustomDataRegionChanged(QString))); 0716 connect(d->cellRegionDialog->categoryDataRegion, SIGNAL(editingFinished()), 0717 this, SLOT(ui_dataSetCategoryDataRegionChanged())); 0718 connect(d->cellRegionDialog->dataSets, SIGNAL(currentIndexChanged(int)), 0719 this, SLOT(ui_dataSetSelectionChanged_CellRegionDialog(int))); 0720 } 0721 d->cellRegionDialog->show(); 0722 d->cellRegionDialog->raise(); 0723 return; 0724 } 0725 } 0726 } else { 0727 debugChartUiPlotArea<<"internal only"; 0728 switch (chart->chartType()) { 0729 case CircleChartType: { 0730 PieDataEditor *dlg = findChildren<PieDataEditor*>().value(0); 0731 if (!dlg) { 0732 dlg = new PieDataEditor(this); 0733 dlg->setModel(chart->internalModel()); 0734 connect(dlg, SIGNAL(finished()), dlg, SLOT(hide())); 0735 } 0736 dlg->show(); 0737 dlg->raise(); 0738 return; 0739 } 0740 case BubbleChartType: { 0741 BubbleDataEditor *dlg = findChildren<BubbleDataEditor*>().value(0); 0742 if (!dlg) { 0743 dlg = new BubbleDataEditor(chart, this); 0744 connect(dlg, SIGNAL(finished()), dlg, SLOT(hide())); 0745 connect(dlg, &BubbleDataEditor::xDataChanged, this, &PlotAreaConfigWidget::dataSetXDataRegionChanged); 0746 connect(dlg, &BubbleDataEditor::yDataChanged, this, &PlotAreaConfigWidget::dataSetYDataRegionChanged); 0747 connect(dlg, &BubbleDataEditor::bubbleDataChanged, this, &PlotAreaConfigWidget::dataSetCustomDataRegionChanged); 0748 } 0749 dlg->show(); 0750 dlg->raise(); 0751 return; 0752 } 0753 case ScatterChartType: { 0754 ScatterDataEditor *dlg = findChildren<ScatterDataEditor*>().value(0); 0755 if (!dlg) { 0756 dlg = new ScatterDataEditor(chart, this); 0757 connect(dlg, SIGNAL(finished()), dlg, SLOT(hide())); 0758 connect(dlg, &ScatterDataEditor::xDataChanged, this, &PlotAreaConfigWidget::dataSetXDataRegionChanged); 0759 connect(dlg, &ScatterDataEditor::yDataChanged, this, &PlotAreaConfigWidget::dataSetYDataRegionChanged); 0760 } 0761 dlg->show(); 0762 dlg->raise(); 0763 return; 0764 } 0765 case StockChartType: { 0766 StockDataEditor *dlg = findChildren<StockDataEditor*>().value(0); 0767 if (!dlg) { 0768 dlg = new StockDataEditor(chart, this); 0769 connect(dlg, SIGNAL(finished()), dlg, SLOT(hide())); 0770 // connect(dlg, &StockDataEditor::xDataChanged, this, &PlotAreaConfigWidget::dataSetXDataRegionChanged); 0771 // connect(dlg, &StockDataEditor::yDataChanged, this, &PlotAreaConfigWidget::dataSetYDataRegionChanged); 0772 } 0773 dlg->show(); 0774 dlg->raise(); 0775 return; 0776 } 0777 default: { 0778 if (!d->tableEditorDialog) { 0779 d->tableEditorDialog = new TableEditorDialog; 0780 d->tableEditorDialog->setProxyModel(chart->proxyModel()); 0781 d->tableEditorDialog->setModel(chart->internalModel()); 0782 } 0783 d->tableEditorDialog->show(); 0784 d->tableEditorDialog->raise(); 0785 return; 0786 } 0787 } 0788 } 0789 } 0790 0791 0792 void PlotAreaConfigWidget::slotShowCellRegionDialog() 0793 { 0794 // Update regions of selected dataset 0795 int selectedDataSet = d->cellRegionDialog->dataSets->currentIndex(); 0796 ui_dataSetSelectionChanged_CellRegionDialog(selectedDataSet); 0797 0798 d->cellRegionDialog->show(); 0799 } 0800 0801 void PlotAreaConfigWidget::setupDialogs() 0802 { 0803 } 0804 0805 void PlotAreaConfigWidget::createActions() 0806 { 0807 } 0808 0809 0810 0811 void PlotAreaConfigWidget::ui_dataSetXDataRegionChanged() 0812 { 0813 // Check for valid index 0814 if (d->selectedDataSet_CellRegionDialog < 0) 0815 return; 0816 0817 const QString regionString = d->cellRegionDialog->xDataRegion->text(); 0818 const CellRegion region(d->tableSource, regionString); 0819 0820 DataSet *dataSet = d->dataSets[d->selectedDataSet_CellRegionDialog]; 0821 0822 emit dataSetXDataRegionChanged(dataSet, region); 0823 } 0824 0825 void PlotAreaConfigWidget::ui_dataSetYDataRegionChanged() 0826 { 0827 // Check for valid index 0828 if (d->selectedDataSet_CellRegionDialog < 0) 0829 return; 0830 0831 const QString regionString = d->cellRegionDialog->yDataRegion->text(); 0832 const CellRegion region(d->tableSource, regionString); 0833 0834 DataSet *dataSet = d->dataSets[d->selectedDataSet_CellRegionDialog]; 0835 0836 emit dataSetYDataRegionChanged(dataSet, region); 0837 } 0838 0839 void PlotAreaConfigWidget::ui_dataSetCustomDataRegionChanged() 0840 { 0841 // Check for valid index 0842 if (d->selectedDataSet_CellRegionDialog < 0) 0843 return; 0844 0845 // const QString regionString = d->cellRegionDialog->bubbleDataRegion->text(); 0846 // const CellRegion region(d->tableSource, regionString); 0847 // 0848 // DataSet *dataSet = d->dataSets[d->selectedDataSet_CellRegionDialog]; 0849 // 0850 // emit dataSetCustomDataRegionChanged(dataSet, region); 0851 0852 } 0853 0854 void PlotAreaConfigWidget::ui_dataSetCategoryDataRegionChanged() 0855 { 0856 // Check for valid index 0857 if (d->selectedDataSet_CellRegionDialog < 0) 0858 return; 0859 0860 const QString regionString = d->cellRegionDialog->categoryDataRegion->text(); 0861 const CellRegion region(d->tableSource, regionString); 0862 0863 DataSet *dataSet = d->dataSets[d->selectedDataSet_CellRegionDialog]; 0864 0865 emit dataSetCategoryDataRegionChanged(dataSet, region); 0866 } 0867 0868 void PlotAreaConfigWidget::ui_dataSetLabelDataRegionChanged() 0869 { 0870 // Check for valid index 0871 if (d->selectedDataSet_CellRegionDialog < 0 || d->selectedDataSet_CellRegionDialog >= d->dataSets.count()) { 0872 return; 0873 } 0874 const QString regionString = d->cellRegionDialog->labelDataRegion->text(); 0875 const CellRegion region(d->tableSource, regionString); 0876 0877 DataSet *dataSet = d->dataSets[d->selectedDataSet_CellRegionDialog]; 0878 0879 emit dataSetLabelDataRegionChanged(dataSet, region); 0880 0881 // label may have changed 0882 QString title = dataSet->labelData().toString(); 0883 if (title.isEmpty()) { 0884 title = i18n("Data Set %1", d->selectedDataSet_CellRegionDialog); 0885 } 0886 d->cellRegionDialog->dataSets->setItemText(d->selectedDataSet_CellRegionDialog, title); 0887 } 0888 0889 0890 void PlotAreaConfigWidget::ui_dataSetSelectionChanged_CellRegionDialog(int index) 0891 { 0892 // Check for valid index 0893 debugChartUiPlotArea<<index<<d->dataSets; 0894 if (index < 0 || index >= d->dataSets.size()) 0895 return; 0896 0897 DataSet *dataSet = d->dataSets[index]; 0898 const int dimensions = dataSet->dimension(); 0899 0900 blockSignals(d->cellRegionDialog, true); 0901 0902 d->cellRegionDialog->labelDataRegion->setText(dataSet->labelDataRegion().toString()); 0903 debugChartUiPlotArea<<"dim"<<dimensions; 0904 if (dimensions > 1) { 0905 d->cellRegionDialog->xDataRegion->setEnabled(true); 0906 d->cellRegionDialog->xDataRegion->setText(dataSet->xDataRegion().toString()); 0907 } else { 0908 d->cellRegionDialog->xDataRegion->setEnabled(false); 0909 } 0910 d->cellRegionDialog->yDataRegion->setText(dataSet->yDataRegion().toString()); 0911 d->cellRegionDialog->categoryDataRegion->setText(dataSet->categoryDataRegion().toString()); 0912 0913 d->selectedDataSet_CellRegionDialog = index; 0914 0915 blockSignals(d->cellRegionDialog, false); 0916 } 0917