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