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