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