1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <svl/style.hxx>
21 #include <svl/itemset.hxx>
22 #include <svl/whiter.hxx>
23
24 #include <svx/svdoutl.hxx>
25 #include <editeng/xmlcnitm.hxx>
26 #include <svx/svdotext.hxx>
27 #include <svx/svdogrp.hxx>
28 #include <editeng/eeitem.hxx>
29 #include <editeng/lrspitem.hxx>
30 #include <editeng/outlobj.hxx>
31
32 #include <drawdoc.hxx>
33 #include "sdtransform.hxx"
34
35 using namespace ::com::sun::star::style;
36
37 class SdTransformOOo2xDocument
38 {
39 public:
40 explicit SdTransformOOo2xDocument( SdDrawDocument& rDocument );
41
42 void transform();
43
44 void transformMasterPages();
45 void transformDrawPages();
46
47 void transformStyles();
48 void transformStyles( SfxStyleFamily eFam );
49 void transformStyle( SfxStyleSheetBase& rSheet );
50
51 void transformShapes( SdrObjList const & rShapes );
52 void transformShape( SdrObject& rObj );
53
54 void transformTextShape( SdrTextObj& rTextShape );
55
56 bool getBulletState( const SfxItemSet& rSet, SfxStyleSheetBase* pSheet, bool& rState );
57 static bool getBulletState( const SfxItemSet& rSet, sal_uInt16 nWhich, bool& rState );
58
59 static bool transformItemSet( SfxItemSet& rSet, bool bNumbering );
60
61 static bool removeAlienAttributes( SfxItemSet& rSet );
62 static bool removeAlienAttributes( SfxItemSet& rSet, sal_uInt16 nWhich );
63
64 SdDrawDocument& mrDocument;
65 SdrOutliner& mrOutliner;
66 };
67
68 /** transforms the given model from OOo 2.x to OOo 3.x. This maps
69 the deprecated EE_PARA_BULLETSTATE and clears the EE_PARA_LRSPACE
70 if used together with a EE_PARA_NUMBULLET */
TransformOOo2xDocument(SdDrawDocument * pDocument)71 void TransformOOo2xDocument( SdDrawDocument* pDocument )
72 {
73 if( pDocument )
74 {
75 SdTransformOOo2xDocument aTransformer( *pDocument );
76 aTransformer.transform();
77 }
78 }
79
80 static const OUStringLiteral gsEnableNumbering( "enable-numbering" );
81 static const OUStringLiteral gsTextNamespace( "urn:oasis:names:tc:opendocument:xmlns:text:1.0" );
82 static const OUStringLiteral gsTrue( "true" );
83
SdTransformOOo2xDocument(SdDrawDocument & rDocument)84 SdTransformOOo2xDocument::SdTransformOOo2xDocument( SdDrawDocument& rDocument )
85 : mrDocument( rDocument )
86 , mrOutliner( rDocument.GetDrawOutliner() )
87 {
88 }
89
transform()90 void SdTransformOOo2xDocument::transform()
91 {
92 transformMasterPages();
93 transformDrawPages();
94 transformStyles();
95 }
96
transformMasterPages()97 void SdTransformOOo2xDocument::transformMasterPages()
98 {
99 sal_uInt16 nMasterPageCount = mrDocument.GetMasterPageCount();
100 for( sal_uInt16 nMasterPage = 0; nMasterPage < nMasterPageCount; nMasterPage++ )
101 {
102 SdrObjList* pPage = mrDocument.GetMasterPage( nMasterPage );
103 if( pPage )
104 transformShapes( *pPage );
105 }
106 }
107
transformDrawPages()108 void SdTransformOOo2xDocument::transformDrawPages()
109 {
110 sal_uInt16 nPageCount = mrDocument.GetPageCount();
111 for( sal_uInt16 nPage = 0; nPage < nPageCount; nPage++ )
112 {
113 SdrObjList* pPage = mrDocument.GetPage( nPage );
114 if( pPage )
115 transformShapes( *pPage );
116 }
117 }
118
transformStyles()119 void SdTransformOOo2xDocument::transformStyles()
120 {
121 transformStyles( SfxStyleFamily::Para );
122 transformStyles( SfxStyleFamily::Page );
123 }
124
transformStyles(SfxStyleFamily eFam)125 void SdTransformOOo2xDocument::transformStyles( SfxStyleFamily eFam )
126 {
127
128 rtl::Reference< SfxStyleSheetBasePool > xStyleSheetPool( mrDocument.GetStyleSheetPool() );
129
130 SfxStyleSheetIterator aIter( xStyleSheetPool.get(), eFam );
131
132 SfxStyleSheetBase* pSheet = aIter.First();
133 while( pSheet )
134 {
135 transformStyle( *pSheet );
136 pSheet = aIter.Next();
137 }
138 }
139
transformStyle(SfxStyleSheetBase & rSheet)140 void SdTransformOOo2xDocument::transformStyle( SfxStyleSheetBase& rSheet )
141 {
142 SfxItemSet& rSet = rSheet.GetItemSet();
143
144 bool bState = false;
145 getBulletState( rSheet.GetItemSet(), rSheet.GetPool()->Find( rSheet.GetParent(), rSheet.GetFamily() ), bState );
146
147 transformItemSet( rSet, bState );
148 removeAlienAttributes( rSet );
149 }
150
transformShapes(SdrObjList const & rShapes)151 void SdTransformOOo2xDocument::transformShapes( SdrObjList const & rShapes )
152 {
153 const size_t nShapeCount = rShapes.GetObjCount();
154 for( size_t nShape = 0; nShape < nShapeCount; ++nShape )
155 {
156 SdrObject* pObj = rShapes.GetObj( nShape );
157 if( pObj )
158 transformShape( *pObj );
159 }
160 }
161
transformShape(SdrObject & rObj)162 void SdTransformOOo2xDocument::transformShape( SdrObject& rObj )
163 {
164 SdrTextObj* pTextShape = dynamic_cast< SdrTextObj* >( &rObj );
165 if( pTextShape )
166 {
167 transformTextShape( *pTextShape );
168 return;
169 }
170
171 SdrObjGroup* pGroupShape = dynamic_cast< SdrObjGroup* >( &rObj );
172 if( pGroupShape )
173 {
174 SdrObjList* pObjList = pGroupShape->GetSubList();
175 if( pObjList )
176 transformShapes( *pObjList );
177 return;
178 }
179 }
180
transformTextShape(SdrTextObj & rTextShape)181 void SdTransformOOo2xDocument::transformTextShape( SdrTextObj& rTextShape )
182 {
183
184 if(rTextShape.IsEmptyPresObj())
185 return;
186
187 OutlinerParaObject* pOPO = rTextShape.GetOutlinerParaObject();
188 if (!pOPO)
189 return;
190
191 mrOutliner.SetText( *pOPO );
192
193 sal_Int32 nCount = mrOutliner.GetParagraphCount();
194
195 bool bChange = false;
196
197 for(sal_Int32 nPara = 0; nPara < nCount; nPara++)
198 {
199 SfxItemSet aParaSet( mrOutliner.GetParaAttribs( nPara ) );
200
201 bool bItemChange = false;
202
203 bool bState = false;
204 const sal_Int16 nDepth = mrOutliner.GetDepth( nPara );
205 if( (nDepth != -1) && (!getBulletState( aParaSet, mrOutliner.GetStyleSheet( nPara ), bState ) || !bState) )
206 {
207 // disable bullet if text::enable-bullet="false" is found
208 if( (nDepth > 0 ) && (rTextShape.GetObjInventor() == SdrInventor::Default) && (rTextShape.GetObjIdentifier() == OBJ_OUTLINETEXT) )
209 {
210 // for outline object and level > 0 burn in the style sheet because it will be changed to "outline 1"
211 SfxStyleSheet* pStyleSheet = mrOutliner.GetStyleSheet( nPara );
212
213 if( pStyleSheet )
214 {
215 // optimize me: only put items hard into paragraph that are not equal to "outline 1" style!
216 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
217
218 SfxWhichIter aIter(aParaSet);
219 sal_uInt16 nWhich(aIter.FirstWhich());
220
221 // now set all none hard attributes from the style
222 while(nWhich)
223 {
224 if(SfxItemState::SET != aParaSet.GetItemState(nWhich))
225 {
226 aParaSet.Put(rStyleSet.Get(nWhich));
227 bItemChange = true;
228 }
229
230 nWhich = aIter.NextWhich();
231 }
232 }
233 }
234
235 mrOutliner.SetDepth( mrOutliner.GetParagraph( nPara ), -1 );
236
237 bChange = true;
238 }
239
240 bItemChange |= transformItemSet( aParaSet, bState );
241
242 bItemChange |= removeAlienAttributes( aParaSet );
243
244 if( bItemChange )
245 {
246 mrOutliner.SetParaAttribs( nPara, aParaSet );
247 bChange = true;
248 }
249 }
250
251 if( bChange )
252 rTextShape.SetOutlinerParaObject(mrOutliner.CreateParaObject());
253
254 mrOutliner.Clear();
255 }
256
getBulletState(const SfxItemSet & rSet,SfxStyleSheetBase * pSheet,bool & rState)257 bool SdTransformOOo2xDocument::getBulletState( const SfxItemSet& rSet, SfxStyleSheetBase* pSheet, bool& rState )
258 {
259 if( getBulletState( rSet, EE_PARA_XMLATTRIBS, rState ) )
260 return true;
261
262 if( getBulletState( rSet, SDRATTR_XMLATTRIBUTES, rState ) )
263 return true;
264
265 if( pSheet && getBulletState( pSheet->GetItemSet(), pSheet->GetPool()->Find( pSheet->GetParent(), pSheet->GetFamily() ), rState ) )
266 return true;
267
268 return false;
269 }
270
getBulletState(const SfxItemSet & rSet,sal_uInt16 nWhich,bool & rState)271 bool SdTransformOOo2xDocument::getBulletState( const SfxItemSet& rSet, sal_uInt16 nWhich, bool& rState )
272 {
273 if( rSet.GetItemState( nWhich ) == SfxItemState::SET )
274 {
275 const SvXMLAttrContainerItem& rAttr = *rSet.GetItem<SvXMLAttrContainerItem>( nWhich );
276
277 const sal_uInt16 nCount = rAttr.GetAttrCount();
278 for( sal_uInt16 nItem = 0; nItem < nCount; nItem++ )
279 {
280 if( ( rAttr.GetAttrLName( nItem ) == gsEnableNumbering ) && ( rAttr.GetAttrNamespace( nItem ) == gsTextNamespace ) )
281 {
282 const OUString& sValue( rAttr.GetAttrValue( nItem ) );
283 rState = sValue == gsTrue;
284 return true;
285 }
286 }
287 }
288
289 return false;
290 }
291
transformItemSet(SfxItemSet & rSet,bool bNumbering)292 bool SdTransformOOo2xDocument::transformItemSet( SfxItemSet& rSet, bool bNumbering )
293 {
294 bool bRet = false;
295 if( bNumbering )
296 {
297 SvxLRSpaceItem aItem( *rSet.GetItem<SvxLRSpaceItem>( EE_PARA_LRSPACE ) );
298 if( (aItem.GetLeft() != 0) || (aItem.GetTextFirstLineOfst() != 0) )
299 {
300 aItem.SetLeftValue( 0 );
301 aItem.SetTextFirstLineOfst( 0 );
302 rSet.Put( aItem );
303 bRet = true;
304 }
305 }
306
307 return bRet;
308 }
309
removeAlienAttributes(SfxItemSet & rSet)310 bool SdTransformOOo2xDocument::removeAlienAttributes( SfxItemSet& rSet )
311 {
312 bool b = removeAlienAttributes( rSet, EE_PARA_XMLATTRIBS );
313 b |= removeAlienAttributes( rSet, SDRATTR_XMLATTRIBUTES );
314 return b;
315 }
316
removeAlienAttributes(SfxItemSet & rSet,sal_uInt16 nWhich)317 bool SdTransformOOo2xDocument::removeAlienAttributes( SfxItemSet& rSet, sal_uInt16 nWhich )
318 {
319 if( rSet.GetItemState( nWhich ) == SfxItemState::SET )
320 {
321 const SvXMLAttrContainerItem& rAttr = *rSet.GetItem<SvXMLAttrContainerItem>( nWhich );
322
323 const sal_uInt16 nCount = rAttr.GetAttrCount();
324 for( sal_uInt16 nItem = 0; nItem < nCount; nItem++ )
325 {
326 if( ( rAttr.GetAttrLName( nItem ) == gsEnableNumbering ) && ( rAttr.GetAttrNamespace( nItem ) == gsTextNamespace ) )
327 {
328 if( nCount == 1 )
329 {
330 rSet.ClearItem( nWhich );
331 }
332 else
333 {
334 SvXMLAttrContainerItem aNewItem( nWhich );
335
336 const sal_uInt16 nFound = nItem;
337 for( nItem = 0; nItem < nCount; nItem++ )
338 {
339 if( nItem != nFound )
340 {
341 OUString const& rNamespace(rAttr.GetAttrNamespace(nItem));
342 OUString const& rPrefix(rAttr.GetAttrPrefix(nItem));
343 if (rPrefix.isEmpty())
344 {
345 aNewItem.AddAttr(rAttr.GetAttrLName(nItem), rAttr.GetAttrValue(nItem));
346 }
347 else
348 {
349 aNewItem.AddAttr(rPrefix, rNamespace, rAttr.GetAttrLName(nItem), rAttr.GetAttrValue(nItem));
350 }
351 }
352 }
353
354 rSet.Put( aNewItem );
355 }
356 return true;
357 }
358 }
359 }
360 return false;
361 }
362
363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
364