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