xref: /aoo41x/main/xmloff/source/text/txtsecte.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #ifndef _XMLOFF_TXTPARAE_HXX
32 #include <xmloff/txtparae.hxx>
33 #endif
34 #include <tools/debug.hxx>
35 #include <rtl/ustring.hxx>
36 #include <rtl/ustrbuf.hxx>
37 
38 #include <vector>
39 
40 
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <com/sun/star/container/XIndexReplace.hpp>
43 
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #include <com/sun/star/beans/PropertyValue.hpp>
46 #include <com/sun/star/beans/PropertyValues.hpp>
47 #include <com/sun/star/beans/PropertyState.hpp>
48 #include <com/sun/star/text/XText.hpp>
49 #include <com/sun/star/text/XTextSection.hpp>
50 #include <com/sun/star/text/SectionFileLink.hpp>
51 #include <com/sun/star/container/XNamed.hpp>
52 #include <com/sun/star/text/XDocumentIndex.hpp>
53 #include "xmloff/xmlnmspe.hxx"
54 #include <xmloff/families.hxx>
55 #include <xmloff/xmluconv.hxx>
56 #include <xmloff/nmspmap.hxx>
57 #include <xmloff/xmlexp.hxx>
58 #include <xmloff/xmltkmap.hxx>
59 #include "XMLTextNumRuleInfo.hxx"
60 #include "XMLSectionExport.hxx"
61 #include "XMLRedlineExport.hxx"
62 #ifndef _XMLOFF_MULTIPROPERTYSETHELPER_HXX
63 #include "MultiPropertySetHelper.hxx"
64 #endif
65 
66 using namespace ::com::sun::star;
67 using namespace ::com::sun::star::text;
68 using namespace ::com::sun::star::uno;
69 using namespace ::std;
70 
71 using ::rtl::OUString;
72 using ::rtl::OUStringBuffer;
73 using ::com::sun::star::beans::XPropertySet;
74 using ::com::sun::star::beans::PropertyValue;
75 using ::com::sun::star::beans::PropertyValues;
76 using ::com::sun::star::beans::PropertyState;
77 using ::com::sun::star::container::XIndexReplace;
78 using ::com::sun::star::container::XNamed;
79 using ::com::sun::star::lang::XServiceInfo;
80 
81 Reference<XText> lcl_findXText(const Reference<XTextSection>& rSect)
82 {
83 	Reference<XText> xText;
84 
85 	Reference<XTextContent> xTextContent(rSect, UNO_QUERY);
86 	if (xTextContent.is())
87 	{
88 		xText.set(xTextContent->getAnchor()->getText());
89 	}
90 
91 	return xText;
92 }
93 
94 void XMLTextParagraphExport::exportListAndSectionChange(
95 	Reference<XTextSection> & rPrevSection,
96 	const Reference<XTextContent> & rNextSectionContent,
97 	const XMLTextNumRuleInfo& rPrevRule,
98 	const XMLTextNumRuleInfo& rNextRule,
99 	sal_Bool bAutoStyles)
100 {
101 	Reference<XTextSection> xNextSection;
102 
103 	// first: get current XTextSection
104 	Reference<XPropertySet> xPropSet(rNextSectionContent, UNO_QUERY);
105 	if (xPropSet.is())
106 	{
107 		if (xPropSet->getPropertySetInfo()->hasPropertyByName(sTextSection))
108 		{
109 			xPropSet->getPropertyValue(sTextSection) >>= xNextSection;
110 		}
111 		// else: no current section
112 	}
113 
114 	exportListAndSectionChange(rPrevSection, xNextSection,
115 							   rPrevRule, rNextRule, bAutoStyles);
116 }
117 
118 void XMLTextParagraphExport::exportListAndSectionChange(
119 	Reference<XTextSection> & rPrevSection,
120 	MultiPropertySetHelper& rPropSetHelper,
121 	sal_Int16 nTextSectionId,
122 	const Reference<XTextContent> & rNextSectionContent,
123 	const XMLTextNumRuleInfo& rPrevRule,
124 	const XMLTextNumRuleInfo& rNextRule,
125 	sal_Bool bAutoStyles)
126 {
127 	Reference<XTextSection> xNextSection;
128 
129 	// first: get current XTextSection
130 	Reference<XPropertySet> xPropSet(rNextSectionContent, UNO_QUERY);
131 	if (xPropSet.is())
132 	{
133 		if( !rPropSetHelper.checkedProperties() )
134 			rPropSetHelper.hasProperties( xPropSet->getPropertySetInfo() );
135 		if( rPropSetHelper.hasProperty( nTextSectionId ))
136 		{
137 			xNextSection.set(rPropSetHelper.getValue( nTextSectionId , xPropSet,
138                 sal_True ), uno::UNO_QUERY);
139 		}
140 		// else: no current section
141 	}
142 
143 	exportListAndSectionChange(rPrevSection, xNextSection,
144 							   rPrevRule, rNextRule, bAutoStyles);
145 }
146 
147 void XMLTextParagraphExport::exportListAndSectionChange(
148 	Reference<XTextSection> & rPrevSection,
149 	const Reference<XTextSection> & rNextSection,
150 	const XMLTextNumRuleInfo& rPrevRule,
151 	const XMLTextNumRuleInfo& rNextRule,
152 	sal_Bool bAutoStyles)
153 {
154 	// old != new? -> maybe we have to start or end a new section
155 	if (rPrevSection != rNextSection)
156 	{
157 		// a new section started, or an old one gets closed!
158 
159 		// close old list
160         XMLTextNumRuleInfo aEmptyNumRuleInfo;
161 		if ( !bAutoStyles )
162             exportListChange(rPrevRule, aEmptyNumRuleInfo);
163 
164 		// Build stacks of old and new sections
165 		// Sections on top of mute sections should not be on the stack
166         vector< Reference<XTextSection> > aOldStack;
167 		Reference<XTextSection> aCurrent(rPrevSection);
168 		while(aCurrent.is())
169 		{
170 			// if we have a mute section, ignore all its children
171 			// (all previous ones)
172 			if (pSectionExport->IsMuteSection(aCurrent))
173 				aOldStack.clear();
174 
175 			aOldStack.push_back(aCurrent);
176 			aCurrent.set(aCurrent->getParentSection());
177 		}
178 
179         vector< Reference<XTextSection> > aNewStack;
180 		aCurrent.set(rNextSection);
181 		sal_Bool bMute = sal_False;
182 		while(aCurrent.is())
183 		{
184 			// if we have a mute section, ignore all its children
185 			// (all previous ones)
186 			if (pSectionExport->IsMuteSection(aCurrent))
187 			{
188 				aNewStack.clear();
189 				bMute = sal_True;
190 			}
191 
192 			aNewStack.push_back(aCurrent);
193 			aCurrent.set(aCurrent->getParentSection());
194 		}
195 
196 		// compare the two stacks
197 		vector<Reference<XTextSection> > ::reverse_iterator aOld =
198 			aOldStack.rbegin();
199 		vector<Reference<XTextSection> > ::reverse_iterator aNew =
200 			aNewStack.rbegin();
201 		// compare bottom sections and skip equal section
202 		while ( (aOld != aOldStack.rend()) &&
203 				(aNew != aNewStack.rend()) &&
204 				(*aOld) == (*aNew) )
205 		{
206 			++aOld;
207 			++aNew;
208 		}
209 
210 		// close all elements of aOld ...
211 		// (order: newest to oldest)
212 		if (aOld != aOldStack.rend())
213 		{
214 			vector<Reference<XTextSection> > ::iterator aOldForward(
215 				aOldStack.begin());
216 			while ((aOldForward != aOldStack.end()) &&
217 				   (*aOldForward != *aOld))
218 			{
219 				if ( !bAutoStyles && (NULL != pRedlineExport) )
220 					pRedlineExport->ExportStartOrEndRedline(*aOldForward,
221 																sal_False);
222 				pSectionExport->ExportSectionEnd(*aOldForward, bAutoStyles);
223 				++aOldForward;
224 			}
225 			if (aOldForward != aOldStack.end())
226 			{
227 				if ( !bAutoStyles && (NULL != pRedlineExport) )
228 					pRedlineExport->ExportStartOrEndRedline(*aOldForward,
229 															sal_False);
230 				pSectionExport->ExportSectionEnd(*aOldForward, bAutoStyles);
231 			}
232 		}
233 
234 		// ...then open all of aNew
235 		// (order: oldest to newest)
236 		while (aNew != aNewStack.rend())
237 		{
238             if ( !bAutoStyles && (NULL != pRedlineExport) )
239 				pRedlineExport->ExportStartOrEndRedline(*aNew, sal_True);
240 			pSectionExport->ExportSectionStart(*aNew, bAutoStyles);
241 			++aNew;
242 		}
243 
244 		// start new list
245 		if ( !bAutoStyles && !bMute )
246             exportListChange(aEmptyNumRuleInfo, rNextRule);
247 	}
248 	else
249 	{
250 		// list change, if sections have not changed
251 		if ( !bAutoStyles )
252 			exportListChange(rPrevRule, rNextRule);
253 	}
254 
255 	// save old section (old numRule gets saved in calling method)
256 	rPrevSection.set(rNextSection);
257 }
258 
259