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 : #include <com/sun/star/util/XCloseable.hpp>
21 :
22 : #include <doc.hxx>
23 : #include "writerhelper.hxx"
24 : #include <msfilter.hxx>
25 : #include <com/sun/star/container/XChild.hpp>
26 : #include <com/sun/star/embed/EmbedStates.hpp>
27 :
28 : #include <algorithm>
29 : #include <functional>
30 : #include <svl/itemiter.hxx>
31 : #include <svx/svdobj.hxx>
32 : #include <svx/svdoole2.hxx>
33 : #include <svx/fmglob.hxx>
34 : #include <editeng/formatbreakitem.hxx>
35 : #include <editeng/tstpitem.hxx>
36 : #include <ndtxt.hxx>
37 : #include <ndnotxt.hxx>
38 : #include <fmtcntnt.hxx>
39 : #include <swtable.hxx>
40 : #include <frmfmt.hxx>
41 : #include <flypos.hxx>
42 : #include <fmtanchr.hxx>
43 : #include <ndgrf.hxx>
44 : #include <fmtfsize.hxx>
45 : #include <SwStyleNameMapper.hxx>
46 : #include <docary.hxx>
47 : #include <charfmt.hxx>
48 : #include <fchrfmt.hxx>
49 : #include <unotools/streamwrap.hxx>
50 : #include <numrule.hxx>
51 : #include <vcl/svapp.hxx>
52 : #include <IDocumentDrawModelAccess.hxx>
53 : #include <IDocumentLayoutAccess.hxx>
54 : #include <IDocumentStylePoolAccess.hxx>
55 :
56 : using namespace com::sun::star;
57 : using namespace nsSwGetPoolIdFromName;
58 :
59 : namespace
60 : {
61 : /*
62 : Stroustroup forgets copy_if, See C++ Programming language Chp 18, pg 530
63 : */
64 : template <typename In , typename Out , typename Pred>
65 16956 : Out my_copy_if(In first, In last, Out res, Pred p)
66 : {
67 93968 : while (first != last)
68 : {
69 60056 : if (p(*first))
70 1088 : *res = *first;
71 60056 : ++first;
72 : }
73 16956 : return res;
74 : }
75 :
76 : // #i98791# - adjust sorting
77 : // Utility to sort SwTextFormatColl's by their assigned outline style list level
78 : class outlinecmp : public
79 : std::binary_function<const SwTextFormatColl*, const SwTextFormatColl*, bool>
80 : {
81 : public:
82 0 : bool operator()(const SwTextFormatColl *pA, const SwTextFormatColl *pB) const
83 : {
84 : // #i98791#
85 0 : bool bResult( false );
86 0 : const bool bIsAAssignedToOutlineStyle( pA->IsAssignedToListLevelOfOutlineStyle() );
87 0 : const bool bIsBAssignedToOutlineStyle( pB->IsAssignedToListLevelOfOutlineStyle() );
88 0 : if ( bIsAAssignedToOutlineStyle != bIsBAssignedToOutlineStyle )
89 : {
90 0 : bResult = bIsBAssignedToOutlineStyle;
91 : }
92 0 : else if ( !bIsAAssignedToOutlineStyle )
93 : {
94 : // pA and pB are equal regarding the sorting criteria.
95 : // Thus return value does not matter.
96 0 : bResult = false;
97 : }
98 : else
99 : {
100 0 : bResult = pA->GetAssignedOutlineStyleLevel() < pB->GetAssignedOutlineStyleLevel();
101 : }
102 :
103 0 : return bResult;
104 : }
105 : };
106 :
107 99 : bool IsValidSlotWhich(sal_uInt16 nSlotId, sal_uInt16 nWhichId)
108 : {
109 99 : return (nSlotId != 0 && nWhichId != 0 && nSlotId != nWhichId);
110 : }
111 :
112 : /*
113 : Utility to convert a SwPosFlyFrms into a simple vector of sw::Frames
114 :
115 : The crucial thing is that a sw::Frame always has an anchor which
116 : points to some content in the document. This is a requirement of exporting
117 : to Word
118 : */
119 610 : sw::Frames SwPosFlyFrmsToFrames(const SwPosFlyFrms &rFlys)
120 : {
121 610 : sw::Frames aRet;
122 :
123 1152 : for(SwPosFlyFrms::const_iterator aIter(rFlys.begin()); aIter != rFlys.end(); ++aIter)
124 : {
125 542 : const SwFrameFormat &rEntry = (*aIter)->GetFormat();
126 :
127 542 : if (const SwPosition* pAnchor = rEntry.GetAnchor().GetContentAnchor())
128 : {
129 : // the anchor position will be invalidated by SetRedlineMode
130 : // so set a dummy position and fix it in UpdateFramePositions
131 : SwPosition const dummy(SwNodeIndex(
132 538 : const_cast<SwNodes&>(pAnchor->nNode.GetNodes())));
133 538 : aRet.push_back(sw::Frame(rEntry, dummy));
134 : }
135 : else
136 : {
137 4 : SwPosition aPos((*aIter)->GetNdIndex());
138 :
139 4 : if (SwTextNode* pTextNd = aPos.nNode.GetNode().GetTextNode())
140 : {
141 4 : aPos.nContent.Assign(pTextNd, 0);
142 : }
143 :
144 4 : aRet.push_back(sw::Frame(rEntry, aPos));
145 : }
146 : }
147 610 : return aRet;
148 : }
149 :
150 : //Utility to test if a frame is anchored at a given node index
151 : class anchoredto: public std::unary_function<const sw::Frame&, bool>
152 : {
153 : private:
154 : sal_uLong mnNode;
155 : public:
156 16956 : explicit anchoredto(sal_uLong nNode) : mnNode(nNode) {}
157 60056 : bool operator()(const sw::Frame &rFrame) const
158 : {
159 60056 : return (mnNode == rFrame.GetPosition().nNode.GetNode().GetIndex());
160 : }
161 : };
162 : }
163 :
164 : namespace sw
165 : {
166 : //For i120928,size conversion before exporting graphic of bullet
167 0 : Frame::Frame(const Graphic &rGrf, const SwPosition &rPos)
168 : : mpFlyFrm(NULL)
169 : , maPos(rPos)
170 : , maSize()
171 : , maLayoutSize()
172 : , meWriterType(eBulletGrf)
173 : , mpStartFrameContent(0)
174 : , mbIsInline(true)
175 : , mbForBullet(true)
176 0 : , maGrf(rGrf)
177 : {
178 0 : const MapMode aMap100mm( MAP_100TH_MM );
179 0 : Size aSize( rGrf.GetPrefSize() );
180 0 : if ( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
181 : {
182 0 : aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap100mm );
183 : }
184 : else
185 : {
186 0 : aSize = OutputDevice::LogicToLogic( aSize,rGrf.GetPrefMapMode(), aMap100mm );
187 : }
188 0 : maSize = aSize;
189 0 : maLayoutSize = maSize;
190 0 : }
191 :
192 1046 : Frame::Frame(const SwFrameFormat &rFormat, const SwPosition &rPos)
193 : : mpFlyFrm(&rFormat)
194 : , maPos(rPos)
195 : , maSize()
196 : , maLayoutSize() // #i43447#
197 : , meWriterType(eTextBox)
198 : , mpStartFrameContent(0)
199 : // #i43447# - move to initialization list
200 1046 : , mbIsInline( (rFormat.GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
201 : // #i120928# - handle graphic of bullet within existing implementation
202 : , mbForBullet(false)
203 2092 : , maGrf()
204 : {
205 1046 : switch (rFormat.Which())
206 : {
207 : case RES_FLYFRMFMT:
208 650 : if (const SwNodeIndex* pIdx = rFormat.GetContent().GetContentIdx())
209 : {
210 650 : SwNodeIndex aIdx(*pIdx, 1);
211 650 : const SwNode &rNd = aIdx.GetNode();
212 : // #i43447# - determine layout size
213 : {
214 650 : SwRect aLayRect( rFormat.FindLayoutRect() );
215 650 : Rectangle aRect( aLayRect.SVRect() );
216 : // The Object is not rendered (e.g. something in unused
217 : // header/footer) - thus, get the values from the format.
218 650 : if ( aLayRect.IsEmpty() )
219 : {
220 39 : aRect.SetSize( rFormat.GetFrmSize().GetSize() );
221 : }
222 650 : maLayoutSize = aRect.GetSize();
223 : }
224 650 : switch (rNd.GetNodeType())
225 : {
226 : case ND_GRFNODE:
227 107 : meWriterType = eGraphic;
228 107 : maSize = rNd.GetNoTextNode()->GetTwipSize();
229 107 : break;
230 : case ND_OLENODE:
231 151 : meWriterType = eOle;
232 151 : maSize = rNd.GetNoTextNode()->GetTwipSize();
233 151 : break;
234 : default:
235 392 : meWriterType = eTextBox;
236 : // #i43447# - Size equals layout size for text boxes
237 392 : maSize = maLayoutSize;
238 392 : break;
239 : }
240 650 : mpStartFrameContent = &rNd;
241 : }
242 : else
243 : {
244 : OSL_ENSURE(false, "Impossible");
245 0 : meWriterType = eTextBox;
246 : }
247 650 : break;
248 : default:
249 396 : if (const SdrObject* pObj = rFormat.FindRealSdrObject())
250 : {
251 396 : if (pObj->GetObjInventor() == FmFormInventor)
252 18 : meWriterType = eFormControl;
253 : else
254 378 : meWriterType = eDrawing;
255 396 : maSize = pObj->GetSnapRect().GetSize();
256 : }
257 : else
258 : {
259 : OSL_ENSURE(false, "Impossible");
260 0 : meWriterType = eDrawing;
261 : }
262 396 : break;
263 : }
264 1046 : }
265 :
266 :
267 0 : void Frame::ForceTreatAsInline()
268 : {
269 0 : mbIsInline = true;
270 0 : }
271 :
272 : namespace hack
273 : {
274 :
275 99 : sal_uInt16 TransformWhichBetweenPools(const SfxItemPool &rDestPool,
276 : const SfxItemPool &rSrcPool, sal_uInt16 nWhich)
277 : {
278 99 : sal_uInt16 nSlotId = rSrcPool.GetSlotId(nWhich);
279 99 : if (IsValidSlotWhich(nSlotId, nWhich))
280 99 : nWhich = rDestPool.GetWhich(nSlotId);
281 : else
282 0 : nWhich = 0;
283 99 : return nWhich;
284 : }
285 :
286 4297 : sal_uInt16 GetSetWhichFromSwDocWhich(const SfxItemSet &rSet,
287 : const SwDoc &rDoc, sal_uInt16 nWhich)
288 : {
289 4297 : if (RES_WHICHHINT_END < *(rSet.GetRanges()))
290 : {
291 6 : nWhich = TransformWhichBetweenPools(*rSet.GetPool(),
292 12 : rDoc.GetAttrPool(), nWhich);
293 : }
294 4297 : return nWhich;
295 : }
296 :
297 15 : DrawingOLEAdaptor::DrawingOLEAdaptor(SdrOle2Obj &rObj,
298 : SfxObjectShell &rPers)
299 : : mxIPRef(rObj.GetObjRef()), mrPers(rPers),
300 15 : mpGraphic( rObj.GetGraphic() )
301 : {
302 15 : rObj.AbandonObject();
303 15 : }
304 :
305 15 : bool DrawingOLEAdaptor::TransferToDoc( OUString &rName )
306 : {
307 : OSL_ENSURE(mxIPRef.is(), "Transferring invalid object to doc");
308 15 : if (!mxIPRef.is())
309 0 : return false;
310 :
311 15 : uno::Reference < container::XChild > xChild( mxIPRef, uno::UNO_QUERY );
312 15 : if ( xChild.is() )
313 12 : xChild->setParent( mrPers.GetModel() );
314 :
315 15 : bool bSuccess = mrPers.GetEmbeddedObjectContainer().InsertEmbeddedObject( mxIPRef, rName );
316 15 : if (bSuccess)
317 : {
318 15 : if ( mpGraphic )
319 : ::svt::EmbeddedObjectRef::SetGraphicToContainer( *mpGraphic,
320 15 : mrPers.GetEmbeddedObjectContainer(),
321 : rName,
322 30 : OUString() );
323 :
324 15 : mxIPRef = 0;
325 : }
326 :
327 15 : return bSuccess;
328 : }
329 :
330 30 : DrawingOLEAdaptor::~DrawingOLEAdaptor()
331 : {
332 15 : if (mxIPRef.is())
333 : {
334 : OSL_ENSURE( !mrPers.GetEmbeddedObjectContainer().HasEmbeddedObject( mxIPRef ), "Object in adaptor is inserted?!" );
335 : try
336 : {
337 0 : uno::Reference < com::sun::star::util::XCloseable > xClose( mxIPRef, uno::UNO_QUERY );
338 0 : if ( xClose.is() )
339 0 : xClose->close(sal_True);
340 : }
341 0 : catch ( const com::sun::star::util::CloseVetoException& )
342 : {
343 : }
344 :
345 0 : mxIPRef = 0;
346 : }
347 15 : }
348 : }
349 :
350 : namespace util
351 : {
352 237 : SwTwips MakeSafePositioningValue(SwTwips nIn)
353 : {
354 237 : if (nIn > SHRT_MAX)
355 4 : nIn = SHRT_MAX;
356 233 : else if (nIn < SHRT_MIN)
357 0 : nIn = SHRT_MIN;
358 237 : return nIn;
359 : }
360 :
361 0 : void SetLayer::SendObjectToHell(SdrObject &rObject) const
362 : {
363 0 : SetObjectLayer(rObject, eHell);
364 0 : }
365 :
366 100 : void SetLayer::SendObjectToHeaven(SdrObject &rObject) const
367 : {
368 100 : SetObjectLayer(rObject, eHeaven);
369 100 : }
370 :
371 100 : void SetLayer::SetObjectLayer(SdrObject &rObject, Layer eLayer) const
372 : {
373 100 : if (FmFormInventor == rObject.GetObjInventor())
374 5 : rObject.SetLayer(mnFormLayer);
375 : else
376 : {
377 95 : switch (eLayer)
378 : {
379 : case eHeaven:
380 95 : rObject.SetLayer(mnHeavenLayer);
381 95 : break;
382 : case eHell:
383 0 : rObject.SetLayer(mnHellLayer);
384 0 : break;
385 : }
386 : }
387 100 : }
388 :
389 : //SetLayer boilerplate begin
390 0 : void SetLayer::Swap(SetLayer& rOther) throw()
391 : {
392 0 : std::swap(mnHeavenLayer, rOther.mnHeavenLayer);
393 0 : std::swap(mnHellLayer, rOther.mnHellLayer);
394 0 : std::swap(mnFormLayer, rOther.mnFormLayer);
395 0 : }
396 :
397 : // #i38889# - by default put objects into the invisible layers.
398 142 : SetLayer::SetLayer(const SwDoc &rDoc)
399 142 : : mnHeavenLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleHeavenId()),
400 142 : mnHellLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleHellId()),
401 284 : mnFormLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleControlsId())
402 : {
403 142 : }
404 :
405 73 : SetLayer::SetLayer(const SetLayer& rOther) throw()
406 : : mnHeavenLayer(rOther.mnHeavenLayer),
407 : mnHellLayer(rOther.mnHellLayer),
408 73 : mnFormLayer(rOther.mnFormLayer)
409 : {
410 73 : }
411 :
412 0 : SetLayer& SetLayer::operator=(const SetLayer& rOther) throw()
413 : {
414 0 : SetLayer aTemp(rOther);
415 0 : Swap(aTemp);
416 0 : return *this;
417 : }
418 : //SetLayer boilerplate end
419 :
420 38374 : void GetPoolItems(const SfxItemSet &rSet, PoolItems &rItems, bool bExportParentItemSet )
421 : {
422 38374 : if( bExportParentItemSet )
423 : {
424 2062 : sal_uInt16 nTotal = rSet.TotalCount();
425 222642 : for( sal_uInt16 nItem =0; nItem < nTotal; ++nItem )
426 : {
427 220580 : const SfxPoolItem* pItem = 0;
428 220580 : if( SfxItemState::SET == rSet.GetItemState( rSet.GetWhichByPos( nItem ), true, &pItem ) )
429 : {
430 15695 : rItems[pItem->Which()] = pItem;
431 : }
432 : }
433 : }
434 36312 : else if( rSet.Count())
435 : {
436 26913 : SfxItemIter aIter(rSet);
437 26913 : if (const SfxPoolItem *pItem = aIter.GetCurItem())
438 : {
439 151009 : do
440 151009 : rItems[pItem->Which()] = pItem;
441 151009 : while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
442 26913 : }
443 : }
444 38374 : }
445 :
446 11871 : const SfxPoolItem *SearchPoolItems(const PoolItems &rItems,
447 : sal_uInt16 eType)
448 : {
449 11871 : sw::cPoolItemIter aIter = rItems.find(eType);
450 11871 : if (aIter != rItems.end())
451 1073 : return aIter->second;
452 10798 : return 0;
453 : }
454 :
455 1073 : void ClearOverridesFromSet(const SwFormatCharFormat &rFormat, SfxItemSet &rSet)
456 : {
457 1073 : if (const SwCharFormat* pCharFormat = rFormat.GetCharFormat())
458 : {
459 1073 : if (pCharFormat->GetAttrSet().Count())
460 : {
461 1005 : SfxItemIter aIter(pCharFormat->GetAttrSet());
462 1005 : const SfxPoolItem *pItem = aIter.GetCurItem();
463 2191 : do
464 2191 : rSet.ClearItem(pItem->Which());
465 3196 : while (!aIter.IsAtEnd() && 0 != (pItem = aIter.NextItem()));
466 : }
467 : }
468 1073 : }
469 :
470 0 : ParaStyles GetParaStyles(const SwDoc &rDoc)
471 : {
472 0 : ParaStyles aStyles;
473 : typedef ParaStyles::size_type mysizet;
474 :
475 0 : const SwTextFormatColls *pColls = rDoc.GetTextFormatColls();
476 0 : mysizet nCount = pColls ? pColls->size() : 0;
477 0 : aStyles.reserve(nCount);
478 0 : for (mysizet nI = 0; nI < nCount; ++nI)
479 0 : aStyles.push_back((*pColls)[ static_cast< sal_uInt16 >(nI) ]);
480 0 : return aStyles;
481 : }
482 :
483 866 : SwTextFormatColl* GetParaStyle(SwDoc &rDoc, const OUString& rName)
484 : {
485 : // Search first in the Doc-Styles
486 866 : SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName(rName);
487 866 : if (!pColl)
488 : {
489 : // Collection not found, try in Pool ?
490 : sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
491 706 : nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL);
492 706 : if (n != SAL_MAX_UINT16) // found or standard
493 45 : pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool(n, false);
494 : }
495 866 : return pColl;
496 : }
497 :
498 969 : SwCharFormat* GetCharStyle(SwDoc &rDoc, const OUString& rName)
499 : {
500 969 : SwCharFormat *pFormat = rDoc.FindCharFormatByName(rName);
501 969 : if (!pFormat)
502 : {
503 : // Collection not found, try in Pool ?
504 : sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
505 830 : nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
506 830 : if (n != SAL_MAX_UINT16) // found or standard
507 18 : pFormat = rDoc.getIDocumentStylePoolAccess().GetCharFormatFromPool(n);
508 : }
509 969 : return pFormat;
510 : }
511 :
512 : // #i98791# - adjust sorting algorithm
513 0 : void SortByAssignedOutlineStyleListLevel(ParaStyles &rStyles)
514 : {
515 0 : std::sort(rStyles.begin(), rStyles.end(), outlinecmp());
516 0 : }
517 :
518 : /*
519 : Utility to extract flyfmts from a document, potentially from a
520 : selection.
521 : */
522 610 : Frames GetFrames(const SwDoc &rDoc, SwPaM *pPaM /*, bool bAll*/)
523 : {
524 610 : SwPosFlyFrms aFlys(rDoc.GetAllFlyFormats(pPaM, true));
525 610 : sw::Frames aRet(SwPosFlyFrmsToFrames(aFlys));
526 610 : return aRet;
527 : }
528 :
529 610 : void UpdateFramePositions(Frames & rFrames)
530 : {
531 1152 : for (Frame & rFrame : rFrames)
532 : {
533 542 : SwFormatAnchor const& rAnchor = rFrame.GetFrameFormat().GetAnchor();
534 542 : if (SwPosition const*const pAnchor = rAnchor.GetContentAnchor())
535 : {
536 538 : rFrame.SetPosition(*pAnchor);
537 : }
538 : else
539 : { // these don't need to be corrected, they're not in redlines
540 : assert(FLY_AT_PAGE == rAnchor.GetAnchorId());
541 : }
542 : }
543 610 : }
544 :
545 16956 : Frames GetFramesInNode(const Frames &rFrames, const SwNode &rNode)
546 : {
547 16956 : Frames aRet;
548 : my_copy_if(rFrames.begin(), rFrames.end(),
549 16956 : std::back_inserter(aRet), anchoredto(rNode.GetIndex()));
550 16956 : return aRet;
551 : }
552 :
553 131 : const SwNumFormat* GetNumFormatFromSwNumRuleLevel(const SwNumRule &rRule,
554 : int nLevel)
555 : {
556 131 : if (nLevel < 0 || nLevel >= MAXLEVEL)
557 : {
558 : OSL_FAIL("Invalid level");
559 0 : return NULL;
560 : }
561 131 : return &(rRule.Get( static_cast< sal_uInt16 >(nLevel) ));
562 : }
563 :
564 1377 : const SwNumFormat* GetNumFormatFromTextNode(const SwTextNode &rTextNode)
565 : {
566 1377 : const SwNumRule *pRule = 0;
567 1377 : if (
568 1377 : rTextNode.IsNumbered() && rTextNode.IsCountedInList() &&
569 : 0 != (pRule = rTextNode.GetNumRule())
570 : )
571 : {
572 : return GetNumFormatFromSwNumRuleLevel(*pRule,
573 131 : rTextNode.GetActualListLevel());
574 : }
575 :
576 : OSL_ENSURE(rTextNode.GetDoc(), "No document for node?, suspicious");
577 1246 : if (!rTextNode.GetDoc())
578 0 : return 0;
579 :
580 1246 : if (
581 1246 : rTextNode.IsNumbered() && rTextNode.IsCountedInList() &&
582 0 : 0 != (pRule = rTextNode.GetDoc()->GetOutlineNumRule())
583 : )
584 : {
585 : return GetNumFormatFromSwNumRuleLevel(*pRule,
586 0 : rTextNode.GetActualListLevel());
587 : }
588 :
589 1246 : return 0;
590 : }
591 :
592 3090 : const SwNumRule* GetNumRuleFromTextNode(const SwTextNode &rTextNode)
593 : {
594 3090 : return GetNormalNumRuleFromTextNode(rTextNode);
595 : }
596 :
597 3090 : const SwNumRule* GetNormalNumRuleFromTextNode(const SwTextNode &rTextNode)
598 : {
599 3090 : const SwNumRule *pRule = 0;
600 :
601 3090 : if (
602 3090 : rTextNode.IsNumbered() && rTextNode.IsCountedInList() &&
603 : 0 != (pRule = rTextNode.GetNumRule())
604 : )
605 : {
606 598 : return pRule;
607 : }
608 2492 : return 0;
609 : }
610 :
611 13 : SwNoTextNode *GetNoTextNodeFromSwFrameFormat(const SwFrameFormat &rFormat)
612 : {
613 13 : const SwNodeIndex *pIndex = rFormat.GetContent().GetContentIdx();
614 : OSL_ENSURE(pIndex, "No NodeIndex in SwFrameFormat ?, suspicious");
615 13 : if (!pIndex)
616 1 : return 0;
617 12 : SwNodeIndex aIdx(*pIndex, 1);
618 12 : return aIdx.GetNode().GetNoTextNode();
619 : }
620 :
621 0 : bool HasPageBreak(const SwNode &rNd)
622 : {
623 0 : const SvxFormatBreakItem *pBreak = 0;
624 0 : if (rNd.IsTableNode() && rNd.GetTableNode())
625 : {
626 0 : const SwTable& rTable = rNd.GetTableNode()->GetTable();
627 0 : const SwFrameFormat* pApply = rTable.GetFrameFormat();
628 : OSL_ENSURE(pApply, "impossible");
629 0 : if (pApply)
630 0 : pBreak = &(ItemGet<SvxFormatBreakItem>(*pApply, RES_BREAK));
631 : }
632 0 : else if (const SwContentNode *pNd = rNd.GetContentNode())
633 0 : pBreak = &(ItemGet<SvxFormatBreakItem>(*pNd, RES_BREAK));
634 :
635 0 : if (pBreak && pBreak->GetBreak() == SVX_BREAK_PAGE_BEFORE)
636 0 : return true;
637 0 : return false;
638 : }
639 :
640 3 : Polygon PolygonFromPolyPolygon(const tools::PolyPolygon &rPolyPoly)
641 : {
642 3 : if(1 == rPolyPoly.Count())
643 : {
644 3 : return rPolyPoly[0];
645 : }
646 : else
647 : {
648 : // This method will now just concatenate the polygons contained
649 : // in the given PolyPolygon. Anything else which might be thought of
650 : // for reducing to a single polygon will just need nore power and
651 : // cannot create more correct results.
652 0 : sal_uInt32 nPointCount(0L);
653 : sal_uInt16 a;
654 :
655 0 : for(a = 0; a < rPolyPoly.Count(); a++)
656 : {
657 0 : nPointCount += (sal_uInt32)rPolyPoly[a].GetSize();
658 : }
659 :
660 0 : if(nPointCount > 0x0000ffff)
661 : {
662 : OSL_FAIL("PolygonFromPolyPolygon: too many points for a single polygon (!)");
663 0 : nPointCount = 0x0000ffff;
664 : }
665 :
666 0 : Polygon aRetval((sal_uInt16)nPointCount);
667 0 : sal_uInt32 nAppendIndex(0L);
668 :
669 0 : for(a = 0; a < rPolyPoly.Count(); a++)
670 : {
671 0 : const Polygon& rCandidate = rPolyPoly[a];
672 :
673 0 : for(sal_uInt16 b(0); nAppendIndex <= nPointCount && b < rCandidate.GetSize(); b++)
674 : {
675 0 : aRetval[(sal_uInt16)nAppendIndex++] = rCandidate[b];
676 : }
677 : }
678 :
679 0 : return aRetval;
680 : }
681 : }
682 :
683 3 : Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon& rPolyPoly, const SwNoTextNode* pNd)
684 : {
685 3 : Polygon aPoly(PolygonFromPolyPolygon(rPolyPoly));
686 3 : const Size &rOrigSize = pNd->GetGraphic().GetPrefSize();
687 6 : Fraction aMapPolyX(ww::nWrap100Percent, rOrigSize.Width());
688 6 : Fraction aMapPolyY(ww::nWrap100Percent, rOrigSize.Height());
689 3 : aPoly.Scale(aMapPolyX, aMapPolyY);
690 :
691 : /*
692 : a) stretch right bound by 15twips
693 : b) shrink bottom bound to where it would have been in word
694 : c) Move it to the left by 15twips
695 :
696 : See the import for details
697 : */
698 3 : const Size &rSize = pNd->GetTwipSize();
699 6 : Fraction aMoveHack(ww::nWrap100Percent, rSize.Width());
700 3 : aMoveHack *= Fraction(15, 1);
701 3 : long nMove(aMoveHack);
702 :
703 : Fraction aHackX(ww::nWrap100Percent + nMove,
704 6 : ww::nWrap100Percent);
705 : Fraction aHackY(ww::nWrap100Percent - nMove,
706 6 : ww::nWrap100Percent);
707 3 : aPoly.Scale(aHackX, aHackY);
708 :
709 3 : aPoly.Move(-nMove, 0);
710 6 : return aPoly;
711 : }
712 :
713 5 : void RedlineStack::open(const SwPosition& rPos, const SfxPoolItem& rAttr)
714 : {
715 : OSL_ENSURE(rAttr.Which() == RES_FLTR_REDLINE, "not a redline");
716 5 : maStack.push_back(new SwFltStackEntry(rPos,rAttr.Clone()));
717 5 : }
718 :
719 : class SameOpenRedlineType :
720 : public std::unary_function<const SwFltStackEntry*, bool>
721 : {
722 : private:
723 : RedlineType_t meType;
724 : public:
725 5 : explicit SameOpenRedlineType(RedlineType_t eType) : meType(eType) {}
726 5 : bool operator()(const SwFltStackEntry *pEntry) const
727 : {
728 : const SwFltRedline *pTest = static_cast<const SwFltRedline *>
729 5 : (pEntry->pAttr);
730 5 : return (pEntry->bOpen && (pTest->eType == meType));
731 : }
732 : };
733 :
734 5 : bool RedlineStack::close(const SwPosition& rPos, RedlineType_t eType)
735 : {
736 : //Search from end for same type
737 : myriter aResult = std::find_if(maStack.rbegin(), maStack.rend(),
738 5 : SameOpenRedlineType(eType));
739 5 : if (aResult != maStack.rend())
740 : {
741 5 : (*aResult)->SetEndPos(rPos);
742 5 : return true;
743 : }
744 0 : return false;
745 : }
746 :
747 459 : void RedlineStack::closeall(const SwPosition& rPos)
748 : {
749 459 : std::for_each(maStack.begin(), maStack.end(), SetEndIfOpen(rPos));
750 459 : }
751 :
752 5 : void SetInDocAndDelete::operator()(SwFltStackEntry *pEntry)
753 : {
754 5 : SwPaM aRegion(pEntry->m_aMkPos.m_nNode);
755 5 : if (
756 10 : pEntry->MakeRegion(&mrDoc, aRegion, true) &&
757 5 : (*aRegion.GetPoint() != *aRegion.GetMark())
758 : )
759 : {
760 5 : mrDoc.getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT |
761 5 : nsRedlineMode_t::REDLINE_SHOW_DELETE));
762 : const SwFltRedline *pFltRedline = static_cast<const SwFltRedline*>
763 5 : (pEntry->pAttr);
764 :
765 5 : if (USHRT_MAX != pFltRedline->nAutorNoPrev)
766 : {
767 : SwRedlineData aData(pFltRedline->eTypePrev,
768 : pFltRedline->nAutorNoPrev, pFltRedline->aStampPrev, OUString(),
769 0 : 0);
770 :
771 0 : mrDoc.getIDocumentRedlineAccess().AppendRedline(new SwRangeRedline(aData, aRegion), true);
772 : }
773 :
774 : SwRedlineData aData(pFltRedline->eType, pFltRedline->nAutorNo,
775 5 : pFltRedline->aStamp, OUString(), 0);
776 :
777 5 : SwRangeRedline *const pNewRedline(new SwRangeRedline(aData, aRegion));
778 : // the point node may be deleted in AppendRedline, so park
779 : // the PaM somewhere safe
780 5 : aRegion.DeleteMark();
781 5 : *aRegion.GetPoint() = SwPosition(SwNodeIndex(mrDoc.GetNodes()));
782 5 : mrDoc.getIDocumentRedlineAccess().AppendRedline(pNewRedline, true);
783 5 : mrDoc.getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)(nsRedlineMode_t::REDLINE_NONE | nsRedlineMode_t::REDLINE_SHOW_INSERT |
784 5 : nsRedlineMode_t::REDLINE_SHOW_DELETE ));
785 : }
786 5 : delete pEntry;
787 5 : }
788 :
789 3 : bool CompareRedlines::operator()(const SwFltStackEntry *pOneE,
790 : const SwFltStackEntry *pTwoE) const
791 : {
792 : const SwFltRedline *pOne= static_cast<const SwFltRedline*>
793 3 : (pOneE->pAttr);
794 : const SwFltRedline *pTwo= static_cast<const SwFltRedline*>
795 3 : (pTwoE->pAttr);
796 :
797 : //Return the earlier time, if two have the same time, prioritize
798 : //inserts over deletes
799 3 : if (pOne->aStamp == pTwo->aStamp)
800 1 : return (pOne->eType == nsRedlineType_t::REDLINE_INSERT && pTwo->eType != nsRedlineType_t::REDLINE_INSERT);
801 : else
802 2 : return (pOne->aStamp < pTwo->aStamp);
803 : }
804 :
805 918 : RedlineStack::~RedlineStack()
806 : {
807 459 : std::sort(maStack.begin(), maStack.end(), CompareRedlines());
808 459 : std::for_each(maStack.begin(), maStack.end(), SetInDocAndDelete(mrDoc));
809 459 : }
810 :
811 8 : sal_uInt16 WrtRedlineAuthor::AddName( const OUString& rNm )
812 : {
813 : sal_uInt16 nRet;
814 : typedef std::vector<OUString>::iterator myiter;
815 8 : myiter aIter = std::find(maAuthors.begin(), maAuthors.end(), rNm);
816 8 : if (aIter != maAuthors.end())
817 2 : nRet = static_cast< sal_uInt16 >(aIter - maAuthors.begin());
818 : else
819 : {
820 6 : nRet = static_cast< sal_uInt16 >(maAuthors.size());
821 6 : maAuthors.push_back(rNm);
822 : }
823 8 : return nRet;
824 : }
825 : }
826 :
827 : namespace util
828 : {
829 0 : InsertedTableClient::InsertedTableClient(SwTableNode & rNode)
830 : {
831 0 : rNode.Add(this);
832 0 : }
833 :
834 0 : SwTableNode * InsertedTableClient::GetTableNode()
835 : {
836 0 : return dynamic_cast<SwTableNode *> (GetRegisteredInNonConst());
837 : }
838 :
839 127 : InsertedTablesManager::InsertedTablesManager(const SwDoc &rDoc)
840 127 : : mbHasRoot(rDoc.getIDocumentLayoutAccess().GetCurrentLayout())
841 : {
842 127 : }
843 :
844 125 : void InsertedTablesManager::DelAndMakeTableFrms()
845 : {
846 125 : if (!mbHasRoot)
847 250 : return;
848 0 : TableMapIter aEnd = maTables.end();
849 0 : for (TableMapIter aIter = maTables.begin(); aIter != aEnd; ++aIter)
850 : {
851 : // exitiert schon ein Layout, dann muss an dieser Tabelle die BoxFrames
852 : // neu erzeugt
853 0 : SwTableNode *pTable = aIter->first->GetTableNode();
854 : OSL_ENSURE(pTable, "Why no expected table");
855 0 : if (pTable)
856 : {
857 0 : SwFrameFormat * pFrameFormat = pTable->GetTable().GetFrameFormat();
858 :
859 0 : if (pFrameFormat != NULL)
860 : {
861 0 : SwNodeIndex *pIndex = aIter->second;
862 0 : pTable->DelFrms();
863 0 : pTable->MakeFrms(pIndex);
864 : }
865 : }
866 : }
867 : }
868 :
869 74 : void InsertedTablesManager::InsertTable(SwTableNode &rTableNode, SwPaM &rPaM)
870 : {
871 74 : if (!mbHasRoot)
872 148 : return;
873 : //Associate this tablenode with this after position, replace an //old
874 : //node association if necessary
875 :
876 0 : InsertedTableClient * pClient = new InsertedTableClient(rTableNode);
877 :
878 0 : maTables.insert(TableMap::value_type(pClient, &(rPaM.GetPoint()->nNode)));
879 : }
880 : }
881 :
882 60 : }
883 :
884 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|