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