File indexing completed on 2024-04-28 16:21:27
0001 /* This file is part of the KDE project 0002 Copyright 2010 Marijn Kruisselbrink <mkruisselbrink@kde.org> 0003 Copyright 2005-2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net> 0004 0005 This program is free software; you can redistribute it and/or modify 0006 it under the terms of the GNU Library General Public License as published by 0007 the Free Software Foundation; either version 2 of the License, or 0008 (at your option) any later version. 0009 0010 This program is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 GNU Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this program; if not, write to the Free Software 0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0018 */ 0019 0020 0021 #ifndef CALLIGRA_SHEETS_REGION 0022 #define CALLIGRA_SHEETS_REGION 0023 0024 #include <QList> 0025 #include <QRect> 0026 #include <QSet> 0027 #include <QSharedDataPointer> 0028 #include <QString> 0029 0030 #include "SheetsDebug.h" 0031 #include "sheets_odf_export.h" 0032 0033 inline uint qHash(const QPoint& point) 0034 { 0035 return (static_cast<uint>(point.x()) << 16) + static_cast<uint>(point.y()); 0036 } 0037 0038 namespace Calligra 0039 { 0040 namespace Sheets 0041 { 0042 class Cell; 0043 class Map; 0044 class Sheet; 0045 0046 /** 0047 * \class Region 0048 * \brief The one for all class for points and ranges. 0049 * \author Stefan Nikolaus <stefan.nikolaus@kdemail.net> 0050 * \since 1.5 0051 */ 0052 class CALLIGRA_SHEETS_ODF_EXPORT Region 0053 { 0054 public: 0055 class Element; 0056 class Point; 0057 class Range; 0058 0059 /** 0060 * Constructor. 0061 * Creates an empty region. 0062 */ 0063 Region(); 0064 0065 /** 0066 * Constructor. 0067 * Creates a region consisting of a point. 0068 * @param point the point's location 0069 * @param sheet the sheet the point belongs to 0070 */ 0071 explicit Region(const QPoint& point, Sheet* sheet = 0); 0072 0073 /** 0074 * Constructor. 0075 * Creates a region consisting of a range. 0076 * @param range the range's location 0077 * @param sheet the sheet the range belongs to 0078 */ 0079 explicit Region(const QRect& range, Sheet* sheet = 0); 0080 0081 /** 0082 * Constructor. 0083 * Creates a region consisting of the region defined in @p expression . 0084 * @param expression a string representing the region (e.g. "A1:B3") 0085 * @param map used to determine the sheet, if it's named in the string 0086 * @param sheet the fallback sheet, if \p expression does not contain one 0087 */ 0088 explicit Region(const QString& expression, const Map* map = 0, Sheet* sheet = 0); 0089 0090 /** 0091 * Copy Constructor. 0092 * Creates a copy of the region. 0093 * @param region the region to copy 0094 */ 0095 Region(const Region& region); 0096 0097 /** 0098 * Constructor. 0099 * Creates a region consisting of a point. 0100 * @param col the column of the point 0101 * @param row the row of the point 0102 * @param sheet the sheet the point belongs to 0103 */ 0104 Region(int col, int row, Sheet* sheet = 0); 0105 0106 /** 0107 * Constructor. 0108 * Creates a region consisting of a range at the location 0109 * @param col the column of the range' starting point 0110 * @param row the row of the range' starting point 0111 * @param width the width of the range 0112 * @param height the height of the range 0113 * @param sheet the sheet the range belongs to 0114 */ 0115 Region(int col, int row, int width, int height, Sheet* sheet = 0); 0116 0117 /** 0118 * Destructor. 0119 */ 0120 virtual ~Region(); 0121 0122 0123 /** 0124 * @return a QRegion that unifies all contained ranges 0125 */ 0126 QVector<QRect> rects() const; 0127 0128 /** 0129 * @param originSheet The name is created relative to this sheet. 0130 * @return the name of the region (e.g. "A1:A2") 0131 */ 0132 QString name(Sheet* originSheet = 0) const; 0133 0134 /** 0135 * @param sRegion will be modified, if a valid sheet was found. The sheetname 0136 * will be removed 0137 * @return sheet named in the @p sRegion or null 0138 */ 0139 Sheet* filterSheetName(QString& sRegion); 0140 0141 0142 0143 /** 0144 * @return @c true, if this region contains no elements 0145 */ 0146 bool isEmpty() const; 0147 0148 /** 0149 * @return @c true, if this region contains only a single point 0150 */ 0151 bool isSingular() const; 0152 0153 /** 0154 * @return @c true, if this region is contiguous 0155 */ 0156 bool isContiguous() const; 0157 0158 /** 0159 * @return @c true, if this region contains at least one valid point or one valid range 0160 */ 0161 bool isValid() const; 0162 0163 /** 0164 * @param col The column to check 0165 * 0166 * @return @c True, if the column @p col is selected. If column @p col 0167 * is not given, it returns true, if at least one column is selected 0168 * 0169 * \note If you want to check more than one column for selection, use 0170 * columnsSelected(). It returns a set of all selected columns at once. 0171 */ 0172 bool isColumnSelected(uint col = 0) const; 0173 0174 /** 0175 * @param row the row to check 0176 * 0177 * @return @c true , if the row @p row is selected. If row @p row 0178 * is not given, it returns true, if at least one row is selected 0179 * 0180 * \note If you want to check more than one row for selection, use 0181 * rowsSelected(). It returns a set of all selected rows at once. 0182 */ 0183 bool isRowSelected(uint row = 0) const; 0184 0185 /** 0186 * @return @c true , if at least one column or one row is selected 0187 */ 0188 bool isColumnOrRowSelected() const; 0189 0190 /** 0191 * @return @c true , if all cells in the sheet are selected 0192 */ 0193 bool isAllSelected() const; 0194 0195 /** 0196 * @return a set of column numbers, for those columns, that are selected 0197 */ 0198 QSet<int> columnsSelected() const; 0199 0200 /** 0201 * @return a set of row numbers, for those rows, that are selected 0202 */ 0203 QSet<int> rowsSelected() const; 0204 0205 /** 0206 * @return a set of column numbers, for those columns, that have at least 0207 * one cell selected 0208 */ 0209 QSet<int> columnsAffected() const; 0210 0211 /** 0212 * @return a set of row numbers, for those rows, that have at least 0213 * one cell selected 0214 */ 0215 QSet<int> rowsAffected() const; 0216 0217 /** 0218 * @param point the point's location 0219 * @param sheet the sheet the point belongs to 0220 * @return @c true, if the region contains the point @p point 0221 */ 0222 bool contains(const QPoint& point, Sheet* sheet = 0) const; 0223 0224 0225 0226 /* TODO Stefan #2: Optimize! Adjacent Points/Ranges */ 0227 /** 0228 * Adds the point @p point to this region. 0229 * @param point the point's location 0230 * @param sheet the sheet the point belongs to 0231 */ 0232 Element* add(const QPoint& point, Sheet* sheet = 0); 0233 0234 /** 0235 * Adds the range @p range to this region. 0236 * @param range the range's location 0237 * @param sheet the sheet the range belongs to 0238 */ 0239 Element* add(const QRect& range, Sheet* sheet = 0); 0240 0241 /** 0242 * Adds the region @p region to this region. 0243 * @param region the region to be added 0244 * @param sheet the fallback sheet used, if an element has no sheet set 0245 */ 0246 Element* add(const Region& region, Sheet* sheet = 0); 0247 0248 /* TODO Stefan #3: Improve! */ 0249 /** 0250 * Subtracts the point @p point from this region. 0251 * @param point the point's location 0252 * @param sheet the sheet the point belongs to 0253 */ 0254 void sub(const QPoint& point, Sheet* sheet); 0255 0256 /** 0257 * Subtracts the range @p range from this region. 0258 * @param range the range's location 0259 * @param sheet the sheet the range belongs to 0260 */ 0261 void sub(const QRect& range, Sheet* sheet); 0262 0263 /** 0264 * Subtracts the region @p region from this region. 0265 * @param region the region to subtract 0266 */ 0267 void sub(const Region& region); 0268 0269 /** 0270 * Intersects the region @p region and this region and 0271 * returns the result of the intersection as a new Region. 0272 */ 0273 Region intersected(const Region& region) const; 0274 0275 /** 0276 * Intersects this region with the row @p row and returns 0277 * the result of the intersection as a new Region. 0278 */ 0279 Region intersectedWithRow(int row) const; 0280 0281 /** 0282 * @param point the point's location 0283 * @param sheet the sheet the point belongs to 0284 */ 0285 virtual Element* eor(const QPoint& point, Sheet* sheet = 0); 0286 0287 /** 0288 * Deletes all elements of the region. The result is an empty region. 0289 */ 0290 virtual void clear(); 0291 0292 0293 QRect firstRange() const; 0294 QRect lastRange() const; 0295 Sheet* firstSheet() const; 0296 Sheet* lastSheet() const; 0297 0298 QRect boundingRect() const; 0299 0300 0301 static QRect normalized(const QRect& rect); 0302 0303 0304 /** 0305 * @param region the region to compare 0306 * @return @c true, if this region equals region @p region 0307 */ 0308 bool operator==(const Region& region) const; 0309 inline bool operator!=(const Region& region) const { 0310 return !operator==(region); 0311 } 0312 0313 /** 0314 * @param region the region to copy 0315 */ 0316 void operator=(const Region& region); 0317 0318 0319 0320 /** 0321 * @return the map to which this region belongs. 0322 */ 0323 const Map* map() const; 0324 0325 /** 0326 * Sets the map to which this region belongs. 0327 */ 0328 void setMap(const Map*); 0329 0330 0331 typedef QList<Element*>::Iterator Iterator; 0332 typedef QList<Element*>::ConstIterator ConstIterator; 0333 0334 ConstIterator constBegin() const; 0335 ConstIterator constEnd() const; 0336 0337 static bool isValid(const QPoint& point); 0338 static bool isValid(const QRect& rect); 0339 0340 protected: 0341 /** 0342 * @return the list of elements 0343 */ 0344 QList<Element*>& cells() const; 0345 0346 /** 0347 * @param index the index of the element in whose front the new point 0348 * is inserted 0349 * @param point the location of the point to be inserted 0350 * @param sheet the sheet the point belongs to 0351 * @param multi @c true to allow multiple occurrences of a point 0352 * @return the added point, a null pointer, if @p point is not 0353 * valid or the element containing @p point 0354 */ 0355 Element* insert(int index, const QPoint& point, Sheet* sheet, bool multi = true); 0356 0357 /** 0358 * @param index the index of the element in whose front the new range 0359 * is inserted 0360 * @param range the location of the range to be inserted 0361 * @param sheet the sheet the range belongs to 0362 * @param multi @c true to allow multiple occurrences of a range 0363 * @return the added range, a null pointer, if @p range is not 0364 * valid or the element containing @p range 0365 */ 0366 Element* insert(int index, const QRect& range, Sheet* sheet, bool multi = true); 0367 0368 /** 0369 * @internal used to create derived Points 0370 */ 0371 virtual Point* createPoint(const QPoint&) const; 0372 0373 /** 0374 * @internal used to create derived Points 0375 */ 0376 virtual Point* createPoint(const QString&) const; 0377 0378 /** 0379 * @internal used to create derived Points 0380 */ 0381 virtual Point* createPoint(const Point&) const; 0382 0383 /** 0384 * @internal used to create derived Ranges 0385 */ 0386 virtual Range* createRange(const QRect&) const; 0387 0388 /** 0389 * @internal used to create derived Ranges 0390 */ 0391 virtual Range* createRange(const Point&, const Point&) const; 0392 0393 /** 0394 * @internal used to create derived Ranges 0395 */ 0396 virtual Range* createRange(const QString&) const; 0397 0398 /** 0399 * @internal used to create derived Ranges 0400 */ 0401 virtual Range* createRange(const Range&) const; 0402 0403 private: 0404 class Private; 0405 QSharedDataPointer<Private> d; 0406 }; 0407 0408 0409 /*************************************************************************** 0410 class Region::Element 0411 ****************************************************************************/ 0412 /** 0413 * Base class for region elements, which can be points or ranges. 0414 * This class is used by Calligra::Sheets::Region and could not be used outside of it. 0415 * 0416 * Size: 0417 * m_sheet: 4 bytes 0418 * vtable: 4 bytes 0419 * sum: 8 bytes 0420 */ 0421 class CALLIGRA_SHEETS_ODF_EXPORT Region::Element 0422 { 0423 public: 0424 enum Type { Undefined, Point, Range }; 0425 0426 Element(); 0427 virtual ~Element(); 0428 0429 virtual Type type() const { 0430 return Undefined; 0431 } 0432 virtual bool isValid() const { 0433 return false; 0434 } 0435 virtual bool isColumn() const { 0436 return false; 0437 } 0438 virtual bool isRow() const { 0439 return false; 0440 } 0441 virtual bool isAll() const { 0442 return false; 0443 } 0444 0445 virtual bool contains(const QPoint&) const { 0446 return false; 0447 } 0448 virtual bool contains(const QRect&) const { 0449 return false; 0450 } 0451 0452 virtual QString name(Sheet* = 0) const { 0453 return QString(""); 0454 } 0455 virtual QRect rect() const { 0456 return QRect(); 0457 } 0458 0459 virtual bool isColumnFixed() const { 0460 return false; 0461 } 0462 virtual bool isRowFixed() const { 0463 return false; 0464 } 0465 virtual bool isTopFixed() const { 0466 return false; 0467 } 0468 virtual bool isLeftFixed() const { 0469 return false; 0470 } 0471 virtual bool isBottomFixed() const { 0472 return false; 0473 } 0474 virtual bool isRightFixed() const { 0475 return false; 0476 } 0477 0478 Sheet* sheet() const { 0479 return m_sheet; 0480 } 0481 void setSheet(Sheet* sheet) { 0482 m_sheet = sheet; 0483 } 0484 0485 protected: 0486 /* TODO Stefan #6: 0487 Elaborate, if this pointer could be avoided by QDict or whatever in 0488 Region. 0489 */ 0490 Sheet* m_sheet; 0491 }; 0492 0493 0494 /*************************************************************************** 0495 class Region::Point 0496 ****************************************************************************/ 0497 0498 /** 0499 * A point in a region. 0500 * This class is used by Calligra::Sheets::Region and could not be used outside of it. 0501 * 0502 * Size: 0503 * m_sheet: 4 bytes 0504 * vtable: 4 bytes 0505 * m_point: 8 bytes 0506 * sum: 16 bytes 0507 */ 0508 class CALLIGRA_SHEETS_ODF_EXPORT Region::Point : public Region::Element 0509 { 0510 public: 0511 Point() : Element(), m_point() {} 0512 Point(int col, int row) : Element(), m_point(col, row) {} 0513 Point(const QPoint&); 0514 Point(const QString&); 0515 ~Point() override; 0516 0517 Type type() const override { 0518 return Element::Point; 0519 } 0520 bool isValid() const override { 0521 return (!m_point.isNull() && Region::isValid(m_point)); 0522 } 0523 bool isColumn() const override { 0524 return false; 0525 } 0526 bool isRow() const override { 0527 return false; 0528 } 0529 bool isAll() const override { 0530 return false; 0531 } 0532 0533 bool contains(const QPoint&) const override; 0534 bool contains(const QRect&) const override; 0535 0536 QString name(Sheet* originSheet = 0) const override; 0537 0538 QRect rect() const override { 0539 return QRect(m_point, m_point); 0540 } 0541 0542 bool isColumnFixed() const override { 0543 return m_fixedColumn; 0544 } 0545 bool isRowFixed() const override { 0546 return m_fixedRow; 0547 } 0548 bool isTopFixed() const override { 0549 return m_fixedRow; 0550 } 0551 bool isLeftFixed() const override { 0552 return m_fixedColumn; 0553 } 0554 bool isBottomFixed() const override { 0555 return m_fixedRow; 0556 } 0557 bool isRightFixed() const override { 0558 return m_fixedColumn; 0559 } 0560 0561 QPoint pos() const { 0562 return m_point; 0563 } 0564 Cell cell() const; 0565 0566 bool operator==(const Point& other) const { 0567 return ((m_point == other.m_point) && (m_sheet == other.m_sheet)); 0568 } 0569 0570 private: 0571 QPoint m_point; 0572 bool m_fixedColumn; 0573 bool m_fixedRow; 0574 }; 0575 0576 0577 /*************************************************************************** 0578 class Region:.Range 0579 ****************************************************************************/ 0580 0581 /** 0582 * A range in a region. 0583 * This class is used by Calligra::Sheets::Region and could not be used outside of it. 0584 * 0585 * Size: 0586 * m_sheet: 4 bytes 0587 * vtable: 4 bytes 0588 * m_range: 16 bytes 0589 * sum: 24 bytes 0590 */ 0591 class CALLIGRA_SHEETS_ODF_EXPORT Region::Range : public Region::Element 0592 { 0593 public: 0594 Range(const QRect&); 0595 Range(const Region::Point&, const Region::Point&); 0596 Range(const QString&); 0597 ~Range() override; 0598 0599 Type type() const override { 0600 return Element::Range; 0601 } 0602 bool isValid() const override { 0603 return !m_range.isNull() && Region::isValid(m_range); 0604 } 0605 bool isColumn() const override; 0606 bool isRow() const override; 0607 bool isAll() const override; 0608 0609 bool contains(const QPoint&) const override; 0610 bool contains(const QRect&) const override; 0611 0612 QString name(Sheet* originSheet = 0) const override; 0613 0614 QRect rect() const override { 0615 return m_range; 0616 } 0617 0618 bool isColumnFixed() const override { 0619 return m_fixedLeft && m_fixedRight; 0620 } 0621 bool isRowFixed() const override { 0622 return m_fixedTop && m_fixedBottom; 0623 } 0624 bool isTopFixed() const override { 0625 return m_fixedTop; 0626 } 0627 bool isLeftFixed() const override { 0628 return m_fixedLeft; 0629 } 0630 bool isBottomFixed() const override { 0631 return m_fixedBottom; 0632 } 0633 bool isRightFixed() const override { 0634 return m_fixedRight; 0635 } 0636 0637 int width() const; 0638 int height() const; 0639 0640 private: 0641 QRect m_range; 0642 bool m_fixedTop; 0643 bool m_fixedLeft; 0644 bool m_fixedBottom; 0645 bool m_fixedRight; 0646 }; 0647 0648 } // namespace Sheets 0649 } // namespace Calligra 0650 0651 Q_DECLARE_TYPEINFO(Calligra::Sheets::Region, Q_MOVABLE_TYPE); 0652 0653 0654 /*************************************************************************** 0655 QDebug support 0656 ****************************************************************************/ 0657 0658 inline QDebug operator<<(QDebug str, const Calligra::Sheets::Region& r) 0659 { 0660 return str << qPrintable(r.name()); 0661 } 0662 0663 #endif // CALLIGRA_SHEETS_REGION