File indexing completed on 2024-04-28 16:21:28
0001 /* This file is part of the KDE project 0002 Copyright 2010 Marijn Kruisselbrink <mkruisselbrink@kde.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "RowFormatStorage.h" 0021 0022 #include "calligra_sheets_limits.h" 0023 #include "3rdparty/mdds/flat_segment_tree.hpp" 0024 0025 #include "Map.h" 0026 #include "RowColumnFormat.h" 0027 #include "Sheet.h" 0028 0029 using namespace Calligra::Sheets; 0030 0031 class Q_DECL_HIDDEN RowFormatStorage::Private 0032 { 0033 public: 0034 Private(); 0035 qreal rawRowHeight(int row, int* lastRow = 0, int* firstRow = 0) const; 0036 0037 Sheet* sheet; 0038 mdds::flat_segment_tree<int, qreal> rowHeights; 0039 mdds::flat_segment_tree<int, bool> hidden; 0040 mdds::flat_segment_tree<int, bool> filtered; 0041 mdds::flat_segment_tree<int, bool> hasPageBreak; 0042 }; 0043 0044 RowFormatStorage::Private::Private() 0045 : rowHeights(1, KS_rowMax+1, -1) 0046 , hidden(1, KS_rowMax+1, false) 0047 , filtered(1, KS_rowMax+1, false) 0048 , hasPageBreak(1, KS_rowMax+1, false) 0049 { 0050 } 0051 0052 RowFormatStorage::RowFormatStorage(Sheet* sheet) 0053 : d(new Private) 0054 { 0055 d->sheet = sheet; 0056 } 0057 0058 RowFormatStorage::~RowFormatStorage() 0059 { 0060 delete d; 0061 } 0062 0063 RowFormatStorage& RowFormatStorage::operator=(const RowFormatStorage& r) 0064 { 0065 *d = *r.d; 0066 return *this; 0067 } 0068 0069 Sheet* RowFormatStorage::sheet() const 0070 { 0071 return d->sheet; 0072 } 0073 0074 qreal RowFormatStorage::rowHeight(int row, int *lastRow, int *firstRow) const 0075 { 0076 qreal v = d->rawRowHeight(row, lastRow, firstRow); 0077 if (v == -1) { 0078 return d->sheet->map()->defaultRowFormat()->height(); 0079 } else { 0080 return v; 0081 } 0082 } 0083 0084 qreal RowFormatStorage::Private::rawRowHeight(int row, int *lastRow, int *firstRow) const 0085 { 0086 qreal v; 0087 if (!rowHeights.search(row, v, firstRow, lastRow)) { 0088 if (firstRow) *firstRow = row; 0089 if (lastRow) *lastRow = row; 0090 return -1; 0091 } else { 0092 if (lastRow) (*lastRow)--; 0093 return v; 0094 } 0095 } 0096 0097 void RowFormatStorage::setRowHeight(int firstRow, int lastRow, qreal height) 0098 { 0099 // first get old row height to properly update documentSize 0100 qreal deltaHeight = -totalVisibleRowHeight(firstRow, lastRow); 0101 0102 d->rowHeights.insert_back(firstRow, lastRow+1, height); 0103 0104 deltaHeight += totalVisibleRowHeight(firstRow, lastRow); 0105 d->sheet->adjustDocumentHeight(deltaHeight); 0106 } 0107 0108 qreal RowFormatStorage::totalRowHeight(int firstRow, int lastRow) const 0109 { 0110 if (lastRow < firstRow) return 0; 0111 qreal res = 0; 0112 for (int row = firstRow; row <= lastRow; ++row) { 0113 int last; 0114 qreal h = rowHeight(row, &last); 0115 res += (qMin(last, lastRow) - row + 1) * h; 0116 row = last; 0117 } 0118 return res; 0119 } 0120 0121 qreal RowFormatStorage::visibleHeight(int row, int *lastRow, int *firstRow) const 0122 { 0123 if (isHiddenOrFiltered(row, lastRow, firstRow)) { 0124 return 0.0; 0125 } else { 0126 int hLastRow, hFirstRow; 0127 qreal height = rowHeight(row, &hLastRow, &hFirstRow); 0128 if (lastRow) *lastRow = qMin(*lastRow, hLastRow); 0129 if (firstRow) *firstRow = qMax(*firstRow, hFirstRow); 0130 return height; 0131 } 0132 } 0133 0134 qreal RowFormatStorage::totalVisibleRowHeight(int firstRow, int lastRow) const 0135 { 0136 if (lastRow < firstRow) return 0; 0137 qreal res = 0; 0138 for (int row = firstRow; row <= lastRow; ++row) { 0139 int last; 0140 qreal h = visibleHeight(row, &last); 0141 res += (qMin(last, lastRow) - row + 1) * h; 0142 row = last; 0143 } 0144 return res; 0145 } 0146 0147 int RowFormatStorage::rowForPosition(qreal ypos, qreal *topOfRow) const 0148 { 0149 int row = 1; 0150 qreal y = 0; 0151 while (row < KS_rowMax) { 0152 int last; 0153 const qreal h = visibleHeight(row, &last); 0154 if (h == 0) { 0155 row = last+1; 0156 continue; 0157 } 0158 const int cnt = last - row + 1; 0159 const int maxcnt = qMin(int((ypos - y) / h), cnt); 0160 y += maxcnt * h; 0161 row += maxcnt; 0162 if (maxcnt < cnt) { 0163 if (topOfRow) *topOfRow = y; 0164 return row; 0165 } 0166 } 0167 return KS_rowMax; 0168 } 0169 0170 bool RowFormatStorage::isHidden(int row, int *lastRow, int *firstRow) const 0171 { 0172 bool v; 0173 if (!d->hidden.search(row, v, firstRow, lastRow)) { 0174 if (firstRow) *firstRow = row; 0175 if (lastRow) *lastRow = row; 0176 return false; 0177 } else { 0178 if (lastRow) (*lastRow)--; 0179 return v; 0180 } 0181 } 0182 0183 void RowFormatStorage::setHidden(int firstRow, int lastRow, bool hidden) 0184 { 0185 qreal deltaHeight = 0; 0186 if (hidden) deltaHeight -= totalVisibleRowHeight(firstRow, lastRow); 0187 d->hidden.insert_back(firstRow, lastRow+1, hidden); 0188 if (!hidden) deltaHeight += totalVisibleRowHeight(firstRow, lastRow); 0189 d->sheet->adjustDocumentHeight(deltaHeight); 0190 } 0191 0192 bool RowFormatStorage::isFiltered(int row, int* lastRow, int *firstRow) const 0193 { 0194 bool v; 0195 if (!d->filtered.search(row, v, firstRow, lastRow)) { 0196 if (firstRow) *firstRow = row; 0197 if (lastRow) *lastRow = row; 0198 return false; 0199 } else { 0200 if (lastRow) (*lastRow)--; 0201 return v; 0202 } 0203 } 0204 0205 void RowFormatStorage::setFiltered(int firstRow, int lastRow, bool filtered) 0206 { 0207 qreal deltaHeight = 0; 0208 if (filtered) deltaHeight -= totalVisibleRowHeight(firstRow, lastRow); 0209 d->filtered.insert_back(firstRow, lastRow+1, filtered); 0210 if (!filtered) deltaHeight += totalVisibleRowHeight(firstRow, lastRow); 0211 d->sheet->adjustDocumentHeight(deltaHeight); 0212 } 0213 0214 bool RowFormatStorage::isHiddenOrFiltered(int row, int* lastRow, int* firstRow) const 0215 { 0216 int hLastRow, hFirstRow, fLastRow, fFirstRow; 0217 bool v = isHidden(row, &hLastRow, &hFirstRow); 0218 v = isFiltered(row, &fLastRow, &fFirstRow) || v; 0219 if (lastRow) *lastRow = qMin(hLastRow, fLastRow); 0220 if (firstRow) *firstRow = qMax(hFirstRow, fFirstRow); 0221 return v; 0222 } 0223 0224 bool RowFormatStorage::hasPageBreak(int row, int* lastRow, int* firstRow) const 0225 { 0226 bool v; 0227 if (!d->hasPageBreak.search(row, v, firstRow, lastRow)) { 0228 if (lastRow) *lastRow = row; 0229 if (firstRow) *firstRow = row; 0230 return false; 0231 } else { 0232 if (lastRow) (*lastRow)--; 0233 return v; 0234 } 0235 } 0236 0237 void RowFormatStorage::setPageBreak(int firstRow, int lastRow, bool pageBreak) 0238 { 0239 d->hasPageBreak.insert_back(firstRow, lastRow+1, pageBreak); 0240 } 0241 0242 int RowFormatStorage::lastNonDefaultRow() const 0243 { 0244 int row = KS_rowMax; 0245 int firstRow; 0246 while (row > 0 && isDefaultRow(row, 0, &firstRow)) { 0247 row = firstRow-1; 0248 } 0249 if (row < 1) return 1; 0250 return row; 0251 } 0252 0253 bool RowFormatStorage::rowsAreEqual(int row1, int row2) const 0254 { 0255 return rowHeight(row1) == rowHeight(row2) 0256 && isHidden(row1) == isHidden(row2) 0257 && isFiltered(row1) == isFiltered(row2) 0258 && hasPageBreak(row1) == hasPageBreak(row2); 0259 } 0260 0261 bool RowFormatStorage::isDefaultRow(int row, int* lastRow, int* firstRow) const 0262 { 0263 bool isDef = true; 0264 int l, f; 0265 isDef = d->rawRowHeight(row, lastRow, firstRow) == -1 && isDef; 0266 isDef = !isHiddenOrFiltered(row, &l, &f) && isDef; 0267 if (lastRow) *lastRow = qMin(*lastRow, l); 0268 if (firstRow) *firstRow = qMax(*firstRow, f); 0269 isDef = !hasPageBreak(row, &l, &f) && isDef; 0270 if (lastRow) *lastRow = qMin(*lastRow, l); 0271 if (firstRow) *firstRow = qMax(*firstRow, f); 0272 return isDef; 0273 } 0274 0275 void RowFormatStorage::setDefault(int firstRow, int lastRow) 0276 { 0277 setRowHeight(firstRow, lastRow, -1); 0278 setHidden(firstRow, lastRow, false); 0279 setFiltered(firstRow, lastRow, false); 0280 setPageBreak(firstRow, lastRow, false); 0281 } 0282 0283 void RowFormatStorage::insertRows(int row, int number) 0284 { 0285 qreal deltaHeight = -totalRowHeight(KS_rowMax - number + 1, KS_rowMax); 0286 d->rowHeights.shift_right(row, number, false); 0287 deltaHeight += totalRowHeight(row, row + number - 1); 0288 d->sheet->adjustDocumentHeight(deltaHeight); 0289 0290 d->hidden.shift_right(row, number, false); 0291 d->filtered.shift_right(row, number, false); 0292 d->hasPageBreak.shift_right(row, number, false); 0293 } 0294 0295 void RowFormatStorage::removeRows(int row, int number) 0296 { 0297 qreal deltaHeight = -totalRowHeight(row, row + number - 1); 0298 d->rowHeights.shift_left(row, row+number-1); 0299 deltaHeight += totalRowHeight(KS_rowMax - number + 1, KS_rowMax); 0300 d->sheet->adjustDocumentHeight(deltaHeight); 0301 0302 d->hidden.shift_left(row, row+number-1); 0303 d->filtered.shift_left(row, row+number-1); 0304 d->hasPageBreak.shift_left(row, row+number-1); 0305 } 0306