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 <switerator.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 810 : GetSupportedServiceNamesImpl(
123 : size_t const nServices, char const*const pServices[])
124 : {
125 810 : uno::Sequence< OUString > ret(nServices);
126 6532 : for (size_t i = 0; i < nServices; ++i)
127 : {
128 5722 : ret[i] = OUString::createFromAscii(pServices[i]);
129 : }
130 810 : return ret;
131 : }
132 :
133 : } // namespace sw
134 :
135 : namespace sw {
136 :
137 8 : void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget)
138 : {
139 8 : rTarget = rSource;
140 :
141 8 : if (rSource.GetNext() != &rSource)
142 : {
143 4 : SwPaM *pPam = static_cast<SwPaM *>(rSource.GetNext());
144 70 : do
145 : {
146 : // create new PaM
147 70 : SwPaM *const pNew = new SwPaM(*pPam);
148 : // insert into ring
149 70 : pNew->MoveTo(&rTarget);
150 70 : pPam = static_cast<SwPaM *>(pPam->GetNext());
151 : }
152 : while (pPam != &rSource);
153 : }
154 8 : }
155 :
156 : } // namespace sw
157 :
158 : struct FrameDependSortListLess
159 : {
160 0 : bool operator() (FrameDependSortListEntry const& r1,
161 : FrameDependSortListEntry 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 : // OD 2004-05-07 #i28701# - adjust 4th parameter
169 1996 : void CollectFrameAtNode( SwClient& rClnt, const SwNodeIndex& rIdx,
170 : FrameDependSortList_t & rFrames,
171 : const bool _bAtCharAnchoredObjs )
172 : {
173 : // _bAtCharAnchoredObjs:
174 : // <sal_True>: at-character anchored objects are collected
175 : // <sal_False>: at-paragraph anchored objects are collected
176 :
177 : // search all borders, images, and OLEs that are connected to the paragraph
178 1996 : SwDoc* pDoc = rIdx.GetNode().GetDoc();
179 :
180 : const sal_uInt16 nChkType = static_cast< sal_uInt16 >((_bAtCharAnchoredObjs)
181 1996 : ? FLY_AT_CHAR : FLY_AT_PARA);
182 : const SwCntntFrm* pCFrm;
183 : const SwCntntNode* pCNd;
184 5972 : if( pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() &&
185 3976 : 0 != (pCNd = rIdx.GetNode().GetCntntNode()) &&
186 1980 : 0 != (pCFrm = pCNd->getLayoutFrm( pDoc->getIDocumentLayoutAccess().GetCurrentLayout())) )
187 : {
188 1980 : const SwSortedObjs *pObjs = pCFrm->GetDrawObjs();
189 1980 : if( pObjs )
190 : {
191 358 : std::set<const SwFrmFmt*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
192 1250 : for( size_t i = 0; i < pObjs->size(); ++i )
193 : {
194 892 : SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
195 892 : SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
196 :
197 : // Filter out textboxes, which are not interesting at an UNO level.
198 892 : if (aTextBoxes.find(&rFmt) != aTextBoxes.end())
199 6 : continue;
200 :
201 886 : if ( rFmt.GetAnchor().GetAnchorId() == nChkType )
202 : {
203 : // create SwDepend and insert into array
204 108 : SwDepend* pNewDepend = new SwDepend( &rClnt, &rFmt );
205 : const sal_Int32 idx =
206 108 : rFmt.GetAnchor().GetCntntAnchor()->nContent.GetIndex();
207 108 : sal_uInt32 nOrder = rFmt.GetAnchor().GetOrder();
208 :
209 : // OD 2004-05-07 #i28701# - sorting no longer needed,
210 : // because list <SwSortedObjs> is already sorted.
211 108 : FrameDependSortListEntry entry(idx, nOrder, pNewDepend);
212 108 : rFrames.push_back(entry);
213 : }
214 358 : }
215 : }
216 : }
217 : else
218 : {
219 16 : const SwFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
220 16 : const size_t nSize = rFmts.size();
221 16 : for ( size_t i = 0; i < nSize; i++)
222 : {
223 0 : const SwFrmFmt* pFmt = rFmts[ i ];
224 0 : const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
225 : const SwPosition* pAnchorPos;
226 0 : if( rAnchor.GetAnchorId() == nChkType &&
227 0 : 0 != (pAnchorPos = rAnchor.GetCntntAnchor()) &&
228 0 : pAnchorPos->nNode == rIdx )
229 : {
230 0 : SwDepend* pNewDepend = new SwDepend( &rClnt, (SwFrmFmt*)pFmt);
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 : FrameDependSortListEntry entry(nIndex, nOrder, pNewDepend);
238 0 : rFrames.push_back(entry);
239 : }
240 : }
241 16 : ::std::sort(rFrames.begin(), rFrames.end(), FrameDependSortListLess());
242 : }
243 1996 : }
244 :
245 313140 : UnoActionContext::UnoActionContext(SwDoc *const pDoc)
246 313140 : : m_pDoc(pDoc)
247 : {
248 313140 : SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
249 313140 : if (pRootFrm)
250 : {
251 42702 : pRootFrm->StartAllAction();
252 : }
253 313140 : }
254 :
255 313140 : UnoActionContext::~UnoActionContext()
256 : {
257 : // Doc may already have been removed here
258 313140 : if (m_pDoc)
259 : {
260 313140 : SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
261 313140 : if (pRootFrm)
262 : {
263 42702 : pRootFrm->EndAllAction();
264 : }
265 : }
266 313140 : }
267 :
268 466 : UnoActionRemoveContext::UnoActionRemoveContext(SwDoc *const pDoc)
269 466 : : m_pDoc(pDoc)
270 : {
271 466 : SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
272 466 : if (pRootFrm)
273 : {
274 344 : pRootFrm->UnoRemoveAllActions();
275 : }
276 466 : }
277 :
278 466 : UnoActionRemoveContext::~UnoActionRemoveContext()
279 : {
280 466 : SwRootFrm *const pRootFrm = m_pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
281 466 : if (pRootFrm)
282 : {
283 344 : pRootFrm->UnoRestoreAllActions();
284 : }
285 466 : }
286 :
287 658985 : void ClientModify(SwClient* pClient, const SfxPoolItem *pOld, const SfxPoolItem *pNew)
288 : {
289 658985 : switch( pOld ? pOld->Which() : 0 )
290 : {
291 : case RES_REMOVE_UNO_OBJECT:
292 : case RES_OBJECTDYING:
293 555240 : if( (void*)pClient->GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject )
294 554166 : ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient);
295 555240 : break;
296 :
297 : case RES_FMT_CHG:
298 : // Is the move to the new one finished and will the old one be deleted?
299 3478 : if( ((SwFmtChg*)pNew)->pChangedFmt == pClient->GetRegisteredIn() &&
300 1671 : ((SwFmtChg*)pOld)->pChangedFmt->IsFmtInDTOR() )
301 1651 : ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient);
302 1807 : break;
303 : }
304 658985 : }
305 :
306 196454 : void SwUnoCursorHelper::SetCrsrAttr(SwPaM & rPam,
307 : const SfxItemSet& rSet,
308 : const SetAttrMode nAttrMode, const bool bTableMode)
309 : {
310 196454 : const SetAttrMode nFlags = nAttrMode | nsSetAttrMode::SETATTR_APICALL;
311 196454 : SwDoc* pDoc = rPam.GetDoc();
312 : //StartEndAction
313 196454 : UnoActionContext aAction(pDoc);
314 196454 : if (rPam.GetNext() != &rPam) // Ring of Cursors
315 : {
316 146 : pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSATTR, NULL);
317 :
318 146 : SwPaM *pCurrent = &rPam;
319 2920 : do
320 : {
321 5840 : if (pCurrent->HasMark() &&
322 0 : ( (bTableMode) ||
323 0 : (*pCurrent->GetPoint() != *pCurrent->GetMark()) ))
324 : {
325 2920 : pDoc->getIDocumentContentOperations().InsertItemSet(*pCurrent, rSet, nFlags);
326 : }
327 2920 : pCurrent= static_cast<SwPaM *>(pCurrent->GetNext());
328 : } while (pCurrent != &rPam);
329 :
330 146 : pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSATTR, NULL);
331 : }
332 : else
333 : {
334 196308 : pDoc->getIDocumentContentOperations().InsertItemSet( rPam, rSet, nFlags );
335 : }
336 :
337 196454 : if( rSet.GetItemState( RES_PARATR_OUTLINELEVEL, false ) >= SfxItemState::DEFAULT )
338 : {
339 1702 : SwTxtNode * pTmpNode = rPam.GetNode().GetTxtNode();
340 1702 : if ( pTmpNode )
341 : {
342 1702 : rPam.GetDoc()->GetNodes().UpdateOutlineNode( *pTmpNode );
343 : }
344 196454 : }
345 196454 : }
346 :
347 : // #i63870#
348 : // split third parameter <bCurrentAttrOnly> into new parameters <bOnlyTxtAttr>
349 : // and <bGetFromChrFmt> to get better control about resulting <SfxItemSet>
350 246686 : void SwUnoCursorHelper::GetCrsrAttr(SwPaM & rPam,
351 : SfxItemSet & rSet, const bool bOnlyTxtAttr, const bool bGetFromChrFmt)
352 : {
353 : static const sal_uLong nMaxLookup = 1000;
354 246686 : SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
355 246686 : SfxItemSet *pSet = &rSet;
356 246686 : SwPaM *pCurrent = & rPam;
357 255122 : do
358 : {
359 255122 : SwPosition const & rStart( *pCurrent->Start() );
360 255122 : SwPosition const & rEnd( *pCurrent->End() );
361 255122 : const sal_uLong nSttNd = rStart.nNode.GetIndex();
362 255122 : const sal_uLong nEndNd = rEnd .nNode.GetIndex();
363 :
364 255122 : if (nEndNd - nSttNd >= nMaxLookup)
365 : {
366 0 : rSet.ClearItem();
367 0 : rSet.InvalidateAllItems();
368 246686 : return;// uno::Any();
369 : }
370 :
371 : // the first node inserts the values into the get set
372 : // all other nodes merge their values into the get set
373 522146 : for (sal_uLong n = nSttNd; n <= nEndNd; ++n)
374 : {
375 267024 : SwNode *const pNd = rPam.GetDoc()->GetNodes()[ n ];
376 267024 : switch (pNd->GetNodeType())
377 : {
378 : case ND_TEXTNODE:
379 : {
380 : const sal_Int32 nStart = (n == nSttNd)
381 261844 : ? rStart.nContent.GetIndex() : 0;
382 : const sal_Int32 nEnd = (n == nEndNd)
383 254554 : ? rEnd.nContent.GetIndex()
384 516398 : : static_cast<SwTxtNode*>(pNd)->GetTxt().getLength();
385 : static_cast<SwTxtNode*>(pNd)->GetAttr(
386 261844 : *pSet, nStart, nEnd, bOnlyTxtAttr, bGetFromChrFmt);
387 : }
388 261844 : break;
389 :
390 : case ND_GRFNODE:
391 : case ND_OLENODE:
392 0 : static_cast<SwCntntNode*>(pNd)->GetAttr( *pSet );
393 0 : break;
394 :
395 : default:
396 5180 : continue; // skip this node
397 : }
398 :
399 261844 : if (pSet != &rSet)
400 : {
401 15726 : rSet.MergeValues( aSet );
402 : }
403 : else
404 : {
405 246118 : pSet = &aSet;
406 : }
407 :
408 261844 : if (aSet.Count())
409 : {
410 11312 : aSet.ClearItem();
411 : }
412 : }
413 255122 : pCurrent= static_cast<SwPaM *>(pCurrent->GetNext());
414 246686 : } while ( pCurrent != &rPam );
415 : }
416 :
417 : class SwXParagraphEnumeration::Impl
418 : : public SwClient
419 : {
420 : public:
421 : uno::Reference< text::XText > const m_xParentText;
422 : const CursorType m_eCursorType;
423 : /// Start node of the cell _or_ table the enumeration belongs to.
424 : /// Used to restrict the movement of the UNO cursor to the cell and its
425 : /// embedded tables.
426 : SwStartNode const*const m_pOwnStartNode;
427 : SwTable const*const m_pOwnTable;
428 : const sal_uLong m_nEndIndex;
429 : sal_Int32 m_nFirstParaStart;
430 : sal_Int32 m_nLastParaEnd;
431 : bool m_bFirstParagraph;
432 : uno::Reference< text::XTextContent > m_xNextPara;
433 :
434 15488 : Impl( uno::Reference< text::XText > const& xParent,
435 : ::std::unique_ptr<SwUnoCrsr> && pCursor,
436 : const CursorType eType,
437 : SwStartNode const*const pStartNode, SwTable const*const pTable)
438 15488 : : SwClient( pCursor.release() )
439 : , m_xParentText( xParent )
440 : , m_eCursorType( eType )
441 : // remember table and start node for later travelling
442 : // (used in export of tables in tables)
443 : , m_pOwnStartNode( pStartNode )
444 : // for import of tables in tables we have to remember the actual
445 : // table and start node of the current position in the enumeration.
446 : , m_pOwnTable( pTable )
447 15488 : , m_nEndIndex( GetCursor()->End()->nNode.GetIndex() )
448 : , m_nFirstParaStart( -1 )
449 : , m_nLastParaEnd( -1 )
450 30976 : , m_bFirstParagraph( true )
451 : {
452 : OSL_ENSURE(m_xParentText.is(), "SwXParagraphEnumeration: no parent?");
453 : OSL_ENSURE(GetRegisteredIn(), "SwXParagraphEnumeration: no cursor?");
454 : OSL_ENSURE( !((CURSOR_SELECTION_IN_TABLE == eType) ||
455 : (CURSOR_TBLTEXT == eType))
456 : || (m_pOwnTable && m_pOwnStartNode),
457 : "SwXParagraphEnumeration: table type but no start node or table?");
458 :
459 27344 : if ((CURSOR_SELECTION == m_eCursorType) ||
460 11856 : (CURSOR_SELECTION_IN_TABLE == m_eCursorType))
461 : {
462 4606 : SwUnoCrsr & rCursor = *GetCursor();
463 4606 : rCursor.Normalize();
464 4606 : m_nFirstParaStart = rCursor.GetPoint()->nContent.GetIndex();
465 4606 : m_nLastParaEnd = rCursor.GetMark()->nContent.GetIndex();
466 4606 : rCursor.DeleteMark();
467 : }
468 15488 : }
469 :
470 46464 : virtual ~Impl() {
471 : // Impl owns the cursor; delete it here: SolarMutex is locked
472 15488 : delete GetRegisteredIn();
473 30976 : }
474 :
475 53664 : SwUnoCrsr * GetCursor() {
476 : return static_cast<SwUnoCrsr*>(
477 53664 : const_cast<SwModify*>(GetRegisteredIn()));
478 : }
479 :
480 : uno::Reference< text::XTextContent > NextElement_Impl()
481 : throw (container::NoSuchElementException, lang::WrappedTargetException,
482 : uno::RuntimeException);
483 : protected:
484 : // SwClient
485 : virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
486 : };
487 :
488 15800 : void SwXParagraphEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
489 : {
490 15800 : ClientModify(this, pOld, pNew);
491 15800 : }
492 :
493 15488 : SwXParagraphEnumeration::SwXParagraphEnumeration(
494 : uno::Reference< text::XText > const& xParent,
495 : ::std::unique_ptr<SwUnoCrsr> && pCursor,
496 : const CursorType eType,
497 : SwStartNode const*const pStartNode, SwTable const*const pTable)
498 : : m_pImpl( new SwXParagraphEnumeration::Impl(xParent, std::move(pCursor), eType,
499 15488 : pStartNode, pTable) )
500 : {
501 15488 : }
502 :
503 30976 : SwXParagraphEnumeration::~SwXParagraphEnumeration()
504 : {
505 30976 : }
506 :
507 : OUString SAL_CALL
508 0 : SwXParagraphEnumeration::getImplementationName() throw (uno::RuntimeException, std::exception)
509 : {
510 0 : return OUString("SwXParagraphEnumeration");
511 : }
512 :
513 : static char const*const g_ServicesParagraphEnum[] =
514 : {
515 : "com.sun.star.text.ParagraphEnumeration",
516 : };
517 :
518 : static const size_t g_nServicesParagraphEnum(
519 : sizeof(g_ServicesParagraphEnum)/sizeof(g_ServicesParagraphEnum[0]));
520 :
521 : sal_Bool SAL_CALL
522 0 : SwXParagraphEnumeration::supportsService(const OUString& rServiceName)
523 : throw (uno::RuntimeException, std::exception)
524 : {
525 0 : return cppu::supportsService(this, rServiceName);
526 : }
527 :
528 : uno::Sequence< OUString > SAL_CALL
529 0 : SwXParagraphEnumeration::getSupportedServiceNames()
530 : throw (uno::RuntimeException, std::exception)
531 : {
532 : return ::sw::GetSupportedServiceNamesImpl(
533 0 : g_nServicesParagraphEnum, g_ServicesParagraphEnum);
534 : }
535 :
536 : sal_Bool SAL_CALL
537 14296 : SwXParagraphEnumeration::hasMoreElements() throw (uno::RuntimeException, std::exception)
538 : {
539 14296 : SolarMutexGuard aGuard;
540 :
541 14296 : return (m_pImpl->m_bFirstParagraph) ? sal_True : m_pImpl->m_xNextPara.is();
542 : }
543 :
544 : //!! compare to SwShellTableCrsr::FillRects() in viscrs.cxx
545 : static SwTableNode *
546 39742 : lcl_FindTopLevelTable(
547 : SwTableNode *const pTblNode, SwTable const*const pOwnTable)
548 : {
549 : // find top-most table in current context (section) level
550 :
551 39742 : SwTableNode * pLast = pTblNode;
552 81024 : for (SwTableNode* pTmp = pLast;
553 40512 : pTmp != NULL && &pTmp->GetTable() != pOwnTable; /* we must not go up higher than the own table! */
554 770 : pTmp = pTmp->StartOfSectionNode()->FindTableNode() )
555 : {
556 770 : pLast = pTmp;
557 : }
558 39742 : return pLast;
559 : }
560 :
561 : static bool
562 46394 : lcl_CursorIsInSection(
563 : SwUnoCrsr const*const pUnoCrsr, SwStartNode const*const pOwnStartNode)
564 : {
565 : // returns true if the cursor is in the section (or in a sub section!)
566 : // represented by pOwnStartNode
567 :
568 46394 : bool bRes = true;
569 46394 : if (pUnoCrsr && pOwnStartNode)
570 : {
571 21064 : const SwEndNode * pOwnEndNode = pOwnStartNode->EndOfSectionNode();
572 42128 : bRes = pOwnStartNode->GetIndex() <= pUnoCrsr->Start()->nNode.GetIndex() &&
573 42128 : pUnoCrsr->End()->nNode.GetIndex() <= pOwnEndNode->GetIndex();
574 : }
575 46394 : return bRes;
576 : }
577 :
578 : uno::Reference< text::XTextContent >
579 33570 : SwXParagraphEnumeration::Impl::NextElement_Impl()
580 : throw (container::NoSuchElementException, lang::WrappedTargetException,
581 : uno::RuntimeException)
582 : {
583 33570 : SwUnoCrsr *const pUnoCrsr = GetCursor();
584 33570 : if (!pUnoCrsr)
585 : {
586 0 : throw uno::RuntimeException();
587 : }
588 :
589 : // check for exceeding selections
590 51666 : if (!m_bFirstParagraph &&
591 32560 : ((CURSOR_SELECTION == m_eCursorType) ||
592 14464 : (CURSOR_SELECTION_IN_TABLE == m_eCursorType)))
593 : {
594 4606 : SwPosition* pStart = pUnoCrsr->Start();
595 : const ::std::unique_ptr<SwUnoCrsr> aNewCrsr(
596 4606 : pUnoCrsr->GetDoc()->CreateUnoCrsr(*pStart, false) );
597 : // one may also go into tables here
598 9212 : if ((CURSOR_TBLTEXT != m_eCursorType) &&
599 4606 : (CURSOR_SELECTION_IN_TABLE != m_eCursorType))
600 : {
601 3632 : aNewCrsr->SetRemainInSection( false );
602 : }
603 :
604 : // os 2005-01-14: This part is only necessary to detect movements out
605 : // of a selection; if there is no selection we don't have to care
606 4606 : SwTableNode *const pTblNode = aNewCrsr->GetNode().FindTableNode();
607 9212 : if (((CURSOR_TBLTEXT != m_eCursorType) &&
608 8238 : (CURSOR_SELECTION_IN_TABLE != m_eCursorType)) && pTblNode)
609 : {
610 0 : aNewCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex();
611 0 : aNewCrsr->Move(fnMoveForward, fnGoNode);
612 : }
613 : else
614 : {
615 4606 : aNewCrsr->MovePara(fnParaNext, fnParaStart);
616 : }
617 4606 : if (m_nEndIndex < aNewCrsr->Start()->nNode.GetIndex())
618 : {
619 412 : return 0;
620 4194 : }
621 : }
622 :
623 33158 : bool bInTable = false;
624 33158 : if (!m_bFirstParagraph)
625 : {
626 17684 : pUnoCrsr->SetRemainInSection( false );
627 : // what to do if already in a table?
628 17684 : SwTableNode * pTblNode = pUnoCrsr->GetNode().FindTableNode();
629 17684 : pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable );
630 17684 : if (pTblNode && (&pTblNode->GetTable() != m_pOwnTable))
631 : {
632 : // this is a foreign table: go to end
633 184 : pUnoCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex();
634 184 : if (!pUnoCrsr->Move(fnMoveForward, fnGoNode))
635 : {
636 2 : return 0;
637 : }
638 182 : bInTable = true;
639 : }
640 : }
641 :
642 33156 : uno::Reference< text::XTextContent > xRef;
643 : // the cursor must remain in the current section or a subsection
644 : // before AND after the movement...
645 55214 : if (lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ) &&
646 35182 : (m_bFirstParagraph || bInTable ||
647 30738 : (pUnoCrsr->MovePara(fnParaNext, fnParaStart) &&
648 13238 : lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ))))
649 : {
650 22058 : SwPosition* pStart = pUnoCrsr->Start();
651 : const sal_Int32 nFirstContent =
652 22058 : (m_bFirstParagraph) ? m_nFirstParaStart : -1;
653 : const sal_Int32 nLastContent =
654 22058 : (m_nEndIndex == pStart->nNode.GetIndex()) ? m_nLastParaEnd : -1;
655 :
656 : // position in a table, or in a simple paragraph?
657 22058 : SwTableNode * pTblNode = pUnoCrsr->GetNode().FindTableNode();
658 22058 : pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable );
659 22058 : if (/*CURSOR_TBLTEXT != eCursorType && CURSOR_SELECTION_IN_TABLE != eCursorType && */
660 22058 : pTblNode && (&pTblNode->GetTable() != m_pOwnTable))
661 : {
662 : // this is a foreign table
663 : SwFrmFmt* pTableFmt =
664 572 : static_cast<SwFrmFmt*>(pTblNode->GetTable().GetFrmFmt());
665 572 : xRef = SwXTextTable::CreateXTextTable(pTableFmt);
666 : }
667 : else
668 : {
669 21486 : text::XText *const pText = m_xParentText.get();
670 64458 : xRef = SwXParagraph::CreateXParagraph(*pUnoCrsr->GetDoc(),
671 21486 : pStart->nNode.GetNode().GetTxtNode(),
672 42972 : static_cast<SwXText*>(pText), nFirstContent, nLastContent);
673 : }
674 : }
675 :
676 33156 : return xRef;
677 : }
678 :
679 18100 : uno::Any SAL_CALL SwXParagraphEnumeration::nextElement()
680 : throw (container::NoSuchElementException, lang::WrappedTargetException,
681 : uno::RuntimeException, std::exception)
682 : {
683 18100 : SolarMutexGuard aGuard;
684 :
685 18100 : if (m_pImpl->m_bFirstParagraph)
686 : {
687 15474 : m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl();
688 15474 : m_pImpl->m_bFirstParagraph = false;
689 : }
690 36200 : const uno::Reference< text::XTextContent > xRef = m_pImpl->m_xNextPara;
691 18100 : if (!xRef.is())
692 : {
693 4 : throw container::NoSuchElementException();
694 : }
695 18096 : m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl();
696 :
697 18096 : uno::Any aRet;
698 18096 : aRet <<= xRef;
699 36196 : return aRet;
700 : }
701 :
702 : class SwXTextRange::Impl
703 : : public SwClient
704 : {
705 : public:
706 : const SfxItemPropertySet & m_rPropSet;
707 : const enum RangePosition m_eRangePosition;
708 : SwDoc & m_rDoc;
709 : uno::Reference<text::XText> m_xParentText;
710 : SwDepend m_ObjectDepend; // register at format of table or frame
711 : ::sw::mark::IMark * m_pMark;
712 :
713 187684 : Impl( SwDoc & rDoc, const enum RangePosition eRange,
714 : SwFrmFmt *const pTblFmt = 0,
715 : const uno::Reference< text::XText > & xParent = 0)
716 : : SwClient()
717 187684 : , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
718 : , m_eRangePosition(eRange)
719 : , m_rDoc(rDoc)
720 : , m_xParentText(xParent)
721 : , m_ObjectDepend(this, pTblFmt)
722 375368 : , m_pMark(0)
723 : {
724 187684 : }
725 :
726 375368 : virtual ~Impl()
727 375368 : {
728 : // Impl owns the bookmark; delete it here: SolarMutex is locked
729 187684 : Invalidate();
730 375368 : }
731 :
732 375818 : void Invalidate()
733 : {
734 375818 : if (m_pMark)
735 : {
736 181202 : m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark);
737 181202 : m_pMark = 0;
738 : }
739 375818 : }
740 :
741 112882 : const ::sw::mark::IMark * GetBookmark() const { return m_pMark; }
742 :
743 : protected:
744 : // SwClient
745 : virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
746 : };
747 :
748 188696 : void SwXTextRange::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
749 : {
750 188696 : const bool bAlreadyRegistered = 0 != GetRegisteredIn();
751 188696 : ClientModify(this, pOld, pNew);
752 188696 : if (m_ObjectDepend.GetRegisteredIn())
753 : {
754 2048 : ClientModify(&m_ObjectDepend, pOld, pNew);
755 : // if the depend was removed then the range must be removed too
756 2048 : if (!m_ObjectDepend.GetRegisteredIn() && GetRegisteredIn())
757 : {
758 0 : const_cast<SwModify*>(GetRegisteredIn())->Remove(this);
759 : }
760 : // or if the range has been removed but the depend is still
761 : // connected then the depend must be removed
762 3118 : else if (bAlreadyRegistered && !GetRegisteredIn() &&
763 1070 : m_ObjectDepend.GetRegisteredIn())
764 : {
765 1070 : const_cast<SwModify*>(m_ObjectDepend.GetRegisteredIn())
766 2140 : ->Remove(& m_ObjectDepend);
767 : }
768 : }
769 188696 : if (!GetRegisteredIn())
770 : {
771 187718 : m_pMark = 0;
772 : }
773 188696 : }
774 :
775 186614 : SwXTextRange::SwXTextRange(SwPaM& rPam,
776 : const uno::Reference< text::XText > & xParent,
777 : const enum RangePosition eRange)
778 186614 : : m_pImpl( new SwXTextRange::Impl(*rPam.GetDoc(), eRange, 0, xParent) )
779 : {
780 186614 : SetPositions(rPam);
781 186614 : }
782 :
783 1070 : SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt)
784 : : m_pImpl(
785 1070 : new SwXTextRange::Impl(*rTblFmt.GetDoc(), RANGE_IS_TABLE, &rTblFmt) )
786 : {
787 1070 : SwTable *const pTable = SwTable::FindTable( &rTblFmt );
788 1070 : SwTableNode *const pTblNode = pTable->GetTableNode();
789 1070 : SwPosition aPosition( *pTblNode );
790 2140 : SwPaM aPam( aPosition );
791 :
792 2140 : SetPositions( aPam );
793 1070 : }
794 :
795 375368 : SwXTextRange::~SwXTextRange()
796 : {
797 375368 : }
798 :
799 0 : const SwDoc * SwXTextRange::GetDoc() const
800 : {
801 0 : return & m_pImpl->m_rDoc;
802 : }
803 :
804 91660 : SwDoc * SwXTextRange::GetDoc()
805 : {
806 91660 : return & m_pImpl->m_rDoc;
807 : }
808 :
809 416 : void SwXTextRange::Invalidate()
810 : {
811 416 : m_pImpl->Invalidate();
812 416 : }
813 :
814 187718 : void SwXTextRange::SetPositions(const SwPaM& rPam)
815 : {
816 187718 : m_pImpl->Invalidate();
817 187718 : IDocumentMarkAccess* const pMA = m_pImpl->m_rDoc.getIDocumentMarkAccess();
818 187718 : m_pImpl->m_pMark = pMA->makeMark(rPam, OUString(),
819 187718 : IDocumentMarkAccess::UNO_BOOKMARK);
820 187718 : m_pImpl->m_pMark->Add(m_pImpl.get());
821 187718 : }
822 :
823 34 : void SwXTextRange::DeleteAndInsert(
824 : const OUString& rText, const bool bForceExpandHints)
825 : throw (uno::RuntimeException)
826 : {
827 34 : if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
828 : {
829 : // setString on table not allowed
830 0 : throw uno::RuntimeException();
831 : }
832 :
833 34 : const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
834 68 : SwCursor aCursor(aPos, 0, false);
835 34 : if (GetPositions(aCursor))
836 : {
837 34 : UnoActionContext aAction(& m_pImpl->m_rDoc);
838 34 : m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
839 34 : if (aCursor.HasMark())
840 : {
841 18 : m_pImpl->m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor);
842 : }
843 :
844 34 : if (!rText.isEmpty())
845 : {
846 : SwUnoCursorHelper::DocInsertStringSplitCR(
847 22 : m_pImpl->m_rDoc, aCursor, rText, bForceExpandHints);
848 :
849 22 : SwUnoCursorHelper::SelectPam(aCursor, true);
850 22 : aCursor.Left(rText.getLength(), CRSR_SKIP_CHARS, false, false);
851 : }
852 34 : SetPositions(aCursor);
853 34 : m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
854 34 : }
855 34 : }
856 :
857 : namespace
858 : {
859 : class theSwXTextRangeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangeUnoTunnelId > {};
860 : }
861 :
862 662892 : const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId()
863 : {
864 662892 : return theSwXTextRangeUnoTunnelId::get().getSeq();
865 : }
866 :
867 : // XUnoTunnel
868 : sal_Int64 SAL_CALL
869 392768 : SwXTextRange::getSomething(const uno::Sequence< sal_Int8 >& rId)
870 : throw (uno::RuntimeException, std::exception)
871 : {
872 392768 : return ::sw::UnoTunnelImpl<SwXTextRange>(rId, this);
873 : }
874 :
875 : OUString SAL_CALL
876 6 : SwXTextRange::getImplementationName() throw (uno::RuntimeException, std::exception)
877 : {
878 6 : return OUString("SwXTextRange");
879 : }
880 :
881 : static char const*const g_ServicesTextRange[] =
882 : {
883 : "com.sun.star.text.TextRange",
884 : "com.sun.star.style.CharacterProperties",
885 : "com.sun.star.style.CharacterPropertiesAsian",
886 : "com.sun.star.style.CharacterPropertiesComplex",
887 : "com.sun.star.style.ParagraphProperties",
888 : "com.sun.star.style.ParagraphPropertiesAsian",
889 : "com.sun.star.style.ParagraphPropertiesComplex",
890 : };
891 :
892 : static const size_t g_nServicesTextRange(
893 : sizeof(g_ServicesTextRange)/sizeof(g_ServicesTextRange[0]));
894 :
895 10 : sal_Bool SAL_CALL SwXTextRange::supportsService(const OUString& rServiceName)
896 : throw (uno::RuntimeException, std::exception)
897 : {
898 10 : return cppu::supportsService(this, rServiceName);
899 : }
900 :
901 : uno::Sequence< OUString > SAL_CALL
902 10 : SwXTextRange::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
903 : {
904 : return ::sw::GetSupportedServiceNamesImpl(
905 10 : g_nServicesTextRange, g_ServicesTextRange);
906 : }
907 :
908 : uno::Reference< text::XText > SAL_CALL
909 10036 : SwXTextRange::getText() throw (uno::RuntimeException, std::exception)
910 : {
911 10036 : SolarMutexGuard aGuard;
912 :
913 10036 : if (!m_pImpl->m_xParentText.is())
914 : {
915 0 : if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE &&
916 0 : m_pImpl->m_ObjectDepend.GetRegisteredIn())
917 : {
918 : SwFrmFmt const*const pTblFmt = static_cast<SwFrmFmt const*>(
919 0 : m_pImpl->m_ObjectDepend.GetRegisteredIn());
920 0 : SwTable const*const pTable = SwTable::FindTable( pTblFmt );
921 0 : SwTableNode const*const pTblNode = pTable->GetTableNode();
922 0 : const SwPosition aPosition( *pTblNode );
923 0 : m_pImpl->m_xParentText =
924 0 : ::sw::CreateParentXText(m_pImpl->m_rDoc, aPosition);
925 : }
926 : }
927 : OSL_ENSURE(m_pImpl->m_xParentText.is(), "SwXTextRange::getText: no text");
928 10036 : return m_pImpl->m_xParentText;
929 : }
930 :
931 : uno::Reference< text::XTextRange > SAL_CALL
932 1596 : SwXTextRange::getStart() throw (uno::RuntimeException, std::exception)
933 : {
934 1596 : SolarMutexGuard aGuard;
935 :
936 1596 : uno::Reference< text::XTextRange > xRet;
937 1596 : ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
938 1596 : if (!m_pImpl->m_xParentText.is())
939 : {
940 0 : getText();
941 : }
942 1596 : if(pBkmk)
943 : {
944 1596 : SwPaM aPam(pBkmk->GetMarkStart());
945 1596 : xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
946 : }
947 0 : else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
948 : {
949 : // start and end are this, if it's a table
950 0 : xRet = this;
951 : }
952 : else
953 : {
954 0 : throw uno::RuntimeException();
955 : }
956 1596 : return xRet;
957 : }
958 :
959 : uno::Reference< text::XTextRange > SAL_CALL
960 4678 : SwXTextRange::getEnd() throw (uno::RuntimeException, std::exception)
961 : {
962 4678 : SolarMutexGuard aGuard;
963 :
964 4678 : uno::Reference< text::XTextRange > xRet;
965 4678 : ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
966 4678 : if (!m_pImpl->m_xParentText.is())
967 : {
968 0 : getText();
969 : }
970 4678 : if(pBkmk)
971 : {
972 4678 : SwPaM aPam(pBkmk->GetMarkEnd());
973 4678 : xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
974 : }
975 0 : else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
976 : {
977 : // start and end are this, if it's a table
978 0 : xRet = this;
979 : }
980 : else
981 : {
982 0 : throw uno::RuntimeException();
983 : }
984 4678 : return xRet;
985 : }
986 :
987 9684 : OUString SAL_CALL SwXTextRange::getString() throw (uno::RuntimeException, std::exception)
988 : {
989 9684 : SolarMutexGuard aGuard;
990 :
991 9684 : OUString sRet;
992 : // for tables there is no bookmark, thus also no text
993 : // one could export the table as ASCII here maybe?
994 19368 : SwPaM aPaM(GetDoc()->GetNodes());
995 9684 : if (GetPositions(aPaM) && aPaM.HasMark())
996 : {
997 9682 : SwUnoCursorHelper::GetTextFromPam(aPaM, sRet);
998 : }
999 19368 : return sRet;
1000 : }
1001 :
1002 34 : void SAL_CALL SwXTextRange::setString(const OUString& rString)
1003 : throw (uno::RuntimeException, std::exception)
1004 : {
1005 34 : SolarMutexGuard aGuard;
1006 :
1007 34 : DeleteAndInsert(rString, false);
1008 34 : }
1009 :
1010 101668 : bool SwXTextRange::GetPositions(SwPaM& rToFill) const
1011 : {
1012 101668 : ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
1013 101668 : if(pBkmk)
1014 : {
1015 101656 : *rToFill.GetPoint() = pBkmk->GetMarkPos();
1016 101656 : if(pBkmk->IsExpanded())
1017 : {
1018 13908 : rToFill.SetMark();
1019 13908 : *rToFill.GetMark() = pBkmk->GetOtherMarkPos();
1020 : }
1021 : else
1022 : {
1023 87748 : rToFill.DeleteMark();
1024 : }
1025 101656 : return true;
1026 : }
1027 12 : return false;
1028 : }
1029 :
1030 : namespace sw {
1031 :
1032 106710 : bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
1033 : const uno::Reference< text::XTextRange > & xTextRange)
1034 : {
1035 106710 : bool bRet = false;
1036 :
1037 106710 : uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
1038 106710 : SwXTextRange* pRange = 0;
1039 106710 : OTextCursorHelper* pCursor = 0;
1040 106710 : SwXTextPortion* pPortion = 0;
1041 106710 : SwXText* pText = 0;
1042 106710 : SwXParagraph* pPara = 0;
1043 106710 : if(xRangeTunnel.is())
1044 : {
1045 106706 : pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
1046 : pCursor =
1047 106706 : ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
1048 : pPortion=
1049 106706 : ::sw::UnoTunnelGetImplementation<SwXTextPortion>(xRangeTunnel);
1050 106706 : pText = ::sw::UnoTunnelGetImplementation<SwXText>(xRangeTunnel);
1051 106706 : pPara = ::sw::UnoTunnelGetImplementation<SwXParagraph>(xRangeTunnel);
1052 : }
1053 :
1054 : // if it's a text then create a temporary cursor there and re-use
1055 : // the pCursor variable
1056 : // #i108489#: Reference in outside scope to keep cursor alive
1057 213420 : uno::Reference< text::XTextCursor > xTextCursor;
1058 106710 : if (pText)
1059 : {
1060 826 : xTextCursor.set( pText->CreateCursor() );
1061 826 : xTextCursor->gotoEnd(sal_True);
1062 : const uno::Reference<lang::XUnoTunnel> xCrsrTunnel(
1063 826 : xTextCursor, uno::UNO_QUERY);
1064 : pCursor =
1065 826 : ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCrsrTunnel);
1066 : }
1067 106710 : if(pRange && pRange->GetDoc() == rToFill.GetDoc())
1068 : {
1069 59910 : bRet = pRange->GetPositions(rToFill);
1070 : }
1071 : else
1072 : {
1073 46800 : if (pPara)
1074 : {
1075 0 : bRet = pPara->SelectPaM(rToFill);
1076 : }
1077 : else
1078 : {
1079 46796 : SwDoc* const pDoc = (pCursor) ? pCursor->GetDoc()
1080 93596 : : ((pPortion) ? pPortion->GetCursor()->GetDoc() : 0);
1081 46796 : const SwPaM* const pUnoCrsr = (pCursor) ? pCursor->GetPaM()
1082 93596 : : ((pPortion) ? pPortion->GetCursor() : 0);
1083 46800 : if (pUnoCrsr && pDoc == rToFill.GetDoc())
1084 : {
1085 : OSL_ENSURE((SwPaM*)pUnoCrsr->GetNext() == pUnoCrsr,
1086 : "what to do about rings?");
1087 46796 : bRet = true;
1088 46796 : *rToFill.GetPoint() = *pUnoCrsr->GetPoint();
1089 46796 : if (pUnoCrsr->HasMark())
1090 : {
1091 18568 : rToFill.SetMark();
1092 18568 : *rToFill.GetMark() = *pUnoCrsr->GetMark();
1093 : }
1094 : else
1095 28228 : rToFill.DeleteMark();
1096 : }
1097 : }
1098 : }
1099 213420 : return bRet;
1100 : }
1101 :
1102 : static bool
1103 342 : lcl_IsStartNodeInFormat(const bool bHeader, SwStartNode *const pSttNode,
1104 : SwFrmFmt const*const pFrmFmt, SwFrmFmt*& rpFormat)
1105 : {
1106 342 : bool bRet = false;
1107 342 : const SfxItemSet& rSet = pFrmFmt->GetAttrSet();
1108 : const SfxPoolItem* pItem;
1109 342 : if (SfxItemState::SET == rSet.GetItemState(
1110 : static_cast<sal_uInt16>(bHeader ? RES_HEADER : RES_FOOTER),
1111 342 : true, &pItem))
1112 : {
1113 330 : SfxPoolItem *const pItemNonConst(const_cast<SfxPoolItem *>(pItem));
1114 : SwFrmFmt *const pHeadFootFmt = (bHeader) ?
1115 : static_cast<SwFmtHeader*>(pItemNonConst)->GetHeaderFmt() :
1116 330 : static_cast<SwFmtFooter*>(pItemNonConst)->GetFooterFmt();
1117 330 : if (pHeadFootFmt)
1118 : {
1119 290 : const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
1120 290 : const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
1121 : SwStartNode const*const pCurSttNode = rNode.FindSttNodeByType(
1122 290 : (bHeader) ? SwHeaderStartNode : SwFooterStartNode);
1123 290 : if (pCurSttNode && (pCurSttNode == pSttNode))
1124 : {
1125 202 : rpFormat = pHeadFootFmt;
1126 202 : bRet = true;
1127 : }
1128 : }
1129 : }
1130 342 : return bRet;
1131 : }
1132 :
1133 : } // namespace sw
1134 :
1135 : uno::Reference< text::XTextRange >
1136 11476 : SwXTextRange::CreateXTextRange(
1137 : SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark)
1138 : {
1139 : const uno::Reference<text::XText> xParentText(
1140 11476 : ::sw::CreateParentXText(rDoc, rPos));
1141 : const ::std::unique_ptr<SwUnoCrsr> pNewCrsr(
1142 22952 : rDoc.CreateUnoCrsr(rPos, false));
1143 11476 : if(pMark)
1144 : {
1145 10372 : pNewCrsr->SetMark();
1146 10372 : *pNewCrsr->GetMark() = *pMark;
1147 : }
1148 11476 : const bool isCell( dynamic_cast<SwXCell*>(xParentText.get()) );
1149 : const uno::Reference< text::XTextRange > xRet(
1150 11476 : new SwXTextRange(*pNewCrsr, xParentText,
1151 11476 : isCell ? RANGE_IN_CELL : RANGE_IN_TEXT) );
1152 22952 : return xRet;
1153 : }
1154 :
1155 : namespace sw {
1156 :
1157 : uno::Reference< text::XText >
1158 11686 : CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
1159 : {
1160 11686 : uno::Reference< text::XText > xParentText;
1161 11686 : SwStartNode* pSttNode = rPos.nNode.GetNode().StartOfSectionNode();
1162 23422 : while(pSttNode && pSttNode->IsSectionNode())
1163 : {
1164 50 : pSttNode = pSttNode->StartOfSectionNode();
1165 : }
1166 11686 : SwStartNodeType eType = pSttNode ? pSttNode->GetStartNodeType() : SwNormalStartNode;
1167 11686 : switch(eType)
1168 : {
1169 : case SwTableBoxStartNode:
1170 : {
1171 902 : SwTableNode const*const pTblNode = pSttNode->FindTableNode();
1172 : SwFrmFmt *const pTableFmt =
1173 902 : static_cast<SwFrmFmt*>(pTblNode->GetTable().GetFrmFmt());
1174 902 : SwTableBox *const pBox = pSttNode->GetTblBox();
1175 :
1176 902 : xParentText = (pBox)
1177 : ? SwXCell::CreateXCell( pTableFmt, pBox )
1178 902 : : new SwXCell( pTableFmt, *pSttNode );
1179 : }
1180 902 : break;
1181 : case SwFlyStartNode:
1182 : {
1183 74 : SwFrmFmt *const pFmt = pSttNode->GetFlyFmt();
1184 74 : if (0 != pFmt)
1185 : {
1186 : xParentText.set(SwXTextFrame::CreateXTextFrame(rDoc, pFmt),
1187 74 : uno::UNO_QUERY);
1188 : }
1189 : }
1190 74 : break;
1191 : case SwHeaderStartNode:
1192 : case SwFooterStartNode:
1193 : {
1194 202 : const bool bHeader = (SwHeaderStartNode == eType);
1195 202 : const sal_uInt16 nPDescCount = rDoc.GetPageDescCnt();
1196 470 : for(sal_uInt16 i = 0; i < nPDescCount; i++)
1197 : {
1198 268 : const SwPageDesc& rDesc = rDoc.GetPageDesc( i );
1199 268 : const SwFrmFmt* pFrmFmtMaster = &rDesc.GetMaster();
1200 268 : const SwFrmFmt* pFrmFmtLeft = &rDesc.GetLeft();
1201 :
1202 268 : SwFrmFmt* pHeadFootFmt = 0;
1203 268 : if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtMaster,
1204 268 : pHeadFootFmt))
1205 : {
1206 : lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtLeft,
1207 74 : pHeadFootFmt);
1208 : }
1209 :
1210 268 : if (pHeadFootFmt)
1211 : {
1212 404 : xParentText = SwXHeadFootText::CreateXHeadFootText(
1213 202 : *pHeadFootFmt, bHeader);
1214 : }
1215 : }
1216 : }
1217 202 : break;
1218 : case SwFootnoteStartNode:
1219 : {
1220 12 : const size_t nFtnCnt = rDoc.GetFtnIdxs().size();
1221 12 : uno::Reference< text::XFootnote > xRef;
1222 18 : for (size_t n = 0; n < nFtnCnt; ++n )
1223 : {
1224 18 : const SwTxtFtn* pTxtFtn = rDoc.GetFtnIdxs()[ n ];
1225 18 : const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
1226 18 : pTxtFtn = rFtn.GetTxtFtn();
1227 : #if OSL_DEBUG_LEVEL > 1
1228 : const SwStartNode* pTmpSttNode =
1229 : pTxtFtn->GetStartNode()->GetNode().
1230 : FindSttNodeByType(SwFootnoteStartNode);
1231 : (void)pTmpSttNode;
1232 : #endif
1233 :
1234 36 : if (pSttNode == pTxtFtn->GetStartNode()->GetNode().
1235 18 : FindSttNodeByType(SwFootnoteStartNode))
1236 : {
1237 : xParentText.set(SwXFootnote::CreateXFootnote(rDoc,
1238 12 : &const_cast<SwFmtFtn&>(rFtn)), uno::UNO_QUERY);
1239 12 : break;
1240 : }
1241 12 : }
1242 : }
1243 12 : break;
1244 : default:
1245 : {
1246 : // then it is the body text
1247 : const uno::Reference<frame::XModel> xModel =
1248 10496 : rDoc.GetDocShell()->GetBaseModel();
1249 : const uno::Reference< text::XTextDocument > xDoc(
1250 20992 : xModel, uno::UNO_QUERY);
1251 20992 : xParentText = xDoc->getText();
1252 : }
1253 : }
1254 : OSL_ENSURE(xParentText.is(), "no parent text?");
1255 11686 : return xParentText;
1256 : }
1257 :
1258 : } // namespace sw
1259 :
1260 : uno::Reference< container::XEnumeration > SAL_CALL
1261 2 : SwXTextRange::createContentEnumeration(const OUString& rServiceName)
1262 : throw (uno::RuntimeException, std::exception)
1263 : {
1264 2 : SolarMutexGuard g;
1265 :
1266 2 : if ( rServiceName != "com.sun.star.text.TextContent" )
1267 : {
1268 0 : throw uno::RuntimeException();
1269 : }
1270 :
1271 2 : if (!GetDoc() || !m_pImpl->GetBookmark())
1272 : {
1273 0 : throw uno::RuntimeException();
1274 : }
1275 4 : const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
1276 : const ::std::unique_ptr<SwUnoCrsr> pNewCrsr(
1277 4 : m_pImpl->m_rDoc.CreateUnoCrsr(aPos, false));
1278 2 : if (!GetPositions(*pNewCrsr))
1279 : {
1280 0 : throw uno::RuntimeException();
1281 : }
1282 :
1283 : const uno::Reference< container::XEnumeration > xRet =
1284 2 : new SwXParaFrameEnumeration(*pNewCrsr, PARAFRAME_PORTION_TEXTRANGE);
1285 4 : return xRet;
1286 : }
1287 :
1288 : uno::Reference< container::XEnumeration > SAL_CALL
1289 0 : SwXTextRange::createEnumeration() throw (uno::RuntimeException, std::exception)
1290 : {
1291 0 : SolarMutexGuard g;
1292 :
1293 0 : if (!GetDoc() || !m_pImpl->GetBookmark())
1294 : {
1295 0 : throw uno::RuntimeException();
1296 : }
1297 0 : const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
1298 : ::std::unique_ptr<SwUnoCrsr> pNewCrsr(
1299 0 : m_pImpl->m_rDoc.CreateUnoCrsr(aPos, false));
1300 0 : if (!GetPositions(*pNewCrsr))
1301 : {
1302 0 : throw uno::RuntimeException();
1303 : }
1304 0 : if (!m_pImpl->m_xParentText.is())
1305 : {
1306 0 : getText();
1307 : }
1308 :
1309 0 : const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition)
1310 0 : ? CURSOR_SELECTION_IN_TABLE : CURSOR_SELECTION;
1311 : const uno::Reference< container::XEnumeration > xRet =
1312 0 : new SwXParagraphEnumeration(m_pImpl->m_xParentText, std::move(pNewCrsr), eSetType);
1313 0 : return xRet;
1314 : }
1315 :
1316 0 : uno::Type SAL_CALL SwXTextRange::getElementType() throw (uno::RuntimeException, std::exception)
1317 : {
1318 0 : return cppu::UnoType<text::XTextRange>::get();
1319 : }
1320 :
1321 0 : sal_Bool SAL_CALL SwXTextRange::hasElements() throw (uno::RuntimeException, std::exception)
1322 : {
1323 0 : return sal_True;
1324 : }
1325 :
1326 : uno::Sequence< OUString > SAL_CALL
1327 2 : SwXTextRange::getAvailableServiceNames() throw (uno::RuntimeException, std::exception)
1328 : {
1329 2 : uno::Sequence< OUString > aRet(1);
1330 2 : OUString* pArray = aRet.getArray();
1331 2 : pArray[0] = "com.sun.star.text.TextContent";
1332 2 : return aRet;
1333 : }
1334 :
1335 : uno::Reference< beans::XPropertySetInfo > SAL_CALL
1336 496 : SwXTextRange::getPropertySetInfo() throw (uno::RuntimeException, std::exception)
1337 : {
1338 496 : SolarMutexGuard aGuard;
1339 :
1340 : static uno::Reference< beans::XPropertySetInfo > xRef =
1341 496 : m_pImpl->m_rPropSet.getPropertySetInfo();
1342 496 : return xRef;
1343 : }
1344 :
1345 : void SAL_CALL
1346 998 : SwXTextRange::setPropertyValue(
1347 : const OUString& rPropertyName, const uno::Any& rValue)
1348 : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
1349 : lang::IllegalArgumentException, lang::WrappedTargetException,
1350 : uno::RuntimeException, std::exception)
1351 : {
1352 998 : SolarMutexGuard aGuard;
1353 :
1354 998 : if (!GetDoc() || !m_pImpl->GetBookmark())
1355 : {
1356 0 : throw uno::RuntimeException();
1357 : }
1358 1996 : SwPaM aPaM(GetDoc()->GetNodes());
1359 998 : GetPositions(aPaM);
1360 998 : SwUnoCursorHelper::SetPropertyValue(aPaM, m_pImpl->m_rPropSet,
1361 1996 : rPropertyName, rValue);
1362 998 : }
1363 :
1364 : uno::Any SAL_CALL
1365 1154 : SwXTextRange::getPropertyValue(const OUString& rPropertyName)
1366 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1367 : uno::RuntimeException, std::exception)
1368 : {
1369 1154 : SolarMutexGuard aGuard;
1370 :
1371 1154 : if (!GetDoc() || !m_pImpl->GetBookmark())
1372 : {
1373 0 : throw uno::RuntimeException();
1374 : }
1375 2304 : SwPaM aPaM(GetDoc()->GetNodes());
1376 1154 : GetPositions(aPaM);
1377 1154 : return SwUnoCursorHelper::GetPropertyValue(aPaM, m_pImpl->m_rPropSet,
1378 2308 : rPropertyName);
1379 : }
1380 :
1381 : void SAL_CALL
1382 0 : SwXTextRange::addPropertyChangeListener(
1383 : const OUString& /*rPropertyName*/,
1384 : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1385 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1386 : uno::RuntimeException, std::exception)
1387 : {
1388 : OSL_FAIL("SwXTextRange::addPropertyChangeListener(): not implemented");
1389 0 : }
1390 :
1391 : void SAL_CALL
1392 0 : SwXTextRange::removePropertyChangeListener(
1393 : const OUString& /*rPropertyName*/,
1394 : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1395 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1396 : uno::RuntimeException, std::exception)
1397 : {
1398 : OSL_FAIL("SwXTextRange::removePropertyChangeListener(): not implemented");
1399 0 : }
1400 :
1401 : void SAL_CALL
1402 0 : SwXTextRange::addVetoableChangeListener(
1403 : const OUString& /*rPropertyName*/,
1404 : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1405 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1406 : uno::RuntimeException, std::exception)
1407 : {
1408 : OSL_FAIL("SwXTextRange::addVetoableChangeListener(): not implemented");
1409 0 : }
1410 :
1411 : void SAL_CALL
1412 0 : SwXTextRange::removeVetoableChangeListener(
1413 : const OUString& /*rPropertyName*/,
1414 : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1415 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1416 : uno::RuntimeException, std::exception)
1417 : {
1418 : OSL_FAIL("SwXTextRange::removeVetoableChangeListener(): not implemented");
1419 0 : }
1420 :
1421 : beans::PropertyState SAL_CALL
1422 2 : SwXTextRange::getPropertyState(const OUString& rPropertyName)
1423 : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
1424 : {
1425 2 : SolarMutexGuard aGuard;
1426 :
1427 2 : if (!GetDoc() || !m_pImpl->GetBookmark())
1428 : {
1429 0 : throw uno::RuntimeException();
1430 : }
1431 4 : SwPaM aPaM(GetDoc()->GetNodes());
1432 2 : GetPositions(aPaM);
1433 2 : return SwUnoCursorHelper::GetPropertyState(aPaM, m_pImpl->m_rPropSet,
1434 4 : rPropertyName);
1435 : }
1436 :
1437 : uno::Sequence< beans::PropertyState > SAL_CALL
1438 138 : SwXTextRange::getPropertyStates(const uno::Sequence< OUString >& rPropertyName)
1439 : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
1440 : {
1441 138 : SolarMutexGuard g;
1442 :
1443 138 : if (!GetDoc() || !m_pImpl->GetBookmark())
1444 : {
1445 0 : throw uno::RuntimeException();
1446 : }
1447 276 : SwPaM aPaM(GetDoc()->GetNodes());
1448 138 : GetPositions(aPaM);
1449 138 : return SwUnoCursorHelper::GetPropertyStates(aPaM, m_pImpl->m_rPropSet,
1450 276 : rPropertyName);
1451 : }
1452 :
1453 2 : void SAL_CALL SwXTextRange::setPropertyToDefault(const OUString& rPropertyName)
1454 : throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
1455 : {
1456 2 : SolarMutexGuard aGuard;
1457 :
1458 2 : if (!GetDoc() || !m_pImpl->GetBookmark())
1459 : {
1460 0 : throw uno::RuntimeException();
1461 : }
1462 4 : SwPaM aPaM(GetDoc()->GetNodes());
1463 2 : GetPositions(aPaM);
1464 2 : SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_pImpl->m_rPropSet,
1465 4 : rPropertyName);
1466 2 : }
1467 :
1468 : uno::Any SAL_CALL
1469 2 : SwXTextRange::getPropertyDefault(const OUString& rPropertyName)
1470 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1471 : uno::RuntimeException, std::exception)
1472 : {
1473 2 : SolarMutexGuard aGuard;
1474 :
1475 2 : if (!GetDoc() || !m_pImpl->GetBookmark())
1476 : {
1477 0 : throw uno::RuntimeException();
1478 : }
1479 4 : SwPaM aPaM(GetDoc()->GetNodes());
1480 2 : GetPositions(aPaM);
1481 2 : return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_pImpl->m_rPropSet,
1482 4 : rPropertyName);
1483 : }
1484 :
1485 : void SAL_CALL
1486 2642 : SwXTextRange::makeRedline(
1487 : const OUString& rRedlineType,
1488 : const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
1489 : throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
1490 : {
1491 2642 : SolarMutexGuard aGuard;
1492 :
1493 2642 : if (!GetDoc() || !m_pImpl->GetBookmark())
1494 : {
1495 0 : throw uno::RuntimeException();
1496 : }
1497 5280 : SwPaM aPaM(GetDoc()->GetNodes());
1498 2642 : SwXTextRange::GetPositions(aPaM);
1499 5284 : SwUnoCursorHelper::makeRedline( aPaM, rRedlineType, rRedlineProperties );
1500 2638 : }
1501 :
1502 : class SwXTextRanges::Impl
1503 : : public SwClient
1504 : {
1505 : public:
1506 : ::std::vector< uno::Reference< text::XTextRange > > m_Ranges;
1507 :
1508 8 : Impl(SwPaM *const pPaM)
1509 : : SwClient( (pPaM)
1510 8 : ? pPaM->GetDoc()->CreateUnoCrsr(*pPaM->GetPoint())
1511 16 : : 0 )
1512 : {
1513 8 : if (pPaM)
1514 : {
1515 8 : ::sw::DeepCopyPaM(*pPaM, *GetCursor());
1516 : }
1517 8 : MakeRanges();
1518 8 : }
1519 :
1520 24 : virtual ~Impl() {
1521 : // Impl owns the cursor; delete it here: SolarMutex is locked
1522 8 : delete GetRegisteredIn();
1523 16 : }
1524 :
1525 16 : SwUnoCrsr * GetCursor() {
1526 : return static_cast<SwUnoCrsr*>(
1527 16 : const_cast<SwModify*>(GetRegisteredIn()));
1528 : }
1529 :
1530 : void MakeRanges();
1531 :
1532 : protected:
1533 : // SwClient
1534 : virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
1535 : };
1536 :
1537 8 : void SwXTextRanges::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
1538 : {
1539 8 : ClientModify(this, pOld, pNew);
1540 8 : }
1541 :
1542 8 : void SwXTextRanges::Impl::MakeRanges()
1543 : {
1544 8 : SwUnoCrsr *const pCursor = GetCursor();
1545 8 : if (pCursor)
1546 : {
1547 8 : SwPaM *pTmpCursor = pCursor;
1548 78 : do {
1549 : const uno::Reference< text::XTextRange > xRange(
1550 : SwXTextRange::CreateXTextRange(
1551 78 : *pTmpCursor->GetDoc(),
1552 156 : *pTmpCursor->GetPoint(), pTmpCursor->GetMark()));
1553 78 : if (xRange.is())
1554 : {
1555 78 : m_Ranges.push_back(xRange);
1556 : }
1557 78 : pTmpCursor = static_cast<SwPaM*>(pTmpCursor->GetNext());
1558 : }
1559 78 : while (pTmpCursor != pCursor);
1560 : }
1561 8 : }
1562 :
1563 0 : const SwUnoCrsr* SwXTextRanges::GetCursor() const
1564 : {
1565 0 : return m_pImpl->GetCursor();
1566 : }
1567 :
1568 8 : SwXTextRanges::SwXTextRanges(SwPaM *const pPaM)
1569 8 : : m_pImpl( new SwXTextRanges::Impl(pPaM) )
1570 : {
1571 8 : }
1572 :
1573 16 : SwXTextRanges::~SwXTextRanges()
1574 : {
1575 16 : }
1576 :
1577 : namespace
1578 : {
1579 : class theSwXTextRangesUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextRangesUnoTunnelId > {};
1580 : }
1581 :
1582 18 : const uno::Sequence< sal_Int8 > & SwXTextRanges::getUnoTunnelId()
1583 : {
1584 18 : return theSwXTextRangesUnoTunnelId::get().getSeq();
1585 : }
1586 :
1587 : sal_Int64 SAL_CALL
1588 0 : SwXTextRanges::getSomething(const uno::Sequence< sal_Int8 >& rId)
1589 : throw (uno::RuntimeException, std::exception)
1590 : {
1591 0 : return ::sw::UnoTunnelImpl<SwXTextRanges>(rId, this);
1592 : }
1593 :
1594 : /*
1595 : * Text positions
1596 : * Up to the first access to a text position, only a SwCursor is stored.
1597 : * Afterwards, an array with uno::Reference<XTextPosition> will be created.
1598 : */
1599 : OUString SAL_CALL
1600 0 : SwXTextRanges::getImplementationName() throw (uno::RuntimeException, std::exception)
1601 : {
1602 0 : return OUString("SwXTextRanges");
1603 : }
1604 :
1605 : static char const*const g_ServicesTextRanges[] =
1606 : {
1607 : "com.sun.star.text.TextRanges",
1608 : };
1609 :
1610 : static const size_t g_nServicesTextRanges(
1611 : sizeof(g_ServicesTextRanges)/sizeof(g_ServicesTextRanges[0]));
1612 :
1613 0 : sal_Bool SAL_CALL SwXTextRanges::supportsService(const OUString& rServiceName)
1614 : throw (uno::RuntimeException, std::exception)
1615 : {
1616 0 : return cppu::supportsService(this, rServiceName);
1617 : }
1618 :
1619 : uno::Sequence< OUString > SAL_CALL
1620 0 : SwXTextRanges::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
1621 : {
1622 : return ::sw::GetSupportedServiceNamesImpl(
1623 0 : g_nServicesTextRanges, g_ServicesTextRanges);
1624 : }
1625 :
1626 8 : sal_Int32 SAL_CALL SwXTextRanges::getCount() throw (uno::RuntimeException, std::exception)
1627 : {
1628 8 : SolarMutexGuard aGuard;
1629 :
1630 8 : return static_cast<sal_Int32>(m_pImpl->m_Ranges.size());
1631 : }
1632 :
1633 10 : uno::Any SAL_CALL SwXTextRanges::getByIndex(sal_Int32 nIndex)
1634 : throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException,
1635 : uno::RuntimeException, std::exception)
1636 : {
1637 10 : SolarMutexGuard aGuard;
1638 :
1639 20 : if ((nIndex < 0) ||
1640 10 : (static_cast<size_t>(nIndex) >= m_pImpl->m_Ranges.size()))
1641 : {
1642 2 : throw lang::IndexOutOfBoundsException();
1643 : }
1644 8 : uno::Any ret;
1645 8 : ret <<= (m_pImpl->m_Ranges.at(nIndex));
1646 10 : return ret;
1647 : }
1648 :
1649 : uno::Type SAL_CALL
1650 2 : SwXTextRanges::getElementType() throw (uno::RuntimeException, std::exception)
1651 : {
1652 2 : return cppu::UnoType<text::XTextRange>::get();
1653 : }
1654 :
1655 2 : sal_Bool SAL_CALL SwXTextRanges::hasElements() throw (uno::RuntimeException, std::exception)
1656 : {
1657 : // no mutex necessary: getCount() does locking
1658 2 : return getCount() > 0;
1659 : }
1660 :
1661 18 : void SwUnoCursorHelper::SetString(SwCursor & rCursor, const OUString& rString)
1662 : {
1663 : // Start/EndAction
1664 18 : SwDoc *const pDoc = rCursor.GetDoc();
1665 18 : UnoActionContext aAction(pDoc);
1666 18 : pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
1667 18 : if (rCursor.HasMark())
1668 : {
1669 16 : pDoc->getIDocumentContentOperations().DeleteAndJoin(rCursor);
1670 : }
1671 18 : if (!rString.isEmpty())
1672 : {
1673 : const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR(
1674 16 : *pDoc, rCursor, rString, false ) );
1675 : OSL_ENSURE( bSuccess, "DocInsertStringSplitCR" );
1676 : (void) bSuccess;
1677 16 : SwUnoCursorHelper::SelectPam(rCursor, true);
1678 16 : rCursor.Left(rString.getLength(), CRSR_SKIP_CHARS, false, false);
1679 : }
1680 18 : pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
1681 18 : }
1682 :
1683 : class SwXParaFrameEnumeration::Impl
1684 : : public SwClient
1685 : {
1686 : public:
1687 : // created by hasMoreElements
1688 : uno::Reference< text::XTextContent > m_xNextObject;
1689 : FrameDependList_t m_Frames;
1690 :
1691 732 : Impl(SwPaM const & rPaM)
1692 732 : : SwClient(rPaM.GetDoc()->CreateUnoCrsr(*rPaM.GetPoint(), false))
1693 : {
1694 732 : if (rPaM.HasMark())
1695 : {
1696 318 : GetCursor()->SetMark();
1697 318 : *GetCursor()->GetMark() = *rPaM.GetMark();
1698 : }
1699 732 : }
1700 :
1701 2196 : virtual ~Impl() {
1702 : // Impl owns the cursor; delete it here: SolarMutex is locked
1703 732 : delete GetRegisteredIn();
1704 1464 : }
1705 :
1706 2778 : SwUnoCrsr * GetCursor() {
1707 : return static_cast<SwUnoCrsr*>(
1708 2778 : const_cast<SwModify*>(GetRegisteredIn()));
1709 : }
1710 :
1711 : protected:
1712 : // SwClient
1713 : virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
1714 : };
1715 :
1716 : struct InvalidFrameDepend {
1717 0 : bool operator() (::boost::shared_ptr<SwDepend> const & rEntry)
1718 0 : { return !rEntry->GetRegisteredIn(); }
1719 : };
1720 :
1721 732 : void SwXParaFrameEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
1722 : {
1723 732 : ClientModify(this, pOld, pNew);
1724 732 : if(!GetRegisteredIn())
1725 : {
1726 732 : m_Frames.clear();
1727 732 : m_xNextObject = 0;
1728 : }
1729 : else
1730 : {
1731 : // check if any frame went away...
1732 : FrameDependList_t::iterator const iter =
1733 : ::std::remove_if(m_Frames.begin(), m_Frames.end(),
1734 0 : InvalidFrameDepend());
1735 0 : m_Frames.erase(iter, m_Frames.end());
1736 : }
1737 732 : }
1738 :
1739 : static bool
1740 860 : lcl_CreateNextObject(SwUnoCrsr& i_rUnoCrsr,
1741 : uno::Reference<text::XTextContent> & o_rNextObject,
1742 : FrameDependList_t & i_rFrames)
1743 : {
1744 860 : if (!i_rFrames.size())
1745 500 : return false;
1746 :
1747 : SwFrmFmt *const pFormat = static_cast<SwFrmFmt*>(const_cast<SwModify*>(
1748 360 : i_rFrames.front()->GetRegisteredIn()));
1749 360 : i_rFrames.pop_front();
1750 : // the format should be valid here, otherwise the client
1751 : // would have been removed in ::Modify
1752 : // check for a shape first
1753 360 : SwDrawContact* const pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement( *pFormat );
1754 360 : if (pContact)
1755 : {
1756 10 : SdrObject * const pSdr = pContact->GetMaster();
1757 10 : if (pSdr)
1758 : {
1759 10 : o_rNextObject.set(pSdr->getUnoShape(), uno::UNO_QUERY);
1760 : }
1761 : }
1762 : else
1763 : {
1764 350 : const SwNodeIndex* pIdx = pFormat->GetCntnt().GetCntntIdx();
1765 : OSL_ENSURE(pIdx, "where is the index?");
1766 : SwNode const*const pNd =
1767 350 : i_rUnoCrsr.GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ];
1768 :
1769 350 : if (!pNd->IsNoTxtNode())
1770 : {
1771 : o_rNextObject.set(SwXTextFrame::CreateXTextFrame(
1772 102 : *pFormat->GetDoc(), pFormat));
1773 : }
1774 248 : else if (pNd->IsGrfNode())
1775 : {
1776 : o_rNextObject.set(SwXTextGraphicObject::CreateXTextGraphicObject(
1777 2 : *pFormat->GetDoc(), pFormat));
1778 : }
1779 : else
1780 : {
1781 : assert(pNd->IsOLENode());
1782 : o_rNextObject.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
1783 246 : *pFormat->GetDoc(), pFormat));
1784 : }
1785 : }
1786 :
1787 360 : return o_rNextObject.is();
1788 : }
1789 :
1790 : // Search for a FLYCNT text attribute at the cursor point and fill the frame
1791 : // into the array
1792 : static void
1793 270 : lcl_FillFrame(SwClient & rEnum, SwUnoCrsr& rUnoCrsr,
1794 : FrameDependList_t & rFrames)
1795 : {
1796 : // search for objects at the cursor - anchored at/as char
1797 270 : SwTxtAttr const*const pTxtAttr = (rUnoCrsr.GetNode().IsTxtNode())
1798 270 : ? rUnoCrsr.GetNode().GetTxtNode()->GetTxtAttrForCharAt(
1799 540 : rUnoCrsr.GetPoint()->nContent.GetIndex(), RES_TXTATR_FLYCNT)
1800 540 : : 0;
1801 270 : if (pTxtAttr)
1802 : {
1803 266 : const SwFmtFlyCnt& rFlyCnt = pTxtAttr->GetFlyCnt();
1804 266 : SwFrmFmt * const pFrmFmt = rFlyCnt.GetFrmFmt();
1805 266 : SwDepend * const pNewDepend = new SwDepend(&rEnum, pFrmFmt);
1806 266 : rFrames.push_back( ::boost::shared_ptr<SwDepend>(pNewDepend) );
1807 : }
1808 270 : }
1809 :
1810 732 : SwXParaFrameEnumeration::SwXParaFrameEnumeration(
1811 : const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode,
1812 : SwFrmFmt *const pFmt)
1813 732 : : m_pImpl( new SwXParaFrameEnumeration::Impl(rPaM) )
1814 : {
1815 732 : if (PARAFRAME_PORTION_PARAGRAPH == eParaFrameMode)
1816 : {
1817 412 : FrameDependSortList_t frames;
1818 824 : ::CollectFrameAtNode(*m_pImpl.get(), rPaM.GetPoint()->nNode,
1819 824 : frames, false);
1820 : ::std::transform(frames.begin(), frames.end(),
1821 412 : ::std::back_inserter(m_pImpl->m_Frames),
1822 824 : ::boost::bind(&FrameDependSortListEntry::pFrameDepend, _1));
1823 : }
1824 320 : else if (pFmt)
1825 : {
1826 : // create SwDepend for frame and insert into array
1827 50 : SwDepend *const pNewDepend = new SwDepend(m_pImpl.get(), pFmt);
1828 50 : m_pImpl->m_Frames.push_back(::boost::shared_ptr<SwDepend>(pNewDepend));
1829 : }
1830 270 : else if ((PARAFRAME_PORTION_CHAR == eParaFrameMode) ||
1831 : (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode))
1832 : {
1833 270 : if (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode)
1834 : {
1835 : //get all frames that are bound at paragraph or at character
1836 4 : SwPosFlyFrms aFlyFrms(rPaM.GetDoc()->GetAllFlyFmts(m_pImpl->GetCursor(), false, true));
1837 :
1838 4 : for(SwPosFlyFrms::const_iterator aIter(aFlyFrms.begin()); aIter != aFlyFrms.end(); ++aIter)
1839 : {
1840 0 : SwFrmFmt *const pFrmFmt = const_cast<SwFrmFmt*>(&((*aIter)->GetFmt()));
1841 :
1842 : // create SwDepend for frame and insert into array
1843 0 : SwDepend *const pNewDepend = new SwDepend(m_pImpl.get(), pFrmFmt);
1844 0 : m_pImpl->m_Frames.push_back(::boost::shared_ptr<SwDepend>(pNewDepend));
1845 4 : }
1846 : }
1847 :
1848 270 : lcl_FillFrame(*m_pImpl.get(), *m_pImpl->GetCursor(), m_pImpl->m_Frames);
1849 : }
1850 732 : }
1851 :
1852 1464 : SwXParaFrameEnumeration::~SwXParaFrameEnumeration()
1853 : {
1854 1464 : }
1855 :
1856 : sal_Bool SAL_CALL
1857 648 : SwXParaFrameEnumeration::hasMoreElements() throw (uno::RuntimeException, std::exception)
1858 : {
1859 648 : SolarMutexGuard aGuard;
1860 :
1861 648 : if (!m_pImpl->GetCursor())
1862 0 : throw uno::RuntimeException();
1863 :
1864 648 : return (m_pImpl->m_xNextObject.is())
1865 : ? sal_True
1866 632 : : lcl_CreateNextObject(*m_pImpl->GetCursor(),
1867 1280 : m_pImpl->m_xNextObject, m_pImpl->m_Frames);
1868 : }
1869 :
1870 360 : uno::Any SAL_CALL SwXParaFrameEnumeration::nextElement()
1871 : throw (container::NoSuchElementException,
1872 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
1873 : {
1874 360 : SolarMutexGuard aGuard;
1875 :
1876 360 : if (!m_pImpl->GetCursor())
1877 : {
1878 0 : throw uno::RuntimeException();
1879 : }
1880 :
1881 360 : if (!m_pImpl->m_xNextObject.is() && m_pImpl->m_Frames.size())
1882 : {
1883 228 : lcl_CreateNextObject(*m_pImpl->GetCursor(),
1884 456 : m_pImpl->m_xNextObject, m_pImpl->m_Frames);
1885 : }
1886 360 : if (!m_pImpl->m_xNextObject.is())
1887 : {
1888 0 : throw container::NoSuchElementException();
1889 : }
1890 360 : uno::Any aRet;
1891 360 : aRet <<= m_pImpl->m_xNextObject;
1892 360 : m_pImpl->m_xNextObject = 0;
1893 360 : return aRet;
1894 : }
1895 :
1896 : OUString SAL_CALL
1897 0 : SwXParaFrameEnumeration::getImplementationName() throw (uno::RuntimeException, std::exception)
1898 : {
1899 0 : return OUString("SwXParaFrameEnumeration");
1900 : }
1901 :
1902 : static char const*const g_ServicesParaFrameEnum[] =
1903 : {
1904 : "com.sun.star.util.ContentEnumeration",
1905 : };
1906 :
1907 : static const size_t g_nServicesParaFrameEnum(
1908 : sizeof(g_ServicesParaFrameEnum)/sizeof(g_ServicesParaFrameEnum[0]));
1909 :
1910 : sal_Bool SAL_CALL
1911 0 : SwXParaFrameEnumeration::supportsService(const OUString& rServiceName)
1912 : throw (uno::RuntimeException, std::exception)
1913 : {
1914 0 : return cppu::supportsService(this, rServiceName);
1915 : }
1916 :
1917 : uno::Sequence< OUString > SAL_CALL
1918 0 : SwXParaFrameEnumeration::getSupportedServiceNames()
1919 : throw (uno::RuntimeException, std::exception)
1920 : {
1921 : return ::sw::GetSupportedServiceNamesImpl(
1922 0 : g_nServicesParaFrameEnum, g_ServicesParaFrameEnum);
1923 270 : }
1924 :
1925 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|