Line data Source code
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 "eschesdo.hxx"
21 : #include <svx/svdobj.hxx>
22 : #include <svx/unoapi.hxx>
23 : #include <svx/svdoashp.hxx>
24 : #include <svx/unoshape.hxx>
25 : #include <vcl/outdev.hxx>
26 : #include <tools/poly.hxx>
27 : #include <vcl/bitmapex.hxx>
28 : #include <vcl/graph.hxx>
29 : #include <tools/debug.hxx>
30 : #include <svx/fmdpage.hxx>
31 : #include <toolkit/unohlp.hxx>
32 : #include <com/sun/star/style/VerticalAlignment.hpp>
33 : #include <com/sun/star/awt/Gradient.hpp>
34 : #include <com/sun/star/drawing/PointSequence.hpp>
35 : #include <com/sun/star/drawing/PointSequenceSequence.hpp>
36 : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
37 : #include <com/sun/star/drawing/FlagSequence.hpp>
38 : #include <com/sun/star/drawing/TextAdjust.hpp>
39 : #include <com/sun/star/drawing/LineDash.hpp>
40 : #include <com/sun/star/text/XText.hpp>
41 : #include <com/sun/star/drawing/CircleKind.hpp>
42 : #include <com/sun/star/drawing/FillStyle.hpp>
43 : #include <com/sun/star/task/XStatusIndicator.hpp>
44 : #include <comphelper/extract.hxx>
45 : #include <svtools/fltcall.hxx>
46 : #include <vcl/cvtgrf.hxx>
47 :
48 : using ::rtl::OUString;
49 : using namespace ::com::sun::star;
50 : using namespace ::com::sun::star::beans;
51 : using namespace ::com::sun::star::container;
52 : using namespace ::com::sun::star::uno;
53 : using namespace ::com::sun::star::drawing;
54 : using namespace ::com::sun::star::text;
55 : using namespace ::com::sun::star::task;
56 : using namespace ::com::sun::star::style;
57 :
58 : #define EES_MAP_FRACTION 1440 // 1440 dpi
59 :
60 54 : ImplEESdrWriter::ImplEESdrWriter( EscherEx& rEx )
61 : :
62 : mpEscherEx ( &rEx ),
63 : maMapModeSrc ( MAP_100TH_MM ),
64 : // PowerPoint: 576 dpi, WinWord: 1440 dpi, Excel: 1440 dpi
65 : maMapModeDest( MAP_INCH, Point(), Fraction( 1, EES_MAP_FRACTION ), Fraction( 1, EES_MAP_FRACTION ) ),
66 : mpPicStrm ( NULL ),
67 : mpHostAppData ( NULL ),
68 : mnPagesWritten ( 0 ),
69 : mnShapeMasterTitle ( 0 ),
70 : mnShapeMasterBody ( 0 ),
71 : mbStatusIndicator ( sal_False ),
72 54 : mbStatus ( sal_False )
73 : {
74 54 : }
75 :
76 :
77 1 : Point ImplEESdrWriter::ImplMapPoint( const Point& rPoint )
78 : {
79 1 : return OutputDevice::LogicToLogic( rPoint, maMapModeSrc, maMapModeDest );
80 : }
81 :
82 1 : Size ImplEESdrWriter::ImplMapSize( const Size& rSize )
83 : {
84 1 : Size aRetSize( OutputDevice::LogicToLogic( rSize, maMapModeSrc, maMapModeDest ) );
85 :
86 1 : if ( !aRetSize.Width() )
87 0 : aRetSize.Width()++;
88 1 : if ( !aRetSize.Height() )
89 0 : aRetSize.Height()++;
90 1 : return aRetSize;
91 : }
92 :
93 0 : void ImplEESdrWriter::ImplFlipBoundingBox( ImplEESdrObject& rObj, EscherPropertyContainer& rPropOpt )
94 : {
95 0 : sal_Int32 nAngle = rObj.GetAngle();
96 0 : Rectangle aRect( rObj.GetRect() );
97 :
98 0 : if ( nAngle < 0 )
99 0 : nAngle = ( 36000 + nAngle ) % 36000;
100 : else
101 0 : nAngle = ( 36000 - ( nAngle % 36000 ) );
102 :
103 0 : double fVal = (double)nAngle * F_PI18000;
104 0 : double fCos = cos( fVal );
105 0 : double fSin = sin( fVal );
106 :
107 0 : double nWidthHalf = (double) aRect.GetWidth() / 2;
108 0 : double nHeightHalf = (double) aRect.GetHeight() / 2;
109 :
110 0 : double nXDiff = fCos * nWidthHalf + fSin * (-nHeightHalf);
111 0 : double nYDiff = - ( fSin * nWidthHalf - fCos * ( -nHeightHalf ) );
112 :
113 0 : aRect.Move( (sal_Int32)( -( nWidthHalf - nXDiff ) ), (sal_Int32)( - ( nHeightHalf + nYDiff ) ) );
114 :
115 0 : nAngle *= 655;
116 0 : nAngle += 0x8000;
117 0 : nAngle &=~0xffff; // nAngle auf volle Gradzahl runden
118 0 : rPropOpt.AddOpt( ESCHER_Prop_Rotation, nAngle );
119 :
120 0 : rObj.SetAngle( nAngle );
121 0 : rObj.SetRect( aRect );
122 0 : }
123 :
124 : // -----------------------------------------------------------------------
125 :
126 : #define ADD_SHAPE( nType, nFlags ) \
127 : { \
128 : nShapeType = nType; \
129 : nShapeID = mpEscherEx->GenerateShapeId(); \
130 : rObj.SetShapeId( nShapeID ); \
131 : mpEscherEx->AddShape( (sal_uInt32)nType, (sal_uInt32)nFlags, nShapeID ); \
132 : rSolverContainer.AddShape( rObj.GetShapeRef(), nShapeID ); \
133 : }
134 :
135 : #define SHAPE_TEXT( bFill ) \
136 : { \
137 : mpEscherEx->OpenContainer( ESCHER_SpContainer ); \
138 : ADD_SHAPE( ESCHER_ShpInst_TextBox, 0xa00 ); \
139 : if ( bFill ) \
140 : aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True ); \
141 : if( rObj.ImplGetText() ) \
142 : aPropOpt.CreateTextProperties( rObj.mXPropSet, \
143 : mpEscherEx->QueryTextID( rObj.GetShapeRef(), \
144 : rObj.GetShapeId() ) ); \
145 : }
146 :
147 : //Map from twips to export units, generally twips as well, only excel and word
148 : //export is happening here, so native units are export units, leave as
149 : //placeholder if required in future
150 0 : void ImplEESdrWriter::MapRect(ImplEESdrObject& /* rObj */ )
151 : {
152 0 : }
153 :
154 1 : sal_uInt32 ImplEESdrWriter::ImplWriteShape( ImplEESdrObject& rObj,
155 : EscherSolverContainer& rSolverContainer,
156 : ImplEESdrPageType ePageType )
157 : {
158 1 : sal_uInt32 nShapeID = 0;
159 1 : sal_uInt16 nShapeType = 0;
160 1 : sal_Bool bDontWriteText = sal_False; // if a metafile is written as shape replacement, then the text is already part of the metafile
161 1 : sal_Bool bAdditionalText = sal_False;
162 1 : sal_uInt32 nGrpShapeID = 0;
163 :
164 : do {
165 1 : mpHostAppData = mpEscherEx->StartShape( rObj.GetShapeRef(), (mpEscherEx->GetGroupLevel() > 1) ? &rObj.GetRect() : 0 );
166 1 : if ( mpHostAppData && mpHostAppData->DontWriteShape() )
167 : break;
168 :
169 : // #i51348# get shape name
170 1 : rtl::OUString aShapeName;
171 1 : if( const SdrObject* pSdrObj = rObj.GetSdrObject() )
172 1 : if (!pSdrObj->GetName().isEmpty())
173 0 : aShapeName = pSdrObj->GetName();
174 :
175 1 : Point aTextRefPoint;
176 :
177 1 : if( rObj.GetType().EqualsAscii( "drawing.Group" ))
178 : {
179 0 : Reference< XIndexAccess > xXIndexAccess( rObj.GetShapeRef(), UNO_QUERY );
180 :
181 0 : if( xXIndexAccess.is() && 0 != xXIndexAccess->getCount() )
182 : {
183 0 : nShapeID = mpEscherEx->EnterGroup( aShapeName, &rObj.GetRect() );
184 0 : nShapeType = ESCHER_ShpInst_Min;
185 :
186 0 : for( sal_uInt32 n = 0, nCnt = xXIndexAccess->getCount();
187 : n < nCnt; ++n )
188 : {
189 : ImplEESdrObject aObj( *this, *(Reference< XShape >*)
190 0 : xXIndexAccess->getByIndex( n ).getValue() );
191 0 : if( aObj.IsValid() )
192 0 : ImplWriteShape( aObj, rSolverContainer, ePageType );
193 0 : }
194 0 : mpEscherEx->LeaveGroup();
195 : }
196 0 : break;
197 : }
198 1 : rObj.SetAngle( rObj.ImplGetInt32PropertyValue( ::rtl::OUString( "RotateAngle" ) ));
199 :
200 3 : if( ( rObj.ImplGetPropertyValue( ::rtl::OUString( "IsFontwork" ) ) &&
201 1 : ::cppu::any2bool( rObj.GetUsrAny() ) ) ||
202 1 : rObj.GetType().EqualsAscii( "drawing.Measure" ) )
203 : {
204 : rObj.SetType( String( RTL_CONSTASCII_STRINGPARAM(
205 : "drawing.dontknow" ),
206 0 : RTL_TEXTENCODING_MS_1252 ));
207 : }
208 :
209 1 : const ::com::sun::star::awt::Size aSize100thmm( rObj.GetShapeRef()->getSize() );
210 1 : const ::com::sun::star::awt::Point aPoint100thmm( rObj.GetShapeRef()->getPosition() );
211 1 : Rectangle aRect100thmm( Point( aPoint100thmm.X, aPoint100thmm.Y ), Size( aSize100thmm.Width, aSize100thmm.Height ) );
212 1 : if ( !mpPicStrm )
213 1 : mpPicStrm = mpEscherEx->QueryPictureStream();
214 1 : EscherPropertyContainer aPropOpt( mpEscherEx->GetGraphicProvider(), mpPicStrm, aRect100thmm );
215 :
216 : // #i51348# shape name
217 1 : if (!aShapeName.isEmpty())
218 0 : aPropOpt.AddOpt( ESCHER_Prop_wzName, aShapeName );
219 1 : if ( InteractionInfo* pInteraction = mpHostAppData ? mpHostAppData->GetInteractionInfo():NULL )
220 : {
221 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
222 0 : const std::auto_ptr< SvMemoryStream >& pMemStrm = pInteraction->getHyperlinkRecord();
223 : SAL_WNODEPRECATED_DECLARATIONS_POP
224 0 : if ( pMemStrm.get() )
225 : {
226 0 : pMemStrm->ObjectOwnsMemory( sal_False );
227 0 : sal_uInt8* pBuf = (sal_uInt8*) pMemStrm->GetData();
228 0 : sal_uInt32 nSize = pMemStrm->Seek( STREAM_SEEK_TO_END );
229 0 : aPropOpt.AddOpt( ESCHER_Prop_pihlShape, sal_False, nSize, pBuf, nSize );
230 : }
231 0 : if ( pInteraction->hasInteraction() )
232 0 : aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080008 );
233 : }
234 :
235 1 : if ( rObj.GetType().EqualsAscii( "drawing.Custom" ) )
236 : {
237 1 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
238 : sal_uInt32 nMirrorFlags;
239 :
240 1 : rtl::OUString sCustomShapeType;
241 1 : MSO_SPT eShapeType = aPropOpt.GetCustomShapeType( rObj.GetShapeRef(), nMirrorFlags, sCustomShapeType );
242 1 : if ( sCustomShapeType == "col-502ad400" || sCustomShapeType == "col-60da8460" )
243 : {
244 0 : ADD_SHAPE( ESCHER_ShpInst_PictureFrame, 0xa00 );
245 0 : if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) )
246 : {
247 0 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
248 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 ); // no fill
249 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 ); // no linestyle
250 0 : SdrObject* pObj = GetSdrObjectFromXShape( rObj.GetShapeRef() );
251 0 : if ( pObj )
252 : {
253 0 : Rectangle aBound = pObj->GetCurrentBoundRect();
254 0 : Point aPosition( ImplMapPoint( aBound.TopLeft() ) );
255 0 : Size aSize( ImplMapSize( aBound.GetSize() ) );
256 0 : rObj.SetRect( Rectangle( aPosition, aSize ) );
257 0 : rObj.SetAngle( 0 );
258 0 : bDontWriteText = sal_True;
259 : }
260 : }
261 : }
262 : else
263 : {
264 1 : ADD_SHAPE(
265 : sal::static_int_cast< sal_uInt16 >(eShapeType),
266 : nMirrorFlags | 0xa00 );
267 1 : aPropOpt.CreateCustomShapeProperties( eShapeType, rObj.GetShapeRef() );
268 1 : aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
269 1 : if ( rObj.ImplGetText() )
270 : {
271 0 : if ( !aPropOpt.IsFontWork() )
272 : aPropOpt.CreateTextProperties( rObj.mXPropSet, mpEscherEx->QueryTextID(
273 0 : rObj.GetShapeRef(), rObj.GetShapeId() ), sal_True, sal_False );
274 : }
275 1 : }
276 : }
277 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Rectangle" ))
278 : {
279 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
280 : sal_Int32 nRadius = (sal_Int32)rObj.ImplGetInt32PropertyValue(
281 0 : ::rtl::OUString( "CornerRadius" ));
282 0 : if( nRadius )
283 : {
284 0 : nRadius = ImplMapSize( Size( nRadius, 0 )).Width();
285 0 : ADD_SHAPE( ESCHER_ShpInst_RoundRectangle, 0xa00 ); // Flags: Connector | HasSpt
286 0 : sal_Int32 nLenght = rObj.GetRect().GetWidth();
287 0 : if ( nLenght > rObj.GetRect().GetHeight() )
288 0 : nLenght = rObj.GetRect().GetHeight();
289 0 : nLenght >>= 1;
290 0 : if ( nRadius >= nLenght )
291 0 : nRadius = 0x2a30; // 0x2a30 ist PPTs maximum radius
292 : else
293 0 : nRadius = ( 0x2a30 * nRadius ) / nLenght;
294 0 : aPropOpt.AddOpt( ESCHER_Prop_adjustValue, nRadius );
295 : }
296 : else
297 : {
298 0 : ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0xa00 ); // Flags: Connector | HasSpt
299 : }
300 0 : aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
301 0 : if( rObj.ImplGetText() )
302 : aPropOpt.CreateTextProperties( rObj.mXPropSet,
303 0 : mpEscherEx->QueryTextID( rObj.GetShapeRef(),
304 0 : rObj.GetShapeId() ), sal_False, sal_False );
305 : }
306 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Ellipse" ))
307 : {
308 0 : CircleKind eCircleKind = CircleKind_FULL;
309 0 : PolyStyle ePolyKind = PolyStyle();
310 0 : if ( rObj.ImplGetPropertyValue( ::rtl::OUString( "CircleKind" ) ) )
311 : {
312 0 : eCircleKind = *( (CircleKind*)rObj.GetUsrAny().getValue() );
313 0 : switch ( eCircleKind )
314 : {
315 : case CircleKind_SECTION :
316 : {
317 0 : ePolyKind = POLY_PIE;
318 : }
319 0 : break;
320 : case CircleKind_ARC :
321 : {
322 0 : ePolyKind = POLY_ARC;
323 : }
324 0 : break;
325 :
326 : case CircleKind_CUT :
327 : {
328 0 : ePolyKind = POLY_CHORD;
329 : }
330 0 : break;
331 :
332 : default:
333 0 : eCircleKind = CircleKind_FULL;
334 : }
335 : }
336 0 : if ( eCircleKind == CircleKind_FULL )
337 : {
338 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
339 0 : ADD_SHAPE( ESCHER_ShpInst_Ellipse, 0xa00 ); // Flags: Connector | HasSpt
340 0 : aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
341 : }
342 : else
343 : {
344 : sal_Int32 nStartAngle, nEndAngle;
345 0 : if ( !rObj.ImplGetPropertyValue( ::rtl::OUString( "CircleStartAngle" ) ) )
346 : break;
347 0 : nStartAngle = *( (sal_Int32*)rObj.GetUsrAny().getValue() );
348 0 : if( !rObj.ImplGetPropertyValue( ::rtl::OUString( "CircleEndAngle" ) ) )
349 : break;
350 0 : nEndAngle = *( (sal_Int32*)rObj.GetUsrAny().getValue() );
351 :
352 0 : Point aStart, aEnd, aCenter;
353 0 : aStart.X() = (sal_Int32)( ( cos( (double)( nStartAngle *
354 0 : F_PI18000 ) ) * 100.0 ) );
355 0 : aStart.Y() = - (sal_Int32)( ( sin( (double)( nStartAngle *
356 0 : F_PI18000 ) ) * 100.0 ) );
357 0 : aEnd.X() = (sal_Int32)( ( cos( (double)( nEndAngle *
358 0 : F_PI18000 ) ) * 100.0 ) );
359 0 : aEnd.Y() = - (sal_Int32)( ( sin( (double)( nEndAngle *
360 0 : F_PI18000 ) ) * 100.0 ) );
361 0 : const Rectangle& rRect = aRect100thmm;
362 0 : aCenter.X() = rRect.Left() + ( rRect.GetWidth() / 2 );
363 0 : aCenter.Y() = rRect.Top() + ( rRect.GetHeight() / 2 );
364 0 : aStart.X() += aCenter.X();
365 0 : aStart.Y() += aCenter.Y();
366 0 : aEnd.X() += aCenter.X();
367 0 : aEnd.Y() += aCenter.Y();
368 0 : Polygon aPolygon( rRect, aStart, aEnd, ePolyKind );
369 0 : if( rObj.GetAngle() )
370 : {
371 0 : aPolygon.Rotate( rRect.TopLeft(), (sal_uInt16)( rObj.GetAngle() / 10 ) );
372 0 : rObj.SetAngle( 0 );
373 : }
374 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
375 0 : ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
376 0 : ::com::sun::star::awt::Rectangle aNewRect;
377 0 : switch ( ePolyKind )
378 : {
379 : case POLY_PIE :
380 : case POLY_CHORD :
381 : {
382 0 : aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, &aPolygon );
383 0 : aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
384 : }
385 0 : break;
386 :
387 : case POLY_ARC :
388 : {
389 0 : aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, &aPolygon );
390 0 : aPropOpt.CreateLineProperties( rObj.mXPropSet, sal_False );
391 : }
392 0 : break;
393 : }
394 0 : rObj.SetRect( Rectangle( ImplMapPoint( Point( aNewRect.X, aNewRect.Y ) ),
395 0 : ImplMapSize( Size( aNewRect.Width, aNewRect.Height ) ) ) );
396 : }
397 0 : if ( rObj.ImplGetText() )
398 : aPropOpt.CreateTextProperties( rObj.mXPropSet,
399 0 : mpEscherEx->QueryTextID( rObj.GetShapeRef(),
400 0 : rObj.GetShapeId() ), sal_False, sal_False );
401 :
402 : }
403 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Control" ))
404 : {
405 : break;
406 : }
407 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Connector" ))
408 : {
409 : sal_uInt16 nSpType, nSpFlags;
410 0 : ::com::sun::star::awt::Rectangle aNewRect;
411 0 : if ( aPropOpt.CreateConnectorProperties( rObj.GetShapeRef(),
412 0 : rSolverContainer, aNewRect, nSpType, nSpFlags ) == sal_False )
413 : break;
414 0 : rObj.SetRect( Rectangle( ImplMapPoint( Point( aNewRect.X, aNewRect.Y ) ),
415 0 : ImplMapSize( Size( aNewRect.Width, aNewRect.Height ) ) ) );
416 :
417 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
418 0 : ADD_SHAPE( nSpType, nSpFlags );
419 : }
420 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Measure" ))
421 : {
422 : break;
423 : }
424 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Line" ))
425 : {
426 0 : ::com::sun::star::awt::Rectangle aNewRect;
427 0 : aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_LINE, sal_False, aNewRect, NULL );
428 0 : MapRect(rObj);
429 : //i27942: Poly/Lines/Bezier do not support text.
430 :
431 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
432 0 : sal_uInt32 nFlags = 0xa00; // Flags: Connector | HasSpt
433 0 : if( aNewRect.Height < 0 )
434 0 : nFlags |= 0x80; // Flags: VertMirror
435 0 : if( aNewRect.Width < 0 )
436 0 : nFlags |= 0x40; // Flags: HorzMirror
437 :
438 0 : ADD_SHAPE( ESCHER_ShpInst_Line, nFlags );
439 0 : aPropOpt.AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex );
440 0 : aPropOpt.CreateLineProperties( rObj.mXPropSet, sal_False );
441 0 : rObj.SetAngle( 0 );
442 : }
443 0 : else if ( rObj.GetType().EqualsAscii( "drawing.PolyPolygon" ))
444 : {
445 0 : if( rObj.ImplHasText() )
446 : {
447 0 : nGrpShapeID = ImplEnterAdditionalTextGroup( rObj.GetShapeRef(), &rObj.GetRect() );
448 0 : bAdditionalText = sal_True;
449 : }
450 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
451 0 : ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
452 0 : ::com::sun::star::awt::Rectangle aNewRect;
453 0 : aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, NULL );
454 0 : MapRect(rObj);
455 0 : aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
456 0 : rObj.SetAngle( 0 );
457 : }
458 0 : else if ( rObj.GetType().EqualsAscii( "drawing.PolyLine" ))
459 : {
460 : //i27942: Poly/Lines/Bezier do not support text.
461 :
462 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
463 0 : ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
464 0 : ::com::sun::star::awt::Rectangle aNewRect;
465 0 : aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, NULL );
466 0 : MapRect(rObj);
467 0 : aPropOpt.CreateLineProperties( rObj.mXPropSet, sal_False );
468 0 : rObj.SetAngle( 0 );
469 : }
470 0 : else if ( rObj.GetType().EqualsAscii( "drawing.OpenBezier" ) )
471 : {
472 : //i27942: Poly/Lines/Bezier do not support text.
473 :
474 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
475 0 : ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
476 0 : ::com::sun::star::awt::Rectangle aNewRect;
477 0 : aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_True, aNewRect, NULL );
478 0 : MapRect(rObj);
479 0 : aPropOpt.CreateLineProperties( rObj.mXPropSet, sal_False );
480 0 : rObj.SetAngle( 0 );
481 : }
482 0 : else if ( rObj.GetType().EqualsAscii( "drawing.ClosedBezier" ) )
483 : {
484 0 : if ( rObj.ImplHasText() )
485 : {
486 0 : nGrpShapeID = ImplEnterAdditionalTextGroup( rObj.GetShapeRef(), &rObj.GetRect() );
487 0 : bAdditionalText = sal_True;
488 : }
489 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
490 0 : ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
491 0 : ::com::sun::star::awt::Rectangle aNewRect;
492 0 : aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_True, aNewRect, NULL );
493 0 : MapRect(rObj);
494 0 : aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
495 0 : rObj.SetAngle( 0 );
496 : }
497 0 : else if ( rObj.GetType().EqualsAscii( "drawing.GraphicObject" ))
498 : {
499 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
500 :
501 : // a GraphicObject can also be a ClickMe element
502 0 : if( rObj.IsEmptyPresObj() && ( ePageType == NORMAL ) )
503 : {
504 0 : ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0x220 ); // Flags: HaveAnchor | HaveMaster
505 0 : sal_uInt32 nTxtBxId = mpEscherEx->QueryTextID( rObj.GetShapeRef(),
506 0 : rObj.GetShapeId() );
507 0 : aPropOpt.AddOpt( ESCHER_Prop_lTxid, nTxtBxId );
508 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
509 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 );
510 0 : aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
511 : }
512 : else
513 : {
514 0 : if( rObj.ImplGetText() )
515 : {
516 : /* SJ #i34951#: because M. documents are not allowing GraphicObjects containing text, we
517 : have to create a simpe Rectangle with fill bitmap instead (while not allowing BitmapMode_Repeat).
518 : */
519 0 : ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0xa00 ); // Flags: Connector | HasSpt
520 0 : if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), sal_True, sal_True, sal_False ) )
521 : {
522 0 : aPropOpt.AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapNone );
523 0 : aPropOpt.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
524 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
525 0 : aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x8000000 );
526 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
527 0 : if ( rObj.ImplGetText() )
528 : aPropOpt.CreateTextProperties( rObj.mXPropSet,
529 0 : mpEscherEx->QueryTextID( rObj.GetShapeRef(),
530 0 : rObj.GetShapeId() ), sal_False, sal_False );
531 : }
532 : }
533 : else
534 : {
535 0 : ADD_SHAPE( ESCHER_ShpInst_PictureFrame, 0xa00 );
536 0 : if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), sal_False, sal_True ) )
537 0 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
538 : }
539 : }
540 : }
541 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Text" ))
542 : {
543 0 : SHAPE_TEXT( sal_True );
544 : }
545 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Page" ))
546 : {
547 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
548 0 : ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0xa00 );
549 0 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x40004 );
550 0 : aPropOpt.AddOpt( ESCHER_Prop_fFillOK, 0x100001 );
551 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110011 );
552 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90008 );
553 0 : aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x10001 );
554 : }
555 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Frame" ))
556 : {
557 : break;
558 : }
559 0 : else if ( rObj.GetType().EqualsAscii( "drawing.OLE2" ))
560 : {
561 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
562 0 : if( rObj.IsEmptyPresObj() && ( ePageType == NORMAL ) )
563 : {
564 0 : ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0x220 ); // Flags: HaveAnchor | HaveMaster
565 0 : sal_uInt32 nTxtBxId = mpEscherEx->QueryTextID( rObj.GetShapeRef(),
566 0 : rObj.GetShapeId() );
567 0 : aPropOpt.AddOpt( ESCHER_Prop_lTxid, nTxtBxId );
568 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
569 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 );
570 0 : aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
571 : }
572 : else
573 : {
574 : //2do: could be made an option in HostAppData whether OLE object should be written or not
575 0 : sal_Bool bAppOLE = sal_True;
576 0 : ADD_SHAPE( ESCHER_ShpInst_PictureFrame,
577 : 0xa00 | (bAppOLE ? SHAPEFLAG_OLESHAPE : 0) );
578 0 : if ( aPropOpt.CreateOLEGraphicProperties( rObj.GetShapeRef() ) )
579 : {
580 0 : if ( bAppOLE )
581 : { // snooped from Xcl hex dump, nobody knows the trouble I have seen
582 0 : aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 );
583 0 : aPropOpt.AddOpt( ESCHER_Prop_pictureId, 0x00000001 );
584 0 : aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000041 );
585 0 : aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000041 );
586 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 );
587 0 : aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x08000040 );
588 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash,0x00080008 );
589 0 : aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080000 );
590 : }
591 0 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
592 : }
593 : }
594 : }
595 0 : else if( '3' == rObj.GetType().GetChar(8 ) &&
596 0 : 'D' == rObj.GetType().GetChar( 9 ) ) // drawing.3D
597 : {
598 : // SceneObject, CubeObject, SphereObject, LatheObject, ExtrudeObject, PolygonObject
599 0 : if ( !rObj.ImplGetPropertyValue( ::rtl::OUString( "Bitmap" ) ) )
600 : break;
601 :
602 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
603 0 : ADD_SHAPE( ESCHER_ShpInst_PictureFrame, 0xa00 );
604 :
605 0 : if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ), sal_False ) )
606 0 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
607 : }
608 0 : else if ( rObj.GetType().EqualsAscii( "drawing.Caption" ))
609 : {
610 0 : rObj.SetAngle( 0 );
611 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
612 0 : ADD_SHAPE( ESCHER_ShpInst_TextBox, 0xa00 );
613 0 : if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) )
614 0 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
615 : }
616 0 : else if ( rObj.GetType().EqualsAscii( "drawing.dontknow" ))
617 : {
618 0 : rObj.SetAngle( 0 );
619 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
620 0 : ADD_SHAPE( ESCHER_ShpInst_PictureFrame, 0xa00 );
621 0 : if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) )
622 0 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
623 : }
624 : else
625 : {
626 : break;
627 : }
628 1 : aPropOpt.CreateShadowProperties( rObj.mXPropSet );
629 :
630 2 : if( USHRT_MAX != mpEscherEx->GetHellLayerId() &&
631 1 : rObj.ImplGetPropertyValue( ::rtl::OUString( "LayerID" ) ) &&
632 0 : (*((sal_uInt16*)rObj.GetUsrAny().getValue()) ) == mpEscherEx->GetHellLayerId() )
633 : {
634 0 : aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x200020 );
635 : }
636 :
637 : {
638 1 : Rectangle aRect( rObj.GetRect() );
639 1 : aRect.Justify();
640 1 : rObj.SetRect( aRect );
641 : }
642 :
643 1 : if( rObj.GetAngle() )
644 0 : ImplFlipBoundingBox( rObj, aPropOpt );
645 :
646 1 : aPropOpt.CreateShapeProperties( rObj.GetShapeRef() );
647 1 : mpEscherEx->Commit( aPropOpt, rObj.GetRect() );
648 1 : if( mpEscherEx->GetGroupLevel() > 1 )
649 0 : mpEscherEx->AddChildAnchor( rObj.GetRect() );
650 :
651 1 : if ( mpHostAppData )
652 : { //! with AdditionalText the App has to control whether these are written or not
653 0 : mpHostAppData->WriteClientAnchor( *mpEscherEx, rObj.GetRect() );
654 0 : mpHostAppData->WriteClientData( *mpEscherEx );
655 0 : if ( !bDontWriteText )
656 0 : mpHostAppData->WriteClientTextbox( *mpEscherEx );
657 : }
658 1 : mpEscherEx->CloseContainer(); // ESCHER_SpContainer
659 :
660 1 : if( bAdditionalText )
661 : {
662 0 : mpEscherEx->EndShape( nShapeType, nShapeID );
663 0 : ImplWriteAdditionalText( rObj, aTextRefPoint );
664 1 : }
665 :
666 : } while ( 0 );
667 :
668 1 : if ( bAdditionalText )
669 0 : mpEscherEx->EndShape( ESCHER_ShpInst_Min, nGrpShapeID );
670 : else
671 1 : mpEscherEx->EndShape( nShapeType, nShapeID );
672 1 : return nShapeID;
673 : }
674 :
675 0 : void ImplEESdrWriter::ImplWriteAdditionalText( ImplEESdrObject& rObj,
676 : const Point& rTextRefPoint )
677 : {
678 0 : sal_uInt32 nShapeID = 0;
679 0 : sal_uInt16 nShapeType = 0;
680 : do
681 : {
682 0 : mpHostAppData = mpEscherEx->StartShape( rObj.GetShapeRef(), (mpEscherEx->GetGroupLevel() > 1) ? &rObj.GetRect() : 0 );
683 0 : if ( mpHostAppData && mpHostAppData->DontWriteShape() )
684 : break;
685 :
686 0 : const ::com::sun::star::awt::Size aSize100thmm( rObj.GetShapeRef()->getSize() );
687 0 : const ::com::sun::star::awt::Point aPoint100thmm( rObj.GetShapeRef()->getPosition() );
688 0 : Rectangle aRect100thmm( Point( aPoint100thmm.X, aPoint100thmm.Y ), Size( aSize100thmm.Width, aSize100thmm.Height ) );
689 0 : if ( !mpPicStrm )
690 0 : mpPicStrm = mpEscherEx->QueryPictureStream();
691 0 : EscherPropertyContainer aPropOpt( mpEscherEx->GetGraphicProvider(), mpPicStrm, aRect100thmm );
692 0 : rObj.SetAngle( rObj.ImplGetInt32PropertyValue( ::rtl::OUString( "RotateAngle" )));
693 0 : sal_Int32 nAngle = rObj.GetAngle();
694 0 : if( rObj.GetType().EqualsAscii( "drawing.Line" ))
695 : {
696 : //2do: this does not work right
697 0 : double fDist = hypot( rObj.GetRect().GetWidth(),
698 0 : rObj.GetRect().GetHeight() );
699 : rObj.SetRect( Rectangle( rTextRefPoint,
700 0 : Point( (sal_Int32)( rTextRefPoint.X() + fDist ), rTextRefPoint.Y() - 1 ) ) );
701 :
702 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
703 0 : mpEscherEx->AddShape( ESCHER_ShpInst_TextBox, 0xa00 );
704 0 : if ( rObj.ImplGetText() )
705 : aPropOpt.CreateTextProperties( rObj.mXPropSet,
706 0 : mpEscherEx->QueryTextID( rObj.GetShapeRef(),
707 0 : rObj.GetShapeId() ) );
708 :
709 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );
710 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
711 0 : aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x60006 ); // Size Shape To Fit Text
712 0 : if ( nAngle < 0 )
713 0 : nAngle = ( 36000 + nAngle ) % 36000;
714 0 : if ( nAngle )
715 0 : ImplFlipBoundingBox( rObj, aPropOpt );
716 : }
717 : else
718 : {
719 0 : mpEscherEx->OpenContainer( ESCHER_SpContainer );
720 0 : nShapeID = mpEscherEx->GenerateShapeId();
721 0 : mpEscherEx->AddShape( nShapeType = ESCHER_ShpInst_TextBox, 0xa00, nShapeID );
722 0 : if ( rObj.ImplGetText() )
723 : aPropOpt.CreateTextProperties( rObj.mXPropSet,
724 0 : mpEscherEx->QueryTextID( rObj.GetShapeRef(),
725 0 : rObj.GetShapeId() ) );
726 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );
727 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
728 :
729 0 : if( nAngle < 0 )
730 0 : nAngle = ( 36000 + nAngle ) % 36000;
731 : else
732 0 : nAngle = ( 36000 - ( nAngle % 36000 ) );
733 :
734 0 : nAngle *= 655;
735 0 : nAngle += 0x8000;
736 0 : nAngle &=~0xffff; // nAngle auf volle Gradzahl runden
737 0 : aPropOpt.AddOpt( ESCHER_Prop_Rotation, nAngle );
738 : mpEscherEx->SetGroupSnapRect( mpEscherEx->GetGroupLevel(),
739 0 : rObj.GetRect() );
740 : mpEscherEx->SetGroupLogicRect( mpEscherEx->GetGroupLevel(),
741 0 : rObj.GetRect() );
742 : }
743 0 : rObj.SetAngle( nAngle );
744 0 : aPropOpt.CreateShapeProperties( rObj.GetShapeRef() );
745 0 : mpEscherEx->Commit( aPropOpt, rObj.GetRect() );
746 :
747 : // write the childanchor
748 0 : mpEscherEx->AddChildAnchor( rObj.GetRect() );
749 :
750 : #if defined EES_WRITE_EPP
751 : // ClientAnchor
752 : mpEscherEx->AddClientAnchor( maRect );
753 : // ClientTextbox
754 : mpEscherEx->OpenContainer( ESCHER_ClientTextbox );
755 : mpEscherEx->AddAtom( 4, EPP_TextHeaderAtom );
756 : *mpStrm << (sal_uInt32)EPP_TEXTTYPE_Other; // Text in a Shape
757 : ImplWriteTextStyleAtom();
758 : mpEscherEx->CloseContainer(); // ESCHER_ClientTextBox
759 : #else // !EES_WRITE_EPP
760 0 : if ( mpHostAppData )
761 : { //! the App has to control whether these are written or not
762 0 : mpHostAppData->WriteClientAnchor( *mpEscherEx, rObj.GetRect() );
763 0 : mpHostAppData->WriteClientData( *mpEscherEx );
764 0 : mpHostAppData->WriteClientTextbox( *mpEscherEx );
765 : }
766 : #endif // EES_WRITE_EPP
767 0 : mpEscherEx->CloseContainer(); // ESCHER_SpContainer
768 : } while ( 0 );
769 0 : mpEscherEx->LeaveGroup();
770 0 : mpEscherEx->EndShape( nShapeType, nShapeID );
771 0 : }
772 :
773 :
774 0 : sal_uInt32 ImplEESdrWriter::ImplEnterAdditionalTextGroup( const Reference< XShape >& rShape,
775 : const Rectangle* pBoundRect )
776 : {
777 0 : mpHostAppData = mpEscherEx->EnterAdditionalTextGroup();
778 0 : sal_uInt32 nGrpId = mpEscherEx->EnterGroup( pBoundRect );
779 0 : mpHostAppData = mpEscherEx->StartShape( rShape, pBoundRect );
780 0 : return nGrpId;
781 : }
782 :
783 :
784 3 : sal_Bool ImplEESdrWriter::ImplInitPageValues()
785 : {
786 3 : mnIndices = 0;
787 3 : mnOutlinerCount = 0; // die gliederungsobjekte muessen dem layout entsprechen,
788 3 : mnEffectCount = 0;
789 3 : mbIsTitlePossible = sal_True; // bei mehr als einem title geht powerpoint in die knie
790 :
791 3 : return sal_True;
792 : }
793 :
794 1 : void ImplEESdrWriter::ImplWritePage(
795 : EscherSolverContainer& rSolverContainer,
796 : ImplEESdrPageType ePageType, sal_Bool /* bBackGround */ )
797 : {
798 1 : ImplInitPageValues();
799 :
800 1 : sal_uInt32 nLastPer = 0, nShapes = mXShapes->getCount();
801 1 : for( sal_uInt32 n = 0; n < nShapes; ++n )
802 : {
803 0 : sal_uInt32 nPer = ( 5 * n ) / nShapes;
804 0 : if( nPer != nLastPer )
805 : {
806 0 : nLastPer = nPer;
807 0 : sal_uInt32 nValue = mnPagesWritten * 5 + nPer;
808 0 : if( nValue > mnStatMaxValue )
809 0 : nValue = mnStatMaxValue;
810 0 : if( mbStatusIndicator )
811 0 : mXStatusIndicator->setValue( nValue );
812 : }
813 :
814 : ImplEESdrObject aObj( *this, *(Reference< XShape >*)
815 0 : mXShapes->getByIndex( n ).getValue() );
816 0 : if( aObj.IsValid() )
817 : {
818 0 : ImplWriteShape( aObj, rSolverContainer, ePageType );
819 : }
820 0 : }
821 1 : mnPagesWritten++;
822 1 : }
823 :
824 54 : ImplEscherExSdr::ImplEscherExSdr( EscherEx& rEx )
825 : :
826 : ImplEESdrWriter( rEx ),
827 : mpSdrPage( NULL ),
828 54 : mpSolverContainer( NULL )
829 : {
830 54 : }
831 :
832 :
833 162 : ImplEscherExSdr::~ImplEscherExSdr()
834 : {
835 : DBG_ASSERT( !mpSolverContainer, "ImplEscherExSdr::~ImplEscherExSdr: unwritten SolverContainer" );
836 54 : delete mpSolverContainer;
837 108 : }
838 :
839 :
840 2 : bool ImplEscherExSdr::ImplInitPage( const SdrPage& rPage )
841 : {
842 : do
843 : {
844 : SvxDrawPage* pSvxDrawPage;
845 2 : if ( mpSdrPage != &rPage || !mXDrawPage.is() )
846 : {
847 : // eventually write SolverContainer of current page, deletes the Solver
848 2 : ImplFlushSolverContainer();
849 :
850 2 : mpSdrPage = NULL;
851 2 : mXDrawPage = pSvxDrawPage = new SvxFmDrawPage( (SdrPage*) &rPage );
852 2 : mXShapes = Reference< XShapes >::query( mXDrawPage );
853 2 : if ( !mXShapes.is() )
854 0 : break;
855 2 : if ( !ImplInitPageValues() ) // ImplEESdrWriter
856 0 : break;
857 2 : mpSdrPage = &rPage;
858 :
859 2 : mpSolverContainer = new EscherSolverContainer;
860 : }
861 : else
862 0 : pSvxDrawPage = SvxDrawPage::getImplementation(mXDrawPage);
863 :
864 2 : return pSvxDrawPage != 0;
865 : } while ( 0 );
866 :
867 0 : return false;
868 : }
869 :
870 0 : bool ImplEscherExSdr::ImplInitUnoShapes( const Reference< XShapes >& rxShapes )
871 : {
872 : // eventually write SolverContainer of current page, deletes the Solver
873 0 : ImplFlushSolverContainer();
874 :
875 0 : if( !rxShapes.is() )
876 0 : return false;
877 :
878 0 : mpSdrPage = 0;
879 0 : mXDrawPage.clear();
880 0 : mXShapes = rxShapes;
881 :
882 0 : if( !ImplInitPageValues() ) // ImplEESdrWriter
883 0 : return false;
884 :
885 0 : mpSolverContainer = new EscherSolverContainer;
886 0 : return true;
887 : }
888 :
889 1 : void ImplEscherExSdr::ImplExitPage()
890 : {
891 : // close all groups before the solver container is written
892 3 : while( mpEscherEx->GetGroupLevel() )
893 1 : mpEscherEx->LeaveGroup();
894 :
895 1 : ImplFlushSolverContainer();
896 1 : mpSdrPage = NULL; // reset page for next init
897 1 : }
898 :
899 :
900 3 : void ImplEscherExSdr::ImplFlushSolverContainer()
901 : {
902 3 : if ( mpSolverContainer )
903 : {
904 1 : mpSolverContainer->WriteSolver( mpEscherEx->GetStream() );
905 1 : delete mpSolverContainer;
906 1 : mpSolverContainer = NULL;
907 : }
908 3 : }
909 :
910 :
911 1 : void ImplEscherExSdr::ImplWriteCurrentPage()
912 : {
913 : DBG_ASSERT( mpSolverContainer, "ImplEscherExSdr::ImplWriteCurrentPage: no SolverContainer" );
914 1 : ImplWritePage( *mpSolverContainer, NORMAL );
915 1 : ImplExitPage();
916 1 : }
917 :
918 :
919 1 : sal_uInt32 ImplEscherExSdr::ImplWriteTheShape( ImplEESdrObject& rObj )
920 : {
921 : DBG_ASSERT( mpSolverContainer, "ImplEscherExSdr::ImplWriteShape: no SolverContainer" );
922 1 : return ImplWriteShape( rObj, *mpSolverContainer, NORMAL );
923 : }
924 :
925 :
926 1 : void EscherEx::AddSdrPage( const SdrPage& rPage )
927 : {
928 1 : if ( mpImplEscherExSdr->ImplInitPage( rPage ) )
929 1 : mpImplEscherExSdr->ImplWriteCurrentPage();
930 1 : }
931 :
932 0 : void EscherEx::AddUnoShapes( const Reference< XShapes >& rxShapes )
933 : {
934 0 : if ( mpImplEscherExSdr->ImplInitUnoShapes( rxShapes ) )
935 0 : mpImplEscherExSdr->ImplWriteCurrentPage();
936 0 : }
937 :
938 1 : sal_uInt32 EscherEx::AddSdrObject( const SdrObject& rObj )
939 : {
940 1 : ImplEESdrObject aObj( *mpImplEscherExSdr, rObj );
941 1 : if( aObj.IsValid() )
942 1 : return mpImplEscherExSdr->ImplWriteTheShape( aObj );
943 0 : return 0;
944 : }
945 :
946 :
947 0 : void EscherEx::EndSdrObjectPage()
948 : {
949 0 : mpImplEscherExSdr->ImplExitPage();
950 0 : }
951 :
952 1 : EscherExHostAppData* EscherEx::StartShape( const Reference< XShape >& /* rShape */, const Rectangle* /*pChildAnchor*/ )
953 : {
954 1 : return NULL;
955 : }
956 :
957 1 : void EscherEx::EndShape( sal_uInt16 /* nShapeType */, sal_uInt32 /* nShapeID */ )
958 : {
959 1 : }
960 :
961 0 : sal_uInt32 EscherEx::QueryTextID( const Reference< XShape >&, sal_uInt32 )
962 : {
963 0 : return 0;
964 : }
965 :
966 : // add an dummy rectangle shape into the escher stream
967 0 : sal_uInt32 EscherEx::AddDummyShape()
968 : {
969 0 : OpenContainer( ESCHER_SpContainer );
970 0 : sal_uInt32 nShapeID = GenerateShapeId();
971 0 : AddShape( ESCHER_ShpInst_Rectangle, 0xa00, nShapeID );
972 0 : CloseContainer();
973 :
974 0 : return nShapeID;
975 : }
976 :
977 : // static
978 1 : const SdrObject* EscherEx::GetSdrObject( const Reference< XShape >& rShape )
979 : {
980 1 : const SdrObject* pRet = 0;
981 1 : const SvxShape* pSvxShape = SvxShape::getImplementation( rShape );
982 : DBG_ASSERT( pSvxShape, "EscherEx::GetSdrObject: no SvxShape" );
983 1 : if( pSvxShape )
984 : {
985 1 : pRet = pSvxShape->GetSdrObject();
986 : DBG_ASSERT( pRet, "EscherEx::GetSdrObject: no SdrObj" );
987 : }
988 1 : return pRet;
989 : }
990 :
991 :
992 1 : ImplEESdrObject::ImplEESdrObject( ImplEscherExSdr& rEx,
993 : const SdrObject& rObj ) :
994 : mnShapeId( 0 ),
995 : mnTextSize( 0 ),
996 : mnAngle( 0 ),
997 : mbValid( sal_False ),
998 : mbPresObj( sal_False ),
999 1 : mbEmptyPresObj( sal_False )
1000 : {
1001 1 : SdrPage* pPage = rObj.GetPage();
1002 : DBG_ASSERT( pPage, "ImplEESdrObject::ImplEESdrObject: no SdrPage" );
1003 1 : if( pPage && rEx.ImplInitPage( *pPage ) )
1004 : {
1005 : // why not declare a const parameter if the object will
1006 : // not be modified?
1007 1 : mXShape = uno::Reference< drawing::XShape >::query( ((SdrObject*)&rObj)->getUnoShape() );
1008 1 : Init( rEx );
1009 : }
1010 1 : }
1011 :
1012 0 : ImplEESdrObject::ImplEESdrObject( ImplEESdrWriter& rEx,
1013 : const Reference< XShape >& rShape ) :
1014 : mXShape( rShape ),
1015 : mnShapeId( 0 ),
1016 : mnTextSize( 0 ),
1017 : mnAngle( 0 ),
1018 : mbValid( sal_False ),
1019 : mbPresObj( sal_False ),
1020 0 : mbEmptyPresObj( sal_False )
1021 : {
1022 0 : Init( rEx );
1023 0 : }
1024 :
1025 :
1026 1 : ImplEESdrObject::~ImplEESdrObject()
1027 : {
1028 1 : }
1029 :
1030 1 : void ImplEESdrObject::Init( ImplEESdrWriter& rEx )
1031 : {
1032 1 : mXPropSet = Reference< XPropertySet >::query( mXShape );
1033 1 : if( mXPropSet.is() )
1034 : {
1035 : static const sal_Char aPrefix[] = "com.sun.star.";
1036 : static const xub_StrLen nPrefix = sizeof(aPrefix)-1;
1037 2 : SetRect( rEx.ImplMapPoint( Point( mXShape->getPosition().X, mXShape->getPosition().Y ) ),
1038 3 : rEx.ImplMapSize( Size( mXShape->getSize().Width, mXShape->getSize().Height ) ) );
1039 1 : mType = String( mXShape->getShapeType() );
1040 1 : mType.Erase( 0, nPrefix ); // strip "com.sun.star."
1041 1 : xub_StrLen nPos = mType.SearchAscii( "Shape" );
1042 1 : mType.Erase( nPos, 5 );
1043 :
1044 1 : static const OUString sPresStr("IsPresentationObject" );
1045 1 : static const OUString sEmptyPresStr("IsEmptyPresentationObject" );
1046 :
1047 1 : if( ImplGetPropertyValue( sPresStr ) )
1048 0 : mbPresObj = ::cppu::any2bool( mAny );
1049 :
1050 1 : if( mbPresObj && ImplGetPropertyValue( sEmptyPresStr ) )
1051 0 : mbEmptyPresObj = ::cppu::any2bool( mAny );
1052 :
1053 1 : mbValid = sal_True;
1054 : }
1055 1 : }
1056 :
1057 3 : sal_Bool ImplEESdrObject::ImplGetPropertyValue( const sal_Unicode* rString )
1058 : {
1059 3 : sal_Bool bRetValue = sal_False;
1060 3 : if( mbValid )
1061 : {
1062 : try
1063 : {
1064 2 : mAny = mXPropSet->getPropertyValue( rString );
1065 2 : if( mAny.hasValue() )
1066 2 : bRetValue = sal_True;
1067 : }
1068 0 : catch( const ::com::sun::star::uno::Exception& )
1069 : {
1070 0 : bRetValue = sal_False;
1071 : }
1072 : }
1073 3 : return bRetValue;
1074 : }
1075 :
1076 : #ifdef USED
1077 : sal_Bool ImplEESdrObject::ImplGetPropertyValue( const Reference< XPropertySet >& rXPropSet,
1078 : const OUString& rString )
1079 : {
1080 : sal_Bool bRetValue = sal_False;
1081 : if( mbValid )
1082 : {
1083 : try
1084 : {
1085 : mAny = rXPropSet->getPropertyValue( rString );
1086 : if( 0 != mAny.get() )
1087 : bRetValue = sal_True;
1088 : }
1089 : catch( const ::com::sun::star::uno::Exception& )
1090 : {
1091 : bRetValue = sal_False;
1092 : }
1093 : }
1094 : return bRetValue;
1095 : }
1096 : #endif
1097 :
1098 1 : void ImplEESdrObject::SetRect( const Point& rPos, const Size& rSz )
1099 : {
1100 1 : maRect = Rectangle( rPos, rSz );
1101 1 : }
1102 :
1103 1 : const SdrObject* ImplEESdrObject::GetSdrObject() const
1104 : {
1105 1 : return EscherEx::GetSdrObject( mXShape );
1106 : }
1107 :
1108 : // loads and converts text from shape, result is being saved in mnTextSize respeichert
1109 1 : sal_uInt32 ImplEESdrObject::ImplGetText()
1110 : {
1111 1 : Reference< XText > xXText( mXShape, UNO_QUERY );
1112 1 : mnTextSize = 0;
1113 1 : if( xXText.is() )
1114 1 : mnTextSize = xXText->getString().getLength();
1115 1 : return mnTextSize;
1116 : }
1117 :
1118 0 : sal_Bool ImplEESdrObject::ImplHasText() const
1119 : {
1120 0 : Reference< XText > xXText( mXShape, UNO_QUERY );
1121 0 : return xXText.is() && !xXText->getString().isEmpty();
1122 : }
1123 :
1124 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|