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 <sal/config.h>
21 :
22 : #include <utility>
23 :
24 : #include <rtl/ustrbuf.hxx>
25 : #include <swtypes.hxx>
26 : #include <hintids.hxx>
27 : #include <cmdid.h>
28 : #include <hints.hxx>
29 : #include <IMark.hxx>
30 : #include <bookmrk.hxx>
31 : #include <frmfmt.hxx>
32 : #include <doc.hxx>
33 : #include <IDocumentUndoRedo.hxx>
34 : #include <IDocumentLayoutAccess.hxx>
35 : #include <textboxhelper.hxx>
36 : #include <ndtxt.hxx>
37 : #include <ndnotxt.hxx>
38 : #include <unocrsr.hxx>
39 : #include <swundo.hxx>
40 : #include <rootfrm.hxx>
41 : #include <flyfrm.hxx>
42 : #include <ftnidx.hxx>
43 : #include <sfx2/linkmgr.hxx>
44 : #include <docary.hxx>
45 : #include <paratr.hxx>
46 : #include <pam.hxx>
47 : #include <shellio.hxx>
48 : #include <swerror.h>
49 : #include <swtblfmt.hxx>
50 : #include <docsh.hxx>
51 : #include <docstyle.hxx>
52 : #include <charfmt.hxx>
53 : #include <txtfld.hxx>
54 : #include <fmtfld.hxx>
55 : #include <fmtpdsc.hxx>
56 : #include <pagedesc.hxx>
57 : #include <poolfmt.hrc>
58 : #include <poolfmt.hxx>
59 : #include <edimp.hxx>
60 : #include <fchrfmt.hxx>
61 : #include <cntfrm.hxx>
62 : #include <pagefrm.hxx>
63 : #include <doctxm.hxx>
64 : #include <sfx2/docfilt.hxx>
65 : #include <sfx2/docfile.hxx>
66 : #include <sfx2/fcontnr.hxx>
67 : #include <fmtrfmrk.hxx>
68 : #include <txtrfmrk.hxx>
69 : #include <unoparaframeenum.hxx>
70 : #include <unofootnote.hxx>
71 : #include <unotextbodyhf.hxx>
72 : #include <unotextrange.hxx>
73 : #include <unoparagraph.hxx>
74 : #include <unomap.hxx>
75 : #include <unoport.hxx>
76 : #include <unocrsrhelper.hxx>
77 : #include <unosett.hxx>
78 : #include <unoprnms.hxx>
79 : #include <unotbl.hxx>
80 : #include <unodraw.hxx>
81 : #include <unocoll.hxx>
82 : #include <unostyle.hxx>
83 : #include <fmtanchr.hxx>
84 : #include <editeng/flstitem.hxx>
85 : #include <editeng/unolingu.hxx>
86 : #include <svtools/ctrltool.hxx>
87 : #include <flypos.hxx>
88 : #include <txtftn.hxx>
89 : #include <fmtftn.hxx>
90 : #include <fmtcntnt.hxx>
91 : #include <com/sun/star/text/WrapTextMode.hpp>
92 : #include <com/sun/star/text/TextContentAnchorType.hpp>
93 : #include <com/sun/star/style/PageStyleLayout.hpp>
94 : #include <com/sun/star/text/XTextDocument.hpp>
95 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
96 : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
97 : #include <unoframe.hxx>
98 : #include <fmthdft.hxx>
99 : #include <osl/mutex.hxx>
100 : #include <vcl/svapp.hxx>
101 : #include <fmtflcnt.hxx>
102 : #include <editeng/brushitem.hxx>
103 : #include <fmtclds.hxx>
104 : #include <dcontact.hxx>
105 : #include <dflyobj.hxx>
106 : #include <crsskip.hxx>
107 : #include <vector>
108 : #include <sortedobjs.hxx>
109 : #include <sortopt.hxx>
110 : #include <algorithm>
111 : #include <iterator>
112 : #include <boost/bind.hpp>
113 : #include <calbck.hxx>
114 : #include <comphelper/servicehelper.hxx>
115 : #include <cppuhelper/supportsservice.hxx>
116 :
117 : using namespace ::com::sun::star;
118 :
119 : namespace sw {
120 :
121 : uno::Sequence< OUString >
122 1179 : GetSupportedServiceNamesImpl(
123 : size_t const nServices, char const*const pServices[])
124 : {
125 1179 : uno::Sequence< OUString > ret(nServices);
126 10242 : for (size_t i = 0; i < nServices; ++i)
127 : {
128 9063 : ret[i] = OUString::createFromAscii(pServices[i]);
129 : }
130 1179 : return ret;
131 : }
132 :
133 : } // namespace sw
134 :
135 : namespace sw {
136 :
137 1 : void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget)
138 : {
139 1 : rTarget = rSource;
140 :
141 1 : if (rSource.GetNext() != &rSource)
142 : {
143 0 : SwPaM *pPam = const_cast<SwPaM*>(rSource.GetNext());
144 0 : do
145 : {
146 : // create new PaM
147 0 : SwPaM *const pNew = new SwPaM(*pPam, nullptr);
148 : // insert into ring
149 0 : pNew->MoveTo(&rTarget);
150 0 : pPam = pPam->GetNext();
151 : }
152 : while (pPam != &rSource);
153 : }
154 1 : }
155 :
156 : } // namespace sw
157 :
158 : struct FrameClientSortListLess
159 : {
160 0 : bool operator() (FrameClientSortListEntry const& r1,
161 : FrameClientSortListEntry const& r2) const
162 : {
163 0 : return (r1.nIndex < r2.nIndex)
164 0 : || ((r1.nIndex == r2.nIndex) && (r1.nOrder < r2.nOrder));
165 : }
166 : };
167 :
168 : namespace
169 : {
170 2905 : void lcl_CollectFrameAtNodeWithLayout(SwDoc* pDoc, const SwContentFrm* pCFrm,
171 : FrameClientSortList_t& rFrames,
172 : const sal_uInt16 nAnchorType)
173 : {
174 2905 : auto pObjs = pCFrm->GetDrawObjs();
175 2905 : if(!pObjs)
176 5597 : return;
177 213 : const auto aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
178 783 : for(const auto pAnchoredObj : *pObjs)
179 : {
180 570 : SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat();
181 : // Filter out textboxes, which are not interesting at an UNO level.
182 570 : if(aTextBoxes.find(&rFormat) != aTextBoxes.end())
183 11 : continue;
184 559 : if(rFormat.GetAnchor().GetAnchorId() == nAnchorType)
185 : {
186 : const auto nIdx =
187 110 : rFormat.GetAnchor().GetContentAnchor()->nContent.GetIndex();
188 110 : const auto nOrder = rFormat.GetAnchor().GetOrder();
189 110 : FrameClientSortListEntry entry(nIdx, nOrder, new sw::FrameClient(&rFormat));
190 110 : rFrames.push_back(entry);
191 : }
192 213 : }
193 : }
194 : }
195 :
196 :
197 2939 : void CollectFrameAtNode( const SwNodeIndex& rIdx,
198 : FrameClientSortList_t& rFrames,
199 : const bool bAtCharAnchoredObjs )
200 : {
201 : // _bAtCharAnchoredObjs:
202 : // <true>: at-character anchored objects are collected
203 : // <false>: at-paragraph anchored objects are collected
204 :
205 : // search all borders, images, and OLEs that are connected to the paragraph
206 2939 : SwDoc* pDoc = rIdx.GetNode().GetDoc();
207 :
208 : const auto nChkType = static_cast< sal_uInt16 >((bAtCharAnchoredObjs)
209 2939 : ? FLY_AT_CHAR : FLY_AT_PARA);
210 : const SwContentFrm* pCFrm;
211 : const SwContentNode* pCNd;
212 8807 : if( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() &&
213 5868 : 0 != (pCNd = rIdx.GetNode().GetContentNode()) &&
214 2929 : 0 != (pCFrm = pCNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout())) )
215 : {
216 2905 : lcl_CollectFrameAtNodeWithLayout(pDoc, pCFrm, rFrames, nChkType);
217 : }
218 : else
219 : {
220 34 : const SwFrameFormats& rFormats = *pDoc->GetSpzFrameFormats();
221 34 : const size_t nSize = rFormats.size();
222 58 : for ( size_t i = 0; i < nSize; i++)
223 : {
224 24 : const SwFrameFormat* pFormat = rFormats[ i ];
225 24 : const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
226 : const SwPosition* pAnchorPos;
227 48 : if( rAnchor.GetAnchorId() == nChkType &&
228 24 : 0 != (pAnchorPos = rAnchor.GetContentAnchor()) &&
229 0 : pAnchorPos->nNode == rIdx )
230 : {
231 :
232 : // OD 2004-05-07 #i28701# - determine insert position for
233 : // sorted <rFrameArr>
234 0 : const sal_Int32 nIndex = pAnchorPos->nContent.GetIndex();
235 0 : sal_uInt32 nOrder = rAnchor.GetOrder();
236 :
237 0 : FrameClientSortListEntry entry(nIndex, nOrder, new sw::FrameClient(const_cast<SwFrameFormat*>(pFormat)));
238 0 : rFrames.push_back(entry);
239 : }
240 : }
241 34 : ::std::sort(rFrames.begin(), rFrames.end(), FrameClientSortListLess());
242 : }
243 2939 : }
244 :
245 203312 : UnoActionContext::UnoActionContext(SwDoc *const pDoc)
246 203312 : : m_pDoc(pDoc)
247 : {
248 203312 : SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
249 203312 : if (pRootFrm)
250 : {
251 20970 : pRootFrm->StartAllAction();
252 : }
253 203312 : }
254 :
255 203312 : UnoActionContext::~UnoActionContext()
256 : {
257 : // Doc may already have been removed here
258 203312 : if (m_pDoc)
259 : {
260 203312 : SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
261 203312 : if (pRootFrm)
262 : {
263 20970 : pRootFrm->EndAllAction();
264 : }
265 : }
266 203312 : }
267 :
268 245 : UnoActionRemoveContext::UnoActionRemoveContext(SwDoc *const pDoc)
269 245 : : m_pDoc(pDoc)
270 : {
271 245 : SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
272 245 : if (pRootFrm)
273 : {
274 174 : pRootFrm->UnoRemoveAllActions();
275 : }
276 245 : }
277 :
278 245 : UnoActionRemoveContext::~UnoActionRemoveContext()
279 : {
280 245 : SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
281 245 : if (pRootFrm)
282 : {
283 174 : pRootFrm->UnoRestoreAllActions();
284 : }
285 245 : }
286 :
287 170378 : void ClientModify(SwClient* pClient, const SfxPoolItem *pOld, const SfxPoolItem *pNew)
288 : {
289 170378 : switch( pOld ? pOld->Which() : 0 )
290 : {
291 : case RES_REMOVE_UNO_OBJECT:
292 : case RES_OBJECTDYING:
293 111854 : if( static_cast<void*>(pClient->GetRegisteredIn()) == static_cast<const SwPtrMsgPoolItem *>(pOld)->pObject )
294 111201 : pClient->GetRegisteredIn()->Remove(pClient);
295 111854 : break;
296 :
297 : case RES_FMT_CHG:
298 : // Is the move to the new one finished and will the old one be deleted?
299 3222 : if( static_cast<const SwFormatChg*>(pNew)->pChangedFormat == pClient->GetRegisteredIn() &&
300 810 : static_cast<const SwFormatChg*>(pOld)->pChangedFormat->IsFormatInDTOR() )
301 804 : static_cast<SwModify*>(pClient->GetRegisteredIn())->Remove(pClient);
302 2412 : break;
303 : }
304 170378 : }
305 :
306 110498 : void SwUnoCursorHelper::SetCrsrAttr(SwPaM & rPam,
307 : const SfxItemSet& rSet,
308 : const SetAttrMode nAttrMode, const bool bTableMode)
309 : {
310 110498 : const SetAttrMode nFlags = nAttrMode | SetAttrMode::APICALL;
311 110498 : SwDoc* pDoc = rPam.GetDoc();
312 : //StartEndAction
313 110498 : UnoActionContext aAction(pDoc);
314 110498 : if (rPam.GetNext() != &rPam) // Ring of Cursors
315 : {
316 73 : pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSATTR, NULL);
317 :
318 1533 : for(SwPaM& rCurrent : rPam.GetRingContainer())
319 : {
320 2920 : if (rCurrent.HasMark() &&
321 0 : ( (bTableMode) ||
322 0 : (*rCurrent.GetPoint() != *rCurrent.GetMark()) ))
323 : {
324 1460 : pDoc->getIDocumentContentOperations().InsertItemSet(rCurrent, rSet, nFlags);
325 : }
326 : }
327 :
328 73 : pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSATTR, NULL);
329 : }
330 : else
331 : {
332 110425 : pDoc->getIDocumentContentOperations().InsertItemSet( rPam, rSet, nFlags );
333 : }
334 :
335 110498 : if( rSet.GetItemState( RES_PARATR_OUTLINELEVEL, false ) >= SfxItemState::DEFAULT )
336 : {
337 870 : SwTextNode * pTmpNode = rPam.GetNode().GetTextNode();
338 870 : if ( pTmpNode )
339 : {
340 870 : rPam.GetDoc()->GetNodes().UpdateOutlineNode( *pTmpNode );
341 : }
342 110498 : }
343 110498 : }
344 :
345 : // #i63870#
346 : // split third parameter <bCurrentAttrOnly> into new parameters <bOnlyTextAttr>
347 : // and <bGetFromChrFormat> to get better control about resulting <SfxItemSet>
348 138761 : void SwUnoCursorHelper::GetCrsrAttr(SwPaM & rPam,
349 : SfxItemSet & rSet, const bool bOnlyTextAttr, const bool bGetFromChrFormat)
350 : {
351 : static const sal_uLong nMaxLookup = 1000;
352 138761 : SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
353 138761 : SfxItemSet *pSet = &rSet;
354 281740 : for(SwPaM& rCurrent : rPam.GetRingContainer())
355 : {
356 142979 : SwPosition const & rStart( *rCurrent.Start() );
357 142979 : SwPosition const & rEnd( *rCurrent.End() );
358 142979 : const sal_uLong nSttNd = rStart.nNode.GetIndex();
359 142979 : const sal_uLong nEndNd = rEnd .nNode.GetIndex();
360 :
361 142979 : if (nEndNd - nSttNd >= nMaxLookup)
362 : {
363 0 : rSet.ClearItem();
364 0 : rSet.InvalidateAllItems();
365 138761 : return;// uno::Any();
366 : }
367 :
368 : // the first node inserts the values into the get set
369 : // all other nodes merge their values into the get set
370 292048 : for (sal_uLong n = nSttNd; n <= nEndNd; ++n)
371 : {
372 149069 : SwNode *const pNd = rPam.GetDoc()->GetNodes()[ n ];
373 149069 : switch (pNd->GetNodeType())
374 : {
375 : case ND_TEXTNODE:
376 : {
377 : const sal_Int32 nStart = (n == nSttNd)
378 146479 : ? rStart.nContent.GetIndex() : 0;
379 : const sal_Int32 nEnd = (n == nEndNd)
380 142695 : ? rEnd.nContent.GetIndex()
381 289174 : : pNd->GetTextNode()->GetText().getLength();
382 146479 : pNd->GetTextNode()->GetAttr(*pSet, nStart, nEnd, bOnlyTextAttr, bGetFromChrFormat);
383 : }
384 146479 : break;
385 :
386 : case ND_GRFNODE:
387 : case ND_OLENODE:
388 0 : static_cast<SwContentNode*>(pNd)->GetAttr( *pSet );
389 0 : break;
390 :
391 : default:
392 2590 : continue; // skip this node
393 : }
394 :
395 146479 : if (pSet != &rSet)
396 : {
397 8002 : rSet.MergeValues( aSet );
398 : }
399 : else
400 : {
401 138477 : pSet = &aSet;
402 : }
403 :
404 146479 : if (aSet.Count())
405 : {
406 5720 : aSet.ClearItem();
407 : }
408 : }
409 138761 : }
410 : }
411 :
412 : struct SwXParagraphEnumerationImpl SAL_FINAL : public SwXParagraphEnumeration
413 : {
414 : uno::Reference< text::XText > const m_xParentText;
415 : const CursorType m_eCursorType;
416 : /// Start node of the cell _or_ table the enumeration belongs to.
417 : /// Used to restrict the movement of the UNO cursor to the cell and its
418 : /// embedded tables.
419 : SwStartNode const*const m_pOwnStartNode;
420 : SwTable const*const m_pOwnTable;
421 : const sal_uLong m_nEndIndex;
422 : sal_Int32 m_nFirstParaStart;
423 : sal_Int32 m_nLastParaEnd;
424 : bool m_bFirstParagraph;
425 : uno::Reference< text::XTextContent > m_xNextPara;
426 : sw::UnoCursorPointer m_pCrsr;
427 :
428 9103 : SwXParagraphEnumerationImpl(
429 : uno::Reference< text::XText > const& xParent,
430 : ::std::shared_ptr<SwUnoCrsr> pCursor,
431 : const CursorType eType,
432 : SwStartNode const*const pStartNode, SwTable const*const pTable)
433 : : m_xParentText( xParent )
434 : , m_eCursorType( eType )
435 : // remember table and start node for later travelling
436 : // (used in export of tables in tables)
437 : , m_pOwnStartNode( pStartNode )
438 : // for import of tables in tables we have to remember the actual
439 : // table and start node of the current position in the enumeration.
440 : , m_pOwnTable( pTable )
441 9103 : , m_nEndIndex( pCursor->End()->nNode.GetIndex() )
442 : , m_nFirstParaStart( -1 )
443 : , m_nLastParaEnd( -1 )
444 : , m_bFirstParagraph( true )
445 18206 : , m_pCrsr(pCursor)
446 : {
447 : OSL_ENSURE(m_xParentText.is(), "SwXParagraphEnumeration: no parent?");
448 : OSL_ENSURE( !((CURSOR_SELECTION_IN_TABLE == eType) ||
449 : (CURSOR_TBLTEXT == eType))
450 : || (m_pOwnTable && m_pOwnStartNode),
451 : "SwXParagraphEnumeration: table type but no start node or table?");
452 :
453 16203 : if ((CURSOR_SELECTION == m_eCursorType) ||
454 7100 : (CURSOR_SELECTION_IN_TABLE == m_eCursorType))
455 : {
456 2942 : SwUnoCrsr & rCursor = *GetCursor();
457 2942 : rCursor.Normalize();
458 2942 : m_nFirstParaStart = rCursor.GetPoint()->nContent.GetIndex();
459 2942 : m_nLastParaEnd = rCursor.GetMark()->nContent.GetIndex();
460 2942 : rCursor.DeleteMark();
461 : }
462 9103 : }
463 :
464 18206 : virtual ~SwXParagraphEnumerationImpl()
465 18206 : { m_pCrsr.reset(nullptr); }
466 9581 : virtual void SAL_CALL release() throw () SAL_OVERRIDE
467 : {
468 9581 : SolarMutexGuard g;
469 9581 : OWeakObject::release();
470 9581 : }
471 :
472 : // XServiceInfo
473 0 : virtual OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
474 0 : { return OUString("SwXParagraphEnumeration"); }
475 0 : virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
476 0 : { return cppu::supportsService(this, rServiceName); };
477 0 : virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
478 0 : { return {"com.sun.star.text.ParagraphEnumeration"}; };
479 :
480 : // XEnumeration
481 : virtual sal_Bool SAL_CALL hasMoreElements() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
482 : virtual ::com::sun::star::uno::Any SAL_CALL nextElement() throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
483 :
484 23099 : SwUnoCrsr* GetCursor()
485 23099 : { return &(*m_pCrsr); }
486 : uno::Reference< text::XTextContent > NextElement_Impl()
487 : throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
488 : };
489 :
490 9103 : SwXParagraphEnumeration* SwXParagraphEnumeration::Create(
491 : uno::Reference< text::XText > const& xParent,
492 : ::std::shared_ptr<SwUnoCrsr> pCursor,
493 : const CursorType eType,
494 : SwStartNode const*const pStartNode,
495 : SwTable const*const pTable)
496 : {
497 9103 : return new SwXParagraphEnumerationImpl(xParent, pCursor, eType, pStartNode, pTable);
498 : }
499 :
500 : sal_Bool SAL_CALL
501 8865 : SwXParagraphEnumerationImpl::hasMoreElements() throw (uno::RuntimeException, std::exception)
502 : {
503 8865 : SolarMutexGuard aGuard;
504 8865 : return m_bFirstParagraph || m_xNextPara.is();
505 : }
506 :
507 : //!! compare to SwShellTableCrsr::FillRects() in viscrs.cxx
508 : static SwTableNode *
509 24255 : lcl_FindTopLevelTable(
510 : SwTableNode *const pTableNode, SwTable const*const pOwnTable)
511 : {
512 : // find top-most table in current context (section) level
513 :
514 24255 : SwTableNode * pLast = pTableNode;
515 49382 : for (SwTableNode* pTmp = pLast;
516 24691 : pTmp != NULL && &pTmp->GetTable() != pOwnTable; /* we must not go up higher than the own table! */
517 436 : pTmp = pTmp->StartOfSectionNode()->FindTableNode() )
518 : {
519 436 : pLast = pTmp;
520 : }
521 24255 : return pLast;
522 : }
523 :
524 : static bool
525 28204 : lcl_CursorIsInSection(
526 : SwUnoCrsr const*const pUnoCrsr, SwStartNode const*const pOwnStartNode)
527 : {
528 : // returns true if the cursor is in the section (or in a sub section!)
529 : // represented by pOwnStartNode
530 :
531 28204 : bool bRes = true;
532 28204 : if (pUnoCrsr && pOwnStartNode)
533 : {
534 12830 : const SwEndNode * pOwnEndNode = pOwnStartNode->EndOfSectionNode();
535 25660 : bRes = pOwnStartNode->GetIndex() <= pUnoCrsr->Start()->nNode.GetIndex() &&
536 25660 : pUnoCrsr->End()->nNode.GetIndex() <= pOwnEndNode->GetIndex();
537 : }
538 28204 : return bRes;
539 : }
540 :
541 : uno::Reference< text::XTextContent >
542 20157 : SwXParagraphEnumerationImpl::NextElement_Impl() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
543 : {
544 20157 : SwUnoCrsr *const pUnoCrsr = GetCursor();
545 20157 : if (!pUnoCrsr)
546 : {
547 0 : throw uno::RuntimeException();
548 : }
549 :
550 : // check for exceeding selections
551 31217 : if (!m_bFirstParagraph &&
552 20117 : ((CURSOR_SELECTION == m_eCursorType) ||
553 9057 : (CURSOR_SELECTION_IN_TABLE == m_eCursorType)))
554 : {
555 2942 : SwPosition* pStart = pUnoCrsr->Start();
556 2942 : auto aNewCrsr(pUnoCrsr->GetDoc()->CreateUnoCrsr(*pStart, false));
557 : // one may also go into tables here
558 5884 : if ((CURSOR_TBLTEXT != m_eCursorType) &&
559 2942 : (CURSOR_SELECTION_IN_TABLE != m_eCursorType))
560 : {
561 2003 : aNewCrsr->SetRemainInSection( false );
562 : }
563 :
564 : // os 2005-01-14: This part is only necessary to detect movements out
565 : // of a selection; if there is no selection we don't have to care
566 2942 : SwTableNode *const pTableNode = aNewCrsr->GetNode().FindTableNode();
567 5884 : if (((CURSOR_TBLTEXT != m_eCursorType) &&
568 4945 : (CURSOR_SELECTION_IN_TABLE != m_eCursorType)) && pTableNode)
569 : {
570 0 : aNewCrsr->GetPoint()->nNode = pTableNode->EndOfSectionIndex();
571 0 : aNewCrsr->Move(fnMoveForward, fnGoNode);
572 : }
573 : else
574 : {
575 2942 : aNewCrsr->MovePara(fnParaNext, fnParaStart);
576 : }
577 2942 : if (m_nEndIndex < aNewCrsr->Start()->nNode.GetIndex())
578 : {
579 215 : return 0;
580 2727 : }
581 : }
582 :
583 19942 : bool bInTable = false;
584 19942 : if (!m_bFirstParagraph)
585 : {
586 10845 : pUnoCrsr->SetRemainInSection( false );
587 : // what to do if already in a table?
588 10845 : SwTableNode * pTableNode = pUnoCrsr->GetNode().FindTableNode();
589 10845 : pTableNode = lcl_FindTopLevelTable( pTableNode, m_pOwnTable );
590 10845 : if (pTableNode && (&pTableNode->GetTable() != m_pOwnTable))
591 : {
592 : // this is a foreign table: go to end
593 109 : pUnoCrsr->GetPoint()->nNode = pTableNode->EndOfSectionIndex();
594 109 : if (!pUnoCrsr->Move(fnMoveForward, fnGoNode))
595 : {
596 1 : return 0;
597 : }
598 108 : bInTable = true;
599 : }
600 : }
601 :
602 19941 : uno::Reference< text::XTextContent > xRef;
603 : // the cursor must remain in the current section or a subsection
604 : // before AND after the movement...
605 33351 : if (lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ) &&
606 21580 : (m_bFirstParagraph || bInTable ||
607 18999 : (pUnoCrsr->MovePara(fnParaNext, fnParaStart) &&
608 8263 : lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ))))
609 : {
610 13410 : SwPosition* pStart = pUnoCrsr->Start();
611 : const sal_Int32 nFirstContent =
612 13410 : (m_bFirstParagraph) ? m_nFirstParaStart : -1;
613 : const sal_Int32 nLastContent =
614 13410 : (m_nEndIndex == pStart->nNode.GetIndex()) ? m_nLastParaEnd : -1;
615 :
616 : // position in a table, or in a simple paragraph?
617 13410 : SwTableNode * pTableNode = pUnoCrsr->GetNode().FindTableNode();
618 13410 : pTableNode = lcl_FindTopLevelTable( pTableNode, m_pOwnTable );
619 13410 : if (/*CURSOR_TBLTEXT != eCursorType && CURSOR_SELECTION_IN_TABLE != eCursorType && */
620 13410 : pTableNode && (&pTableNode->GetTable() != m_pOwnTable))
621 : {
622 : // this is a foreign table
623 : SwFrameFormat* pTableFormat =
624 320 : static_cast<SwFrameFormat*>(pTableNode->GetTable().GetFrameFormat());
625 320 : xRef = SwXTextTable::CreateXTextTable(pTableFormat);
626 : }
627 : else
628 : {
629 13090 : text::XText *const pText = m_xParentText.get();
630 39270 : xRef = SwXParagraph::CreateXParagraph(*pUnoCrsr->GetDoc(),
631 13090 : pStart->nNode.GetNode().GetTextNode(),
632 26180 : static_cast<SwXText*>(pText), nFirstContent, nLastContent);
633 : }
634 : }
635 :
636 19941 : return xRef;
637 : }
638 :
639 11062 : uno::Any SAL_CALL SwXParagraphEnumerationImpl::nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
640 : {
641 11062 : SolarMutexGuard aGuard;
642 11062 : if (m_bFirstParagraph)
643 : {
644 9097 : m_xNextPara = NextElement_Impl();
645 9097 : m_bFirstParagraph = false;
646 : }
647 22124 : const uno::Reference< text::XTextContent > xRef = m_xNextPara;
648 11062 : if (!xRef.is())
649 : {
650 2 : throw container::NoSuchElementException();
651 : }
652 11060 : m_xNextPara = NextElement_Impl();
653 :
654 11060 : uno::Any aRet;
655 11060 : aRet <<= xRef;
656 22122 : return aRet;
657 : }
658 :
659 : class SwXTextRange::Impl
660 : : public SwClient
661 : {
662 : public:
663 : const SfxItemPropertySet & m_rPropSet;
664 : const enum RangePosition m_eRangePosition;
665 : SwDoc & m_rDoc;
666 : uno::Reference<text::XText> m_xParentText;
667 : SwDepend m_ObjectDepend; // register at format of table or frame
668 : ::sw::mark::IMark * m_pMark;
669 :
670 105737 : Impl( SwDoc & rDoc, const enum RangePosition eRange,
671 : SwFrameFormat *const pTableFormat = 0,
672 : const uno::Reference< text::XText > & xParent = 0)
673 : : SwClient()
674 105737 : , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
675 : , m_eRangePosition(eRange)
676 : , m_rDoc(rDoc)
677 : , m_xParentText(xParent)
678 : , m_ObjectDepend(this, pTableFormat)
679 211474 : , m_pMark(0)
680 : {
681 105737 : }
682 :
683 211474 : virtual ~Impl()
684 211474 : {
685 : // Impl owns the bookmark; delete it here: SolarMutex is locked
686 105737 : Invalidate();
687 211474 : }
688 :
689 211679 : void Invalidate()
690 : {
691 211679 : if (m_pMark)
692 : {
693 101200 : m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark);
694 101200 : m_pMark = 0;
695 : }
696 211679 : }
697 :
698 65432 : const ::sw::mark::IMark * GetBookmark() const { return m_pMark; }
699 :
700 : protected:
701 : // SwClient
702 : virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
703 : };
704 :
705 106366 : void SwXTextRange::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
706 : {
707 106366 : const bool bAlreadyRegistered = 0 != GetRegisteredIn();
708 106366 : ClientModify(this, pOld, pNew);
709 106366 : if (m_ObjectDepend.GetRegisteredIn())
710 : {
711 1231 : ClientModify(&m_ObjectDepend, pOld, pNew);
712 : // if the depend was removed then the range must be removed too
713 1231 : if (!m_ObjectDepend.GetRegisteredIn() && GetRegisteredIn())
714 : {
715 0 : GetRegisteredIn()->Remove(this);
716 : }
717 : // or if the range has been removed but the depend is still
718 : // connected then the depend must be removed
719 1838 : else if (bAlreadyRegistered && !GetRegisteredIn() &&
720 607 : m_ObjectDepend.GetRegisteredIn())
721 : {
722 : m_ObjectDepend.GetRegisteredIn()
723 607 : ->Remove(& m_ObjectDepend);
724 : }
725 : }
726 106366 : if (!GetRegisteredIn())
727 : {
728 105742 : m_pMark = 0;
729 : }
730 106366 : }
731 :
732 105130 : SwXTextRange::SwXTextRange(SwPaM& rPam,
733 : const uno::Reference< text::XText > & xParent,
734 : const enum RangePosition eRange)
735 105130 : : m_pImpl( new SwXTextRange::Impl(*rPam.GetDoc(), eRange, 0, xParent) )
736 : {
737 105130 : SetPositions(rPam);
738 105130 : }
739 :
740 607 : SwXTextRange::SwXTextRange(SwFrameFormat& rTableFormat)
741 : : m_pImpl(
742 607 : new SwXTextRange::Impl(*rTableFormat.GetDoc(), RANGE_IS_TABLE, &rTableFormat) )
743 : {
744 607 : SwTable *const pTable = SwTable::FindTable( &rTableFormat );
745 607 : SwTableNode *const pTableNode = pTable->GetTableNode();
746 607 : SwPosition aPosition( *pTableNode );
747 1214 : SwPaM aPam( aPosition );
748 :
749 1214 : SetPositions( aPam );
750 607 : }
751 :
752 211474 : SwXTextRange::~SwXTextRange()
753 : {
754 211474 : }
755 :
756 0 : const SwDoc * SwXTextRange::GetDoc() const
757 : {
758 0 : return & m_pImpl->m_rDoc;
759 : }
760 :
761 52827 : SwDoc * SwXTextRange::GetDoc()
762 : {
763 52827 : return & m_pImpl->m_rDoc;
764 : }
765 :
766 200 : void SwXTextRange::Invalidate()
767 : {
768 200 : m_pImpl->Invalidate();
769 200 : }
770 :
771 105742 : void SwXTextRange::SetPositions(const SwPaM& rPam)
772 : {
773 105742 : m_pImpl->Invalidate();
774 105742 : IDocumentMarkAccess* const pMA = m_pImpl->m_rDoc.getIDocumentMarkAccess();
775 105742 : m_pImpl->m_pMark = pMA->makeMark(rPam, OUString(),
776 105742 : IDocumentMarkAccess::MarkType::UNO_BOOKMARK);
777 105742 : m_pImpl->m_pMark->Add(m_pImpl.get());
778 105742 : }
779 :
780 5 : void SwXTextRange::DeleteAndInsert(
781 : const OUString& rText, const bool bForceExpandHints)
782 : throw (uno::RuntimeException)
783 : {
784 5 : if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
785 : {
786 : // setString on table not allowed
787 0 : throw uno::RuntimeException();
788 : }
789 :
790 5 : const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
791 10 : SwCursor aCursor(aPos, 0, false);
792 5 : if (GetPositions(aCursor))
793 : {
794 5 : UnoActionContext aAction(& m_pImpl->m_rDoc);
795 5 : m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
796 5 : if (aCursor.HasMark())
797 : {
798 2 : m_pImpl->m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor);
799 : }
800 :
801 5 : if (!rText.isEmpty())
802 : {
803 : SwUnoCursorHelper::DocInsertStringSplitCR(
804 3 : m_pImpl->m_rDoc, aCursor, rText, bForceExpandHints);
805 :
806 3 : SwUnoCursorHelper::SelectPam(aCursor, true);
807 3 : aCursor.Left(rText.getLength(), CRSR_SKIP_CHARS, false, false);
808 : }
809 5 : SetPositions(aCursor);
810 5 : m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
811 5 : }
812 5 : }
813 :
814 : namespace
815 : {
816 : class theSwXTextRangeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangeUnoTunnelId > {};
817 : }
818 :
819 414849 : const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId()
820 : {
821 414849 : return theSwXTextRangeUnoTunnelId::get().getSeq();
822 : }
823 :
824 : // XUnoTunnel
825 : sal_Int64 SAL_CALL
826 233944 : SwXTextRange::getSomething(const uno::Sequence< sal_Int8 >& rId)
827 : throw (uno::RuntimeException, std::exception)
828 : {
829 233944 : return ::sw::UnoTunnelImpl<SwXTextRange>(rId, this);
830 : }
831 :
832 : OUString SAL_CALL
833 0 : SwXTextRange::getImplementationName() throw (uno::RuntimeException, std::exception)
834 : {
835 0 : return OUString("SwXTextRange");
836 : }
837 :
838 : static char const*const g_ServicesTextRange[] =
839 : {
840 : "com.sun.star.text.TextRange",
841 : "com.sun.star.style.CharacterProperties",
842 : "com.sun.star.style.CharacterPropertiesAsian",
843 : "com.sun.star.style.CharacterPropertiesComplex",
844 : "com.sun.star.style.ParagraphProperties",
845 : "com.sun.star.style.ParagraphPropertiesAsian",
846 : "com.sun.star.style.ParagraphPropertiesComplex",
847 : };
848 :
849 : static const size_t g_nServicesTextRange(
850 : sizeof(g_ServicesTextRange)/sizeof(g_ServicesTextRange[0]));
851 :
852 0 : sal_Bool SAL_CALL SwXTextRange::supportsService(const OUString& rServiceName)
853 : throw (uno::RuntimeException, std::exception)
854 : {
855 0 : return cppu::supportsService(this, rServiceName);
856 : }
857 :
858 : uno::Sequence< OUString > SAL_CALL
859 0 : SwXTextRange::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
860 : {
861 : return ::sw::GetSupportedServiceNamesImpl(
862 0 : g_nServicesTextRange, g_ServicesTextRange);
863 : }
864 :
865 : uno::Reference< text::XText > SAL_CALL
866 6182 : SwXTextRange::getText() throw (uno::RuntimeException, std::exception)
867 : {
868 6182 : SolarMutexGuard aGuard;
869 :
870 6182 : if (!m_pImpl->m_xParentText.is())
871 : {
872 0 : if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE &&
873 0 : m_pImpl->m_ObjectDepend.GetRegisteredIn())
874 : {
875 : SwFrameFormat const*const pTableFormat = static_cast<SwFrameFormat const*>(
876 0 : m_pImpl->m_ObjectDepend.GetRegisteredIn());
877 0 : SwTable const*const pTable = SwTable::FindTable( pTableFormat );
878 0 : SwTableNode const*const pTableNode = pTable->GetTableNode();
879 0 : const SwPosition aPosition( *pTableNode );
880 0 : m_pImpl->m_xParentText =
881 0 : ::sw::CreateParentXText(m_pImpl->m_rDoc, aPosition);
882 : }
883 : }
884 : OSL_ENSURE(m_pImpl->m_xParentText.is(), "SwXTextRange::getText: no text");
885 6182 : return m_pImpl->m_xParentText;
886 : }
887 :
888 : uno::Reference< text::XTextRange > SAL_CALL
889 862 : SwXTextRange::getStart() throw (uno::RuntimeException, std::exception)
890 : {
891 862 : SolarMutexGuard aGuard;
892 :
893 862 : uno::Reference< text::XTextRange > xRet;
894 862 : ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
895 862 : if (!m_pImpl->m_xParentText.is())
896 : {
897 0 : getText();
898 : }
899 862 : if(pBkmk)
900 : {
901 862 : SwPaM aPam(pBkmk->GetMarkStart());
902 862 : xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
903 : }
904 0 : else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
905 : {
906 : // start and end are this, if it's a table
907 0 : xRet = this;
908 : }
909 : else
910 : {
911 0 : throw uno::RuntimeException();
912 : }
913 862 : return xRet;
914 : }
915 :
916 : uno::Reference< text::XTextRange > SAL_CALL
917 2580 : SwXTextRange::getEnd() throw (uno::RuntimeException, std::exception)
918 : {
919 2580 : SolarMutexGuard aGuard;
920 :
921 2580 : uno::Reference< text::XTextRange > xRet;
922 2580 : ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
923 2580 : if (!m_pImpl->m_xParentText.is())
924 : {
925 0 : getText();
926 : }
927 2580 : if(pBkmk)
928 : {
929 2580 : SwPaM aPam(pBkmk->GetMarkEnd());
930 2580 : xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
931 : }
932 0 : else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
933 : {
934 : // start and end are this, if it's a table
935 0 : xRet = this;
936 : }
937 : else
938 : {
939 0 : throw uno::RuntimeException();
940 : }
941 2580 : return xRet;
942 : }
943 :
944 4846 : OUString SAL_CALL SwXTextRange::getString() throw (uno::RuntimeException, std::exception)
945 : {
946 4846 : SolarMutexGuard aGuard;
947 :
948 4846 : OUString sRet;
949 : // for tables there is no bookmark, thus also no text
950 : // one could export the table as ASCII here maybe?
951 9692 : SwPaM aPaM(GetDoc()->GetNodes());
952 4846 : if (GetPositions(aPaM) && aPaM.HasMark())
953 : {
954 4844 : SwUnoCursorHelper::GetTextFromPam(aPaM, sRet);
955 : }
956 9692 : return sRet;
957 : }
958 :
959 5 : void SAL_CALL SwXTextRange::setString(const OUString& rString)
960 : throw (uno::RuntimeException, std::exception)
961 : {
962 5 : SolarMutexGuard aGuard;
963 :
964 5 : DeleteAndInsert(rString, false);
965 5 : }
966 :
967 59529 : bool SwXTextRange::GetPositions(SwPaM& rToFill) const
968 : {
969 59529 : ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
970 59529 : if(pBkmk)
971 : {
972 59521 : *rToFill.GetPoint() = pBkmk->GetMarkPos();
973 59521 : if(pBkmk->IsExpanded())
974 : {
975 7004 : rToFill.SetMark();
976 7004 : *rToFill.GetMark() = pBkmk->GetOtherMarkPos();
977 : }
978 : else
979 : {
980 52517 : rToFill.DeleteMark();
981 : }
982 59521 : return true;
983 : }
984 8 : return false;
985 : }
986 :
987 : namespace sw {
988 :
989 63691 : bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
990 : const uno::Reference< text::XTextRange > & xTextRange)
991 : {
992 63691 : bool bRet = false;
993 :
994 63691 : uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
995 63691 : SwXTextRange* pRange = 0;
996 63691 : OTextCursorHelper* pCursor = 0;
997 63691 : SwXTextPortion* pPortion = 0;
998 63691 : SwXText* pText = 0;
999 63691 : SwXParagraph* pPara = 0;
1000 63691 : if(xRangeTunnel.is())
1001 : {
1002 63690 : pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
1003 : pCursor =
1004 63690 : ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
1005 : pPortion=
1006 63690 : ::sw::UnoTunnelGetImplementation<SwXTextPortion>(xRangeTunnel);
1007 63690 : pText = ::sw::UnoTunnelGetImplementation<SwXText>(xRangeTunnel);
1008 63690 : pPara = ::sw::UnoTunnelGetImplementation<SwXParagraph>(xRangeTunnel);
1009 : }
1010 :
1011 : // if it's a text then create a temporary cursor there and re-use
1012 : // the pCursor variable
1013 : // #i108489#: Reference in outside scope to keep cursor alive
1014 127382 : uno::Reference< text::XTextCursor > xTextCursor;
1015 63691 : if (pText)
1016 : {
1017 453 : xTextCursor.set( pText->CreateCursor() );
1018 453 : xTextCursor->gotoEnd(sal_True);
1019 : const uno::Reference<lang::XUnoTunnel> xCrsrTunnel(
1020 453 : xTextCursor, uno::UNO_QUERY);
1021 : pCursor =
1022 453 : ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCrsrTunnel);
1023 : }
1024 63691 : if(pRange && pRange->GetDoc() == rToFill.GetDoc())
1025 : {
1026 35649 : bRet = pRange->GetPositions(rToFill);
1027 : }
1028 : else
1029 : {
1030 28042 : if (pPara)
1031 : {
1032 2 : bRet = pPara->SelectPaM(rToFill);
1033 : }
1034 : else
1035 : {
1036 28039 : SwDoc* const pDoc = (pCursor) ? pCursor->GetDoc()
1037 56079 : : ((pPortion) ? pPortion->GetCursor()->GetDoc() : 0);
1038 28039 : const SwPaM* const pUnoCrsr = (pCursor) ? pCursor->GetPaM()
1039 56079 : : ((pPortion) ? pPortion->GetCursor() : 0);
1040 28040 : if (pUnoCrsr && pDoc == rToFill.GetDoc())
1041 : {
1042 : OSL_ENSURE(!pUnoCrsr->IsMultiSelection(),
1043 : "what to do about rings?");
1044 28039 : bRet = true;
1045 28039 : *rToFill.GetPoint() = *pUnoCrsr->GetPoint();
1046 28039 : if (pUnoCrsr->HasMark())
1047 : {
1048 10814 : rToFill.SetMark();
1049 10814 : *rToFill.GetMark() = *pUnoCrsr->GetMark();
1050 : }
1051 : else
1052 17225 : rToFill.DeleteMark();
1053 : }
1054 : }
1055 : }
1056 127382 : return bRet;
1057 : }
1058 :
1059 : static bool
1060 997 : lcl_IsStartNodeInFormat(const bool bHeader, SwStartNode *const pSttNode,
1061 : SwFrameFormat const*const pFrameFormat, SwFrameFormat*& rpFormat)
1062 : {
1063 997 : bool bRet = false;
1064 997 : const SfxItemSet& rSet = pFrameFormat->GetAttrSet();
1065 : const SfxPoolItem* pItem;
1066 997 : if (SfxItemState::SET == rSet.GetItemState(
1067 : static_cast<sal_uInt16>(bHeader ? RES_HEADER : RES_FOOTER),
1068 997 : true, &pItem))
1069 : {
1070 983 : SfxPoolItem *const pItemNonConst(const_cast<SfxPoolItem *>(pItem));
1071 : SwFrameFormat *const pHeadFootFormat = (bHeader) ?
1072 : static_cast<SwFormatHeader*>(pItemNonConst)->GetHeaderFormat() :
1073 983 : static_cast<SwFormatFooter*>(pItemNonConst)->GetFooterFormat();
1074 983 : if (pHeadFootFormat)
1075 : {
1076 499 : const SwFormatContent& rFlyContent = pHeadFootFormat->GetContent();
1077 499 : const SwNode& rNode = rFlyContent.GetContentIdx()->GetNode();
1078 : SwStartNode const*const pCurSttNode = rNode.FindSttNodeByType(
1079 499 : (bHeader) ? SwHeaderStartNode : SwFooterStartNode);
1080 499 : if (pCurSttNode && (pCurSttNode == pSttNode))
1081 : {
1082 175 : rpFormat = pHeadFootFormat;
1083 175 : bRet = true;
1084 : }
1085 : }
1086 : }
1087 997 : return bRet;
1088 : }
1089 :
1090 : } // namespace sw
1091 :
1092 : uno::Reference< text::XTextRange >
1093 6359 : SwXTextRange::CreateXTextRange(
1094 : SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark)
1095 : {
1096 : const uno::Reference<text::XText> xParentText(
1097 6359 : ::sw::CreateParentXText(rDoc, rPos));
1098 12718 : const auto pNewCrsr(rDoc.CreateUnoCrsr(rPos, false));
1099 6359 : if(pMark)
1100 : {
1101 5378 : pNewCrsr->SetMark();
1102 5378 : *pNewCrsr->GetMark() = *pMark;
1103 : }
1104 6359 : const bool isCell( dynamic_cast<SwXCell*>(xParentText.get()) );
1105 : const uno::Reference< text::XTextRange > xRet(
1106 6359 : new SwXTextRange(*pNewCrsr, xParentText,
1107 6359 : isCell ? RANGE_IN_CELL : RANGE_IN_TEXT) );
1108 12718 : return xRet;
1109 : }
1110 :
1111 : namespace sw {
1112 :
1113 : uno::Reference< text::XText >
1114 6497 : CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
1115 : {
1116 6497 : uno::Reference< text::XText > xParentText;
1117 6497 : SwStartNode* pSttNode = rPos.nNode.GetNode().StartOfSectionNode();
1118 13004 : while(pSttNode && pSttNode->IsSectionNode())
1119 : {
1120 10 : pSttNode = pSttNode->StartOfSectionNode();
1121 : }
1122 6497 : SwStartNodeType eType = pSttNode ? pSttNode->GetStartNodeType() : SwNormalStartNode;
1123 6497 : switch(eType)
1124 : {
1125 : case SwTableBoxStartNode:
1126 : {
1127 857 : SwTableNode const*const pTableNode = pSttNode->FindTableNode();
1128 : SwFrameFormat *const pTableFormat =
1129 857 : static_cast<SwFrameFormat*>(pTableNode->GetTable().GetFrameFormat());
1130 857 : SwTableBox *const pBox = pSttNode->GetTableBox();
1131 :
1132 857 : xParentText = (pBox)
1133 : ? SwXCell::CreateXCell( pTableFormat, pBox )
1134 857 : : new SwXCell( pTableFormat, *pSttNode );
1135 : }
1136 857 : break;
1137 : case SwFlyStartNode:
1138 : {
1139 101 : SwFrameFormat *const pFormat = pSttNode->GetFlyFormat();
1140 101 : if (0 != pFormat)
1141 : {
1142 : xParentText.set(SwXTextFrame::CreateXTextFrame(rDoc, pFormat),
1143 101 : uno::UNO_QUERY);
1144 : }
1145 : }
1146 101 : break;
1147 : case SwHeaderStartNode:
1148 : case SwFooterStartNode:
1149 : {
1150 175 : const bool bHeader = (SwHeaderStartNode == eType);
1151 175 : const size_t nPDescCount = rDoc.GetPageDescCnt();
1152 751 : for(size_t i = 0; i < nPDescCount; i++)
1153 : {
1154 576 : const SwPageDesc& rDesc = rDoc.GetPageDesc( i );
1155 576 : const SwFrameFormat* pFrameFormatMaster = &rDesc.GetMaster();
1156 576 : const SwFrameFormat* pFrameFormatLeft = &rDesc.GetLeft();
1157 :
1158 576 : SwFrameFormat* pHeadFootFormat = 0;
1159 576 : if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrameFormatMaster,
1160 576 : pHeadFootFormat))
1161 : {
1162 : lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrameFormatLeft,
1163 421 : pHeadFootFormat);
1164 : }
1165 :
1166 576 : if (pHeadFootFormat)
1167 : {
1168 350 : xParentText = SwXHeadFootText::CreateXHeadFootText(
1169 175 : *pHeadFootFormat, bHeader);
1170 : }
1171 : }
1172 : }
1173 175 : break;
1174 : case SwFootnoteStartNode:
1175 : {
1176 6 : const size_t nFootnoteCnt = rDoc.GetFootnoteIdxs().size();
1177 6 : uno::Reference< text::XFootnote > xRef;
1178 9 : for (size_t n = 0; n < nFootnoteCnt; ++n )
1179 : {
1180 9 : const SwTextFootnote* pTextFootnote = rDoc.GetFootnoteIdxs()[ n ];
1181 9 : const SwFormatFootnote& rFootnote = pTextFootnote->GetFootnote();
1182 9 : pTextFootnote = rFootnote.GetTextFootnote();
1183 : #if OSL_DEBUG_LEVEL > 1
1184 : const SwStartNode* pTmpSttNode =
1185 : pTextFootnote->GetStartNode()->GetNode().
1186 : FindSttNodeByType(SwFootnoteStartNode);
1187 : (void)pTmpSttNode;
1188 : #endif
1189 :
1190 18 : if (pSttNode == pTextFootnote->GetStartNode()->GetNode().
1191 9 : FindSttNodeByType(SwFootnoteStartNode))
1192 : {
1193 : xParentText.set(SwXFootnote::CreateXFootnote(rDoc,
1194 6 : &const_cast<SwFormatFootnote&>(rFootnote)), uno::UNO_QUERY);
1195 6 : break;
1196 : }
1197 6 : }
1198 : }
1199 6 : break;
1200 : default:
1201 : {
1202 : // then it is the body text
1203 : const uno::Reference<frame::XModel> xModel =
1204 5358 : rDoc.GetDocShell()->GetBaseModel();
1205 : const uno::Reference< text::XTextDocument > xDoc(
1206 10716 : xModel, uno::UNO_QUERY);
1207 10716 : xParentText = xDoc->getText();
1208 : }
1209 : }
1210 : OSL_ENSURE(xParentText.is(), "no parent text?");
1211 6497 : return xParentText;
1212 : }
1213 :
1214 : } // namespace sw
1215 :
1216 : uno::Reference< container::XEnumeration > SAL_CALL
1217 0 : SwXTextRange::createContentEnumeration(const OUString& rServiceName)
1218 : throw (uno::RuntimeException, std::exception)
1219 : {
1220 0 : SolarMutexGuard g;
1221 :
1222 0 : if ( rServiceName != "com.sun.star.text.TextContent" )
1223 : {
1224 0 : throw uno::RuntimeException();
1225 : }
1226 :
1227 0 : if (!GetDoc() || !m_pImpl->GetBookmark())
1228 : {
1229 0 : throw uno::RuntimeException();
1230 : }
1231 0 : const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
1232 0 : const auto pNewCrsr(m_pImpl->m_rDoc.CreateUnoCrsr(aPos, false));
1233 0 : if (!GetPositions(*pNewCrsr))
1234 : {
1235 0 : throw uno::RuntimeException();
1236 : }
1237 :
1238 0 : return SwXParaFrameEnumeration::Create(*pNewCrsr, PARAFRAME_PORTION_TEXTRANGE);
1239 : }
1240 :
1241 : uno::Reference< container::XEnumeration > SAL_CALL
1242 1 : SwXTextRange::createEnumeration() throw (uno::RuntimeException, std::exception)
1243 : {
1244 1 : SolarMutexGuard g;
1245 :
1246 1 : if (!GetDoc() || !m_pImpl->GetBookmark())
1247 : {
1248 0 : throw uno::RuntimeException();
1249 : }
1250 2 : const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
1251 2 : auto pNewCrsr(m_pImpl->m_rDoc.CreateUnoCrsr(aPos, false));
1252 1 : if (!GetPositions(*pNewCrsr))
1253 : {
1254 0 : throw uno::RuntimeException();
1255 : }
1256 1 : if (!m_pImpl->m_xParentText.is())
1257 : {
1258 0 : getText();
1259 : }
1260 :
1261 1 : const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition)
1262 1 : ? CURSOR_SELECTION_IN_TABLE : CURSOR_SELECTION;
1263 2 : return SwXParagraphEnumeration::Create(m_pImpl->m_xParentText, pNewCrsr, eSetType);
1264 : }
1265 :
1266 0 : uno::Type SAL_CALL SwXTextRange::getElementType() throw (uno::RuntimeException, std::exception)
1267 : {
1268 0 : return cppu::UnoType<text::XTextRange>::get();
1269 : }
1270 :
1271 0 : sal_Bool SAL_CALL SwXTextRange::hasElements() throw (uno::RuntimeException, std::exception)
1272 : {
1273 0 : return sal_True;
1274 : }
1275 :
1276 : uno::Sequence< OUString > SAL_CALL
1277 0 : SwXTextRange::getAvailableServiceNames() throw (uno::RuntimeException, std::exception)
1278 : {
1279 0 : uno::Sequence< OUString > aRet(1);
1280 0 : OUString* pArray = aRet.getArray();
1281 0 : pArray[0] = "com.sun.star.text.TextContent";
1282 0 : return aRet;
1283 : }
1284 :
1285 : uno::Reference< beans::XPropertySetInfo > SAL_CALL
1286 277 : SwXTextRange::getPropertySetInfo() throw (uno::RuntimeException, std::exception)
1287 : {
1288 277 : SolarMutexGuard aGuard;
1289 :
1290 : static uno::Reference< beans::XPropertySetInfo > xRef =
1291 277 : m_pImpl->m_rPropSet.getPropertySetInfo();
1292 277 : return xRef;
1293 : }
1294 :
1295 : void SAL_CALL
1296 434 : SwXTextRange::setPropertyValue(
1297 : const OUString& rPropertyName, const uno::Any& rValue)
1298 : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
1299 : lang::IllegalArgumentException, lang::WrappedTargetException,
1300 : uno::RuntimeException, std::exception)
1301 : {
1302 434 : SolarMutexGuard aGuard;
1303 :
1304 434 : if (!GetDoc() || !m_pImpl->GetBookmark())
1305 : {
1306 0 : throw uno::RuntimeException();
1307 : }
1308 868 : SwPaM aPaM(GetDoc()->GetNodes());
1309 434 : GetPositions(aPaM);
1310 434 : SwUnoCursorHelper::SetPropertyValue(aPaM, m_pImpl->m_rPropSet,
1311 868 : rPropertyName, rValue);
1312 434 : }
1313 :
1314 : uno::Any SAL_CALL
1315 433 : SwXTextRange::getPropertyValue(const OUString& rPropertyName)
1316 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1317 : uno::RuntimeException, std::exception)
1318 : {
1319 433 : SolarMutexGuard aGuard;
1320 :
1321 433 : if (!GetDoc() || !m_pImpl->GetBookmark())
1322 : {
1323 0 : throw uno::RuntimeException();
1324 : }
1325 864 : SwPaM aPaM(GetDoc()->GetNodes());
1326 433 : GetPositions(aPaM);
1327 433 : return SwUnoCursorHelper::GetPropertyValue(aPaM, m_pImpl->m_rPropSet,
1328 866 : rPropertyName);
1329 : }
1330 :
1331 : void SAL_CALL
1332 0 : SwXTextRange::addPropertyChangeListener(
1333 : const OUString& /*rPropertyName*/,
1334 : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1335 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1336 : uno::RuntimeException, std::exception)
1337 : {
1338 : OSL_FAIL("SwXTextRange::addPropertyChangeListener(): not implemented");
1339 0 : }
1340 :
1341 : void SAL_CALL
1342 0 : SwXTextRange::removePropertyChangeListener(
1343 : const OUString& /*rPropertyName*/,
1344 : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1345 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1346 : uno::RuntimeException, std::exception)
1347 : {
1348 : OSL_FAIL("SwXTextRange::removePropertyChangeListener(): not implemented");
1349 0 : }
1350 :
1351 : void SAL_CALL
1352 0 : SwXTextRange::addVetoableChangeListener(
1353 : const OUString& /*rPropertyName*/,
1354 : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1355 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1356 : uno::RuntimeException, std::exception)
1357 : {
1358 : OSL_FAIL("SwXTextRange::addVetoableChangeListener(): not implemented");
1359 0 : }
1360 :
1361 : void SAL_CALL
1362 0 : SwXTextRange::removeVetoableChangeListener(
1363 : const OUString& /*rPropertyName*/,
1364 : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1365 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1366 : uno::RuntimeException, std::exception)
1367 : {
1368 : OSL_FAIL("SwXTextRange::removeVetoableChangeListener(): not implemented");
1369 0 : }
1370 :
1371 : beans::PropertyState SAL_CALL
1372 0 : SwXTextRange::getPropertyState(const OUString& rPropertyName)
1373 : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
1374 : {
1375 0 : SolarMutexGuard aGuard;
1376 :
1377 0 : if (!GetDoc() || !m_pImpl->GetBookmark())
1378 : {
1379 0 : throw uno::RuntimeException();
1380 : }
1381 0 : SwPaM aPaM(GetDoc()->GetNodes());
1382 0 : GetPositions(aPaM);
1383 0 : return SwUnoCursorHelper::GetPropertyState(aPaM, m_pImpl->m_rPropSet,
1384 0 : rPropertyName);
1385 : }
1386 :
1387 : uno::Sequence< beans::PropertyState > SAL_CALL
1388 263 : SwXTextRange::getPropertyStates(const uno::Sequence< OUString >& rPropertyName)
1389 : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
1390 : {
1391 263 : SolarMutexGuard g;
1392 :
1393 263 : if (!GetDoc() || !m_pImpl->GetBookmark())
1394 : {
1395 0 : throw uno::RuntimeException();
1396 : }
1397 526 : SwPaM aPaM(GetDoc()->GetNodes());
1398 263 : GetPositions(aPaM);
1399 263 : return SwUnoCursorHelper::GetPropertyStates(aPaM, m_pImpl->m_rPropSet,
1400 526 : rPropertyName);
1401 : }
1402 :
1403 0 : void SAL_CALL SwXTextRange::setPropertyToDefault(const OUString& rPropertyName)
1404 : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
1405 : {
1406 0 : SolarMutexGuard aGuard;
1407 :
1408 0 : if (!GetDoc() || !m_pImpl->GetBookmark())
1409 : {
1410 0 : throw uno::RuntimeException();
1411 : }
1412 0 : SwPaM aPaM(GetDoc()->GetNodes());
1413 0 : GetPositions(aPaM);
1414 0 : SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_pImpl->m_rPropSet,
1415 0 : rPropertyName);
1416 0 : }
1417 :
1418 : uno::Any SAL_CALL
1419 0 : SwXTextRange::getPropertyDefault(const OUString& rPropertyName)
1420 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1421 : uno::RuntimeException, std::exception)
1422 : {
1423 0 : SolarMutexGuard aGuard;
1424 :
1425 0 : if (!GetDoc() || !m_pImpl->GetBookmark())
1426 : {
1427 0 : throw uno::RuntimeException();
1428 : }
1429 0 : SwPaM aPaM(GetDoc()->GetNodes());
1430 0 : GetPositions(aPaM);
1431 0 : return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_pImpl->m_rPropSet,
1432 0 : rPropertyName);
1433 : }
1434 :
1435 : void SAL_CALL
1436 1330 : SwXTextRange::makeRedline(
1437 : const OUString& rRedlineType,
1438 : const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
1439 : throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
1440 : {
1441 1330 : SolarMutexGuard aGuard;
1442 :
1443 1330 : if (!GetDoc() || !m_pImpl->GetBookmark())
1444 : {
1445 0 : throw uno::RuntimeException();
1446 : }
1447 2658 : SwPaM aPaM(GetDoc()->GetNodes());
1448 1330 : SwXTextRange::GetPositions(aPaM);
1449 2660 : SwUnoCursorHelper::makeRedline( aPaM, rRedlineType, rRedlineProperties );
1450 1328 : }
1451 :
1452 2 : struct SwXTextRangesImpl SAL_FINAL : public SwXTextRanges
1453 : {
1454 :
1455 : // XUnoTunnel
1456 : virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1457 :
1458 : // XServiceInfo
1459 0 : virtual OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
1460 0 : { return OUString("SwXTextRanges"); };
1461 0 : virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
1462 0 : { return cppu::supportsService(this, rServiceName); };
1463 0 : virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
1464 0 : { return { "com.sun.star.text.TextRanges" }; };
1465 :
1466 : // XElementAccess
1467 0 : virtual ::com::sun::star::uno::Type SAL_CALL getElementType() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
1468 0 : { return cppu::UnoType<text::XTextRange>::get(); };
1469 0 : virtual sal_Bool SAL_CALL hasElements() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
1470 0 : { return getCount() > 0; };
1471 : // XIndexAccess
1472 : virtual sal_Int32 SAL_CALL getCount() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1473 : virtual ::com::sun::star::uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1474 :
1475 1 : SwXTextRangesImpl(SwPaM *const pPaM)
1476 1 : {
1477 1 : if (pPaM)
1478 : {
1479 1 : m_pUnoCursor.reset(pPaM->GetDoc()->CreateUnoCrsr(*pPaM->GetPoint()));
1480 1 : ::sw::DeepCopyPaM(*pPaM, *GetCursor());
1481 : }
1482 1 : MakeRanges();
1483 1 : }
1484 11 : virtual void SAL_CALL release() throw () SAL_OVERRIDE
1485 : {
1486 11 : SolarMutexGuard g;
1487 11 : OWeakObject::release();
1488 11 : }
1489 3 : virtual SwUnoCrsr* GetCursor() SAL_OVERRIDE
1490 3 : { return &(*m_pUnoCursor); };
1491 : void MakeRanges();
1492 : ::std::vector< uno::Reference< text::XTextRange > > m_Ranges;
1493 : sw::UnoCursorPointer m_pUnoCursor;
1494 : };
1495 :
1496 1 : void SwXTextRangesImpl::MakeRanges()
1497 : {
1498 1 : if (GetCursor())
1499 : {
1500 2 : for(SwPaM& rTmpCursor : GetCursor()->GetRingContainer())
1501 : {
1502 : const uno::Reference< text::XTextRange > xRange(
1503 : SwXTextRange::CreateXTextRange(
1504 1 : *rTmpCursor.GetDoc(),
1505 2 : *rTmpCursor.GetPoint(), rTmpCursor.GetMark()));
1506 1 : if (xRange.is())
1507 : {
1508 1 : m_Ranges.push_back(xRange);
1509 : }
1510 1 : }
1511 : }
1512 1 : }
1513 :
1514 1 : SwXTextRanges* SwXTextRanges::Create(SwPaM *const pPaM)
1515 1 : { return new SwXTextRangesImpl(pPaM); }
1516 :
1517 : namespace
1518 : {
1519 : class theSwXTextRangesUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangesUnoTunnelId > {};
1520 : }
1521 :
1522 8 : const uno::Sequence< sal_Int8 > & SwXTextRanges::getUnoTunnelId()
1523 8 : { return theSwXTextRangesUnoTunnelId::get().getSeq(); }
1524 :
1525 : sal_Int64 SAL_CALL
1526 0 : SwXTextRangesImpl::getSomething(const uno::Sequence< sal_Int8 >& rId)
1527 : throw (uno::RuntimeException, std::exception)
1528 : {
1529 0 : return ::sw::UnoTunnelImpl<SwXTextRanges>(rId, this);
1530 : }
1531 :
1532 : /*
1533 : * Text positions
1534 : * Up to the first access to a text position, only a SwCursor is stored.
1535 : * Afterwards, an array with uno::Reference<XTextPosition> will be created.
1536 : */
1537 :
1538 2 : sal_Int32 SAL_CALL SwXTextRangesImpl::getCount()
1539 : throw (uno::RuntimeException, std::exception)
1540 : {
1541 2 : SolarMutexGuard aGuard;
1542 2 : return static_cast<sal_Int32>(m_Ranges.size());
1543 : }
1544 :
1545 1 : uno::Any SAL_CALL SwXTextRangesImpl::getByIndex(sal_Int32 nIndex) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
1546 : {
1547 1 : SolarMutexGuard aGuard;
1548 1 : if ((nIndex < 0) || (static_cast<size_t>(nIndex) >= m_Ranges.size()))
1549 0 : throw lang::IndexOutOfBoundsException();
1550 1 : uno::Any ret;
1551 1 : ret <<= (m_Ranges.at(nIndex));
1552 1 : return ret;
1553 : }
1554 :
1555 9 : void SwUnoCursorHelper::SetString(SwCursor & rCursor, const OUString& rString)
1556 : {
1557 : // Start/EndAction
1558 9 : SwDoc *const pDoc = rCursor.GetDoc();
1559 9 : UnoActionContext aAction(pDoc);
1560 9 : pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
1561 9 : if (rCursor.HasMark())
1562 : {
1563 8 : pDoc->getIDocumentContentOperations().DeleteAndJoin(rCursor);
1564 : }
1565 9 : if (!rString.isEmpty())
1566 : {
1567 : const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR(
1568 8 : *pDoc, rCursor, rString, false ) );
1569 : OSL_ENSURE( bSuccess, "DocInsertStringSplitCR" );
1570 : (void) bSuccess;
1571 8 : SwUnoCursorHelper::SelectPam(rCursor, true);
1572 8 : rCursor.Left(rString.getLength(), CRSR_SKIP_CHARS, false, false);
1573 : }
1574 9 : pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
1575 9 : }
1576 :
1577 2302 : struct SwXParaFrameEnumerationImpl SAL_FINAL : public SwXParaFrameEnumeration
1578 : {
1579 : // XServiceInfo
1580 0 : virtual OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
1581 0 : { return OUString("SwXParaFrameEnumeration"); };
1582 0 : virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
1583 0 : { return cppu::supportsService(this, rServiceName); };
1584 0 : virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
1585 0 : { return {"com.sun.star.util.ContentEnumeration"}; };
1586 :
1587 : // XEnumeration
1588 : virtual sal_Bool SAL_CALL hasMoreElements() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1589 : virtual ::com::sun::star::uno::Any SAL_CALL nextElement() throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1590 :
1591 : SwXParaFrameEnumerationImpl(const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode, SwFrameFormat* const pFormat = nullptr);
1592 2368 : virtual void SAL_CALL release() throw () SAL_OVERRIDE
1593 : {
1594 2368 : SolarMutexGuard g;
1595 2368 : OWeakObject::release();
1596 2368 : }
1597 1742 : SwUnoCrsr* GetCursor()
1598 1742 : { return &(*m_pUnoCursor); }
1599 1420 : void PurgeFrameClients()
1600 : {
1601 1420 : if(!m_pUnoCursor)
1602 : {
1603 0 : m_vFrames.clear();
1604 0 : m_xNextObject = nullptr;
1605 : }
1606 : else
1607 : {
1608 : // removing orphaned SwDepends
1609 : const auto iter = std::remove_if(m_vFrames.begin(), m_vFrames.end(),
1610 2218 : [] (std::shared_ptr<sw::FrameClient>& rEntry) -> bool { return !rEntry->GetRegisteredIn(); });
1611 1420 : m_vFrames.erase(iter, m_vFrames.end());
1612 : }
1613 1420 : }
1614 : void FillFrame();
1615 : bool CreateNextObject();
1616 : uno::Reference< text::XTextContent > m_xNextObject;
1617 : FrameClientList_t m_vFrames;
1618 : ::sw::UnoCursorPointer m_pUnoCursor;
1619 : };
1620 :
1621 :
1622 :
1623 1151 : SwXParaFrameEnumeration* SwXParaFrameEnumeration::Create(const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode, SwFrameFormat* const pFormat)
1624 1151 : { return new SwXParaFrameEnumerationImpl(rPaM, eParaFrameMode, pFormat); }
1625 :
1626 1151 : SwXParaFrameEnumerationImpl::SwXParaFrameEnumerationImpl(
1627 : const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode,
1628 : SwFrameFormat* const pFormat)
1629 1151 : : m_pUnoCursor(rPaM.GetDoc()->CreateUnoCrsr(*rPaM.GetPoint(), false))
1630 : {
1631 1151 : if (rPaM.HasMark())
1632 : {
1633 161 : GetCursor()->SetMark();
1634 161 : *GetCursor()->GetMark() = *rPaM.GetMark();
1635 : }
1636 1151 : if (PARAFRAME_PORTION_PARAGRAPH == eParaFrameMode)
1637 : {
1638 990 : FrameClientSortList_t vFrames;
1639 990 : ::CollectFrameAtNode(rPaM.GetPoint()->nNode, vFrames, false);
1640 : ::std::transform(vFrames.begin(), vFrames.end(),
1641 : ::std::back_inserter(m_vFrames),
1642 1067 : [] (const FrameClientSortListEntry& rEntry) { return rEntry.pFrameClient; });
1643 : }
1644 161 : else if (pFormat)
1645 : {
1646 25 : m_vFrames.push_back(std::shared_ptr<sw::FrameClient>(new sw::FrameClient(pFormat)));
1647 : }
1648 136 : else if ((PARAFRAME_PORTION_CHAR == eParaFrameMode) ||
1649 : (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode))
1650 : {
1651 136 : if (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode)
1652 : {
1653 : //get all frames that are bound at paragraph or at character
1654 0 : for(const auto& pFlyFrm : rPaM.GetDoc()->GetAllFlyFormats(GetCursor(), false, true))
1655 : {
1656 0 : const auto pFrameFormat = const_cast<SwFrameFormat*>(&pFlyFrm->GetFormat());
1657 0 : m_vFrames.push_back(std::shared_ptr<sw::FrameClient>(new sw::FrameClient(pFrameFormat)));
1658 0 : }
1659 : }
1660 136 : FillFrame();
1661 : }
1662 1151 : }
1663 :
1664 : // Search for a FLYCNT text attribute at the cursor point and fill the frame
1665 : // into the array
1666 136 : void SwXParaFrameEnumerationImpl::FillFrame()
1667 : {
1668 136 : if(!m_pUnoCursor->GetNode().IsTextNode())
1669 0 : return;
1670 : // search for objects at the cursor - anchored at/as char
1671 136 : const auto pTextAttr = m_pUnoCursor->GetNode().GetTextNode()->GetTextAttrForCharAt(
1672 272 : m_pUnoCursor->GetPoint()->nContent.GetIndex(), RES_TXTATR_FLYCNT);
1673 136 : if(!pTextAttr)
1674 0 : return;
1675 136 : const SwFormatFlyCnt& rFlyCnt = pTextAttr->GetFlyCnt();
1676 136 : SwFrameFormat* const pFrameFormat = rFlyCnt.GetFrameFormat();
1677 136 : m_vFrames.push_back(std::shared_ptr<sw::FrameClient>(new sw::FrameClient(pFrameFormat)));
1678 : }
1679 :
1680 1274 : bool SwXParaFrameEnumerationImpl::CreateNextObject()
1681 : {
1682 1274 : if (!m_vFrames.size())
1683 1036 : return false;
1684 :
1685 : SwFrameFormat* const pFormat = static_cast<SwFrameFormat*>(
1686 238 : m_vFrames.front()->GetRegisteredIn());
1687 238 : m_vFrames.pop_front();
1688 : // the format should be valid here, otherwise the client
1689 : // would have been removed by PurgeFrameClients
1690 : // check for a shape first
1691 238 : SwDrawContact* const pContact = SwIterator<SwDrawContact,SwFormat>( *pFormat ).First();
1692 238 : if (pContact)
1693 : {
1694 19 : SdrObject* const pSdr = pContact->GetMaster();
1695 19 : if (pSdr)
1696 19 : m_xNextObject.set(pSdr->getUnoShape(), uno::UNO_QUERY);
1697 : }
1698 : else
1699 : {
1700 219 : const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx();
1701 : OSL_ENSURE(pIdx, "where is the index?");
1702 : SwNode const*const pNd =
1703 219 : m_pUnoCursor->GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ];
1704 :
1705 219 : if (!pNd->IsNoTextNode())
1706 : {
1707 : m_xNextObject.set(SwXTextFrame::CreateXTextFrame(
1708 89 : *pFormat->GetDoc(), pFormat));
1709 : }
1710 130 : else if (pNd->IsGrfNode())
1711 : {
1712 : m_xNextObject.set(SwXTextGraphicObject::CreateXTextGraphicObject(
1713 6 : *pFormat->GetDoc(), pFormat));
1714 : }
1715 : else
1716 : {
1717 : assert(pNd->IsOLENode());
1718 : m_xNextObject.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
1719 124 : *pFormat->GetDoc(), pFormat));
1720 : }
1721 : }
1722 238 : return m_xNextObject.is();
1723 : }
1724 :
1725 : sal_Bool SAL_CALL
1726 1182 : SwXParaFrameEnumerationImpl::hasMoreElements() throw (uno::RuntimeException, std::exception)
1727 : {
1728 1182 : SolarMutexGuard aGuard;
1729 1182 : if (!GetCursor())
1730 0 : throw uno::RuntimeException();
1731 1182 : PurgeFrameClients();
1732 1182 : return m_xNextObject.is() || CreateNextObject();
1733 : }
1734 :
1735 238 : uno::Any SAL_CALL SwXParaFrameEnumerationImpl::nextElement()
1736 : throw (container::NoSuchElementException,
1737 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
1738 : {
1739 238 : SolarMutexGuard aGuard;
1740 238 : if (!GetCursor())
1741 0 : throw uno::RuntimeException();
1742 238 : PurgeFrameClients();
1743 238 : if (!m_xNextObject.is() && m_vFrames.size())
1744 115 : CreateNextObject();
1745 238 : if (!m_xNextObject.is())
1746 0 : throw container::NoSuchElementException();
1747 238 : uno::Any aRet;
1748 238 : aRet <<= m_xNextObject;
1749 238 : m_xNextObject = nullptr;
1750 238 : return aRet;
1751 177 : }
1752 :
1753 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|