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
28using namespace Calligra::Sheets;
29
30class PageManager::Private
31{
32public:
33 Sheet* sheet;
34 QList<QRect> pages; // page number to cell range
35 PrintSettings settings;
36};
37
38
39PageManager::PageManager(Sheet* sheet)
40 : d(new Private)
41{
42 d->sheet = sheet;
43 d->settings = *sheet->printSettings();
44}
45
46PageManager::~PageManager()
47{
48 delete d;
49}
50
51void 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
192void 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
201int PageManager::pageCount() const
202{
203 return d->pages.count();
204}
205
206QRect 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
213QSizeF 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
220Sheet* PageManager::sheet() const
221{
222 return d->sheet;
223}
224
225const PrintSettings& PageManager::printSettings() const
226{
227 return d->settings;
228}
229
230void PageManager::clearPages()
231{
232}
233
234bool PageManager::pageNeedsPrinting(const QRect& cellRange) const
235{
236 Q_UNUSED(cellRange);
237 return true;
238}
239
240void PageManager::insertPage(int page)
241{
242 Q_UNUSED(page);
243}
244
245void PageManager::preparePage(int page)
246{
247 Q_UNUSED(page);
248}
249