File indexing completed on 2024-05-12 16:35:25

0001 /* This file is part of the KDE project
0002    Copyright (C) 2002-2004 Ariya Hidayat <ariya@kde.org>
0003              (C) 2002-2003 Norbert Andres <nandres@web.de>
0004              (C) 2002 John Dailey <dailey@vt.edu>
0005              (C) 1999-2002 Laurent Montel <montel@kde.org>
0006              (C) 2001-2002 Philipp Mueller <philipp.mueller@gmx.de>
0007              (C) 2000-2001 Werner Trobin <trobin@kde.org>
0008              (C) 1998-2000 Torben Weis <weis@kde.org>
0009 
0010    This library is free software; you can redistribute it and/or
0011    modify it under the terms of the GNU Library General Public
0012    License as published by the Free Software Foundation; either
0013    version 2 of the License, or (at your option) any later version.
0014 
0015    This library is distributed in the hope that it will be useful,
0016    but WITHOUT ANY WARRANTY; without even the implied warranty of
0017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0018    Library General Public License for more details.
0019 
0020    You should have received a copy of the GNU Library General Public License
0021    along with this library; see the file COPYING.LIB.  If not, write to
0022    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0023    Boston, MA 02110-1301, USA.
0024 */
0025 
0026 
0027 #include "SeriesDialog.h"
0028 
0029 #include "ui/Selection.h"
0030 #include "Sheet.h"
0031 
0032 #include "commands/DataManipulators.h"
0033 
0034 #include <kmessagebox.h>
0035 #include <KLocalizedString>
0036 
0037 #include <QGroupBox>
0038 #include <QHBoxLayout>
0039 #include <QGridLayout>
0040 #include <QLabel>
0041 #include <QRadioButton>
0042 #include <QCheckBox>
0043 #include <QDoubleSpinBox>
0044 
0045 using namespace Calligra::Sheets;
0046 
0047 SeriesDialog::SeriesDialog(QWidget* parent, Selection* selection)
0048         : KoDialog(parent)
0049 {
0050     setCaption(i18n("Series"));
0051     setButtons(Ok | Cancel);
0052     setModal(true);
0053 
0054     m_selection = selection;
0055 
0056     QWidget *page = new QWidget();
0057     setMainWidget(page);
0058 
0059     QVBoxLayout *grid1 = new QVBoxLayout(page);
0060 
0061     QGroupBox* gb1 = new QGroupBox(i18n("Insert Values"), page);
0062     QHBoxLayout *gb1layout = new QHBoxLayout(gb1);
0063     column = new QRadioButton(i18n("Vertical"), gb1);
0064     column->setWhatsThis(i18n("Insert the series vertically, one below the other"));
0065     row = new QRadioButton(i18n("Horizontal"), gb1);
0066     row->setWhatsThis(i18n("Insert the series horizontally, from left to right"));
0067     column->setChecked(true);
0068 
0069     gb1layout->addWidget(column);
0070     gb1layout->addWidget(row);
0071 
0072     QGroupBox* gb2 = new QGroupBox(i18n("Type"), page);
0073     QHBoxLayout *gb2layout = new QHBoxLayout(gb2);
0074     linear = new QRadioButton(i18n("Linear (2,4,6,...)"), gb2);
0075     linear->setWhatsThis(i18n("Generate a series from 'start' to 'end' and for each step add "
0076                               "the value provided in step. This creates a series where each value "
0077                               "is 'step' larger than the value before it."));
0078     geometric = new QRadioButton(i18n("Geometric (2,4,8,...)"), gb2);
0079     geometric->setWhatsThis(i18n("Generate a series from 'start' to 'end' and for each step multiply "
0080                                  "the value with the value provided in step. Using a step of 5 produces a list like: "
0081                                  "5, 25, 125, 625 since 5 multiplied by 5 (step) equals 25, and that multiplied by 5 equals 125, "
0082                                  "which multiplied by the same step-value of 5 equals 625."));
0083     linear->setChecked(true);
0084 
0085     gb2layout->addWidget(linear);
0086     gb2layout->addWidget(geometric);
0087 
0088     QGroupBox* gb = new QGroupBox(i18n("Parameters"), page);
0089     QGridLayout *gb_layout = new QGridLayout(gb);
0090 
0091     QLabel* label = new QLabel(i18n("Start value:"), gb);
0092     gb_layout->addWidget(label, 0, 0);
0093     start = new QDoubleSpinBox(gb);
0094     start->setValue(0.0);
0095     start->setRange(-999999.999, 999999.99);
0096     start->setSingleStep(1.0);
0097     start->setDecimals(3);
0098     gb_layout->addWidget(start, 0, 1);
0099 
0100     label = new QLabel(i18n("Stop value:"), gb);
0101     gb_layout->addWidget(label, 1, 0);
0102     end = new QDoubleSpinBox(gb);
0103     end->setValue(0.0);
0104     end->setRange(-999999.999, 999999.99);
0105     end->setSingleStep(1.0);
0106     end->setDecimals(3);
0107     gb_layout->addWidget(end, 1, 1);
0108 
0109     label = new QLabel(i18n("Step value:"), gb);
0110     gb_layout->addWidget(label, 2, 0);
0111     step = new QDoubleSpinBox(gb);
0112     step->setValue(0.0);
0113     step->setRange(-999999.999, 999999.99);
0114     step->setSingleStep(1.0);
0115     step->setDecimals(3);
0116     gb_layout->addWidget(step, 2, 1);
0117     gb_layout->setColumnStretch(1, 9);
0118 
0119     grid1->addWidget(gb);
0120     grid1->addWidget(gb1);
0121     grid1->addWidget(gb2);
0122 
0123     start->setFocus();
0124 }
0125 
0126 void SeriesDialog::slotButtonClicked(int button)
0127 {
0128     if (button != KoDialog::Ok) {
0129         KoDialog::slotButtonClicked(button);
0130         return;
0131     }
0132 
0133     bool isColumn = column->isChecked();
0134     bool isLinear = linear->isChecked();
0135 
0136     QString tmp;
0137     double dstep, dend, dstart;
0138 
0139     dstart = start->value();
0140     dend = end->value();
0141     dstep = step->value();
0142     if (!isLinear) { // = Geometric
0143         if (dstart < 0.0 || dend < 0.0) {
0144             KMessageBox::error(this, i18n("End and start value must be positive."));
0145             return;
0146         }
0147         if (dstart > dend && dstep >= 1.0) {
0148             KMessageBox::error(this, i18n("End value must be greater than the start "
0149                                           "value or the step must be less than '1'."));
0150             return;
0151         }
0152         if (dstart == 0.0 || dend == 0.0 || dstep == 0.0) {
0153             KMessageBox::error(this, i18n("None of the Start, Stop or Step values "
0154                                           "may be equal to zero."));
0155             return;
0156         }
0157         if (dstep == 1.0) {
0158             KMessageBox::error(this, i18n("Step value must be different from 1"));
0159             return;
0160         }
0161         if (dstep < 0.0) {
0162             KMessageBox::error(this, i18n("Step is negative."));
0163             return;
0164         }
0165     }
0166 
0167     if (isLinear) { // Linear
0168         if (dstep == 0.0) {
0169             KMessageBox::error(this, i18n("The step value must be greater than zero; "
0170                                           "otherwise, the linear series is infinite."));
0171             return;
0172         }
0173         if ((dstep > 0.0) && (dend < dstart)) {
0174             KMessageBox::error(this, i18n("If the start value is greater than the "
0175                                           "end value the step must be less than zero."));
0176             return;
0177         }
0178         if ((dstep < 0.0) && (dstart <= dend)) {
0179             KMessageBox::error(this, i18n("If the step is negative, the start value "
0180                                           "must be greater then the end value."));
0181             return;
0182         }
0183     }
0184 
0185     SeriesManipulator *manipulator = new SeriesManipulator;
0186     manipulator->setSheet(m_selection->activeSheet());
0187     manipulator->setupSeries(m_selection->marker(), dstart, dend, dstep,
0188                              isColumn ? SeriesManipulator::Column : SeriesManipulator::Row,
0189                              isLinear ? SeriesManipulator::Linear : SeriesManipulator::Geometric);
0190 
0191     // setupSeries also called add(), so we can call execute directly
0192     manipulator->execute(m_selection->canvas());
0193 
0194     accept();
0195 }