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 <com/sun/star/util/XCloseable.hpp>
21 :
22 : #include <doc.hxx>
23 : #include "writerhelper.hxx"
24 : #include <msfilter.hxx>
25 : #include <com/sun/star/container/XChild.hpp>
26 : #include <com/sun/star/embed/EmbedStates.hpp>
27 :
28 : #include <algorithm>
29 : #include <functional>
30 : #include <svl/itemiter.hxx>
31 : #include <svx/svdobj.hxx>
32 : #include <svx/svdoole2.hxx>
33 : #include <svx/fmglob.hxx>
34 : #include <editeng/formatbreakitem.hxx>
35 : #include <editeng/tstpitem.hxx>
36 : #include <ndtxt.hxx>
37 : #include <ndnotxt.hxx>
38 : #include <fmtcntnt.hxx>
39 : #include <swtable.hxx>
40 : #include <frmfmt.hxx>
41 : #include <flypos.hxx>
42 : #include <fmtanchr.hxx>
43 : #include <ndgrf.hxx>
44 : #include <fmtfsize.hxx>
45 : #include <SwStyleNameMapper.hxx>
46 : #include <docary.hxx>
47 : #include <charfmt.hxx>
48 : #include <fchrfmt.hxx>
49 : #include <unotools/streamwrap.hxx>
50 : #include <numrule.hxx>
51 : #include <vcl/svapp.hxx>
52 : #include <IDocumentDrawModelAccess.hxx>
53 : #include <IDocumentLayoutAccess.hxx>
54 : #include <IDocumentStylePoolAccess.hxx>
55 :
56 : using namespace com::sun::star;
57 : using namespace nsSwGetPoolIdFromName;
58 :
59 : namespace
60 : {
61 : /*
62 : Stroustroup forgets copy_if, See C++ Programming language Chp 18, pg 530
63 : */
64 : template <typename In , typename Out , typename Pred>
65 28688 : Out my_copy_if(In first, In last, Out res, Pred p)
66 : {
67 159992 : while (first != last)
68 : {
69 102616 : if (p(*first))
70 1976 : *res = *first;
71 102616 : ++first;
72 : }
73 28688 : return res;
74 : }
75 :
76 : // #i98791# - adjust sorting
77 : // Utility to sort SwTxtFmtColl's by their assigned outline style list level
78 : class outlinecmp : public
79 : std::binary_function<const SwTxtFmtColl*, const SwTxtFmtColl*, bool>
80 : {
81 : public:
82 0 : bool operator()(const SwTxtFmtColl *pA, const SwTxtFmtColl *pB) const
83 : {
84 : // #i98791#
85 0 : bool bResult( false );
86 0 : const bool bIsAAssignedToOutlineStyle( pA->IsAssignedToListLevelOfOutlineStyle() );
87 0 : const bool bIsBAssignedToOutlineStyle( pB->IsAssignedToListLevelOfOutlineStyle() );
88 0 : if ( bIsAAssignedToOutlineStyle != bIsBAssignedToOutlineStyle )
89 : {
90 0 : bResult = bIsBAssignedToOutlineStyle;
91 : }
92 0 : else if ( !bIsAAssignedToOutlineStyle )
93 : {
94 : // pA and pB are equal regarding the sorting criteria.
95 : // Thus return value does not matter.
96 0 : bResult = false;
97 : }
98 : else
99 : {
100 0 : bResult = pA->GetAssignedOutlineStyleLevel() < pB->GetAssignedOutlineStyleLevel();
101 : }
102 :
103 0 : return bResult;
104 : }
105 : };
106 :
107 160 : bool IsValidSlotWhich(sal_uInt16 nSlotId, sal_uInt16 nWhichId)
108 : {
109 160 : return (nSlotId != 0 && nWhichId != 0 && nSlotId != nWhichId);
110 : }
111 :
112 : /*
113 : Utility to convert a SwPosFlyFrms into a simple vector of sw::Frames
114 :
115 : The crucial thing is that a sw::Frame always has an anchor which
116 : points to some content in the document. This is a requirement of exporting
117 : to Word
118 : */
119 1032 : sw::Frames SwPosFlyFrmsToFrames(const SwPosFlyFrms &rFlys)
120 : {
121 1032 : sw::Frames aRet;
122 :
123 2028 : for(SwPosFlyFrms::const_iterator aIter(rFlys.begin()); aIter != rFlys.end(); ++aIter)
124 : {
125 996 : const SwFrmFmt &rEntry = (*aIter)->GetFmt();
126 :
127 996 : if (const SwPosition* pAnchor = rEntry.GetAnchor().GetCntntAnchor())
128 : {
129 994 : aRet.push_back(sw::Frame(rEntry, *pAnchor));
130 : }
131 : else
132 : {
133 2 : SwPosition aPos((*aIter)->GetNdIndex());
134 :
135 2 : if (SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode())
136 : {
137 2 : aPos.nContent.Assign(pTxtNd, 0);
138 : }
139 :
140 2 : aRet.push_back(sw::Frame(rEntry, aPos));
141 : }
142 : }
143 1032 : return aRet;
144 : }
145 :
146 : //Utility to test if a frame is anchored at a given node index
147 : class anchoredto: public std::unary_function<const sw::Frame&, bool>
148 : {
149 : private:
150 : sal_uLong mnNode;
151 : public:
152 28688 : anchoredto(sal_uLong nNode) : mnNode(nNode) {}
153 102616 : bool operator()(const sw::Frame &rFrame) const
154 : {
155 102616 : return (mnNode == rFrame.GetPosition().nNode.GetNode().GetIndex());
156 : }
157 : };
158 : }
159 :
160 : namespace sw
161 : {
162 : //For i120928,size conversion before exporting graphic of bullet
163 0 : Frame::Frame(const Graphic &rGrf, const SwPosition &rPos)
164 : : mpFlyFrm(NULL)
165 : , maPos(rPos)
166 : , maSize()
167 : , maLayoutSize()
168 : , meWriterType(eBulletGrf)
169 : , mpStartFrameContent(0)
170 : , mbIsInline(true)
171 : , mbForBullet(true)
172 0 : , maGrf(rGrf)
173 : {
174 0 : const MapMode aMap100mm( MAP_100TH_MM );
175 0 : Size aSize( rGrf.GetPrefSize() );
176 0 : if ( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
177 : {
178 0 : aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap100mm );
179 : }
180 : else
181 : {
182 0 : aSize = OutputDevice::LogicToLogic( aSize,rGrf.GetPrefMapMode(), aMap100mm );
183 : }
184 0 : maSize = aSize;
185 0 : maLayoutSize = maSize;
186 0 : }
187 :
188 1902 : Frame::Frame(const SwFrmFmt &rFmt, const SwPosition &rPos)
189 : : mpFlyFrm(&rFmt)
190 : , maPos(rPos)
191 : , maSize()
192 : , maLayoutSize() // #i43447#
193 : , meWriterType(eTxtBox)
194 : , mpStartFrameContent(0)
195 : // #i43447# - move to initialization list
196 1902 : , mbIsInline( (rFmt.GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
197 : // #i120928# - handle graphic of bullet within existing implementation
198 : , mbForBullet(false)
199 3804 : , maGrf()
200 : {
201 1902 : switch (rFmt.Which())
202 : {
203 : case RES_FLYFRMFMT:
204 1152 : if (const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx())
205 : {
206 1152 : SwNodeIndex aIdx(*pIdx, 1);
207 1152 : const SwNode &rNd = aIdx.GetNode();
208 : using sw::util::GetSwappedInSize;
209 : // #i43447# - determine layout size
210 : {
211 1152 : SwRect aLayRect( rFmt.FindLayoutRect() );
212 1152 : Rectangle aRect( aLayRect.SVRect() );
213 : // The Object is not rendered (e.g. something in unused
214 : // header/footer) - thus, get the values from the format.
215 1152 : if ( aLayRect.IsEmpty() )
216 : {
217 52 : aRect.SetSize( rFmt.GetFrmSize().GetSize() );
218 : }
219 1152 : maLayoutSize = aRect.GetSize();
220 : }
221 1152 : switch (rNd.GetNodeType())
222 : {
223 : case ND_GRFNODE:
224 128 : meWriterType = eGraphic;
225 128 : maSize = GetSwappedInSize(*rNd.GetNoTxtNode());
226 128 : break;
227 : case ND_OLENODE:
228 302 : meWriterType = eOle;
229 302 : maSize = GetSwappedInSize(*rNd.GetNoTxtNode());
230 302 : break;
231 : default:
232 722 : meWriterType = eTxtBox;
233 : // #i43447# - Size equals layout size for text boxes
234 722 : maSize = maLayoutSize;
235 722 : break;
236 : }
237 1152 : mpStartFrameContent = &rNd;
238 : }
239 : else
240 : {
241 : OSL_ENSURE(false, "Impossible");
242 0 : meWriterType = eTxtBox;
243 : }
244 1152 : break;
245 : default:
246 750 : if (const SdrObject* pObj = rFmt.FindRealSdrObject())
247 : {
248 750 : if (pObj->GetObjInventor() == FmFormInventor)
249 22 : meWriterType = eFormControl;
250 : else
251 728 : meWriterType = eDrawing;
252 750 : maSize = pObj->GetSnapRect().GetSize();
253 : }
254 : else
255 : {
256 : OSL_ENSURE(false, "Impossible");
257 0 : meWriterType = eDrawing;
258 : }
259 750 : break;
260 : }
261 1902 : }
262 :
263 :
264 0 : void Frame::ForceTreatAsInline()
265 : {
266 0 : mbIsInline = true;
267 0 : }
268 :
269 : namespace hack
270 : {
271 :
272 160 : sal_uInt16 TransformWhichBetweenPools(const SfxItemPool &rDestPool,
273 : const SfxItemPool &rSrcPool, sal_uInt16 nWhich)
274 : {
275 160 : sal_uInt16 nSlotId = rSrcPool.GetSlotId(nWhich);
276 160 : if (IsValidSlotWhich(nSlotId, nWhich))
277 160 : nWhich = rDestPool.GetWhich(nSlotId);
278 : else
279 0 : nWhich = 0;
280 160 : return nWhich;
281 : }
282 :
283 6070 : sal_uInt16 GetSetWhichFromSwDocWhich(const SfxItemSet &rSet,
284 : const SwDoc &rDoc, sal_uInt16 nWhich)
285 : {
286 6070 : if (RES_WHICHHINT_END < *(rSet.GetRanges()))
287 : {
288 0 : nWhich = TransformWhichBetweenPools(*rSet.GetPool(),
289 0 : rDoc.GetAttrPool(), nWhich);
290 : }
291 6070 : return nWhich;
292 : }
293 :
294 30 : DrawingOLEAdaptor::DrawingOLEAdaptor(SdrOle2Obj &rObj,
295 : SfxObjectShell &rPers)
296 : : msOrigPersistName(rObj.GetPersistName()),
297 : mxIPRef(rObj.GetObjRef()), mrPers(rPers),
298 30 : mpGraphic( rObj.GetGraphic() )
299 : {
300 30 : rObj.AbandonObject();
301 30 : }
302 :
303 30 : bool DrawingOLEAdaptor::TransferToDoc( OUString &rName )
304 : {
305 : OSL_ENSURE(mxIPRef.is(), "Transferring invalid object to doc");
306 30 : if (!mxIPRef.is())
307 0 : return false;
308 :
309 30 : uno::Reference < container::XChild > xChild( mxIPRef, uno::UNO_QUERY );
310 30 : if ( xChild.is() )
311 24 : xChild->setParent( mrPers.GetModel() );
312 :
313 30 : bool bSuccess = mrPers.GetEmbeddedObjectContainer().InsertEmbeddedObject( mxIPRef, rName );
314 30 : if (bSuccess)
315 : {
316 30 : if ( mpGraphic )
317 : ::svt::EmbeddedObjectRef::SetGraphicToContainer( *mpGraphic,
318 30 : mrPers.GetEmbeddedObjectContainer(),
319 : rName,
320 60 : OUString() );
321 :
322 30 : mxIPRef = 0;
323 : }
324 :
325 30 : return bSuccess;
326 : }
327 :
328 60 : DrawingOLEAdaptor::~DrawingOLEAdaptor()
329 : {
330 30 : if (mxIPRef.is())
331 : {
332 : OSL_ENSURE( !mrPers.GetEmbeddedObjectContainer().HasEmbeddedObject( mxIPRef ), "Object in adaptor is inserted?!" );
333 : try
334 : {
335 0 : uno::Reference < com::sun::star::util::XCloseable > xClose( mxIPRef, uno::UNO_QUERY );
336 0 : if ( xClose.is() )
337 0 : xClose->close(sal_True);
338 : }
339 0 : catch ( const com::sun::star::util::CloseVetoException& )
340 : {
341 : }
342 :
343 0 : mxIPRef = 0;
344 : }
345 30 : }
346 : }
347 :
348 : namespace util
349 : {
350 396 : SwTwips MakeSafePositioningValue(SwTwips nIn)
351 : {
352 396 : if (nIn > SHRT_MAX)
353 0 : nIn = SHRT_MAX;
354 396 : else if (nIn < SHRT_MIN)
355 0 : nIn = SHRT_MIN;
356 396 : return nIn;
357 : }
358 :
359 0 : void SetLayer::SendObjectToHell(SdrObject &rObject) const
360 : {
361 0 : SetObjectLayer(rObject, eHell);
362 0 : }
363 :
364 190 : void SetLayer::SendObjectToHeaven(SdrObject &rObject) const
365 : {
366 190 : SetObjectLayer(rObject, eHeaven);
367 190 : }
368 :
369 190 : void SetLayer::SetObjectLayer(SdrObject &rObject, Layer eLayer) const
370 : {
371 190 : if (FmFormInventor == rObject.GetObjInventor())
372 10 : rObject.SetLayer(mnFormLayer);
373 : else
374 : {
375 180 : switch (eLayer)
376 : {
377 : case eHeaven:
378 180 : rObject.SetLayer(mnHeavenLayer);
379 180 : break;
380 : case eHell:
381 0 : rObject.SetLayer(mnHellLayer);
382 0 : break;
383 : }
384 : }
385 190 : }
386 :
387 : //SetLayer boilerplate begin
388 0 : void SetLayer::Swap(SetLayer& rOther) throw()
389 : {
390 0 : std::swap(mnHeavenLayer, rOther.mnHeavenLayer);
391 0 : std::swap(mnHellLayer, rOther.mnHellLayer);
392 0 : std::swap(mnFormLayer, rOther.mnFormLayer);
393 0 : }
394 :
395 : // #i38889# - by default put objects into the invisible layers.
396 234 : SetLayer::SetLayer(const SwDoc &rDoc)
397 234 : : mnHeavenLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleHeavenId()),
398 234 : mnHellLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleHellId()),
399 468 : mnFormLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleControlsId())
400 : {
401 234 : }
402 :
403 106 : SetLayer::SetLayer(const SetLayer& rOther) throw()
404 : : mnHeavenLayer(rOther.mnHeavenLayer),
405 : mnHellLayer(rOther.mnHellLayer),
406 106 : mnFormLayer(rOther.mnFormLayer)
407 : {
408 106 : }
409 :
410 0 : SetLayer& SetLayer::operator=(const SetLayer& rOther) throw()
411 : {
412 0 : SetLayer aTemp(rOther);
413 0 : Swap(aTemp);
414 0 : return *this;
415 : }
416 : //SetLayer boilerplate end
417 :
418 64872 : void GetPoolItems(const SfxItemSet &rSet, PoolItems &rItems, bool bExportParentItemSet )
419 : {
420 64872 : if( bExportParentItemSet )
421 : {
422 2844 : sal_uInt16 nTotal = rSet.TotalCount();
423 313236 : for( sal_uInt16 nItem =0; nItem < nTotal; ++nItem )
424 : {
425 310392 : const SfxPoolItem* pItem = 0;
426 310392 : if( SfxItemState::SET == rSet.GetItemState( rSet.GetWhichByPos( nItem ), true, &pItem ) )
427 : {
428 17552 : rItems[pItem->Which()] = pItem;
429 : }
430 : }
431 : }
432 62028 : else if( rSet.Count())
433 : {
434 45626 : SfxItemIter aIter(rSet);
435 45626 : if (const SfxPoolItem *pItem = aIter.GetCurItem())
436 : {
437 252624 : do
438 252624 : rItems[pItem->Which()] = pItem;
439 252624 : while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
440 45626 : }
441 : }
442 64872 : }
443 :
444 20258 : const SfxPoolItem *SearchPoolItems(const PoolItems &rItems,
445 : sal_uInt16 eType)
446 : {
447 20258 : sw::cPoolItemIter aIter = rItems.find(eType);
448 20258 : if (aIter != rItems.end())
449 2098 : return aIter->second;
450 18160 : return 0;
451 : }
452 :
453 2098 : void ClearOverridesFromSet(const SwFmtCharFmt &rFmt, SfxItemSet &rSet)
454 : {
455 2098 : if (const SwCharFmt* pCharFmt = rFmt.GetCharFmt())
456 : {
457 2098 : if (pCharFmt->GetAttrSet().Count())
458 : {
459 1962 : SfxItemIter aIter(pCharFmt->GetAttrSet());
460 1962 : const SfxPoolItem *pItem = aIter.GetCurItem();
461 4256 : do
462 4256 : rSet.ClearItem(pItem->Which());
463 6218 : while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
464 : }
465 : }
466 2098 : }
467 :
468 0 : ParaStyles GetParaStyles(const SwDoc &rDoc)
469 : {
470 0 : ParaStyles aStyles;
471 : typedef ParaStyles::size_type mysizet;
472 :
473 0 : const SwTxtFmtColls *pColls = rDoc.GetTxtFmtColls();
474 0 : mysizet nCount = pColls ? pColls->size() : 0;
475 0 : aStyles.reserve(nCount);
476 0 : for (mysizet nI = 0; nI < nCount; ++nI)
477 0 : aStyles.push_back((*pColls)[ static_cast< sal_uInt16 >(nI) ]);
478 0 : return aStyles;
479 : }
480 :
481 1492 : SwTxtFmtColl* GetParaStyle(SwDoc &rDoc, const OUString& rName)
482 : {
483 : // Search first in the Doc-Styles
484 1492 : SwTxtFmtColl* pColl = rDoc.FindTxtFmtCollByName(rName);
485 1492 : if (!pColl)
486 : {
487 : // Collection not found, try in Pool ?
488 : sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
489 1292 : nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL);
490 1292 : if (n != SAL_MAX_UINT16) // found or standard
491 70 : pColl = rDoc.getIDocumentStylePoolAccess().GetTxtCollFromPool(n, false);
492 : }
493 1492 : return pColl;
494 : }
495 :
496 1580 : SwCharFmt* GetCharStyle(SwDoc &rDoc, const OUString& rName)
497 : {
498 1580 : SwCharFmt *pFmt = rDoc.FindCharFmtByName(rName);
499 1580 : if (!pFmt)
500 : {
501 : // Collection not found, try in Pool ?
502 : sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
503 1400 : nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
504 1400 : if (n != SAL_MAX_UINT16) // found or standard
505 32 : pFmt = rDoc.getIDocumentStylePoolAccess().GetCharFmtFromPool(n);
506 : }
507 1580 : return pFmt;
508 : }
509 :
510 : // #i98791# - adjust sorting algorithm
511 0 : void SortByAssignedOutlineStyleListLevel(ParaStyles &rStyles)
512 : {
513 0 : std::sort(rStyles.begin(), rStyles.end(), outlinecmp());
514 0 : }
515 :
516 : /*
517 : Utility to extract flyfmts from a document, potentially from a
518 : selection.
519 : */
520 1032 : Frames GetFrames(const SwDoc &rDoc, SwPaM *pPaM /*, bool bAll*/)
521 : {
522 1032 : SwPosFlyFrms aFlys(rDoc.GetAllFlyFmts(pPaM, true));
523 1032 : sw::Frames aRet(SwPosFlyFrmsToFrames(aFlys));
524 1032 : return aRet;
525 : }
526 :
527 28688 : Frames GetFramesInNode(const Frames &rFrames, const SwNode &rNode)
528 : {
529 28688 : Frames aRet;
530 : my_copy_if(rFrames.begin(), rFrames.end(),
531 28688 : std::back_inserter(aRet), anchoredto(rNode.GetIndex()));
532 28688 : return aRet;
533 : }
534 :
535 262 : const SwNumFmt* GetNumFmtFromSwNumRuleLevel(const SwNumRule &rRule,
536 : int nLevel)
537 : {
538 262 : if (nLevel < 0 || nLevel >= MAXLEVEL)
539 : {
540 : OSL_FAIL("Invalid level");
541 0 : return NULL;
542 : }
543 262 : return &(rRule.Get( static_cast< sal_uInt16 >(nLevel) ));
544 : }
545 :
546 2742 : const SwNumFmt* GetNumFmtFromTxtNode(const SwTxtNode &rTxtNode)
547 : {
548 2742 : const SwNumRule *pRule = 0;
549 2742 : if (
550 2742 : rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
551 : 0 != (pRule = rTxtNode.GetNumRule())
552 : )
553 : {
554 : return GetNumFmtFromSwNumRuleLevel(*pRule,
555 262 : rTxtNode.GetActualListLevel());
556 : }
557 :
558 : OSL_ENSURE(rTxtNode.GetDoc(), "No document for node?, suspicious");
559 2480 : if (!rTxtNode.GetDoc())
560 0 : return 0;
561 :
562 2480 : if (
563 2480 : rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
564 0 : 0 != (pRule = rTxtNode.GetDoc()->GetOutlineNumRule())
565 : )
566 : {
567 : return GetNumFmtFromSwNumRuleLevel(*pRule,
568 0 : rTxtNode.GetActualListLevel());
569 : }
570 :
571 2480 : return 0;
572 : }
573 :
574 5542 : const SwNumRule* GetNumRuleFromTxtNode(const SwTxtNode &rTxtNode)
575 : {
576 5542 : return GetNormalNumRuleFromTxtNode(rTxtNode);
577 : }
578 :
579 5542 : const SwNumRule* GetNormalNumRuleFromTxtNode(const SwTxtNode &rTxtNode)
580 : {
581 5542 : const SwNumRule *pRule = 0;
582 :
583 5542 : if (
584 5542 : rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
585 : 0 != (pRule = rTxtNode.GetNumRule())
586 : )
587 : {
588 674 : return pRule;
589 : }
590 4868 : return 0;
591 : }
592 :
593 14 : SwNoTxtNode *GetNoTxtNodeFromSwFrmFmt(const SwFrmFmt &rFmt)
594 : {
595 14 : const SwNodeIndex *pIndex = rFmt.GetCntnt().GetCntntIdx();
596 : OSL_ENSURE(pIndex, "No NodeIndex in SwFrmFmt ?, suspicious");
597 14 : if (!pIndex)
598 0 : return 0;
599 14 : SwNodeIndex aIdx(*pIndex, 1);
600 14 : return aIdx.GetNode().GetNoTxtNode();
601 : }
602 :
603 0 : bool HasPageBreak(const SwNode &rNd)
604 : {
605 0 : const SvxFmtBreakItem *pBreak = 0;
606 0 : if (rNd.IsTableNode() && rNd.GetTableNode())
607 : {
608 0 : const SwTable& rTable = rNd.GetTableNode()->GetTable();
609 0 : const SwFrmFmt* pApply = rTable.GetFrmFmt();
610 : OSL_ENSURE(pApply, "impossible");
611 0 : if (pApply)
612 0 : pBreak = &(ItemGet<SvxFmtBreakItem>(*pApply, RES_BREAK));
613 : }
614 0 : else if (const SwCntntNode *pNd = rNd.GetCntntNode())
615 0 : pBreak = &(ItemGet<SvxFmtBreakItem>(*pNd, RES_BREAK));
616 :
617 0 : if (pBreak && pBreak->GetBreak() == SVX_BREAK_PAGE_BEFORE)
618 0 : return true;
619 0 : return false;
620 : }
621 :
622 6 : Polygon PolygonFromPolyPolygon(const tools::PolyPolygon &rPolyPoly)
623 : {
624 6 : if(1 == rPolyPoly.Count())
625 : {
626 6 : return rPolyPoly[0];
627 : }
628 : else
629 : {
630 : // This method will now just concatenate the polygons contained
631 : // in the given PolyPolygon. Anything else which might be thought of
632 : // for reducing to a single polygon will just need nore power and
633 : // cannot create more correct results.
634 0 : sal_uInt32 nPointCount(0L);
635 : sal_uInt16 a;
636 :
637 0 : for(a = 0; a < rPolyPoly.Count(); a++)
638 : {
639 0 : nPointCount += (sal_uInt32)rPolyPoly[a].GetSize();
640 : }
641 :
642 0 : if(nPointCount > 0x0000ffff)
643 : {
644 : OSL_FAIL("PolygonFromPolyPolygon: too many points for a single polygon (!)");
645 0 : nPointCount = 0x0000ffff;
646 : }
647 :
648 0 : Polygon aRetval((sal_uInt16)nPointCount);
649 0 : sal_uInt32 nAppendIndex(0L);
650 :
651 0 : for(a = 0; a < rPolyPoly.Count(); a++)
652 : {
653 0 : const Polygon& rCandidate = rPolyPoly[a];
654 :
655 0 : for(sal_uInt16 b(0); nAppendIndex <= nPointCount && b < rCandidate.GetSize(); b++)
656 : {
657 0 : aRetval[(sal_uInt16)nAppendIndex++] = rCandidate[b];
658 : }
659 : }
660 :
661 0 : return aRetval;
662 : }
663 : }
664 :
665 6 : Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon& rPolyPoly, const SwNoTxtNode* pNd)
666 : {
667 6 : Polygon aPoly(PolygonFromPolyPolygon(rPolyPoly));
668 6 : const Size &rOrigSize = pNd->GetGraphic().GetPrefSize();
669 6 : Fraction aMapPolyX(ww::nWrap100Percent, rOrigSize.Width());
670 6 : Fraction aMapPolyY(ww::nWrap100Percent, rOrigSize.Height());
671 6 : aPoly.Scale(aMapPolyX, aMapPolyY);
672 :
673 : /*
674 : a) stretch right bound by 15twips
675 : b) shrink bottom bound to where it would have been in word
676 : c) Move it to the left by 15twips
677 :
678 : See the import for details
679 : */
680 6 : const Size &rSize = pNd->GetTwipSize();
681 6 : Fraction aMoveHack(ww::nWrap100Percent, rSize.Width());
682 6 : aMoveHack *= Fraction(15, 1);
683 6 : long nMove(aMoveHack);
684 :
685 : Fraction aHackX(ww::nWrap100Percent + nMove,
686 6 : ww::nWrap100Percent);
687 : Fraction aHackY(ww::nWrap100Percent - nMove,
688 6 : ww::nWrap100Percent);
689 6 : aPoly.Scale(aHackX, aHackY);
690 :
691 6 : aPoly.Move(-nMove, 0);
692 6 : return aPoly;
693 : }
694 :
695 504 : Size GetSwappedInSize(const SwNoTxtNode& rNd)
696 : {
697 504 : Size aGrTwipSz(rNd.GetTwipSize());
698 504 : if ((!aGrTwipSz.Width() || !aGrTwipSz.Height()))
699 : {
700 22 : SwGrfNode *pGrfNode = const_cast<SwGrfNode*>(rNd.GetGrfNode());
701 22 : if (pGrfNode && (GRAPHIC_NONE != pGrfNode->GetGrf().GetType()))
702 : {
703 18 : bool bWasSwappedOut = pGrfNode->GetGrfObj().IsSwappedOut();
704 18 : pGrfNode->SwapIn();
705 18 : aGrTwipSz = pGrfNode->GetTwipSize();
706 18 : if (bWasSwappedOut)
707 0 : pGrfNode->SwapOut();
708 : }
709 : }
710 :
711 : OSL_ENSURE(aGrTwipSz.Width() && aGrTwipSz.Height(), "0 x 0 graphic ?");
712 504 : return aGrTwipSz;
713 : }
714 :
715 10 : void RedlineStack::open(const SwPosition& rPos, const SfxPoolItem& rAttr)
716 : {
717 : OSL_ENSURE(rAttr.Which() == RES_FLTR_REDLINE, "not a redline");
718 10 : maStack.push_back(new SwFltStackEntry(rPos,rAttr.Clone()));
719 10 : }
720 :
721 : class SameOpenRedlineType :
722 : public std::unary_function<const SwFltStackEntry*, bool>
723 : {
724 : private:
725 : RedlineType_t meType;
726 : public:
727 10 : SameOpenRedlineType(RedlineType_t eType) : meType(eType) {}
728 10 : bool operator()(const SwFltStackEntry *pEntry) const
729 : {
730 : const SwFltRedline *pTest = static_cast<const SwFltRedline *>
731 10 : (pEntry->pAttr);
732 10 : return (pEntry->bOpen && (pTest->eType == meType));
733 : }
734 : };
735 :
736 10 : bool RedlineStack::close(const SwPosition& rPos, RedlineType_t eType)
737 : {
738 : //Search from end for same type
739 : myriter aResult = std::find_if(maStack.rbegin(), maStack.rend(),
740 10 : SameOpenRedlineType(eType));
741 10 : if (aResult != maStack.rend())
742 : {
743 10 : (*aResult)->SetEndPos(rPos);
744 10 : return true;
745 : }
746 0 : return false;
747 : }
748 :
749 814 : void RedlineStack::closeall(const SwPosition& rPos)
750 : {
751 814 : std::for_each(maStack.begin(), maStack.end(), SetEndIfOpen(rPos));
752 814 : }
753 :
754 10 : void SetInDocAndDelete::operator()(SwFltStackEntry *pEntry)
755 : {
756 10 : SwPaM aRegion(pEntry->m_aMkPos.m_nNode);
757 10 : if (
758 20 : pEntry->MakeRegion(&mrDoc, aRegion, true) &&
759 10 : (*aRegion.GetPoint() != *aRegion.GetMark())
760 : )
761 : {
762 10 : mrDoc.getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT |
763 10 : nsRedlineMode_t::REDLINE_SHOW_DELETE));
764 : const SwFltRedline *pFltRedline = static_cast<const SwFltRedline*>
765 10 : (pEntry->pAttr);
766 :
767 10 : if (USHRT_MAX != pFltRedline->nAutorNoPrev)
768 : {
769 : SwRedlineData aData(pFltRedline->eTypePrev,
770 : pFltRedline->nAutorNoPrev, pFltRedline->aStampPrev, OUString(),
771 0 : 0);
772 :
773 0 : mrDoc.getIDocumentRedlineAccess().AppendRedline(new SwRangeRedline(aData, aRegion), true);
774 : }
775 :
776 : SwRedlineData aData(pFltRedline->eType, pFltRedline->nAutorNo,
777 10 : pFltRedline->aStamp, OUString(), 0);
778 :
779 10 : SwRangeRedline *const pNewRedline(new SwRangeRedline(aData, aRegion));
780 : // the point node may be deleted in AppendRedline, so park
781 : // the PaM somewhere safe
782 10 : aRegion.DeleteMark();
783 10 : *aRegion.GetPoint() = SwPosition(SwNodeIndex(mrDoc.GetNodes()));
784 10 : mrDoc.getIDocumentRedlineAccess().AppendRedline(pNewRedline, true);
785 10 : mrDoc.getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_NONE | nsRedlineMode_t::REDLINE_SHOW_INSERT |
786 10 : nsRedlineMode_t::REDLINE_SHOW_DELETE ));
787 : }
788 10 : delete pEntry;
789 10 : }
790 :
791 6 : bool CompareRedlines::operator()(const SwFltStackEntry *pOneE,
792 : const SwFltStackEntry *pTwoE) const
793 : {
794 : const SwFltRedline *pOne= static_cast<const SwFltRedline*>
795 6 : (pOneE->pAttr);
796 : const SwFltRedline *pTwo= static_cast<const SwFltRedline*>
797 6 : (pTwoE->pAttr);
798 :
799 : //Return the earlier time, if two have the same time, prioritize
800 : //inserts over deletes
801 6 : if (pOne->aStamp == pTwo->aStamp)
802 2 : return (pOne->eType == nsRedlineType_t::REDLINE_INSERT && pTwo->eType != nsRedlineType_t::REDLINE_INSERT);
803 : else
804 4 : return (pOne->aStamp < pTwo->aStamp);
805 : }
806 :
807 1628 : RedlineStack::~RedlineStack()
808 : {
809 814 : std::sort(maStack.begin(), maStack.end(), CompareRedlines());
810 814 : std::for_each(maStack.begin(), maStack.end(), SetInDocAndDelete(mrDoc));
811 814 : }
812 :
813 16 : sal_uInt16 WrtRedlineAuthor::AddName( const OUString& rNm )
814 : {
815 : sal_uInt16 nRet;
816 : typedef std::vector<OUString>::iterator myiter;
817 16 : myiter aIter = std::find(maAuthors.begin(), maAuthors.end(), rNm);
818 16 : if (aIter != maAuthors.end())
819 4 : nRet = static_cast< sal_uInt16 >(aIter - maAuthors.begin());
820 : else
821 : {
822 12 : nRet = static_cast< sal_uInt16 >(maAuthors.size());
823 12 : maAuthors.push_back(rNm);
824 : }
825 16 : return nRet;
826 : }
827 : }
828 :
829 : namespace util
830 : {
831 0 : InsertedTableClient::InsertedTableClient(SwTableNode & rNode)
832 : {
833 0 : rNode.Add(this);
834 0 : }
835 :
836 0 : SwTableNode * InsertedTableClient::GetTableNode()
837 : {
838 0 : return dynamic_cast<SwTableNode *> (GetRegisteredInNonConst());
839 : }
840 :
841 190 : InsertedTablesManager::InsertedTablesManager(const SwDoc &rDoc)
842 190 : : mbHasRoot(rDoc.getIDocumentLayoutAccess().GetCurrentLayout())
843 : {
844 190 : }
845 :
846 186 : void InsertedTablesManager::DelAndMakeTblFrms()
847 : {
848 186 : if (!mbHasRoot)
849 372 : return;
850 0 : TblMapIter aEnd = maTables.end();
851 0 : for (TblMapIter aIter = maTables.begin(); aIter != aEnd; ++aIter)
852 : {
853 : // exitiert schon ein Layout, dann muss an dieser Tabelle die BoxFrames
854 : // neu erzeugt
855 0 : SwTableNode *pTable = aIter->first->GetTableNode();
856 : OSL_ENSURE(pTable, "Why no expected table");
857 0 : if (pTable)
858 : {
859 0 : SwFrmFmt * pFrmFmt = pTable->GetTable().GetFrmFmt();
860 :
861 0 : if (pFrmFmt != NULL)
862 : {
863 0 : SwNodeIndex *pIndex = aIter->second;
864 0 : pTable->DelFrms();
865 0 : pTable->MakeFrms(pIndex);
866 : }
867 : }
868 : }
869 : }
870 :
871 140 : void InsertedTablesManager::InsertTable(SwTableNode &rTableNode, SwPaM &rPaM)
872 : {
873 140 : if (!mbHasRoot)
874 280 : return;
875 : //Associate this tablenode with this after position, replace an //old
876 : //node association if necessary
877 :
878 0 : InsertedTableClient * pClient = new InsertedTableClient(rTableNode);
879 :
880 0 : maTables.insert(TblMap::value_type(pClient, &(rPaM.GetPoint()->nNode)));
881 : }
882 : }
883 :
884 102 : }
885 :
886 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|