summaryrefslogtreecommitdiff
path: root/sw/source/filter/ww8/writerhelper.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/ww8/writerhelper.cxx')
-rw-r--r--sw/source/filter/ww8/writerhelper.cxx784
1 files changed, 784 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/writerhelper.cxx b/sw/source/filter/ww8/writerhelper.cxx
new file mode 100644
index 000000000000..cb1471fa88ab
--- /dev/null
+++ b/sw/source/filter/ww8/writerhelper.cxx
@@ -0,0 +1,784 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+#include <com/sun/star/util/XCloseable.hpp>
+
+#include <doc.hxx>
+#include "writerhelper.hxx"
+#include <msfilter.hxx>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+
+#include <algorithm> //std::swap
+#include <functional> //std::binary_function
+#include <svl/itemiter.hxx> //SfxItemIter
+#include <svx/svdobj.hxx> //SdrObject
+#include <svx/svdoole2.hxx> //SdrOle2Obj
+#include <svx/fmglob.hxx> //FmFormInventor
+#include <editeng/brkitem.hxx> //SvxFmtBreakItem
+#include <editeng/tstpitem.hxx> //SvxTabStopItem
+#include <ndtxt.hxx> //SwTxtNode
+#include <ndnotxt.hxx> //SwNoTxtNode
+#include <fmtcntnt.hxx> //SwFmtCntnt
+#include <swtable.hxx> //SwTable
+#include <frmfmt.hxx> //SwFrmFmt
+#include <flypos.hxx> //SwPosFlyFrms
+#include <fmtanchr.hxx> //SwFmtAnchor
+#include <ndgrf.hxx> //SwGrfNode
+#include <fmtfsize.hxx> //SwFmtFrmSize
+#include <SwStyleNameMapper.hxx> //SwStyleNameMapper
+#include <docary.hxx> //SwCharFmts
+#include <charfmt.hxx> //SwCharFmt
+#include <fchrfmt.hxx> //SwFmtCharFmt
+#ifndef _UNOTOOLS_STREAMWRAP_HXX
+#include <unotools/streamwrap.hxx>
+#endif
+#include <numrule.hxx>
+
+using namespace com::sun::star;
+using namespace nsSwGetPoolIdFromName;
+
+
+namespace
+{
+ /*
+ Stroustroup forgets copy_if, See C++ Programming language Chp 18, pg 530
+ */
+ template <typename In , typename Out , typename Pred>
+ Out my_copy_if(In first, In last, Out res, Pred p)
+ {
+ while (first != last)
+ {
+ if (p(*first))
+ *res = *first;
+ ++first;
+ }
+ return res;
+ }
+
+ // #i98791# - adjust sorting
+ // Utility to sort SwTxtFmtColl's by their assigned outline style list level
+ class outlinecmp : public
+ std::binary_function<const SwTxtFmtColl*, const SwTxtFmtColl*, bool>
+ {
+ public:
+ bool operator()(const SwTxtFmtColl *pA, const SwTxtFmtColl *pB) const
+ {
+ // #i98791#
+ bool bResult( false );
+ const bool bIsAAssignedToOutlineStyle( pA->IsAssignedToListLevelOfOutlineStyle() );
+ const bool bIsBAssignedToOutlineStyle( pB->IsAssignedToListLevelOfOutlineStyle() );
+ if ( bIsAAssignedToOutlineStyle != bIsBAssignedToOutlineStyle )
+ {
+ bResult = bIsBAssignedToOutlineStyle;
+ }
+ else if ( !bIsAAssignedToOutlineStyle )
+ {
+ // pA and pB are equal regarding the sorting criteria.
+ // Thus return value does not matter.
+ bResult = false;
+ }
+ else
+ {
+ bResult = pA->GetAssignedOutlineStyleLevel() < pB->GetAssignedOutlineStyleLevel();
+ }
+
+ return bResult;
+ // <--
+ }
+ };
+ // <--
+
+ bool IsValidSlotWhich(sal_uInt16 nSlotId, sal_uInt16 nWhichId)
+ {
+ return (nSlotId != 0 && nWhichId != 0 && nSlotId != nWhichId);
+ }
+
+ /*
+ Utility to convert a SwPosFlyFrms into a simple vector of sw::Frames
+
+ The crucial thing is that a sw::Frame always has an anchor which
+ points to some content in the document. This is a requirement of exporting
+ to Word
+ */
+ sw::Frames SwPosFlyFrmsToFrames(const SwPosFlyFrms &rFlys)
+ {
+ sw::Frames aRet;
+ sal_uInt16 nEnd = rFlys.Count();
+ for (sal_uInt16 nI = 0; nI < nEnd; ++nI)
+ {
+ const SwFrmFmt &rEntry = rFlys[nI]->GetFmt();
+ if (const SwPosition* pAnchor = rEntry.GetAnchor().GetCntntAnchor())
+ aRet.push_back(sw::Frame(rEntry, *pAnchor));
+ else
+ {
+ SwPosition aPos(rFlys[nI]->GetNdIndex());
+ if (SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode())
+ aPos.nContent.Assign(pTxtNd, 0);
+ aRet.push_back(sw::Frame(rEntry, aPos));
+ }
+ }
+ return aRet;
+ }
+
+ //Utility to test if a frame is anchored at a given node index
+ class anchoredto: public std::unary_function<const sw::Frame&, bool>
+ {
+ private:
+ sal_uLong mnNode;
+ public:
+ anchoredto(sal_uLong nNode) : mnNode(nNode) {}
+ bool operator()(const sw::Frame &rFrame) const
+ {
+ return (mnNode == rFrame.GetPosition().nNode.GetNode().GetIndex());
+ }
+ };
+}
+
+namespace sw
+{
+ Frame::Frame(const SwFrmFmt &rFmt, const SwPosition &rPos)
+ : mpFlyFrm(&rFmt),
+ maPos(rPos),
+ maSize(),
+ maLayoutSize(), // #i43447#
+ meWriterType(eTxtBox),
+ mpStartFrameContent(0),
+ // #i43447# - move to initialization list
+ mbIsInline( (rFmt.GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
+ {
+ switch (rFmt.Which())
+ {
+ case RES_FLYFRMFMT:
+ if (const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx())
+ {
+ SwNodeIndex aIdx(*pIdx, 1);
+ const SwNode &rNd = aIdx.GetNode();
+ using sw::util::GetSwappedInSize;
+ // #i43447# - determine layout size
+ {
+ SwRect aLayRect( rFmt.FindLayoutRect() );
+ Rectangle aRect( aLayRect.SVRect() );
+ // The Object is not rendered (e.g. something in unused
+ // header/footer) - thus, get the values from the format.
+ if ( aLayRect.IsEmpty() )
+ {
+ aRect.SetSize( rFmt.GetFrmSize().GetSize() );
+ }
+ maLayoutSize = aRect.GetSize();
+ }
+ // <--
+ switch (rNd.GetNodeType())
+ {
+ case ND_GRFNODE:
+ meWriterType = eGraphic;
+ maSize = GetSwappedInSize(*rNd.GetNoTxtNode());
+ break;
+ case ND_OLENODE:
+ meWriterType = eOle;
+ maSize = GetSwappedInSize(*rNd.GetNoTxtNode());
+ break;
+ default:
+ meWriterType = eTxtBox;
+ // #i43447# - Size equals layout size for text boxes
+ maSize = maLayoutSize;
+ // <--
+ break;
+ }
+ mpStartFrameContent = &rNd;
+ }
+ else
+ {
+ OSL_ENSURE(!this, "Impossible");
+ meWriterType = eTxtBox;
+ }
+ break;
+ default:
+ if (const SdrObject* pObj = rFmt.FindRealSdrObject())
+ {
+ if (pObj->GetObjInventor() == FmFormInventor)
+ meWriterType = eFormControl;
+ else
+ meWriterType = eDrawing;
+ maSize = pObj->GetSnapRect().GetSize();
+ }
+ else
+ {
+ OSL_ENSURE(!this, "Impossible");
+ meWriterType = eDrawing;
+ }
+ break;
+ }
+ }
+
+ bool Frame::IsInline() const
+ {
+ return mbIsInline;
+ }
+
+ void Frame::ForceTreatAsInline()
+ {
+ mbIsInline = true;
+ }
+
+ namespace hack
+ {
+
+ sal_uInt16 TransformWhichBetweenPools(const SfxItemPool &rDestPool,
+ const SfxItemPool &rSrcPool, sal_uInt16 nWhich)
+ {
+ sal_uInt16 nSlotId = rSrcPool.GetSlotId(nWhich);
+ if (IsValidSlotWhich(nSlotId, nWhich))
+ nWhich = rDestPool.GetWhich(nSlotId);
+ else
+ nWhich = 0;
+ return nWhich;
+ }
+
+ sal_uInt16 GetSetWhichFromSwDocWhich(const SfxItemSet &rSet,
+ const SwDoc &rDoc, sal_uInt16 nWhich)
+ {
+ if (RES_WHICHHINT_END < *(rSet.GetRanges()))
+ {
+ nWhich = TransformWhichBetweenPools(*rSet.GetPool(),
+ rDoc.GetAttrPool(), nWhich);
+ }
+ return nWhich;
+ }
+
+ DrawingOLEAdaptor::DrawingOLEAdaptor(SdrOle2Obj &rObj,
+ SfxObjectShell &rPers)
+ : msOrigPersistName(rObj.GetPersistName()),
+ mxIPRef(rObj.GetObjRef()), mrPers(rPers),
+ mpGraphic( rObj.GetGraphic() )
+ {
+ rObj.AbandonObject();
+ }
+
+ bool DrawingOLEAdaptor::TransferToDoc( ::rtl::OUString &rName )
+ {
+ OSL_ENSURE(mxIPRef.is(), "Transferring invalid object to doc");
+ if (!mxIPRef.is())
+ return false;
+
+ uno::Reference < container::XChild > xChild( mxIPRef, uno::UNO_QUERY );
+ if ( xChild.is() )
+ xChild->setParent( mrPers.GetModel() );
+
+ bool bSuccess = mrPers.GetEmbeddedObjectContainer().InsertEmbeddedObject( mxIPRef, rName );
+ if (bSuccess)
+ {
+ if ( mpGraphic )
+ ::svt::EmbeddedObjectRef::SetGraphicToContainer( *mpGraphic,
+ mrPers.GetEmbeddedObjectContainer(),
+ rName,
+ ::rtl::OUString() );
+
+ mxIPRef = 0;
+ }
+
+ return bSuccess;
+ }
+
+ DrawingOLEAdaptor::~DrawingOLEAdaptor()
+ {
+ if (mxIPRef.is())
+ {
+ DBG_ASSERT( !mrPers.GetEmbeddedObjectContainer().HasEmbeddedObject( mxIPRef ), "Object in adaptor is inserted?!" );
+ try
+ {
+ uno::Reference < com::sun::star::util::XCloseable > xClose( mxIPRef, uno::UNO_QUERY );
+ if ( xClose.is() )
+ xClose->close(sal_True);
+ }
+ catch ( com::sun::star::util::CloseVetoException& )
+ {
+ }
+
+ mxIPRef = 0;
+ }
+ }
+ }
+
+ namespace util
+ {
+ SV_IMPL_OP_PTRARR_SORT(AuthorInfos, AuthorInfo_Ptr)
+
+ SwTwips MakeSafePositioningValue(SwTwips nIn)
+ {
+ if (nIn > SHRT_MAX)
+ nIn = SHRT_MAX;
+ else if (nIn < SHRT_MIN)
+ nIn = SHRT_MIN;
+ return nIn;
+ }
+
+ void SetLayer::SendObjectToHell(SdrObject &rObject) const
+ {
+ SetObjectLayer(rObject, eHell);
+ }
+
+ void SetLayer::SendObjectToHeaven(SdrObject &rObject) const
+ {
+ SetObjectLayer(rObject, eHeaven);
+ }
+
+ void SetLayer::SetObjectLayer(SdrObject &rObject, Layer eLayer) const
+ {
+ if (FmFormInventor == rObject.GetObjInventor())
+ rObject.SetLayer(mnFormLayer);
+ else
+ {
+ switch (eLayer)
+ {
+ case eHeaven:
+ rObject.SetLayer(mnHeavenLayer);
+ break;
+ case eHell:
+ rObject.SetLayer(mnHellLayer);
+ break;
+ }
+ }
+ }
+
+ //SetLayer boilerplate begin
+ void SetLayer::Swap(SetLayer& rOther) throw()
+ {
+ std::swap(mnHeavenLayer, rOther.mnHeavenLayer);
+ std::swap(mnHellLayer, rOther.mnHellLayer);
+ std::swap(mnFormLayer, rOther.mnFormLayer);
+ }
+
+ // #i38889# - by default put objects into the invisible layers.
+ SetLayer::SetLayer(const SwDoc &rDoc)
+ : mnHeavenLayer(rDoc.GetInvisibleHeavenId()),
+ mnHellLayer(rDoc.GetInvisibleHellId()),
+ mnFormLayer(rDoc.GetInvisibleControlsId())
+ {
+ }
+
+ SetLayer::SetLayer(const SetLayer& rOther) throw()
+ : mnHeavenLayer(rOther.mnHeavenLayer),
+ mnHellLayer(rOther.mnHellLayer),
+ mnFormLayer(rOther.mnFormLayer)
+ {
+ }
+
+ SetLayer& SetLayer::operator=(const SetLayer& rOther) throw()
+ {
+ SetLayer aTemp(rOther);
+ Swap(aTemp);
+ return *this;
+ }
+ //SetLayer boilerplate end
+
+ void GetPoolItems(const SfxItemSet &rSet, PoolItems &rItems, bool bExportParentItemSet )
+ {
+ if( bExportParentItemSet )
+ {
+ sal_uInt16 nTotal = rSet.TotalCount();
+ for( sal_uInt16 nItem =0; nItem < nTotal; ++nItem )
+ {
+ const SfxPoolItem* pItem = 0;
+ if( SFX_ITEM_SET == rSet.GetItemState( rSet.GetWhichByPos( nItem ), true, &pItem ) )
+ {
+ rItems[pItem->Which()] = pItem;
+ }
+ }
+ }
+ else if( rSet.Count())
+ {
+ SfxItemIter aIter(rSet);
+ if (const SfxPoolItem *pItem = aIter.GetCurItem())
+ {
+ do
+ rItems[pItem->Which()] = pItem;
+ while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
+ }
+ }
+ }
+
+ const SfxPoolItem *SearchPoolItems(const PoolItems &rItems,
+ sal_uInt16 eType)
+ {
+ sw::cPoolItemIter aIter = rItems.find(eType);
+ if (aIter != rItems.end())
+ return aIter->second;
+ return 0;
+ }
+
+ void ClearOverridesFromSet(const SwFmtCharFmt &rFmt, SfxItemSet &rSet)
+ {
+ if (const SwCharFmt* pCharFmt = rFmt.GetCharFmt())
+ {
+ if (pCharFmt->GetAttrSet().Count())
+ {
+ SfxItemIter aIter(pCharFmt->GetAttrSet());
+ const SfxPoolItem *pItem = aIter.GetCurItem();
+ do
+ rSet.ClearItem(pItem->Which());
+ while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
+ }
+ }
+ }
+
+ ParaStyles GetParaStyles(const SwDoc &rDoc)
+ {
+ ParaStyles aStyles;
+ typedef ParaStyles::size_type mysizet;
+
+ const SwTxtFmtColls *pColls = rDoc.GetTxtFmtColls();
+ mysizet nCount = pColls ? pColls->Count() : 0;
+ aStyles.reserve(nCount);
+ for (mysizet nI = 0; nI < nCount; ++nI)
+ aStyles.push_back((*pColls)[ static_cast< sal_uInt16 >(nI) ]);
+ return aStyles;
+ }
+
+ SwTxtFmtColl* GetParaStyle(SwDoc &rDoc, const String& rName)
+ {
+ // Search first in the Doc-Styles
+ SwTxtFmtColl* pColl = rDoc.FindTxtFmtCollByName(rName);
+ if (!pColl)
+ {
+ // Collection not found, try in Pool ?
+ sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
+ nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL);
+ if (n != SAL_MAX_UINT16) // found or standard
+ pColl = rDoc.GetTxtCollFromPool(n, false);
+ }
+ return pColl;
+ }
+
+ SwCharFmt* GetCharStyle(SwDoc &rDoc, const String& rName)
+ {
+ SwCharFmt *pFmt = rDoc.FindCharFmtByName(rName);
+ if (!pFmt)
+ {
+ // Collection not found, try in Pool ?
+ sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
+ nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
+ if (n != SAL_MAX_UINT16) // found or standard
+ pFmt = rDoc.GetCharFmtFromPool(n);
+ }
+ return pFmt;
+ }
+
+ // #i98791# - adjust sorting algorithm
+ void SortByAssignedOutlineStyleListLevel(ParaStyles &rStyles)
+ {
+ std::sort(rStyles.begin(), rStyles.end(), outlinecmp());
+ }
+
+ /*
+ Utility to extract flyfmts from a document, potentially from a
+ selection.
+ */
+ Frames GetFrames(const SwDoc &rDoc, SwPaM *pPaM /*, bool bAll*/)
+ {
+ SwPosFlyFrms aFlys;
+ rDoc.GetAllFlyFmts(aFlys, pPaM, true);
+ sw::Frames aRet(SwPosFlyFrmsToFrames(aFlys));
+ for (sal_uInt16 i = aFlys.Count(); i > 0;)
+ delete aFlys[--i];
+ return aRet;
+ }
+
+ Frames GetFramesInNode(const Frames &rFrames, const SwNode &rNode)
+ {
+ Frames aRet;
+ my_copy_if(rFrames.begin(), rFrames.end(),
+ std::back_inserter(aRet), anchoredto(rNode.GetIndex()));
+ return aRet;
+ }
+
+ const SwNumFmt* GetNumFmtFromTxtNode(const SwTxtNode &rTxtNode)
+ {
+ const SwNumRule *pRule = 0;
+ if (
+ rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
+ 0 != (pRule = rTxtNode.GetNumRule())
+ )
+ {
+ return &(pRule->Get( static_cast< sal_uInt16 >(rTxtNode.GetActualListLevel()) ));
+ }
+
+ OSL_ENSURE(rTxtNode.GetDoc(), "No document for node?, suspicious");
+ if (!rTxtNode.GetDoc())
+ return 0;
+
+ if (
+ rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
+ 0 != (pRule = rTxtNode.GetDoc()->GetOutlineNumRule())
+ )
+ {
+ return &(pRule->Get( static_cast< sal_uInt16 >(rTxtNode.GetActualListLevel()) ));
+ }
+
+ return 0;
+ }
+
+ const SwNumRule* GetNumRuleFromTxtNode(const SwTxtNode &rTxtNode)
+ {
+ return GetNormalNumRuleFromTxtNode(rTxtNode);
+ }
+
+ const SwNumRule* GetNormalNumRuleFromTxtNode(const SwTxtNode &rTxtNode)
+ {
+ const SwNumRule *pRule = 0;
+
+ if (
+ rTxtNode.IsNumbered() && rTxtNode.IsCountedInList() &&
+ 0 != (pRule = rTxtNode.GetNumRule())
+ )
+ {
+ return pRule;
+ }
+ return 0;
+ }
+
+
+ SwNoTxtNode *GetNoTxtNodeFromSwFrmFmt(const SwFrmFmt &rFmt)
+ {
+ const SwNodeIndex *pIndex = rFmt.GetCntnt().GetCntntIdx();
+ OSL_ENSURE(pIndex, "No NodeIndex in SwFrmFmt ?, suspicious");
+ if (!pIndex)
+ return 0;
+ SwNodeIndex aIdx(*pIndex, 1);
+ return aIdx.GetNode().GetNoTxtNode();
+ }
+
+ bool HasPageBreak(const SwNode &rNd)
+ {
+ const SvxFmtBreakItem *pBreak = 0;
+ if (rNd.IsTableNode() && rNd.GetTableNode())
+ {
+ const SwTable& rTable = rNd.GetTableNode()->GetTable();
+ const SwFrmFmt* pApply = rTable.GetFrmFmt();
+ OSL_ENSURE(pApply, "impossible");
+ if (pApply)
+ pBreak = &(ItemGet<SvxFmtBreakItem>(*pApply, RES_BREAK));
+ }
+ else if (const SwCntntNode *pNd = rNd.GetCntntNode())
+ pBreak = &(ItemGet<SvxFmtBreakItem>(*pNd, RES_BREAK));
+
+ if (pBreak && pBreak->GetBreak() == SVX_BREAK_PAGE_BEFORE)
+ return true;
+ return false;
+ }
+
+ Polygon PolygonFromPolyPolygon(const PolyPolygon &rPolyPoly)
+ {
+ if(1 == rPolyPoly.Count())
+ {
+ return rPolyPoly[0];
+ }
+ else
+ {
+ // This method will now just concatenate the polygons contained
+ // in the given PolyPolygon. Anything else which might be thought of
+ // for reducing to a single polygon will just need nore power and
+ // cannot create more correct results.
+ sal_uInt32 nPointCount(0L);
+ sal_uInt16 a;
+
+ for(a = 0; a < rPolyPoly.Count(); a++)
+ {
+ nPointCount += (sal_uInt32)rPolyPoly[a].GetSize();
+ }
+
+ if(nPointCount > 0x0000ffff)
+ {
+ OSL_FAIL("PolygonFromPolyPolygon: too many points for a single polygon (!)");
+ nPointCount = 0x0000ffff;
+ }
+
+ Polygon aRetval((sal_uInt16)nPointCount);
+ sal_uInt32 nAppendIndex(0L);
+
+ for(a = 0; a < rPolyPoly.Count(); a++)
+ {
+ const Polygon& rCandidate = rPolyPoly[a];
+
+ for(sal_uInt16 b(0); nAppendIndex <= nPointCount && b < rCandidate.GetSize(); b++)
+ {
+ aRetval[(sal_uInt16)nAppendIndex++] = rCandidate[b];
+ }
+ }
+
+ return aRetval;
+ }
+ }
+
+ bool IsStarSymbol(const String &rFontName)
+ {
+ String sFamilyNm(GetFontToken(rFontName, 0));
+ return (sFamilyNm.EqualsIgnoreCaseAscii("starsymbol") ||
+ sFamilyNm.EqualsIgnoreCaseAscii("opensymbol"));
+ }
+
+ Size GetSwappedInSize(const SwNoTxtNode& rNd)
+ {
+ Size aGrTwipSz(rNd.GetTwipSize());
+ if ((!aGrTwipSz.Width() || !aGrTwipSz.Height()))
+ {
+ SwGrfNode *pGrfNode = const_cast<SwGrfNode*>(rNd.GetGrfNode());
+ if (pGrfNode && (GRAPHIC_NONE != pGrfNode->GetGrf().GetType()))
+ {
+ bool bWasSwappedOut = pGrfNode->GetGrfObj().IsSwappedOut();
+ pGrfNode->SwapIn();
+ aGrTwipSz = pGrfNode->GetTwipSize();
+ if (bWasSwappedOut)
+ pGrfNode->SwapOut();
+ }
+ }
+
+ OSL_ENSURE(aGrTwipSz.Width() && aGrTwipSz.Height(), "0 x 0 graphic ?");
+ return aGrTwipSz;
+ }
+
+ void RedlineStack::open(const SwPosition& rPos, const SfxPoolItem& rAttr)
+ {
+ OSL_ENSURE(rAttr.Which() == RES_FLTR_REDLINE, "not a redline");
+ maStack.push_back(new SwFltStackEntry(rPos,rAttr.Clone()));
+ }
+
+
+ class SameOpenRedlineType :
+ public std::unary_function<const SwFltStackEntry*, bool>
+ {
+ private:
+ RedlineType_t meType;
+ public:
+ SameOpenRedlineType(RedlineType_t eType) : meType(eType) {}
+ bool operator()(const SwFltStackEntry *pEntry) const
+ {
+ const SwFltRedline *pTest = static_cast<const SwFltRedline *>
+ (pEntry->pAttr);
+ return (pEntry->bLocked && (pTest->eType == meType));
+ }
+ };
+
+ bool RedlineStack::close(const SwPosition& rPos, RedlineType_t eType)
+ {
+ //Search from end for same type
+ myriter aResult = std::find_if(maStack.rbegin(), maStack.rend(),
+ SameOpenRedlineType(eType));
+ if (aResult != maStack.rend())
+ {
+ (*aResult)->SetEndPos(rPos);
+ return true;
+ }
+ return false;
+ }
+
+
+
+ void RedlineStack::closeall(const SwPosition& rPos)
+ {
+ std::for_each(maStack.begin(), maStack.end(), CloseIfOpen(rPos));
+ }
+
+
+ void SetInDocAndDelete::operator()(SwFltStackEntry *pEntry)
+ {
+ SwPaM aRegion(pEntry->nMkNode);
+ if (
+ pEntry->MakeRegion(&mrDoc, aRegion, true) &&
+ (*aRegion.GetPoint() != *aRegion.GetMark())
+ )
+ {
+ mrDoc.SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT |
+ nsRedlineMode_t::REDLINE_SHOW_DELETE));
+ const SwFltRedline *pFltRedline = static_cast<const SwFltRedline*>
+ (pEntry->pAttr);
+
+ if (USHRT_MAX != pFltRedline->nAutorNoPrev)
+ {
+ SwRedlineData aData(pFltRedline->eTypePrev,
+ pFltRedline->nAutorNoPrev, pFltRedline->aStampPrev, aEmptyStr,
+ 0);
+
+ mrDoc.AppendRedline(new SwRedline(aData, aRegion), true);
+ }
+
+ SwRedlineData aData(pFltRedline->eType, pFltRedline->nAutorNo,
+ pFltRedline->aStamp, aEmptyStr, 0);
+
+ mrDoc.AppendRedline(new SwRedline(aData, aRegion), true);
+ mrDoc.SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_NONE | nsRedlineMode_t::REDLINE_SHOW_INSERT |
+ nsRedlineMode_t::REDLINE_SHOW_DELETE ));
+ }
+ delete pEntry;
+ }
+
+
+ bool CompareRedlines::operator()(const SwFltStackEntry *pOneE,
+ const SwFltStackEntry *pTwoE) const
+ {
+ const SwFltRedline *pOne= static_cast<const SwFltRedline*>
+ (pOneE->pAttr);
+ const SwFltRedline *pTwo= static_cast<const SwFltRedline*>
+ (pTwoE->pAttr);
+
+ //Return the earlier time, if two have the same time, prioritize
+ //inserts over deletes
+ if (pOne->aStamp == pTwo->aStamp)
+ return (pOne->eType == nsRedlineType_t::REDLINE_INSERT && pTwo->eType != nsRedlineType_t::REDLINE_INSERT);
+ else
+ return (pOne->aStamp < pTwo->aStamp) ? true : false;
+ }
+
+
+ RedlineStack::~RedlineStack()
+ {
+ std::sort(maStack.begin(), maStack.end(), CompareRedlines());
+ std::for_each(maStack.begin(), maStack.end(), SetInDocAndDelete(mrDoc));
+ }
+
+ sal_uInt16 WrtRedlineAuthor::AddName( const String& rNm )
+ {
+ sal_uInt16 nRet;
+ typedef std::vector<String>::iterator myiter;
+ myiter aIter = std::find(maAuthors.begin(), maAuthors.end(), rNm);
+ if (aIter != maAuthors.end())
+ nRet = static_cast< sal_uInt16 >(aIter - maAuthors.begin());
+ else
+ {
+ nRet = static_cast< sal_uInt16 >(maAuthors.size());
+ maAuthors.push_back(rNm);
+ }
+ return nRet;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */