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