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