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