1 /* This file is part of the KDE project
2    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3    Copyright (C) 2005-2006 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
4 
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public
7    License as published by the Free Software Foundation; either
8    version 2 of the License, or (at your option) any later version.
9 
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14 
15    You should have received a copy of the GNU Library General Public License
16    along with this library; see the file COPYING.LIB.  If not, write to
17    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18    Boston, MA 02110-1301, USA.
19 */
20 
21 #ifndef CALLIGRA_SHEETS_SELECTION
22 #define CALLIGRA_SHEETS_SELECTION
23 
24 #include <QColor>
25 #include <QList>
26 
27 #include <KoToolSelection.h>
28 
29 #include "SheetsDebug.h"
30 
31 #include <sheets/Region.h>
32 
33 #include "sheets_common_export.h"
34 
35 class KoCanvasBase;
36 
37 namespace Calligra
38 {
39 namespace Sheets
40 {
41 
42 /**
43  * \class Selection
44  * \brief Manages the selection of cells.
45  * Represents cell selections for general operations and for cell references
46  * used in formulaes.
47  * \author Torben Weis <weis@kde.org>
48  * \author Stefan Nikolaus <stefan.nikolaus@kdemail.net>
49  */
50 class CALLIGRA_SHEETS_COMMON_EXPORT Selection : public KoToolSelection, public Region
51 {
52     Q_OBJECT
53 
54 public:
55     /**
56      * The selection mode.
57      */
58     // TODO Stefan: merge with RegionSelector::SelectionMode
59     enum Mode {
60         SingleCell = 0,     ///< single cell selection mode
61         MultipleCells = 1   ///< multiple cell selection mode
62     };
63 
64     /**
65      * Constructor.
66      * Creates a new selection with (1,1) as initial location.
67      * @param canvasBase the canvas interface
68      */
69     explicit Selection(KoCanvasBase* canvasBase);
70 
71     /**
72      * Copy Constructor.
73      * Creates a copy of @p selection
74      * @param selection the Selection to copy
75      */
76     Selection(const Selection& selection);
77 
78     /**
79      * Destructor.
80      */
81     ~Selection() override;
82 
83     /**
84      * \return the canvas this selection works for.
85      */
86     KoCanvasBase* canvas() const;
87 
88     /**
89      * Sets the selection to @p point
90      * @param point the point's location
91      * @param sheet the sheet the point belongs to
92      */
93     void initialize(const QPoint& point, Sheet* sheet = 0);
94 
95     /**
96      * Sets the selection to @p range
97      * @param range the range's location
98      * @param sheet the sheet the range belongs to
99      */
100     void initialize(const QRect& range, Sheet* sheet = 0);
101 
102     /**
103      * Sets the selection to @p region
104      * @param region the region's locations
105      * @param sheet the sheet the region belongs to
106      */
107     void initialize(const Region& region, Sheet* sheet = 0);
108 
109     /**
110      * Emits signal changed(const Region&)
111      */
112     void update();
113 
114     /**
115      * Update the marker of the selection to @p point .
116      * Uses the anchor as starting point
117      * @p point the new marker location
118      */
119     void update(const QPoint& point);
120 
121     /**
122      * Extends the current selection with the Point @p point
123      * @param point the point's location
124      * @param sheet the sheet the point belongs to
125      */
126     void extend(const QPoint& point, Sheet* sheet = 0);
127 
128     /**
129      * Extends the current selection with the Range @p range
130      * @param range the range's location
131      * @param sheet the sheet the range belongs to
132      */
133     void extend(const QRect& range, Sheet* sheet = 0);
134 
135     /**
136      * Extends the current selection with the Region @p region
137      * @param region the region's locations
138      */
139     void extend(const Region& region);
140 
141     /**
142      * @param point the point's location
143      * @param sheet the sheet the point belongs to
144      */
145     Element* eor(const QPoint& point, Sheet* sheet = 0) override;
146 
147     /**
148      * The anchor is the starting point of a range. For points marker and anchor are the same
149      */
150     const QPoint& anchor() const;
151 
152     /**
153      * The cursor represents the cursor position. This is needed for merged cells
154      */
155     const QPoint& cursor() const;
156 
157     /**
158      * The marker is the end point of a range. For points marker and anchor are the same
159      */
160     const QPoint& marker() const;
161 
162     /**
163      * Checks whether the region consists only of one point
164      */
165     bool isSingular() const;
166 
167     /**
168      * @return the name of the region (e.g. "A1:A2")
169      */
170     QString name(Sheet* originSheet = 0) const;
171 
172     /**
173      * Sets the selection's active sheet.
174      * For usual selections this is always the origin sheet,
175      * but for cell choices used for formulaes it may differ.
176      * @param sheet the sheet which is currently active
177      */
178     void setActiveSheet(Sheet* sheet);
179 
180     /**
181      * @return the selection's active sheet
182      */
183     Sheet* activeSheet() const;
184 
185     /**
186      * Sets the selection's origin sheet.
187      * @param sheet the sheet from which the selection starts
188      */
189     void setOriginSheet(Sheet* sheet);
190 
191     /**
192      * @return the selection's origin sheet
193      */
194     Sheet* originSheet() const;
195 
196     /**
197      * Activates the cell location/range, that has \p cell as bottom left or
198      * right cell. If more than one occurrence would fit, the first one is taken.
199      * \return the index of the activated range or \c -1, if nothing fits
200      */
201     int setActiveElement(const Cell &cell);
202 
203     /**
204      * @return the active element
205      */
206     Element* activeElement() const;
207 
208     /**
209      * Sets the starting position and the length of a sub-region.
210      * On inserting/updating the selection the sub-region gets replaced
211      * by the new cell location/range.
212      * A \p length of \c 0 results in no replacement, but just in inserting the
213      * new cell location/range before the range index \p start.
214      * \param start The index of a range in this selection. It has to be a valid
215      * index; otherwise the sub-region will be set to the whole region.
216      * \param length The amount of ranges in the sub-region. If it exceeds the
217      * amount of ranges, beginning from \p start to the end of range list, it
218      * will be adjusted.
219      * \param active The active element within the sub-region.
220      * \verbatim start <= active <= start + length \endverbatim
221      */
222     void setActiveSubRegion(int start, int length, int active = -1);
223 
224     /**
225      *
226      */
227     QString activeSubRegionName() const;
228 
229     /**
230      * Clears the elements of the subregion
231      */
232     void clearSubRegion();
233 
234     /**
235      * fix subregion dimensions
236      */
237     void fixSubRegionDimension();
238 
239     /**
240      * Deletes all elements of the region. The result is an empty region.
241      */
242     void clear() override;
243 
244 
245     /**
246      * \param mode single cell or multiple cell selection
247      */
248     void setSelectionMode(Mode mode);
249 
250     /**
251      * Extends \p area to include the merged cells, that are not fully covered,
252      * completely.
253      * \return the extended area
254      */
255     QRect extendToMergedAreas(const QRect& area) const;
256 
257     const QList<QColor>& colors() const;
258 
259     void selectAll();
260 
261     /** Start using a reference selection instead of normal one. */
262     void startReferenceSelection();
263     /** End using reference selection. */
264     void endReferenceSelection(bool saveChanges = true);
265     /** Enable/disable reference choosing mode. */
266     void setReferenceSelectionMode(bool enable);
267     /** Are we in reference choosing mode ? */
268     bool referenceSelectionMode() const;
269     /** Are we currently using a reference selection ? */
270     bool referenceSelection() const;
271 
272     void emitAboutToModify();
273     void emitModified();
274     void emitRefreshSheetViews();
275     void emitVisibleSheetRequested(Sheet* sheet);
276     void emitCloseEditor(bool saveChanges, bool expandMatrix = false);
277     void emitRequestFocusEditor();
278 
279     void scrollToCursor();
280 Q_SIGNALS:
281     /**
282      * Emitted when the Selection was changed.
283      * @param region the changed part of the Selection
284      */
285     void changed(const Region& region);
286 
287     /**
288      * An operation on the selection is about to happen.
289      */
290     void aboutToModify(const Region& region);
291 
292     /**
293      * Emitted when the content was modified.
294      */
295     void modified(const Region& region);
296 
297     void refreshSheetViews();
298     void visibleSheetRequested(Sheet* sheet);
299     void closeEditor(bool saveChanges, bool expandMatrix);
300     void activeSheetChanged(Sheet* sheet);
301     void requestFocusEditor();
302 
303     void documentReadWriteToggled(bool readWrite);
304     void sheetProtectionToggled(bool protect);
305 
306     void updateAccessedCellRange(Sheet* sheet, const QPoint& location);
307 
308 protected:
309     class Point;
310     class Range;
311 
312     /**
313      * @internal used to create derived Points
314      */
315     Region::Point* createPoint(const QPoint&) const override;
316 
317     /**
318      * @internal used to create derived Points
319      */
320     Region::Point* createPoint(const QString&) const override;
321 
322     /**
323      * @internal used to create derived Points
324      */
325     Region::Point* createPoint(const Region::Point&) const override;
326 
327     /**
328      * @internal used to create derived Ranges
329      */
330     Region::Range* createRange(const QRect&) const override;
331 
332     /**
333      * @internal used to create derived Ranges
334      */
335     Region::Range* createRange(const Region::Point&, const Region::Point&) const override;
336 
337     /**
338      * @internal used to create derived Ranges
339      */
340     Region::Range* createRange(const QString&) const override;
341 
342     /**
343      * @internal used to create derived Ranges
344      */
345     Region::Range* createRange(const Region::Range&) const override;
346 
347     /**
348      * Dilates the region and emits the changed() signal.
349      * \internal
350      */
351     void emitChanged(const Region& changedRegion);
352 
353     /**
354      * @internal
355      */
356     void dump() const;
357 
358 private:
359     // do not allow assignment
360     Selection& operator=(const Selection&);
361 
362     class Private;
363     Private * const d;
364 };
365 
366 /***************************************************************************
367   class Selection::Point
368 ****************************************************************************/
369 
370 /**
371  * This Point is extended by an color attribute.
372  */
373 class Selection::Point : public Region::Point
374 {
375 public:
376     Point(const QPoint& point);
377     Point(const QString& string);
378     Point(const Region::Point& point);
379 
setColor(const QColor & color)380     void setColor(const QColor& color) {
381         m_color = color;
382     }
color()383     virtual const QColor& color() const {
384         return m_color;
385     }
386 
387 private:
388     QColor m_color;
389 };
390 
391 /***************************************************************************
392   class Selection::Range
393 ****************************************************************************/
394 
395 /**
396  * This Range is extended by an color attribute.
397  */
398 class Selection::Range : public Region::Range
399 {
400 public:
401     Range(const QRect& rect);
402     Range(const Calligra::Sheets::Region::Point& tl, const Calligra::Sheets::Region::Point& br);
403     Range(const QString& string);
404     Range(const Region::Range& range);
405 
setColor(const QColor & color)406     void setColor(const QColor& color) {
407         m_color = color;
408     }
color()409     const QColor& color() const {
410         return m_color;
411     }
412 
413 private:
414     QColor m_color;
415 };
416 
417 } // namespace Sheets
418 } // namespace Calligra
419 
420 #endif // CALLIGRA_SHEETS_SELECTION
421