merge the formfield patch from ooo-build
[ooovba.git] / sw / source / filter / ww8 / writerhelper.cxx
blob861587ff6ecc058e37ee03fec388565d9f5d36fd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: writerhelper.cxx,v $
10 * $Revision: 1.29 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
35 #include <com/sun/star/util/XCloseable.hpp>
37 #include <doc.hxx>
38 # include "writerhelper.hxx"
39 # include <msfilter.hxx>
40 #include <com/sun/star/container/XChild.hpp>
41 #include <com/sun/star/embed/EmbedStates.hpp>
43 #include <algorithm> //std::swap
44 #include <functional> //std::binary_function
45 # include <svtools/itemiter.hxx> //SfxItemIter
46 # include <svx/svdobj.hxx> //SdrObject
47 # include <svx/svdoole2.hxx> //SdrOle2Obj
48 # include <svx/fmglob.hxx> //FmFormInventor
49 # include <svx/brkitem.hxx> //SvxFmtBreakItem
50 # include <svx/tstpitem.hxx> //SvxTabStopItem
51 # include <ndtxt.hxx> //SwTxtNode
52 # include <ndnotxt.hxx> //SwNoTxtNode
53 # include <fmtcntnt.hxx> //SwFmtCntnt
54 # include <swtable.hxx> //SwTable
55 # include <frmfmt.hxx> //SwFrmFmt
56 # include <flypos.hxx> //SwPosFlyFrms
57 # include <fmtanchr.hxx> //SwFmtAnchor
58 # include <ndgrf.hxx> //SwGrfNode
59 # include <fmtfsize.hxx> //SwFmtFrmSize
60 # include <SwStyleNameMapper.hxx> //SwStyleNameMapper
61 # include <docary.hxx> //SwCharFmts
62 # include <charfmt.hxx> //SwCharFmt
63 # include <fchrfmt.hxx> //SwFmtCharFmt
64 #ifndef _UNOTOOLS_STREAMWRAP_HXX
65 # include <unotools/streamwrap.hxx>
66 #endif
67 #include <numrule.hxx>
69 #ifdef DEBUGDUMP
70 # include <vcl/svapp.hxx>
71 # ifndef _TOOLS_URLOBJ_HXX
72 # include <tools/urlobj.hxx>
73 # endif
74 # ifndef _UNOTOOLS_UCBSTREAMHELPER_HXX
75 # include <unotools/ucbstreamhelper.hxx>
76 # endif
77 # include <unotools/localfilehelper.hxx>
78 #endif
80 using namespace com::sun::star;
81 using namespace nsSwGetPoolIdFromName;
84 namespace
87 Stroustroup forgets copy_if, See C++ Programming language Chp 18, pg 530
89 template <typename In , typename Out , typename Pred>
90 Out my_copy_if(In first, In last, Out res, Pred p)
92 while (first != last)
94 if (p(*first))
95 *res = *first;
96 ++first;
98 return res;
101 // --> OD 2009-02-04 #i98791# - adjust sorting
102 //Utility to sort SwTxtFmtColl's by their assigned outline style list level
103 class outlinecmp : public
104 std::binary_function<const SwTxtFmtColl*, const SwTxtFmtColl*, bool>
106 public:
107 bool operator()(const SwTxtFmtColl *pA, const SwTxtFmtColl *pB) const
109 // --> OD 2009-02-04 #i98791#
110 // return pA->GetAttrOutlineLevel() < pB->GetAttrOutlineLevel(); //<-end,zhaojianwei
111 bool bResult( false );
112 const bool bIsAAssignedToOutlineStyle( pA->IsAssignedToListLevelOfOutlineStyle() );
113 const bool bIsBAssignedToOutlineStyle( pB->IsAssignedToListLevelOfOutlineStyle() );
114 if ( bIsAAssignedToOutlineStyle != bIsBAssignedToOutlineStyle )
116 bResult = bIsBAssignedToOutlineStyle;
118 else if ( !bIsAAssignedToOutlineStyle )
120 // pA and pB are equal regarding the sorting criteria.
121 // Thus return value does not matter.
122 bResult = false;
124 else
126 bResult = pA->GetAssignedOutlineStyleLevel() < pB->GetAssignedOutlineStyleLevel();
129 return bResult;
130 // <--
133 // <--
135 bool IsValidSlotWhich(USHORT nSlotId, USHORT nWhichId)
137 return (nSlotId != 0 && nWhichId != 0 && nSlotId != nWhichId);
141 Utility to convert a SwPosFlyFrms into a simple vector of sw::Frames
143 The crucial thing is that a sw::Frame always has an anchor which
144 points to some content in the document. This is a requirement of exporting
145 to Word
147 sw::Frames SwPosFlyFrmsToFrames(const SwPosFlyFrms &rFlys)
149 sw::Frames aRet;
150 USHORT nEnd = rFlys.Count();
151 for (USHORT nI = 0; nI < nEnd; ++nI)
153 const SwFrmFmt &rEntry = rFlys[nI]->GetFmt();
154 if (const SwPosition* pAnchor = rEntry.GetAnchor().GetCntntAnchor())
155 aRet.push_back(sw::Frame(rEntry, *pAnchor));
156 else
158 SwPosition aPos(rFlys[nI]->GetNdIndex());
159 if (SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode())
160 aPos.nContent.Assign(pTxtNd, 0);
161 aRet.push_back(sw::Frame(rEntry, aPos));
164 return aRet;
167 //Utility to test if a frame is anchored at a given node index
168 class anchoredto: public std::unary_function<const sw::Frame&, bool>
170 private:
171 ULONG mnNode;
172 public:
173 anchoredto(ULONG nNode) : mnNode(nNode) {}
174 bool operator()(const sw::Frame &rFrame) const
176 return (mnNode == rFrame.GetPosition().nNode.GetNode().GetIndex());
181 namespace sw
183 Frame::Frame(const SwFrmFmt &rFmt, const SwPosition &rPos)
184 : mpFlyFrm(&rFmt),
185 maPos(rPos),
186 maSize(),
187 // --> OD 2007-04-19 #i43447#
188 maLayoutSize(),
189 // <--
190 meWriterType(eTxtBox),
191 mpStartFrameContent(0),
192 // --> OD 2007-04-19 #i43447# - move to initialization list
193 mbIsInline( (rFmt.GetAnchor().GetAnchorId() == FLY_IN_CNTNT) )
194 // <--
196 switch (rFmt.Which())
198 case RES_FLYFRMFMT:
199 if (const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx())
201 SwNodeIndex aIdx(*pIdx, 1);
202 const SwNode &rNd = aIdx.GetNode();
203 using sw::util::GetSwappedInSize;
204 // --> OD 2007-04-19 #i43447# - determine layout size
206 SwRect aLayRect( rFmt.FindLayoutRect() );
207 Rectangle aRect( aLayRect.SVRect() );
208 // The Object is not rendered (e.g. something in unused
209 // header/footer) - thus, get the values from the format.
210 if ( aLayRect.IsEmpty() )
212 aRect.SetSize( rFmt.GetFrmSize().GetSize() );
214 maLayoutSize = aRect.GetSize();
216 // <--
217 switch (rNd.GetNodeType())
219 case ND_GRFNODE:
220 meWriterType = eGraphic;
221 maSize = GetSwappedInSize(*rNd.GetNoTxtNode());
222 break;
223 case ND_OLENODE:
224 meWriterType = eOle;
225 maSize = GetSwappedInSize(*rNd.GetNoTxtNode());
226 break;
227 default:
228 meWriterType = eTxtBox;
229 // --> OD 2007-04-19 #i43447#
230 // Size equals layout size for text boxes
231 maSize = maLayoutSize;
232 // <--
233 break;
235 mpStartFrameContent = &rNd;
237 else
239 ASSERT(!this, "Impossible");
240 meWriterType = eTxtBox;
242 break;
243 default:
244 if (const SdrObject* pObj = rFmt.FindRealSdrObject())
246 if (pObj->GetObjInventor() == FmFormInventor)
247 meWriterType = eFormControl;
248 else
249 meWriterType = eDrawing;
250 maSize = pObj->GetSnapRect().GetSize();
252 else
254 ASSERT(!this, "Impossible");
255 meWriterType = eDrawing;
257 break;
261 bool Frame::IsInline() const
263 return mbIsInline;
266 void Frame::ForceTreatAsInline()
268 mbIsInline = true;
271 namespace hack
274 USHORT TransformWhichBetweenPools(const SfxItemPool &rDestPool,
275 const SfxItemPool &rSrcPool, USHORT nWhich)
277 USHORT nSlotId = rSrcPool.GetSlotId(nWhich);
278 if (IsValidSlotWhich(nSlotId, nWhich))
279 nWhich = rDestPool.GetWhich(nSlotId);
280 else
281 nWhich = 0;
282 return nWhich;
285 USHORT GetSetWhichFromSwDocWhich(const SfxItemSet &rSet,
286 const SwDoc &rDoc, USHORT nWhich)
288 if (RES_WHICHHINT_END < *(rSet.GetRanges()))
290 nWhich = TransformWhichBetweenPools(*rSet.GetPool(),
291 rDoc.GetAttrPool(), nWhich);
293 return nWhich;
296 DrawingOLEAdaptor::DrawingOLEAdaptor(SdrOle2Obj &rObj,
297 SfxObjectShell &rPers)
298 : msOrigPersistName(rObj.GetPersistName()),
299 mxIPRef(rObj.GetObjRef()), mrPers(rPers),
300 mpGraphic( rObj.GetGraphic() )
302 //rObj.SetPersistName(String());
303 //rObj.SetObjRef(0);
304 rObj.AbandonObject();
307 bool DrawingOLEAdaptor::TransferToDoc( ::rtl::OUString &rName )
309 ASSERT(mxIPRef.is(), "Transferring invalid object to doc");
310 if (!mxIPRef.is())
311 return false;
313 uno::Reference < container::XChild > xChild( mxIPRef, uno::UNO_QUERY );
314 if ( xChild.is() )
315 xChild->setParent( mrPers.GetModel() );
317 bool bSuccess = mrPers.GetEmbeddedObjectContainer().InsertEmbeddedObject( mxIPRef, rName );
318 if (bSuccess)
320 if ( mpGraphic )
321 ::svt::EmbeddedObjectRef::SetGraphicToContainer( *mpGraphic,
322 mrPers.GetEmbeddedObjectContainer(),
323 rName,
324 ::rtl::OUString() );
326 //mxIPRef->changeState( embed::EmbedStates::LOADED );
327 mxIPRef = 0;
330 return bSuccess;
333 DrawingOLEAdaptor::~DrawingOLEAdaptor()
335 if (mxIPRef.is())
337 DBG_ASSERT( !mrPers.GetEmbeddedObjectContainer().HasEmbeddedObject( mxIPRef ), "Object in adaptor is inserted?!" );
340 uno::Reference < com::sun::star::util::XCloseable > xClose( mxIPRef, uno::UNO_QUERY );
341 if ( xClose.is() )
342 xClose->close(sal_True);
344 catch ( com::sun::star::util::CloseVetoException& )
348 mxIPRef = 0;
352 #ifdef DEBUGDUMP
353 SvStream *CreateDebuggingStream(const String &rSuffix)
355 SvStream* pDbgOut = 0;
356 static sal_Int32 nCount;
357 String aFileName(String(RTL_CONSTASCII_STRINGPARAM("wwdbg")));
358 aFileName.Append(String::CreateFromInt32(++nCount));
359 aFileName.Append(rSuffix);
360 String aURLStr;
361 if (::utl::LocalFileHelper::ConvertPhysicalNameToURL(
362 Application::GetAppFileName(), aURLStr))
364 INetURLObject aURL(aURLStr);
365 aURL.removeSegment();
366 aURL.removeFinalSlash();
367 aURL.Append(aFileName);
369 pDbgOut = ::utl::UcbStreamHelper::CreateStream(
370 aURL.GetMainURL(INetURLObject::NO_DECODE),
371 STREAM_TRUNC | STREAM_WRITE);
373 return pDbgOut;
376 void DumpStream(const SvStream &rSrc, SvStream &rDest, sal_uInt32 nLen)
378 SvStream &rSource = const_cast<SvStream&>(rSrc);
379 ULONG nOrigPos = rSource.Tell();
380 if (nLen == STREAM_SEEK_TO_END)
382 rSource.Seek(STREAM_SEEK_TO_END);
383 nLen = rSource.Tell();
385 if (nLen - nOrigPos)
387 rSource.Seek(nOrigPos);
388 sal_Char* pDat = new sal_Char[nLen];
389 rSource.Read(pDat, nLen);
390 rDest.Write(pDat, nLen);
391 delete[] pDat;
392 rSource.Seek(nOrigPos);
395 #endif
398 namespace util
400 SV_IMPL_OP_PTRARR_SORT(AuthorInfos, AuthorInfo_Ptr)
402 SwTwips MakeSafePositioningValue(SwTwips nIn)
404 if (nIn > SHRT_MAX)
405 nIn = SHRT_MAX;
406 else if (nIn < SHRT_MIN)
407 nIn = SHRT_MIN;
408 return nIn;
411 void SetLayer::SendObjectToHell(SdrObject &rObject) const
413 SetObjectLayer(rObject, eHell);
416 void SetLayer::SendObjectToHeaven(SdrObject &rObject) const
418 SetObjectLayer(rObject, eHeaven);
421 void SetLayer::SetObjectLayer(SdrObject &rObject, Layer eLayer) const
423 if (FmFormInventor == rObject.GetObjInventor())
424 rObject.SetLayer(mnFormLayer);
425 else
427 switch (eLayer)
429 case eHeaven:
430 rObject.SetLayer(mnHeavenLayer);
431 break;
432 case eHell:
433 rObject.SetLayer(mnHellLayer);
434 break;
439 //SetLayer boilerplate begin
440 void SetLayer::Swap(SetLayer& rOther) throw()
442 std::swap(mnHeavenLayer, rOther.mnHeavenLayer);
443 std::swap(mnHellLayer, rOther.mnHellLayer);
444 std::swap(mnFormLayer, rOther.mnFormLayer);
447 // --> OD 2004-12-13 #i38889# - by default put objects into the invisible
448 // layers.
449 SetLayer::SetLayer(const SwDoc &rDoc)
450 : mnHeavenLayer(rDoc.GetInvisibleHeavenId()),
451 mnHellLayer(rDoc.GetInvisibleHellId()),
452 mnFormLayer(rDoc.GetInvisibleControlsId())
455 // <--
457 SetLayer::SetLayer(const SetLayer& rOther) throw()
458 : mnHeavenLayer(rOther.mnHeavenLayer),
459 mnHellLayer(rOther.mnHellLayer),
460 mnFormLayer(rOther.mnFormLayer)
464 SetLayer& SetLayer::operator=(const SetLayer& rOther) throw()
466 SetLayer aTemp(rOther);
467 Swap(aTemp);
468 return *this;
470 //SetLayer boilerplate end
472 void GetPoolItems(const SfxItemSet &rSet, PoolItems &rItems)
474 if (rSet.Count())
476 SfxItemIter aIter(rSet);
477 if (const SfxPoolItem *pItem = aIter.GetCurItem())
480 rItems[pItem->Which()] = pItem;
481 while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
486 const SfxPoolItem *SearchPoolItems(const PoolItems &rItems,
487 sal_uInt16 eType)
489 sw::cPoolItemIter aIter = rItems.find(eType);
490 if (aIter != rItems.end())
491 return aIter->second;
492 return 0;
495 void ClearOverridesFromSet(const SwFmtCharFmt &rFmt, SfxItemSet &rSet)
497 if (const SwCharFmt* pCharFmt = rFmt.GetCharFmt())
499 if (pCharFmt->GetAttrSet().Count())
501 SfxItemIter aIter(pCharFmt->GetAttrSet());
502 const SfxPoolItem *pItem = aIter.GetCurItem();
504 rSet.ClearItem(pItem->Which());
505 while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
510 ParaStyles GetParaStyles(const SwDoc &rDoc)
512 ParaStyles aStyles;
513 typedef ParaStyles::size_type mysizet;
515 const SwTxtFmtColls *pColls = rDoc.GetTxtFmtColls();
516 mysizet nCount = pColls ? pColls->Count() : 0;
517 aStyles.reserve(nCount);
518 for (mysizet nI = 0; nI < nCount; ++nI)
519 aStyles.push_back((*pColls)[ static_cast< USHORT >(nI) ]);
520 return aStyles;
523 SwTxtFmtColl* GetParaStyle(SwDoc &rDoc, const String& rName)
525 // Search first in the Doc-Styles
526 SwTxtFmtColl* pColl = rDoc.FindTxtFmtCollByName(rName);
527 if (!pColl)
529 // Collection not found, try in Pool ?
530 sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
531 nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL);
532 if (n != SAL_MAX_UINT16) // found or standard
533 pColl = rDoc.GetTxtCollFromPool(n, false);
535 return pColl;
538 SwCharFmt* GetCharStyle(SwDoc &rDoc, const String& rName)
540 SwCharFmt *pFmt = rDoc.FindCharFmtByName(rName);
541 if (!pFmt)
543 // Collection not found, try in Pool ?
544 sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
545 nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
546 if (n != SAL_MAX_UINT16) // found or standard
547 pFmt = rDoc.GetCharFmtFromPool(n);
549 return pFmt;
552 // --> OD 2009-02-04 #i98791# - adjust sorting algorithm
553 void SortByAssignedOutlineStyleListLevel(ParaStyles &rStyles)
555 std::sort(rStyles.begin(), rStyles.end(), outlinecmp());
557 // <--
560 Utility to extract flyfmts from a document, potentially from a
561 selection.
563 Frames GetFrames(const SwDoc &rDoc, SwPaM *pPaM /*, bool bAll*/)
565 SwPosFlyFrms aFlys;
566 rDoc.GetAllFlyFmts(aFlys, pPaM, true);
567 sw::Frames aRet(SwPosFlyFrmsToFrames(aFlys));
568 for (USHORT i = aFlys.Count(); i > 0;)
569 delete aFlys[--i];
570 return aRet;
573 Frames GetFramesBetweenNodes(const Frames &rFrames,
574 const SwNode &rStart, const SwNode &rEnd)
576 Frames aRet;
577 ULONG nEnd = rEnd.GetIndex();
578 for (ULONG nI = rStart.GetIndex(); nI < nEnd; ++nI)
580 my_copy_if(rFrames.begin(), rFrames.end(),
581 std::back_inserter(aRet), anchoredto(nI));
583 return aRet;
587 Frames GetFramesInNode(const Frames &rFrames, const SwNode &rNode)
589 Frames aRet;
590 my_copy_if(rFrames.begin(), rFrames.end(),
591 std::back_inserter(aRet), anchoredto(rNode.GetIndex()));
592 return aRet;
595 const SwNumFmt* GetNumFmtFromTxtNode(const SwTxtNode &rTxtNode)
597 const SwNumRule *pRule = 0;
598 if (
599 rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
600 0 != (pRule = rTxtNode.GetNumRule())
603 return &(pRule->Get( static_cast< USHORT >(rTxtNode.GetActualListLevel()) ));
606 ASSERT(rTxtNode.GetDoc(), "No document for node?, suspicious");
607 if (!rTxtNode.GetDoc())
608 return 0;
610 if (
611 rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
612 0 != (pRule = rTxtNode.GetDoc()->GetOutlineNumRule())
615 return &(pRule->Get( static_cast< USHORT >(rTxtNode.GetActualListLevel()) ));
618 return 0;
621 const SwNumRule* GetNumRuleFromTxtNode(const SwTxtNode &rTxtNode)
623 return GetNormalNumRuleFromTxtNode(rTxtNode);
626 const SwNumRule* GetNormalNumRuleFromTxtNode(const SwTxtNode &rTxtNode)
628 const SwNumRule *pRule = 0;
630 if (
631 rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
632 0 != (pRule = rTxtNode.GetNumRule())
635 return pRule;
637 return 0;
641 SwNoTxtNode *GetNoTxtNodeFromSwFrmFmt(const SwFrmFmt &rFmt)
643 const SwNodeIndex *pIndex = rFmt.GetCntnt().GetCntntIdx();
644 ASSERT(pIndex, "No NodeIndex in SwFrmFmt ?, suspicious");
645 if (!pIndex)
646 return 0;
647 SwNodeIndex aIdx(*pIndex, 1);
648 return aIdx.GetNode().GetNoTxtNode();
651 bool HasPageBreak(const SwNode &rNd)
653 const SvxFmtBreakItem *pBreak = 0;
654 if (rNd.IsTableNode() && rNd.GetTableNode())
656 const SwTable& rTable = rNd.GetTableNode()->GetTable();
657 const SwFrmFmt* pApply = rTable.GetFrmFmt();
658 ASSERT(pApply, "impossible");
659 if (pApply)
660 pBreak = &(ItemGet<SvxFmtBreakItem>(*pApply, RES_BREAK));
662 else if (const SwCntntNode *pNd = rNd.GetCntntNode())
663 pBreak = &(ItemGet<SvxFmtBreakItem>(*pNd, RES_BREAK));
665 if (pBreak && pBreak->GetBreak() == SVX_BREAK_PAGE_BEFORE)
666 return true;
667 return false;
670 Polygon PolygonFromPolyPolygon(const PolyPolygon &rPolyPoly)
672 if(1 == rPolyPoly.Count())
674 return rPolyPoly[0];
676 else
678 // This method will now just concatenate the polygons contained
679 // in the given PolyPolygon. Anything else which might be thought of
680 // for reducing to a single polygon will just need nore power and
681 // cannot create more correct results.
682 sal_uInt32 nPointCount(0L);
683 sal_uInt16 a;
685 for(a = 0; a < rPolyPoly.Count(); a++)
687 nPointCount += (sal_uInt32)rPolyPoly[a].GetSize();
690 if(nPointCount > 0x0000ffff)
692 DBG_ERROR("PolygonFromPolyPolygon: too many points for a single polygon (!)");
693 nPointCount = 0x0000ffff;
696 Polygon aRetval((sal_uInt16)nPointCount);
697 sal_uInt32 nAppendIndex(0L);
699 for(a = 0; a < rPolyPoly.Count(); a++)
701 const Polygon& rCandidate = rPolyPoly[a];
703 for(sal_uInt16 b(0); nAppendIndex <= nPointCount && b < rCandidate.GetSize(); b++)
705 aRetval[(sal_uInt16)nAppendIndex++] = rCandidate[b];
709 return aRetval;
713 bool IsStarSymbol(const String &rFontName)
715 String sFamilyNm(GetFontToken(rFontName, 0));
716 return (sFamilyNm.EqualsIgnoreCaseAscii("starsymbol") ||
717 sFamilyNm.EqualsIgnoreCaseAscii("opensymbol"));
720 Size GetSwappedInSize(const SwNoTxtNode& rNd)
722 Size aGrTwipSz(rNd.GetTwipSize());
723 if ((!aGrTwipSz.Width() || !aGrTwipSz.Height()))
725 SwGrfNode *pGrfNode = const_cast<SwGrfNode*>(rNd.GetGrfNode());
726 if (pGrfNode && (GRAPHIC_NONE != pGrfNode->GetGrf().GetType()))
728 bool bWasSwappedOut = pGrfNode->GetGrfObj().IsSwappedOut();
729 pGrfNode->SwapIn();
730 aGrTwipSz = pGrfNode->GetTwipSize();
731 if (bWasSwappedOut)
732 pGrfNode->SwapOut();
736 ASSERT(aGrTwipSz.Width() && aGrTwipSz.Height(), "0 x 0 graphic ?");
737 return aGrTwipSz;
740 void RedlineStack::open(const SwPosition& rPos, const SfxPoolItem& rAttr)
742 ASSERT(rAttr.Which() == RES_FLTR_REDLINE, "not a redline");
743 maStack.push_back(new SwFltStackEntry(rPos,rAttr.Clone()));
747 class SameOpenRedlineType :
748 public std::unary_function<const SwFltStackEntry*, bool>
750 private:
751 RedlineType_t meType;
752 public:
753 SameOpenRedlineType(RedlineType_t eType) : meType(eType) {}
754 bool operator()(const SwFltStackEntry *pEntry) const
756 const SwFltRedline *pTest = static_cast<const SwFltRedline *>
757 (pEntry->pAttr);
758 return (pEntry->bLocked && (pTest->eType == meType));
762 bool RedlineStack::close(const SwPosition& rPos, RedlineType_t eType)
764 //Search from end for same type
765 myriter aResult = std::find_if(maStack.rbegin(), maStack.rend(),
766 SameOpenRedlineType(eType));
767 if (aResult != maStack.rend())
769 (*aResult)->SetEndPos(rPos);
770 return true;
772 return false;
777 void RedlineStack::closeall(const SwPosition& rPos)
779 std::for_each(maStack.begin(), maStack.end(), CloseIfOpen(rPos));
783 void SetInDocAndDelete::operator()(SwFltStackEntry *pEntry)
785 SwPaM aRegion(pEntry->nMkNode);
786 if (
787 pEntry->MakeRegion(&mrDoc, aRegion, true) &&
788 (*aRegion.GetPoint() != *aRegion.GetMark())
791 mrDoc.SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT |
792 nsRedlineMode_t::REDLINE_SHOW_DELETE));
793 const SwFltRedline *pFltRedline = static_cast<const SwFltRedline*>
794 (pEntry->pAttr);
796 if (USHRT_MAX != pFltRedline->nAutorNoPrev)
798 SwRedlineData aData(pFltRedline->eTypePrev,
799 pFltRedline->nAutorNoPrev, pFltRedline->aStampPrev, aEmptyStr,
802 mrDoc.AppendRedline(new SwRedline(aData, aRegion), true);
805 SwRedlineData aData(pFltRedline->eType, pFltRedline->nAutorNo,
806 pFltRedline->aStamp, aEmptyStr, 0);
808 mrDoc.AppendRedline(new SwRedline(aData, aRegion), true);
809 mrDoc.SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_NONE | nsRedlineMode_t::REDLINE_SHOW_INSERT |
810 nsRedlineMode_t::REDLINE_SHOW_DELETE ));
812 delete pEntry;
816 bool CompareRedlines::operator()(const SwFltStackEntry *pOneE,
817 const SwFltStackEntry *pTwoE) const
819 const SwFltRedline *pOne= static_cast<const SwFltRedline*>
820 (pOneE->pAttr);
821 const SwFltRedline *pTwo= static_cast<const SwFltRedline*>
822 (pTwoE->pAttr);
824 //Return the earlier time, if two have the same time, prioritize
825 //inserts over deletes
826 if (pOne->aStamp == pTwo->aStamp)
827 return (pOne->eType == nsRedlineType_t::REDLINE_INSERT && pTwo->eType != nsRedlineType_t::REDLINE_INSERT);
828 else
829 return (pOne->aStamp < pTwo->aStamp) ? true : false;
833 RedlineStack::~RedlineStack()
835 std::sort(maStack.begin(), maStack.end(), CompareRedlines());
836 std::for_each(maStack.begin(), maStack.end(), SetInDocAndDelete(mrDoc));
839 USHORT WrtRedlineAuthor::AddName( const String& rNm )
841 USHORT nRet;
842 typedef std::vector<String>::iterator myiter;
843 myiter aIter = std::find(maAuthors.begin(), maAuthors.end(), rNm);
844 if (aIter != maAuthors.end())
845 nRet = static_cast< USHORT >(aIter - maAuthors.begin());
846 else
848 nRet = static_cast< USHORT >(maAuthors.size());
849 maAuthors.push_back(rNm);
851 return nRet;
854 std::vector<String> WrtRedlineAuthor::GetNames()
856 return maAuthors;
861 /* vi:set tabstop=4 shiftwidth=4 expandtab: */