File indexing completed on 2024-05-12 15:27:56
0001 /*************************************************************************** 0002 File : CartesianPlotDock.cpp 0003 Project : LabPlot 0004 Description : widget for cartesian plot properties 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2011-2020 by Alexander Semke (alexander.semke@web.de) 0007 Copyright : (C) 2012-2013 by Stefan Gerlach (stefan.gerlach@uni-konstanz.de) 0008 0009 ***************************************************************************/ 0010 0011 /*************************************************************************** 0012 * * 0013 * This program is free software; you can redistribute it and/or modify * 0014 * it under the terms of the GNU General Public License as published by * 0015 * the Free Software Foundation; either version 2 of the License, or * 0016 * (at your option) any later version. * 0017 * * 0018 * This program is distributed in the hope that it will be useful, * 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0021 * GNU General Public License for more details. * 0022 * * 0023 * You should have received a copy of the GNU General Public License * 0024 * along with this program; if not, write to the Free Software * 0025 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0026 * Boston, MA 02110-1301 USA * 0027 * * 0028 ***************************************************************************/ 0029 0030 #include "CartesianPlotDock.h" 0031 #include "backend/worksheet/plots/PlotArea.h" 0032 #include "backend/worksheet/plots/cartesian/XYCurve.h" 0033 #include "backend/core/column/Column.h" 0034 0035 #include "kdefrontend/widgets/LabelWidget.h" 0036 #include "kdefrontend/GuiTools.h" 0037 #include "kdefrontend/TemplateHandler.h" 0038 #include "kdefrontend/ThemeHandler.h" 0039 0040 #include <QCompleter> 0041 #include <QPainter> 0042 #include <QTimer> 0043 #include <QDir> 0044 #include <QDirModel> 0045 #include <QFileDialog> 0046 #include <QImageReader> 0047 #include <QButtonGroup> 0048 #include <QIntValidator> 0049 0050 /*! 0051 \class CartesianPlotDock 0052 \brief Provides a widget for editing the properties of the cartesian plot currently selected in the project explorer. 0053 0054 \ingroup kdefrontend 0055 */ 0056 0057 CartesianPlotDock::CartesianPlotDock(QWidget* parent) : BaseDock(parent) { 0058 ui.setupUi(this); 0059 m_leName = ui.leName; 0060 m_leComment = ui.leComment; 0061 0062 //"General"-tab 0063 auto* rangeButtonsGroup(new QButtonGroup); 0064 rangeButtonsGroup->addButton(ui.rbRangeFirst); 0065 rangeButtonsGroup->addButton(ui.rbRangeLast); 0066 rangeButtonsGroup->addButton(ui.rbRangeFree); 0067 0068 ui.leXMin->setValidator(new QDoubleValidator(ui.leXMin)); 0069 ui.leXMax->setValidator(new QDoubleValidator(ui.leXMax)); 0070 ui.leYMin->setValidator(new QDoubleValidator(ui.leYMin)); 0071 ui.leYMax->setValidator(new QDoubleValidator(ui.leYMax)); 0072 0073 //"Range breaks"-tab 0074 ui.bAddXBreak->setIcon( QIcon::fromTheme("list-add") ); 0075 ui.bRemoveXBreak->setIcon( QIcon::fromTheme("list-remove") ); 0076 ui.cbXBreak->addItem("1"); 0077 0078 ui.bAddYBreak->setIcon( QIcon::fromTheme("list-add") ); 0079 ui.bRemoveYBreak->setIcon( QIcon::fromTheme("list-remove") ); 0080 ui.cbYBreak->addItem("1"); 0081 0082 //"Background"-tab 0083 ui.bOpen->setIcon( QIcon::fromTheme("document-open") ); 0084 ui.leBackgroundFileName->setCompleter(new QCompleter(new QDirModel, this)); 0085 0086 //"Title"-tab 0087 auto* hboxLayout = new QHBoxLayout(ui.tabTitle); 0088 labelWidget = new LabelWidget(ui.tabTitle); 0089 hboxLayout->addWidget(labelWidget); 0090 hboxLayout->setContentsMargins(2,2,2,2); 0091 hboxLayout->setSpacing(2); 0092 0093 //adjust layouts in the tabs 0094 for (int i = 0; i < ui.tabWidget->count(); ++i) { 0095 auto* layout = qobject_cast<QGridLayout*>(ui.tabWidget->widget(i)->layout()); 0096 if (!layout) 0097 continue; 0098 0099 layout->setContentsMargins(2,2,2,2); 0100 layout->setHorizontalSpacing(2); 0101 layout->setVerticalSpacing(2); 0102 } 0103 0104 // "Cursor"-tab 0105 QStringList list = {i18n("NoPen"), i18n("SolidLine"), i18n("DashLine"), i18n("DotLine"), i18n("DashDotLine"), i18n("DashDotDotLine")}; 0106 ui.cbCursorLineStyle->clear(); 0107 for (int i = 0; i < list.count(); i++) 0108 ui.cbCursorLineStyle->addItem(list[i], i); 0109 0110 //Validators 0111 ui.leRangeFirst->setValidator( new QIntValidator(ui.leRangeFirst) ); 0112 ui.leRangeLast->setValidator( new QIntValidator(ui.leRangeLast) ); 0113 ui.leXBreakStart->setValidator( new QDoubleValidator(ui.leXBreakStart) ); 0114 ui.leXBreakEnd->setValidator( new QDoubleValidator(ui.leXBreakEnd) ); 0115 ui.leYBreakStart->setValidator( new QDoubleValidator(ui.leYBreakStart) ); 0116 ui.leYBreakEnd->setValidator( new QDoubleValidator(ui.leYBreakEnd) ); 0117 0118 //set the current locale 0119 updateLocale(); 0120 0121 //SIGNAL/SLOT 0122 //General 0123 connect(ui.leName, &QLineEdit::textChanged, this, &CartesianPlotDock::nameChanged); 0124 connect(ui.leComment, &QLineEdit::textChanged, this, &CartesianPlotDock::commentChanged); 0125 connect(ui.chkVisible, &QCheckBox::clicked, this, &CartesianPlotDock::visibilityChanged); 0126 connect(ui.sbLeft, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::geometryChanged); 0127 connect(ui.sbTop, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::geometryChanged); 0128 connect(ui.sbWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::geometryChanged); 0129 connect(ui.sbHeight, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::geometryChanged); 0130 0131 connect(ui.leRangeFirst, &QLineEdit::textChanged, this, &CartesianPlotDock::rangeFirstChanged); 0132 connect(ui.leRangeLast, &QLineEdit::textChanged, this, &CartesianPlotDock::rangeLastChanged); 0133 connect(rangeButtonsGroup, QOverload<int>::of(&QButtonGroup::buttonClicked), this, &CartesianPlotDock::rangeTypeChanged); 0134 0135 connect(ui.chkAutoScaleX, &QCheckBox::stateChanged, this, &CartesianPlotDock::autoScaleXChanged); 0136 connect(ui.leXMin, &QLineEdit::textChanged, this, &CartesianPlotDock::xMinChanged); 0137 connect(ui.leXMax, &QLineEdit::textChanged, this, &CartesianPlotDock::xMaxChanged); 0138 connect(ui.dateTimeEditXMin, &QDateTimeEdit::dateTimeChanged, this, &CartesianPlotDock::xMinDateTimeChanged); 0139 connect(ui.dateTimeEditXMax, &QDateTimeEdit::dateTimeChanged, this, &CartesianPlotDock::xMaxDateTimeChanged); 0140 connect(ui.cbXScaling, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::xScaleChanged); 0141 connect(ui.cbXRangeFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::xRangeFormatChanged); 0142 0143 connect(ui.chkAutoScaleY, &QCheckBox::stateChanged, this, &CartesianPlotDock::autoScaleYChanged); 0144 connect(ui.leYMin, &QLineEdit::textChanged, this, &CartesianPlotDock::yMinChanged); 0145 connect(ui.leYMax, &QLineEdit::textChanged, this, &CartesianPlotDock::yMaxChanged); 0146 connect(ui.dateTimeEditYMin, &QDateTimeEdit::dateTimeChanged, this, &CartesianPlotDock::yMinDateTimeChanged); 0147 connect(ui.dateTimeEditYMax, &QDateTimeEdit::dateTimeChanged, this, &CartesianPlotDock::yMaxDateTimeChanged); 0148 connect(ui.cbYScaling, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::yScaleChanged); 0149 connect(ui.cbYRangeFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::yRangeFormatChanged); 0150 0151 //Range breaks 0152 connect(ui.chkXBreak, &QCheckBox::toggled, this, &CartesianPlotDock::toggleXBreak); 0153 connect(ui.bAddXBreak, &QPushButton::clicked, this, &CartesianPlotDock::addXBreak); 0154 connect(ui.bRemoveXBreak, &QPushButton::clicked, this, &CartesianPlotDock::removeXBreak); 0155 connect(ui.cbXBreak, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::currentXBreakChanged); 0156 connect(ui.leXBreakStart, &QLineEdit::textChanged, this, &CartesianPlotDock::xBreakStartChanged); 0157 connect(ui.leXBreakEnd, &QLineEdit::textChanged, this, &CartesianPlotDock::xBreakEndChanged); 0158 connect(ui.sbXBreakPosition, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::xBreakPositionChanged); 0159 connect(ui.cbXBreakStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::xBreakStyleChanged); 0160 0161 connect(ui.chkYBreak, &QCheckBox::toggled, this, &CartesianPlotDock::toggleYBreak); 0162 connect(ui.bAddYBreak, &QPushButton::clicked, this, &CartesianPlotDock::addYBreak); 0163 connect(ui.bRemoveYBreak, &QPushButton::clicked, this, &CartesianPlotDock::removeYBreak); 0164 connect(ui.cbYBreak, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::currentYBreakChanged); 0165 connect(ui.leYBreakStart, &QLineEdit::textChanged, this, &CartesianPlotDock::yBreakStartChanged); 0166 connect(ui.leYBreakEnd, &QLineEdit::textChanged, this, &CartesianPlotDock::yBreakEndChanged); 0167 connect(ui.sbYBreakPosition, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::yBreakPositionChanged); 0168 connect(ui.cbYBreakStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::yBreakStyleChanged); 0169 0170 //Background 0171 connect(ui.cbBackgroundType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::backgroundTypeChanged); 0172 connect(ui.cbBackgroundColorStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::backgroundColorStyleChanged); 0173 connect(ui.cbBackgroundImageStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::backgroundImageStyleChanged); 0174 connect(ui.cbBackgroundBrushStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::backgroundBrushStyleChanged); 0175 connect(ui.bOpen, &QPushButton::clicked, this, &CartesianPlotDock::selectFile); 0176 connect(ui.leBackgroundFileName, &QLineEdit::textChanged, this, &CartesianPlotDock::fileNameChanged); 0177 connect(ui.kcbBackgroundFirstColor, &KColorButton::changed, this, &CartesianPlotDock::backgroundFirstColorChanged); 0178 connect(ui.kcbBackgroundSecondColor, &KColorButton::changed, this, &CartesianPlotDock::backgroundSecondColorChanged); 0179 connect(ui.sbBackgroundOpacity, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::backgroundOpacityChanged); 0180 0181 //Border 0182 connect(ui.cbBorderStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::borderStyleChanged); 0183 connect(ui.kcbBorderColor, &KColorButton::changed, this, &CartesianPlotDock::borderColorChanged); 0184 connect(ui.sbBorderWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::borderWidthChanged); 0185 connect(ui.sbBorderCornerRadius, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::borderCornerRadiusChanged); 0186 connect(ui.sbBorderOpacity, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::borderOpacityChanged); 0187 0188 //Padding 0189 connect(ui.sbPaddingHorizontal, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::horizontalPaddingChanged); 0190 connect(ui.sbPaddingVertical, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::verticalPaddingChanged); 0191 connect(ui.sbPaddingRight, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::rightPaddingChanged); 0192 connect(ui.sbPaddingBottom, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &CartesianPlotDock::bottomPaddingChanged); 0193 connect(ui.cbPaddingSymmetric, &QCheckBox::toggled, this, &CartesianPlotDock::symmetricPaddingChanged); 0194 0195 // Cursor 0196 connect(ui.sbCursorLineWidth, QOverload<int>::of(&QSpinBox::valueChanged), this, &CartesianPlotDock::cursorLineWidthChanged); 0197 connect(ui.kcbCursorLineColor, &KColorButton::changed, this, &CartesianPlotDock::cursorLineColorChanged); 0198 connect(ui.cbCursorLineStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CartesianPlotDock::cursorLineStyleChanged); 0199 0200 //theme and template handlers 0201 auto* frame = new QFrame(this); 0202 auto* layout = new QHBoxLayout(frame); 0203 layout->setContentsMargins(0, 11, 0, 11); 0204 0205 m_themeHandler = new ThemeHandler(this); 0206 layout->addWidget(m_themeHandler); 0207 connect(m_themeHandler, &ThemeHandler::loadThemeRequested, this, &CartesianPlotDock::loadTheme); 0208 connect(m_themeHandler, &ThemeHandler::info, this, &CartesianPlotDock::info); 0209 0210 auto* templateHandler = new TemplateHandler(this, TemplateHandler::ClassName::CartesianPlot); 0211 layout->addWidget(templateHandler); 0212 connect(templateHandler, &TemplateHandler::loadConfigRequested, this, &CartesianPlotDock::loadConfigFromTemplate); 0213 connect(templateHandler, &TemplateHandler::saveConfigRequested, this, &CartesianPlotDock::saveConfigAsTemplate); 0214 connect(templateHandler, &TemplateHandler::info, this, &CartesianPlotDock::info); 0215 0216 ui.verticalLayout->addWidget(frame); 0217 0218 //TODO: activate the tab again once the functionality is implemented 0219 ui.tabWidget->removeTab(2); 0220 0221 init(); 0222 } 0223 0224 void CartesianPlotDock::init() { 0225 this->retranslateUi(); 0226 0227 GuiTools::updatePenStyles(ui.cbCursorLineStyle, Qt::black); 0228 0229 /* 0230 //TODO: activate later once range breaking is implemented 0231 //create icons for the different styles for scale breaking 0232 QPainter pa; 0233 pa.setPen( QPen(Qt::SolidPattern, 0) ); 0234 QPixmap pm(20, 20); 0235 ui.cbXBreakStyle->setIconSize( QSize(20,20) ); 0236 ui.cbYBreakStyle->setIconSize( QSize(20,20) ); 0237 0238 //simple 0239 pm.fill(Qt::transparent); 0240 pa.begin( &pm ); 0241 pa.setRenderHint(QPainter::Antialiasing); 0242 pa.setBrush(Qt::SolidPattern); 0243 pa.drawLine(3,10,8,10); 0244 pa.drawLine(12,10,17,10); 0245 pa.end(); 0246 ui.cbXBreakStyle->setItemIcon(0, pm); 0247 ui.cbYBreakStyle->setItemIcon(0, pm); 0248 0249 //vertical 0250 pm.fill(Qt::transparent); 0251 pa.begin( &pm ); 0252 pa.setRenderHint(QPainter::Antialiasing); 0253 pa.setBrush(Qt::SolidPattern); 0254 pa.drawLine(3,10,8,10); 0255 pa.drawLine(12,10,17,10); 0256 pa.drawLine(8,14,8,6); 0257 pa.drawLine(12,14,12,6); 0258 pa.end(); 0259 ui.cbXBreakStyle->setItemIcon(1, pm); 0260 ui.cbYBreakStyle->setItemIcon(1, pm); 0261 0262 //sloped 0263 pm.fill(Qt::transparent); 0264 pa.begin( &pm ); 0265 pa.setRenderHint(QPainter::Antialiasing); 0266 pa.setBrush(Qt::SolidPattern); 0267 pa.drawLine(3,10,8,10); 0268 pa.drawLine(12,10,17,10); 0269 pa.drawLine(6,14,10,6); 0270 pa.drawLine(10,14,14,6); 0271 pa.end(); 0272 ui.cbXBreakStyle->setItemIcon(2, pm); 0273 ui.cbYBreakStyle->setItemIcon(2, pm); 0274 */ 0275 } 0276 0277 void CartesianPlotDock::setPlots(QList<CartesianPlot*> list) { 0278 m_initializing = true; 0279 m_plotList = list; 0280 m_plot = list.first(); 0281 m_aspect = list.first(); 0282 0283 QList<TextLabel*> labels; 0284 for (auto* plot : list) 0285 labels.append(plot->title()); 0286 0287 labelWidget->setLabels(labels); 0288 0289 //if there is more then one plot in the list, disable the name and comment fields in the tab "general" 0290 if (list.size() == 1) { 0291 ui.lName->setEnabled(true); 0292 ui.leName->setEnabled(true); 0293 ui.lComment->setEnabled(true); 0294 ui.leComment->setEnabled(true); 0295 0296 ui.leName->setText(m_plot->name()); 0297 ui.leComment->setText(m_plot->comment()); 0298 } else { 0299 ui.lName->setEnabled(false); 0300 ui.leName->setEnabled(false); 0301 ui.lComment->setEnabled(false); 0302 ui.leComment->setEnabled(false); 0303 0304 ui.leName->setText(QString()); 0305 ui.leComment->setText(QString()); 0306 } 0307 0308 symmetricPaddingChanged(m_plot->symmetricPadding()); 0309 0310 ui.leName->setStyleSheet(""); 0311 ui.leName->setToolTip(""); 0312 0313 //show the properties of the first plot 0314 this->load(); 0315 0316 //update active widgets 0317 m_themeHandler->setCurrentTheme(m_plot->theme()); 0318 0319 //Deactivate the geometry related widgets, if the worksheet layout is active. 0320 //Currently, a plot can only be a child of the worksheet itself, so we only need to ask the parent aspect (=worksheet). 0321 //TODO redesign this, if the hierarchy will be changend in future (a plot is a child of a new object group/container or so) 0322 auto* w = dynamic_cast<Worksheet*>(m_plot->parentAspect()); 0323 if (w) { 0324 bool b = (w->layout() == Worksheet::Layout::NoLayout); 0325 ui.sbTop->setEnabled(b); 0326 ui.sbLeft->setEnabled(b); 0327 ui.sbWidth->setEnabled(b); 0328 ui.sbHeight->setEnabled(b); 0329 connect(w, &Worksheet::layoutChanged, this, &CartesianPlotDock::layoutChanged); 0330 } 0331 0332 //SIGNALs/SLOTs 0333 connect(m_plot, &CartesianPlot::aspectDescriptionChanged, this, &CartesianPlotDock::plotDescriptionChanged); 0334 connect(m_plot, &CartesianPlot::rectChanged, this, &CartesianPlotDock::plotRectChanged); 0335 connect(m_plot, &CartesianPlot::rangeTypeChanged, this, &CartesianPlotDock::plotRangeTypeChanged); 0336 connect(m_plot, &CartesianPlot::rangeFirstValuesChanged, this, &CartesianPlotDock::plotRangeFirstValuesChanged); 0337 connect(m_plot, &CartesianPlot::rangeLastValuesChanged, this, &CartesianPlotDock::plotRangeLastValuesChanged); 0338 connect(m_plot, &CartesianPlot::xAutoScaleChanged, this, &CartesianPlotDock::plotXAutoScaleChanged); 0339 connect(m_plot, &CartesianPlot::xMinChanged, this, &CartesianPlotDock::plotXMinChanged); 0340 connect(m_plot, &CartesianPlot::xMaxChanged, this, &CartesianPlotDock::plotXMaxChanged); 0341 connect(m_plot, &CartesianPlot::xScaleChanged, this, &CartesianPlotDock::plotXScaleChanged); 0342 connect(m_plot, &CartesianPlot::xRangeFormatChanged, this, &CartesianPlotDock::plotXRangeFormatChanged); 0343 connect(m_plot, &CartesianPlot::yAutoScaleChanged, this, &CartesianPlotDock::plotYAutoScaleChanged); 0344 connect(m_plot, &CartesianPlot::yMinChanged, this, &CartesianPlotDock::plotYMinChanged); 0345 connect(m_plot, &CartesianPlot::yMaxChanged, this, &CartesianPlotDock::plotYMaxChanged); 0346 connect(m_plot, &CartesianPlot::yScaleChanged, this, &CartesianPlotDock::plotYScaleChanged); 0347 connect(m_plot, &CartesianPlot::yRangeFormatChanged, this, &CartesianPlotDock::plotYRangeFormatChanged); 0348 connect(m_plot, &CartesianPlot::visibleChanged, this, &CartesianPlotDock::plotVisibleChanged); 0349 0350 //range breaks 0351 connect(m_plot, &CartesianPlot::xRangeBreakingEnabledChanged, this, &CartesianPlotDock::plotXRangeBreakingEnabledChanged); 0352 connect(m_plot, &CartesianPlot::xRangeBreaksChanged, this, &CartesianPlotDock::plotXRangeBreaksChanged); 0353 connect(m_plot, &CartesianPlot::yRangeBreakingEnabledChanged, this, &CartesianPlotDock::plotYRangeBreakingEnabledChanged); 0354 connect(m_plot, &CartesianPlot::yRangeBreaksChanged, this, &CartesianPlotDock::plotYRangeBreaksChanged); 0355 0356 // Plot Area 0357 connect(m_plot->plotArea(), &PlotArea::backgroundTypeChanged, this, &CartesianPlotDock::plotBackgroundTypeChanged); 0358 connect(m_plot->plotArea(), &PlotArea::backgroundColorStyleChanged, this, &CartesianPlotDock::plotBackgroundColorStyleChanged); 0359 connect(m_plot->plotArea(), &PlotArea::backgroundImageStyleChanged, this, &CartesianPlotDock::plotBackgroundImageStyleChanged); 0360 connect(m_plot->plotArea(), &PlotArea::backgroundBrushStyleChanged, this, &CartesianPlotDock::plotBackgroundBrushStyleChanged); 0361 connect(m_plot->plotArea(), &PlotArea::backgroundFirstColorChanged, this, &CartesianPlotDock::plotBackgroundFirstColorChanged); 0362 connect(m_plot->plotArea(), &PlotArea::backgroundSecondColorChanged, this, &CartesianPlotDock::plotBackgroundSecondColorChanged); 0363 connect(m_plot->plotArea(), &PlotArea::backgroundFileNameChanged, this, &CartesianPlotDock::plotBackgroundFileNameChanged); 0364 connect(m_plot->plotArea(), &PlotArea::backgroundOpacityChanged, this, &CartesianPlotDock::plotBackgroundOpacityChanged); 0365 connect(m_plot->plotArea(), &PlotArea::borderPenChanged, this, &CartesianPlotDock::plotBorderPenChanged); 0366 connect(m_plot->plotArea(), &PlotArea::borderOpacityChanged, this, &CartesianPlotDock::plotBorderOpacityChanged); 0367 connect(m_plot, &CartesianPlot::horizontalPaddingChanged, this, &CartesianPlotDock::plotHorizontalPaddingChanged); 0368 connect(m_plot, &CartesianPlot::verticalPaddingChanged, this, &CartesianPlotDock::plotVerticalPaddingChanged); 0369 connect(m_plot, &CartesianPlot::rightPaddingChanged, this, &CartesianPlotDock::plotRightPaddingChanged); 0370 connect(m_plot, &CartesianPlot::bottomPaddingChanged, this, &CartesianPlotDock::plotBottomPaddingChanged); 0371 connect(m_plot, &CartesianPlot::symmetricPaddingChanged, this, &CartesianPlotDock::plotSymmetricPaddingChanged); 0372 0373 m_initializing = false; 0374 } 0375 0376 void CartesianPlotDock::activateTitleTab() { 0377 ui.tabWidget->setCurrentWidget(ui.tabTitle); 0378 } 0379 0380 /* 0381 * updates the locale in the widgets. called when the application settins are changed. 0382 */ 0383 void CartesianPlotDock::updateLocale() { 0384 SET_NUMBER_LOCALE 0385 0386 //update the QSpinBoxes 0387 ui.sbLeft->setLocale(numberLocale); 0388 ui.sbTop->setLocale(numberLocale); 0389 ui.sbWidth->setLocale(numberLocale); 0390 ui.sbHeight->setLocale(numberLocale); 0391 ui.sbBorderWidth->setLocale(numberLocale); 0392 ui.sbBorderCornerRadius->setLocale(numberLocale); 0393 ui.sbPaddingHorizontal->setLocale(numberLocale); 0394 ui.sbPaddingVertical->setLocale(numberLocale); 0395 ui.sbPaddingRight->setLocale(numberLocale); 0396 ui.sbPaddingBottom->setLocale(numberLocale); 0397 0398 //update the QLineEdits, avoid the change events 0399 if (m_plot) { 0400 Lock lock(m_initializing); 0401 ui.leRangeFirst->setText(numberLocale.toString(m_plot->rangeFirstValues())); 0402 ui.leRangeLast->setText(numberLocale.toString(m_plot->rangeLastValues())); 0403 ui.leXMin->setText(numberLocale.toString(m_plot->xMin())); 0404 ui.leXMax->setText(numberLocale.toString(m_plot->xMax())); 0405 ui.leYMin->setText(numberLocale.toString(m_plot->yMin())); 0406 ui.leYMax->setText(numberLocale.toString(m_plot->yMax())); 0407 } 0408 0409 //update the title label 0410 labelWidget->updateLocale(); 0411 } 0412 0413 void CartesianPlotDock::updateUnits() { 0414 const KConfigGroup group = KSharedConfig::openConfig()->group(QLatin1String("Settings_General")); 0415 BaseDock::Units units = (BaseDock::Units)group.readEntry("Units", static_cast<int>(Units::Metric)); 0416 if (units == m_units) 0417 return; 0418 0419 m_units = units; 0420 Lock lock(m_initializing); 0421 QString suffix; 0422 if (m_units == Units::Metric) { 0423 //convert from imperial to metric 0424 m_worksheetUnit = Worksheet::Unit::Centimeter; 0425 suffix = QLatin1String(" cm"); 0426 ui.sbLeft->setValue(ui.sbLeft->value()*2.54); 0427 ui.sbTop->setValue(ui.sbTop->value()*2.54); 0428 ui.sbWidth->setValue(ui.sbWidth->value()*2.54); 0429 ui.sbHeight->setValue(ui.sbHeight->value()*2.54); 0430 ui.sbBorderCornerRadius->setValue(ui.sbBorderCornerRadius->value()*2.54); 0431 ui.sbPaddingHorizontal->setValue(ui.sbPaddingHorizontal->value()*2.54); 0432 ui.sbPaddingVertical->setValue(ui.sbPaddingVertical->value()*2.54); 0433 ui.sbPaddingRight->setValue(ui.sbPaddingRight->value()*2.54); 0434 ui.sbPaddingBottom->setValue(ui.sbPaddingBottom->value()*2.54); 0435 } else { 0436 //convert from metric to imperial 0437 m_worksheetUnit = Worksheet::Unit::Inch; 0438 suffix = QLatin1String(" in"); 0439 ui.sbLeft->setValue(ui.sbLeft->value()/2.54); 0440 ui.sbTop->setValue(ui.sbTop->value()/2.54); 0441 ui.sbWidth->setValue(ui.sbWidth->value()/2.54); 0442 ui.sbHeight->setValue(ui.sbHeight->value()/2.54); 0443 ui.sbBorderCornerRadius->setValue(ui.sbBorderCornerRadius->value()/2.54); 0444 ui.sbPaddingHorizontal->setValue(ui.sbPaddingHorizontal->value()/2.54); 0445 ui.sbPaddingVertical->setValue(ui.sbPaddingVertical->value()/2.54); 0446 ui.sbPaddingRight->setValue(ui.sbPaddingRight->value()/2.54); 0447 ui.sbPaddingBottom->setValue(ui.sbPaddingBottom->value()/2.54); 0448 } 0449 0450 ui.sbLeft->setSuffix(suffix); 0451 ui.sbTop->setSuffix(suffix); 0452 ui.sbWidth->setSuffix(suffix); 0453 ui.sbHeight->setSuffix(suffix); 0454 ui.sbBorderCornerRadius->setSuffix(suffix); 0455 ui.sbPaddingHorizontal->setSuffix(suffix); 0456 ui.sbPaddingVertical->setSuffix(suffix); 0457 ui.sbPaddingRight->setSuffix(suffix); 0458 ui.sbPaddingBottom->setSuffix(suffix); 0459 0460 labelWidget->updateUnits(); 0461 } 0462 0463 //************************************************************ 0464 //**** SLOTs for changes triggered in CartesianPlotDock ****** 0465 //************************************************************ 0466 void CartesianPlotDock::retranslateUi() { 0467 Lock lock(m_initializing); 0468 0469 //general 0470 ui.cbXRangeFormat->addItem(i18n("Numeric")); 0471 ui.cbXRangeFormat->addItem(i18n("Date and Time")); 0472 ui.cbYRangeFormat->addItem(i18n("Numeric")); 0473 ui.cbYRangeFormat->addItem(i18n("Date and Time")); 0474 0475 ui.cbXScaling->addItem( i18n("linear") ); 0476 ui.cbXScaling->addItem( i18n("log(x)") ); 0477 ui.cbXScaling->addItem( i18n("log2(x)") ); 0478 ui.cbXScaling->addItem( i18n("ln(x)") ); 0479 ui.cbXScaling->addItem( i18n("log(abs(x))") ); 0480 ui.cbXScaling->addItem( i18n("log2(abs(x))") ); 0481 ui.cbXScaling->addItem( i18n("ln(abs(x))") ); 0482 0483 ui.cbYScaling->addItem( i18n("linear") ); 0484 ui.cbYScaling->addItem( i18n("log(y)") ); 0485 ui.cbYScaling->addItem( i18n("log2(y)") ); 0486 ui.cbYScaling->addItem( i18n("ln(y)") ); 0487 ui.cbYScaling->addItem( i18n("log(abs(y))") ); 0488 ui.cbYScaling->addItem( i18n("log2(abs(y))") ); 0489 ui.cbYScaling->addItem( i18n("ln(abs(y))") ); 0490 0491 //scale breakings 0492 ui.cbXBreakStyle->addItem( i18n("Simple") ); 0493 ui.cbXBreakStyle->addItem( i18n("Vertical") ); 0494 ui.cbXBreakStyle->addItem( i18n("Sloped") ); 0495 0496 ui.cbYBreakStyle->addItem( i18n("Simple") ); 0497 ui.cbYBreakStyle->addItem( i18n("Vertical") ); 0498 ui.cbYBreakStyle->addItem( i18n("Sloped") ); 0499 0500 //plot area 0501 ui.cbBackgroundType->addItem(i18n("Color")); 0502 ui.cbBackgroundType->addItem(i18n("Image")); 0503 ui.cbBackgroundType->addItem(i18n("Pattern")); 0504 0505 ui.cbBackgroundColorStyle->addItem(i18n("Single Color")); 0506 ui.cbBackgroundColorStyle->addItem(i18n("Horizontal Gradient")); 0507 ui.cbBackgroundColorStyle->addItem(i18n("Vertical Gradient")); 0508 ui.cbBackgroundColorStyle->addItem(i18n("Diag. Gradient (From Top Left)")); 0509 ui.cbBackgroundColorStyle->addItem(i18n("Diag. Gradient (From Bottom Left)")); 0510 ui.cbBackgroundColorStyle->addItem(i18n("Radial Gradient")); 0511 0512 ui.cbBackgroundImageStyle->addItem(i18n("Scaled and Cropped")); 0513 ui.cbBackgroundImageStyle->addItem(i18n("Scaled")); 0514 ui.cbBackgroundImageStyle->addItem(i18n("Scaled, Keep Proportions")); 0515 ui.cbBackgroundImageStyle->addItem(i18n("Centered")); 0516 ui.cbBackgroundImageStyle->addItem(i18n("Tiled")); 0517 ui.cbBackgroundImageStyle->addItem(i18n("Center Tiled")); 0518 0519 GuiTools::updatePenStyles(ui.cbBorderStyle, Qt::black); 0520 GuiTools::updateBrushStyles(ui.cbBackgroundBrushStyle, Qt::SolidPattern); 0521 0522 QString suffix; 0523 if (m_units == Units::Metric) 0524 suffix = QLatin1String(" cm"); 0525 else 0526 suffix = QLatin1String(" in"); 0527 0528 ui.sbLeft->setSuffix(suffix); 0529 ui.sbTop->setSuffix(suffix); 0530 ui.sbWidth->setSuffix(suffix); 0531 ui.sbHeight->setSuffix(suffix); 0532 ui.sbBorderCornerRadius->setSuffix(suffix); 0533 ui.sbPaddingHorizontal->setSuffix(suffix); 0534 ui.sbPaddingVertical->setSuffix(suffix); 0535 ui.sbPaddingRight->setSuffix(suffix); 0536 ui.sbPaddingBottom->setSuffix(suffix); 0537 } 0538 0539 // "General"-tab 0540 void CartesianPlotDock::visibilityChanged(bool state) { 0541 if (m_initializing) 0542 return; 0543 0544 for (auto* plot : m_plotList) 0545 plot->setVisible(state); 0546 } 0547 0548 void CartesianPlotDock::geometryChanged() { 0549 if (m_initializing) 0550 return; 0551 0552 double x = Worksheet::convertToSceneUnits(ui.sbLeft->value(), m_worksheetUnit); 0553 double y = Worksheet::convertToSceneUnits(ui.sbTop->value(), m_worksheetUnit); 0554 double w = Worksheet::convertToSceneUnits(ui.sbWidth->value(), m_worksheetUnit); 0555 double h = Worksheet::convertToSceneUnits(ui.sbHeight->value(), m_worksheetUnit); 0556 0557 QRectF rect(x, y, w, h); 0558 m_plot->setRect(rect); 0559 } 0560 0561 /*! 0562 Called when the layout in the worksheet gets changed. 0563 Enables/disables the geometry widgets if the layout was deactivated/activated. 0564 Shows the new geometry values of the first plot if the layout was activated. 0565 */ 0566 void CartesianPlotDock::layoutChanged(Worksheet::Layout layout) { 0567 bool b = (layout == Worksheet::Layout::NoLayout); 0568 ui.sbTop->setEnabled(b); 0569 ui.sbLeft->setEnabled(b); 0570 ui.sbWidth->setEnabled(b); 0571 ui.sbHeight->setEnabled(b); 0572 } 0573 0574 void CartesianPlotDock::rangeTypeChanged() { 0575 CartesianPlot::RangeType type; 0576 if (ui.rbRangeFirst->isChecked()) { 0577 ui.leRangeFirst->setEnabled(true); 0578 ui.leRangeLast->setEnabled(false); 0579 type = CartesianPlot::RangeType::First; 0580 } else if (ui.rbRangeLast->isChecked()) { 0581 ui.leRangeFirst->setEnabled(false); 0582 ui.leRangeLast->setEnabled(true); 0583 type = CartesianPlot::RangeType::Last; 0584 } else { 0585 ui.leRangeFirst->setEnabled(false); 0586 ui.leRangeLast->setEnabled(false); 0587 type = CartesianPlot::RangeType::Free; 0588 } 0589 0590 if (m_initializing) 0591 return; 0592 0593 for (auto* plot : m_plotList) 0594 plot->setRangeType(type); 0595 } 0596 0597 void CartesianPlotDock::rangeFirstChanged(const QString& text) { 0598 if (m_initializing) 0599 return; 0600 0601 const int value = text.toInt(); 0602 for (auto* plot : m_plotList) 0603 plot->setRangeFirstValues(value); 0604 } 0605 0606 void CartesianPlotDock::rangeLastChanged(const QString& text) { 0607 if (m_initializing) 0608 return; 0609 0610 const int value = text.toInt(); 0611 for (auto* plot : m_plotList) 0612 plot->setRangeLastValues(value); 0613 } 0614 0615 void CartesianPlotDock::autoScaleXChanged(int state) { 0616 bool checked = (state == Qt::Checked); 0617 ui.cbXRangeFormat->setEnabled(!checked); 0618 ui.leXMin->setEnabled(!checked); 0619 ui.leXMax->setEnabled(!checked); 0620 ui.dateTimeEditXMin->setEnabled(!checked); 0621 ui.dateTimeEditXMax->setEnabled(!checked); 0622 0623 if (m_initializing) 0624 return; 0625 0626 for (auto* plot : m_plotList) 0627 plot->setAutoScaleX(checked); 0628 } 0629 0630 void CartesianPlotDock::xMinChanged(const QString& value) { 0631 if (m_initializing) 0632 return; 0633 0634 const Lock lock(m_initializing); 0635 bool ok; 0636 SET_NUMBER_LOCALE 0637 const double xMin = numberLocale.toDouble(value, &ok); 0638 if (ok) { 0639 for (auto* plot : m_plotList) 0640 plot->setXMin(xMin); 0641 } 0642 } 0643 0644 void CartesianPlotDock::xMaxChanged(const QString& value) { 0645 if (m_initializing) 0646 return; 0647 0648 const Lock lock(m_initializing); 0649 bool ok; 0650 SET_NUMBER_LOCALE 0651 const double xMax = numberLocale.toDouble(value, &ok); 0652 if (ok) { 0653 for (auto* plot : m_plotList) 0654 plot->setXMax(xMax); 0655 } 0656 } 0657 0658 void CartesianPlotDock::xMinDateTimeChanged(const QDateTime& dateTime) { 0659 if (m_initializing) 0660 return; 0661 0662 quint64 value = dateTime.toMSecsSinceEpoch(); 0663 for (auto* plot : m_plotList) 0664 plot->setXMin(value); 0665 } 0666 0667 void CartesianPlotDock::xMaxDateTimeChanged(const QDateTime& dateTime) { 0668 if (m_initializing) 0669 return; 0670 0671 quint64 value = dateTime.toMSecsSinceEpoch(); 0672 for (auto* plot : m_plotList) 0673 plot->setXMax(value); 0674 } 0675 0676 /*! 0677 called on scale changes (linear, log) for the x-axis 0678 */ 0679 void CartesianPlotDock::xScaleChanged(int index) { 0680 if (m_initializing) 0681 return; 0682 0683 auto scale = static_cast<CartesianPlot::Scale>(index); 0684 for (auto* plot : m_plotList) 0685 plot->setXScale(scale); 0686 } 0687 0688 void CartesianPlotDock::xRangeFormatChanged(int index) { 0689 bool numeric = (index == 0); 0690 0691 ui.lXMin->setVisible(numeric); 0692 ui.leXMin->setVisible(numeric); 0693 ui.lXMax->setVisible(numeric); 0694 ui.leXMax->setVisible(numeric); 0695 0696 ui.lXMinDateTime->setVisible(!numeric); 0697 ui.dateTimeEditXMin->setVisible(!numeric); 0698 ui.lXMaxDateTime->setVisible(!numeric); 0699 ui.dateTimeEditXMax->setVisible(!numeric); 0700 0701 if (m_initializing) 0702 return; 0703 0704 auto format = (CartesianPlot::RangeFormat)index; 0705 for (auto* plot : m_plotList) 0706 plot->setXRangeFormat(format); 0707 } 0708 0709 void CartesianPlotDock::autoScaleYChanged(int state) { 0710 bool checked = (state == Qt::Checked); 0711 ui.cbYRangeFormat->setEnabled(!checked); 0712 ui.leYMin->setEnabled(!checked); 0713 ui.leYMax->setEnabled(!checked); 0714 ui.dateTimeEditYMin->setEnabled(!checked); 0715 ui.dateTimeEditYMax->setEnabled(!checked); 0716 0717 if (m_initializing) 0718 return; 0719 0720 for (auto* plot : m_plotList) 0721 plot->setAutoScaleY(checked); 0722 } 0723 0724 void CartesianPlotDock::yMinChanged(const QString& value) { 0725 if (m_initializing) 0726 return; 0727 0728 const Lock lock(m_initializing); 0729 bool ok; 0730 SET_NUMBER_LOCALE 0731 const double yMin = numberLocale.toDouble(value, &ok); 0732 if (ok) { 0733 for (auto* plot : m_plotList) 0734 plot->setYMin(yMin); 0735 } 0736 } 0737 0738 void CartesianPlotDock::yMaxChanged(const QString& value) { 0739 if (m_initializing) 0740 return; 0741 0742 const Lock lock(m_initializing); 0743 bool ok; 0744 SET_NUMBER_LOCALE 0745 const double yMax = numberLocale.toDouble(value, &ok); 0746 if (ok) { 0747 for (auto* plot : m_plotList) 0748 plot->setYMax(yMax); 0749 } 0750 } 0751 0752 void CartesianPlotDock::yMinDateTimeChanged(const QDateTime& dateTime) { 0753 if (m_initializing) 0754 return; 0755 0756 quint64 value = dateTime.toMSecsSinceEpoch(); 0757 for (auto* plot : m_plotList) 0758 plot->setXMin(value); 0759 } 0760 0761 void CartesianPlotDock::yMaxDateTimeChanged(const QDateTime& dateTime) { 0762 if (m_initializing) 0763 return; 0764 0765 quint64 value = dateTime.toMSecsSinceEpoch(); 0766 for (auto* plot : m_plotList) 0767 plot->setXMax(value); 0768 } 0769 0770 /*! 0771 called on scale changes (linear, log) for the y-axis 0772 */ 0773 void CartesianPlotDock::yScaleChanged(int index) { 0774 if (m_initializing) 0775 return; 0776 0777 auto scale = static_cast<CartesianPlot::Scale>(index); 0778 for (auto* plot : m_plotList) 0779 plot->setYScale(scale); 0780 } 0781 0782 void CartesianPlotDock::yRangeFormatChanged(int index) { 0783 bool numeric = (index == 0); 0784 0785 ui.lYMin->setVisible(numeric); 0786 ui.leYMin->setVisible(numeric); 0787 ui.lYMax->setVisible(numeric); 0788 ui.leYMax->setVisible(numeric); 0789 0790 ui.lYMinDateTime->setVisible(!numeric); 0791 ui.dateTimeEditYMin->setVisible(!numeric); 0792 ui.lYMaxDateTime->setVisible(!numeric); 0793 ui.dateTimeEditYMax->setVisible(!numeric); 0794 0795 if (m_initializing) 0796 return; 0797 0798 auto format = (CartesianPlot::RangeFormat)index; 0799 for (auto* plot : m_plotList) 0800 plot->setYRangeFormat(format); 0801 } 0802 0803 // "Range Breaks"-tab 0804 0805 // x-range breaks 0806 void CartesianPlotDock::toggleXBreak(bool b) { 0807 ui.frameXBreakEdit->setEnabled(b); 0808 ui.leXBreakStart->setEnabled(b); 0809 ui.leXBreakEnd->setEnabled(b); 0810 ui.sbXBreakPosition->setEnabled(b); 0811 ui.cbXBreakStyle->setEnabled(b); 0812 0813 if (m_initializing) 0814 return; 0815 0816 for (auto* plot : m_plotList) 0817 plot->setXRangeBreakingEnabled(b); 0818 } 0819 0820 void CartesianPlotDock::addXBreak() { 0821 ui.bRemoveXBreak->setVisible(true); 0822 0823 CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks(); 0824 CartesianPlot::RangeBreak b; 0825 breaks.list<<b; 0826 breaks.lastChanged = breaks.list.size() - 1; 0827 for (auto* plot : m_plotList) 0828 plot->setXRangeBreaks(breaks); 0829 0830 ui.cbXBreak->addItem(QString::number(ui.cbXBreak->count() + 1)); 0831 ui.cbXBreak->setCurrentIndex(ui.cbXBreak->count()-1); 0832 } 0833 0834 void CartesianPlotDock::removeXBreak() { 0835 ui.bRemoveXBreak->setVisible(m_plot->xRangeBreaks().list.size()>1); 0836 int index = ui.cbXBreak->currentIndex(); 0837 CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks(); 0838 breaks.list.takeAt(index); 0839 breaks.lastChanged = -1; 0840 for (auto* plot : m_plotList) 0841 plot->setXRangeBreaks(breaks); 0842 0843 ui.cbXBreak->clear(); 0844 for (int i = 1; i <= breaks.list.size(); ++i) 0845 ui.cbXBreak->addItem(QString::number(i)); 0846 0847 if (index < ui.cbXBreak->count()-1) 0848 ui.cbXBreak->setCurrentIndex(index); 0849 else 0850 ui.cbXBreak->setCurrentIndex(ui.cbXBreak->count()-1); 0851 0852 ui.bRemoveXBreak->setVisible(ui.cbXBreak->count()!=1); 0853 } 0854 0855 void CartesianPlotDock::currentXBreakChanged(int index) { 0856 if (m_initializing) 0857 return; 0858 0859 if (index == -1) 0860 return; 0861 0862 m_initializing = true; 0863 SET_NUMBER_LOCALE 0864 const CartesianPlot::RangeBreak rangeBreak = m_plot->xRangeBreaks().list.at(index); 0865 QString str = std::isnan(rangeBreak.start) ? QString() : numberLocale.toString(rangeBreak.start); 0866 ui.leXBreakStart->setText(str); 0867 str = std::isnan(rangeBreak.end) ? QString() : numberLocale.toString(rangeBreak.end); 0868 ui.leXBreakEnd->setText(str); 0869 ui.sbXBreakPosition->setValue(rangeBreak.position*100); 0870 ui.cbXBreakStyle->setCurrentIndex((int)rangeBreak.style); 0871 m_initializing = false; 0872 } 0873 0874 void CartesianPlotDock::xBreakStartChanged() { 0875 if (m_initializing) 0876 return; 0877 0878 int index = ui.cbXBreak->currentIndex(); 0879 CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks(); 0880 breaks.list[index].start = ui.leXBreakStart->text().toDouble(); 0881 breaks.lastChanged = index; 0882 0883 for (auto* plot : m_plotList) 0884 plot->setXRangeBreaks(breaks); 0885 } 0886 0887 void CartesianPlotDock::xBreakEndChanged() { 0888 if (m_initializing) 0889 return; 0890 0891 int index = ui.cbXBreak->currentIndex(); 0892 CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks(); 0893 breaks.list[index].end = ui.leXBreakEnd->text().toDouble(); 0894 breaks.lastChanged = index; 0895 0896 for (auto* plot : m_plotList) 0897 plot->setXRangeBreaks(breaks); 0898 } 0899 0900 void CartesianPlotDock::xBreakPositionChanged(int value) { 0901 if (m_initializing) 0902 return; 0903 0904 int index = ui.cbXBreak->currentIndex(); 0905 CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks(); 0906 breaks.list[index].position = (float)value/100.; 0907 breaks.lastChanged = index; 0908 0909 for (auto* plot : m_plotList) 0910 plot->setXRangeBreaks(breaks); 0911 } 0912 0913 void CartesianPlotDock::xBreakStyleChanged(int styleIndex) { 0914 if (m_initializing) 0915 return; 0916 0917 int index = ui.cbXBreak->currentIndex(); 0918 auto style = CartesianPlot::RangeBreakStyle(styleIndex); 0919 CartesianPlot::RangeBreaks breaks = m_plot->xRangeBreaks(); 0920 breaks.list[index].style = style; 0921 breaks.lastChanged = index; 0922 0923 for (auto* plot : m_plotList) 0924 plot->setXRangeBreaks(breaks); 0925 } 0926 0927 // y-range breaks 0928 void CartesianPlotDock::toggleYBreak(bool b) { 0929 ui.frameYBreakEdit->setEnabled(b); 0930 ui.leYBreakStart->setEnabled(b); 0931 ui.leYBreakEnd->setEnabled(b); 0932 ui.sbYBreakPosition->setEnabled(b); 0933 ui.cbYBreakStyle->setEnabled(b); 0934 0935 if (m_initializing) 0936 return; 0937 0938 for (auto* plot : m_plotList) 0939 plot->setYRangeBreakingEnabled(b); 0940 } 0941 0942 void CartesianPlotDock::addYBreak() { 0943 ui.bRemoveYBreak->setVisible(true); 0944 0945 CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks(); 0946 CartesianPlot::RangeBreak b; 0947 breaks.list << b; 0948 breaks.lastChanged = breaks.list.size() - 1; 0949 for (auto* plot : m_plotList) 0950 plot->setYRangeBreaks(breaks); 0951 0952 ui.cbYBreak->addItem(QString::number(ui.cbYBreak->count() + 1)); 0953 ui.cbYBreak->setCurrentIndex(ui.cbYBreak->count()-1); 0954 } 0955 0956 void CartesianPlotDock::removeYBreak() { 0957 ui.bRemoveYBreak->setVisible(m_plot->yRangeBreaks().list.size() > 1); 0958 int index = ui.cbYBreak->currentIndex(); 0959 CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks(); 0960 breaks.list.takeAt(index); 0961 breaks.lastChanged = -1; 0962 for (auto* plot : m_plotList) 0963 plot->setYRangeBreaks(breaks); 0964 0965 ui.cbYBreak->clear(); 0966 for (int i = 1; i <= breaks.list.size(); ++i) 0967 ui.cbYBreak->addItem(QString::number(i)); 0968 0969 if (index < ui.cbYBreak->count()-1) 0970 ui.cbYBreak->setCurrentIndex(index); 0971 else 0972 ui.cbYBreak->setCurrentIndex(ui.cbYBreak->count()-1); 0973 0974 ui.bRemoveYBreak->setVisible(ui.cbYBreak->count() != 1); 0975 } 0976 0977 void CartesianPlotDock::currentYBreakChanged(int index) { 0978 if (m_initializing) 0979 return; 0980 0981 if (index == -1) 0982 return; 0983 0984 m_initializing = true; 0985 SET_NUMBER_LOCALE 0986 const CartesianPlot::RangeBreak rangeBreak = m_plot->yRangeBreaks().list.at(index); 0987 QString str = std::isnan(rangeBreak.start) ? QString() : numberLocale.toString(rangeBreak.start); 0988 ui.leYBreakStart->setText(str); 0989 str = std::isnan(rangeBreak.end) ? QString() : numberLocale.toString(rangeBreak.end); 0990 ui.leYBreakEnd->setText(str); 0991 ui.sbYBreakPosition->setValue(rangeBreak.position*100); 0992 ui.cbYBreakStyle->setCurrentIndex((int)rangeBreak.style); 0993 m_initializing = false; 0994 } 0995 0996 void CartesianPlotDock::yBreakStartChanged() { 0997 if (m_initializing) 0998 return; 0999 1000 int index = ui.cbYBreak->currentIndex(); 1001 CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks(); 1002 breaks.list[index].start = ui.leYBreakStart->text().toDouble(); 1003 breaks.lastChanged = index; 1004 1005 for (auto* plot : m_plotList) 1006 plot->setYRangeBreaks(breaks); 1007 } 1008 1009 void CartesianPlotDock::yBreakEndChanged() { 1010 if (m_initializing) 1011 return; 1012 1013 int index = ui.cbYBreak->currentIndex(); 1014 CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks(); 1015 breaks.list[index].end = ui.leYBreakEnd->text().toDouble(); 1016 breaks.lastChanged = index; 1017 1018 for (auto* plot : m_plotList) 1019 plot->setYRangeBreaks(breaks); 1020 } 1021 1022 void CartesianPlotDock::yBreakPositionChanged(int value) { 1023 if (m_initializing) 1024 return; 1025 1026 int index = ui.cbYBreak->currentIndex(); 1027 CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks(); 1028 breaks.list[index].position = (float)value/100.; 1029 breaks.lastChanged = index; 1030 1031 for (auto* plot : m_plotList) 1032 plot->setYRangeBreaks(breaks); 1033 } 1034 1035 void CartesianPlotDock::yBreakStyleChanged(int styleIndex) { 1036 if (m_initializing) 1037 return; 1038 1039 int index = ui.cbYBreak->currentIndex(); 1040 auto style = CartesianPlot::RangeBreakStyle(styleIndex); 1041 CartesianPlot::RangeBreaks breaks = m_plot->yRangeBreaks(); 1042 breaks.list[index].style = style; 1043 breaks.lastChanged = index; 1044 1045 for (auto* plot : m_plotList) 1046 plot->setYRangeBreaks(breaks); 1047 } 1048 1049 // "Plot area"-tab 1050 void CartesianPlotDock::backgroundTypeChanged(int index) { 1051 auto type = (PlotArea::BackgroundType)index; 1052 1053 if (type == PlotArea::BackgroundType::Color) { 1054 ui.lBackgroundColorStyle->show(); 1055 ui.cbBackgroundColorStyle->show(); 1056 ui.lBackgroundImageStyle->hide(); 1057 ui.cbBackgroundImageStyle->hide(); 1058 ui.lBackgroundBrushStyle->hide(); 1059 ui.cbBackgroundBrushStyle->hide(); 1060 1061 ui.lBackgroundFileName->hide(); 1062 ui.leBackgroundFileName->hide(); 1063 ui.bOpen->hide(); 1064 1065 ui.lBackgroundFirstColor->show(); 1066 ui.kcbBackgroundFirstColor->show(); 1067 1068 auto style = (PlotArea::BackgroundColorStyle) ui.cbBackgroundColorStyle->currentIndex(); 1069 if (style == PlotArea::BackgroundColorStyle::SingleColor) { 1070 ui.lBackgroundFirstColor->setText(i18n("Color:")); 1071 ui.lBackgroundSecondColor->hide(); 1072 ui.kcbBackgroundSecondColor->hide(); 1073 } else { 1074 ui.lBackgroundFirstColor->setText(i18n("First color:")); 1075 ui.lBackgroundSecondColor->show(); 1076 ui.kcbBackgroundSecondColor->show(); 1077 } 1078 } else if (type == PlotArea::BackgroundType::Image) { 1079 ui.lBackgroundColorStyle->hide(); 1080 ui.cbBackgroundColorStyle->hide(); 1081 ui.lBackgroundImageStyle->show(); 1082 ui.cbBackgroundImageStyle->show(); 1083 ui.lBackgroundBrushStyle->hide(); 1084 ui.cbBackgroundBrushStyle->hide(); 1085 ui.lBackgroundFileName->show(); 1086 ui.leBackgroundFileName->show(); 1087 ui.bOpen->show(); 1088 1089 ui.lBackgroundFirstColor->hide(); 1090 ui.kcbBackgroundFirstColor->hide(); 1091 ui.lBackgroundSecondColor->hide(); 1092 ui.kcbBackgroundSecondColor->hide(); 1093 } else if (type == PlotArea::BackgroundType::Pattern) { 1094 ui.lBackgroundFirstColor->setText(i18n("Color:")); 1095 ui.lBackgroundColorStyle->hide(); 1096 ui.cbBackgroundColorStyle->hide(); 1097 ui.lBackgroundImageStyle->hide(); 1098 ui.cbBackgroundImageStyle->hide(); 1099 ui.lBackgroundBrushStyle->show(); 1100 ui.cbBackgroundBrushStyle->show(); 1101 ui.lBackgroundFileName->hide(); 1102 ui.leBackgroundFileName->hide(); 1103 ui.bOpen->hide(); 1104 1105 ui.lBackgroundFirstColor->show(); 1106 ui.kcbBackgroundFirstColor->show(); 1107 ui.lBackgroundSecondColor->hide(); 1108 ui.kcbBackgroundSecondColor->hide(); 1109 } 1110 1111 if (m_initializing) 1112 return; 1113 1114 for (auto* plot : m_plotList) 1115 plot->plotArea()->setBackgroundType(type); 1116 } 1117 1118 void CartesianPlotDock::backgroundColorStyleChanged(int index) { 1119 auto style = (PlotArea::BackgroundColorStyle)index; 1120 1121 if (style == PlotArea::BackgroundColorStyle::SingleColor) { 1122 ui.lBackgroundFirstColor->setText(i18n("Color:")); 1123 ui.lBackgroundSecondColor->hide(); 1124 ui.kcbBackgroundSecondColor->hide(); 1125 } else { 1126 ui.lBackgroundFirstColor->setText(i18n("First color:")); 1127 ui.lBackgroundSecondColor->show(); 1128 ui.kcbBackgroundSecondColor->show(); 1129 ui.lBackgroundBrushStyle->hide(); 1130 ui.cbBackgroundBrushStyle->hide(); 1131 } 1132 1133 if (m_initializing) 1134 return; 1135 1136 for (auto* plot : m_plotList) 1137 plot->plotArea()->setBackgroundColorStyle(style); 1138 } 1139 1140 void CartesianPlotDock::backgroundImageStyleChanged(int index) { 1141 if (m_initializing) 1142 return; 1143 1144 auto style = (PlotArea::BackgroundImageStyle)index; 1145 for (auto* plot : m_plotList) 1146 plot->plotArea()->setBackgroundImageStyle(style); 1147 } 1148 1149 void CartesianPlotDock::backgroundBrushStyleChanged(int index) { 1150 if (m_initializing) 1151 return; 1152 1153 auto style = (Qt::BrushStyle)index; 1154 for (auto* plot : m_plotList) 1155 plot->plotArea()->setBackgroundBrushStyle(style); 1156 } 1157 1158 void CartesianPlotDock::backgroundFirstColorChanged(const QColor& c) { 1159 if (m_initializing) 1160 return; 1161 1162 for (auto* plot : m_plotList) 1163 plot->plotArea()->setBackgroundFirstColor(c); 1164 } 1165 1166 void CartesianPlotDock::backgroundSecondColorChanged(const QColor& c) { 1167 if (m_initializing) 1168 return; 1169 1170 for (auto* plot : m_plotList) 1171 plot->plotArea()->setBackgroundSecondColor(c); 1172 } 1173 1174 /*! 1175 opens a file dialog and lets the user select the image file. 1176 */ 1177 void CartesianPlotDock::selectFile() { 1178 KConfigGroup conf(KSharedConfig::openConfig(), "CartesianPlotDock"); 1179 QString dir = conf.readEntry("LastImageDir", ""); 1180 1181 QString formats; 1182 for (const auto& format : QImageReader::supportedImageFormats()) { 1183 QString f = "*." + QString(format.constData()); 1184 if (f == QLatin1String("*.svg")) 1185 continue; 1186 formats.isEmpty() ? formats += f : formats += ' ' + f; 1187 } 1188 1189 QString path = QFileDialog::getOpenFileName(this, i18n("Select the image file"), dir, i18n("Images (%1)", formats)); 1190 if (path.isEmpty()) 1191 return; //cancel was clicked in the file-dialog 1192 1193 int pos = path.lastIndexOf(QLatin1String("/")); 1194 if (pos != -1) { 1195 QString newDir{path.left(pos)}; 1196 if (newDir != dir) 1197 conf.writeEntry("LastImageDir", newDir); 1198 } 1199 1200 ui.leBackgroundFileName->setText(path); 1201 1202 for (auto* plot : m_plotList) 1203 plot->plotArea()->setBackgroundFileName(path); 1204 } 1205 1206 void CartesianPlotDock::fileNameChanged() { 1207 if (m_initializing) 1208 return; 1209 1210 const QString& fileName = ui.leBackgroundFileName->text(); 1211 bool invalid = (!fileName.isEmpty() && !QFile::exists(fileName)); 1212 GuiTools::highlight(ui.leBackgroundFileName, invalid); 1213 1214 for (auto* plot : m_plotList) 1215 plot->plotArea()->setBackgroundFileName(fileName); 1216 } 1217 1218 void CartesianPlotDock::backgroundOpacityChanged(int value) { 1219 if (m_initializing) 1220 return; 1221 1222 qreal opacity = (float)value/100.; 1223 for (auto* plot : m_plotList) 1224 plot->plotArea()->setBackgroundOpacity(opacity); 1225 } 1226 1227 // "Border"-tab 1228 void CartesianPlotDock::borderStyleChanged(int index) { 1229 if (m_initializing) 1230 return; 1231 1232 auto penStyle = Qt::PenStyle(index); 1233 QPen pen; 1234 for (auto* plot : m_plotList) { 1235 pen = plot->plotArea()->borderPen(); 1236 pen.setStyle(penStyle); 1237 plot->plotArea()->setBorderPen(pen); 1238 } 1239 } 1240 1241 void CartesianPlotDock::borderColorChanged(const QColor& color) { 1242 if (m_initializing) 1243 return; 1244 1245 QPen pen; 1246 for (auto* plot : m_plotList) { 1247 pen = plot->plotArea()->borderPen(); 1248 pen.setColor(color); 1249 plot->plotArea()->setBorderPen(pen); 1250 } 1251 1252 m_initializing = true; 1253 GuiTools::updatePenStyles(ui.cbBorderStyle, color); 1254 m_initializing = false; 1255 } 1256 1257 void CartesianPlotDock::borderWidthChanged(double value) { 1258 if (m_initializing) 1259 return; 1260 1261 QPen pen; 1262 for (auto* plot : m_plotList) { 1263 pen = plot->plotArea()->borderPen(); 1264 pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) ); 1265 plot->plotArea()->setBorderPen(pen); 1266 } 1267 } 1268 1269 void CartesianPlotDock::borderCornerRadiusChanged(double value) { 1270 if (m_initializing) 1271 return; 1272 1273 for (auto* plot : m_plotList) 1274 plot->plotArea()->setBorderCornerRadius(Worksheet::convertToSceneUnits(value, m_worksheetUnit)); 1275 } 1276 1277 void CartesianPlotDock::borderOpacityChanged(int value) { 1278 if (m_initializing) 1279 return; 1280 1281 qreal opacity = (float)value/100.; 1282 for (auto* plot : m_plotList) 1283 plot->plotArea()->setBorderOpacity(opacity); 1284 } 1285 1286 void CartesianPlotDock::symmetricPaddingChanged(bool checked) { 1287 ui.lPaddingHorizontalRight->setVisible(!checked); 1288 ui.sbPaddingRight->setVisible(!checked); 1289 ui.lPaddingVerticalDown->setVisible(!checked); 1290 ui.sbPaddingBottom->setVisible(!checked); 1291 1292 if (checked) { 1293 ui.lPaddingHorizontal->setText(i18n("Horizontal:")); 1294 ui.lPaddingVertical->setText(i18n("Vertical:")); 1295 } else { 1296 ui.lPaddingHorizontal->setText(i18n("Left:")); 1297 ui.lPaddingVertical->setText(i18n("Top:")); 1298 } 1299 1300 if (m_initializing) 1301 return; 1302 1303 for (auto* plot : m_plotList) 1304 plot->setSymmetricPadding(checked); 1305 1306 if (checked) { 1307 rightPaddingChanged(ui.sbPaddingHorizontal->value()); 1308 bottomPaddingChanged(ui.sbPaddingVertical->value()); 1309 } 1310 } 1311 1312 void CartesianPlotDock::horizontalPaddingChanged(double value) { 1313 if (m_initializing) 1314 return; 1315 double padding = Worksheet::convertToSceneUnits(value, m_worksheetUnit); 1316 for (auto* plot : m_plotList) 1317 plot->setHorizontalPadding(padding); 1318 1319 if (m_plot->symmetricPadding()) { 1320 for (auto* plot: m_plotList) 1321 plot->setRightPadding(padding); 1322 } 1323 } 1324 1325 void CartesianPlotDock::rightPaddingChanged(double value) { 1326 if (m_initializing) 1327 return; 1328 double padding = Worksheet::convertToSceneUnits(value, m_worksheetUnit); 1329 for (auto* plot : m_plotList) 1330 plot->setRightPadding(padding); 1331 } 1332 1333 void CartesianPlotDock::verticalPaddingChanged(double value) { 1334 if (m_initializing) 1335 return; 1336 1337 // TODO: find better solution (set spinbox range). When plot->rect().width() does change? 1338 double padding = Worksheet::convertToSceneUnits(value, m_worksheetUnit); 1339 for (auto* plot : m_plotList) 1340 plot->setVerticalPadding(padding); 1341 1342 if (m_plot->symmetricPadding()) { 1343 for (auto* plot: m_plotList) 1344 plot->setBottomPadding(padding); 1345 } 1346 } 1347 1348 void CartesianPlotDock::bottomPaddingChanged(double value) { 1349 if (m_initializing) 1350 return; 1351 double padding = Worksheet::convertToSceneUnits(value, m_worksheetUnit); 1352 for (auto* plot : m_plotList) 1353 plot->setBottomPadding(padding); 1354 } 1355 1356 void CartesianPlotDock::cursorLineWidthChanged(int width) { 1357 if (m_initializing) 1358 return; 1359 1360 for (auto* plot : m_plotList) { 1361 QPen pen = plot->cursorPen(); 1362 pen.setWidthF( Worksheet::convertToSceneUnits(width, Worksheet::Unit::Point) ); 1363 plot->setCursorPen(pen); 1364 } 1365 } 1366 1367 void CartesianPlotDock::cursorLineColorChanged(const QColor& color) { 1368 if (m_initializing) 1369 return; 1370 1371 for (auto* plot : m_plotList) { 1372 QPen pen = plot->cursorPen(); 1373 pen.setColor(color); 1374 plot->setCursorPen(pen); 1375 } 1376 1377 m_initializing = true; 1378 GuiTools::updatePenStyles(ui.cbCursorLineStyle, color); 1379 m_initializing = false; 1380 } 1381 1382 void CartesianPlotDock::cursorLineStyleChanged(int index) { 1383 if (m_initializing) 1384 return; 1385 1386 if (index > 5) 1387 return; 1388 1389 for (auto* plot : m_plotList) { 1390 QPen pen = plot->cursorPen(); 1391 pen.setStyle(static_cast<Qt::PenStyle>(index)); 1392 plot->setCursorPen(pen); 1393 } 1394 } 1395 1396 //************************************************************* 1397 //****** SLOTs for changes triggered in CartesianPlot ********* 1398 //************************************************************* 1399 //general 1400 void CartesianPlotDock::plotDescriptionChanged(const AbstractAspect* aspect) { 1401 if (m_plot != aspect) 1402 return; 1403 1404 m_initializing = true; 1405 if (aspect->name() != ui.leName->text()) 1406 ui.leName->setText(aspect->name()); 1407 else if (aspect->comment() != ui.leComment->text()) 1408 ui.leComment->setText(aspect->comment()); 1409 m_initializing = false; 1410 } 1411 1412 void CartesianPlotDock::plotRectChanged(QRectF& rect) { 1413 m_initializing = true; 1414 ui.sbLeft->setValue(Worksheet::convertFromSceneUnits(rect.x(), m_worksheetUnit)); 1415 ui.sbTop->setValue(Worksheet::convertFromSceneUnits(rect.y(), m_worksheetUnit)); 1416 ui.sbWidth->setValue(Worksheet::convertFromSceneUnits(rect.width(), m_worksheetUnit)); 1417 ui.sbHeight->setValue(Worksheet::convertFromSceneUnits(rect.height(), m_worksheetUnit)); 1418 m_initializing = false; 1419 } 1420 1421 void CartesianPlotDock::plotRangeTypeChanged(CartesianPlot::RangeType type) { 1422 m_initializing = true; 1423 switch (type) { 1424 case CartesianPlot::RangeType::Free: 1425 ui.rbRangeFree->setChecked(true); 1426 break; 1427 case CartesianPlot::RangeType::First: 1428 ui.rbRangeFirst->setChecked(true); 1429 break; 1430 case CartesianPlot::RangeType::Last: 1431 ui.rbRangeLast->setChecked(true); 1432 break; 1433 } 1434 m_initializing = false; 1435 } 1436 1437 void CartesianPlotDock::plotRangeFirstValuesChanged(int value) { 1438 m_initializing = true; 1439 SET_NUMBER_LOCALE 1440 ui.leRangeFirst->setText(numberLocale.toString(value)); 1441 m_initializing = false; 1442 } 1443 1444 void CartesianPlotDock::plotRangeLastValuesChanged(int value) { 1445 m_initializing = true; 1446 SET_NUMBER_LOCALE 1447 ui.leRangeLast->setText(numberLocale.toString(value)); 1448 m_initializing = false; 1449 } 1450 1451 void CartesianPlotDock::plotXAutoScaleChanged(bool value) { 1452 m_initializing = true; 1453 ui.chkAutoScaleX->setChecked(value); 1454 m_initializing = false; 1455 } 1456 1457 void CartesianPlotDock::plotXMinChanged(double value) { 1458 if (m_initializing) 1459 return; 1460 const Lock lock(m_initializing); 1461 SET_NUMBER_LOCALE 1462 ui.leXMin->setText(numberLocale.toString(value)); 1463 ui.dateTimeEditXMin->setDateTime(QDateTime::fromMSecsSinceEpoch(value)); 1464 } 1465 1466 void CartesianPlotDock::plotXMaxChanged(double value) { 1467 if (m_initializing) 1468 return; 1469 const Lock lock(m_initializing); 1470 SET_NUMBER_LOCALE 1471 ui.leXMax->setText(numberLocale.toString(value)); 1472 ui.dateTimeEditXMax->setDateTime( QDateTime::fromMSecsSinceEpoch(value) ); 1473 } 1474 1475 void CartesianPlotDock::plotXScaleChanged(CartesianPlot::Scale scale) { 1476 m_initializing = true; 1477 ui.cbXScaling->setCurrentIndex(static_cast<int>(scale)); 1478 m_initializing = false; 1479 } 1480 1481 void CartesianPlotDock::plotXRangeFormatChanged(CartesianPlot::RangeFormat format) { 1482 m_initializing = true; 1483 ui.cbXRangeFormat->setCurrentIndex(static_cast<int>(format)); 1484 m_initializing = false; 1485 } 1486 1487 void CartesianPlotDock::plotYAutoScaleChanged(bool value) { 1488 m_initializing = true; 1489 ui.chkAutoScaleY->setChecked(value); 1490 m_initializing = false; 1491 } 1492 1493 void CartesianPlotDock::plotYMinChanged(double value) { 1494 if (m_initializing) 1495 return; 1496 const Lock lock(m_initializing); 1497 SET_NUMBER_LOCALE 1498 ui.leYMin->setText(numberLocale.toString(value)); 1499 ui.dateTimeEditYMin->setDateTime( QDateTime::fromMSecsSinceEpoch(value) ); 1500 } 1501 1502 void CartesianPlotDock::plotYMaxChanged(double value) { 1503 if (m_initializing) 1504 return; 1505 const Lock lock(m_initializing); 1506 SET_NUMBER_LOCALE 1507 ui.leYMax->setText(numberLocale.toString(value)); 1508 ui.dateTimeEditYMax->setDateTime( QDateTime::fromMSecsSinceEpoch(value) ); 1509 } 1510 1511 void CartesianPlotDock::plotYScaleChanged(CartesianPlot::Scale scale) { 1512 m_initializing = true; 1513 ui.cbYScaling->setCurrentIndex(static_cast<int>(scale)); 1514 m_initializing = false; 1515 } 1516 1517 void CartesianPlotDock::plotYRangeFormatChanged(CartesianPlot::RangeFormat format) { 1518 m_initializing = true; 1519 ui.cbYRangeFormat->setCurrentIndex(static_cast<int>(format)); 1520 m_initializing = false; 1521 } 1522 1523 void CartesianPlotDock::plotVisibleChanged(bool on) { 1524 m_initializing = true; 1525 ui.chkVisible->setChecked(on); 1526 m_initializing = false; 1527 } 1528 1529 //range breaks 1530 void CartesianPlotDock::plotXRangeBreakingEnabledChanged(bool on) { 1531 m_initializing = true; 1532 ui.chkXBreak->setChecked(on); 1533 m_initializing = false; 1534 } 1535 1536 void CartesianPlotDock::plotXRangeBreaksChanged(const CartesianPlot::RangeBreaks& breaks) { 1537 Q_UNUSED(breaks); 1538 } 1539 1540 void CartesianPlotDock::plotYRangeBreakingEnabledChanged(bool on) { 1541 m_initializing = true; 1542 ui.chkYBreak->setChecked(on); 1543 m_initializing = false; 1544 } 1545 1546 void CartesianPlotDock::plotYRangeBreaksChanged(const CartesianPlot::RangeBreaks& breaks) { 1547 Q_UNUSED(breaks); 1548 } 1549 1550 //background 1551 void CartesianPlotDock::plotBackgroundTypeChanged(PlotArea::BackgroundType type) { 1552 m_initializing = true; 1553 ui.cbBackgroundType->setCurrentIndex(static_cast<int>(type)); 1554 m_initializing = false; 1555 } 1556 1557 void CartesianPlotDock::plotBackgroundColorStyleChanged(PlotArea::BackgroundColorStyle style) { 1558 m_initializing = true; 1559 ui.cbBackgroundColorStyle->setCurrentIndex(static_cast<int>(style)); 1560 m_initializing = false; 1561 } 1562 1563 void CartesianPlotDock::plotBackgroundImageStyleChanged(PlotArea::BackgroundImageStyle style) { 1564 m_initializing = true; 1565 ui.cbBackgroundImageStyle->setCurrentIndex(static_cast<int>(style)); 1566 m_initializing = false; 1567 } 1568 1569 void CartesianPlotDock::plotBackgroundBrushStyleChanged(Qt::BrushStyle style) { 1570 m_initializing = true; 1571 ui.cbBackgroundBrushStyle->setCurrentIndex(style); 1572 m_initializing = false; 1573 } 1574 1575 void CartesianPlotDock::plotBackgroundFirstColorChanged(QColor& color) { 1576 m_initializing = true; 1577 ui.kcbBackgroundFirstColor->setColor(color); 1578 m_initializing = false; 1579 } 1580 1581 void CartesianPlotDock::plotBackgroundSecondColorChanged(QColor& color) { 1582 m_initializing = true; 1583 ui.kcbBackgroundSecondColor->setColor(color); 1584 m_initializing = false; 1585 } 1586 1587 void CartesianPlotDock::plotBackgroundFileNameChanged(QString& filename) { 1588 m_initializing = true; 1589 ui.leBackgroundFileName->setText(filename); 1590 m_initializing = false; 1591 } 1592 1593 void CartesianPlotDock::plotBackgroundOpacityChanged(float opacity) { 1594 m_initializing = true; 1595 ui.sbBackgroundOpacity->setValue( round(opacity*100.0) ); 1596 m_initializing = false; 1597 } 1598 1599 void CartesianPlotDock::plotBorderPenChanged(QPen& pen) { 1600 m_initializing = true; 1601 if (ui.cbBorderStyle->currentIndex() != pen.style()) 1602 ui.cbBorderStyle->setCurrentIndex(pen.style()); 1603 if (ui.kcbBorderColor->color() != pen.color()) 1604 ui.kcbBorderColor->setColor(pen.color()); 1605 if (ui.sbBorderWidth->value() != pen.widthF()) 1606 ui.sbBorderWidth->setValue(Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point)); 1607 m_initializing = false; 1608 } 1609 1610 void CartesianPlotDock::plotBorderCornerRadiusChanged(float value) { 1611 m_initializing = true; 1612 ui.sbBorderCornerRadius->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit)); 1613 m_initializing = false; 1614 } 1615 1616 void CartesianPlotDock::plotBorderOpacityChanged(float value) { 1617 m_initializing = true; 1618 float v = (float)value*100.; 1619 ui.sbBorderOpacity->setValue(v); 1620 m_initializing = false; 1621 } 1622 1623 void CartesianPlotDock::plotHorizontalPaddingChanged(float value) { 1624 m_initializing = true; 1625 ui.sbPaddingHorizontal->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit)); 1626 m_initializing = false; 1627 } 1628 1629 void CartesianPlotDock::plotVerticalPaddingChanged(float value) { 1630 m_initializing = true; 1631 ui.sbPaddingVertical->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit)); 1632 m_initializing = false; 1633 } 1634 1635 void CartesianPlotDock::plotRightPaddingChanged(double value) { 1636 m_initializing = true; 1637 ui.sbPaddingRight->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit)); 1638 m_initializing = false; 1639 } 1640 1641 void CartesianPlotDock::plotBottomPaddingChanged(double value) { 1642 m_initializing = true; 1643 ui.sbPaddingBottom->setValue(Worksheet::convertFromSceneUnits(value, m_worksheetUnit)); 1644 m_initializing = false; 1645 } 1646 1647 void CartesianPlotDock::plotSymmetricPaddingChanged(bool symmetric) { 1648 m_initializing = true; 1649 ui.cbPaddingSymmetric->setChecked(symmetric); 1650 m_initializing = false; 1651 } 1652 1653 void CartesianPlotDock::plotCursorPenChanged(const QPen& pen) { 1654 m_initializing = true; 1655 ui.sbCursorLineWidth->setValue(Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point)); 1656 ui.kcbCursorLineColor->setColor(pen.color()); 1657 ui.cbCursorLineStyle->setCurrentIndex(pen.style()); 1658 m_initializing = false; 1659 } 1660 1661 //************************************************************* 1662 //******************** SETTINGS ******************************* 1663 //************************************************************* 1664 void CartesianPlotDock::loadConfigFromTemplate(KConfig& config) { 1665 //extract the name of the template from the file name 1666 QString name; 1667 int index = config.name().lastIndexOf(QLatin1String("/")); 1668 if (index != -1) 1669 name = config.name().right(config.name().size() - index - 1); 1670 else 1671 name = config.name(); 1672 1673 int size = m_plotList.size(); 1674 if (size > 1) 1675 m_plot->beginMacro(i18n("%1 cartesian plots: template \"%2\" loaded", size, name)); 1676 else 1677 m_plot->beginMacro(i18n("%1: template \"%2\" loaded", m_plot->name(), name)); 1678 1679 this->loadConfig(config); 1680 1681 m_plot->endMacro(); 1682 } 1683 1684 void CartesianPlotDock::load() { 1685 //General-tab 1686 ui.chkVisible->setChecked(m_plot->isVisible()); 1687 ui.sbLeft->setValue(Worksheet::convertFromSceneUnits(m_plot->rect().x(), m_worksheetUnit)); 1688 ui.sbTop->setValue(Worksheet::convertFromSceneUnits(m_plot->rect().y(), m_worksheetUnit)); 1689 ui.sbWidth->setValue(Worksheet::convertFromSceneUnits(m_plot->rect().width(), m_worksheetUnit)); 1690 ui.sbHeight->setValue(Worksheet::convertFromSceneUnits(m_plot->rect().height(), m_worksheetUnit)); 1691 1692 switch (m_plot->rangeType()) { 1693 case CartesianPlot::RangeType::Free: 1694 ui.rbRangeFree->setChecked(true); 1695 break; 1696 case CartesianPlot::RangeType::First: 1697 ui.rbRangeFirst->setChecked(true); 1698 break; 1699 case CartesianPlot::RangeType::Last: 1700 ui.rbRangeLast->setChecked(true); 1701 break; 1702 } 1703 rangeTypeChanged(); 1704 SET_NUMBER_LOCALE 1705 ui.leRangeFirst->setText( numberLocale.toString(m_plot->rangeFirstValues()) ); 1706 ui.leRangeLast->setText( numberLocale.toString(m_plot->rangeLastValues()) ); 1707 1708 ui.chkAutoScaleX->setChecked(m_plot->autoScaleX()); 1709 ui.leXMin->setText(numberLocale.toString(m_plot->xMin())); 1710 ui.leXMax->setText(numberLocale.toString(m_plot->xMax())); 1711 ui.dateTimeEditXMin->setDisplayFormat(m_plot->xRangeDateTimeFormat()); 1712 ui.dateTimeEditXMax->setDisplayFormat(m_plot->xRangeDateTimeFormat()); 1713 ui.dateTimeEditXMin->setDateTime(QDateTime::fromMSecsSinceEpoch(m_plot->xMin())); 1714 ui.dateTimeEditXMax->setDateTime(QDateTime::fromMSecsSinceEpoch(m_plot->xMax())); 1715 ui.cbXScaling->setCurrentIndex( (int) m_plot->xScale() ); 1716 ui.cbXRangeFormat->setCurrentIndex( (int) m_plot->xRangeFormat() ); 1717 1718 ui.chkAutoScaleY->setChecked(m_plot->autoScaleY()); 1719 ui.leYMin->setText(numberLocale.toString(m_plot->yMin())); 1720 ui.leYMax->setText(numberLocale.toString(m_plot->yMax())); 1721 ui.dateTimeEditYMin->setDisplayFormat(m_plot->yRangeDateTimeFormat()); 1722 ui.dateTimeEditYMax->setDisplayFormat(m_plot->yRangeDateTimeFormat()); 1723 ui.dateTimeEditYMin->setDateTime(QDateTime::fromMSecsSinceEpoch(m_plot->yMin())); 1724 ui.dateTimeEditYMax->setDateTime(QDateTime::fromMSecsSinceEpoch(m_plot->yMax())); 1725 ui.cbYScaling->setCurrentIndex( (int)m_plot->yScale() ); 1726 ui.cbYRangeFormat->setCurrentIndex( (int) m_plot->yRangeFormat() ); 1727 1728 //Title 1729 labelWidget->load(); 1730 1731 //x-range breaks, show the first break 1732 ui.chkXBreak->setChecked(m_plot->xRangeBreakingEnabled()); 1733 this->toggleXBreak(m_plot->xRangeBreakingEnabled()); 1734 ui.bRemoveXBreak->setVisible(m_plot->xRangeBreaks().list.size() > 1); 1735 ui.cbXBreak->clear(); 1736 if (!m_plot->xRangeBreaks().list.isEmpty()) { 1737 for (int i = 1; i <= m_plot->xRangeBreaks().list.size(); ++i) 1738 ui.cbXBreak->addItem(QString::number(i)); 1739 } else 1740 ui.cbXBreak->addItem("1"); 1741 ui.cbXBreak->setCurrentIndex(0); 1742 1743 //y-range breaks, show the first break 1744 ui.chkYBreak->setChecked(m_plot->yRangeBreakingEnabled()); 1745 this->toggleYBreak(m_plot->yRangeBreakingEnabled()); 1746 ui.bRemoveYBreak->setVisible(m_plot->yRangeBreaks().list.size() > 1); 1747 ui.cbYBreak->clear(); 1748 if (!m_plot->yRangeBreaks().list.isEmpty()) { 1749 for (int i = 1; i <= m_plot->yRangeBreaks().list.size(); ++i) 1750 ui.cbYBreak->addItem(QString::number(i)); 1751 } else 1752 ui.cbYBreak->addItem("1"); 1753 ui.cbYBreak->setCurrentIndex(0); 1754 1755 //"Plot Area"-tab 1756 //Background 1757 ui.cbBackgroundType->setCurrentIndex( (int)m_plot->plotArea()->backgroundType() ); 1758 backgroundTypeChanged(ui.cbBackgroundType->currentIndex()); 1759 ui.cbBackgroundColorStyle->setCurrentIndex( (int) m_plot->plotArea()->backgroundColorStyle() ); 1760 ui.cbBackgroundImageStyle->setCurrentIndex( (int) m_plot->plotArea()->backgroundImageStyle() ); 1761 ui.cbBackgroundBrushStyle->setCurrentIndex( (int) m_plot->plotArea()->backgroundBrushStyle() ); 1762 ui.leBackgroundFileName->setText( m_plot->plotArea()->backgroundFileName() ); 1763 ui.kcbBackgroundFirstColor->setColor( m_plot->plotArea()->backgroundFirstColor() ); 1764 ui.kcbBackgroundSecondColor->setColor( m_plot->plotArea()->backgroundSecondColor() ); 1765 ui.sbBackgroundOpacity->setValue( round(m_plot->plotArea()->backgroundOpacity()*100.0) ); 1766 1767 //highlight the text field for the background image red if an image is used and cannot be found 1768 const QString& fileName = m_plot->plotArea()->backgroundFileName(); 1769 bool invalid = (!fileName.isEmpty() && !QFile::exists(fileName)); 1770 GuiTools::highlight(ui.leBackgroundFileName, invalid); 1771 1772 //Padding 1773 ui.sbPaddingHorizontal->setValue( Worksheet::convertFromSceneUnits(m_plot->horizontalPadding(), m_worksheetUnit) ); 1774 ui.sbPaddingVertical->setValue( Worksheet::convertFromSceneUnits(m_plot->verticalPadding(), m_worksheetUnit) ); 1775 ui.sbPaddingRight->setValue(Worksheet::convertFromSceneUnits(m_plot->rightPadding(), m_worksheetUnit)); 1776 ui.sbPaddingBottom->setValue(Worksheet::convertFromSceneUnits(m_plot->bottomPadding(), m_worksheetUnit)); 1777 ui.cbPaddingSymmetric->setChecked(m_plot->symmetricPadding()); 1778 1779 //Border 1780 ui.kcbBorderColor->setColor( m_plot->plotArea()->borderPen().color() ); 1781 ui.cbBorderStyle->setCurrentIndex( (int) m_plot->plotArea()->borderPen().style() ); 1782 ui.sbBorderWidth->setValue( Worksheet::convertFromSceneUnits(m_plot->plotArea()->borderPen().widthF(), Worksheet::Unit::Point) ); 1783 ui.sbBorderCornerRadius->setValue( Worksheet::convertFromSceneUnits(m_plot->plotArea()->borderCornerRadius(), m_worksheetUnit) ); 1784 ui.sbBorderOpacity->setValue( round(m_plot->plotArea()->borderOpacity()*100) ); 1785 GuiTools::updatePenStyles(ui.cbBorderStyle, ui.kcbBorderColor->color()); 1786 1787 // Cursor 1788 QPen pen = m_plot->cursorPen(); 1789 ui.cbCursorLineStyle->setCurrentIndex(pen.style()); 1790 ui.kcbCursorLineColor->setColor(pen.color()); 1791 ui.sbCursorLineWidth->setValue(pen.width()); 1792 GuiTools::updatePenStyles(ui.cbCursorLineStyle, pen.color()); 1793 } 1794 1795 void CartesianPlotDock::loadConfig(KConfig& config) { 1796 KConfigGroup group = config.group("CartesianPlot"); 1797 1798 //General 1799 //we don't load/save the settings in the general-tab, since they are not style related. 1800 //It doesn't make sense to load/save them in the template. 1801 //This data is read in CartesianPlotDock::setPlots(). 1802 1803 //Title 1804 KConfigGroup plotTitleGroup = config.group("CartesianPlotTitle"); 1805 labelWidget->loadConfig(plotTitleGroup); 1806 1807 //Scale breakings 1808 //TODO 1809 1810 //Background-tab 1811 ui.cbBackgroundType->setCurrentIndex( group.readEntry("BackgroundType", (int) m_plot->plotArea()->backgroundType()) ); 1812 ui.cbBackgroundColorStyle->setCurrentIndex( group.readEntry("BackgroundColorStyle", (int) m_plot->plotArea()->backgroundColorStyle()) ); 1813 ui.cbBackgroundImageStyle->setCurrentIndex( group.readEntry("BackgroundImageStyle", (int) m_plot->plotArea()->backgroundImageStyle()) ); 1814 ui.cbBackgroundBrushStyle->setCurrentIndex( group.readEntry("BackgroundBrushStyle", (int) m_plot->plotArea()->backgroundBrushStyle()) ); 1815 ui.leBackgroundFileName->setText( group.readEntry("BackgroundFileName", m_plot->plotArea()->backgroundFileName()) ); 1816 ui.kcbBackgroundFirstColor->setColor( group.readEntry("BackgroundFirstColor", m_plot->plotArea()->backgroundFirstColor()) ); 1817 ui.kcbBackgroundSecondColor->setColor( group.readEntry("BackgroundSecondColor", m_plot->plotArea()->backgroundSecondColor()) ); 1818 ui.sbBackgroundOpacity->setValue( round(group.readEntry("BackgroundOpacity", m_plot->plotArea()->backgroundOpacity())*100.0) ); 1819 ui.sbPaddingHorizontal->setValue(Worksheet::convertFromSceneUnits(group.readEntry("HorizontalPadding", m_plot->horizontalPadding()), m_worksheetUnit)); 1820 ui.sbPaddingVertical->setValue(Worksheet::convertFromSceneUnits(group.readEntry("VerticalPadding", m_plot->verticalPadding()), m_worksheetUnit)); 1821 ui.sbPaddingRight->setValue(Worksheet::convertFromSceneUnits(group.readEntry("RightPadding", m_plot->rightPadding()), m_worksheetUnit)); 1822 ui.sbPaddingBottom->setValue(Worksheet::convertFromSceneUnits(group.readEntry("BottomPadding", m_plot->bottomPadding()), m_worksheetUnit)); 1823 ui.cbPaddingSymmetric->setChecked(group.readEntry("SymmetricPadding", m_plot->symmetricPadding())); 1824 1825 //Border-tab 1826 ui.kcbBorderColor->setColor( group.readEntry("BorderColor", m_plot->plotArea()->borderPen().color()) ); 1827 ui.cbBorderStyle->setCurrentIndex( group.readEntry("BorderStyle", (int) m_plot->plotArea()->borderPen().style()) ); 1828 ui.sbBorderWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("BorderWidth", m_plot->plotArea()->borderPen().widthF()), Worksheet::Unit::Point) ); 1829 ui.sbBorderCornerRadius->setValue( Worksheet::convertFromSceneUnits(group.readEntry("BorderCornerRadius", m_plot->plotArea()->borderCornerRadius()), m_worksheetUnit) ); 1830 ui.sbBorderOpacity->setValue( group.readEntry("BorderOpacity", m_plot->plotArea()->borderOpacity())*100 ); 1831 1832 m_initializing = true; 1833 GuiTools::updatePenStyles(ui.cbBorderStyle, ui.kcbBorderColor->color()); 1834 GuiTools::updatePenStyles(ui.cbCursorLineStyle, m_plot->cursorPen().color()); 1835 m_initializing = false; 1836 } 1837 1838 void CartesianPlotDock::saveConfigAsTemplate(KConfig& config) { 1839 KConfigGroup group = config.group("CartesianPlot"); 1840 1841 //General 1842 //we don't load/save the settings in the general-tab, since they are not style related. 1843 //It doesn't make sense to load/save them in the template. 1844 1845 //Title 1846 KConfigGroup plotTitleGroup = config.group("CartesianPlotTitle"); 1847 labelWidget->saveConfig(plotTitleGroup); 1848 1849 //Scale breakings 1850 //TODO 1851 1852 //Background 1853 group.writeEntry("BackgroundType", ui.cbBackgroundType->currentIndex()); 1854 group.writeEntry("BackgroundColorStyle", ui.cbBackgroundColorStyle->currentIndex()); 1855 group.writeEntry("BackgroundImageStyle", ui.cbBackgroundImageStyle->currentIndex()); 1856 group.writeEntry("BackgroundBrushStyle", ui.cbBackgroundBrushStyle->currentIndex()); 1857 group.writeEntry("BackgroundFileName", ui.leBackgroundFileName->text()); 1858 group.writeEntry("BackgroundFirstColor", ui.kcbBackgroundFirstColor->color()); 1859 group.writeEntry("BackgroundSecondColor", ui.kcbBackgroundSecondColor->color()); 1860 group.writeEntry("BackgroundOpacity", ui.sbBackgroundOpacity->value()/100.0); 1861 group.writeEntry("HorizontalPadding", Worksheet::convertToSceneUnits(ui.sbPaddingHorizontal->value(), m_worksheetUnit)); 1862 group.writeEntry("VerticalPadding", Worksheet::convertToSceneUnits(ui.sbPaddingVertical->value(), m_worksheetUnit)); 1863 group.writeEntry("RightPadding", Worksheet::convertToSceneUnits(ui.sbPaddingRight->value(), m_worksheetUnit)); 1864 group.writeEntry("BottomPadding", Worksheet::convertToSceneUnits(ui.sbPaddingBottom->value(), m_worksheetUnit)); 1865 group.writeEntry("SymmetricPadding", ui.cbPaddingSymmetric->isChecked()); 1866 1867 //Border 1868 group.writeEntry("BorderStyle", ui.cbBorderStyle->currentIndex()); 1869 group.writeEntry("BorderColor", ui.kcbBorderColor->color()); 1870 group.writeEntry("BorderWidth", Worksheet::convertToSceneUnits(ui.sbBorderWidth->value(), Worksheet::Unit::Point)); 1871 group.writeEntry("BorderCornerRadius", Worksheet::convertToSceneUnits(ui.sbBorderCornerRadius->value(), m_worksheetUnit)); 1872 group.writeEntry("BorderOpacity", ui.sbBorderOpacity->value()/100.0); 1873 1874 config.sync(); 1875 } 1876 1877 void CartesianPlotDock::loadTheme(const QString& theme) { 1878 for (auto* plot : m_plotList) 1879 plot->setTheme(theme); 1880 } 1881 1882 void CartesianPlotDock::saveTheme(KConfig& config) const { 1883 if (!m_plotList.isEmpty()) 1884 m_plotList.at(0)->saveTheme(config); 1885 }