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