File indexing completed on 2024-05-19 16:09:59
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2010-2012 C. Boemann <cbo@boemann.dk> 0003 * Copyright (C) 2006,2011 Sebastian Sauer <mail@dipe.org> 0004 * Copyright (C) 2006-2007, 2010 Thomas Zander <zander@kde.org> 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public License 0017 * along with this library; see the file COPYING.LIB. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "KWRootAreaProviderTextBox.h" 0023 #include "KWRootAreaProvider.h" 0024 #include "KWPageManager.h" 0025 #include "KWDocument.h" 0026 #include "frames/KWTextFrameSet.h" 0027 #include "frames/KWCopyShape.h" 0028 #include "frames/KWFrameLayout.h" 0029 0030 #include <KoTextLayoutRootArea.h> 0031 #include <KoShape.h> 0032 #include <KoShapeContainer.h> 0033 #include <KoTextShapeData.h> 0034 #include <KoTextDocumentLayout.h> 0035 0036 #include <WordsDebug.h> 0037 0038 KWRootAreaProviderTextBox::KWRootAreaProviderTextBox(KWTextFrameSet *textFrameSet) 0039 : KWRootAreaProviderBase(textFrameSet) 0040 { 0041 } 0042 0043 KWRootAreaProviderTextBox::~KWRootAreaProviderTextBox() 0044 { 0045 //FIXME : this code crashes so far, why ? 0046 /*foreach (QList<KoTextLayoutRootArea*> areaList, m_rootAreaCache.values()) 0047 qDeleteAll(areaList);*/ 0048 m_rootAreaCache.clear(); 0049 } 0050 0051 void KWRootAreaProviderTextBox::clearPages(int /*pageNumber*/) 0052 { 0053 KoTextDocumentLayout *lay = dynamic_cast<KoTextDocumentLayout*>(frameSet()->document()->documentLayout()); 0054 Q_ASSERT(lay); 0055 foreach(KoTextLayoutRootArea *area, m_rootAreaCache) { 0056 releaseAllAfter(area); 0057 lay->removeRootArea(area); 0058 } 0059 } 0060 0061 void KWRootAreaProviderTextBox::setPageDirty(int /*pageNumber*/) 0062 { 0063 foreach(KoTextLayoutRootArea *rootArea, m_rootAreaCache) { 0064 rootArea->setDirty(); // be sure the root-areas are relayouted 0065 } 0066 } 0067 0068 0069 KoTextLayoutRootArea *KWRootAreaProviderTextBox::provide(KoTextDocumentLayout *documentLayout, const RootAreaConstraint &, int requestedPosition, bool *isNewArea) 0070 { 0071 KWPageManager *pageManager = frameSet()->wordsDocument()->pageManager(); 0072 Q_ASSERT(pageManager); 0073 if (pageManager->pageCount() == 0) { // not ready yet (may happen e.g. on loading a document) 0074 return 0; 0075 } 0076 0077 if (m_rootAreaCache.size() > requestedPosition) 0078 { 0079 KoTextLayoutRootArea *rootArea = m_rootAreaCache[requestedPosition]; 0080 Q_ASSERT(rootArea); 0081 0082 // No constraints except for the main frame set 0083 *isNewArea = false; 0084 return rootArea; 0085 } 0086 0087 if (!documentLayout->referencedLayout()) { 0088 KoTextDocumentLayout *reflay = dynamic_cast<KoTextDocumentLayout*>(frameSet()->wordsDocument()->frameLayout()->mainFrameSet()->document()->documentLayout()); 0089 documentLayout->setReferencedLayout(reflay); 0090 } 0091 0092 if (frameSet()->shapeCount() > requestedPosition) { 0093 KoShape *shape = frameSet()->shapes()[requestedPosition]; 0094 Q_ASSERT(shape); 0095 0096 KoTextLayoutRootArea *area = new KoTextLayoutRootArea(documentLayout); 0097 m_rootAreaCache.append(area); 0098 Q_ASSERT(m_rootAreaCache.size() > requestedPosition); 0099 0100 KoTextShapeData *data = qobject_cast<KoTextShapeData*>(shape->userData()); 0101 if (data) { 0102 data->setRootArea(area); 0103 area->setAssociatedShape(shape); 0104 } else { 0105 warnWords << "shape has no KoTextShapeData"; 0106 } 0107 0108 if ((!shape->anchor()) || shape->anchor()->anchorType() == KoShapeAnchor::AnchorPage) { 0109 KWPage *page = new KWPage(pageManager->page(shape)); 0110 area->setPage(page); 0111 } 0112 0113 0114 area->setLayoutEnvironmentResctictions(true, true); 0115 0116 *isNewArea = true; 0117 return area; 0118 } 0119 0120 *isNewArea = true; 0121 0122 return 0; 0123 } 0124 0125 // afterThis==nullptr means delete everything 0126 void KWRootAreaProviderTextBox::releaseAllAfter(KoTextLayoutRootArea *afterThis) 0127 { 0128 while (m_rootAreaCache.count() != 0 && m_rootAreaCache.back() != afterThis){ 0129 m_rootAreaCache.removeLast(); 0130 } 0131 } 0132 0133 void KWRootAreaProviderTextBox::doPostLayout(KoTextLayoutRootArea *rootArea, bool isNewRootArea) 0134 { 0135 KWDocument *kwdoc = const_cast<KWDocument*>(frameSet()->wordsDocument()); 0136 KWPageManager *pageManager = kwdoc->pageManager(); 0137 Q_ASSERT(pageManager); 0138 0139 KoShape *shape = rootArea->associatedShape(); 0140 if (!shape) { 0141 return; 0142 } 0143 0144 KWPage page = pageManager->page(shape); 0145 Q_ASSERT(page.isValid()); 0146 0147 if (false){//FIXME m_pages.count() > pageManager->pageCount()) { 0148 // we need to wait for the mainFrameSet to finish till we are able to continue 0149 KWRootAreaProvider *provider = (KWRootAreaProvider *)kwdoc->frameLayout()->mainFrameSet()->rootAreaProvider(); 0150 provider->addDependentProvider(this, page.pageNumber()); 0151 } 0152 0153 0154 KoTextShapeData *data = qobject_cast<KoTextShapeData*>(shape->userData()); 0155 Q_ASSERT(data); 0156 0157 debugWords << "pageNumber=" << page.pageNumber() << "frameSetType=" << "isNewRootArea=" << isNewRootArea << "rootArea=" << rootArea << "isDirty=" << rootArea->isDirty(); 0158 0159 QRectF updateRect = shape->outlineRect(); 0160 0161 QSizeF newSize = shape->size() 0162 - QSizeF(data->leftPadding() + data->rightPadding(), 0163 data->topPadding() + data->bottomPadding()); 0164 0165 KoBorder *border = shape->border(); 0166 0167 if (border) { 0168 newSize -= QSizeF(border->borderWidth(KoBorder::LeftBorder) + border->borderWidth(KoBorder::RightBorder), border->borderWidth(KoBorder::TopBorder) + border->borderWidth(KoBorder::BottomBorder)); 0169 } 0170 0171 if (data->resizeMethod() == KoTextShapeData::AutoGrowWidthAndHeight 0172 ||data->resizeMethod() == KoTextShapeData::AutoGrowWidth) { 0173 newSize.setWidth(rootArea->right() - rootArea->left()); 0174 } 0175 0176 newSize += QSizeF(data->leftPadding() + data->rightPadding(), 0177 data->topPadding() + data->bottomPadding()); 0178 if (border) { 0179 newSize += QSizeF(border->borderWidth(KoBorder::LeftBorder) + border->borderWidth(KoBorder::RightBorder), border->borderWidth(KoBorder::TopBorder) + border->borderWidth(KoBorder::BottomBorder)); 0180 } 0181 0182 if (newSize != rootArea->associatedShape()->size()) { 0183 rootArea->associatedShape()->setSize(newSize); 0184 0185 // transfer the new size to the copy-shapes 0186 foreach(KWCopyShape *cs, frameSet()->copyShapes()) { 0187 cs->setSize(newSize); 0188 } 0189 } 0190 0191 updateRect |= rootArea->associatedShape()->outlineRect(); 0192 rootArea->associatedShape()->update(updateRect); 0193 } 0194 0195 QRectF KWRootAreaProviderTextBox::suggestRect(KoTextLayoutRootArea *rootArea) 0196 { 0197 KoShape *shape = rootArea->associatedShape(); 0198 if (!shape) { // no shape => nothing to draw => no space needed 0199 return QRectF(0., 0., 0.,0.); 0200 } 0201 0202 QRectF rect = KWRootAreaProviderBase::suggestRect(rootArea); 0203 0204 if (frameSet()->shapes().back() == shape) { 0205 rect.setHeight(1E6); 0206 } 0207 0208 return rect; 0209 } 0210