[Libreoffice-commits] .: 5 commits - offapi/com sw/inc sw/qa sw/source xmloff/inc xmloff/source

Miklos Vajna vmiklos at kemper.freedesktop.org
Fri Jul 20 06:20:57 PDT 2012


 offapi/com/sun/star/text/textfield/Annotation.idl |    5 +
 sw/inc/docufld.hxx                                |    7 +-
 sw/qa/core/swdoc-test.cxx                         |    2 
 sw/source/core/crsr/bookmrk.cxx                   |   37 ++++++++++++
 sw/source/core/doc/docbm.cxx                      |    5 +
 sw/source/core/fields/docufld.cxx                 |   24 ++++++--
 sw/source/core/inc/bookmrk.hxx                    |    1 
 sw/source/core/unocore/unofield.cxx               |   16 ++++-
 sw/source/core/unocore/unomap.cxx                 |    1 
 sw/source/core/unocore/unoportenum.cxx            |   31 ++++++++++
 sw/source/filter/html/htmlfld.cxx                 |    2 
 sw/source/filter/html/swhtml.cxx                  |    2 
 sw/source/filter/ww8/ww8par.cxx                   |    2 
 sw/source/ui/fldui/fldmgr.cxx                     |    2 
 sw/source/ui/wrtsh/wrtsh2.cxx                     |    3 -
 xmloff/inc/txtfldi.hxx                            |    6 ++
 xmloff/inc/xmloff/txtimp.hxx                      |    2 
 xmloff/inc/xmloff/xmltoken.hxx                    |    1 
 xmloff/source/core/xmltoken.cxx                   |    1 
 xmloff/source/text/txtflde.cxx                    |    4 +
 xmloff/source/text/txtfldi.cxx                    |   66 ++++++++++++++++++++--
 xmloff/source/text/txtimp.cxx                     |    2 
 xmloff/source/text/txtparae.cxx                   |   34 ++++++++++-
 23 files changed, 232 insertions(+), 24 deletions(-)

New commits:
commit 2fe8ce572222e90327cfeed6b7da07a2c57bdbbb
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Jul 20 14:41:23 2012 +0200

    SwXTextField::attachToRange: don't generate new fieldmark id on each import
    
    Change-Id: If7256136cde91279ad8b684da1b7bf1666bd1dba

diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index d06ec8c..1b14610 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -92,6 +92,7 @@
 #include <docsh.hxx>
 #include <fmtmeta.hxx> // MetaFieldManager
 #include <switerator.hxx>
+#include <bookmrk.hxx>
 #include <rtl/strbuf.hxx>
 #include <vector>
 #include <xmloff/odffields.hxx>
@@ -1760,7 +1761,17 @@ void SwXTextField::attachToRange(
                         aPam,
                         OUString(),
                         ODF_COMMENTRANGE);
-                ((SwPostItField*)aFmt.GetFld())->SetName(pFieldmark->GetName());
+                SwPostItField* pPostItField = (SwPostItField*)aFmt.GetFld();
+                if (pPostItField->GetName().isEmpty())
+                    // The fieldmark always has a (generated) name.
+                    pPostItField->SetName(pFieldmark->GetName());
+                else
+                {
+                    // The field has a name already, use it.
+                    sw::mark::MarkBase* pMarkBase = dynamic_cast<sw::mark::MarkBase*>(pFieldmark);
+                    if (pMarkBase)
+                        pMarkBase->SetName(pPostItField->GetName());
+                }
 
                 // Make sure we always insert the field at the end
                 SwPaM aEnd(*aPam.End(), *aPam.End());
commit d4b473dd9ba77427b28d97847067b8877c2033d9
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Jul 20 14:27:07 2012 +0200

    office:annotation-end import
    
    Change-Id: I8d1475b5bc9a36dade5ce28e74139834c69f8e14

diff --git a/xmloff/inc/txtfldi.hxx b/xmloff/inc/txtfldi.hxx
index 7c0e6e6..b2483de 100644
--- a/xmloff/inc/txtfldi.hxx
+++ b/xmloff/inc/txtfldi.hxx
@@ -1345,15 +1345,20 @@ class XMLAnnotationImportContext : public XMLTextFieldImportContext
     const ::rtl::OUString sPropertyContent;
     const ::rtl::OUString sPropertyDate;
     const ::rtl::OUString sPropertyTextRange;
+    const ::rtl::OUString sPropertyName;
 
     ::rtl::OUStringBuffer aAuthorBuffer;
     ::rtl::OUStringBuffer aInitialsBuffer;
+    OUString aName;
     ::rtl::OUStringBuffer aTextBuffer;
     ::rtl::OUStringBuffer aDateBuffer;
 
     com::sun::star::uno::Reference < com::sun::star::beans::XPropertySet > mxField;
     com::sun::star::uno::Reference < com::sun::star::text::XTextCursor >  mxCursor;
     com::sun::star::uno::Reference < com::sun::star::text::XTextCursor >  mxOldCursor;
