1 | /* This file is part of the KDE project |
2 | Copyright 2008 Stefan Nikolaus <stefan.nikolaus@kdemail.net> |
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; either |
7 | version 2 of the License, or (at your option) any later version. |
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 | #include "PageManager.h" |
21 | |
22 | #include "PrintSettings.h" |
23 | #include "Region.h" |
24 | #include "RowColumnFormat.h" |
25 | #include "RowFormatStorage.h" |
26 | #include "Sheet.h" |
27 | |
28 | using namespace Calligra::Sheets; |
29 | |
30 | class PageManager::Private |
31 | { |
32 | public: |
33 | Sheet* sheet; |
34 | QList<QRect> pages; // page number to cell range |
35 | PrintSettings settings; |
36 | }; |
37 | |
38 | |
39 | PageManager::PageManager(Sheet* sheet) |
40 | : d(new Private) |
41 | { |
42 | d->sheet = sheet; |
43 | d->settings = *sheet->printSettings(); |
44 | } |
45 | |
46 | PageManager::~PageManager() |
47 | { |
48 | delete d; |
49 | } |
50 | |
51 | void PageManager::layoutPages() |
52 | { |
53 | const Sheet* sheet = d->sheet; |
54 | const PrintSettings settings = d->settings; |
55 | d->pages.clear(); |
56 | clearPages(); |
57 | int pageNumber = 1; |
58 | preparePage(pageNumber); |
59 | |
60 | if (settings.pageOrder() == PrintSettings::LeftToRight) { |
61 | // kDebug() << "processing printRanges" << settings.printRegion(); |
62 | // iterate over the print ranges |
63 | Region::ConstIterator end = settings.printRegion().constEnd(); |
64 | for (Region::ConstIterator it = settings.printRegion().constBegin(); it != end; ++it) { |
65 | if (!(*it)->isValid()) |
66 | continue; |
67 | |
68 | // limit the print range to the used area |
69 | const QRect printRange = (*it)->rect() & sheet->usedArea(true); |
70 | // kDebug() << "processing printRange" << printRange; |
71 | |
72 | int rows = 0; |
73 | double height = 0.0; |
74 | for (int row = printRange.top(); row <= printRange.bottom(); ++row) { |
75 | rows++; |
76 | height += sheet->rowFormats()->visibleHeight(row); |
77 | |
78 | // 1. find the number of rows per page |
79 | if (row == printRange.bottom()) // always iterate over the last 'page row' |
80 | ; |
81 | else if (height + sheet->rowFormats()->visibleHeight(row + 1) <= size(pageNumber).height()) |
82 | continue; |
83 | |
84 | // kDebug() << "1. done: row" << row << "rows" << rows << "height" << height; |
85 | |
86 | int columns = 0; |
87 | double width = 0.0; |
88 | // 2. iterate over the columns and create the pages |
89 | for (int col = printRange.left(); col < printRange.right(); ++col) { |
90 | columns++; |
91 | width += sheet->columnFormat(col)->visibleWidth(); |
92 | |
93 | // Does the next column fit too? |
94 | if (width + sheet->columnFormat(col + 1)->visibleWidth() <= size(pageNumber).width()) |
95 | continue; |
96 | |
97 | // kDebug() << "col" << col << "columns" << columns << "width" << width; |
98 | const QRect cellRange(col - columns + 1, row - rows + 1, columns, rows); |
99 | if (pageNeedsPrinting(cellRange)) { |
100 | d->pages.append(cellRange); |
101 | insertPage(pageNumber++); |
102 | preparePage(pageNumber); // prepare the next page |
103 | } |
104 | columns = 0; |
105 | width = 0.0; |
106 | } |
107 | // Always insert a page for the last column |
108 | columns++; |
109 | const QRect cellRange(printRange.right() - columns + 1, row - rows + 1, columns, rows); |
110 | if (pageNeedsPrinting(cellRange)) { |
111 | d->pages.append(cellRange); |
112 | insertPage(pageNumber); |
113 | pageNumber++; |
114 | } |
115 | |
116 | // 3. prepare for the next row of pages |
117 | if (row != printRange.bottom()) { |
118 | preparePage(pageNumber); |
119 | } |
120 | rows = 0; |
121 | height = 0.0; |
122 | } |
123 | } |
124 | } else { // if (settings.pageOrder() == PrintSettings::TopToBottom) |
125 | // kDebug() << "processing printRanges" << settings.printRegion(); |
126 | // iterate over the print ranges |
127 | Region::ConstIterator end = settings.printRegion().constEnd(); |
128 | for (Region::ConstIterator it = settings.printRegion().constBegin(); it != end; ++it) { |
129 | if (!(*it)->isValid()) |
130 | continue; |
131 | |
132 | // limit the print range to the used area |
133 | const QRect printRange = (*it)->rect() & sheet->usedArea(); |
134 | kDebug() << "processing printRange" << printRange; |
135 | |
136 | int columns = 0; |
137 | double width = 0.0; |
138 | for (int col = printRange.left(); col <= printRange.right(); ++col) { |
139 | columns++; |
140 | width += sheet->columnFormat(col)->visibleWidth(); |
141 | |
142 | // 1. find the number of columns per page |
143 | if (col == printRange.right()) // always iterate over the last 'page column' |
144 | ; |
145 | else if (width + sheet->columnFormat(col + 1)->visibleWidth() <= size(pageNumber).width()) |
146 | continue; |
147 | |
148 | // kDebug() << "1. done: col" << col << "columns" << columns << "width" << width; |
149 | |
150 | int rows = 0; |
151 | double height = 0.0; |
152 | // 2. iterate over the rows and create the pages |
153 | for (int row = printRange.top(); row < printRange.bottom(); ++row) { |
154 | rows++; |
155 | height += sheet->rowFormats()->visibleHeight(row); |
156 | |
157 | // Does the next row fit too? |
158 | if (height + sheet->rowFormats()->visibleHeight(row + 1) <= size(pageNumber).height()) |
159 | continue; |
160 | |
161 | // kDebug() << "row" << row << "rows" << rows << "height" << height; |
162 | const QRect cellRange(col - columns + 1, row - rows + 1, columns, rows); |
163 | if (pageNeedsPrinting(cellRange)) { |
164 | d->pages.append(cellRange); |
165 | insertPage(pageNumber++); |
166 | preparePage(pageNumber); // prepare the next page |
167 | } |
168 | rows = 0; |
169 | height = 0.0; |
170 | } |
171 | // Always insert a page for the last row |
172 | rows++; |
173 | const QRect cellRange(col - columns + 1, printRange.bottom() - rows + 1, columns, rows); |
174 | if (pageNeedsPrinting(cellRange)) { |
175 | d->pages.append(cellRange); |
176 | insertPage(pageNumber); |
177 | pageNumber++; |
178 | } |
179 | |
180 | // 3. prepare for the next column of pages |
181 | if (col != printRange.right()) { |
182 | preparePage(pageNumber); |
183 | } |
184 | columns = 0; |
185 | width = 0.0; |
186 | } |
187 | } |
188 | } |
189 | kDebug() << d->pages.count() << "page(s) created" ; |
190 | } |
191 | |
192 | void PageManager::setPrintSettings(const PrintSettings& settings, bool force) |
193 | { |
194 | if (!force && settings == d->settings) |
195 | return; |
196 | kDebug() << (d->pages.isEmpty() ? "Creating" : "Recreating" ) << "pages..." ; |
197 | d->settings = settings; |
198 | layoutPages(); |
199 | } |
200 | |
201 | int PageManager::pageCount() const |
202 | { |
203 | return d->pages.count(); |
204 | } |
205 | |
206 | QRect PageManager::cellRange(int page) const |
207 | { |
208 | if (page < 1 || page > d->pages.count()) |
209 | return QRect(); |
210 | return d->pages[page - 1]; |
211 | } |
212 | |
213 | QSizeF PageManager::size(int page) const |
214 | { |
215 | if (page < 1 || page > d->pages.count()) |
216 | return QSizeF(); |
217 | return QSizeF(d->settings.printWidth() + 0.5, d->settings.printHeight() + 0.5); // FIXME |
218 | } |
219 | |
220 | Sheet* PageManager::sheet() const |
221 | { |
222 | return d->sheet; |
223 | } |
224 | |
225 | const PrintSettings& PageManager::printSettings() const |
226 | { |
227 | return d->settings; |
228 | } |
229 | |
230 | void PageManager::clearPages() |
231 | { |
232 | } |
233 | |
234 | bool PageManager::pageNeedsPrinting(const QRect& cellRange) const |
235 | { |
236 | Q_UNUSED(cellRange); |
237 | return true; |
238 | } |
239 | |
240 | void PageManager::insertPage(int page) |
241 | { |
242 | Q_UNUSED(page); |
243 | } |
244 | |
245 | void PageManager::preparePage(int page) |
246 | { |
247 | Q_UNUSED(page); |
248 | } |
249 | |