bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / filter / ww8 / writerhelper.cxx
blobfad2d679b02626ac6a1a26fd86f70d2c348f8b38
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <com/sun/star/util/XCloseable.hpp>
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>
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
54 using namespace com::sun::star;
55 using namespace nsSwGetPoolIdFromName;
58 namespace
61 Stroustroup forgets copy_if, See C++ Programming language Chp 18, pg 530
63 template <typename In , typename Out , typename Pred>
64 Out my_copy_if(In first, In last, Out res, Pred p)
66 while (first != last)
68 if (p(*first))
69 *res = *first;
70 ++first;
72 return res;
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>
80 public:
81 bool operator()(const SwTxtFmtColl *pA, const SwTxtFmtColl *pB) const
83 // #i98791#
84 bool bResult( false );
85 const bool bIsAAssignedToOutlineStyle( pA->IsAssignedToListLevelOfOutlineStyle() );
86 const bool bIsBAssignedToOutlineStyle( pB->IsAssignedToListLevelOfOutlineStyle() );
87 if ( bIsAAssignedToOutlineStyle != bIsBAssignedToOutlineStyle )
89 bResult = bIsBAssignedToOutlineStyle;
91 else if ( !bIsAAssignedToOutlineStyle )
93 // pA and pB are equal regarding the sorting criteria.
94 // Thus return value does not matter.
95 bResult = false;
97 else
99 bResult = pA->GetAssignedOutlineStyleLevel() < pB->GetAssignedOutlineStyleLevel();
102 return bResult;
106 bool IsValidSlotWhich(sal_uInt16 nSlotId, sal_uInt16 nWhichId)
108 return (nSlotId != 0 && nWhichId != 0 && nSlotId != nWhichId);
112 Utility to convert a SwPosFlyFrms into a simple vector of sw::Frames
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
118 sw::Frames SwPosFlyFrmsToFrames(const SwPosFlyFrms &rFlys)
120 sw::Frames aRet;
122 for(SwPosFlyFrms::const_iterator aIter(rFlys.begin()); aIter != rFlys.end(); ++aIter)
124 const SwFrmFmt &rEntry = (*aIter)->GetFmt();
126 if (const SwPosition* pAnchor = rEntry.GetAnchor().GetCntntAnchor())
128 aRet.push_back(sw::Frame(rEntry, *pAnchor));
130 else
132 SwPosition aPos((*aIter)->GetNdIndex());
134 if (SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode())
136 aPos.nContent.Assign(pTxtNd, 0);
139 aRet.push_back(sw::Frame(rEntry, aPos));
142 return aRet;
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>
148 private:
149 sal_uLong mnNode;
150 public:
151 anchoredto(sal_uLong nNode) : mnNode(nNode) {}
152 bool operator()(const sw::Frame &rFrame) const
154 return (mnNode == rFrame.GetPosition().nNode.GetNode().GetIndex());
159 namespace sw
161 //For i120928,size conversion before exporting graphic of bullet
162 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 , maGrf(rGrf)
173 const MapMode aMap100mm( MAP_100TH_MM );
174 Size aSize( rGrf.GetPrefSize() );
175 if ( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
177 aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap100mm );
179 else
181 aSize = OutputDevice::LogicToLogic( aSize,rGrf.GetPrefMapMode(), aMap100mm );
183 maSize = aSize;
184 maLayoutSize = maSize;
187 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 , mbIsInline( (rFmt.GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
196 // #i120928# - handle graphic of bullet within existing implementation
197 , mbForBullet(false)
198 , maGrf()
200 switch (rFmt.Which())
202 case RES_FLYFRMFMT:
203 if (const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx())
205 SwNodeIndex aIdx(*pIdx, 1);
206 const SwNode &rNd = aIdx.GetNode();
207 using sw::util::GetSwappedInSize;
208 // #i43447# - determine layout size
210 SwRect aLayRect( rFmt.FindLayoutRect() );
211 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 if ( aLayRect.IsEmpty() )
216 aRect.SetSize( rFmt.GetFrmSize().GetSize() );
218 maLayoutSize = aRect.GetSize();
220 switch (rNd.GetNodeType())
222 case ND_GRFNODE:
223 meWriterType = eGraphic;
224 maSize = GetSwappedInSize(*rNd.GetNoTxtNode());
225 break;
226 case ND_OLENODE:
227 meWriterType = eOle;
228 maSize = GetSwappedInSize(*rNd.GetNoTxtNode());
229 break;
230 default:
231 meWriterType = eTxtBox;
232 // #i43447# - Size equals layout size for text boxes
233 maSize = maLayoutSize;
234 break;
236 mpStartFrameContent = &rNd;
238 else
240 OSL_ENSURE(!this, "Impossible");
241 meWriterType = eTxtBox;
243 break;
244 default:
245 if (const SdrObject* pObj = rFmt.FindRealSdrObject())
247 if (pObj->GetObjInventor() == FmFormInventor)
248 meWriterType = eFormControl;
249 else
250 meWriterType = eDrawing;
251 maSize = pObj->GetSnapRect().GetSize();
253 else
255 OSL_ENSURE(!this, "Impossible");
256 meWriterType = eDrawing;
258 break;
262 bool Frame::IsInline() const
264 return mbIsInline;
267 void Frame::ForceTreatAsInline()
269 mbIsInline = true;
272 namespace hack
275 sal_uInt16 TransformWhichBetweenPools(const SfxItemPool &rDestPool,
276 const SfxItemPool &rSrcPool, sal_uInt16 nWhich)
278 sal_uInt16 nSlotId = rSrcPool.GetSlotId(nWhich);
279 if (IsValidSlotWhich(nSlotId, nWhich))
280 nWhich = rDestPool.GetWhich(nSlotId);
281 else
282 nWhich = 0;
283 return nWhich;
286 sal_uInt16 GetSetWhichFromSwDocWhich(const SfxItemSet &rSet,
287 const SwDoc &rDoc, sal_uInt16 nWhich)
289 if (RES_WHICHHINT_END < *(rSet.GetRanges()))
291 nWhich = TransformWhichBetweenPools(*rSet.GetPool(),
292 rDoc.GetAttrPool(), nWhich);
294 return nWhich;
297 DrawingOLEAdaptor::DrawingOLEAdaptor(SdrOle2Obj &rObj,
298 SfxObjectShell &rPers)
299 : msOrigPersistName(rObj.GetPersistName()),
300 mxIPRef(rObj.GetObjRef()), mrPers(rPers),
301 mpGraphic( rObj.GetGraphic() )
303 rObj.AbandonObject();
306 bool DrawingOLEAdaptor::TransferToDoc( OUString &rName )
308 OSL_ENSURE(mxIPRef.is(), "Transferring invalid object to doc");
309 if (!mxIPRef.is())
310 return false;
312 uno::Reference < container::XChild > xChild( mxIPRef, uno::UNO_QUERY );
313 if ( xChild.is() )
314 xChild->setParent( mrPers.GetModel() );
316 bool bSuccess = mrPers.GetEmbeddedObjectContainer().InsertEmbeddedObject( mxIPRef, rName );
317 if (bSuccess)
319 if ( mpGraphic )
320 ::svt::EmbeddedObjectRef::SetGraphicToContainer( *mpGraphic,
321 mrPers.GetEmbeddedObjectContainer(),
322 rName,
323 OUString() );
325 mxIPRef = 0;
328 return bSuccess;
331 DrawingOLEAdaptor::~DrawingOLEAdaptor()
333 if (mxIPRef.is())
335 OSL_ENSURE( !mrPers.GetEmbeddedObjectContainer().HasEmbeddedObject( mxIPRef ), "Object in adaptor is inserted?!" );
338 uno::Reference < com::sun::star::util::XCloseable > xClose( mxIPRef, uno::UNO_QUERY );
339 if ( xClose.is() )
340 xClose->close(sal_True);
342 catch ( const com::sun::star::util::CloseVetoException& )
346 mxIPRef = 0;
351 namespace util
353 SwTwips MakeSafePositioningValue(SwTwips nIn)
355 if (nIn > SHRT_MAX)
356 nIn = SHRT_MAX;
357 else if (nIn < SHRT_MIN)
358 nIn = SHRT_MIN;
359 return nIn;
362 void SetLayer::SendObjectToHell(SdrObject &rObject) const
364 SetObjectLayer(rObject, eHell);
367 void SetLayer::SendObjectToHeaven(SdrObject &rObject) const
369 SetObjectLayer(rObject, eHeaven);
372 void SetLayer::SetObjectLayer(SdrObject &rObject, Layer eLayer) const
374 if (FmFormInventor == rObject.GetObjInventor())
375 rObject.SetLayer(mnFormLayer);
376 else
378 switch (eLayer)
380 case eHeaven:
381 rObject.SetLayer(mnHeavenLayer);
382 break;
383 case eHell:
384 rObject.SetLayer(mnHellLayer);
385 break;
390 //SetLayer boilerplate begin
391 void SetLayer::Swap(SetLayer& rOther) throw()
393 std::swap(mnHeavenLayer, rOther.mnHeavenLayer);
394 std::swap(mnHellLayer, rOther.mnHellLayer);
395 std::swap(mnFormLayer, rOther.mnFormLayer);
398 // #i38889# - by default put objects into the invisible layers.
399 SetLayer::SetLayer(const SwDoc &rDoc)
400 : mnHeavenLayer(rDoc.GetInvisibleHeavenId()),
401 mnHellLayer(rDoc.GetInvisibleHellId()),
402 mnFormLayer(rDoc.GetInvisibleControlsId())
406 SetLayer::SetLayer(const SetLayer& rOther) throw()
407 : mnHeavenLayer(rOther.mnHeavenLayer),
408 mnHellLayer(rOther.mnHellLayer),
409 mnFormLayer(rOther.mnFormLayer)
413 SetLayer& SetLayer::operator=(const SetLayer& rOther) throw()
415 SetLayer aTemp(rOther);
416 Swap(aTemp);
417 return *this;
419 //SetLayer boilerplate end
421 void GetPoolItems(const SfxItemSet &rSet, PoolItems &rItems, bool bExportParentItemSet )
423 if( bExportParentItemSet )
425 sal_uInt16 nTotal = rSet.TotalCount();
426 for( sal_uInt16 nItem =0; nItem < nTotal; ++nItem )
428 const SfxPoolItem* pItem = 0;
429 if( SFX_ITEM_SET == rSet.GetItemState( rSet.GetWhichByPos( nItem ), true, &pItem ) )
431 rItems[pItem->Which()] = pItem;
435 else if( rSet.Count())
437 SfxItemIter aIter(rSet);
438 if (const SfxPoolItem *pItem = aIter.GetCurItem())
441 rItems[pItem->Which()] = pItem;
442 while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
447 const SfxPoolItem *SearchPoolItems(const PoolItems &rItems,
448 sal_uInt16 eType)
450 sw::cPoolItemIter aIter = rItems.find(eType);
451 if (aIter != rItems.end())
452 return aIter->second;
453 return 0;
456 void ClearOverridesFromSet(const SwFmtCharFmt &rFmt, SfxItemSet &rSet)
458 if (const SwCharFmt* pCharFmt = rFmt.GetCharFmt())
460 if (pCharFmt->GetAttrSet().Count())
462 SfxItemIter aIter(pCharFmt->GetAttrSet());
463 const SfxPoolItem *pItem = aIter.GetCurItem();
465 rSet.ClearItem(pItem->Which());
466 while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
471 ParaStyles GetParaStyles(const SwDoc &rDoc)
473 ParaStyles aStyles;
474 typedef ParaStyles::size_type mysizet;
476 const SwTxtFmtColls *pColls = rDoc.GetTxtFmtColls();
477 mysizet nCount = pColls ? pColls->size() : 0;
478 aStyles.reserve(nCount);
479 for (mysizet nI = 0; nI < nCount; ++nI)
480 aStyles.push_back((*pColls)[ static_cast< sal_uInt16 >(nI) ]);
481 return aStyles;
484 SwTxtFmtColl* GetParaStyle(SwDoc &rDoc, const OUString& rName)
486 // Search first in the Doc-Styles
487 SwTxtFmtColl* pColl = rDoc.FindTxtFmtCollByName(rName);
488 if (!pColl)
490 // Collection not found, try in Pool ?
491 sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
492 nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL);
493 if (n != SAL_MAX_UINT16) // found or standard
494 pColl = rDoc.GetTxtCollFromPool(n, false);
496 return pColl;
499 SwCharFmt* GetCharStyle(SwDoc &rDoc, const OUString& rName)
501 SwCharFmt *pFmt = rDoc.FindCharFmtByName(rName);
502 if (!pFmt)
504 // Collection not found, try in Pool ?
505 sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
506 nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
507 if (n != SAL_MAX_UINT16) // found or standard
508 pFmt = rDoc.GetCharFmtFromPool(n);
510 return pFmt;
513 // #i98791# - adjust sorting algorithm
514 void SortByAssignedOutlineStyleListLevel(ParaStyles &rStyles)
516 std::sort(rStyles.begin(), rStyles.end(), outlinecmp());
520 Utility to extract flyfmts from a document, potentially from a
521 selection.
523 Frames GetFrames(const SwDoc &rDoc, SwPaM *pPaM /*, bool bAll*/)
525 SwPosFlyFrms aFlys(rDoc.GetAllFlyFmts(pPaM, true));
526 sw::Frames aRet(SwPosFlyFrmsToFrames(aFlys));
527 return aRet;
530 Frames GetFramesInNode(const Frames &rFrames, const SwNode &rNode)
532 Frames aRet;
533 my_copy_if(rFrames.begin(), rFrames.end(),
534 std::back_inserter(aRet), anchoredto(rNode.GetIndex()));
535 return aRet;
538 const SwNumFmt* GetNumFmtFromSwNumRuleLevel(const SwNumRule &rRule,
539 int nLevel)
541 if (nLevel < 0 || nLevel >= MAXLEVEL)
543 OSL_FAIL("Invalid level");
544 return NULL;
546 return &(rRule.Get( static_cast< sal_uInt16 >(nLevel) ));
549 const SwNumFmt* GetNumFmtFromTxtNode(const SwTxtNode &rTxtNode)
551 const SwNumRule *pRule = 0;
552 if (
553 rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
554 0 != (pRule = rTxtNode.GetNumRule())
557 return GetNumFmtFromSwNumRuleLevel(*pRule,
558 rTxtNode.GetActualListLevel());
561 OSL_ENSURE(rTxtNode.GetDoc(), "No document for node?, suspicious");
562 if (!rTxtNode.GetDoc())
563 return 0;
565 if (
566 rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
567 0 != (pRule = rTxtNode.GetDoc()->GetOutlineNumRule())
570 return GetNumFmtFromSwNumRuleLevel(*pRule,
571 rTxtNode.GetActualListLevel());
574 return 0;
577 const SwNumRule* GetNumRuleFromTxtNode(const SwTxtNode &rTxtNode)
579 return GetNormalNumRuleFromTxtNode(rTxtNode);
582 const SwNumRule* GetNormalNumRuleFromTxtNode(const SwTxtNode &rTxtNode)
584 const SwNumRule *pRule = 0;
586 if (
587 rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
588 0 != (pRule = rTxtNode.GetNumRule())
591 return pRule;
593 return 0;
597 SwNoTxtNode *GetNoTxtNodeFromSwFrmFmt(const SwFrmFmt &rFmt)
599 const SwNodeIndex *pIndex = rFmt.GetCntnt().GetCntntIdx();
600 OSL_ENSURE(pIndex, "No NodeIndex in SwFrmFmt ?, suspicious");
601 if (!pIndex)
602 return 0;
603 SwNodeIndex aIdx(*pIndex, 1);
604 return aIdx.GetNode().GetNoTxtNode();
607 bool HasPageBreak(const SwNode &rNd)
609 const SvxFmtBreakItem *pBreak = 0;
610 if (rNd.IsTableNode() && rNd.GetTableNode())
612 const SwTable& rTable = rNd.GetTableNode()->GetTable();
613 const SwFrmFmt* pApply = rTable.GetFrmFmt();
614 OSL_ENSURE(pApply, "impossible");
615 if (pApply)
616 pBreak = &(ItemGet<SvxFmtBreakItem>(*pApply, RES_BREAK));
618 else if (const SwCntntNode *pNd = rNd.GetCntntNode())
619 pBreak = &(ItemGet<SvxFmtBreakItem>(*pNd, RES_BREAK));
621 if (pBreak && pBreak->GetBreak() == SVX_BREAK_PAGE_BEFORE)
622 return true;
623 return false;
626 Polygon PolygonFromPolyPolygon(const PolyPolygon &rPolyPoly)
628 if(1 == rPolyPoly.Count())
630 return rPolyPoly[0];
632 else
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 sal_uInt32 nPointCount(0L);
639 sal_uInt16 a;
641 for(a = 0; a < rPolyPoly.Count(); a++)
643 nPointCount += (sal_uInt32)rPolyPoly[a].GetSize();
646 if(nPointCount > 0x0000ffff)
648 OSL_FAIL("PolygonFromPolyPolygon: too many points for a single polygon (!)");
649 nPointCount = 0x0000ffff;
652 Polygon aRetval((sal_uInt16)nPointCount);
653 sal_uInt32 nAppendIndex(0L);
655 for(a = 0; a < rPolyPoly.Count(); a++)
657 const Polygon& rCandidate = rPolyPoly[a];
659 for(sal_uInt16 b(0); nAppendIndex <= nPointCount && b < rCandidate.GetSize(); b++)
661 aRetval[(sal_uInt16)nAppendIndex++] = rCandidate[b];
665 return aRetval;
669 bool IsStarSymbol(const OUString &rFontName)
671 sal_Int32 nIndex = 0;
672 OUString sFamilyNm(GetNextFontToken(rFontName, nIndex));
673 return (sFamilyNm.equalsIgnoreAsciiCase("starsymbol") ||
674 sFamilyNm.equalsIgnoreAsciiCase("opensymbol"));
677 Size GetSwappedInSize(const SwNoTxtNode& rNd)
679 Size aGrTwipSz(rNd.GetTwipSize());
680 if ((!aGrTwipSz.Width() || !aGrTwipSz.Height()))
682 SwGrfNode *pGrfNode = const_cast<SwGrfNode*>(rNd.GetGrfNode());
683 if (pGrfNode && (GRAPHIC_NONE != pGrfNode->GetGrf().GetType()))
685 bool bWasSwappedOut = pGrfNode->GetGrfObj().IsSwappedOut();
686 pGrfNode->SwapIn();
687 aGrTwipSz = pGrfNode->GetTwipSize();
688 if (bWasSwappedOut)
689 pGrfNode->SwapOut();
693 OSL_ENSURE(aGrTwipSz.Width() && aGrTwipSz.Height(), "0 x 0 graphic ?");
694 return aGrTwipSz;
697 void RedlineStack::open(const SwPosition& rPos, const SfxPoolItem& rAttr)
699 OSL_ENSURE(rAttr.Which() == RES_FLTR_REDLINE, "not a redline");
700 maStack.push_back(new SwFltStackEntry(rPos,rAttr.Clone()));
704 class SameOpenRedlineType :
705 public std::unary_function<const SwFltStackEntry*, bool>
707 private:
708 RedlineType_t meType;
709 public:
710 SameOpenRedlineType(RedlineType_t eType) : meType(eType) {}
711 bool operator()(const SwFltStackEntry *pEntry) const
713 const SwFltRedline *pTest = static_cast<const SwFltRedline *>
714 (pEntry->pAttr);
715 return (pEntry->bOpen && (pTest->eType == meType));
719 bool RedlineStack::close(const SwPosition& rPos, RedlineType_t eType)
721 //Search from end for same type
722 myriter aResult = std::find_if(maStack.rbegin(), maStack.rend(),
723 SameOpenRedlineType(eType));
724 if (aResult != maStack.rend())
726 (*aResult)->SetEndPos(rPos);
727 return true;
729 return false;
732 void RedlineStack::closeall(const SwPosition& rPos)
734 std::for_each(maStack.begin(), maStack.end(), SetEndIfOpen(rPos));
737 void SetInDocAndDelete::operator()(SwFltStackEntry *pEntry)
739 SwPaM aRegion(pEntry->m_aMkPos.m_nNode);
740 if (
741 pEntry->MakeRegion(&mrDoc, aRegion, true) &&
742 (*aRegion.GetPoint() != *aRegion.GetMark())
745 mrDoc.SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT |
746 nsRedlineMode_t::REDLINE_SHOW_DELETE));
747 const SwFltRedline *pFltRedline = static_cast<const SwFltRedline*>
748 (pEntry->pAttr);
750 if (USHRT_MAX != pFltRedline->nAutorNoPrev)
752 SwRedlineData aData(pFltRedline->eTypePrev,
753 pFltRedline->nAutorNoPrev, pFltRedline->aStampPrev, aEmptyStr,
756 mrDoc.AppendRedline(new SwRedline(aData, aRegion), true);
759 SwRedlineData aData(pFltRedline->eType, pFltRedline->nAutorNo,
760 pFltRedline->aStamp, aEmptyStr, 0);
762 SwRedline *const pNewRedline(new SwRedline(aData, aRegion));
763 // the point node may be deleted in AppendRedline, so park
764 // the PaM somewhere safe
765 aRegion.DeleteMark();
766 *aRegion.GetPoint() = SwPosition(SwNodeIndex(mrDoc.GetNodes()));
767 mrDoc.AppendRedline(pNewRedline, true);
768 mrDoc.SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_NONE | nsRedlineMode_t::REDLINE_SHOW_INSERT |
769 nsRedlineMode_t::REDLINE_SHOW_DELETE ));
771 delete pEntry;
775 bool CompareRedlines::operator()(const SwFltStackEntry *pOneE,
776 const SwFltStackEntry *pTwoE) const
778 const SwFltRedline *pOne= static_cast<const SwFltRedline*>
779 (pOneE->pAttr);
780 const SwFltRedline *pTwo= static_cast<const SwFltRedline*>
781 (pTwoE->pAttr);
783 //Return the earlier time, if two have the same time, prioritize
784 //inserts over deletes
785 if (pOne->aStamp == pTwo->aStamp)
786 return (pOne->eType == nsRedlineType_t::REDLINE_INSERT && pTwo->eType != nsRedlineType_t::REDLINE_INSERT);
787 else
788 return (pOne->aStamp < pTwo->aStamp) ? true : false;
792 RedlineStack::~RedlineStack()
794 std::sort(maStack.begin(), maStack.end(), CompareRedlines());
795 std::for_each(maStack.begin(), maStack.end(), SetInDocAndDelete(mrDoc));
798 sal_uInt16 WrtRedlineAuthor::AddName( const OUString& rNm )
800 sal_uInt16 nRet;
801 typedef std::vector<OUString>::iterator myiter;
802 myiter aIter = std::find(maAuthors.begin(), maAuthors.end(), rNm);
803 if (aIter != maAuthors.end())
804 nRet = static_cast< sal_uInt16 >(aIter - maAuthors.begin());
805 else
807 nRet = static_cast< sal_uInt16 >(maAuthors.size());
808 maAuthors.push_back(rNm);
810 return nRet;
814 namespace util
816 InsertedTableClient::InsertedTableClient(SwTableNode & rNode)
818 rNode.Add(this);
821 SwTableNode * InsertedTableClient::GetTableNode()
823 return dynamic_cast<SwTableNode *> (GetRegisteredInNonConst());
826 InsertedTablesManager::InsertedTablesManager(const SwDoc &rDoc)
827 : mbHasRoot(rDoc.GetCurrentLayout()) //swmod 080218
831 void InsertedTablesManager::DelAndMakeTblFrms()
833 if (!mbHasRoot)
834 return;
835 TblMapIter aEnd = maTables.end();
836 for (TblMapIter aIter = maTables.begin(); aIter != aEnd; ++aIter)
838 // exitiert schon ein Layout, dann muss an dieser Tabelle die BoxFrames
839 // neu erzeugt
840 SwTableNode *pTable = aIter->first->GetTableNode();
841 OSL_ENSURE(pTable, "Why no expected table");
842 if (pTable)
844 SwFrmFmt * pFrmFmt = pTable->GetTable().GetFrmFmt();
846 if (pFrmFmt != NULL)
848 SwNodeIndex *pIndex = aIter->second;
849 pTable->DelFrms();
850 pTable->MakeFrms(pIndex);
856 void InsertedTablesManager::InsertTable(SwTableNode &rTableNode, SwPaM &rPaM)
858 if (!mbHasRoot)
859 return;
860 //Associate this tablenode with this after position, replace an //old
861 //node association if necessary
863 InsertedTableClient * pClient = new InsertedTableClient(rTableNode);
865 maTables.insert(TblMap::value_type(pClient, &(rPaM.GetPoint()->nNode)));
871 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */