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