1 /* This file is part of the KDE project
2    Copyright (C) 2006 Tomas Mecir <mecirt@gmail.com>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; only
7    version 2 of the License.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public License
15    along with this library; see the file COPYING.LIB.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17    Boston, MA 02110-1301, USA.
18 */
19 
20 
21 #ifndef CALLIGRA_SHEETS_DATA_MANIPULATORS
22 #define CALLIGRA_SHEETS_DATA_MANIPULATORS
23 
24 #include "AbstractRegionCommand.h"
25 #include "Global.h"
26 #include "Style.h"
27 #include "Value.h"
28 
29 #include "sheets_common_export.h"
30 
31 
32 namespace Calligra
33 {
34 namespace Sheets
35 {
36 
37 /**
38  * \ingroup Commands
39  * \brief Abstract command for setting values.
40  */
41 class CALLIGRA_SHEETS_COMMON_EXPORT AbstractDataManipulator : public AbstractRegionCommand
42 {
43 public:
44     explicit AbstractDataManipulator(KUndo2Command *parent = 0);
45     ~AbstractDataManipulator() override;
46 
47     bool process(Element* element) override;
48 
49 protected:
50     /** Return new value. row/col are relative to sheet, not element.
51     If the function sets *parse to true, the value will be treated as an
52     user-entered string and parsed by Cell. */
53     virtual Value newValue(Element *element, int col, int row,
54                            bool *parse, Format::Type *fmtType) = 0;
55 
56     /** do we want to change this cell ? */
wantChange(Element * element,int col,int row)57     virtual bool wantChange(Element *element, int col, int row) {
58         Q_UNUSED(element)
59         Q_UNUSED(col)
60         Q_UNUSED(row)
61         return true;
62     }
63 
64     /**
65      * Starts the undo recording.
66      */
67     bool preProcessing() override;
68 
69     /**
70      * Processes the region. Calls process(Element*).
71      */
72     bool mainProcessing() override;
73 
74     /**
75      * Stops the undo recording and stores the old data.
76      */
77     bool postProcessing() override;
78 };
79 
80 /**
81  * \ingroup Commands
82  * \brief Abstract command for setting values/styles.
83  */
84 class AbstractDFManipulator : public AbstractDataManipulator
85 {
86 public:
87     explicit AbstractDFManipulator(KUndo2Command *parent = 0);
88     ~AbstractDFManipulator() override;
89     bool process(Element* element) override;
90 
91     /** returns whether this manipulator changes formats */
changeFormat()92     bool changeFormat() {
93         return m_changeformat;
94     }
95     /** set whether this manipulator changes formats */
setChangeFormat(bool chf)96     void setChangeFormat(bool chf) {
97         m_changeformat = chf;
98     }
99 protected:
100     /** this method should return new format for a given cell */
101     virtual Style newFormat(Element *element, int col, int row) = 0;
102 
103     bool m_changeformat : 1;
104 };
105 
106 
107 /**
108  * \ingroup Commands
109  * \brief Sets values of a cell range.
110  */
111 class DataManipulator : public AbstractDataManipulator
112 {
113 public:
114     explicit DataManipulator(KUndo2Command *parent = 0);
115     ~DataManipulator() override;
setParsing(bool val)116     void setParsing(bool val) {
117         m_parsing = val;
118     }
setExpandMatrix(bool expand)119     void setExpandMatrix(bool expand) {
120         m_expandMatrix = expand;
121     }
122     /** set the values for the range. Can be either a single value, or
123     a value array */
setValue(Value val)124     void setValue(Value val) {
125         m_data = val;
126     }
127     /** If set, all cells shall be switched to this format. If parsing is
128     true, the resulting value may end up being different. */
setFormat(Format::Type fmtType)129     void setFormat(Format::Type fmtType) {
130         m_format = fmtType;
131     }
132 protected:
133     bool preProcessing() override;
134     bool process(Element* element) override;
135     Value newValue(Element *element, int col, int row, bool *, Format::Type *) override;
136     bool wantChange(Element *element, int col, int row) override;
137 
138     Value m_data;
139     Format::Type m_format;
140     bool m_parsing : 1;
141     bool m_expandMatrix : 1;
142 };
143 
144 
145 /**
146  * \ingroup Commands
147  * \brief Fills a value series into a cell range.
148  */
149 class SeriesManipulator : public AbstractDataManipulator
150 {
151 public:
152     enum Series { Column, Row, Linear, Geometric };
153 
154     SeriesManipulator();
155     ~SeriesManipulator() override;
156 
157     /** Setup the series. This sets the necessary parameters, and also the
158     correct range. */
159     void setupSeries(const QPoint &_marker, double start, double end,
160                      double step, Series mode, Series type);
161 protected:
162     Value newValue(Element *element, int col, int row, bool *,
163                            Format::Type *) override;
164 
165     Series m_type;
166     Value m_start, m_step, m_prev;
167     int m_last;
168 };
169 
170 
171 /**
172  * \ingroup Commands
173  * \brief Fills values into a cell range.
174  */
175 class FillManipulator : public AbstractDFManipulator
176 {
177 public:
178     FillManipulator();
179     ~FillManipulator() override;
180 
181     enum Direction { Up = 0, Down, Left, Right };
182 
setDirection(Direction d)183     void setDirection(Direction d) {
184         m_dir = d;
185     }
186 protected:
187     Value newValue(Element *element, int col, int row,
188                            bool *parse, Format::Type *fmtType) override;
189     Style newFormat(Element *element, int col, int row) override;
190     Direction m_dir;
191 };
192 
193 
194 /**
195  * \ingroup Commands
196  * \brief Converts string values to upper-/lowercase.
197  */
198 class CaseManipulator: public AbstractDataManipulator
199 {
200 public:
201     CaseManipulator();
202     ~CaseManipulator() override;
203 
204     enum CaseMode {
205         Upper = 0,
206         Lower,
207         FirstUpper
208     };
changeMode(CaseMode mode)209     void changeMode(CaseMode mode) {
210         m_mode = mode;
211     }
212     void changeLowerCase();
213     void changeFirstUpper();
214 protected:
215     Value newValue(Element *element, int col, int row,
216                            bool *parse, Format::Type *fmtType) override;
217 
218     /** do we want to change this cell ? */
219     bool wantChange(Element *element, int col, int row) override;
220 
221     CaseMode m_mode;
222 };
223 
224 
225 /**
226  * \ingroup Commands
227  * \brief Inserts/Removes cells by shifting other cells.
228  */
229 class ShiftManipulator : public AbstractRegionCommand
230 {
231 public:
232     enum Direction { ShiftRight, ShiftBottom };
233     explicit ShiftManipulator(KUndo2Command *parent = 0);
234     ~ShiftManipulator() override;
setDirection(Direction direction)235     void setDirection(Direction direction) {
236         m_direction = direction;
237     }
238     void setReverse(bool reverse) override;
239 
240 protected:
241     bool process(Element*) override;
242     bool preProcessing() override;
243     bool mainProcessing() override;
244     bool postProcessing() override;
245 
246 private:
247     Direction m_direction;
248 
249     enum Mode { Insert, Delete };
250     Mode m_mode;
251 };
252 
253 } // namespace Sheets
254 } // namespace Calligra
255 
256 #endif  // CALLIGRA_SHEETS_DATA_MANIPULATORS
257