+    /// If this is an annotation end, then position of the start.
+    com::sun::star::uno::Reference < com::sun::star::text::XTextContent >  m_xStart;
+    sal_uInt16 m_nToken;
 
 public:
 
@@ -1361,6 +1366,7 @@ public:
 
     XMLAnnotationImportContext(SvXMLImport& rImport,
                                XMLTextImportHelper& rHlp,
+                               sal_uInt16 nToken,
                                sal_uInt16 nPrfx,
                                const ::rtl::OUString& sLocalName);
 
diff --git a/xmloff/inc/xmloff/txtimp.hxx b/xmloff/inc/xmloff/txtimp.hxx
index f01c0ec..d4a1156 100644
--- a/xmloff/inc/xmloff/txtimp.hxx
+++ b/xmloff/inc/xmloff/txtimp.hxx
@@ -221,6 +221,8 @@ enum XMLTextPElemTokens
     XML_TOK_TEXT_SHEET_NAME,
     XML_TOK_TEXT_BIBLIOGRAPHY_MARK,
     XML_TOK_TEXT_ANNOTATION,
+    XML_TOK_TEXT_ANNOTATION_END,
+    XML_TOK_TEXT_NAME,
     XML_TOK_TEXT_SCRIPT,
     XML_TOK_TEXT_TABLE_FORMULA,
     XML_TOK_TEXT_DROPDOWN,
