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 }