[prev in list] [next in list] [prev in thread] [next in thread] 

List:       koffice-devel
Subject:    [review] kword odfwriter
From:       Thomas Zander <zander () kde ! org>
Date:       2009-04-05 12:49:22
Message-ID: 200904051449.26458.zander () kde ! org
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


Please review for the 2.0 branch

New code to fix saving of shapes to ODf which lead to invalid ODF in some 
cases.

See attached
-- 
Thomas Zander

["0001-Fixes-Saving-ODF-z-indexes-requires-them-to-be-nonN.patch" (text/x-diff)]

From ebac086656f365a48e20592b59e705fae7cd25f7 Mon Sep 17 00:00:00 2001
From: Thomas Zander <zander@kde.org>
Date: Sun, 5 Apr 2009 14:37:56 +0200
Subject: [PATCH] Fixes: Saving ODF z-indexes requires them to be nonNegative
 Details: We rebase the shapes per page to adjust the zindexes during saving.

---
 kword/part/KWOdfWriter.cpp |   49 +++++++++++++++++++++++++++++++++++++++----
 kword/part/KWOdfWriter.h   |   10 +++++++++
 2 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/kword/part/KWOdfWriter.cpp b/kword/part/KWOdfWriter.cpp
index 3ac7434..3316728 100644
--- a/kword/part/KWOdfWriter.cpp
+++ b/kword/part/KWOdfWriter.cpp
@@ -33,6 +33,8 @@
 #include <KoTextShapeData.h>
 #include <KoStyleManager.h>
 #include <KoParagraphStyle.h>
+#include <KoShapeGroup.h>
+#include <KoShapeLayer.h>
 
 #include <QBuffer>
 #include <QTextCursor>
@@ -143,7 +145,8 @@ void KWOdfWriter::saveHeaderFooter(KoEmbeddedDocumentSaver& \
embeddedSaver, KoGen  
 KWOdfWriter::KWOdfWriter(KWDocument *document)
         : QObject(),
-        m_document(document)
+        m_document(document),
+        m_shapeTree(4,2)
 {
 }
 
@@ -181,6 +184,8 @@ bool KWOdfWriter::save(KoOdfWriteStore & odfStore, \
KoEmbeddedDocumentSaver & emb  bodyWriter->startElement("office:body");
     bodyWriter->startElement("office:text");
 
+    calculateZindexOffsets();
+
     KWTextFrameSet *mainTextFrame = 0;
 
     foreach (KWFrameSet *fs, m_document->frameSets()) {
@@ -284,12 +289,13 @@ bool KWOdfWriter::save(KoOdfWriteStore & odfStore, \
KoEmbeddedDocumentSaver & emb  }
 
             // shape properties
-            int pageNumber = m_document->pageManager()->pageNumber(shape);
-            const qreal pagePos = m_document->pageManager()->topOfPage(pageNumber);
+            KWPage page = m_document->pageManager()->page(shape);
+            const qreal pagePos = page.offsetInDocument();
 
-            shape->setAdditionalAttribute("draw:z-index", \
QString::number(shape->zIndex())); +            const int effectiveZIndex = \
shape->zIndex() + m_zIndexOffsets.value(page); +            \
shape->setAdditionalAttribute("draw:z-index", QString::number(effectiveZIndex));  \
                shape->setAdditionalAttribute("text:anchor-type", "page");
-            shape->setAdditionalAttribute("text:anchor-page-number", \
QString::number(pageNumber)); +            \
shape->setAdditionalAttribute("text:anchor-page-number", \
                QString::number(page.pageNumber()));
             context.addShapeOffset(shape, QMatrix(1, 0, 0 , 1, 0, -pagePos ));
             shape->saveOdf(context);
             context.removeShapeOffset(shape);
@@ -350,3 +356,36 @@ bool KWOdfWriter::save(KoOdfWriteStore & odfStore, \
KoEmbeddedDocumentSaver & emb  return true;
 }
 
+void KWOdfWriter::calculateZindexOffsets()
+{
+    Q_ASSERT(m_zIndexOffsets.isEmpty()); // call this method only once, please.
+    foreach (KWFrameSet *fs, m_document->frameSets()) {
+        if (KWord::isAutoGenerated(dynamic_cast<KWTextFrameSet*>(fs)))
+            continue;
+        foreach (KWFrame *frame, fs->frames()) {
+            addShapeToTree(frame->shape());
+        }
+    }
+
+    foreach (const KWPage &page, m_document->pageManager()->pages()) {
+        int minZIndex = 0;
+        foreach (KoShape *shape, m_shapeTree.intersects(page.rect()))
+            minZIndex = qMin(shape->zIndex(), minZIndex);
+        m_zIndexOffsets.insert(page, -minZIndex);
+    }
+}
+
+void KWOdfWriter::addShapeToTree(KoShape *shape)
+{
+    if (! dynamic_cast<KoShapeGroup*>(shape) && ! \
dynamic_cast<KoShapeLayer*>(shape)) +        \
m_shapeTree.insert(shape->boundingRect(), shape); +
+    // add the children of a KoShapeContainer
+    KoShapeContainer* container = dynamic_cast<KoShapeContainer*>(shape);
+    if (container) {
+        foreach(KoShape* containerShape, container->iterator()) {
+            addShapeToTree(containerShape);
+        }
+    }
+
+}
diff --git a/kword/part/KWOdfWriter.h b/kword/part/KWOdfWriter.h
index 2ab9d47..9d39969 100644
--- a/kword/part/KWOdfWriter.h
+++ b/kword/part/KWOdfWriter.h
@@ -26,11 +26,14 @@
 
 #include "KWPageStyle.h"
 
+#include <KoRTree.h>
+
 class KWDocument;
 class KoOdfWriteStore;
 class KoEmbeddedDocumentSaver;
 class KoGenStyles;
 class KWTextFrameSet;
+class KWPage;
 
 /**
  * Class that has a lot of the OpenDocument (ODF) saving code for KWord.
@@ -61,9 +64,16 @@ private:
     QByteArray serializeHeaderFooter(KoEmbeddedDocumentSaver& embeddedSaver, \
                KoGenStyles& mainStyles, KWTextFrameSet* fs);
     void saveHeaderFooter(KoEmbeddedDocumentSaver& embeddedSaver, KoGenStyles& \
mainStyles);  
+    void calculateZindexOffsets();
+    void addShapeToTree(KoShape *shape);
+
     /// The KWord document.
     KWDocument *m_document;
     QHash<KWPageStyle, QString> masterPages;
+    /// Since ODF requires zindexes >= 0 and we can have negative ones we will \
calculate an offset per +    /// page and store that here.
+    QHash<KWPage, int> m_zIndexOffsets;
+    KoRTree<KoShape *> m_shapeTree;
 };
 
 #endif
-- 
1.5.6.5


["signature.asc" (application/pgp-signature)]

_______________________________________________
koffice-devel mailing list
koffice-devel@kde.org
https://mail.kde.org/mailman/listinfo/koffice-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic