summaryrefslogtreecommitdiff
path: root/sw/source/filter/xml/xmlimp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/xml/xmlimp.cxx')
-rw-r--r--sw/source/filter/xml/xmlimp.cxx246
1 files changed, 186 insertions, 60 deletions
diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx
index c3888f268902..c05f76160f66 100644
--- a/sw/source/filter/xml/xmlimp.cxx
+++ b/sw/source/filter/xml/xmlimp.cxx
@@ -35,6 +35,13 @@
#include <xmloff/XMLFontStylesContext.hxx>
#include <xmloff/ProgressBarHelper.hxx>
#include <doc.hxx>
+#include <drawdoc.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentListsAccess.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <IDocumentDrawModelAccess.hxx>
+#include <numrule.hxx>
#include <TextCursorHelper.hxx>
#include <unotext.hxx>
#include <unotextrange.hxx>
@@ -42,8 +49,12 @@
#include <poolfmt.hxx>
#include <ndtxt.hxx>
#include <editsh.hxx>
+#include <poolfmt.hrc>
+#include <svl/stritem.hxx>
#include "xmlimp.hxx"
#include "xmltexti.hxx"
+#include <list.hxx>
+#include <swdll.hxx>
#include <xmloff/DocumentSettingsContext.hxx>
#include <docsh.hxx>
#include <editeng/unolingu.hxx>
@@ -857,7 +868,7 @@ void SwXMLImport::endDocument( void )
// tdf#113877
// when we insert one document with list inside into another one with list at the insert position,
- // the resulting numbering in these lists are not consequent.
+ // the resulting numbering in these lists is not consequent.
//
// Main document:
// 1. One
@@ -880,65 +891,7 @@ void SwXMLImport::endDocument( void )
// 6. Three
// 7.
//
- if (IsInsertMode() && pSttNdIdx->GetIndex())
- {
- sal_uLong index = 1;
-
- // the last node of the main document where we have inserted a document
- SwNode * p1 = pDoc->GetNodes()[pSttNdIdx->GetIndex() + 0];
-
- // the first node of the inserted document
- SwNode * p2 = pDoc->GetNodes()[pSttNdIdx->GetIndex() + index];
-
- // the first node of the inserted document,
- // which will be used to detect if inside inserted document a new list was started
- const SfxPoolItem* listId2Initial = nullptr;
-
- while (
- p1 && p2
- && (p1->GetNodeType() == p2->GetNodeType())
- && (p1->IsTxtNode() == p2->IsTxtNode())
- )
- {
- SwCntntNode * c1 = static_cast<SwCntntNode *>(p1);
- SwCntntNode * c2 = static_cast<SwCntntNode *>(p2);
-
- const SfxPoolItem* listId1 = c1->GetNoCondAttr(RES_PARATR_LIST_ID, false);
- const SfxPoolItem* listId2 = c2->GetNoCondAttr(RES_PARATR_LIST_ID, false);
-
- if (!listId2Initial)
- {
- listId2Initial = listId2;
- }
-
- if (! (listId2Initial && listId2 && (*listId2Initial == *listId2)) )
- {
- // no more list items of the first list inside inserted document
- break;
- }
-
- if (listId1 && listId2)
- {
- c2->SetAttr(*listId1);
- }
- else
- {
- // no more appropriate list items
- break;
- }
-
- // get next item
- index++;
- if (index >= pDoc->GetNodes().Count())
- {
- // no more items
- break;
- }
-
- p2 = pDoc->GetNodes()[pSttNdIdx->GetIndex() + index];
- }
- }
-
+ MergeListsAtDocumentInsertPosition(pDoc);
}
}
@@ -1010,6 +963,179 @@ void SwXMLImport::endDocument( void )
ClearTextImport();
}
+// tdf#113877
+// when we insert one document with list inside into another one with list at the insert position,
+// the resulting numbering in these lists is not consequent.
+//
+// CASE-1: Main document:
+// 1. One
+// 2. Two
+// 3. Three
+// 4. <-- insert position
+//
+// Inserted document:
+// 1. One
+// 2. Two
+// 3. Three
+// 4.
+//
+// Expected result
+// 1. One
+// 2. Two
+// 3. Three
+// 4. One
+// 5. Two
+// 6. Three
+// 7.
+//
+// CASE-2: Main document:
+// 1. One
+// 2. Two
+// 3. Three
+// 4. <-- insert position
+//
+// Inserted document:
+// A) One
+// B) Two
+// C) Three
+// D)
+//
+// Expected result
+// 1. One
+// 2. Two
+// 3. Three
+// 4. One
+// A) Two
+// B) Three
+// 5.
+//
+void SwXMLImport::MergeListsAtDocumentInsertPosition(SwDoc *pDoc)
+{
+ // 1. check enviroment
+ if (! pDoc)
+ return;
+
+ if (! IsInsertMode() || ! pSttNdIdx->GetIndex())
+ return;
+
+ sal_uLong index = 1;
+
+ // the last node of the main document where we have inserted a document
+ const SwNodePtr node1 = pDoc->GetNodes()[pSttNdIdx->GetIndex() + 0];
+
+ // the first node of the inserted document
+ SwNodePtr node2 = pDoc->GetNodes()[pSttNdIdx->GetIndex() + index];
+
+ if (! (node1 && node2
+ && (node1->GetNodeType() == node2->GetNodeType())
+ && (node1->IsTxtNode() == node2->IsTxtNode())
+ ))
+ {
+ // not a text node at insert position
+ return;
+ }
+
+ // 2. get the first node of the inserted document,
+ // which will be used to detect if inside inserted document a new list was started after the first list
+ const SfxPoolItem* pListId2Initial = nullptr;
+ {
+ SwCntntNode* contentNode1 = static_cast<SwCntntNode *>(node1);
+ SwCntntNode* contentNode2 = static_cast<SwCntntNode *>(node2);
+
+ // check if both lists have the same list properties
+ const SfxPoolItem* pListId1 = contentNode1->GetNoCondAttr( RES_PARATR_LIST_ID, false );
+ const SfxPoolItem* pListId2 = contentNode2->GetNoCondAttr( RES_PARATR_LIST_ID, false );
+
+ if (! pListId1)
+ return;
+ if (! pListId2)
+ return;
+
+ const OUString& sListId1 = dynamic_cast<const SfxStringItem*>(pListId1)->GetValue();
+ const OUString& sListId2 = dynamic_cast<const SfxStringItem*>(pListId2)->GetValue();
+
+ const SwList* pList1 = pDoc->getListByName( sListId1 );
+ const SwList* pList2 = pDoc->getListByName( sListId2 );
+
+ if (! pList1)
+ return;
+ if (! pList2)
+ return;
+
+ const OUString& sDefaultListStyleName1 = pList1->GetDefaultListStyleName();
+ const OUString& sDefaultListStyleName2 = pList2->GetDefaultListStyleName();
+
+ if (sDefaultListStyleName1 != sDefaultListStyleName2)
+ {
+ const SwNumRule* pNumRule1 = pDoc->FindNumRulePtr( sDefaultListStyleName1 );
+ const SwNumRule* pNumRule2 = pDoc->FindNumRulePtr( sDefaultListStyleName2 );
+
+ if (pNumRule1 && pNumRule2)
+ {
+ // check style of the each list level
+ for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
+ {
+ if( !( pNumRule1->Get( n ) == pNumRule2->Get( n ) ))
+ {
+ return;
+ }
+ }
+
+ // our list should be merged
+ pListId2Initial = pListId2;
+ }
+ }
+ else
+ {
+ // our list should be merged
+ pListId2Initial = pListId2;
+ }
+ }
+
+ if (! pListId2Initial)
+ {
+ // two lists have different styles => they should not be merged
+ return;
+ }
+
+ // 3. merge two lists
+ while (
+ node1 && node2
+ && (node1->GetNodeType() == node2->GetNodeType())
+ && (node1->IsTxtNode() == node2->IsTxtNode())
+ )
+ {
+ SwCntntNode* contentNode1 = static_cast<SwCntntNode *>( node1 );
+ SwCntntNode* contentNode2 = static_cast<SwCntntNode *>( node2 );
+
+ const SfxPoolItem* pListId1 = contentNode1->GetNoCondAttr( RES_PARATR_LIST_ID, false );
+ const SfxPoolItem* pListId2 = contentNode2->GetNoCondAttr( RES_PARATR_LIST_ID, false );
+
+ if (! pListId1)
+ return;
+ if (! pListId2)
+ return;
+
+ if (*pListId2Initial != *pListId2)
+ {
+ // no more list items of the first list inside inserted document
+ return;
+ }
+
+ // set list style to this list element
+ contentNode2->SetAttr(*pListId1);
+
+ // get next item
+ index++;
+ if (index >= pDoc->GetNodes().Count())
+ {
+ // no more items
+ return;
+ }
+
+ node2 = pDoc->GetNodes()[pSttNdIdx->GetIndex() + index];
+ }
+}
// Locally derive XMLTextShapeImportHelper, so we can take care of the
// form import This is Writer, but not text specific, so it should go