diff --git a/xmloff/source/text/txtfldi.cxx b/xmloff/source/text/txtfldi.cxx
index 9425b79..0e8057b 100644
--- a/xmloff/source/text/txtfldi.cxx
+++ b/xmloff/source/text/txtfldi.cxx
@@ -567,7 +567,9 @@ XMLTextFieldImportContext::CreateTextFieldImportContext(
             break;
 
         case XML_TOK_TEXT_ANNOTATION:
+        case XML_TOK_TEXT_ANNOTATION_END:
             pContext = new XMLAnnotationImportContext( rImport, rHlp,
+                                                       nToken,
                                                        nPrefix, rName);
             break;
 
@@ -3629,6 +3631,7 @@ TYPEINIT1(XMLAnnotationImportContext, XMLTextFieldImportContext);
 XMLAnnotationImportContext::XMLAnnotationImportContext(
     SvXMLImport& rImport,
     XMLTextImportHelper& rHlp,
+    sal_uInt16 nToken,
     sal_uInt16 nPrfx,
     const OUString& sLocalName) :
         XMLTextFieldImportContext(rImport, rHlp, sAPI_annotation,
@@ -3638,7 +3641,9 @@ XMLAnnotationImportContext::XMLAnnotationImportContext(
         sPropertyContent(sAPI_content),
         // why is there no UNO_NAME_DATE_TIME, but only UNO_NAME_DATE_TIME_VALUE?
         sPropertyDate(sAPI_date_time_value),
-        sPropertyTextRange(sAPI_TextRange)
+        sPropertyTextRange(sAPI_TextRange),
+        sPropertyName(sAPI_name),
+        m_nToken(nToken)
 {
     bValid = sal_True;
 
@@ -3649,10 +3654,11 @@ XMLAnnotationImportContext::XMLAnnotationImportContext(
 }
 
 void XMLAnnotationImportContext::ProcessAttribute(
-    sal_uInt16,
-    const OUString& )
+    sal_uInt16 nToken,
+    const OUString& rValue )
 {
-    // ignore
+    if (nToken == XML_TOK_TEXT_NAME)
+        aName = rValue;
 }
 
 SvXMLImportContext* XMLAnnotationImportContext::CreateChildContext(
@@ -3747,7 +3753,21 @@ void XMLAnnotationImportContext::EndElement()
             // workaround for #80606#
             try
             {
-                GetImportHelper().InsertTextContent( xTextContent );
+                if (m_nToken == XML_TOK_TEXT_ANNOTATION_END && m_xStart.is())
+                {
+                    // So we are ending a previous annotation, let's create a
+                    // text range covering the old and the current position.
+                    uno::Reference<text::XText> xText = GetImportHelper().GetText();
+                    uno::Reference<text::XTextCursor> xCursor = xText->createTextCursorByRange(m_xStart->getAnchor());
+                    xCursor->gotoRange(GetImportHelper().GetCursorAsRange(), true);
+                    uno::Reference<text::XTextRange> xTextRange(xCursor, uno::UNO_QUERY);
+                    xText->insertTextContent(xTextRange, xTextContent, !xCursor->isCollapsed());
+
+                    // Now we can delete the old annotation with the incorrect position.
+                    uno::Reference<lang::XComponent>(m_xStart, uno::UNO_QUERY)->dispose();
+                }
+                else
+                    GetImportHelper().InsertTextContent( xTextContent );
             }
             catch (const lang::IllegalArgumentException&)
             {
@@ -3762,6 +3782,39 @@ void XMLAnnotationImportContext::EndElement()
 void XMLAnnotationImportContext::PrepareField(
     const Reference<XPropertySet> & xPropertySet)
 {
+    if (m_nToken == XML_TOK_TEXT_ANNOTATION_END && !aName.isEmpty())
+    {
+        // Search for a previous annotation with the same name.
+        Reference<XTextFieldsSupplier> xTextFieldsSupplier(GetImport().GetModel(), UNO_QUERY);
+        uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
+        uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+        uno::Reference<beans::XPropertySet> xPrevField;
+        while (xFields->hasMoreElements())
+        {
+            uno::Reference<beans::XPropertySet> xCurrField(xFields->nextElement(), uno::UNO_QUERY);
+            OUString aFieldName;
+            xCurrField->getPropertyValue(sPropertyName) >>= aFieldName;
+            if (aFieldName == aName)
+            {
+                xPrevField = xCurrField;
+                break;
+            }
+        }
+        if (xPrevField.is())
+        {
+            // Found? Then copy over the properties.
+            xPropertySet->setPropertyValue(sPropertyAuthor, xPrevField->getPropertyValue(sPropertyAuthor));
+            xPropertySet->setPropertyValue(sPropertyInitials, xPrevField->getPropertyValue(sPropertyInitials));
+            xPropertySet->setPropertyValue(sPropertyDate, xPrevField->getPropertyValue(sPropertyDate));
+            xPropertySet->setPropertyValue(sPropertyName, xPrevField->getPropertyValue(sPropertyName));
+            xPropertySet->setPropertyValue(sPropertyContent, xPrevField->getPropertyValue(sPropertyContent));
+
+            // And save a reference to it, so we can delete it later.
+            m_xStart.set(xPrevField, uno::UNO_QUERY);
+            return;
+        }
+    }
+
     // import (possibly empty) author
     OUString sAuthor( aAuthorBuffer.makeStringAndClear() );
     xPropertySet->setPropertyValue(sPropertyAuthor, makeAny(sAuthor));
@@ -3792,6 +3845,9 @@ void XMLAnnotationImportContext::PrepareField(
             sBuffer = sBuffer.copy(0, sBuffer.getLength()-1);
         xPropertySet->setPropertyValue(sPropertyContent, makeAny(sBuffer));
     }
+
+    if (!aName.isEmpty())
+        xPropertySet->setPropertyValue(sPropertyName, makeAny(aName));
 }
 
 
diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx
index e751058..7b2deda 100644
--- a/xmloff/source/text/txtimp.cxx
+++ b/xmloff/source/text/txtimp.cxx
@@ -271,6 +271,7 @@ static SvXMLTokenMapEntry aTextPElemTokenMap[] =
     { XML_NAMESPACE_TEXT, XML_BIBLIOGRAPHY_MARK,
       XML_TOK_TEXT_BIBLIOGRAPHY_MARK },
     { XML_NAMESPACE_OFFICE, XML_ANNOTATION, XML_TOK_TEXT_ANNOTATION },
+    { XML_NAMESPACE_OFFICE, XML_ANNOTATION_END, XML_TOK_TEXT_ANNOTATION_END },
     { XML_NAMESPACE_TEXT, XML_SCRIPT, XML_TOK_TEXT_SCRIPT },
     { XML_NAMESPACE_TEXT, XML_TABLE_FORMULA, XML_TOK_TEXT_TABLE_FORMULA },
     { XML_NAMESPACE_TEXT, XML_DROPDOWN, XML_TOK_TEXT_DROPDOWN },
@@ -488,6 +489,7 @@ static SvXMLTokenMapEntry aTextFieldAttrTokenMap[] =
     { XML_NAMESPACE_TEXT, XML_CURRENT_VALUE,
                 XML_TOK_TEXTFIELD_CURRENT_VALUE },
     { XML_NAMESPACE_TEXT, XML_TABLE_TYPE, XML_TOK_TEXTFIELD_TABLE_TYPE },
+    { XML_NAMESPACE_OFFICE, XML_NAME, XML_TOK_TEXT_NAME },
 
     XML_TOKEN_MAP_END
 };
commit 8d9991c97a3e9574d7424aa3d295e5b6b2830bda
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Thu Jul 19 12:49:37 2012 +0200

    TextFieldmark::ReleaseDoc: properly remove text fieldmarks from SwDoc
    
    Change-Id: I7b11cf78f106807561be77c51641796319aaf636

diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 7e15633..75f58ca 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -98,6 +98,38 @@ namespace
         }
         io_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_UI_REPLACE, NULL);
     };
+
+    static void lcl_RemoveFieldMarks(Fieldmark* const pField,
+        SwDoc* const io_pDoc,
+        const sal_Unicode aStartMark,
+        const sal_Unicode aEndMark)
+    {
+        SwPosition& rStart = pField->GetMarkStart();
+        SwPosition& rEnd = pField->GetMarkEnd();
+        SwTxtNode const*const pStartTxtNode =
+            rStart.nNode.GetNode().GetTxtNode();
+        SwTxtNode const*const pEndTxtNode = rEnd.nNode.GetNode().GetTxtNode();
+        const sal_Unicode ch_start=pStartTxtNode->GetTxt().GetChar(rStart.nContent.GetIndex());
+        xub_StrLen nEndPos = ( rEnd == rStart ||  rEnd.nContent.GetIndex() == 0 ) ?
+            rEnd.nContent.GetIndex() : rEnd.nContent.GetIndex() - 1;
+        const sal_Unicode ch_end=pEndTxtNode->GetTxt().GetChar( nEndPos );
+        SwPaM aStartPaM(rStart);
+        SwPaM aEndPaM(rEnd);
+        io_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_UI_REPLACE, NULL);
+        if( ch_start == aStartMark )
+        {
+            SwPaM aStart(rStart, rStart);
+            aStart.End()->nContent++;
+            io_pDoc->DeleteRange(aStart);
+        }
+        if ( ch_end == aEndMark )
+        {
+            SwPaM aEnd(rEnd, rEnd);
+            aEnd.Start()->nContent--;
+            io_pDoc->DeleteRange(aEnd);
+        }
+        io_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_UI_REPLACE, NULL);
+    };
 }
 
 namespace sw { namespace mark
@@ -316,6 +348,11 @@ namespace sw { namespace mark
         lcl_AssureFieldMarksSet(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
     }
 
+    void TextFieldmark::ReleaseDoc(SwDoc* const pDoc)
+    {
+        lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
+    }
+
     CheckboxFieldmark::CheckboxFieldmark(const SwPaM& rPaM)
         : Fieldmark(rPaM)
     { }
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index a00e075..cfc8629 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -593,7 +593,7 @@ namespace sw { namespace mark
                 isPosInRange = true, isOtherPosInRange = true;
             }
 
-            if(isPosInRange && (isOtherPosInRange || !pMark->IsExpanded()))
+            if(isPosInRange && (isOtherPosInRange || !pMark->IsExpanded() || IDocumentMarkAccess::GetType(*pMark) == TEXT_FIELDMARK))
             {
                 // completely in range
 
@@ -697,6 +697,9 @@ namespace sw { namespace mark
                     "<MarkManager::deleteMark(..)>"
                     " - Bookmark not found.");
                 m_vFieldmarks.erase(ppFieldmark);
+                sw::mark::TextFieldmark* pTextFieldmark = dynamic_cast<sw::mark::TextFieldmark*>(ppMark->get());
+                if (pTextFieldmark)
+                    pTextFieldmark->ReleaseDoc(m_pDoc);
                 break;
             }
             case IDocumentMarkAccess::NAVIGATOR_REMINDER:
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 9739a99..bbbb2ff 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -237,6 +237,7 @@ namespace sw {
         public:
             TextFieldmark(const SwPaM& rPaM);
             virtual void InitDoc(SwDoc* const io_pDoc);
+            void ReleaseDoc(SwDoc* const pDoc);
         };
 
         class CheckboxFieldmark
commit 672ca6077ff9f65f29e0d7521149595f4eaf7a63
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Fri Jul 20 15:05:04 2012 +0200

    office:annotation-end export
    
    Change-Id: Idd815f2d10e67ae9cf91f06b6b4c92a0ebe2e856

diff --git a/xmloff/inc/xmloff/xmltoken.hxx b/xmloff/inc/xmloff/xmltoken.hxx
index 73dcd95..c4113ca 100644
--- a/xmloff/inc/xmloff/xmltoken.hxx
+++ b/xmloff/inc/xmloff/xmltoken.hxx
@@ -244,6 +244,7 @@ namespace xmloff { namespace token {
         XML_ANIMATION_STOP_INSIDE,
         XML_ANIMATIONS,
         XML_ANNOTATION,
+        XML_ANNOTATION_END,
         XML_ANNOTATIONS,
         XML_ANNOTE,
         XML_APPEAR,
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 14c3fb1..f7d8f28 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -248,6 +248,7 @@ namespace xmloff { namespace token {
         TOKEN( "animation-stop-inside",           XML_ANIMATION_STOP_INSIDE ),
         TOKEN( "animations",                      XML_ANIMATIONS ),
         TOKEN( "annotation",                      XML_ANNOTATION ),
+        TOKEN( "annotation-end",                  XML_ANNOTATION_END ),
         TOKEN( "annotations",                     XML_ANNOTATIONS ),
         TOKEN( "annote",                          XML_ANNOTE ),
         TOKEN( "appear",                          XML_APPEAR ),
diff --git a/xmloff/source/text/txtflde.cxx b/xmloff/source/text/txtflde.cxx
index bc78c34..c649b97 100644
--- a/xmloff/source/text/txtflde.cxx
+++ b/xmloff/source/text/txtflde.cxx
@@ -1737,6 +1737,10 @@ void XMLTextFieldExport::ExportFieldHelper(
                    "Unexpected presentation for annotation field");
 
         // annotation element + content
+        OUString aName;
+        rPropSet->getPropertyValue(sPropertyName) >>= aName;
+        if (!aName.isEmpty())
+            GetExport().AddAttribute(XML_NAMESPACE_OFFICE, XML_NAME, aName);
         SvXMLElementExport aElem(GetExport(), XML_NAMESPACE_OFFICE,
                                  XML_ANNOTATION, sal_False, sal_True);
 
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index 04b008c..392f491 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -2181,6 +2181,7 @@ void XMLTextParagraphExport::exportTextRangeEnumeration(
 {
     static OUString sMeta("InContentMetadata");
     bool bPrevCharIsSpace = bPrvChrIsSpc;
+    bool bAnnotationStarted = false;
 
     /* This is  used for exporting to strict OpenDocument 1.2, in which case traditional
      * bookmarks are used instead of fieldmarks. */
@@ -2204,8 +2205,15 @@ void XMLTextParagraphExport::exportTextRangeEnumeration(
             }
             else if( sType.equals(sTextField))
             {
-                exportTextField( xTxtRange, bAutoStyles, bIsProgress );
-                bPrevCharIsSpace = false;
+                if (bAnnotationStarted)
+                {
+                    bAnnotationStarted = false;
+                }
+                else
+                {
+                    exportTextField( xTxtRange, bAutoStyles, bIsProgress );
+                    bPrevCharIsSpace = false;
+                }
             }
             else if( sType.equals( sFrame ) )
             {
@@ -2265,6 +2273,14 @@ void XMLTextParagraphExport::exportTextRangeEnumeration(
             }
             else if (sType.equals(sTextFieldStart))
             {
+                Reference< ::com::sun::star::text::XFormField > xFormField(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
+                if (xFormField->getFieldType() == ODF_COMMENTRANGE)
+                {
+                    exportTextField( xTxtRange, bAutoStyles, bIsProgress );
+                    bAnnotationStarted = true;
+                    continue;
+                }
+
                 /* As of now, textmarks are a proposed extension to the OpenDocument standard. */
                 if ( GetExport().getDefaultVersion() > SvtSaveOptions::ODFVER_012 )
                 {
@@ -2273,7 +2289,6 @@ void XMLTextParagraphExport::exportTextRangeEnumeration(
                     {
                         GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xBookmark->getName());
                     }
-                    Reference< ::com::sun::star::text::XFormField > xFormField(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
                     if (xFormField.is())
                     {
                         GetExport().AddAttribute(XML_NAMESPACE_FIELD, XML_TYPE, xFormField->getFieldType());
@@ -2288,7 +2303,6 @@ void XMLTextParagraphExport::exportTextRangeEnumeration(
                 /* The OpenDocument standard does not include support for TextMarks for now, so use bookmarks instead. */
                 else
                 {
-                    Reference< ::com::sun::star::text::XFormField > xFormField(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
                     if (xFormField.is())
                     {
                         Reference< ::com::sun::star::container::XNameAccess > xParameters(xFormField->getParameters(), UNO_QUERY);
@@ -2322,6 +2336,18 @@ void XMLTextParagraphExport::exportTextRangeEnumeration(
             }
             else if (sType.equals(sTextFieldEnd))
             {
+                if (bAnnotationStarted)
+                {
+                    Reference<XNamed> xBookmark(xPropSet->getPropertyValue(sBookmark), UNO_QUERY);
+                    const OUString& rName = xBookmark->getName();
+                    if (!rName.isEmpty())
+                        GetExport().AddAttribute(XML_NAMESPACE_OFFICE, XML_NAME, rName);
+                    SvXMLElementExport aElem( GetExport(), !bAutoStyles,
+                        XML_NAMESPACE_OFFICE, XML_ANNOTATION_END,
+                        sal_False, sal_False );
+                    continue;
+                }
+
                 if ( GetExport().getDefaultVersion() > SvtSaveOptions::ODFVER_012 )
                 {
                     SvXMLElementExport aElem( GetExport(), !bAutoStyles,
commit b11e923a50ca532016fc0802e1d2dfa53efa0679
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Thu Jul 19 13:28:30 2012 +0200

    SwPostItField: add aName member
    
    To handle roundtrip of office:name in ODF.
    
    Change-Id: I35dab189f7b9b8191ca92c647332e2271d4806f9

diff --git a/offapi/com/sun/star/text/textfield/Annotation.idl b/offapi/com/sun/star/text/textfield/Annotation.idl
index db9d7e2..d214324 100644
--- a/offapi/com/sun/star/text/textfield/Annotation.idl
+++ b/offapi/com/sun/star/text/textfield/Annotation.idl
@@ -43,6 +43,11 @@ published service Annotation
         @since LibreOffice 3.7
      */
     [optional, property]string Initials;
+    /** contains the name of the annotation.
+
+        @since LibreOffice 3.7
+     */
+    [optional, property]string Name;
     /** contains the annotation's content
      */
     [property]string Content;
diff --git a/sw/inc/docufld.hxx b/sw/inc/docufld.hxx
index a16aabe..b62b2f6 100644
--- a/sw/inc/docufld.hxx
+++ b/sw/inc/docufld.hxx
@@ -520,14 +520,15 @@ class SW_DLLPUBLIC SwPostItField : public SwField
 {
     rtl::OUString sTxt;
     rtl::OUString sAuthor;
-    rtl::OUString sInitials;
+    rtl::OUString sInitials; ///< Initials of the author.
+    rtl::OUString sName; ///< Name of the comment.
     DateTime    aDateTime;
     OutlinerParaObject* mpText;
     SwTextAPIObject* m_pTextObject;
 
 public:
     SwPostItField( SwPostItFieldType*,
-                   const String& rAuthor, const String& rTxt, const String& rInitials, const DateTime& rDate);
+                   const String& rAuthor, const String& rTxt, const String& rInitials, const String& rName, const DateTime& rDate);
     ~SwPostItField();
 
     virtual String          Expand() const;
@@ -546,6 +547,8 @@ public:
     virtual void            SetPar2(const rtl::OUString& rStr);
     const rtl::OUString&    GetTxt() const { return sTxt; }
     const rtl::OUString&    GetInitials() const;
+    void                    SetName(const rtl::OUString& rStr);
+    const OUString&         GetName() const;
 
     const OutlinerParaObject*   GetTextObject() const;
     void SetTextObject( OutlinerParaObject* pText );
diff --git a/sw/qa/core/swdoc-test.cxx b/sw/qa/core/swdoc-test.cxx
index f76cad3..ae49266 100644
--- a/sw/qa/core/swdoc-test.cxx
+++ b/sw/qa/core/swdoc-test.cxx
@@ -376,7 +376,7 @@ void SwDocTest::testSwScanner()
         DateTime aDate(DateTime::SYSTEM);
         SwPostItField aPostIt(
             (SwPostItFieldType*)m_pDoc->GetSysFldType(RES_POSTITFLD), rtl::OUString("An Author"),
-            rtl::OUString("Some Text"), rtl::OUString("WhatEver"), aDate );
+            rtl::OUString("Some Text"), rtl::OUString("Initials"), OUString("Name"), aDate );
         m_pDoc->InsertPoolItem(aPaM, SwFmtFld(aPostIt), 0);
 
         m_pDoc->InsertString(aPaM, rtl::OUString("Apple"));
diff --git a/sw/source/core/fields/docufld.cxx b/sw/source/core/fields/docufld.cxx
index 7a22990..75e824c 100644
--- a/sw/source/core/fields/docufld.cxx
+++ b/sw/source/core/fields/docufld.cxx
@@ -1735,8 +1735,8 @@ SwFieldType* SwPostItFieldType::Copy() const
  --------------------------------------------------------------------*/
 
 SwPostItField::SwPostItField( SwPostItFieldType* pT,
-        const String& rAuthor, const String& rTxt, const String& rInitials, const DateTime& rDateTime )
-    : SwField( pT ), sTxt( rTxt ), sAuthor( rAuthor ), sInitials( rInitials ), aDateTime( rDateTime ), mpText(0), m_pTextObject(0)
+        const String& rAuthor, const String& rTxt, const String& rInitials, const String& rName, const DateTime& rDateTime )
+    : SwField( pT ), sTxt( rTxt ), sAuthor( rAuthor ), sInitials( rInitials ), sName( rName ), aDateTime( rDateTime ), mpText(0), m_pTextObject(0)
 {
 }
 
@@ -1765,8 +1765,8 @@ String SwPostItField::GetDescription() const
 
 SwField* SwPostItField::Copy() const
 {
-    SwPostItField* pRet = new SwPostItField( (SwPostItFieldType*)GetTyp(), sAuthor, sInitials,
-                                sTxt, aDateTime);
+    SwPostItField* pRet = new SwPostItField( (SwPostItFieldType*)GetTyp(), sAuthor, sTxt, sInitials, sName,
+                                aDateTime);
     if (mpText)
         pRet->SetTextObject( new OutlinerParaObject(*mpText) );
     return pRet;
@@ -1804,6 +1804,16 @@ const rtl::OUString& SwPostItField::GetInitials() const
     return sInitials;
 }
 
+void SwPostItField::SetName(const rtl::OUString& rName)
+{
+    sName = rName;
+}
+
+const rtl::OUString& SwPostItField::GetName() const
+{
+    return sName;
+}
+
 const OutlinerParaObject* SwPostItField::GetTextObject() const
 {
     return mpText;
@@ -1835,6 +1845,9 @@ bool SwPostItField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
     case FIELD_PROP_PAR3:
         rAny <<= OUString(sInitials);
         break;
+    case FIELD_PROP_PAR4:
+        rAny <<= OUString(sName);
+        break;
     case FIELD_PROP_TEXT:
         {
             if ( !m_pTextObject )
@@ -1902,6 +1915,9 @@ bool SwPostItField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
     case FIELD_PROP_PAR3:
         rAny >>= sInitials;
         break;
+    case FIELD_PROP_PAR4:
+        rAny >>= sName;
+        break;
     case FIELD_PROP_TEXT:
         OSL_FAIL("Not implemented!");
         break;
diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index 7793e09..d06ec8c 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -1246,7 +1246,7 @@ void SwXTextField::attachToRange(
                     aDateTime.SetSec(m_pProps->pDateTime->Seconds);
                 }
                 pFld = new SwPostItField((SwPostItFieldType*)pFldType,
-                        m_pProps->sPar1, m_pProps->sPar2, m_pProps->sPar3, aDateTime);
+                        m_pProps->sPar1, m_pProps->sPar2, m_pProps->sPar3, m_pProps->sPar4, aDateTime);
                 if ( m_pTextObject )
                 {
                     ((SwPostItField*)pFld)->SetTextObject( m_pTextObject->CreateText() );
@@ -1756,10 +1756,11 @@ void SwXTextField::attachToRange(
             if (*aPam.GetPoint() != *aPam.GetMark() && m_nServiceId == SW_SERVICE_FIELDTYPE_ANNOTATION)
             {
                 IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess();
-                pMarksAccess->makeFieldBookmark(
+                sw::mark::IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark(
                         aPam,
                         OUString(),
                         ODF_COMMENTRANGE);
+                ((SwPostItField*)aFmt.GetFld())->SetName(pFieldmark->GetName());
 
                 // Make sure we always insert the field at the end
                 SwPaM aEnd(*aPam.End(), *aPam.End());
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
index 25e5dd3..35a7900 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -1863,6 +1863,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s
                     {SW_PROP_NMID(UNO_NAME_AUTHOR), FIELD_PROP_PAR1,    CPPU_E2T(CPPUTYPE_OUSTRING),   PROPERTY_NONE, 0},
                     {SW_PROP_NMID(UNO_NAME_CONTENT),    FIELD_PROP_PAR2,    CPPU_E2T(CPPUTYPE_OUSTRING),   PROPERTY_NONE, 0},
                     {SW_PROP_NMID(UNO_NAME_INITIALS),   FIELD_PROP_PAR3,    CPPU_E2T(CPPUTYPE_OUSTRING),   PROPERTY_NONE, 0},
+                    {SW_PROP_NMID(UNO_NAME_NAME),       FIELD_PROP_PAR4,    CPPU_E2T(CPPUTYPE_OUSTRING),   PROPERTY_NONE, 0},
                     {SW_PROP_NMID(UNO_NAME_DATE_TIME_VALUE),    FIELD_PROP_DATE_TIME,   CPPU_E2T(CPPUTYPE_DATETIME),    PROPERTY_NONE, 0},
                     {SW_PROP_NMID(UNO_NAME_DATE),    FIELD_PROP_DATE,   CPPU_E2T(CPPUTYPE_DATE),    PROPERTY_NONE, 0},
                     {SW_PROP_NMID(UNO_NAME_TEXT_RANGE), FIELD_PROP_TEXT, CPPU_E2T(CPPUTYPE_REFINTERFACE),  PropertyAttribute::READONLY,    0},
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index fdfe3c6..ed9ef38 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -54,6 +54,9 @@
 #include <unoidx.hxx>
 #include <redline.hxx>
 #include <crsskip.hxx>
+#include <switerator.hxx>
+#include <docufld.hxx>
+#include <fmtfld.hxx>
 #include <osl/mutex.hxx>
 #include <vcl/svapp.hxx>
 #include <comphelper/servicehelper.hxx>
@@ -326,6 +329,27 @@ lcl_FillFieldMarkArray(FieldMarks_t & rFieldMarks, SwUnoCrsr const & rUnoCrsr,
     }
 }
 
+static const SwFmtFld* lcl_getFieldByName(SwDoc* pDoc, const OUString& rName)
+{
+    const SwFldTypes* pFldTypes = pDoc->GetFldTypes();
+    sal_uInt16 nCount = pFldTypes->size();
+    for (sal_uInt16 nType = 0; nType < nCount; ++nType)
+    {
+        const SwFieldType *pCurType = (*pFldTypes)[nType];
+        SwIterator<SwFmtFld, SwFieldType> aIter(*pCurType);
+        for (const SwFmtFld* pCurFldFmt = aIter.First(); pCurFldFmt; pCurFldFmt = aIter.Next())
+        {
+            if (pCurFldFmt->GetFld()->GetTyp()->Which() != RES_POSTITFLD)
+                continue;
+
+            const SwPostItField* pField = dynamic_cast<const SwPostItField*>(pCurFldFmt->GetFld());
+            if (pField->GetName() == rName)
+                return pCurFldFmt;
+        }
+    }
+    return 0;
+}
+
 static uno::Reference<text::XTextRange>
 lcl_ExportFieldMark(
         uno::Reference< text::XText > const & i_xParentText,
@@ -359,7 +383,14 @@ lcl_ExportFieldMark(
             pUnoCrsr, i_xParentText, PORTION_FIELD_START);
         xRef = pPortion;
         if (pPortion && pFieldmark && pDoc)
+        {
             pPortion->SetBookmark( SwXFieldmark::CreateXFieldmark( *pDoc, *pFieldmark ) );
+            Reference<XTextField> xField;
+            const SwFmtFld* pField = lcl_getFieldByName(pDoc, pFieldmark->GetName());
+            if (pField)
+                xField = SwXTextField::CreateSwXTextField(*pDoc, *pField);
+            pPortion->SetTextField(xField);
+        }
     }
     else if (CH_TXT_ATR_FIELDEND == Char)
     {
diff --git a/sw/source/filter/html/htmlfld.cxx b/sw/source/filter/html/htmlfld.cxx
index 46f1bc9..f33b797 100644
--- a/sw/source/filter/html/htmlfld.cxx
+++ b/sw/source/filter/html/htmlfld.cxx
@@ -656,7 +656,7 @@ void SwHTMLParser::InsertComment( const String& rComment, const sal_Char *pTag )
 
     SwPostItField aPostItFld(
                     (SwPostItFieldType*)pDoc->GetSysFldType( RES_POSTITFLD ),
-                    aEmptyStr, aComment, aEmptyStr, DateTime( DateTime::SYSTEM ) );
+                    aEmptyStr, aComment, aEmptyStr, aEmptyStr, DateTime( DateTime::SYSTEM ) );
     InsertAttr( SwFmtFld( aPostItFld ) );
 
     if( bMoveFwd )
diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx
index 5f10021..18850d5 100644
--- a/sw/source/filter/html/swhtml.cxx
+++ b/sw/source/filter/html/swhtml.cxx
@@ -5388,7 +5388,7 @@ void SwHTMLParser::ParseMoreMetaOptions()
 
     SwPostItField aPostItFld(
         (SwPostItFieldType*)pDoc->GetSysFldType( RES_POSTITFLD ),
-        aEmptyStr, sText.makeStringAndClear(), aEmptyStr, DateTime( DateTime::SYSTEM ) );
+        aEmptyStr, sText.makeStringAndClear(), aEmptyStr, aEmptyStr, DateTime( DateTime::SYSTEM ) );
     SwFmtFld aFmtFld( aPostItFld );
     InsertAttr( aFmtFld );
 }
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 6acf843..54118d3 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -1792,7 +1792,7 @@ long SwWW8ImplReader::Read_And(WW8PLCFManResult* pRes)
     this->pFmtOfJustInsertedApo = 0;
     SwPostItField aPostIt(
         (SwPostItFieldType*)rDoc.GetSysFldType(RES_POSTITFLD), sAuthor,
-        sTxt, aEmptyStr, aDate );
+        sTxt, aEmptyStr, aEmptyStr, aDate );
     aPostIt.SetTextObject(pOutliner);
 
     pCtrlStck->NewAttr(*pPaM->GetPoint(), SvxCharHiddenItem(false, RES_CHRATR_HIDDEN));
diff --git a/sw/source/ui/fldui/fldmgr.cxx b/sw/source/ui/fldui/fldmgr.cxx
index ed483c1..3312a6a 100644
--- a/sw/source/ui/fldui/fldmgr.cxx
+++ b/sw/source/ui/fldui/fldmgr.cxx
@@ -870,7 +870,7 @@ sal_Bool SwFldMgr::InsertFld(  const SwInsertFld_Data& rData, SwPaM *pPam )
         case TYP_POSTITFLD:
         {
             SwPostItFieldType* pType = (SwPostItFieldType*)pCurShell->GetFldType(0, RES_POSTITFLD);
-            pFld = new SwPostItField(pType, rData.sPar1, rData.sPar2, aEmptyStr, DateTime( DateTime::SYSTEM ));
+            pFld = new SwPostItField(pType, rData.sPar1, rData.sPar2, aEmptyStr, aEmptyStr, DateTime( DateTime::SYSTEM ));
             break;
         }
         case TYP_SCRIPTFLD:
diff --git a/sw/source/ui/wrtsh/wrtsh2.cxx b/sw/source/ui/wrtsh/wrtsh2.cxx
index f6dda8c..17f2c8c 100644
--- a/sw/source/ui/wrtsh/wrtsh2.cxx
+++ b/sw/source/ui/wrtsh/wrtsh2.cxx
@@ -90,7 +90,8 @@ void SwWrtShell::Insert(SwField &rFld, SwPaM *pCommentRange)
     {
         // If an annotation field is inserted, take care of the relevant fieldmark.
         IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess();
-        pMarksAccess->makeFieldBookmark(*pCommentRange, OUString(), ODF_COMMENTRANGE);
+        sw::mark::IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark(*pCommentRange, OUString(), ODF_COMMENTRANGE);
+        ((SwPostItField&)rFld).SetName(pFieldmark->GetName());
     }
 
     bool bDeleted = false;


More information about the Libreoffice-commits mailing list