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