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 #include "RowRepeatStorage.h" 0020 0021 #include <QList> 0022 #include <QPair> 0023 #include <QDebug> 0024 0025 #include "calligra_sheets_limits.h" 0026 0027 using namespace Calligra::Sheets; 0028 0029 RowRepeatStorage::RowRepeatStorage() 0030 { 0031 } 0032 0033 void RowRepeatStorage::dump() const 0034 { 0035 for (QMap<int, int>::const_iterator it = m_data.begin(); it != m_data.end(); ++it) { 0036 qDebug() << "[" << (it.key() - it.value() + 1) << it.key() << "] =" << it.value(); 0037 } 0038 } 0039 0040 void RowRepeatStorage::setRowRepeat(int firstRow, int rowRepeat) 0041 { 0042 const int lastRow = firstRow + rowRepeat - 1; 0043 // see if m_data contains a range that includes firstRow 0044 QMap<int, int>::iterator it = m_data.lowerBound(firstRow); 0045 typedef QPair<int, int> intPair; 0046 QList<intPair> newRanges; 0047 // returns first range that ends at or after firstRow 0048 if (it != m_data.end()) { 0049 while (it != m_data.end() && (it.key() - it.value() + 1) <= lastRow) { 0050 if ((it.key() - it.value() + 1) < firstRow) { 0051 // starts before the new range, so we want to change the row repeat value of this range 0052 // but since the key is the end of the range, we can only remove it and re-insert it later 0053 newRanges.append(qMakePair(firstRow - 1, it.value() - (it.key() - firstRow + 1))); 0054 if (it.key() > lastRow) { 0055 // ends after the new range, so also adjust the end 0056 it.value() = it.key() - lastRow; 0057 ++it; 0058 } else { 0059 it = m_data.erase(it); 0060 } 0061 } else { 0062 // starts inside the new range, ends in or after the new range 0063 if (it.key() <= lastRow) { 0064 // ends inside the new range, so just remove 0065 it = m_data.erase(it); 0066 } else { 0067 // ends after the new range, adjust and go to the next 0068 it.value() = it.key() - lastRow; 0069 ++it; 0070 } 0071 } 0072 } 0073 } 0074 0075 // finally set the new range of row-repeat values 0076 if (rowRepeat != 1) 0077 m_data[lastRow] = rowRepeat; 0078 0079 foreach (const intPair& p, newRanges) { 0080 if (p.second > 1) m_data[p.first] = p.second; 0081 } 0082 } 0083 0084 int RowRepeatStorage::rowRepeat(int row) const 0085 { 0086 // first range that ends at or after row 0087 QMap<int, int>::const_iterator it = m_data.lowerBound(row); 0088 // not found? default value = 1 0089 if (it == m_data.end()) return 1; 0090 // otherwise, see if row is actually inside the range 0091 if (it.key() - it.value() + 1 <= row) { 0092 return it.value(); 0093 } 0094 return 1; 0095 } 0096 0097 int RowRepeatStorage::firstIdenticalRow(int row) const 0098 { 0099 // first range that ends at or after row 0100 QMap<int, int>::const_iterator it = m_data.lowerBound(row); 0101 // not found? default value = row 0102 if (it == m_data.end()) return row; 0103 // otherwise, see if row is actually inside the range 0104 if (it.key() - it.value() + 1 <= row) { 0105 return it.key() - it.value() + 1; 0106 } 0107 return row; 0108 } 0109 0110 void RowRepeatStorage::insertRows(int row, int count) 0111 { 0112 typedef QPair<int, int> intPair; 0113 QList<intPair> newRanges; 0114 0115 // first range that ends at or after row 0116 QMap<int, int>::iterator it = m_data.lowerBound(row); 0117 while (it != m_data.end()) { 0118 if (it.key() - it.value() + 1 < row) { 0119 // starts before the newly inserted rows, so split it up 0120 newRanges.append(qMakePair(row-1, row - it.key() + it.value() - 1)); 0121 newRanges.append(qMakePair(it.key() + count, it.key() - row + 1)); 0122 } else { 0123 newRanges.append(qMakePair(it.key() + count, it.value())); 0124 } 0125 it = m_data.erase(it); 0126 } 0127 0128 m_data[row+count-1] = count; 0129 foreach (const intPair& p, newRanges) { 0130 if (p.second > 1) m_data[p.first] = p.second; 0131 } 0132 } 0133 0134 void RowRepeatStorage::removeRows(int row, int count) 0135 { 0136 typedef QPair<int, int> intPair; 0137 QList<intPair> newRanges; 0138 0139 // first range that ends at or after row 0140 QMap<int, int>::iterator it = m_data.lowerBound(row); 0141 while (it != m_data.end()) { 0142 if (it.key() - it.value() + 1 < row) { 0143 // starts before removed rows 0144 newRanges.append(qMakePair(row-1, row - it.key() + it.value() - 1)); 0145 } 0146 if (it.key() >= row + count) { 0147 // ends after the removed rows 0148 newRanges.append(qMakePair(it.key() - count, qMin(it.value(), it.key() - row - count + 1))); 0149 } 0150 it = m_data.erase(it); 0151 } 0152 0153 foreach (const intPair& p, newRanges) { 0154 if (p.second > 1) m_data[p.first] = p.second; 0155 } 0156 } 0157 0158 void RowRepeatStorage::insertShiftDown(const QRect &rect) 0159 { 0160 RowRepeatStorage s2 = *this; 0161 s2.insertRows(rect.top(), rect.height()); 0162 0163 typedef QPair<int, int> intPair; 0164 QList<intPair> newRanges; 0165 0166 for (int row = 1; row <= KS_rowMax;) { 0167 int repeat1 = rowRepeat(row); 0168 int repeat2 = s2.rowRepeat(row); 0169 repeat1 -= row - firstIdenticalRow(row); 0170 repeat2 -= row - s2.firstIdenticalRow(row); 0171 int repeat = qMin(repeat1, repeat2); 0172 if (repeat > 1) { 0173 newRanges.append(qMakePair(row + repeat - 1, repeat)); 0174 } 0175 row += repeat; 0176 } 0177 0178 m_data.clear(); 0179 foreach (const intPair& p, newRanges) { 0180 if (p.second > 1) m_data[p.first] = p.second; 0181 } 0182 } 0183 0184 void RowRepeatStorage::removeShiftUp(const QRect &rect) 0185 { 0186 RowRepeatStorage s2 = *this; 0187 s2.removeRows(rect.top(), rect.height()); 0188 0189 typedef QPair<int, int> intPair; 0190 QList<intPair> newRanges; 0191 0192 for (int row = 1; row <= KS_rowMax;) { 0193 int repeat1 = rowRepeat(row); 0194 int repeat2 = s2.rowRepeat(row); 0195 repeat1 -= row - firstIdenticalRow(row); 0196 repeat2 -= row - s2.firstIdenticalRow(row); 0197 int repeat = qMin(repeat1, repeat2); 0198 if (repeat > 1) { 0199 newRanges.append(qMakePair(row + repeat - 1, repeat)); 0200 } 0201 row += repeat; 0202 } 0203 0204 m_data.clear(); 0205 foreach (const intPair& p, newRanges) { 0206 if (p.second > 1) m_data[p.first] = p.second; 0207 } 0208 } 0209 0210 void RowRepeatStorage::insertShiftRight(const QRect &rect) 0211 { 0212 splitRowRepeat(rect.top()); 0213 splitRowRepeat(rect.bottom()+1); 0214 } 0215 0216 void RowRepeatStorage::removeShiftLeft(const QRect &rect) 0217 { 0218 // identical to insert 0219 insertShiftRight(rect); 0220 } 0221 0222 void RowRepeatStorage::splitRowRepeat(int row) 0223 { 0224 // first range that ends at or after row 0225 QMap<int, int>::iterator it = m_data.lowerBound(row); 0226 if (it != m_data.end() && (it.key() - it.value() + 1) < row) { 0227 // range starts before row, ends in or after it; split it 0228 int start = it.key() - it.value() + 1; 0229 int count = row - start; 0230 it.value() = it.key() - row + 1; 0231 if (count > 1) m_data[start+count-1] = count; 0232 } 0233 }