File indexing completed on 2024-05-12 16:36:45

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2008-2009 Thorsten Zachmann <zachmann@kde.org>
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 "KPrPlaceholderTextStrategy.h"
0021 
0022 #include <QTextDocument>
0023 #include <QTextCursor>
0024 #include <QTextBlock>
0025 #include <QPainter>
0026 
0027 #include <KoOdfLoadingContext.h>
0028 #include <KoProperties.h>
0029 #include <KoOdfStylesReader.h>
0030 #include <KoXmlWriter.h>
0031 #include <KoParagraphStyle.h>
0032 #include <KoShape.h>
0033 #include <KoShapeLoadingContext.h>
0034 #include <KoShapeFactoryBase.h>
0035 #include <KoShapeRegistry.h>
0036 #include <KoShapeSavingContext.h>
0037 #include <KoTextShapeData.h>
0038 #include <KoTextSharedLoadingData.h>
0039 #include <KoTextDocument.h>
0040 #include <KoTextEditor.h>
0041 #include <KoTextDocumentLayout.h>
0042 #include <KoTextWriter.h>
0043 #include <KoStyleManager.h>
0044 #include <KoXmlReader.h>
0045 #include <KoXmlNS.h>
0046 
0047 #include "StageDebug.h"
0048 
0049 KPrPlaceholderTextStrategy::KPrPlaceholderTextStrategy( const QString & presentationClass )
0050 : KPrPlaceholderStrategy( presentationClass )
0051 , m_textShape( 0 )
0052 {
0053 }
0054 
0055 KPrPlaceholderTextStrategy::~KPrPlaceholderTextStrategy()
0056 {
0057     delete m_textShape;
0058 }
0059 
0060 KoShape *KPrPlaceholderTextStrategy::createShape(KoDocumentResourceManager *documentResources)
0061 {
0062     KoShape * shape = KPrPlaceholderStrategy::createShape(documentResources);
0063     if ( m_textShape ) {
0064         KoTextShapeData * data = qobject_cast<KoTextShapeData*>( m_textShape->userData() );
0065         KoTextShapeData * newData = qobject_cast<KoTextShapeData*>( shape->userData() );
0066         if ( data && newData ) {
0067             QTextCursor cursor( data->document() );
0068             QTextCursor newCursor( newData->document() );
0069             KoTextDocument textDocument( newData->document() );
0070 
0071             QTextBlockFormat blockFormat( cursor.blockFormat() );
0072             newCursor.setBlockFormat( blockFormat );
0073 
0074             QTextCharFormat chatFormat( cursor.blockCharFormat() );
0075             newCursor.setBlockCharFormat( chatFormat );
0076         }
0077     }
0078     return shape;
0079 }
0080 
0081 void KPrPlaceholderTextStrategy::paint( QPainter & painter, const KoViewConverter &converter, const QRectF & rect, KoShapePaintingContext &paintcontext)
0082 {
0083     if ( m_textShape ) {
0084         painter.save();
0085         m_textShape->setSize( rect.size() );
0086         // this code is needed to make sure the text of the textshape is layouted before it is painted
0087         KoTextShapeData * shapeData = qobject_cast<KoTextShapeData*>( m_textShape->userData() );
0088         QTextDocument * document = shapeData->document();
0089         KoTextDocumentLayout * lay = qobject_cast<KoTextDocumentLayout*>( document->documentLayout() );
0090         if ( lay ) {
0091             lay->layout();
0092         }
0093         m_textShape->paint( painter, converter, paintcontext);
0094 
0095         KoShape::applyConversion( painter, converter );
0096         QPen pen(Qt::gray, 0);
0097         //pen.setStyle( Qt::DashLine ); // endless loop
0098         painter.setPen( pen );
0099         painter.drawRect( rect );
0100         painter.restore();
0101     }
0102     else {
0103         KPrPlaceholderStrategy::paint( painter, converter, rect, paintcontext);
0104     }
0105 }
0106 
0107 void KPrPlaceholderTextStrategy::saveOdf( KoShapeSavingContext & context )
0108 {
0109     if (m_textShape) {
0110         KoTextShapeData *shapeData = qobject_cast<KoTextShapeData*>(m_textShape->userData());
0111         if (shapeData) {
0112             KoStyleManager *styleManager = KoTextDocument(shapeData->document()).styleManager();
0113             if (styleManager) {
0114                 QTextDocument *document = shapeData->document();
0115                 QTextBlock block = document->begin();
0116                 QString styleName = KoTextWriter::saveParagraphStyle(block, styleManager, context);
0117                 context.xmlWriter().addAttribute("draw:text-style-name", styleName);
0118             }
0119         }
0120     }
0121     KPrPlaceholderStrategy::saveOdf( context );
0122 }
0123 
0124 bool KPrPlaceholderTextStrategy::loadOdf( const KoXmlElement & element, KoShapeLoadingContext & context )
0125 {
0126     if (KoTextSharedLoadingData *textSharedData = dynamic_cast<KoTextSharedLoadingData *>(context.sharedData(KOTEXT_SHARED_LOADING_ID))) {
0127         KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("TextShapeID");
0128         Q_ASSERT(factory);
0129         if (!factory) {
0130             warnStage << "text shape factory not found";
0131             return false;
0132         }
0133         delete m_textShape;
0134         m_textShape = factory->createDefaultShape(context.documentResourceManager());
0135 
0136         KoTextShapeData *shapeData = qobject_cast<KoTextShapeData*>(m_textShape->userData());
0137         shapeData->document()->setUndoRedoEnabled(false);
0138 
0139         QTextDocument *document = shapeData->document();
0140         QTextCursor cursor(document);
0141         QTextBlock block = cursor.block();
0142 
0143         const QString styleName = element.attributeNS(KoXmlNS::presentation, "style-name");
0144         if (!styleName.isEmpty()) {
0145             const KoXmlElement *style = context.odfLoadingContext().stylesReader().findStyle(styleName, "presentation", context.odfLoadingContext().useStylesAutoStyles());
0146 
0147             if (style) {
0148                 KoParagraphStyle paragraphStyle;
0149                 paragraphStyle.loadOdf(style, context);
0150                 paragraphStyle.applyStyle(block, false); // TODO t.zachmann is the false correct?
0151             }
0152         }
0153 
0154         const QString textStyleName = element.attributeNS(KoXmlNS::draw, "text-style-name");
0155         if (!textStyleName.isEmpty()) {
0156             KoParagraphStyle *style = textSharedData->paragraphStyle(textStyleName, context.odfLoadingContext().useStylesAutoStyles());
0157             if (style) {
0158                 style->applyStyle(block, false); // TODO t.zachmann is the false correct?
0159             }
0160         }
0161 
0162         cursor.insertText(text());
0163         shapeData->setDirty();
0164         shapeData->document()->setUndoRedoEnabled(true);
0165     }
0166     return true;
0167 }
0168 
0169 void KPrPlaceholderTextStrategy::init(KoDocumentResourceManager *documentResources)
0170 {
0171     KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value( "TextShapeID" );
0172     Q_ASSERT( factory );
0173     if (!factory) {
0174         warnStage << "text shape factory not found";
0175         return;
0176     }
0177     KoProperties props;
0178     props.setProperty("text", text());
0179     delete m_textShape;
0180     m_textShape = factory->createShape(&props, documentResources);
0181 }
0182 
0183 KoShapeUserData * KPrPlaceholderTextStrategy::userData() const
0184 {
0185     return m_textShape ? m_textShape->userData() : 0;
0186 }