File indexing completed on 2024-05-12 15:27:55
0001 /*************************************************************************** 0002 File : AxisDock.cpp 0003 Project : LabPlot 0004 Description : axes widget class 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2011-2020 Alexander Semke (alexander.semke@web.de) 0007 Copyright : (C) 2012-2020 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 "AxisDock.h" 0031 #include "backend/core/AspectTreeModel.h" 0032 #include "backend/core/column/Column.h" 0033 #include "backend/core/Project.h" 0034 #include "backend/worksheet/Worksheet.h" 0035 #include "backend/worksheet/plots/cartesian/CartesianPlot.h" 0036 #include "commonfrontend/widgets/TreeViewComboBox.h" 0037 #include "kdefrontend/GuiTools.h" 0038 #include "kdefrontend/TemplateHandler.h" 0039 #include "kdefrontend/widgets/LabelWidget.h" 0040 #include "commonfrontend/widgets/DateTimeSpinBox.h" 0041 0042 #include <QTimer> 0043 #include <QDir> 0044 #include <QPainter> 0045 #include <KLocalizedString> 0046 #include <KMessageBox> 0047 0048 extern "C" { 0049 #include <gsl/gsl_math.h> 0050 #include "backend/nsl/nsl_math.h" 0051 } 0052 0053 /*! 0054 \class AxisDock 0055 \brief Provides a widget for editing the properties of the axes currently selected in the project explorer. 0056 0057 \ingroup kdefrontend 0058 */ 0059 0060 AxisDock::AxisDock(QWidget* parent) : BaseDock(parent) { 0061 ui.setupUi(this); 0062 m_leName = ui.leName; 0063 m_leComment = ui.leComment; 0064 0065 //"Title"-tab 0066 auto* hboxLayout = new QHBoxLayout(ui.tabTitle); 0067 labelWidget = new LabelWidget(ui.tabTitle); 0068 labelWidget->setFixedLabelMode(true); 0069 hboxLayout->addWidget(labelWidget); 0070 hboxLayout->setContentsMargins(2,2,2,2); 0071 hboxLayout->setSpacing(2); 0072 0073 //"Ticks"-tab 0074 auto* layout = static_cast<QGridLayout*>(ui.tabTicks->layout()); 0075 cbMajorTicksColumn = new TreeViewComboBox(ui.tabTicks); 0076 layout->addWidget(cbMajorTicksColumn, 7, 2); 0077 cbMinorTicksColumn = new TreeViewComboBox(ui.tabTicks); 0078 layout->addWidget(cbMinorTicksColumn, 21, 2); 0079 dtsbMajorTicksIncrement = new DateTimeSpinBox(ui.tabTicks); 0080 layout->addWidget(dtsbMajorTicksIncrement, 6, 2); 0081 dtsbMinorTicksIncrement = new DateTimeSpinBox(ui.tabTicks); 0082 layout->addWidget(dtsbMinorTicksIncrement, 20, 2); 0083 0084 //adjust layouts in the tabs 0085 for (int i = 0; i < ui.tabWidget->count(); ++i) { 0086 layout = dynamic_cast<QGridLayout*>(ui.tabWidget->widget(i)->layout()); 0087 if (!layout) 0088 continue; 0089 0090 layout->setContentsMargins(2,2,2,2); 0091 layout->setHorizontalSpacing(2); 0092 layout->setVerticalSpacing(2); 0093 } 0094 0095 //set the current locale 0096 SET_NUMBER_LOCALE 0097 ui.sbLineWidth->setLocale(numberLocale); 0098 ui.sbMajorTicksSpacingNumeric->setLocale(numberLocale); 0099 ui.sbMajorTicksWidth->setLocale(numberLocale); 0100 ui.sbMajorTicksLength->setLocale(numberLocale); 0101 ui.sbMinorTicksSpacingNumeric->setLocale(numberLocale); 0102 ui.sbMinorTicksWidth->setLocale(numberLocale); 0103 ui.sbMinorTicksLength->setLocale(numberLocale); 0104 ui.sbLabelsOffset->setLocale(numberLocale); 0105 ui.sbMajorGridWidth->setLocale(numberLocale); 0106 ui.sbMinorGridWidth->setLocale(numberLocale); 0107 labelWidget->updateLocale(); 0108 0109 //********************************** Slots ********************************************** 0110 0111 //"General"-tab 0112 connect(ui.leName, &QLineEdit::textChanged, this, &AxisDock::nameChanged); 0113 connect(ui.leComment, &QLineEdit::textChanged, this, &AxisDock::commentChanged); 0114 connect(ui.chkVisible, &QCheckBox::clicked, this, &AxisDock::visibilityChanged); 0115 0116 connect(ui.cbOrientation, QOverload<int>::of(&QComboBox::currentIndexChanged), 0117 this, &AxisDock::orientationChanged); 0118 connect(ui.cbPosition, QOverload<int>::of(&QComboBox::currentIndexChanged), 0119 this, QOverload<int>::of(&AxisDock::positionChanged)); 0120 connect(ui.lePosition, &QLineEdit::textChanged, 0121 this, QOverload<>::of(&AxisDock::positionChanged)); 0122 connect(ui.cbScale, QOverload<int>::of(&QComboBox::currentIndexChanged), 0123 this, &AxisDock::scaleChanged); 0124 0125 connect(ui.chkAutoScale, &QCheckBox::stateChanged, this, &AxisDock::autoScaleChanged); 0126 connect(ui.leStart, &QLineEdit::textChanged, this, &AxisDock::startChanged); 0127 connect(ui.leEnd, &QLineEdit::textChanged, this, &AxisDock::endChanged); 0128 connect(ui.dateTimeEditStart, &QDateTimeEdit::dateTimeChanged, this, &AxisDock::startDateTimeChanged); 0129 connect(ui.dateTimeEditEnd, &QDateTimeEdit::dateTimeChanged, this, &AxisDock::endDateTimeChanged); 0130 connect(ui.leZeroOffset, &QLineEdit::textChanged, this, &AxisDock::zeroOffsetChanged); 0131 connect(ui.leScalingFactor, &QLineEdit::textChanged, this, &AxisDock::scalingFactorChanged); 0132 0133 //"Line"-tab 0134 connect(ui.cbLineStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), 0135 this, &AxisDock::lineStyleChanged); 0136 connect(ui.kcbLineColor, &KColorButton::changed, this, &AxisDock::lineColorChanged); 0137 connect(ui.sbLineWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0138 this, &AxisDock::lineWidthChanged); 0139 connect(ui.sbLineOpacity, QOverload<int>::of(&QSpinBox::valueChanged), 0140 this, &AxisDock::lineOpacityChanged); 0141 connect(ui.cbArrowPosition, QOverload<int>::of(&QComboBox::currentIndexChanged), 0142 this, &AxisDock::arrowPositionChanged); 0143 connect(ui.cbArrowType, QOverload<int>::of(&QComboBox::currentIndexChanged), 0144 this, &AxisDock::arrowTypeChanged); 0145 connect(ui.sbArrowSize, QOverload<int>::of(&QSpinBox::valueChanged), 0146 this, &AxisDock::arrowSizeChanged); 0147 0148 //"Major ticks"-tab 0149 connect(ui.cbMajorTicksDirection, QOverload<int>::of(&QComboBox::currentIndexChanged), 0150 this, &AxisDock::majorTicksDirectionChanged); 0151 connect(ui.cbMajorTicksType, QOverload<int>::of(&QComboBox::currentIndexChanged), 0152 this, &AxisDock::majorTicksTypeChanged); 0153 connect(ui.sbMajorTicksNumber, QOverload<int>::of(&QSpinBox::valueChanged), 0154 this, &AxisDock::majorTicksNumberChanged); 0155 connect(ui.sbMajorTicksSpacingNumeric, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0156 this, &AxisDock::majorTicksSpacingChanged); 0157 connect(dtsbMajorTicksIncrement, &DateTimeSpinBox::valueChanged, 0158 this, &AxisDock::majorTicksSpacingChanged); 0159 connect(cbMajorTicksColumn, &TreeViewComboBox::currentModelIndexChanged, 0160 this, &AxisDock::majorTicksColumnChanged); 0161 connect(ui.cbMajorTicksLineStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), 0162 this, &AxisDock::majorTicksLineStyleChanged); 0163 connect(ui.kcbMajorTicksColor, &KColorButton::changed, this, &AxisDock::majorTicksColorChanged); 0164 connect(ui.sbMajorTicksWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0165 this, &AxisDock::majorTicksWidthChanged); 0166 connect(ui.sbMajorTicksLength, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0167 this, &AxisDock::majorTicksLengthChanged); 0168 connect(ui.sbMajorTicksOpacity, QOverload<int>::of(&QSpinBox::valueChanged), 0169 this, &AxisDock::majorTicksOpacityChanged); 0170 0171 //"Minor ticks"-tab 0172 connect(ui.cbMinorTicksDirection, QOverload<int>::of(&QComboBox::currentIndexChanged), 0173 this, &AxisDock::minorTicksDirectionChanged); 0174 connect(ui.cbMinorTicksType, QOverload<int>::of(&QComboBox::currentIndexChanged), 0175 this, &AxisDock::minorTicksTypeChanged); 0176 connect(ui.sbMinorTicksNumber, QOverload<int>::of(&QSpinBox::valueChanged), 0177 this, &AxisDock::minorTicksNumberChanged); 0178 connect(ui.sbMinorTicksSpacingNumeric, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0179 this, &AxisDock::minorTicksSpacingChanged); 0180 connect(dtsbMinorTicksIncrement, &DateTimeSpinBox::valueChanged, 0181 this, &AxisDock::minorTicksSpacingChanged); 0182 connect(cbMinorTicksColumn, &TreeViewComboBox::currentModelIndexChanged, 0183 this, &AxisDock::minorTicksColumnChanged); 0184 connect(ui.cbMinorTicksLineStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), 0185 this, &AxisDock::minorTicksLineStyleChanged); 0186 connect(ui.kcbMinorTicksColor, &KColorButton::changed, this, &AxisDock::minorTicksColorChanged); 0187 connect(ui.sbMinorTicksWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0188 this, &AxisDock::minorTicksWidthChanged); 0189 connect(ui.sbMinorTicksLength, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0190 this, &AxisDock::minorTicksLengthChanged); 0191 connect(ui.sbMinorTicksOpacity, QOverload<int>::of(&QSpinBox::valueChanged), 0192 this, &AxisDock::minorTicksOpacityChanged); 0193 0194 //"Extra ticks"-tab 0195 0196 //"Tick labels"-tab 0197 connect(ui.cbLabelsFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), 0198 this, &AxisDock::labelsFormatChanged); 0199 connect(ui.sbLabelsPrecision, QOverload<int>::of(&QSpinBox::valueChanged), 0200 this, &AxisDock::labelsPrecisionChanged); 0201 connect(ui.chkLabelsAutoPrecision, &QCheckBox::stateChanged, this, &AxisDock::labelsAutoPrecisionChanged); 0202 connect(ui.cbLabelsDateTimeFormat, QOverload<int>::of(&QComboBox::currentIndexChanged), 0203 this, &AxisDock::labelsDateTimeFormatChanged); 0204 connect(ui.cbLabelsPosition, QOverload<int>::of(&QComboBox::currentIndexChanged), 0205 this, &AxisDock::labelsPositionChanged); 0206 connect(ui.sbLabelsOffset, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0207 this, &AxisDock::labelsOffsetChanged); 0208 connect(ui.sbLabelsRotation, QOverload<int>::of(&QSpinBox::valueChanged), 0209 this, &AxisDock::labelsRotationChanged); 0210 connect(ui.kfrLabelsFont, &KFontRequester::fontSelected, this, &AxisDock::labelsFontChanged); 0211 connect(ui.kcbLabelsFontColor, &KColorButton::changed, this, &AxisDock::labelsFontColorChanged); 0212 connect(ui.cbLabelsBackgroundType, QOverload<int>::of(&QComboBox::currentIndexChanged), 0213 this, &AxisDock::labelsBackgroundTypeChanged); 0214 connect(ui.kcbLabelsBackgroundColor, &KColorButton::changed, this, &AxisDock::labelsBackgroundColorChanged); 0215 connect(ui.leLabelsPrefix, &QLineEdit::textChanged, this, &AxisDock::labelsPrefixChanged); 0216 connect(ui.leLabelsSuffix, &QLineEdit::textChanged, this, &AxisDock::labelsSuffixChanged); 0217 connect(ui.sbLabelsOpacity, QOverload<int>::of(&QSpinBox::valueChanged), 0218 this, &AxisDock::labelsOpacityChanged); 0219 0220 //"Grid"-tab 0221 connect(ui.cbMajorGridStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), 0222 this, &AxisDock::majorGridStyleChanged); 0223 connect(ui.kcbMajorGridColor, &KColorButton::changed, this, &AxisDock::majorGridColorChanged); 0224 connect(ui.sbMajorGridWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0225 this, &AxisDock::majorGridWidthChanged); 0226 connect(ui.sbMajorGridOpacity, QOverload<int>::of(&QSpinBox::valueChanged), 0227 this, &AxisDock::majorGridOpacityChanged); 0228 0229 connect(ui.cbMinorGridStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), 0230 this, &AxisDock::minorGridStyleChanged); 0231 connect(ui.kcbMinorGridColor, &KColorButton::changed, this, &AxisDock::minorGridColorChanged); 0232 connect(ui.sbMinorGridWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0233 this, &AxisDock::minorGridWidthChanged); 0234 connect(ui.sbMinorGridOpacity, QOverload<int>::of(&QSpinBox::valueChanged), 0235 this, &AxisDock::minorGridOpacityChanged); 0236 0237 //template handler 0238 auto* frame = new QFrame(this); 0239 auto* hlayout = new QHBoxLayout(frame); 0240 hlayout->setContentsMargins(0, 11, 0, 11); 0241 0242 auto* templateHandler = new TemplateHandler(this, TemplateHandler::ClassName::Axis); 0243 hlayout->addWidget(templateHandler); 0244 connect(templateHandler, &TemplateHandler::loadConfigRequested, this, &AxisDock::loadConfigFromTemplate); 0245 connect(templateHandler, &TemplateHandler::saveConfigRequested, this, &AxisDock::saveConfigAsTemplate); 0246 connect(templateHandler, &TemplateHandler::info, this, &AxisDock::info); 0247 0248 ui.verticalLayout->addWidget(frame); 0249 0250 init(); 0251 } 0252 0253 AxisDock::~AxisDock() { 0254 if (m_aspectTreeModel) 0255 delete m_aspectTreeModel; 0256 } 0257 0258 void AxisDock::init() { 0259 Lock lock(m_initializing); 0260 0261 //Validators 0262 ui.lePosition->setValidator( new QDoubleValidator(ui.lePosition) ); 0263 ui.leStart->setValidator( new QDoubleValidator(ui.leStart) ); 0264 ui.leEnd->setValidator( new QDoubleValidator(ui.leEnd) ); 0265 ui.leZeroOffset->setValidator( new QDoubleValidator(ui.leZeroOffset) ); 0266 ui.leScalingFactor->setValidator( new QDoubleValidator(ui.leScalingFactor) ); 0267 0268 //TODO move this stuff to retranslateUI() 0269 ui.cbPosition->addItem(i18n("Top")); 0270 ui.cbPosition->addItem(i18n("Bottom")); 0271 ui.cbPosition->addItem(i18n("Centered")); 0272 ui.cbPosition->addItem(i18n("Custom")); 0273 0274 ui.cbScale->addItem( i18n("Linear") ); 0275 ui.cbScale->addItem( QLatin1String("log(x)") ); 0276 ui.cbScale->addItem( QLatin1String("log2(x)") ); 0277 ui.cbScale->addItem( QLatin1String("ln(x)") ); 0278 ui.cbScale->addItem( QLatin1String("sqrt(x)") ); 0279 ui.cbScale->addItem( QLatin1String("x^2") ); 0280 0281 ui.cbOrientation->addItem( i18n("Horizontal") ); 0282 ui.cbOrientation->addItem( i18n("Vertical") ); 0283 0284 //Arrows 0285 ui.cbArrowType->addItem( i18n("No arrow") ); 0286 ui.cbArrowType->addItem( i18n("Simple, Small") ); 0287 ui.cbArrowType->addItem( i18n("Simple, Big") ); 0288 ui.cbArrowType->addItem( i18n("Filled, Small") ); 0289 ui.cbArrowType->addItem( i18n("Filled, Big") ); 0290 ui.cbArrowType->addItem( i18n("Semi-filled, Small") ); 0291 ui.cbArrowType->addItem( i18n("Semi-filled, Big") ); 0292 0293 QPainter pa; 0294 pa.setPen( QPen(Qt::SolidPattern, 0) ); 0295 QPixmap pm(20, 20); 0296 ui.cbArrowType->setIconSize( QSize(20,20) ); 0297 0298 //no arrow 0299 pm.fill(Qt::transparent); 0300 pa.begin( &pm ); 0301 pa.setRenderHint(QPainter::Antialiasing); 0302 pa.setBrush(Qt::SolidPattern); 0303 pa.drawLine(3, 10, 17, 10); 0304 pa.end(); 0305 ui.cbArrowType->setItemIcon(0, pm); 0306 0307 //simple, small 0308 double cos_phi = cos(M_PI/6.); 0309 pm.fill(Qt::transparent); 0310 pa.begin( &pm ); 0311 pa.setRenderHint(QPainter::Antialiasing); 0312 pa.drawLine(3, 10, 17, 10); 0313 pa.drawLine(17,10, 10, 10-5*cos_phi); 0314 pa.drawLine(17,10, 10, 10+5*cos_phi); 0315 pa.end(); 0316 ui.cbArrowType->setItemIcon(1, pm); 0317 0318 //simple, big 0319 pm.fill(Qt::transparent); 0320 pa.begin( &pm ); 0321 pa.setRenderHint(QPainter::Antialiasing); 0322 pa.drawLine(3, 10, 17, 10); 0323 pa.drawLine(17,10, 10, 10-10*cos_phi); 0324 pa.drawLine(17,10, 10, 10+10*cos_phi); 0325 pa.end(); 0326 ui.cbArrowType->setItemIcon(2, pm); 0327 0328 //filled, small 0329 pm.fill(Qt::transparent); 0330 pa.begin( &pm ); 0331 pa.setRenderHint(QPainter::Antialiasing); 0332 pa.setBrush(Qt::SolidPattern); 0333 pa.drawLine(3, 10, 17, 10); 0334 //TODO: use QPolygon? 0335 QPointF points3[3] = { QPointF(17, 10), QPointF(10, 10-4*cos_phi), QPointF(10, 10+4*cos_phi) }; 0336 pa.drawPolygon(points3, 3); 0337 pa.end(); 0338 ui.cbArrowType->setItemIcon(3, pm); 0339 0340 //filled, big 0341 pm.fill(Qt::transparent); 0342 pa.begin( &pm ); 0343 pa.setRenderHint(QPainter::Antialiasing); 0344 pa.setBrush(Qt::SolidPattern); 0345 pa.drawLine(3, 10, 17, 10); 0346 QPointF points4[3] = { QPointF(17, 10), QPointF(10, 10-10*cos_phi), QPointF(10, 10+10*cos_phi) }; 0347 pa.drawPolygon(points4, 3); 0348 pa.end(); 0349 ui.cbArrowType->setItemIcon(4, pm); 0350 0351 //semi-filled, small 0352 pm.fill(Qt::transparent); 0353 pa.begin( &pm ); 0354 pa.setRenderHint(QPainter::Antialiasing); 0355 pa.setBrush(Qt::SolidPattern); 0356 pa.drawLine(3, 10, 17, 10); 0357 QPointF points5[4] = { QPointF(17, 10), QPointF(10, 10-4*cos_phi), QPointF(13, 10), QPointF(10, 10+4*cos_phi) }; 0358 pa.drawPolygon(points5, 4); 0359 pa.end(); 0360 ui.cbArrowType->setItemIcon(5, pm); 0361 0362 //semi-filled, big 0363 pm.fill(Qt::transparent); 0364 pa.begin( &pm ); 0365 pa.setRenderHint(QPainter::Antialiasing); 0366 pa.setBrush(Qt::SolidPattern); 0367 pa.drawLine(3, 10, 17, 10); 0368 QPointF points6[4] = { QPointF(17, 10), QPointF(10, 10-10*cos_phi), QPointF(13, 10), QPointF(10, 10+10*cos_phi) }; 0369 pa.drawPolygon(points6, 4); 0370 pa.end(); 0371 ui.cbArrowType->setItemIcon(6, pm); 0372 0373 ui.cbArrowPosition->addItem( i18n("Left") ); 0374 ui.cbArrowPosition->addItem( i18n("Right") ); 0375 ui.cbArrowPosition->addItem( i18n("Both") ); 0376 0377 ui.cbMajorTicksDirection->addItem( i18n("None") ); 0378 ui.cbMajorTicksDirection->addItem( i18n("In") ); 0379 ui.cbMajorTicksDirection->addItem( i18n("Out") ); 0380 ui.cbMajorTicksDirection->addItem( i18n("In and Out") ); 0381 0382 ui.cbMajorTicksType->addItem( i18n("Number") ); 0383 ui.cbMajorTicksType->addItem( i18n("Spacing") ); 0384 ui.cbMajorTicksType->addItem( i18n("Custom column") ); 0385 0386 ui.cbMinorTicksDirection->addItem( i18n("None") ); 0387 ui.cbMinorTicksDirection->addItem( i18n("In") ); 0388 ui.cbMinorTicksDirection->addItem( i18n("Out") ); 0389 ui.cbMinorTicksDirection->addItem( i18n("In and Out") ); 0390 0391 ui.cbMinorTicksType->addItem( i18n("Number") ); 0392 ui.cbMinorTicksType->addItem( i18n("Spacing") ); 0393 ui.cbMinorTicksType->addItem( i18n("Custom column") ); 0394 0395 GuiTools::updatePenStyles(ui.cbLineStyle, QColor(Qt::black)); 0396 GuiTools::updatePenStyles(ui.cbMajorTicksLineStyle, QColor(Qt::black)); 0397 GuiTools::updatePenStyles(ui.cbMinorTicksLineStyle, QColor(Qt::black)); 0398 GuiTools::updatePenStyles(ui.cbMajorGridStyle, QColor(Qt::black)); 0399 GuiTools::updatePenStyles(ui.cbMinorGridStyle, QColor(Qt::black)); 0400 0401 //labels 0402 ui.cbLabelsPosition->addItem(i18n("No labels")); 0403 ui.cbLabelsPosition->addItem(i18n("Top")); 0404 ui.cbLabelsPosition->addItem(i18n("Bottom")); 0405 0406 ui.cbLabelsFormat->addItem( i18n("Decimal notation") ); 0407 ui.cbLabelsFormat->addItem( i18n("Scientific notation") ); 0408 ui.cbLabelsFormat->addItem( i18n("Powers of 10") ); 0409 ui.cbLabelsFormat->addItem( i18n("Powers of 2") ); 0410 ui.cbLabelsFormat->addItem( i18n("Powers of e") ); 0411 ui.cbLabelsFormat->addItem( i18n("Multiples of π") ); 0412 0413 ui.cbLabelsDateTimeFormat->addItems(AbstractColumn::dateTimeFormats()); 0414 0415 ui.cbLabelsBackgroundType->addItem(i18n("Transparent")); 0416 ui.cbLabelsBackgroundType->addItem(i18n("Color")); 0417 } 0418 0419 void AxisDock::setModel() { 0420 QList<AspectType> list{AspectType::Folder, AspectType::Workbook, AspectType::Spreadsheet, AspectType::Column}; 0421 cbMajorTicksColumn->setTopLevelClasses(list); 0422 cbMinorTicksColumn->setTopLevelClasses(list); 0423 0424 list = {AspectType::Column}; 0425 m_aspectTreeModel->setSelectableAspects(list); 0426 0427 cbMajorTicksColumn->setModel(m_aspectTreeModel); 0428 cbMinorTicksColumn->setModel(m_aspectTreeModel); 0429 } 0430 0431 /*! 0432 sets the axes. The properties of the axes in the list \c list can be edited in this widget. 0433 */ 0434 void AxisDock::setAxes(QList<Axis*> list) { 0435 Lock lock(m_initializing); 0436 m_axesList = list; 0437 m_axis = list.first(); 0438 m_aspect = list.first(); 0439 Q_ASSERT(m_axis != nullptr); 0440 m_aspectTreeModel = new AspectTreeModel(m_axis->project()); 0441 this->setModel(); 0442 0443 labelWidget->setAxes(list); 0444 0445 //if there are more then one axis in the list, disable the tab "general" 0446 if (list.size() == 1) { 0447 ui.lName->setEnabled(true); 0448 ui.leName->setEnabled(true); 0449 ui.lComment->setEnabled(true); 0450 ui.leComment->setEnabled(true); 0451 ui.leName->setText(m_axis->name()); 0452 ui.leComment->setText(m_axis->comment()); 0453 this->setModelIndexFromColumn(cbMajorTicksColumn, m_axis->majorTicksColumn()); 0454 this->setModelIndexFromColumn(cbMinorTicksColumn, m_axis->minorTicksColumn()); 0455 } else { 0456 ui.lName->setEnabled(false); 0457 ui.leName->setEnabled(false); 0458 ui.lComment->setEnabled(false); 0459 ui.leComment->setEnabled(false); 0460 ui.leName->setText(QString()); 0461 ui.leComment->setText(QString()); 0462 cbMajorTicksColumn->setCurrentModelIndex(QModelIndex()); 0463 cbMinorTicksColumn->setCurrentModelIndex(QModelIndex()); 0464 } 0465 ui.leName->setStyleSheet(""); 0466 ui.leName->setToolTip(""); 0467 0468 //show the properties of the first axis 0469 this->load(); 0470 0471 // general 0472 connect(m_axis, &Axis::aspectDescriptionChanged, this, &AxisDock::axisDescriptionChanged); 0473 connect(m_axis, &Axis::orientationChanged, this, QOverload<Axis::Orientation>::of(&AxisDock::axisOrientationChanged)); 0474 connect(m_axis, QOverload<Axis::Position>::of(&Axis::positionChanged), 0475 this, QOverload<Axis::Position>::of(&AxisDock::axisPositionChanged)); 0476 connect(m_axis, &Axis::scaleChanged, this, &AxisDock::axisScaleChanged); 0477 connect(m_axis, &Axis::autoScaleChanged, this, &AxisDock::axisAutoScaleChanged); 0478 connect(m_axis, &Axis::startChanged, this, &AxisDock::axisStartChanged); 0479 connect(m_axis, &Axis::endChanged, this, &AxisDock::axisEndChanged); 0480 connect(m_axis, &Axis::zeroOffsetChanged, this, &AxisDock::axisZeroOffsetChanged); 0481 connect(m_axis, &Axis::scalingFactorChanged, this, &AxisDock::axisScalingFactorChanged); 0482 0483 // line 0484 connect(m_axis, &Axis::linePenChanged, this, &AxisDock::axisLinePenChanged); 0485 connect(m_axis, &Axis::lineOpacityChanged, this, &AxisDock::axisLineOpacityChanged); 0486 connect(m_axis, &Axis::arrowTypeChanged, this, &AxisDock::axisArrowTypeChanged); 0487 connect(m_axis, &Axis::arrowPositionChanged, this, &AxisDock::axisArrowPositionChanged); 0488 connect(m_axis, &Axis::arrowSizeChanged, this, &AxisDock::axisArrowSizeChanged); 0489 0490 // ticks 0491 connect(m_axis, &Axis::majorTicksDirectionChanged, this, &AxisDock::axisMajorTicksDirectionChanged); 0492 connect(m_axis, &Axis::majorTicksTypeChanged, this, &AxisDock::axisMajorTicksTypeChanged); 0493 connect(m_axis, &Axis::majorTicksNumberChanged, this, &AxisDock::axisMajorTicksNumberChanged); 0494 connect(m_axis, &Axis::majorTicksSpacingChanged, this, &AxisDock::axisMajorTicksSpacingChanged); 0495 connect(m_axis, &Axis::majorTicksPenChanged, this, &AxisDock::axisMajorTicksPenChanged); 0496 connect(m_axis, &Axis::majorTicksLengthChanged, this, &AxisDock::axisMajorTicksLengthChanged); 0497 connect(m_axis, &Axis::majorTicksOpacityChanged, this, &AxisDock::axisMajorTicksOpacityChanged); 0498 connect(m_axis, &Axis::minorTicksDirectionChanged, this, &AxisDock::axisMinorTicksDirectionChanged); 0499 connect(m_axis, &Axis::minorTicksTypeChanged, this, &AxisDock::axisMinorTicksTypeChanged); 0500 connect(m_axis, &Axis::minorTicksNumberChanged, this, &AxisDock::axisMinorTicksNumberChanged); 0501 connect(m_axis, &Axis::minorTicksIncrementChanged, this, &AxisDock::axisMinorTicksSpacingChanged); 0502 connect(m_axis, &Axis::minorTicksPenChanged, this, &AxisDock::axisMinorTicksPenChanged); 0503 connect(m_axis, &Axis::minorTicksLengthChanged, this, &AxisDock::axisMinorTicksLengthChanged); 0504 connect(m_axis, &Axis::minorTicksOpacityChanged, this, &AxisDock::axisMinorTicksOpacityChanged); 0505 0506 // labels 0507 connect(m_axis, &Axis::labelsFormatChanged, this, &AxisDock::axisLabelsFormatChanged); 0508 connect(m_axis, &Axis::labelsAutoPrecisionChanged, this, &AxisDock::axisLabelsAutoPrecisionChanged); 0509 connect(m_axis, &Axis::labelsPrecisionChanged, this, &AxisDock::axisLabelsPrecisionChanged); 0510 connect(m_axis, &Axis::labelsDateTimeFormatChanged, this, &AxisDock::axisLabelsDateTimeFormatChanged); 0511 connect(m_axis, &Axis::labelsPositionChanged, this, &AxisDock::axisLabelsPositionChanged); 0512 connect(m_axis, &Axis::labelsOffsetChanged, this, &AxisDock::axisLabelsOffsetChanged); 0513 connect(m_axis, &Axis::labelsRotationAngleChanged, this, &AxisDock::axisLabelsRotationAngleChanged); 0514 connect(m_axis, &Axis::labelsFontChanged, this, &AxisDock::axisLabelsFontChanged); 0515 connect(m_axis, &Axis::labelsColorChanged, this, &AxisDock::axisLabelsFontColorChanged); 0516 connect(m_axis, &Axis::labelsBackgroundTypeChanged, this, &AxisDock::axisLabelsBackgroundTypeChanged); 0517 connect(m_axis, &Axis::labelsBackgroundColorChanged, this, &AxisDock::axisLabelsBackgroundColorChanged); 0518 connect(m_axis, &Axis::labelsPrefixChanged, this, &AxisDock::axisLabelsPrefixChanged); 0519 connect(m_axis, &Axis::labelsSuffixChanged, this, &AxisDock::axisLabelsSuffixChanged); 0520 connect(m_axis, &Axis::labelsOpacityChanged, this, &AxisDock::axisLabelsOpacityChanged); 0521 0522 // grids 0523 connect(m_axis, &Axis::majorGridPenChanged, this, &AxisDock::axisMajorGridPenChanged); 0524 connect(m_axis, &Axis::majorGridOpacityChanged, this, &AxisDock::axisMajorGridOpacityChanged); 0525 connect(m_axis, &Axis::minorGridPenChanged, this, &AxisDock::axisMinorGridPenChanged); 0526 connect(m_axis, &Axis::minorGridOpacityChanged, this, &AxisDock::axisMinorGridOpacityChanged); 0527 0528 connect(m_axis, &Axis::visibilityChanged, this, &AxisDock::axisVisibilityChanged); 0529 } 0530 0531 /* 0532 * updates the locale in the widgets. called when the application settins are changed. 0533 */ 0534 void AxisDock::updateLocale() { 0535 SET_NUMBER_LOCALE 0536 ui.sbLineWidth->setLocale(numberLocale); 0537 ui.sbMajorTicksSpacingNumeric->setLocale(numberLocale); 0538 ui.sbMajorTicksWidth->setLocale(numberLocale); 0539 ui.sbMajorTicksLength->setLocale(numberLocale); 0540 ui.sbMinorTicksSpacingNumeric->setLocale(numberLocale); 0541 ui.sbMinorTicksWidth->setLocale(numberLocale); 0542 ui.sbMinorTicksLength->setLocale(numberLocale); 0543 ui.sbLabelsOffset->setLocale(numberLocale); 0544 ui.sbMajorGridWidth->setLocale(numberLocale); 0545 ui.sbMinorGridWidth->setLocale(numberLocale); 0546 0547 //update the QLineEdits, avoid the change events 0548 Lock lock(m_initializing); 0549 ui.lePosition->setText(numberLocale.toString(m_axis->offset())); 0550 ui.leStart->setText(numberLocale.toString(m_axis->start())); 0551 ui.leEnd->setText(numberLocale.toString(m_axis->end())); 0552 0553 //update the title label 0554 labelWidget->updateLocale(); 0555 } 0556 0557 void AxisDock::activateTitleTab() { 0558 ui.tabWidget->setCurrentWidget(ui.tabTitle); 0559 } 0560 0561 void AxisDock::setModelIndexFromColumn(TreeViewComboBox* cb, const AbstractColumn* column) { 0562 if (column) 0563 cb->setCurrentModelIndex(m_aspectTreeModel->modelIndexOfAspect(column)); 0564 else 0565 cb->setCurrentModelIndex(QModelIndex()); 0566 } 0567 0568 //************************************************************* 0569 //********** SLOTs for changes triggered in AxisDock ********** 0570 //************************************************************* 0571 //"General"-tab 0572 void AxisDock::visibilityChanged(bool state) { 0573 if (m_initializing) 0574 return; 0575 0576 for (auto* axis : m_axesList) 0577 axis->setVisible(state); 0578 } 0579 0580 /*! 0581 called if the orientation (horizontal or vertical) of the current axis is changed. 0582 */ 0583 void AxisDock::orientationChanged(int item) { 0584 auto orientation{Axis::Orientation(item)}; 0585 if (orientation == Axis::Orientation::Horizontal) { 0586 ui.cbPosition->setItemText(0, i18n("Top") ); 0587 ui.cbPosition->setItemText(1, i18n("Bottom") ); 0588 ui.cbLabelsPosition->setItemText(1, i18n("Top") ); 0589 ui.cbLabelsPosition->setItemText(2, i18n("Bottom") ); 0590 0591 ui.cbScale->setItemText(1, QLatin1String("log(x)") ); 0592 ui.cbScale->setItemText(2, QLatin1String("log2(x)") ); 0593 ui.cbScale->setItemText(3, QLatin1String("ln(x)") ); 0594 ui.cbScale->setItemText(4, QLatin1String("sqrt(x)") ); 0595 ui.cbScale->setItemText(5, QLatin1String("x^2") ); 0596 } else { //vertical 0597 ui.cbPosition->setItemText(0, i18n("Left") ); 0598 ui.cbPosition->setItemText(1, i18n("Right") ); 0599 ui.cbLabelsPosition->setItemText(1, i18n("Right") ); 0600 ui.cbLabelsPosition->setItemText(2, i18n("Left") ); 0601 0602 ui.cbScale->setItemText(1, QLatin1String("log(y)") ); 0603 ui.cbScale->setItemText(2, QLatin1String("log2(y)") ); 0604 ui.cbScale->setItemText(3, QLatin1String("ln(y)") ); 0605 ui.cbScale->setItemText(4, QLatin1String("sqrt(y)") ); 0606 ui.cbScale->setItemText(5, QLatin1String("y^2") ); 0607 } 0608 0609 if (m_initializing) 0610 return; 0611 0612 //depending on the current orientation we need to update axis position and labels position 0613 0614 //axis position, map from the current index in the combobox to the enum value in Axis::Position 0615 Axis::Position axisPosition; 0616 int posIndex = ui.cbPosition->currentIndex(); 0617 if (orientation == Axis::Orientation::Horizontal) { 0618 if (posIndex > 1) 0619 posIndex += 2; 0620 axisPosition = Axis::Position(posIndex); 0621 } else 0622 axisPosition = Axis::Position(posIndex+2); 0623 0624 //labels position 0625 posIndex = ui.cbLabelsPosition->currentIndex(); 0626 auto labelsPosition = Axis::LabelsPosition(posIndex); 0627 0628 for (auto* axis : m_axesList) { 0629 axis->beginMacro(i18n("%1: set axis orientation", axis->name())); 0630 axis->setOrientation(orientation); 0631 axis->setPosition(axisPosition); 0632 axis->setLabelsPosition(labelsPosition); 0633 axis->endMacro(); 0634 } 0635 } 0636 0637 /*! 0638 called if one of the predefined axis positions 0639 (top, bottom, left, right, center or custom) was changed. 0640 */ 0641 void AxisDock::positionChanged(int index) { 0642 if (index == -1) 0643 return; //we occasionally get -1 here, nothing to do in this case 0644 0645 if (index == 3) 0646 ui.lePosition->setVisible(true); 0647 else 0648 ui.lePosition->setVisible(false); 0649 0650 if (m_initializing) 0651 return; 0652 0653 //map from the current index in the combo box to the enum value in Axis::Position, 0654 //depends on the current orientation 0655 Axis::Position position; 0656 if ( ui.cbOrientation->currentIndex() == 0 ) { 0657 if (index>1) 0658 index += 2; 0659 position = Axis::Position(index); 0660 } else 0661 position = Axis::Position(index+2); 0662 0663 for (auto* axis : m_axesList) 0664 axis->setPosition(position); 0665 } 0666 0667 /*! 0668 called when the custom position of the axis in the corresponding LineEdit is changed. 0669 */ 0670 void AxisDock::positionChanged() { 0671 if (m_initializing) 0672 return; 0673 0674 bool ok; 0675 SET_NUMBER_LOCALE 0676 const double offset{numberLocale.toDouble(ui.lePosition->text(), &ok)}; 0677 if (ok) { 0678 for (auto* axis : m_axesList) 0679 axis->setOffset(offset); 0680 } 0681 } 0682 0683 void AxisDock::scaleChanged(int index) { 0684 if (m_initializing) 0685 return; 0686 0687 auto scale = static_cast<Axis::Scale>(index); 0688 for (auto* axis : m_axesList) 0689 axis->setScale(scale); 0690 } 0691 0692 void AxisDock::autoScaleChanged(int index) { 0693 bool autoScale = index == Qt::Checked; 0694 ui.leStart->setEnabled(!autoScale); 0695 ui.leEnd->setEnabled(!autoScale); 0696 ui.dateTimeEditStart->setEnabled(!autoScale); 0697 ui.dateTimeEditEnd->setEnabled(!autoScale); 0698 0699 if (m_initializing) 0700 return; 0701 0702 for (auto* axis : m_axesList) 0703 axis->setAutoScale(autoScale); 0704 } 0705 0706 void AxisDock::startChanged() { 0707 if (m_initializing) 0708 return; 0709 0710 bool ok; 0711 SET_NUMBER_LOCALE 0712 double value{numberLocale.toDouble(ui.leStart->text(), &ok)}; 0713 if (!ok) 0714 return; 0715 0716 //check first, whether the value for the lower limit is valid for the log- and square root scaling. If not, set the default values. 0717 auto scale = Axis::Scale(ui.cbScale->currentIndex()); 0718 if (scale == Axis::Scale::Log10 || scale == Axis::Scale::Log2 || scale == Axis::Scale::Ln) { 0719 if (value <= 0) { 0720 KMessageBox::sorry(this, 0721 i18n("The axes lower limit has a non-positive value. Default minimal value will be used."), 0722 i18n("Wrong lower limit value") ); 0723 value = 0.01; 0724 ui.leStart->setText(numberLocale.toString(value) ); 0725 } 0726 } else if (scale == Axis::Scale::Sqrt) { 0727 if (value < 0) { 0728 KMessageBox::sorry(this, 0729 i18n("The axes lower limit has a negative value. Default minimal value will be used."), 0730 i18n("Wrong lower limit value") ); 0731 value = 0; 0732 ui.leStart->setText(numberLocale.toString(value) ); 0733 } 0734 } 0735 0736 const Lock lock(m_initializing); 0737 for (auto* axis : m_axesList) 0738 axis->setStart(value); 0739 } 0740 0741 void AxisDock::endChanged() { 0742 if (m_initializing) 0743 return; 0744 0745 bool ok; 0746 SET_NUMBER_LOCALE 0747 const double value{numberLocale.toDouble(ui.leEnd->text(), &ok)}; 0748 if (!ok) 0749 return; 0750 0751 const Lock lock(m_initializing); 0752 for (auto* axis : m_axesList) 0753 axis->setEnd(value); 0754 } 0755 0756 void AxisDock::startDateTimeChanged(const QDateTime& dateTime) { 0757 if (m_initializing) 0758 return; 0759 0760 quint64 value = dateTime.toMSecsSinceEpoch(); 0761 for (auto* axis : m_axesList) 0762 axis->setStart(value); 0763 } 0764 0765 void AxisDock::endDateTimeChanged(const QDateTime& dateTime) { 0766 if (m_initializing) 0767 return; 0768 0769 quint64 value = dateTime.toMSecsSinceEpoch(); 0770 for (auto* axis : m_axesList) 0771 axis->setEnd(value); 0772 } 0773 0774 void AxisDock::zeroOffsetChanged() { 0775 if (m_initializing) 0776 return; 0777 0778 bool ok; 0779 SET_NUMBER_LOCALE 0780 const double offset{numberLocale.toDouble(ui.leZeroOffset->text(), &ok)}; 0781 if (!ok) 0782 return; 0783 0784 const Lock lock(m_initializing); 0785 for (auto* axis : m_axesList) 0786 axis->setZeroOffset(offset); 0787 } 0788 0789 void AxisDock::scalingFactorChanged() { 0790 if (m_initializing) 0791 return; 0792 0793 bool ok; 0794 SET_NUMBER_LOCALE 0795 const double scalingFactor{numberLocale.toDouble(ui.leScalingFactor->text(), &ok)}; 0796 if (!ok) 0797 return; 0798 0799 if (scalingFactor != 0.0) { 0800 const Lock lock(m_initializing); 0801 for (auto* axis : m_axesList) 0802 axis->setScalingFactor(scalingFactor); 0803 } 0804 } 0805 0806 // "Line"-tab 0807 void AxisDock::lineStyleChanged(int index) { 0808 if (index == -1) 0809 return; 0810 0811 auto penStyle = Qt::PenStyle(index); 0812 0813 bool b = (penStyle != Qt::NoPen); 0814 ui.lLineColor->setEnabled(b); 0815 ui.kcbLineColor->setEnabled(b); 0816 ui.lLineWidth->setEnabled(b); 0817 ui.sbLineWidth->setEnabled(b); 0818 ui.lLineOpacity->setEnabled(b); 0819 ui.sbLineOpacity->setEnabled(b); 0820 0821 if (m_initializing) 0822 return; 0823 0824 QPen pen; 0825 for (auto* axis : m_axesList) { 0826 pen = axis->linePen(); 0827 pen.setStyle(penStyle); 0828 axis->setLinePen(pen); 0829 } 0830 } 0831 0832 void AxisDock::lineColorChanged(const QColor& color) { 0833 if (m_initializing) 0834 return; 0835 0836 QPen pen; 0837 for (auto* axis : m_axesList) { 0838 pen = axis->linePen(); 0839 pen.setColor(color); 0840 axis->setLinePen(pen); 0841 } 0842 0843 m_initializing = true; 0844 GuiTools::updatePenStyles(ui.cbLineStyle, color); 0845 m_initializing = false; 0846 } 0847 0848 void AxisDock::lineWidthChanged(double value) { 0849 if (m_initializing) 0850 return; 0851 0852 QPen pen; 0853 for (auto* axis : m_axesList) { 0854 pen = axis->linePen(); 0855 pen.setWidthF(Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point)); 0856 axis->setLinePen(pen); 0857 } 0858 } 0859 0860 void AxisDock::lineOpacityChanged(int value) { 0861 if (m_initializing) 0862 return; 0863 0864 qreal opacity = (double)value/100.; 0865 for (auto* axis : m_axesList) 0866 axis->setLineOpacity(opacity); 0867 } 0868 0869 void AxisDock::arrowTypeChanged(int index) { 0870 auto type = (Axis::ArrowType)index; 0871 if (type == Axis::ArrowType::NoArrow) { 0872 ui.cbArrowPosition->setEnabled(false); 0873 ui.sbArrowSize->setEnabled(false); 0874 } else { 0875 ui.cbArrowPosition->setEnabled(true); 0876 ui.sbArrowSize->setEnabled(true); 0877 } 0878 0879 if (m_initializing) 0880 return; 0881 0882 for (auto* axis : m_axesList) 0883 axis->setArrowType(type); 0884 } 0885 0886 void AxisDock::arrowPositionChanged(int index) { 0887 if (m_initializing) 0888 return; 0889 0890 auto position = (Axis::ArrowPosition)index; 0891 for (auto* axis : m_axesList) 0892 axis->setArrowPosition(position); 0893 } 0894 0895 void AxisDock::arrowSizeChanged(int value) { 0896 if (m_initializing) 0897 return; 0898 0899 double v = Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point); 0900 for (auto* axis : m_axesList) 0901 axis->setArrowSize(v); 0902 } 0903 0904 //"Major ticks" tab 0905 void AxisDock::majorTicksDirectionChanged(int index) { 0906 Axis::TicksDirection direction = Axis::TicksDirection(index); 0907 0908 bool b = (direction != Axis::noTicks); 0909 ui.lMajorTicksType->setEnabled(b); 0910 ui.cbMajorTicksType->setEnabled(b); 0911 ui.lMajorTicksType->setEnabled(b); 0912 ui.cbMajorTicksType->setEnabled(b); 0913 ui.lMajorTicksNumber->setEnabled(b); 0914 ui.sbMajorTicksNumber->setEnabled(b); 0915 ui.lMajorTicksSpacingNumeric->setEnabled(b); 0916 ui.sbMajorTicksSpacingNumeric->setEnabled(b); 0917 ui.lMajorTicksIncrementDateTime->setEnabled(b); 0918 dtsbMajorTicksIncrement->setEnabled(b); 0919 ui.lMajorTicksLineStyle->setEnabled(b); 0920 ui.cbMajorTicksLineStyle->setEnabled(b); 0921 dtsbMinorTicksIncrement->setEnabled(b); 0922 if (b) { 0923 if (ui.cbMajorTicksLineStyle->currentIndex() != -1) { 0924 auto penStyle = Qt::PenStyle(ui.cbMajorTicksLineStyle->currentIndex()); 0925 b = (penStyle != Qt::NoPen); 0926 } else 0927 b = false; 0928 } 0929 ui.lMajorTicksColor->setEnabled(b); 0930 ui.kcbMajorTicksColor->setEnabled(b); 0931 ui.lMajorTicksWidth->setEnabled(b); 0932 ui.sbMajorTicksWidth->setEnabled(b); 0933 ui.lMajorTicksLength->setEnabled(b); 0934 ui.sbMajorTicksLength->setEnabled(b); 0935 ui.lMajorTicksOpacity->setEnabled(b); 0936 ui.sbMajorTicksOpacity->setEnabled(b); 0937 0938 if (m_initializing) 0939 return; 0940 0941 for (auto* axis : m_axesList) 0942 axis->setMajorTicksDirection(direction); 0943 } 0944 0945 /*! 0946 called if the current style of the ticks (Number or Increment) is changed. 0947 Shows/hides the corresponding widgets. 0948 */ 0949 void AxisDock::majorTicksTypeChanged(int index) { 0950 if (!m_axis) // If elements are added to the combobox 'cbMajorTicksType' (at init of this class), then this function is called, which is a problem if no axis are available 0951 return; 0952 0953 auto type = Axis::TicksType(index); 0954 if (type == Axis::TicksType::TotalNumber) { 0955 ui.lMajorTicksNumber->show(); 0956 ui.sbMajorTicksNumber->show(); 0957 ui.lMajorTicksSpacingNumeric->hide(); 0958 ui.sbMajorTicksSpacingNumeric->hide(); 0959 ui.lMajorTicksIncrementDateTime->hide(); 0960 dtsbMajorTicksIncrement->hide(); 0961 ui.lMajorTicksColumn->hide(); 0962 cbMajorTicksColumn->hide(); 0963 } else if (type == Axis::TicksType::Spacing) { 0964 ui.lMajorTicksNumber->hide(); 0965 ui.sbMajorTicksNumber->hide(); 0966 ui.lMajorTicksSpacingNumeric->show(); 0967 0968 const auto* plot = static_cast<const CartesianPlot*>(m_axis->parentAspect()); 0969 bool numeric = ( (m_axis->orientation() == Axis::Orientation::Horizontal && plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric) 0970 || (m_axis->orientation() == Axis::Orientation::Vertical && plot->yRangeFormat() == CartesianPlot::RangeFormat::Numeric) ); 0971 if (numeric) { 0972 ui.lMajorTicksIncrementDateTime->hide(); 0973 dtsbMajorTicksIncrement->hide(); 0974 ui.lMajorTicksSpacingNumeric->show(); 0975 ui.sbMajorTicksSpacingNumeric->show(); 0976 } else { 0977 ui.lMajorTicksIncrementDateTime->show(); 0978 dtsbMajorTicksIncrement->show(); 0979 ui.lMajorTicksSpacingNumeric->hide(); 0980 ui.sbMajorTicksSpacingNumeric->hide(); 0981 } 0982 0983 ui.lMajorTicksColumn->hide(); 0984 cbMajorTicksColumn->hide(); 0985 0986 // Check if spacing is not to small 0987 majorTicksSpacingChanged(); 0988 } else { 0989 ui.lMajorTicksNumber->hide(); 0990 ui.sbMajorTicksNumber->hide(); 0991 ui.lMajorTicksSpacingNumeric->hide(); 0992 ui.sbMajorTicksSpacingNumeric->hide(); 0993 ui.lMajorTicksIncrementDateTime->hide(); 0994 dtsbMajorTicksIncrement->hide(); 0995 ui.lMajorTicksColumn->show(); 0996 cbMajorTicksColumn->show(); 0997 } 0998 0999 if (m_initializing) 1000 return; 1001 1002 for (auto* axis : m_axesList) 1003 axis->setMajorTicksType(type); 1004 } 1005 1006 void AxisDock::majorTicksNumberChanged(int value) { 1007 if (m_initializing) 1008 return; 1009 1010 for (auto* axis : m_axesList) 1011 axis->setMajorTicksNumber(value); 1012 } 1013 1014 void AxisDock::majorTicksSpacingChanged() { 1015 if (m_initializing) 1016 return; 1017 1018 const auto* plot = static_cast<const CartesianPlot*>(m_axis->parentAspect()); 1019 1020 bool numeric = ( (m_axis->orientation() == Axis::Orientation::Horizontal && plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric) 1021 || (m_axis->orientation() == Axis::Orientation::Vertical && plot->yRangeFormat() == CartesianPlot::RangeFormat::Numeric) ); 1022 1023 double spacing = numeric ? ui.sbMajorTicksSpacingNumeric->value() : dtsbMajorTicksIncrement->value(); 1024 double range = fabs(m_axis->end() - m_axis->start()); 1025 DEBUG("major spacing = " << spacing << ", range = " << range) 1026 1027 // fix spacing if incorrect (not set or > 100 ticks) 1028 if (spacing == 0. || range / spacing > 100.) { 1029 if (spacing == 0) 1030 spacing = range / (ui.sbMajorTicksNumber->value() - 1); 1031 1032 if (range / spacing > 100.) 1033 spacing = range / 100.; 1034 1035 DEBUG("new spacing = " << spacing) 1036 // determine stepsize and number of decimals 1037 m_initializing = true; 1038 if (numeric) { 1039 int decimals = nsl_math_rounded_decimals(spacing) + 1; 1040 DEBUG("decimals = " << decimals << ", step = " << gsl_pow_int(10., -decimals)) 1041 ui.sbMajorTicksSpacingNumeric->setDecimals(decimals); 1042 ui.sbMajorTicksSpacingNumeric->setSingleStep(gsl_pow_int(10., -decimals)); 1043 ui.sbMajorTicksSpacingNumeric->setMaximum(range); 1044 ui.sbMajorTicksSpacingNumeric->setValue(spacing); 1045 } else //TODO: check reversed axis 1046 dtsbMajorTicksIncrement->setValue(spacing); 1047 m_initializing = false; 1048 } 1049 1050 for (auto* axis : m_axesList) 1051 axis->setMajorTicksSpacing(spacing); 1052 } 1053 1054 void AxisDock::majorTicksLineStyleChanged(int index) { 1055 if (index == -1) 1056 return; 1057 1058 auto penStyle = Qt::PenStyle(index); 1059 1060 bool b = (penStyle != Qt::NoPen); 1061 ui.lMajorTicksColor->setEnabled(b); 1062 ui.kcbMajorTicksColor->setEnabled(b); 1063 ui.lMajorTicksWidth->setEnabled(b); 1064 ui.sbMajorTicksWidth->setEnabled(b); 1065 ui.lMajorTicksLength->setEnabled(b); 1066 ui.sbMajorTicksLength->setEnabled(b); 1067 ui.lMajorTicksOpacity->setEnabled(b); 1068 ui.sbMajorTicksOpacity->setEnabled(b); 1069 1070 if (m_initializing) 1071 return; 1072 1073 QPen pen; 1074 for (auto* axis : m_axesList) { 1075 pen = axis->majorTicksPen(); 1076 pen.setStyle(penStyle); 1077 axis->setMajorTicksPen(pen); 1078 } 1079 } 1080 1081 void AxisDock::majorTicksColumnChanged(const QModelIndex& index) { 1082 if (m_initializing) 1083 return; 1084 1085 auto* aspect = static_cast<AbstractAspect*>(index.internalPointer()); 1086 AbstractColumn* column = nullptr; 1087 if (aspect) { 1088 column = dynamic_cast<AbstractColumn*>(aspect); 1089 Q_ASSERT(column != nullptr); 1090 } 1091 1092 for (auto* axis : m_axesList) 1093 axis->setMajorTicksColumn(column); 1094 } 1095 1096 void AxisDock::majorTicksColorChanged(const QColor& color) { 1097 if (m_initializing) 1098 return; 1099 1100 QPen pen; 1101 for (auto* axis : m_axesList) { 1102 pen = axis->majorTicksPen(); 1103 pen.setColor(color); 1104 axis->setMajorTicksPen(pen); 1105 } 1106 1107 m_initializing = true; 1108 GuiTools::updatePenStyles(ui.cbMajorTicksLineStyle, color); 1109 m_initializing = false; 1110 } 1111 1112 void AxisDock::majorTicksWidthChanged(double value) { 1113 if (m_initializing) 1114 return; 1115 1116 QPen pen; 1117 for (auto* axis : m_axesList) { 1118 pen = axis->majorTicksPen(); 1119 pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) ); 1120 axis->setMajorTicksPen(pen); 1121 } 1122 } 1123 1124 void AxisDock::majorTicksLengthChanged(double value) { 1125 if (m_initializing) 1126 return; 1127 1128 for (auto* axis : m_axesList) 1129 axis->setMajorTicksLength( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) ); 1130 } 1131 1132 void AxisDock::majorTicksOpacityChanged(int value) { 1133 if (m_initializing) 1134 return; 1135 1136 qreal opacity = (double)value/100.; 1137 for (auto* axis : m_axesList) 1138 axis->setMajorTicksOpacity(opacity); 1139 } 1140 1141 //"Minor ticks" tab 1142 void AxisDock::minorTicksDirectionChanged(int index) { 1143 Axis::TicksDirection direction = Axis::TicksDirection(index); 1144 bool b = (direction != Axis::noTicks); 1145 ui.lMinorTicksType->setEnabled(b); 1146 ui.cbMinorTicksType->setEnabled(b); 1147 ui.lMinorTicksType->setEnabled(b); 1148 ui.cbMinorTicksType->setEnabled(b); 1149 ui.lMinorTicksNumber->setEnabled(b); 1150 ui.sbMinorTicksNumber->setEnabled(b); 1151 ui.lMinorTicksSpacingNumeric->setEnabled(b); 1152 ui.sbMinorTicksSpacingNumeric->setEnabled(b); 1153 ui.lMinorTicksIncrementDateTime->setEnabled(b); 1154 dtsbMinorTicksIncrement->setEnabled(b); 1155 ui.lMinorTicksLineStyle->setEnabled(b); 1156 ui.cbMinorTicksLineStyle->setEnabled(b); 1157 if (b) { 1158 if (ui.cbMinorTicksLineStyle->currentIndex() != -1) { 1159 auto penStyle = Qt::PenStyle(ui.cbMinorTicksLineStyle->currentIndex()); 1160 b = (penStyle != Qt::NoPen); 1161 } else 1162 b = false; 1163 } 1164 ui.lMinorTicksColor->setEnabled(b); 1165 ui.kcbMinorTicksColor->setEnabled(b); 1166 ui.lMinorTicksWidth->setEnabled(b); 1167 ui.sbMinorTicksWidth->setEnabled(b); 1168 ui.lMinorTicksLength->setEnabled(b); 1169 ui.sbMinorTicksLength->setEnabled(b); 1170 ui.lMinorTicksOpacity->setEnabled(b); 1171 ui.sbMinorTicksOpacity->setEnabled(b); 1172 1173 if (m_initializing) 1174 return; 1175 1176 for (auto* axis : m_axesList) 1177 axis->setMinorTicksDirection(direction); 1178 } 1179 1180 void AxisDock::minorTicksTypeChanged(int index) { 1181 if (!m_axis) // If elements are added to the combobox 'cbMajorTicksType' (at init of this class), then this function is called, which is a problem if no axis are available 1182 return; 1183 1184 auto type = Axis::TicksType(index); 1185 if (type == Axis::TicksType::TotalNumber) { 1186 ui.lMinorTicksNumber->show(); 1187 ui.sbMinorTicksNumber->show(); 1188 ui.lMinorTicksSpacingNumeric->hide(); 1189 ui.sbMinorTicksSpacingNumeric->hide(); 1190 ui.lMinorTicksColumn->hide(); 1191 cbMinorTicksColumn->hide(); 1192 ui.lMinorTicksIncrementDateTime->hide(); 1193 dtsbMinorTicksIncrement->hide(); 1194 } else if ( type == Axis::TicksType::Spacing) { 1195 ui.lMinorTicksNumber->hide(); 1196 ui.sbMinorTicksNumber->hide(); 1197 1198 const auto* plot = static_cast<const CartesianPlot*>(m_axis->parentAspect()); 1199 bool numeric = ( (m_axis->orientation() == Axis::Orientation::Horizontal && plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric) 1200 || (m_axis->orientation() == Axis::Orientation::Vertical && plot->yRangeFormat() == CartesianPlot::RangeFormat::Numeric) ); 1201 if (numeric) { 1202 ui.lMinorTicksSpacingNumeric->show(); 1203 ui.sbMinorTicksSpacingNumeric->show(); 1204 ui.lMinorTicksIncrementDateTime->hide(); 1205 dtsbMinorTicksIncrement->hide(); 1206 } else { 1207 ui.lMinorTicksSpacingNumeric->hide(); 1208 ui.sbMinorTicksSpacingNumeric->hide(); 1209 ui.lMinorTicksIncrementDateTime->show(); 1210 dtsbMinorTicksIncrement->show(); 1211 } 1212 1213 ui.lMinorTicksColumn->hide(); 1214 cbMinorTicksColumn->hide(); 1215 1216 // Check if spacing is not to small 1217 minorTicksSpacingChanged(); 1218 } else { 1219 ui.lMinorTicksNumber->hide(); 1220 ui.sbMinorTicksNumber->hide(); 1221 ui.lMinorTicksSpacingNumeric->hide(); 1222 ui.sbMinorTicksSpacingNumeric->hide(); 1223 ui.lMinorTicksIncrementDateTime->hide(); 1224 dtsbMinorTicksIncrement->hide(); 1225 ui.lMinorTicksColumn->show(); 1226 cbMinorTicksColumn->show(); 1227 } 1228 1229 if (m_initializing) 1230 return; 1231 1232 for (auto* axis : m_axesList) 1233 axis->setMinorTicksType(type); 1234 } 1235 1236 void AxisDock::minorTicksNumberChanged(int value) { 1237 if (m_initializing) 1238 return; 1239 1240 for (auto* axis : m_axesList) 1241 axis->setMinorTicksNumber(value); 1242 } 1243 1244 void AxisDock::minorTicksSpacingChanged() { 1245 if (m_initializing) 1246 return; 1247 1248 const auto* plot = static_cast<const CartesianPlot*>(m_axis->parentAspect()); 1249 1250 bool numeric = ( (m_axis->orientation() == Axis::Orientation::Horizontal && plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric) 1251 || (m_axis->orientation() == Axis::Orientation::Vertical && plot->yRangeFormat() == CartesianPlot::RangeFormat::Numeric) ); 1252 1253 double spacing = numeric ? ui.sbMinorTicksSpacingNumeric->value() : dtsbMinorTicksIncrement->value(); 1254 double range = fabs(m_axis->end() - m_axis->start()); 1255 //DEBUG("minor spacing = " << spacing << ", range = " << range) 1256 int numberTicks = 0; 1257 1258 int majorTicks = m_axis->majorTicksNumber(); 1259 if (spacing > 0.) 1260 numberTicks = range / (majorTicks - 1) / spacing - 1; // recalc 1261 //DEBUG(" nticks = " << numberTicks) 1262 1263 // set if unset or > 100. 1264 if (spacing == 0. || numberTicks > 100) { 1265 if (spacing == 0.) 1266 spacing = range / (majorTicks - 1) / (ui.sbMinorTicksNumber->value() + 1); 1267 1268 numberTicks = range / (majorTicks - 1) / spacing - 1; // recalculate number of ticks 1269 1270 if (numberTicks > 100) // maximum 100 minor ticks 1271 spacing = range / (majorTicks - 1) / (100 + 1); 1272 1273 DEBUG("new spacing = " << spacing) 1274 DEBUG("new nticks = " << numberTicks) 1275 // determine stepsize and number of decimals 1276 m_initializing = true; 1277 if (numeric) { 1278 int decimals = nsl_math_rounded_decimals(spacing) + 1; 1279 DEBUG("decimals = " << decimals << ", step = " << gsl_pow_int(10., -decimals)) 1280 ui.sbMinorTicksSpacingNumeric->setDecimals(decimals); 1281 ui.sbMinorTicksSpacingNumeric->setSingleStep(gsl_pow_int(10., -decimals)); 1282 ui.sbMinorTicksSpacingNumeric->setMaximum(range); 1283 ui.sbMinorTicksSpacingNumeric->setValue(spacing); 1284 } else 1285 dtsbMinorTicksIncrement->setValue(spacing); 1286 m_initializing = false; 1287 } 1288 1289 for (auto* axis : m_axesList) 1290 axis->setMinorTicksSpacing(spacing); 1291 } 1292 1293 void AxisDock::minorTicksColumnChanged(const QModelIndex& index) { 1294 if (m_initializing) 1295 return; 1296 1297 auto* aspect = static_cast<AbstractAspect*>(index.internalPointer()); 1298 auto* column = dynamic_cast<AbstractColumn*>(aspect); 1299 Q_ASSERT(column != nullptr); 1300 1301 for (auto* axis : m_axesList) 1302 axis->setMinorTicksColumn(column); 1303 } 1304 1305 void AxisDock::minorTicksLineStyleChanged(int index) { 1306 if (index == -1) 1307 return; 1308 1309 auto penStyle = Qt::PenStyle(index); 1310 1311 bool b = (penStyle != Qt::NoPen); 1312 ui.lMinorTicksColor->setEnabled(b); 1313 ui.kcbMinorTicksColor->setEnabled(b); 1314 ui.lMinorTicksWidth->setEnabled(b); 1315 ui.sbMinorTicksWidth->setEnabled(b); 1316 ui.lMinorTicksLength->setEnabled(b); 1317 ui.sbMinorTicksLength->setEnabled(b); 1318 ui.lMinorTicksOpacity->setEnabled(b); 1319 ui.sbMinorTicksOpacity->setEnabled(b); 1320 1321 if (m_initializing) 1322 return; 1323 1324 QPen pen; 1325 for (auto* axis : m_axesList) { 1326 pen = axis->minorTicksPen(); 1327 pen.setStyle(penStyle); 1328 axis->setMinorTicksPen(pen); 1329 } 1330 } 1331 1332 void AxisDock::minorTicksColorChanged(const QColor& color) { 1333 if (m_initializing) 1334 return; 1335 1336 QPen pen; 1337 for (auto* axis : m_axesList) { 1338 pen = axis->minorTicksPen(); 1339 pen.setColor(color); 1340 axis->setMinorTicksPen(pen); 1341 } 1342 1343 m_initializing = true; 1344 GuiTools::updatePenStyles(ui.cbMinorTicksLineStyle, color); 1345 m_initializing = false; 1346 } 1347 1348 void AxisDock::minorTicksWidthChanged(double value) { 1349 if (m_initializing) 1350 return; 1351 1352 QPen pen; 1353 for (auto* axis : m_axesList) { 1354 pen = axis->minorTicksPen(); 1355 pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) ); 1356 axis->setMinorTicksPen(pen); 1357 } 1358 } 1359 1360 void AxisDock::minorTicksLengthChanged(double value) { 1361 if (m_initializing) 1362 return; 1363 1364 for (auto* axis : m_axesList) 1365 axis->setMinorTicksLength( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) ); 1366 } 1367 1368 void AxisDock::minorTicksOpacityChanged(int value) { 1369 if (m_initializing) 1370 return; 1371 1372 qreal opacity = (double)value/100.; 1373 for (auto* axis : m_axesList) 1374 axis->setMinorTicksOpacity(opacity); 1375 } 1376 1377 //"Tick labels"-tab 1378 void AxisDock::labelsFormatChanged(int index) { 1379 if (m_initializing) 1380 return; 1381 1382 for (auto* axis : m_axesList) 1383 axis->setLabelsFormat(Axis::LabelsFormat(index)); 1384 } 1385 1386 void AxisDock::labelsPrecisionChanged(int value) { 1387 if (m_initializing) 1388 return; 1389 1390 for (auto* axis : m_axesList) 1391 axis->setLabelsPrecision(value); 1392 } 1393 1394 1395 void AxisDock::labelsAutoPrecisionChanged(int state) { 1396 bool checked = (state == Qt::Checked); 1397 ui.sbLabelsPrecision->setEnabled(!checked); 1398 1399 if (m_initializing) 1400 return; 1401 1402 for (auto* axis : m_axesList) 1403 axis->setLabelsAutoPrecision(checked); 1404 } 1405 1406 void AxisDock::labelsDateTimeFormatChanged(int) { 1407 if (m_initializing) 1408 return; 1409 1410 for (auto* axis : m_axesList) 1411 axis->setLabelsDateTimeFormat(ui.cbLabelsDateTimeFormat->currentText()); 1412 } 1413 1414 void AxisDock::labelsPositionChanged(int index) { 1415 auto position = Axis::LabelsPosition(index); 1416 1417 bool b = (position != Axis::LabelsPosition::NoLabels); 1418 ui.lLabelsOffset->setEnabled(b); 1419 ui.sbLabelsOffset->setEnabled(b); 1420 ui.lLabelsRotation->setEnabled(b); 1421 ui.sbLabelsRotation->setEnabled(b); 1422 ui.lLabelsFont->setEnabled(b); 1423 ui.kfrLabelsFont->setEnabled(b); 1424 ui.lLabelsColor->setEnabled(b); 1425 ui.kcbLabelsFontColor->setEnabled(b); 1426 ui.lLabelsPrefix->setEnabled(b); 1427 ui.leLabelsPrefix->setEnabled(b); 1428 ui.lLabelsSuffix->setEnabled(b); 1429 ui.leLabelsSuffix->setEnabled(b); 1430 ui.lLabelsOpacity->setEnabled(b); 1431 ui.sbLabelsOpacity->setEnabled(b); 1432 1433 if (m_initializing) 1434 return; 1435 1436 for (auto* axis : m_axesList) 1437 axis->setLabelsPosition(position); 1438 } 1439 1440 void AxisDock::labelsOffsetChanged(double value) { 1441 if (m_initializing) 1442 return; 1443 1444 for (auto* axis : m_axesList) 1445 axis->setLabelsOffset( Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point) ); 1446 } 1447 1448 void AxisDock::labelsRotationChanged(int value) { 1449 if (m_initializing) 1450 return; 1451 1452 for (auto* axis : m_axesList) 1453 axis->setLabelsRotationAngle(value); 1454 } 1455 1456 void AxisDock::labelsPrefixChanged() { 1457 if (m_initializing) 1458 return; 1459 1460 QString prefix = ui.leLabelsPrefix->text(); 1461 for (auto* axis : m_axesList) 1462 axis->setLabelsPrefix(prefix); 1463 } 1464 1465 void AxisDock::labelsSuffixChanged() { 1466 if (m_initializing) 1467 return; 1468 1469 QString suffix = ui.leLabelsSuffix->text(); 1470 for (auto* axis : m_axesList) 1471 axis->setLabelsSuffix(suffix); 1472 } 1473 1474 void AxisDock::labelsFontChanged(const QFont& font) { 1475 if (m_initializing) 1476 return; 1477 1478 QFont labelsFont = font; 1479 labelsFont.setPixelSize( Worksheet::convertToSceneUnits(font.pointSizeF(), Worksheet::Unit::Point) ); 1480 for (auto* axis : m_axesList) 1481 axis->setLabelsFont( labelsFont ); 1482 } 1483 1484 void AxisDock::labelsFontColorChanged(const QColor& color) { 1485 if (m_initializing) 1486 return; 1487 1488 for (auto* axis : m_axesList) 1489 axis->setLabelsColor(color); 1490 } 1491 1492 void AxisDock::labelsBackgroundTypeChanged(int index) { 1493 auto type = Axis::LabelsBackgroundType(index); 1494 1495 bool transparent = (type == Axis::LabelsBackgroundType::Transparent); 1496 ui.lLabelsBackgroundColor->setVisible(!transparent); 1497 ui.kcbLabelsBackgroundColor->setVisible(!transparent); 1498 1499 if (m_initializing) 1500 return; 1501 1502 for (auto* axis : m_axesList) 1503 axis->setLabelsBackgroundType(type); 1504 } 1505 1506 void AxisDock::labelsBackgroundColorChanged(const QColor& color) { 1507 if (m_initializing) 1508 return; 1509 1510 for (auto* axis : m_axesList) 1511 axis->setLabelsBackgroundColor(color); 1512 } 1513 1514 void AxisDock::labelsOpacityChanged(int value) { 1515 if (m_initializing) 1516 return; 1517 1518 qreal opacity = (float)value/100.; 1519 for (auto* axis : m_axesList) 1520 axis->setLabelsOpacity(opacity); 1521 } 1522 1523 // "Grid"-tab 1524 //major grid 1525 void AxisDock::majorGridStyleChanged(int index) { 1526 if (index == -1) 1527 return; 1528 1529 auto penStyle = Qt::PenStyle(index); 1530 1531 bool b = (penStyle != Qt::NoPen); 1532 ui.lMajorGridColor->setEnabled(b); 1533 ui.kcbMajorGridColor->setEnabled(b); 1534 ui.lMajorGridWidth->setEnabled(b); 1535 ui.sbMajorGridWidth->setEnabled(b); 1536 ui.lMajorGridOpacity->setEnabled(b); 1537 ui.sbMajorGridOpacity->setEnabled(b); 1538 1539 if (m_initializing) 1540 return; 1541 1542 QPen pen; 1543 for (auto* axis : m_axesList) { 1544 pen = axis->majorGridPen(); 1545 pen.setStyle(penStyle); 1546 axis->setMajorGridPen(pen); 1547 } 1548 } 1549 1550 void AxisDock::majorGridColorChanged(const QColor& color) { 1551 if (m_initializing) 1552 return; 1553 1554 QPen pen; 1555 for (auto* axis : m_axesList) { 1556 pen = axis->majorGridPen(); 1557 pen.setColor(color); 1558 axis->setMajorGridPen(pen); 1559 } 1560 1561 m_initializing = true; 1562 GuiTools::updatePenStyles(ui.cbMajorGridStyle, color); 1563 m_initializing = false; 1564 } 1565 1566 void AxisDock::majorGridWidthChanged(double value) { 1567 if (m_initializing) 1568 return; 1569 1570 QPen pen; 1571 for (auto* axis : m_axesList) { 1572 pen = axis->majorGridPen(); 1573 pen.setWidthF(Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point)); 1574 axis->setMajorGridPen(pen); 1575 } 1576 } 1577 1578 void AxisDock::majorGridOpacityChanged(int value) { 1579 if (m_initializing) 1580 return; 1581 1582 qreal opacity = (double)value/100.; 1583 for (auto* axis : m_axesList) 1584 axis->setMajorGridOpacity(opacity); 1585 } 1586 1587 //minor grid 1588 void AxisDock::minorGridStyleChanged(int index) { 1589 if (index == -1) 1590 return; 1591 1592 auto penStyle = Qt::PenStyle(index); 1593 1594 bool b = (penStyle != Qt::NoPen); 1595 ui.lMinorGridColor->setEnabled(b); 1596 ui.kcbMinorGridColor->setEnabled(b); 1597 ui.lMinorGridWidth->setEnabled(b); 1598 ui.sbMinorGridWidth->setEnabled(b); 1599 ui.lMinorGridOpacity->setEnabled(b); 1600 ui.sbMinorGridOpacity->setEnabled(b); 1601 1602 if (m_initializing) 1603 return; 1604 1605 QPen pen; 1606 for (auto* axis : m_axesList) { 1607 pen = axis->minorGridPen(); 1608 pen.setStyle(penStyle); 1609 axis->setMinorGridPen(pen); 1610 } 1611 } 1612 1613 void AxisDock::minorGridColorChanged(const QColor& color) { 1614 if (m_initializing) 1615 return; 1616 1617 QPen pen; 1618 for (auto* axis : m_axesList) { 1619 pen = axis->minorGridPen(); 1620 pen.setColor(color); 1621 axis->setMinorGridPen(pen); 1622 } 1623 1624 m_initializing = true; 1625 GuiTools::updatePenStyles(ui.cbMinorGridStyle, color); 1626 m_initializing = false; 1627 } 1628 1629 void AxisDock::minorGridWidthChanged(double value) { 1630 if (m_initializing) 1631 return; 1632 1633 QPen pen; 1634 for (auto* axis : m_axesList) { 1635 pen = axis->minorGridPen(); 1636 pen.setWidthF(Worksheet::convertToSceneUnits(value, Worksheet::Unit::Point)); 1637 axis->setMinorGridPen(pen); 1638 } 1639 } 1640 1641 void AxisDock::minorGridOpacityChanged(int value) { 1642 if (m_initializing) 1643 return; 1644 1645 qreal opacity = (double)value/100.; 1646 for (auto* axis : m_axesList) 1647 axis->setMinorGridOpacity(opacity); 1648 } 1649 1650 //************************************************************* 1651 //************ SLOTs for changes triggered in Axis ************ 1652 //************************************************************* 1653 void AxisDock::axisDescriptionChanged(const AbstractAspect* aspect) { 1654 if (m_axis != aspect) 1655 return; 1656 1657 const Lock lock(m_initializing); 1658 if (aspect->name() != ui.leName->text()) 1659 ui.leName->setText(aspect->name()); 1660 else if (aspect->comment() != ui.leComment->text()) 1661 ui.leComment->setText(aspect->comment()); 1662 } 1663 1664 void AxisDock::axisOrientationChanged(Axis::Orientation orientation) { 1665 m_initializing = true; 1666 ui.cbOrientation->setCurrentIndex(static_cast<int>(orientation)); 1667 m_initializing = false; 1668 } 1669 1670 void AxisDock::axisPositionChanged(Axis::Position position) { 1671 m_initializing = true; 1672 1673 //map from the enum Qt::Orientation to the index in the combo box 1674 int index{static_cast<int>(position)}; 1675 if (index > 1) 1676 ui.cbPosition->setCurrentIndex(index-2); 1677 else 1678 ui.cbPosition->setCurrentIndex(index); 1679 1680 m_initializing = false; 1681 } 1682 1683 void AxisDock::axisPositionChanged(double value) { 1684 m_initializing = true; 1685 SET_NUMBER_LOCALE 1686 ui.lePosition->setText(numberLocale.toString(value)); 1687 m_initializing = false; 1688 } 1689 1690 void AxisDock::axisScaleChanged(Axis::Scale scale) { 1691 m_initializing = true; 1692 ui.cbScale->setCurrentIndex(static_cast<int>(scale)); 1693 m_initializing = false; 1694 } 1695 1696 void AxisDock::axisAutoScaleChanged(bool on) { 1697 m_initializing = true; 1698 ui.chkAutoScale->setChecked(on); 1699 m_initializing = false; 1700 } 1701 1702 void AxisDock::axisStartChanged(double value) { 1703 if (m_initializing) return; 1704 const Lock lock(m_initializing); 1705 1706 SET_NUMBER_LOCALE 1707 ui.leStart->setText(numberLocale.toString(value)); 1708 ui.dateTimeEditStart->setDateTime( QDateTime::fromMSecsSinceEpoch(value) ); 1709 1710 // determine stepsize and number of decimals 1711 double range = std::abs(m_axis->end() - m_axis->start()); 1712 int decimals = nsl_math_rounded_decimals(range) + 1; 1713 DEBUG("range = " << range << ", decimals = " << decimals) 1714 ui.sbMajorTicksSpacingNumeric->setDecimals(decimals); 1715 ui.sbMajorTicksSpacingNumeric->setSingleStep(gsl_pow_int(10., -decimals)); 1716 ui.sbMajorTicksSpacingNumeric->setMaximum(range); 1717 } 1718 1719 void AxisDock::axisEndChanged(double value) { 1720 if (m_initializing) return; 1721 const Lock lock(m_initializing); 1722 1723 SET_NUMBER_LOCALE 1724 ui.leEnd->setText(numberLocale.toString(value)); 1725 ui.dateTimeEditEnd->setDateTime( QDateTime::fromMSecsSinceEpoch(value) ); 1726 1727 // determine stepsize and number of decimals 1728 double range = std::abs(m_axis->end() - m_axis->start()); 1729 int decimals = nsl_math_rounded_decimals(range) + 1; 1730 DEBUG("range = " << range << ", decimals = " << decimals) 1731 ui.sbMajorTicksSpacingNumeric->setDecimals(decimals); 1732 ui.sbMajorTicksSpacingNumeric->setSingleStep(gsl_pow_int(10., -decimals)); 1733 ui.sbMajorTicksSpacingNumeric->setMaximum(range); 1734 } 1735 1736 void AxisDock::axisZeroOffsetChanged(qreal value) { 1737 if (m_initializing) return; 1738 const Lock lock(m_initializing); 1739 SET_NUMBER_LOCALE 1740 ui.leZeroOffset->setText(numberLocale.toString(value)); 1741 } 1742 1743 void AxisDock::axisScalingFactorChanged(qreal value) { 1744 if (m_initializing) return; 1745 const Lock lock(m_initializing); 1746 SET_NUMBER_LOCALE 1747 ui.leScalingFactor->setText(numberLocale.toString(value)); 1748 } 1749 1750 //line 1751 void AxisDock::axisLinePenChanged(const QPen& pen) { 1752 m_initializing = true; 1753 ui.cbLineStyle->setCurrentIndex( pen.style() ); 1754 ui.kcbLineColor->setColor( pen.color() ); 1755 GuiTools::updatePenStyles(ui.cbLineStyle, pen.color() ); 1756 ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point) ); 1757 m_initializing = false; 1758 } 1759 1760 void AxisDock::axisArrowTypeChanged(Axis::ArrowType type) { 1761 m_initializing = true; 1762 ui.cbArrowType->setCurrentIndex((int)type); 1763 m_initializing = false; 1764 } 1765 1766 void AxisDock::axisLineOpacityChanged(qreal opacity) { 1767 m_initializing = true; 1768 ui.sbLineOpacity->setValue( round(opacity*100.0) ); 1769 m_initializing = false; 1770 } 1771 1772 void AxisDock::axisArrowPositionChanged(Axis::ArrowPosition position) { 1773 m_initializing = true; 1774 ui.cbArrowPosition->setCurrentIndex( (int)position ); 1775 m_initializing = false; 1776 } 1777 1778 void AxisDock::axisArrowSizeChanged(qreal size) { 1779 m_initializing = true; 1780 ui.sbArrowSize->setValue( (int)Worksheet::convertFromSceneUnits(size, Worksheet::Unit::Point) ); 1781 m_initializing = false; 1782 } 1783 1784 //major ticks 1785 void AxisDock::axisMajorTicksDirectionChanged(Axis::TicksDirection direction) { 1786 m_initializing = true; 1787 ui.cbMajorTicksDirection->setCurrentIndex(direction); 1788 m_initializing = false; 1789 } 1790 void AxisDock::axisMajorTicksTypeChanged(Axis::TicksType type) { 1791 m_initializing = true; 1792 ui.cbMajorTicksType->setCurrentIndex(static_cast<int>(type)); 1793 m_initializing = false; 1794 } 1795 void AxisDock::axisMajorTicksNumberChanged(int number) { 1796 m_initializing = true; 1797 ui.sbMajorTicksNumber->setValue(number); 1798 m_initializing = false; 1799 } 1800 void AxisDock::axisMajorTicksSpacingChanged(qreal increment) { 1801 m_initializing = true; 1802 const auto* plot = dynamic_cast<const CartesianPlot*>(m_axis->parentAspect()); 1803 if (plot) { 1804 bool numeric = ( (m_axis->orientation() == Axis::Orientation::Horizontal && plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric) 1805 || (m_axis->orientation() == Axis::Orientation::Vertical && plot->yRangeFormat() == CartesianPlot::RangeFormat::Numeric) ); 1806 1807 if (numeric) 1808 ui.sbMajorTicksSpacingNumeric->setValue(increment); 1809 else { 1810 dtsbMajorTicksIncrement->setValue(increment); 1811 } 1812 } 1813 m_initializing = false; 1814 } 1815 void AxisDock::axisMajorTicksPenChanged(const QPen& pen) { 1816 m_initializing = true; 1817 ui.cbMajorTicksLineStyle->setCurrentIndex(pen.style()); 1818 ui.kcbMajorTicksColor->setColor(pen.color()); 1819 ui.sbMajorTicksWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point) ); 1820 m_initializing = false; 1821 } 1822 void AxisDock::axisMajorTicksLengthChanged(qreal length) { 1823 m_initializing = true; 1824 ui.sbMajorTicksLength->setValue( Worksheet::convertFromSceneUnits(length, Worksheet::Unit::Point) ); 1825 m_initializing = false; 1826 } 1827 void AxisDock::axisMajorTicksOpacityChanged(qreal opacity) { 1828 m_initializing = true; 1829 ui.sbMajorTicksOpacity->setValue( round(opacity*100.0)); 1830 m_initializing = false; 1831 } 1832 1833 //minor ticks 1834 void AxisDock::axisMinorTicksDirectionChanged(Axis::TicksDirection direction) { 1835 m_initializing = true; 1836 ui.cbMinorTicksDirection->setCurrentIndex(direction); 1837 m_initializing = false; 1838 } 1839 void AxisDock::axisMinorTicksTypeChanged(Axis::TicksType type) { 1840 m_initializing = true; 1841 ui.cbMinorTicksType->setCurrentIndex(static_cast<int>(type)); 1842 m_initializing = false; 1843 } 1844 void AxisDock::axisMinorTicksNumberChanged(int number) { 1845 m_initializing = true; 1846 ui.sbMinorTicksNumber->setValue(number); 1847 m_initializing = false; 1848 } 1849 void AxisDock::axisMinorTicksSpacingChanged(qreal increment) { 1850 m_initializing = true; 1851 const auto* plot = dynamic_cast<const CartesianPlot*>(m_axis->parentAspect()); 1852 if (plot) { 1853 bool numeric = ( (m_axis->orientation() == Axis::Orientation::Horizontal && plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric) 1854 || (m_axis->orientation() == Axis::Orientation::Vertical && plot->yRangeFormat() == CartesianPlot::RangeFormat::Numeric) ); 1855 1856 if (numeric) 1857 ui.sbMinorTicksSpacingNumeric->setValue(increment); 1858 else { 1859 dtsbMinorTicksIncrement->setValue(increment); 1860 } 1861 } 1862 m_initializing = false; 1863 } 1864 void AxisDock::axisMinorTicksPenChanged(const QPen& pen) { 1865 m_initializing = true; 1866 ui.cbMinorTicksLineStyle->setCurrentIndex(pen.style()); 1867 ui.kcbMinorTicksColor->setColor(pen.color()); 1868 ui.sbMinorTicksWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point) ); 1869 m_initializing = false; 1870 } 1871 void AxisDock::axisMinorTicksLengthChanged(qreal length) { 1872 m_initializing = true; 1873 ui.sbMinorTicksLength->setValue( Worksheet::convertFromSceneUnits(length, Worksheet::Unit::Point) ); 1874 m_initializing = false; 1875 } 1876 void AxisDock::axisMinorTicksOpacityChanged(qreal opacity) { 1877 m_initializing = true; 1878 ui.sbMinorTicksOpacity->setValue(round(opacity*100.0)); 1879 m_initializing = false; 1880 } 1881 1882 //labels 1883 void AxisDock::axisLabelsFormatChanged(Axis::LabelsFormat format) { 1884 m_initializing = true; 1885 ui.cbLabelsFormat->setCurrentIndex(static_cast<int>(format)); 1886 m_initializing = false; 1887 } 1888 void AxisDock::axisLabelsAutoPrecisionChanged(bool on) { 1889 m_initializing = true; 1890 ui.chkLabelsAutoPrecision->setChecked((int) on); 1891 m_initializing = false; 1892 } 1893 void AxisDock::axisLabelsPrecisionChanged(int precision) { 1894 m_initializing = true; 1895 ui.sbLabelsPrecision->setValue(precision); 1896 m_initializing = false; 1897 } 1898 void AxisDock::axisLabelsDateTimeFormatChanged(const QString& format) { 1899 m_initializing = true; 1900 ui.cbLabelsDateTimeFormat->setCurrentText(format); 1901 m_initializing = false; 1902 } 1903 void AxisDock::axisLabelsPositionChanged(Axis::LabelsPosition position) { 1904 m_initializing = true; 1905 ui.cbLabelsPosition->setCurrentIndex(static_cast<int>(position)); 1906 m_initializing = false; 1907 } 1908 void AxisDock::axisLabelsOffsetChanged(double offset) { 1909 m_initializing = true; 1910 ui.sbLabelsOffset->setValue( Worksheet::convertFromSceneUnits(offset, Worksheet::Unit::Point) ); 1911 m_initializing = false; 1912 } 1913 void AxisDock::axisLabelsRotationAngleChanged(qreal rotation) { 1914 m_initializing = true; 1915 ui.sbLabelsRotation->setValue(rotation); 1916 m_initializing = false; 1917 } 1918 void AxisDock::axisLabelsFontChanged(const QFont& font) { 1919 m_initializing = true; 1920 //we need to set the font size in points for KFontRequester 1921 QFont newFont(font); 1922 newFont.setPointSizeF( round(Worksheet::convertFromSceneUnits(font.pixelSize(), Worksheet::Unit::Point)) ); 1923 ui.kfrLabelsFont->setFont(newFont); 1924 m_initializing = false; 1925 } 1926 void AxisDock::axisLabelsFontColorChanged(const QColor& color) { 1927 m_initializing = true; 1928 ui.kcbLabelsFontColor->setColor(color); 1929 m_initializing = false; 1930 } 1931 void AxisDock::axisLabelsBackgroundTypeChanged(Axis::LabelsBackgroundType type) { 1932 m_initializing = true; 1933 ui.cbLabelsBackgroundType->setCurrentIndex(static_cast<int>(type)); 1934 m_initializing = false; 1935 } 1936 void AxisDock::axisLabelsBackgroundColorChanged(const QColor& color) { 1937 m_initializing = true; 1938 ui.kcbLabelsBackgroundColor->setColor(color); 1939 m_initializing = false; 1940 } 1941 void AxisDock::axisLabelsPrefixChanged(const QString& prefix) { 1942 m_initializing = true; 1943 ui.leLabelsPrefix->setText(prefix); 1944 m_initializing = false; 1945 } 1946 void AxisDock::axisLabelsSuffixChanged(const QString& suffix) { 1947 m_initializing = true; 1948 ui.leLabelsSuffix->setText(suffix); 1949 m_initializing = false; 1950 } 1951 void AxisDock::axisLabelsOpacityChanged(qreal opacity) { 1952 m_initializing = true; 1953 ui.sbLabelsOpacity->setValue( round(opacity*100.0) ); 1954 m_initializing = false; 1955 } 1956 1957 //grid 1958 void AxisDock::axisMajorGridPenChanged(const QPen& pen) { 1959 m_initializing = true; 1960 ui.cbMajorGridStyle->setCurrentIndex((int) pen.style()); 1961 ui.kcbMajorGridColor->setColor(pen.color()); 1962 GuiTools::updatePenStyles(ui.cbMajorGridStyle, pen.color()); 1963 ui.sbMajorGridWidth->setValue(Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point)); 1964 m_initializing = false; 1965 } 1966 void AxisDock::axisMajorGridOpacityChanged(qreal opacity) { 1967 m_initializing = true; 1968 ui.sbMajorGridOpacity->setValue( round(opacity*100.0) ); 1969 m_initializing = false; 1970 } 1971 void AxisDock::axisMinorGridPenChanged(const QPen& pen) { 1972 m_initializing = true; 1973 ui.cbMinorGridStyle->setCurrentIndex((int) pen.style()); 1974 ui.kcbMinorGridColor->setColor(pen.color()); 1975 GuiTools::updatePenStyles(ui.cbMinorGridStyle, pen.color()); 1976 ui.sbMinorGridWidth->setValue(Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Unit::Point)); 1977 m_initializing = false; 1978 } 1979 void AxisDock::axisMinorGridOpacityChanged(qreal opacity) { 1980 m_initializing = true; 1981 ui.sbMinorGridOpacity->setValue( round(opacity*100.0) ); 1982 m_initializing = false; 1983 } 1984 1985 void AxisDock::axisVisibilityChanged(bool on) { 1986 m_initializing = true; 1987 ui.chkVisible->setChecked(on); 1988 m_initializing = false; 1989 } 1990 1991 //************************************************************* 1992 //************************* Settings ************************** 1993 //************************************************************* 1994 void AxisDock::load() { 1995 //General 1996 ui.chkVisible->setChecked( m_axis->isVisible() ); 1997 ui.cbOrientation->setCurrentIndex( (int) m_axis->orientation() ); 1998 1999 int index = (int)m_axis->position(); 2000 if (index > 1) 2001 ui.cbPosition->setCurrentIndex(index-2); 2002 else 2003 ui.cbPosition->setCurrentIndex(index); 2004 2005 SET_NUMBER_LOCALE 2006 ui.lePosition->setText( numberLocale.toString(m_axis->offset()) ); 2007 ui.cbScale->setCurrentIndex( (int)m_axis->scale() ); 2008 ui.chkAutoScale->setChecked( m_axis->autoScale() ); 2009 ui.leStart->setText( numberLocale.toString(m_axis->start()) ); 2010 ui.leEnd->setText( numberLocale.toString(m_axis->end()) ); 2011 2012 ui.sbMajorTicksSpacingNumeric->setDecimals(0); 2013 ui.sbMajorTicksSpacingNumeric->setSingleStep(m_axis->majorTicksSpacing()); 2014 2015 //depending on range format of the axis (numeric vs. datetime), show/hide the corresponding widgets 2016 const auto* plot = dynamic_cast<const CartesianPlot*>(m_axis->parentAspect()); 2017 if (plot) { 2018 bool numeric = ( (m_axis->orientation() == Axis::Orientation::Horizontal && plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric) 2019 || (m_axis->orientation() == Axis::Orientation::Vertical && plot->yRangeFormat() == CartesianPlot::RangeFormat::Numeric) ); 2020 //ranges 2021 ui.lStart->setVisible(numeric); 2022 ui.lEnd->setVisible(numeric); 2023 ui.leStart->setVisible(numeric); 2024 ui.leEnd->setVisible(numeric); 2025 ui.lStartDateTime->setVisible(!numeric); 2026 ui.dateTimeEditStart->setVisible(!numeric); 2027 ui.lEndDateTime->setVisible(!numeric); 2028 ui.dateTimeEditEnd->setVisible(!numeric); 2029 2030 //tick labels format 2031 ui.lLabelsFormat->setVisible(numeric); 2032 ui.cbLabelsFormat->setVisible(numeric); 2033 ui.chkLabelsAutoPrecision->setVisible(numeric); 2034 ui.lLabelsPrecision->setVisible(numeric); 2035 ui.sbLabelsPrecision->setVisible(numeric); 2036 ui.cbLabelsDateTimeFormat->setVisible(numeric); 2037 ui.lLabelsDateTimeFormat->setVisible(!numeric); 2038 ui.cbLabelsDateTimeFormat->setVisible(!numeric); 2039 2040 if (!numeric) { 2041 if (m_axis->orientation() == Axis::Orientation::Horizontal) { 2042 ui.dateTimeEditStart->setDisplayFormat(plot->xRangeDateTimeFormat()); 2043 ui.dateTimeEditEnd->setDisplayFormat(plot->xRangeDateTimeFormat()); 2044 } else { 2045 ui.dateTimeEditStart->setDisplayFormat(plot->yRangeDateTimeFormat()); 2046 ui.dateTimeEditEnd->setDisplayFormat(plot->yRangeDateTimeFormat()); 2047 } 2048 ui.dateTimeEditStart->setDateTime(QDateTime::fromMSecsSinceEpoch(m_axis->start())); 2049 ui.dateTimeEditEnd->setDateTime(QDateTime::fromMSecsSinceEpoch(m_axis->end())); 2050 2051 } 2052 } 2053 2054 ui.leZeroOffset->setText( numberLocale.toString(m_axis->zeroOffset()) ); 2055 ui.leScalingFactor->setText( numberLocale.toString(m_axis->scalingFactor()) ); 2056 2057 //Line 2058 ui.cbLineStyle->setCurrentIndex( (int) m_axis->linePen().style() ); 2059 ui.kcbLineColor->setColor( m_axis->linePen().color() ); 2060 ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits(m_axis->linePen().widthF(), Worksheet::Unit::Point) ); 2061 ui.sbLineOpacity->setValue( round(m_axis->lineOpacity()*100.0) ); 2062 ui.cbArrowType->setCurrentIndex( (int)m_axis->arrowType() ); 2063 ui.cbArrowPosition->setCurrentIndex( (int)m_axis->arrowPosition() ); 2064 ui.sbArrowSize->setValue( (int)Worksheet::convertFromSceneUnits(m_axis->arrowSize(), Worksheet::Unit::Point) ); 2065 2066 //Major ticks 2067 ui.cbMajorTicksDirection->setCurrentIndex( (int) m_axis->majorTicksDirection() ); 2068 ui.cbMajorTicksType->setCurrentIndex( (int) m_axis->majorTicksType() ); 2069 ui.sbMajorTicksNumber->setValue( m_axis->majorTicksNumber() ); 2070 ui.cbMajorTicksLineStyle->setCurrentIndex( (int) m_axis->majorTicksPen().style() ); 2071 ui.kcbMajorTicksColor->setColor( m_axis->majorTicksPen().color() ); 2072 ui.sbMajorTicksWidth->setValue( Worksheet::convertFromSceneUnits( m_axis->majorTicksPen().widthF(), Worksheet::Unit::Point) ); 2073 ui.sbMajorTicksLength->setValue( Worksheet::convertFromSceneUnits( m_axis->majorTicksLength(), Worksheet::Unit::Point) ); 2074 ui.sbMajorTicksOpacity->setValue( round(m_axis->majorTicksOpacity()*100.0) ); 2075 2076 //Minor ticks 2077 ui.cbMinorTicksDirection->setCurrentIndex( (int) m_axis->minorTicksDirection() ); 2078 ui.cbMinorTicksType->setCurrentIndex( (int) m_axis->minorTicksType() ); 2079 ui.sbMinorTicksNumber->setValue( m_axis->minorTicksNumber() ); 2080 ui.cbMinorTicksLineStyle->setCurrentIndex( (int) m_axis->minorTicksPen().style() ); 2081 ui.kcbMinorTicksColor->setColor( m_axis->minorTicksPen().color() ); 2082 ui.sbMinorTicksWidth->setValue( Worksheet::convertFromSceneUnits(m_axis->minorTicksPen().widthF(), Worksheet::Unit::Point) ); 2083 ui.sbMinorTicksLength->setValue( Worksheet::convertFromSceneUnits(m_axis->minorTicksLength(), Worksheet::Unit::Point) ); 2084 ui.sbMinorTicksOpacity->setValue( round(m_axis->minorTicksOpacity()*100.0) ); 2085 2086 //Extra ticks 2087 //TODO 2088 2089 // Tick label 2090 ui.cbLabelsPosition->setCurrentIndex( (int) m_axis->labelsPosition() ); 2091 ui.sbLabelsOffset->setValue( Worksheet::convertFromSceneUnits(m_axis->labelsOffset(), Worksheet::Unit::Point) ); 2092 ui.sbLabelsRotation->setValue( m_axis->labelsRotationAngle() ); 2093 ui.cbLabelsFormat->setCurrentIndex( (int) m_axis->labelsFormat() ); 2094 ui.chkLabelsAutoPrecision->setChecked( (int) m_axis->labelsAutoPrecision() ); 2095 ui.sbLabelsPrecision->setValue( (int)m_axis->labelsPrecision() ); 2096 ui.cbLabelsDateTimeFormat->setCurrentText(m_axis->labelsDateTimeFormat()); 2097 //we need to set the font size in points for KFontRequester 2098 QFont font = m_axis->labelsFont(); 2099 font.setPointSizeF( round(Worksheet::convertFromSceneUnits(font.pixelSize(), Worksheet::Unit::Point)) ); 2100 ui.kfrLabelsFont->setFont( font ); 2101 ui.kcbLabelsFontColor->setColor( m_axis->labelsColor() ); 2102 ui.cbLabelsBackgroundType->setCurrentIndex( (int) m_axis->labelsBackgroundType() ); 2103 ui.kcbLabelsBackgroundColor->setColor( m_axis->labelsBackgroundColor() ); 2104 ui.leLabelsPrefix->setText( m_axis->labelsPrefix() ); 2105 ui.leLabelsSuffix->setText( m_axis->labelsSuffix() ); 2106 ui.sbLabelsOpacity->setValue( round(m_axis->labelsOpacity()*100.0) ); 2107 2108 //Grid 2109 ui.cbMajorGridStyle->setCurrentIndex( (int) m_axis->majorGridPen().style() ); 2110 ui.kcbMajorGridColor->setColor( m_axis->majorGridPen().color() ); 2111 ui.sbMajorGridWidth->setValue( Worksheet::convertFromSceneUnits(m_axis->majorGridPen().widthF(), Worksheet::Unit::Point) ); 2112 ui.sbMajorGridOpacity->setValue( round(m_axis->majorGridOpacity()*100.0) ); 2113 2114 ui.cbMinorGridStyle->setCurrentIndex( (int) m_axis->minorGridPen().style() ); 2115 ui.kcbMinorGridColor->setColor( m_axis->minorGridPen().color() ); 2116 ui.sbMinorGridWidth->setValue( Worksheet::convertFromSceneUnits(m_axis->minorGridPen().widthF(), Worksheet::Unit::Point) ); 2117 ui.sbMinorGridOpacity->setValue( round(m_axis->minorGridOpacity()*100.0) ); 2118 2119 GuiTools::updatePenStyles(ui.cbLineStyle, ui.kcbLineColor->color()); 2120 this->majorTicksTypeChanged(ui.cbMajorTicksType->currentIndex()); 2121 GuiTools::updatePenStyles(ui.cbMajorTicksLineStyle, ui.kcbMajorTicksColor->color()); 2122 this->minorTicksTypeChanged(ui.cbMinorTicksType->currentIndex()); 2123 GuiTools::updatePenStyles(ui.cbMinorTicksLineStyle, ui.kcbMinorTicksColor->color()); 2124 GuiTools::updatePenStyles(ui.cbMajorGridStyle, ui.kcbMajorGridColor->color()); 2125 GuiTools::updatePenStyles(ui.cbMinorGridStyle, ui.kcbMinorGridColor->color()); 2126 } 2127 2128 void AxisDock::loadConfigFromTemplate(KConfig& config) { 2129 //extract the name of the template from the file name 2130 QString name; 2131 int index = config.name().lastIndexOf(QLatin1String("/")); 2132 if (index != -1) 2133 name = config.name().right(config.name().size() - index - 1); 2134 else 2135 name = config.name(); 2136 2137 int size = m_axesList.size(); 2138 if (size > 1) 2139 m_axis->beginMacro(i18n("%1 axes: template \"%2\" loaded", size, name)); 2140 else 2141 m_axis->beginMacro(i18n("%1: template \"%2\" loaded", m_axis->name(), name)); 2142 2143 this->loadConfig(config); 2144 2145 m_axis->endMacro(); 2146 } 2147 2148 void AxisDock::loadConfig(KConfig& config) { 2149 KConfigGroup group = config.group( "Axis" ); 2150 2151 bool numeric = false; 2152 const auto* plot = dynamic_cast<const CartesianPlot*>(m_axis->parentAspect()); 2153 if (plot) { 2154 numeric = ( (m_axis->orientation() == Axis::Orientation::Horizontal && plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric) 2155 || (m_axis->orientation() == Axis::Orientation::Vertical && plot->yRangeFormat() == CartesianPlot::RangeFormat::Numeric) ); 2156 } 2157 2158 //General 2159 ui.cbOrientation->setCurrentIndex( group.readEntry("Orientation", (int) m_axis->orientation()) ); 2160 2161 int index = group.readEntry("Position", (int) m_axis->position()); 2162 if (index > 1) 2163 ui.cbPosition->setCurrentIndex(index-2); 2164 else 2165 ui.cbPosition->setCurrentIndex(index); 2166 2167 SET_NUMBER_LOCALE 2168 ui.lePosition->setText( numberLocale.toString(group.readEntry("PositionOffset", m_axis->offset())) ); 2169 ui.cbScale->setCurrentIndex( group.readEntry("Scale", (int) m_axis->scale()) ); 2170 ui.chkAutoScale->setChecked( group.readEntry("AutoScale", m_axis->autoScale()) ); 2171 ui.leStart->setText( numberLocale.toString(group.readEntry("Start", m_axis->start())) ); 2172 ui.leEnd->setText( numberLocale.toString(group.readEntry("End", m_axis->end())) ); 2173 ui.leZeroOffset->setText( numberLocale.toString(group.readEntry("ZeroOffset", m_axis->zeroOffset())) ); 2174 ui.leScalingFactor->setText( numberLocale.toString(group.readEntry("ScalingFactor", m_axis->scalingFactor())) ); 2175 2176 //Title 2177 KConfigGroup axisLabelGroup = config.group("AxisLabel"); 2178 labelWidget->loadConfig(axisLabelGroup); 2179 2180 //Line 2181 ui.cbLineStyle->setCurrentIndex( group.readEntry("LineStyle", (int) m_axis->linePen().style()) ); 2182 ui.kcbLineColor->setColor( group.readEntry("LineColor", m_axis->linePen().color()) ); 2183 ui.sbLineWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("LineWidth", m_axis->linePen().widthF()), Worksheet::Unit::Point) ); 2184 ui.sbLineOpacity->setValue( round(group.readEntry("LineOpacity", m_axis->lineOpacity())*100.0) ); 2185 ui.cbArrowType->setCurrentIndex( group.readEntry("ArrowType", (int) m_axis->arrowType()) ); 2186 ui.cbArrowPosition->setCurrentIndex( group.readEntry("ArrowPosition", (int) m_axis->arrowPosition()) ); 2187 ui.sbArrowSize->setValue( Worksheet::convertFromSceneUnits(group.readEntry("ArrowSize", m_axis->arrowSize()), Worksheet::Unit::Point) ); 2188 2189 //Major ticks 2190 ui.cbMajorTicksDirection->setCurrentIndex( group.readEntry("MajorTicksDirection", (int) m_axis->majorTicksDirection()) ); 2191 ui.cbMajorTicksType->setCurrentIndex( group.readEntry("MajorTicksType", (int) m_axis->majorTicksType()) ); 2192 ui.sbMajorTicksNumber->setValue( group.readEntry("MajorTicksNumber", m_axis->majorTicksNumber()) ); 2193 if (numeric) 2194 ui.sbMajorTicksSpacingNumeric->setValue(group.readEntry("MajorTicksIncrement", m_axis->majorTicksSpacing())); 2195 else 2196 dtsbMajorTicksIncrement->setValue(group.readEntry("MajorTicksIncrement", m_axis->majorTicksSpacing())); 2197 ui.cbMajorTicksLineStyle->setCurrentIndex( group.readEntry("MajorTicksLineStyle", (int) m_axis->majorTicksPen().style()) ); 2198 ui.kcbMajorTicksColor->setColor( group.readEntry("MajorTicksColor", m_axis->majorTicksPen().color()) ); 2199 ui.sbMajorTicksWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("MajorTicksWidth", m_axis->majorTicksPen().widthF()), Worksheet::Unit::Point) ); 2200 ui.sbMajorTicksLength->setValue( Worksheet::convertFromSceneUnits(group.readEntry("MajorTicksLength", m_axis->majorTicksLength()), Worksheet::Unit::Point) ); 2201 ui.sbMajorTicksOpacity->setValue( round(group.readEntry("MajorTicksOpacity", m_axis->majorTicksOpacity())*100.0) ); 2202 2203 //Minor ticks 2204 ui.cbMinorTicksDirection->setCurrentIndex( group.readEntry("MinorTicksDirection", (int) m_axis->minorTicksDirection()) ); 2205 ui.cbMinorTicksType->setCurrentIndex( group.readEntry("MinorTicksType", (int) m_axis->minorTicksType()) ); 2206 ui.sbMinorTicksNumber->setValue( group.readEntry("MinorTicksNumber", m_axis->minorTicksNumber()) ); 2207 if (numeric) 2208 ui.sbMinorTicksSpacingNumeric->setValue(group.readEntry("MinorTicksIncrement", m_axis->minorTicksSpacing())); 2209 else 2210 dtsbMinorTicksIncrement->setValue(group.readEntry("MinorTicksIncrement", m_axis->minorTicksSpacing())); 2211 ui.cbMinorTicksLineStyle->setCurrentIndex( group.readEntry("MinorTicksLineStyle", (int) m_axis->minorTicksPen().style()) ); 2212 ui.kcbMinorTicksColor->setColor( group.readEntry("MinorTicksColor", m_axis->minorTicksPen().color()) ); 2213 ui.sbMinorTicksWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("MinorTicksWidth", m_axis->minorTicksPen().widthF()), Worksheet::Unit::Point) ); 2214 ui.sbMinorTicksLength->setValue( Worksheet::convertFromSceneUnits(group.readEntry("MinorTicksLength", m_axis->minorTicksLength()), Worksheet::Unit::Point) ); 2215 ui.sbMinorTicksOpacity->setValue( round(group.readEntry("MinorTicksOpacity", m_axis->minorTicksOpacity())*100.0) ); 2216 2217 //Extra ticks 2218 //TODO 2219 2220 // Tick label 2221 ui.cbLabelsFormat->setCurrentIndex( group.readEntry("LabelsFormat", (int) m_axis->labelsFormat()) ); 2222 ui.chkLabelsAutoPrecision->setChecked( group.readEntry("LabelsAutoPrecision", (int) m_axis->labelsAutoPrecision()) ); 2223 ui.sbLabelsPrecision->setValue( group.readEntry("LabelsPrecision", (int)m_axis->labelsPrecision()) ); 2224 ui.cbLabelsDateTimeFormat->setCurrentText( group.readEntry("LabelsDateTimeFormat", "yyyy-MM-dd hh:mm:ss") ); 2225 ui.cbLabelsPosition->setCurrentIndex( group.readEntry("LabelsPosition", (int) m_axis->labelsPosition()) ); 2226 ui.sbLabelsOffset->setValue( Worksheet::convertFromSceneUnits(group.readEntry("LabelsOffset", m_axis->labelsOffset()), Worksheet::Unit::Point) ); 2227 ui.sbLabelsRotation->setValue( group.readEntry("LabelsRotation", m_axis->labelsRotationAngle()) ); 2228 //we need to set the font size in points for KFontRequester 2229 QFont font = m_axis->labelsFont(); 2230 font.setPointSizeF( round(Worksheet::convertFromSceneUnits(font.pixelSize(), Worksheet::Unit::Point)) ); 2231 ui.kfrLabelsFont->setFont( group.readEntry("LabelsFont", font) ); 2232 ui.kcbLabelsFontColor->setColor( group.readEntry("LabelsFontColor", m_axis->labelsColor()) ); 2233 ui.cbLabelsBackgroundType->setCurrentIndex( group.readEntry("LabelsBackgroundType", (int) m_axis->labelsBackgroundType()) ); 2234 ui.kcbLabelsBackgroundColor->setColor( group.readEntry("LabelsBackgroundColor", m_axis->labelsBackgroundColor()) ); 2235 ui.leLabelsPrefix->setText( group.readEntry("LabelsPrefix", m_axis->labelsPrefix()) ); 2236 ui.leLabelsSuffix->setText( group.readEntry("LabelsSuffix", m_axis->labelsSuffix()) ); 2237 ui.sbLabelsOpacity->setValue( round(group.readEntry("LabelsOpacity", m_axis->labelsOpacity())*100.0) ); 2238 2239 //Grid 2240 ui.cbMajorGridStyle->setCurrentIndex( group.readEntry("MajorGridStyle", (int) m_axis->majorGridPen().style()) ); 2241 ui.kcbMajorGridColor->setColor( group.readEntry("MajorGridColor", m_axis->majorGridPen().color()) ); 2242 ui.sbMajorGridWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("MajorGridWidth", m_axis->majorGridPen().widthF()), Worksheet::Unit::Point) ); 2243 ui.sbMajorGridOpacity->setValue( round(group.readEntry("MajorGridOpacity", m_axis->majorGridOpacity())*100.0) ); 2244 2245 ui.cbMinorGridStyle->setCurrentIndex( group.readEntry("MinorGridStyle", (int) m_axis->minorGridPen().style()) ); 2246 ui.kcbMinorGridColor->setColor( group.readEntry("MinorGridColor", m_axis->minorGridPen().color()) ); 2247 ui.sbMinorGridWidth->setValue( Worksheet::convertFromSceneUnits(group.readEntry("MinorGridWidth", m_axis->minorGridPen().widthF()), Worksheet::Unit::Point) ); 2248 ui.sbMinorGridOpacity->setValue( round(group.readEntry("MinorGridOpacity", m_axis->minorGridOpacity())*100.0) ); 2249 2250 m_initializing = true; 2251 GuiTools::updatePenStyles(ui.cbLineStyle, ui.kcbLineColor->color()); 2252 this->majorTicksTypeChanged(ui.cbMajorTicksType->currentIndex()); 2253 GuiTools::updatePenStyles(ui.cbMajorTicksLineStyle, ui.kcbMajorTicksColor->color()); 2254 this->minorTicksTypeChanged(ui.cbMinorTicksType->currentIndex()); 2255 GuiTools::updatePenStyles(ui.cbMinorTicksLineStyle, ui.kcbMinorTicksColor->color()); 2256 GuiTools::updatePenStyles(ui.cbMajorGridStyle, ui.kcbMajorGridColor->color()); 2257 GuiTools::updatePenStyles(ui.cbMinorGridStyle, ui.kcbMinorGridColor->color()); 2258 m_initializing = false; 2259 } 2260 2261 void AxisDock::saveConfigAsTemplate(KConfig& config) { 2262 KConfigGroup group = config.group( "Axis" ); 2263 2264 bool numeric = false; 2265 const auto* plot = dynamic_cast<const CartesianPlot*>(m_axis->parentAspect()); 2266 if (plot) { 2267 numeric = ( (m_axis->orientation() == Axis::Orientation::Horizontal && plot->xRangeFormat() == CartesianPlot::RangeFormat::Numeric) 2268 || (m_axis->orientation() == Axis::Orientation::Vertical && plot->yRangeFormat() == CartesianPlot::RangeFormat::Numeric) ); 2269 } 2270 2271 //General 2272 group.writeEntry("Orientation", ui.cbOrientation->currentIndex()); 2273 2274 if (ui.cbPosition->currentIndex() == 2) { 2275 group.writeEntry("Position", static_cast<int>(Axis::Position::Centered)); 2276 } else if (ui.cbPosition->currentIndex() == 3) { 2277 group.writeEntry("Position", static_cast<int>(Axis::Position::Custom)); 2278 } else { 2279 if (ui.cbOrientation->currentIndex() == static_cast<int>(Axis::Orientation::Horizontal)) 2280 group.writeEntry("Position", ui.cbPosition->currentIndex()); 2281 else 2282 group.writeEntry("Position", ui.cbPosition->currentIndex() + 2); 2283 } 2284 2285 SET_NUMBER_LOCALE 2286 group.writeEntry("PositionOffset", numberLocale.toDouble(ui.lePosition->text())); 2287 group.writeEntry("Scale", ui.cbScale->currentIndex()); 2288 group.writeEntry("Start", numberLocale.toDouble(ui.leStart->text())); 2289 group.writeEntry("End", numberLocale.toDouble(ui.leEnd->text())); 2290 group.writeEntry("ZeroOffset", numberLocale.toDouble(ui.leZeroOffset->text())); 2291 group.writeEntry("ScalingFactor", numberLocale.toDouble(ui.leScalingFactor->text())); 2292 2293 //Title 2294 KConfigGroup axisLabelGroup = config.group("AxisLabel"); 2295 labelWidget->saveConfig(axisLabelGroup); 2296 2297 //Line 2298 group.writeEntry("LineStyle", ui.cbLineStyle->currentIndex()); 2299 group.writeEntry("LineColor", ui.kcbLineColor->color()); 2300 group.writeEntry("LineWidth", Worksheet::convertToSceneUnits(ui.sbLineWidth->value(), Worksheet::Unit::Point)); 2301 group.writeEntry("LineOpacity", ui.sbLineOpacity->value()/100.); 2302 2303 //Major ticks 2304 group.writeEntry("MajorTicksDirection", ui.cbMajorTicksDirection->currentIndex()); 2305 group.writeEntry("MajorTicksType", ui.cbMajorTicksType->currentIndex()); 2306 group.writeEntry("MajorTicksNumber", ui.sbMajorTicksNumber->value()); 2307 if (numeric) 2308 group.writeEntry("MajorTicksIncrement", QString::number(ui.sbMajorTicksSpacingNumeric->value())); 2309 else 2310 group.writeEntry("MajorTicksIncrement", QString::number(dtsbMajorTicksIncrement->value())); 2311 group.writeEntry("MajorTicksLineStyle", ui.cbMajorTicksLineStyle->currentIndex()); 2312 group.writeEntry("MajorTicksColor", ui.kcbMajorTicksColor->color()); 2313 group.writeEntry("MajorTicksWidth", Worksheet::convertToSceneUnits(ui.sbMajorTicksWidth->value(), Worksheet::Unit::Point)); 2314 group.writeEntry("MajorTicksLength", Worksheet::convertToSceneUnits(ui.sbMajorTicksLength->value(), Worksheet::Unit::Point)); 2315 group.writeEntry("MajorTicksOpacity", ui.sbMajorTicksOpacity->value()/100.); 2316 2317 //Minor ticks 2318 group.writeEntry("MinorTicksDirection", ui.cbMinorTicksDirection->currentIndex()); 2319 group.writeEntry("MinorTicksType", ui.cbMinorTicksType->currentIndex()); 2320 group.writeEntry("MinorTicksNumber", ui.sbMinorTicksNumber->value()); 2321 if (numeric) 2322 group.writeEntry("MinorTicksIncrement", QString::number(ui.sbMinorTicksSpacingNumeric->value())); 2323 else 2324 group.writeEntry("MinorTicksIncrement", QString::number(dtsbMinorTicksIncrement->value())); 2325 group.writeEntry("MinorTicksLineStyle", ui.cbMinorTicksLineStyle->currentIndex()); 2326 group.writeEntry("MinorTicksColor", ui.kcbMinorTicksColor->color()); 2327 group.writeEntry("MinorTicksWidth", Worksheet::convertFromSceneUnits(ui.sbMinorTicksWidth->value(), Worksheet::Unit::Point)); 2328 group.writeEntry("MinorTicksLength", Worksheet::convertFromSceneUnits(ui.sbMinorTicksLength->value(), Worksheet::Unit::Point)); 2329 group.writeEntry("MinorTicksOpacity", ui.sbMinorTicksOpacity->value()/100.); 2330 2331 //Extra ticks 2332 // TODO 2333 2334 // Tick label 2335 group.writeEntry("LabelsFormat", ui.cbLabelsFormat->currentIndex()); 2336 group.writeEntry("LabelsAutoPrecision", ui.chkLabelsAutoPrecision->isChecked()); 2337 group.writeEntry("LabelsPrecision", ui.sbLabelsPrecision->value()); 2338 group.writeEntry("LabelsPosition", ui.cbLabelsPosition->currentIndex()); 2339 group.writeEntry("LabelsOffset", Worksheet::convertToSceneUnits(ui.sbLabelsOffset->value(), Worksheet::Unit::Point)); 2340 group.writeEntry("LabelsRotation", ui.sbLabelsRotation->value()); 2341 group.writeEntry("LabelsFont", ui.kfrLabelsFont->font()); 2342 group.writeEntry("LabelsFontColor", ui.kcbLabelsFontColor->color()); 2343 group.writeEntry("LabelsBackgroundType", ui.cbLabelsBackgroundType->currentIndex()); 2344 group.writeEntry("LabelsBackgroundColor", ui.kcbLabelsBackgroundColor->color()); 2345 group.writeEntry("LabelsPrefix", ui.leLabelsPrefix->text()); 2346 group.writeEntry("LabelsSuffix", ui.leLabelsSuffix->text()); 2347 group.writeEntry("LabelsOpacity", ui.sbLabelsOpacity->value()/100.); 2348 2349 //Grid 2350 group.writeEntry("MajorGridStyle", ui.cbMajorGridStyle->currentIndex()); 2351 group.writeEntry("MajorGridColor", ui.kcbMajorGridColor->color()); 2352 group.writeEntry("MajorGridWidth", Worksheet::convertToSceneUnits(ui.sbMajorGridWidth->value(), Worksheet::Unit::Point)); 2353 group.writeEntry("MajorGridOpacity", ui.sbMajorGridOpacity->value()/100.); 2354 2355 group.writeEntry("MinorGridStyle", ui.cbMinorGridStyle->currentIndex()); 2356 group.writeEntry("MinorGridColor", ui.kcbMinorGridColor->color()); 2357 group.writeEntry("MinorGridWidth", Worksheet::convertToSceneUnits(ui.sbMinorGridWidth->value(), Worksheet::Unit::Point)); 2358 group.writeEntry("MinorGridOpacity", ui.sbMinorGridOpacity->value()/100.); 2359 config.sync(); 2360 }