File indexing completed on 2024-05-05 08:41:18
0001 /* 0002 * Copyright (C) 2010-2015 by Stephen Allewell 0003 * steve.allewell@gmail.com 0004 * 0005 * This program is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation; either version 2 of the License, or 0008 * (at your option) any later version. 0009 */ 0010 0011 #include "Page.h" 0012 0013 #include <QPainter> 0014 #include <QPrinterInfo> 0015 0016 #include <KLocalizedString> 0017 0018 #include "Document.h" 0019 #include "Element.h" 0020 #include "Exceptions.h" 0021 0022 Page::Page(QPageSize pageSize, QPageLayout::Orientation orientation) 0023 : QPageLayout( 0024 pageSize, 0025 orientation, 0026 QMarginsF(Configuration::page_MarginLeft(), Configuration::page_MarginTop(), Configuration::page_MarginRight(), Configuration::page_MarginBottom()), 0027 QPageLayout::Millimeter) 0028 , m_pageNumber(0) 0029 { 0030 } 0031 0032 Page::Page(const Page &other) 0033 : QPageLayout(other) 0034 { 0035 *this = other; 0036 } 0037 0038 Page::~Page() 0039 { 0040 qDeleteAll(m_elements); 0041 } 0042 0043 Page &Page::operator=(const Page &other) 0044 { 0045 if (this != &other) { 0046 qDeleteAll(m_elements); 0047 m_elements.clear(); 0048 0049 m_pageNumber = other.m_pageNumber; 0050 0051 QListIterator<Element *> elementIterator(other.m_elements); 0052 0053 while (elementIterator.hasNext()) { 0054 Element *element = elementIterator.next(); 0055 0056 if (element->type() != Element::Plan) { 0057 Element *cloned = element->clone(); 0058 cloned->setParent(this); 0059 m_elements.append(cloned); 0060 0061 if (cloned->type() == Element::Pattern) { 0062 if (dynamic_cast<PatternElement *>(cloned)->showPlan()) { 0063 cloned = dynamic_cast<PatternElement *>(cloned)->planElement(); 0064 cloned->setParent(this); 0065 m_elements.append(cloned); 0066 } 0067 } 0068 } 0069 } 0070 } 0071 0072 return *this; 0073 } 0074 0075 int Page::pageNumber() const 0076 { 0077 return m_pageNumber; 0078 } 0079 0080 const QList<Element *> Page::elements() const 0081 { 0082 return m_elements; 0083 } 0084 0085 void Page::setPageNumber(int pageNumber) 0086 { 0087 m_pageNumber = pageNumber; 0088 } 0089 0090 void Page::addElement(Element *element) 0091 { 0092 m_elements.append(element); 0093 } 0094 0095 void Page::removeElement(Element *element) 0096 { 0097 m_elements.removeOne(element); 0098 } 0099 0100 void Page::render(Document *document, QPainter *painter) const 0101 { 0102 painter->save(); 0103 0104 if (painter->device()->paintEngine() == nullptr) { 0105 painter->setPen(QPen(Qt::red, 0.05)); 0106 painter->drawRect(painter->window().marginsRemoved(margins().toMargins())); 0107 } 0108 0109 QListIterator<Element *> elementIterator(m_elements); 0110 0111 while (elementIterator.hasNext()) { 0112 Element *element = elementIterator.next(); 0113 element->render(document, painter); 0114 } 0115 0116 painter->restore(); 0117 } 0118 0119 Element *Page::itemAt(const QPoint &pos) const 0120 { 0121 Element *element = nullptr; 0122 0123 if (m_elements.count()) { 0124 QListIterator<Element *> elementIterator(m_elements); 0125 elementIterator.toBack(); // start from the end of the list 0126 0127 while (elementIterator.hasPrevious()) { 0128 Element *testElement = elementIterator.previous(); 0129 0130 if (testElement->rectangle().contains(pos)) { 0131 element = testElement; 0132 break; 0133 } 0134 } 0135 } 0136 0137 return element; // will be the element under the cursor or 0 0138 } 0139 0140 QDataStream &operator<<(QDataStream &stream, const Page &page) 0141 { 0142 stream << qint32(page.version); 0143 0144 stream << qint32(page.m_pageNumber) << qint32(page.pageSize().id()) << qint32(page.orientation()) << qint32(page.margins().left()) 0145 << qint32(page.margins().top()) << qint32(page.margins().right()) << qint32(page.margins().bottom()) << qint32(page.m_elements.count()); 0146 0147 QListIterator<Element *> elementIterator(page.m_elements); 0148 0149 while (elementIterator.hasNext()) { 0150 const Element *element = elementIterator.next(); 0151 stream << qint32(element->type()); 0152 0153 if (element->type() != Element::Plan) { 0154 stream << *element; 0155 } 0156 } 0157 0158 if (stream.status() != QDataStream::Ok) { 0159 throw FailedWriteFile(stream.status()); 0160 } 0161 0162 return stream; 0163 } 0164 0165 QDataStream &operator>>(QDataStream &stream, Page &page) 0166 { 0167 qint32 version; 0168 qint32 pageNumber; 0169 qint32 pageSizeId; 0170 qint32 orientation; 0171 qint32 left; 0172 qint32 top; 0173 qint32 right; 0174 qint32 bottom; 0175 qint32 showGrid; 0176 qint32 gridX; 0177 qint32 gridY; 0178 qreal zoomFactor; 0179 0180 stream >> version; 0181 0182 switch (version) { 0183 case 102: 0184 stream >> pageNumber >> pageSizeId >> orientation >> left >> top >> right >> bottom; 0185 page.m_pageNumber = pageNumber; 0186 page.setPageSize(QPageSize(static_cast<QPageSize::PageSizeId>(pageSizeId))); 0187 page.setOrientation(static_cast<QPageLayout::Orientation>(orientation)); 0188 page.setMargins(QMarginsF(left, top, right, bottom)); 0189 0190 page.readElements(stream); 0191 break; 0192 0193 case 101: 0194 stream >> pageNumber >> pageSizeId >> orientation >> left >> top >> right >> bottom >> showGrid >> gridX >> gridY; 0195 page.m_pageNumber = pageNumber; 0196 page.setPageSize(QPageSize(static_cast<QPageSize::PageSizeId>(pageSizeId))); 0197 page.setOrientation(static_cast<QPageLayout::Orientation>(orientation)); 0198 page.setMargins(QMarginsF(left, top, right, bottom)); 0199 0200 page.readElements(stream); 0201 0202 stream >> zoomFactor; 0203 break; 0204 0205 case 100: 0206 stream >> pageSizeId >> orientation >> left >> top >> right >> bottom; 0207 page.setPageSize(QPageSize(static_cast<QPageSize::PageSizeId>(pageSizeId))); 0208 page.setOrientation(static_cast<QPageLayout::Orientation>(orientation)); 0209 page.setMargins(QMarginsF(left, top, right, bottom)); 0210 0211 page.readElements(stream); 0212 0213 stream >> zoomFactor; 0214 break; 0215 0216 default: 0217 throw InvalidFileVersion(QString(i18n("Page version %1", version))); 0218 break; 0219 } 0220 0221 return stream; 0222 } 0223 0224 void Page::readElements(QDataStream &stream) 0225 { 0226 qint32 elements; 0227 qint32 type; 0228 Element *element; 0229 0230 stream >> elements; 0231 0232 while (elements--) { 0233 stream >> type; 0234 0235 switch (static_cast<Element::Type>(type)) { 0236 case Element::Text: 0237 element = new TextElement(this, QRect()); 0238 break; 0239 0240 case Element::Pattern: 0241 element = new PatternElement(this, QRect()); 0242 break; 0243 0244 case Element::Plan: 0245 element = nullptr; // handled by the PatternElement 0246 break; 0247 0248 case Element::Key: 0249 element = new KeyElement(this, QRect()); 0250 break; 0251 0252 case Element::Image: 0253 element = new ImageElement(this, QRect()); 0254 break; 0255 0256 default: 0257 throw FailedReadFile(QString(i18n("Invalid element type"))); 0258 break; 0259 } 0260 0261 if (element) { 0262 stream >> *element; 0263 m_elements.append(element); 0264 0265 if (element->type() == Element::Pattern) { 0266 if (dynamic_cast<PatternElement *>(element)->showPlan()) { 0267 m_elements.append(dynamic_cast<PatternElement *>(element)->planElement()); 0268 } 0269 } 0270 } 0271 } 0272 }