File indexing completed on 2024-04-28 16:21:25

0001 /* This file is part of the KDE project
0002    Copyright 2008 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
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 "PageManager.h"
0021 
0022 #include "PrintSettings.h"
0023 #include "Region.h"
0024 #include "RowColumnFormat.h"
0025 #include "RowFormatStorage.h"
0026 #include "Sheet.h"
0027 
0028 using namespace Calligra::Sheets;
0029 
0030 class Q_DECL_HIDDEN PageManager::Private
0031 {
0032 public:
0033     Sheet* sheet;
0034     QList<QRect> pages; // page number to cell range
0035     PrintSettings settings;
0036 };
0037 
0038 
0039 PageManager::PageManager(Sheet* sheet)
0040         : d(new Private)
0041 {
0042     d->sheet = sheet;
0043     d->settings = *sheet->printSettings();
0044 }
0045 
0046 PageManager::~PageManager()
0047 {
0048     delete d;
0049 }
0050 
0051 void PageManager::layoutPages()
0052 {
0053     const Sheet* sheet = d->sheet;
0054     const PrintSettings settings = d->settings;
0055     d->pages.clear();
0056     clearPages();
0057     int pageNumber = 1;
0058     preparePage(pageNumber);
0059 
0060     if (settings.pageOrder() == PrintSettings::LeftToRight) {
0061 //         debugSheets << "processing printRanges" << settings.printRegion();
0062         // iterate over the print ranges
0063         Region::ConstIterator end = settings.printRegion().constEnd();
0064         for (Region::ConstIterator it = settings.printRegion().constBegin(); it != end; ++it) {
0065             if (!(*it)->isValid())
0066                 continue;
0067 
0068             // limit the print range to the used area
0069             const QRect printRange = (*it)->rect() & sheet->usedArea(true);
0070 //             debugSheets << "processing printRange" << printRange;
0071 
0072             int rows = 0;
0073             double height = 0.0;
0074             for (int row = printRange.top(); row <= printRange.bottom(); ++row) {
0075                 rows++;
0076                 height += sheet->rowFormats()->visibleHeight(row);
0077 
0078                 // 1. find the number of rows per page
0079                 if (row == printRange.bottom()) // always iterate over the last 'page row'
0080                     ;
0081                 else if (height + sheet->rowFormats()->visibleHeight(row + 1) <= size(pageNumber).height())
0082                     continue;
0083 
0084 //                 debugSheets << "1. done: row" << row << "rows" << rows << "height" << height;
0085 
0086                 int columns = 0;
0087                 double width = 0.0;
0088                 // 2. iterate over the columns and create the pages
0089                 for (int col = printRange.left(); col < printRange.right(); ++col) {
0090                     columns++;
0091                     width += sheet->columnFormat(col)->visibleWidth();
0092 
0093                     // Does the next column fit too?
0094                     if (width + sheet->columnFormat(col + 1)->visibleWidth() <= size(pageNumber).width())
0095                         continue;
0096 
0097 //                     debugSheets << "col" << col << "columns" << columns << "width" << width;
0098                     const QRect cellRange(col - columns + 1, row - rows + 1, columns, rows);
0099                     if (pageNeedsPrinting(cellRange)) {
0100                         d->pages.append(cellRange);
0101                         insertPage(pageNumber++);
0102                         preparePage(pageNumber); // prepare the next page
0103                     }
0104                     columns = 0;
0105                     width = 0.0;
0106                 }
0107                 // Always insert a page for the last column
0108                 columns++;
0109                 const QRect cellRange(printRange.right() - columns + 1, row - rows + 1, columns, rows);
0110                 if (pageNeedsPrinting(cellRange)) {
0111                     d->pages.append(cellRange);
0112                     insertPage(pageNumber);
0113                     pageNumber++;
0114                 }
0115 
0116                 // 3. prepare for the next row of pages
0117                 if (row != printRange.bottom()) {
0118                     preparePage(pageNumber);
0119                 }
0120                 rows = 0;
0121                 height = 0.0;
0122             }
0123         }
0124     } else { // if (settings.pageOrder() == PrintSettings::TopToBottom)
0125 //         debugSheets << "processing printRanges" << settings.printRegion();
0126         // iterate over the print ranges
0127         Region::ConstIterator end = settings.printRegion().constEnd();
0128         for (Region::ConstIterator it = settings.printRegion().constBegin(); it != end; ++it) {
0129             if (!(*it)->isValid())
0130                 continue;
0131 
0132             // limit the print range to the used area
0133             const QRect printRange = (*it)->rect() & sheet->usedArea();
0134             debugSheets << "processing printRange" << printRange;
0135 
0136             int columns = 0;
0137             double width = 0.0;
0138             for (int col = printRange.left(); col <= printRange.right(); ++col) {
0139                 columns++;
0140                 width += sheet->columnFormat(col)->visibleWidth();
0141 
0142                 // 1. find the number of columns per page
0143                 if (col == printRange.right()) // always iterate over the last 'page column'
0144                     ;
0145                 else if (width + sheet->columnFormat(col + 1)->visibleWidth() <= size(pageNumber).width())
0146                     continue;
0147 
0148 //                 debugSheets << "1. done: col" << col << "columns" << columns << "width" << width;
0149 
0150                 int rows = 0;
0151                 double height = 0.0;
0152                 // 2. iterate over the rows and create the pages
0153                 for (int row = printRange.top(); row < printRange.bottom(); ++row) {
0154                     rows++;
0155                     height += sheet->rowFormats()->visibleHeight(row);
0156 
0157                     // Does the next row fit too?
0158                     if (height + sheet->rowFormats()->visibleHeight(row + 1) <= size(pageNumber).height())
0159                         continue;
0160 
0161 //                     debugSheets << "row" << row << "rows" << rows << "height" << height;
0162                     const QRect cellRange(col - columns + 1, row - rows + 1, columns, rows);
0163                     if (pageNeedsPrinting(cellRange)) {
0164                         d->pages.append(cellRange);
0165                         insertPage(pageNumber++);
0166                         preparePage(pageNumber); // prepare the next page
0167                     }
0168                     rows = 0;
0169                     height = 0.0;
0170                 }
0171                 // Always insert a page for the last row
0172                 rows++;
0173                 const QRect cellRange(col - columns + 1, printRange.bottom() - rows + 1, columns, rows);
0174                 if (pageNeedsPrinting(cellRange)) {
0175                     d->pages.append(cellRange);
0176                     insertPage(pageNumber);
0177                     pageNumber++;
0178                 }
0179 
0180                 // 3. prepare for the next column of pages
0181                 if (col != printRange.right()) {
0182                     preparePage(pageNumber);
0183                 }
0184                 columns = 0;
0185                 width = 0.0;
0186             }
0187         }
0188     }
0189     debugSheets << d->pages.count() << "page(s) created";
0190 }
0191 
0192 void PageManager::setPrintSettings(const PrintSettings& settings, bool force)
0193 {
0194     if (!force && settings == d->settings)
0195         return;
0196     debugSheets << (d->pages.isEmpty() ? "Creating" : "Recreating") << "pages...";
0197     d->settings = settings;
0198     layoutPages();
0199 }
0200 
0201 int PageManager::pageCount() const
0202 {
0203     return d->pages.count();
0204 }
0205 
0206 QRect PageManager::cellRange(int page) const
0207 {
0208     if (page < 1 || page > d->pages.count())
0209         return QRect();
0210     return d->pages[page - 1];
0211 }
0212 
0213 QSizeF PageManager::size(int page) const
0214 {
0215     if (page < 1 || page > d->pages.count())
0216         return QSizeF();
0217     return QSizeF(d->settings.printWidth() + 0.5, d->settings.printHeight() + 0.5); // FIXME
0218 }
0219 
0220 Sheet* PageManager::sheet() const
0221 {
0222     return d->sheet;
0223 }
0224 
0225 const PrintSettings& PageManager::printSettings() const
0226 {
0227     return d->settings;
0228 }
0229 
0230 void PageManager::clearPages()
0231 {
0232 }
0233 
0234 bool PageManager::pageNeedsPrinting(const QRect& cellRange) const
0235 {
0236     Q_UNUSED(cellRange);
0237     return true;
0238 }
0239 
0240 void PageManager::insertPage(int page)
0241 {
0242     Q_UNUSED(page);
0243 }
0244 
0245 void PageManager::preparePage(int page)
0246 {
0247     Q_UNUSED(page);
0248 }