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 throw (container::NoSuchElementException, lang::WrappedTargetException,
519 uno::RuntimeException);
520 protected:
521 // SwClient
522 virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew);
523
524 };
525
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)526 void SwXParagraphEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
527 {
528 ClientModify(this, pOld, pNew);
529 }
530
SwXParagraphEnumeration(uno::Reference<text::XText> const & xParent,::std::auto_ptr<SwUnoCrsr> pCursor,const CursorType eType,SwStartNode const * const pStartNode,SwTable const * const pTable)531 SwXParagraphEnumeration::SwXParagraphEnumeration(
532 uno::Reference< text::XText > const& xParent,
533 ::std::auto_ptr<SwUnoCrsr> pCursor,
534 const CursorType eType,
535 SwStartNode const*const pStartNode, SwTable const*const pTable)
536 : m_pImpl( new SwXParagraphEnumeration::Impl(xParent, pCursor, eType,
537 pStartNode, pTable) )
538 {
539 }
540
~SwXParagraphEnumeration()541 SwXParagraphEnumeration::~SwXParagraphEnumeration()
542 {
543 }
544
545 OUString SAL_CALL
getImplementationName()546 SwXParagraphEnumeration::getImplementationName() throw (uno::RuntimeException)
547 {
548 return C2U("SwXParagraphEnumeration");
549 }
550
551 static char const*const g_ServicesParagraphEnum[] =
552 {
553 "com.sun.star.text.ParagraphEnumeration",
554 };
555 static const size_t g_nServicesParagraphEnum(
556 sizeof(g_ServicesParagraphEnum)/sizeof(g_ServicesParagraphEnum[0]));
557
558 sal_Bool SAL_CALL
supportsService(const OUString & rServiceName)559 SwXParagraphEnumeration::supportsService(const OUString& rServiceName)
560 throw (uno::RuntimeException)
561 {
562 return ::sw::SupportsServiceImpl(
563 g_nServicesParagraphEnum, g_ServicesParagraphEnum, rServiceName);
564 }
565
566 uno::Sequence< OUString > SAL_CALL
getSupportedServiceNames()567 SwXParagraphEnumeration::getSupportedServiceNames()
568 throw (uno::RuntimeException)
569 {
570 return ::sw::GetSupportedServiceNamesImpl(
571 g_nServicesParagraphEnum, g_ServicesParagraphEnum);
572 }
573
574 sal_Bool SAL_CALL
hasMoreElements()575 SwXParagraphEnumeration::hasMoreElements() throw (uno::RuntimeException)
576 {
577 vos::OGuard aGuard(Application::GetSolarMutex());
578
579 return (m_pImpl->m_bFirstParagraph) ? sal_True : m_pImpl->m_xNextPara.is();
580 }
581
582 //!! compare to SwShellTableCrsr::FillRects() in viscrs.cxx
583 static SwTableNode *
lcl_FindTopLevelTable(SwTableNode * const pTblNode,SwTable const * const pOwnTable)584 lcl_FindTopLevelTable(
585 SwTableNode *const pTblNode, SwTable const*const pOwnTable)
586 {
587 // find top-most table in current context (section) level
588
589 SwTableNode * pLast = pTblNode;
590 for (SwTableNode* pTmp = pLast;
591 pTmp != NULL && &pTmp->GetTable() != pOwnTable; /* we must not go up higher than the own table! */
592 pTmp = pTmp->StartOfSectionNode()->FindTableNode() )
593 {
594 pLast = pTmp;
595 }
596 return pLast;
597 }
598
599
600 static bool
lcl_CursorIsInSection(SwUnoCrsr const * const pUnoCrsr,SwStartNode const * const pOwnStartNode)601 lcl_CursorIsInSection(
602 SwUnoCrsr const*const pUnoCrsr, SwStartNode const*const pOwnStartNode)
603 {
604 // returns true if the cursor is in the section (or in a sub section!)
605 // represented by pOwnStartNode
606
607 bool bRes = true;
608 if (pUnoCrsr && pOwnStartNode)
609 {
610 const SwEndNode * pOwnEndNode = pOwnStartNode->EndOfSectionNode();
611 bRes = pOwnStartNode->GetIndex() <= pUnoCrsr->Start()->nNode.GetIndex() &&
612 pUnoCrsr->End()->nNode.GetIndex() <= pOwnEndNode->GetIndex();
613 }
614 return bRes;
615 }
616
617
618 uno::Reference< text::XTextContent >
NextElement_Impl()619 SwXParagraphEnumeration::Impl::NextElement_Impl()
620 throw (container::NoSuchElementException, lang::WrappedTargetException,
621 uno::RuntimeException)
622 {
623 SwUnoCrsr *const pUnoCrsr = GetCursor();
624 if (!pUnoCrsr)
625 {
626 throw uno::RuntimeException();
627 }
628
629 // check for exceeding selections
630 if (!m_bFirstParagraph &&
631 ((CURSOR_SELECTION == m_eCursorType) ||
632 (CURSOR_SELECTION_IN_TABLE == m_eCursorType)))
633 {
634 SwPosition* pStart = pUnoCrsr->Start();
635 const ::std::auto_ptr<SwUnoCrsr> aNewCrsr(
636 pUnoCrsr->GetDoc()->CreateUnoCrsr(*pStart, sal_False) );
637 // one may also go into tables here
638 if ((CURSOR_TBLTEXT != m_eCursorType) &&
639 (CURSOR_SELECTION_IN_TABLE != m_eCursorType))
640 {
641 aNewCrsr->SetRemainInSection( sal_False );
642 }
643
644 // os 2005-01-14: This part is only necessary to detect movements out
645 // of a selection; if there is no selection we don't have to care
646 SwTableNode *const pTblNode = aNewCrsr->GetNode()->FindTableNode();
647 if (((CURSOR_TBLTEXT != m_eCursorType) &&
648 (CURSOR_SELECTION_IN_TABLE != m_eCursorType)) && pTblNode)
649 {
650 aNewCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex();
651 aNewCrsr->Move(fnMoveForward, fnGoNode);
652 }
653 else
654 {
655 aNewCrsr->MovePara(fnParaNext, fnParaStart);
656 }
657 if (m_nEndIndex < aNewCrsr->Start()->nNode.GetIndex())
658 {
659 return 0;
660 }
661 }
662
663 sal_Bool bInTable = sal_False;
664 if (!m_bFirstParagraph)
665 {
666 pUnoCrsr->SetRemainInSection( sal_False );
667 // what to do if already in a table?
668 SwTableNode * pTblNode = pUnoCrsr->GetNode()->FindTableNode();
669 pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable );
670 if (pTblNode && (&pTblNode->GetTable() != m_pOwnTable))
671 {
672 // this is a foreign table: go to end
673 pUnoCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex();
674 if (!pUnoCrsr->Move(fnMoveForward, fnGoNode))
675 {
676 return 0;
677 }
678 bInTable = sal_True;
679 }
680 }
681
682 uno::Reference< text::XTextContent > xRef;
683 // the cursor must remain in the current section or a subsection
684 // before AND after the movement...
685 if (lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ) &&
686 (m_bFirstParagraph || bInTable ||
687 (pUnoCrsr->MovePara(fnParaNext, fnParaStart) &&
688 lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ))))
689 {
690 SwPosition* pStart = pUnoCrsr->Start();
691 const sal_Int32 nFirstContent =
692 (m_bFirstParagraph) ? m_nFirstParaStart : -1;
693 const sal_Int32 nLastContent =
694 (m_nEndIndex == pStart->nNode.GetIndex()) ? m_nLastParaEnd : -1;
695
696 // position in a table, or in a simple paragraph?
697 SwTableNode * pTblNode = pUnoCrsr->GetNode()->FindTableNode();
698 pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable );
699 if (/*CURSOR_TBLTEXT != eCursorType && CURSOR_SELECTION_IN_TABLE != eCursorType && */
700 pTblNode && (&pTblNode->GetTable() != m_pOwnTable))
701 {
702 // this is a foreign table
703 SwFrmFmt* pTableFmt =
704 static_cast<SwFrmFmt*>(pTblNode->GetTable().GetFrmFmt());
705 text::XTextTable *const pTable =
706 SwXTextTables::GetObject( *pTableFmt );
707 xRef = static_cast<text::XTextContent*>(
708 static_cast<SwXTextTable*>(pTable));
709 }
710 else
711 {
712 text::XText *const pText = m_xParentText.get();
713 xRef = SwXParagraph::CreateXParagraph(*pUnoCrsr->GetDoc(),
714 *pStart->nNode.GetNode().GetTxtNode(),
715 static_cast<SwXText*>(pText), nFirstContent, nLastContent);
716 }
717 }
718
719 return xRef;
720 }
721
nextElement()722 uno::Any SAL_CALL SwXParagraphEnumeration::nextElement()
723 throw (container::NoSuchElementException, lang::WrappedTargetException,
724 uno::RuntimeException)
725 {
726 vos::OGuard aGuard(Application::GetSolarMutex());
727
728 if (m_pImpl->m_bFirstParagraph)
729 {
730 m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl();
731 m_pImpl->m_bFirstParagraph = false;
732 }
733 const uno::Reference< text::XTextContent > xRef = m_pImpl->m_xNextPara;
734 if (!xRef.is())
735 {
736 throw container::NoSuchElementException();
737 }
738 m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl();
739
740 uno::Any aRet;
741 aRet <<= xRef;
742 return aRet;
743 }
744
745 /******************************************************************
746 * SwXTextRange
747 ******************************************************************/
748
749 class SwXTextRange::Impl
750 : public SwClient
751 {
752
753 public:
754
755 const SfxItemPropertySet & m_rPropSet;
756 const enum RangePosition m_eRangePosition;
757 SwDoc & m_rDoc;
758 uno::Reference<text::XText> m_xParentText;
759 SwDepend m_ObjectDepend; // register at format of table or frame
760 ::sw::mark::IMark * m_pMark;
761
Impl(SwDoc & rDoc,const enum RangePosition eRange,SwFrmFmt * const pTblFmt=0,const uno::Reference<text::XText> & xParent=0)762 Impl( SwDoc & rDoc, const enum RangePosition eRange,
763 SwFrmFmt *const pTblFmt = 0,
764 const uno::Reference< text::XText > & xParent = 0)
765 : SwClient()
766 , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
767 , m_eRangePosition(eRange)
768 , m_rDoc(rDoc)
769 , m_xParentText(xParent)
770 , m_ObjectDepend(this, pTblFmt)
771 , m_pMark(0)
772 {
773 }
774
~Impl()775 ~Impl()
776 {
777 // Impl owns the bookmark; delete it here: SolarMutex is locked
778 Invalidate();
779 }
780
Invalidate()781 void Invalidate()
782 {
783 if (m_pMark)
784 {
785 m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark);
786 m_pMark = 0;
787 }
788 }
789
GetBookmark() const790 const ::sw::mark::IMark * GetBookmark() const { return m_pMark; }
791 protected:
792 // SwClient
793 virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew);
794
795 };
796
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)797 void SwXTextRange::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
798 {
799 const bool bAlreadyRegistered = 0 != GetRegisteredIn();
800 ClientModify(this, pOld, pNew);
801 if (m_ObjectDepend.GetRegisteredIn())
802 {
803 ClientModify(&m_ObjectDepend, pOld, pNew);
804 // if the depend was removed then the range must be removed too
805 if (!m_ObjectDepend.GetRegisteredIn() && GetRegisteredIn())
806 {
807 const_cast<SwModify*>(GetRegisteredIn())->Remove(this);
808 }
809 // or if the range has been removed but the depend ist still
810 // connected then the depend must be removed
811 else if (bAlreadyRegistered && !GetRegisteredIn() &&
812 m_ObjectDepend.GetRegisteredIn())
813 {
814 const_cast<SwModify*>(m_ObjectDepend.GetRegisteredIn())
815 ->Remove(& m_ObjectDepend);
816 }
817 }
818 if (!GetRegisteredIn())
819 {
820 m_pMark = 0;
821 }
822 }
823
824
SwXTextRange(SwPaM & rPam,const uno::Reference<text::XText> & xParent,const enum RangePosition eRange)825 SwXTextRange::SwXTextRange(SwPaM& rPam,
826 const uno::Reference< text::XText > & xParent,
827 const enum RangePosition eRange)
828 : m_pImpl( new SwXTextRange::Impl(*rPam.GetDoc(), eRange, 0, xParent) )
829 {
830 SetPositions(rPam);
831 }
832
SwXTextRange(SwFrmFmt & rTblFmt)833 SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt)
834 : m_pImpl(
835 new SwXTextRange::Impl(*rTblFmt.GetDoc(), RANGE_IS_TABLE, &rTblFmt) )
836 {
837 SwTable *const pTable = SwTable::FindTable( &rTblFmt );
838 SwTableNode *const pTblNode = pTable->GetTableNode();
839 SwPosition aPosition( *pTblNode );
840 SwPaM aPam( aPosition );
841
842 SetPositions( aPam );
843 }
844
~SwXTextRange()845 SwXTextRange::~SwXTextRange()
846 {
847 }
848
GetDoc() const849 const SwDoc * SwXTextRange::GetDoc() const
850 {
851 return & m_pImpl->m_rDoc;
852 }
853
GetDoc()854 SwDoc * SwXTextRange::GetDoc()
855 {
856 return & m_pImpl->m_rDoc;
857 }
858
859
Invalidate()860 void SwXTextRange::Invalidate()
861 {
862 m_pImpl->Invalidate();
863 }
864
SetPositions(const SwPaM & rPam)865 void SwXTextRange::SetPositions(const SwPaM& rPam)
866 {
867 m_pImpl->Invalidate();
868 IDocumentMarkAccess* const pMA = m_pImpl->m_rDoc.getIDocumentMarkAccess();
869 m_pImpl->m_pMark = pMA->makeMark(rPam, ::rtl::OUString(),
870 IDocumentMarkAccess::UNO_BOOKMARK);
871 m_pImpl->m_pMark->Add(m_pImpl.get());
872 }
873
DeleteAndInsert(const::rtl::OUString & rText,const bool bForceExpandHints)874 void SwXTextRange::DeleteAndInsert(
875 const ::rtl::OUString& rText, const bool bForceExpandHints)
876 throw (uno::RuntimeException)
877 {
878 if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
879 {
880 // setString on table not allowed
881 throw uno::RuntimeException();
882 }
883
884 const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
885 SwCursor aCursor(aPos, 0, false);
886 if (GetPositions(aCursor))
887 {
888 UnoActionContext aAction(& m_pImpl->m_rDoc);
889 m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
890 if (aCursor.HasMark())
891 {
892 m_pImpl->m_rDoc.DeleteAndJoin(aCursor);
893 }
894
895 if (rText.getLength())
896 {
897 SwUnoCursorHelper::DocInsertStringSplitCR(
898 m_pImpl->m_rDoc, aCursor, rText, bForceExpandHints);
899
900 SwUnoCursorHelper::SelectPam(aCursor, true);
901 aCursor.Left(rText.getLength(), CRSR_SKIP_CHARS, sal_False, sal_False);
902 }
903 SetPositions(aCursor);
904 m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
905 }
906 }
907
getUnoTunnelId()908 const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId()
909 {
910 static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
911 return aSeq;
912 }
913
914 // XUnoTunnel
915 sal_Int64 SAL_CALL
getSomething(const uno::Sequence<sal_Int8> & rId)916 SwXTextRange::getSomething(const uno::Sequence< sal_Int8 >& rId)
917 throw (uno::RuntimeException)
918 {
919 return ::sw::UnoTunnelImpl<SwXTextRange>(rId, this);
920 }
921
922 OUString SAL_CALL
getImplementationName()923 SwXTextRange::getImplementationName() throw (uno::RuntimeException)
924 {
925 return OUString::createFromAscii("SwXTextRange");
926 }
927
928 static char const*const g_ServicesTextRange[] =
929 {
930 "com.sun.star.text.TextRange",
931 "com.sun.star.style.CharacterProperties",
932 "com.sun.star.style.CharacterPropertiesAsian",
933 "com.sun.star.style.CharacterPropertiesComplex",
934 "com.sun.star.style.ParagraphProperties",
935 "com.sun.star.style.ParagraphPropertiesAsian",
936 "com.sun.star.style.ParagraphPropertiesComplex",
937 };
938 static const size_t g_nServicesTextRange(
939 sizeof(g_ServicesTextRange)/sizeof(g_ServicesTextRange[0]));
940
supportsService(const OUString & rServiceName)941 sal_Bool SAL_CALL SwXTextRange::supportsService(const OUString& rServiceName)
942 throw (uno::RuntimeException)
943 {
944 return ::sw::SupportsServiceImpl(
945 g_nServicesTextRange, g_ServicesTextRange, rServiceName);
946 }
947
948 uno::Sequence< OUString > SAL_CALL
getSupportedServiceNames()949 SwXTextRange::getSupportedServiceNames() throw (uno::RuntimeException)
950 {
951 return ::sw::GetSupportedServiceNamesImpl(
952 g_nServicesTextRange, g_ServicesTextRange);
953 }
954
955 uno::Reference< text::XText > SAL_CALL
getText()956 SwXTextRange::getText() throw (uno::RuntimeException)
957 {
958 vos::OGuard aGuard(Application::GetSolarMutex());
959
960 if (!m_pImpl->m_xParentText.is())
961 {
962 if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE &&
963 m_pImpl->m_ObjectDepend.GetRegisteredIn())
964 {
965 SwFrmFmt const*const pTblFmt = static_cast<SwFrmFmt const*>(
966 m_pImpl->m_ObjectDepend.GetRegisteredIn());
967 SwTable const*const pTable = SwTable::FindTable( pTblFmt );
968 SwTableNode const*const pTblNode = pTable->GetTableNode();
969 const SwPosition aPosition( *pTblNode );
970 m_pImpl->m_xParentText =
971 ::sw::CreateParentXText(m_pImpl->m_rDoc, aPosition);
972 }
973 }
974 OSL_ENSURE(m_pImpl->m_xParentText.is(), "SwXTextRange::getText: no text");
975 return m_pImpl->m_xParentText;
976 }
977
978 uno::Reference< text::XTextRange > SAL_CALL
getStart()979 SwXTextRange::getStart() throw (uno::RuntimeException)
980 {
981 vos::OGuard aGuard(Application::GetSolarMutex());
982
983 uno::Reference< text::XTextRange > xRet;
984 ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
985 if (!m_pImpl->m_xParentText.is())
986 {
987 getText();
988 }
989 if(pBkmk)
990 {
991 SwPaM aPam(pBkmk->GetMarkStart());
992 xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
993 }
994 else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
995 {
996 // start and end are this, if its a table
997 xRet = this;
998 }
999 else
1000 {
1001 throw uno::RuntimeException();
1002 }
1003 return xRet;
1004 }
1005
1006 uno::Reference< text::XTextRange > SAL_CALL
getEnd()1007 SwXTextRange::getEnd() throw (uno::RuntimeException)
1008 {
1009 vos::OGuard aGuard(Application::GetSolarMutex());
1010
1011 uno::Reference< text::XTextRange > xRet;
1012 ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
1013 if (!m_pImpl->m_xParentText.is())
1014 {
1015 getText();
1016 }
1017 if(pBkmk)
1018 {
1019 SwPaM aPam(pBkmk->GetMarkEnd());
1020 xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText);
1021 }
1022 else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition)
1023 {
1024 // start and end are this, if its a table
1025 xRet = this;
1026 }
1027 else
1028 {
1029 throw uno::RuntimeException();
1030 }
1031 return xRet;
1032 }
1033
getString()1034 OUString SAL_CALL SwXTextRange::getString() throw (uno::RuntimeException)
1035 {
1036 vos::OGuard aGuard(Application::GetSolarMutex());
1037
1038 OUString sRet;
1039 // for tables there is no bookmark, thus also no text
1040 // one could export the table as ASCII here maybe?
1041 SwPaM aPaM(GetDoc()->GetNodes());
1042 if (GetPositions(aPaM) && aPaM.HasMark())
1043 {
1044 SwUnoCursorHelper::GetTextFromPam(aPaM, sRet);
1045 }
1046 return sRet;
1047 }
1048
setString(const OUString & rString)1049 void SAL_CALL SwXTextRange::setString(const OUString& rString)
1050 throw (uno::RuntimeException)
1051 {
1052 vos::OGuard aGuard(Application::GetSolarMutex());
1053
1054 DeleteAndInsert(rString, false);
1055 }
1056
GetPositions(SwPaM & rToFill) const1057 bool SwXTextRange::GetPositions(SwPaM& rToFill) const
1058 {
1059 ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
1060 if(pBkmk)
1061 {
1062 *rToFill.GetPoint() = pBkmk->GetMarkPos();
1063 if(pBkmk->IsExpanded())
1064 {
1065 rToFill.SetMark();
1066 *rToFill.GetMark() = pBkmk->GetOtherMarkPos();
1067 }
1068 else
1069 {
1070 rToFill.DeleteMark();
1071 }
1072 return true;
1073 }
1074 return false;
1075 }
1076
1077 namespace sw {
1078
XTextRangeToSwPaM(SwUnoInternalPaM & rToFill,const uno::Reference<text::XTextRange> & xTextRange)1079 bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
1080 const uno::Reference< text::XTextRange > & xTextRange)
1081 {
1082 bool bRet = false;
1083
1084 uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
1085 SwXTextRange* pRange = 0;
1086 OTextCursorHelper* pCursor = 0;
1087 SwXTextPortion* pPortion = 0;
1088 SwXText* pText = 0;
1089 SwXParagraph* pPara = 0;
1090 if(xRangeTunnel.is())
1091 {
1092 pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
1093 pCursor =
1094 ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
1095 pPortion=
1096 ::sw::UnoTunnelGetImplementation<SwXTextPortion>(xRangeTunnel);
1097 pText = ::sw::UnoTunnelGetImplementation<SwXText>(xRangeTunnel);
1098 pPara = ::sw::UnoTunnelGetImplementation<SwXParagraph>(xRangeTunnel);
1099 }
1100
1101 // if it's a text then create a temporary cursor there and re-use
1102 // the pCursor variable
1103 // #i108489#: Reference in outside scope to keep cursor alive
1104 uno::Reference< text::XTextCursor > xTextCursor;
1105 if (pText)
1106 {
1107 xTextCursor.set( pText->CreateCursor() );
1108 xTextCursor->gotoEnd(sal_True);
1109 const uno::Reference<lang::XUnoTunnel> xCrsrTunnel(
1110 xTextCursor, uno::UNO_QUERY);
1111 pCursor =
1112 ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCrsrTunnel);
1113 }
1114 if(pRange && pRange->GetDoc() == rToFill.GetDoc())
1115 {
1116 bRet = pRange->GetPositions(rToFill);
1117 }
1118 else
1119 {
1120 if (pPara)
1121 {
1122 bRet = pPara->SelectPaM(rToFill);
1123 }
1124 else
1125 {
1126 SwDoc* const pDoc = (pCursor) ? pCursor->GetDoc()
1127 : ((pPortion) ? pPortion->GetCursor()->GetDoc() : 0);
1128 const SwPaM* const pUnoCrsr = (pCursor) ? pCursor->GetPaM()
1129 : ((pPortion) ? pPortion->GetCursor() : 0);
1130 if (pUnoCrsr && pDoc == rToFill.GetDoc())
1131 {
1132 DBG_ASSERT((SwPaM*)pUnoCrsr->GetNext() == pUnoCrsr,
1133 "what to do about rings?");
1134 bRet = true;
1135 *rToFill.GetPoint() = *pUnoCrsr->GetPoint();
1136 if (pUnoCrsr->HasMark())
1137 {
1138 rToFill.SetMark();
1139 *rToFill.GetMark() = *pUnoCrsr->GetMark();
1140 }
1141 else
1142 rToFill.DeleteMark();
1143 }
1144 }
1145 }
1146 return bRet;
1147 }
1148
1149 static bool
lcl_IsStartNodeInFormat(const bool bHeader,SwStartNode * const pSttNode,SwFrmFmt const * const pFrmFmt,SwFrmFmt * & rpFormat)1150 lcl_IsStartNodeInFormat(const bool bHeader, SwStartNode *const pSttNode,
1151 SwFrmFmt const*const pFrmFmt, SwFrmFmt*& rpFormat)
1152 {
1153 bool bRet = false;
1154 const SfxItemSet& rSet = pFrmFmt->GetAttrSet();
1155 const SfxPoolItem* pItem;
1156 if (SFX_ITEM_SET == rSet.GetItemState(
1157 static_cast<sal_uInt16>(bHeader ? RES_HEADER : RES_FOOTER),
1158 sal_True, &pItem))
1159 {
1160 SfxPoolItem *const pItemNonConst(const_cast<SfxPoolItem *>(pItem));
1161 SwFrmFmt *const pHeadFootFmt = (bHeader) ?
1162 static_cast<SwFmtHeader*>(pItemNonConst)->GetHeaderFmt() :
1163 static_cast<SwFmtFooter*>(pItemNonConst)->GetFooterFmt();
1164 if (pHeadFootFmt)
1165 {
1166 const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
1167 const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
1168 SwStartNode const*const pCurSttNode = rNode.FindSttNodeByType(
1169 (bHeader) ? SwHeaderStartNode : SwFooterStartNode);
1170 if (pCurSttNode && (pCurSttNode == pSttNode))
1171 {
1172 rpFormat = pHeadFootFmt;
1173 bRet = true;
1174 }
1175 }
1176 }
1177 return bRet;
1178 }
1179
1180 } // namespace sw
1181
1182 uno::Reference< text::XTextRange >
CreateXTextRange(SwDoc & rDoc,const SwPosition & rPos,const SwPosition * const pMark)1183 SwXTextRange::CreateXTextRange(
1184 SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark)
1185 {
1186 const uno::Reference<text::XText> xParentText(
1187 ::sw::CreateParentXText(rDoc, rPos));
1188 const ::std::auto_ptr<SwUnoCrsr> pNewCrsr(
1189 rDoc.CreateUnoCrsr(rPos, sal_False));
1190 if(pMark)
1191 {
1192 pNewCrsr->SetMark();
1193 *pNewCrsr->GetMark() = *pMark;
1194 }
1195 const bool isCell( dynamic_cast<SwXCell*>(xParentText.get()) );
1196 const uno::Reference< text::XTextRange > xRet(
1197 new SwXTextRange(*pNewCrsr, xParentText,
1198 isCell ? RANGE_IN_CELL : RANGE_IN_TEXT) );
1199 return xRet;
1200 }
1201
1202 namespace sw {
1203
1204 uno::Reference< text::XText >
CreateParentXText(SwDoc & rDoc,const SwPosition & rPos)1205 CreateParentXText(SwDoc & rDoc, const SwPosition& rPos)
1206 {
1207 uno::Reference< text::XText > xParentText;
1208 SwStartNode* pSttNode = rPos.nNode.GetNode().StartOfSectionNode();
1209 while(pSttNode && pSttNode->IsSectionNode())
1210 {
1211 pSttNode = pSttNode->StartOfSectionNode();
1212 }
1213 SwStartNodeType eType = pSttNode->GetStartNodeType();
1214 switch(eType)
1215 {
1216 case SwTableBoxStartNode:
1217 {
1218 SwTableNode const*const pTblNode = pSttNode->FindTableNode();
1219 SwFrmFmt *const pTableFmt =
1220 static_cast<SwFrmFmt*>(pTblNode->GetTable().GetFrmFmt());
1221 SwTableBox *const pBox = pSttNode->GetTblBox();
1222
1223 xParentText = (pBox)
1224 ? SwXCell::CreateXCell( pTableFmt, pBox )
1225 : new SwXCell( pTableFmt, *pSttNode );
1226 }
1227 break;
1228 case SwFlyStartNode:
1229 {
1230 SwFrmFmt *const pFmt = pSttNode->GetFlyFmt();
1231 if (0 != pFmt)
1232 {
1233 SwXTextFrame* pFrame = SwIterator<SwXTextFrame,SwFmt>::FirstElement( *pFmt );
1234 xParentText = pFrame ? pFrame : new SwXTextFrame( *pFmt );
1235 }
1236 }
1237 break;
1238 case SwHeaderStartNode:
1239 case SwFooterStartNode:
1240 {
1241 const bool bHeader = (SwHeaderStartNode == eType);
1242 const sal_uInt16 nPDescCount = rDoc.GetPageDescCnt();
1243 for(sal_uInt16 i = 0; i < nPDescCount; i++)
1244 {
1245 const SwPageDesc& rDesc =
1246 // C++ is retarded
1247 const_cast<SwDoc const&>(rDoc).GetPageDesc( i );
1248 const SwFrmFmt* pFrmFmtMaster = &rDesc.GetMaster();
1249 const SwFrmFmt* pFrmFmtLeft = &rDesc.GetLeft();
1250
1251 SwFrmFmt* pHeadFootFmt = 0;
1252 if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtMaster,
1253 pHeadFootFmt))
1254 {
1255 lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtLeft,
1256 pHeadFootFmt);
1257 }
1258
1259 if (pHeadFootFmt)
1260 {
1261 xParentText = SwXHeadFootText::CreateXHeadFootText(
1262 *pHeadFootFmt, bHeader);
1263 }
1264 }
1265 }
1266 break;
1267 case SwFootnoteStartNode:
1268 {
1269 const sal_uInt16 nFtnCnt = rDoc.GetFtnIdxs().Count();
1270 uno::Reference< text::XFootnote > xRef;
1271 for (sal_uInt16 n = 0; n < nFtnCnt; ++n )
1272 {
1273 const SwTxtFtn* pTxtFtn = rDoc.GetFtnIdxs()[ n ];
1274 const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
1275 pTxtFtn = rFtn.GetTxtFtn();
1276 #if OSL_DEBUG_LEVEL > 1
1277 const SwStartNode* pTmpSttNode =
1278 pTxtFtn->GetStartNode()->GetNode().
1279 FindSttNodeByType(SwFootnoteStartNode);
1280 (void)pTmpSttNode;
1281 #endif
1282
1283 if (pSttNode == pTxtFtn->GetStartNode()->GetNode().
1284 FindSttNodeByType(SwFootnoteStartNode))
1285 {
1286 xParentText = SwXFootnote::CreateXFootnote(rDoc, rFtn);
1287 break;
1288 }
1289 }
1290 }
1291 break;
1292 default:
1293 {
1294 // then it is the body text
1295 const uno::Reference<frame::XModel> xModel =
1296 rDoc.GetDocShell()->GetBaseModel();
1297 const uno::Reference< text::XTextDocument > xDoc(
1298 xModel, uno::UNO_QUERY);
1299 xParentText = xDoc->getText();
1300 }
1301 }
1302 OSL_ENSURE(xParentText.is(), "no parent text?");
1303 return xParentText;
1304 }
1305
1306 } // namespace sw
1307
1308 uno::Reference< container::XEnumeration > SAL_CALL
createContentEnumeration(const OUString & rServiceName)1309 SwXTextRange::createContentEnumeration(const OUString& rServiceName)
1310 throw (uno::RuntimeException)
1311 {
1312 vos::OGuard g(Application::GetSolarMutex());
1313
1314 if (!rServiceName.equalsAscii("com.sun.star.text.TextContent"))
1315 {
1316 throw uno::RuntimeException();
1317 }
1318
1319 if (!GetDoc() || !m_pImpl->GetBookmark())
1320 {
1321 throw uno::RuntimeException();
1322 }
1323 const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
1324 const ::std::auto_ptr<SwUnoCrsr> pNewCrsr(
1325 m_pImpl->m_rDoc.CreateUnoCrsr(aPos, sal_False));
1326 if (!GetPositions(*pNewCrsr))
1327 {
1328 throw uno::RuntimeException();
1329 }
1330
1331 const uno::Reference< container::XEnumeration > xRet =
1332 new SwXParaFrameEnumeration(*pNewCrsr, PARAFRAME_PORTION_TEXTRANGE);
1333 return xRet;
1334 }
1335
1336 uno::Reference< container::XEnumeration > SAL_CALL
createEnumeration()1337 SwXTextRange::createEnumeration() throw (uno::RuntimeException)
1338 {
1339 vos::OGuard g(Application::GetSolarMutex());
1340
1341 if (!GetDoc() || !m_pImpl->GetBookmark())
1342 {
1343 throw uno::RuntimeException();
1344 }
1345 const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent());
1346 ::std::auto_ptr<SwUnoCrsr> pNewCrsr(
1347 m_pImpl->m_rDoc.CreateUnoCrsr(aPos, sal_False));
1348 if (!GetPositions(*pNewCrsr))
1349 {
1350 throw uno::RuntimeException();
1351 }
1352 if (!m_pImpl->m_xParentText.is())
1353 {
1354 getText();
1355 }
1356
1357 const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition)
1358 ? CURSOR_SELECTION_IN_TABLE : CURSOR_SELECTION;
1359 const uno::Reference< container::XEnumeration > xRet =
1360 new SwXParagraphEnumeration(m_pImpl->m_xParentText, pNewCrsr, eSetType);
1361 return xRet;
1362 }
1363
getElementType()1364 uno::Type SAL_CALL SwXTextRange::getElementType() throw (uno::RuntimeException)
1365 {
1366 return text::XTextRange::static_type();
1367 }
1368
hasElements()1369 sal_Bool SAL_CALL SwXTextRange::hasElements() throw (uno::RuntimeException)
1370 {
1371 return sal_True;
1372 }
1373
1374 uno::Sequence< OUString > SAL_CALL
getAvailableServiceNames()1375 SwXTextRange::getAvailableServiceNames() throw (uno::RuntimeException)
1376 {
1377 uno::Sequence< OUString > aRet(1);
1378 OUString* pArray = aRet.getArray();
1379 pArray[0] = OUString::createFromAscii("com.sun.star.text.TextContent");
1380 return aRet;
1381 }
1382
1383 uno::Reference< beans::XPropertySetInfo > SAL_CALL
getPropertySetInfo()1384 SwXTextRange::getPropertySetInfo() throw (uno::RuntimeException)
1385 {
1386 vos::OGuard aGuard(Application::GetSolarMutex());
1387
1388 static uno::Reference< beans::XPropertySetInfo > xRef =
1389 m_pImpl->m_rPropSet.getPropertySetInfo();
1390 return xRef;
1391 }
1392
1393 void SAL_CALL
setPropertyValue(const OUString & rPropertyName,const uno::Any & rValue)1394 SwXTextRange::setPropertyValue(
1395 const OUString& rPropertyName, const uno::Any& rValue)
1396 throw (beans::UnknownPropertyException, beans::PropertyVetoException,
1397 lang::IllegalArgumentException, lang::WrappedTargetException,
1398 uno::RuntimeException)
1399 {
1400 vos::OGuard aGuard(Application::GetSolarMutex());
1401
1402 if (!GetDoc() || !m_pImpl->GetBookmark())
1403 {
1404 throw uno::RuntimeException();
1405 }
1406 SwPaM aPaM(GetDoc()->GetNodes());
1407 GetPositions(aPaM);
1408 SwUnoCursorHelper::SetPropertyValue(aPaM, m_pImpl->m_rPropSet,
1409 rPropertyName, rValue);
1410 }
1411
1412 uno::Any SAL_CALL
getPropertyValue(const OUString & rPropertyName)1413 SwXTextRange::getPropertyValue(const OUString& rPropertyName)
1414 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1415 uno::RuntimeException)
1416 {
1417 vos::OGuard aGuard(Application::GetSolarMutex());
1418
1419 if (!GetDoc() || !m_pImpl->GetBookmark())
1420 {
1421 throw uno::RuntimeException();
1422 }
1423 SwPaM aPaM(GetDoc()->GetNodes());
1424 GetPositions(aPaM);
1425 return SwUnoCursorHelper::GetPropertyValue(aPaM, m_pImpl->m_rPropSet,
1426 rPropertyName);
1427 }
1428
1429 void SAL_CALL
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1430 SwXTextRange::addPropertyChangeListener(
1431 const ::rtl::OUString& /*rPropertyName*/,
1432 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1433 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1434 uno::RuntimeException)
1435 {
1436 OSL_ENSURE(false,
1437 "SwXTextRange::addPropertyChangeListener(): not implemented");
1438 }
1439
1440 void SAL_CALL
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1441 SwXTextRange::removePropertyChangeListener(
1442 const ::rtl::OUString& /*rPropertyName*/,
1443 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1444 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1445 uno::RuntimeException)
1446 {
1447 OSL_ENSURE(false,
1448 "SwXTextRange::removePropertyChangeListener(): not implemented");
1449 }
1450
1451 void SAL_CALL
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1452 SwXTextRange::addVetoableChangeListener(
1453 const ::rtl::OUString& /*rPropertyName*/,
1454 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1455 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1456 uno::RuntimeException)
1457 {
1458 OSL_ENSURE(false,
1459 "SwXTextRange::addVetoableChangeListener(): not implemented");
1460 }
1461
1462 void SAL_CALL
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1463 SwXTextRange::removeVetoableChangeListener(
1464 const ::rtl::OUString& /*rPropertyName*/,
1465 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1466 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1467 uno::RuntimeException)
1468 {
1469 OSL_ENSURE(false,
1470 "SwXTextRange::removeVetoableChangeListener(): not implemented");
1471 }
1472
1473 beans::PropertyState SAL_CALL
getPropertyState(const OUString & rPropertyName)1474 SwXTextRange::getPropertyState(const OUString& rPropertyName)
1475 throw (beans::UnknownPropertyException, uno::RuntimeException)
1476 {
1477 vos::OGuard aGuard(Application::GetSolarMutex());
1478
1479 if (!GetDoc() || !m_pImpl->GetBookmark())
1480 {
1481 throw uno::RuntimeException();
1482 }
1483 SwPaM aPaM(GetDoc()->GetNodes());
1484 GetPositions(aPaM);
1485 return SwUnoCursorHelper::GetPropertyState(aPaM, m_pImpl->m_rPropSet,
1486 rPropertyName);
1487 }
1488
1489 uno::Sequence< beans::PropertyState > SAL_CALL
getPropertyStates(const uno::Sequence<OUString> & rPropertyName)1490 SwXTextRange::getPropertyStates(const uno::Sequence< OUString >& rPropertyName)
1491 throw (beans::UnknownPropertyException, uno::RuntimeException)
1492 {
1493 vos::OGuard g(Application::GetSolarMutex());
1494
1495 if (!GetDoc() || !m_pImpl->GetBookmark())
1496 {
1497 throw uno::RuntimeException();
1498 }
1499 SwPaM aPaM(GetDoc()->GetNodes());
1500 GetPositions(aPaM);
1501 return SwUnoCursorHelper::GetPropertyStates(aPaM, m_pImpl->m_rPropSet,
1502 rPropertyName);
1503 }
1504
setPropertyToDefault(const OUString & rPropertyName)1505 void SAL_CALL SwXTextRange::setPropertyToDefault(const OUString& rPropertyName)
1506 throw (beans::UnknownPropertyException, uno::RuntimeException)
1507 {
1508 vos::OGuard aGuard(Application::GetSolarMutex());
1509
1510 if (!GetDoc() || !m_pImpl->GetBookmark())
1511 {
1512 throw uno::RuntimeException();
1513 }
1514 SwPaM aPaM(GetDoc()->GetNodes());
1515 GetPositions(aPaM);
1516 SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_pImpl->m_rPropSet,
1517 rPropertyName);
1518 }
1519
1520 uno::Any SAL_CALL
getPropertyDefault(const OUString & rPropertyName)1521 SwXTextRange::getPropertyDefault(const OUString& rPropertyName)
1522 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1523 uno::RuntimeException)
1524 {
1525 vos::OGuard aGuard(Application::GetSolarMutex());
1526
1527 if (!GetDoc() || !m_pImpl->GetBookmark())
1528 {
1529 throw uno::RuntimeException();
1530 }
1531 SwPaM aPaM(GetDoc()->GetNodes());
1532 GetPositions(aPaM);
1533 return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_pImpl->m_rPropSet,
1534 rPropertyName);
1535 }
1536
1537 void SAL_CALL
makeRedline(const::rtl::OUString & rRedlineType,const uno::Sequence<beans::PropertyValue> & rRedlineProperties)1538 SwXTextRange::makeRedline(
1539 const ::rtl::OUString& rRedlineType,
1540 const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
1541 throw (lang::IllegalArgumentException, uno::RuntimeException)
1542 {
1543 vos::OGuard aGuard(Application::GetSolarMutex());
1544
1545 if (!GetDoc() || !m_pImpl->GetBookmark())
1546 {
1547 throw uno::RuntimeException();
1548 }
1549 SwPaM aPaM(GetDoc()->GetNodes());
1550 SwXTextRange::GetPositions(aPaM);
1551 SwUnoCursorHelper::makeRedline( aPaM, rRedlineType, rRedlineProperties );
1552 }
1553
1554 /******************************************************************
1555 * SwXTextRanges
1556 ******************************************************************/
1557
1558 class SwXTextRanges::Impl
1559 : public SwClient
1560 {
1561
1562 public:
1563
1564 ::std::vector< uno::Reference< text::XTextRange > > m_Ranges;
1565
Impl(SwPaM * const pPaM)1566 Impl(SwPaM *const pPaM)
1567 : SwClient( (pPaM)
1568 ? pPaM->GetDoc()->CreateUnoCrsr(*pPaM->GetPoint())
1569 : 0 )
1570 {
1571 if (pPaM)
1572 {
1573 ::sw::DeepCopyPaM(*pPaM, *GetCursor());
1574 }
1575 MakeRanges();
1576 }
1577
~Impl()1578 ~Impl() {
1579 // Impl owns the cursor; delete it here: SolarMutex is locked
1580 delete GetRegisteredIn();
1581 }
1582
GetCursor()1583 SwUnoCrsr * GetCursor() {
1584 return static_cast<SwUnoCrsr*>(
1585 const_cast<SwModify*>(GetRegisteredIn()));
1586 }
1587
1588 void MakeRanges();
1589 protected:
1590 // SwClient
1591 virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew);
1592
1593 };
1594
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)1595 void SwXTextRanges::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
1596 {
1597 ClientModify(this, pOld, pNew);
1598 }
1599
MakeRanges()1600 void SwXTextRanges::Impl::MakeRanges()
1601 {
1602 SwUnoCrsr *const pCursor = GetCursor();
1603 if (pCursor)
1604 {
1605 SwPaM *pTmpCursor = pCursor;
1606 do {
1607 const uno::Reference< text::XTextRange > xRange(
1608 SwXTextRange::CreateXTextRange(
1609 *pTmpCursor->GetDoc(),
1610 *pTmpCursor->GetPoint(), pTmpCursor->GetMark()));
1611 if (xRange.is())
1612 {
1613 m_Ranges.push_back(xRange);
1614 }
1615 pTmpCursor = static_cast<SwPaM*>(pTmpCursor->GetNext());
1616 }
1617 while (pTmpCursor != pCursor);
1618 }
1619 }
1620
GetCursor() const1621 const SwUnoCrsr* SwXTextRanges::GetCursor() const
1622 {
1623 return m_pImpl->GetCursor();
1624 }
1625
SwXTextRanges(SwPaM * const pPaM)1626 SwXTextRanges::SwXTextRanges(SwPaM *const pPaM)
1627 : m_pImpl( new SwXTextRanges::Impl(pPaM) )
1628 {
1629 }
1630
~SwXTextRanges()1631 SwXTextRanges::~SwXTextRanges()
1632 {
1633 }
1634
getUnoTunnelId()1635 const uno::Sequence< sal_Int8 > & SwXTextRanges::getUnoTunnelId()
1636 {
1637 static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
1638 return aSeq;
1639 }
1640
1641 sal_Int64 SAL_CALL
getSomething(const uno::Sequence<sal_Int8> & rId)1642 SwXTextRanges::getSomething(const uno::Sequence< sal_Int8 >& rId)
1643 throw (uno::RuntimeException)
1644 {
1645 return ::sw::UnoTunnelImpl<SwXTextRanges>(rId, this);
1646 }
1647
1648 /****************************************************************************
1649 * Text positions
1650 * Bis zum ersten Zugriff auf eine TextPosition wird ein SwCursor gehalten,
1651 * danach wird ein Array mit uno::Reference< XTextPosition > angelegt
1652 *
1653 ****************************************************************************/
1654 OUString SAL_CALL
getImplementationName()1655 SwXTextRanges::getImplementationName() throw (uno::RuntimeException)
1656 {
1657 return C2U("SwXTextRanges");
1658 }
1659
1660 static char const*const g_ServicesTextRanges[] =
1661 {
1662 "com.sun.star.text.TextRanges",
1663 };
1664 static const size_t g_nServicesTextRanges(
1665 sizeof(g_ServicesTextRanges)/sizeof(g_ServicesTextRanges[0]));
1666
supportsService(const OUString & rServiceName)1667 sal_Bool SAL_CALL SwXTextRanges::supportsService(const OUString& rServiceName)
1668 throw (uno::RuntimeException)
1669 {
1670 return ::sw::SupportsServiceImpl(
1671 g_nServicesTextRanges, g_ServicesTextRanges, rServiceName);
1672 }
1673
1674 uno::Sequence< OUString > SAL_CALL
getSupportedServiceNames()1675 SwXTextRanges::getSupportedServiceNames() throw (uno::RuntimeException)
1676 {
1677 return ::sw::GetSupportedServiceNamesImpl(
1678 g_nServicesTextRanges, g_ServicesTextRanges);
1679 }
1680
getCount()1681 sal_Int32 SAL_CALL SwXTextRanges::getCount() throw (uno::RuntimeException)
1682 {
1683 vos::OGuard aGuard(Application::GetSolarMutex());
1684
1685 return static_cast<sal_Int32>(m_pImpl->m_Ranges.size());
1686 }
1687
getByIndex(sal_Int32 nIndex)1688 uno::Any SAL_CALL SwXTextRanges::getByIndex(sal_Int32 nIndex)
1689 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException,
1690 uno::RuntimeException)
1691 {
1692 vos::OGuard aGuard(Application::GetSolarMutex());
1693
1694 if ((nIndex < 0) ||
1695 (static_cast<size_t>(nIndex) >= m_pImpl->m_Ranges.size()))
1696 {
1697 throw lang::IndexOutOfBoundsException();
1698 }
1699 uno::Any ret;
1700 ret <<= (m_pImpl->m_Ranges.at(nIndex));
1701 return ret;
1702 }
1703
1704 uno::Type SAL_CALL
getElementType()1705 SwXTextRanges::getElementType() throw (uno::RuntimeException)
1706 {
1707 return text::XTextRange::static_type();
1708 }
1709
hasElements()1710 sal_Bool SAL_CALL SwXTextRanges::hasElements() throw (uno::RuntimeException)
1711 {
1712 // no mutex necessary: getCount() does locking
1713 return getCount() > 0;
1714 }
1715
SetString(SwCursor & rCursor,const OUString & rString)1716 void SwUnoCursorHelper::SetString(SwCursor & rCursor, const OUString& rString)
1717 {
1718 // Start/EndAction
1719 SwDoc *const pDoc = rCursor.GetDoc();
1720 UnoActionContext aAction(pDoc);
1721 pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
1722 if (rCursor.HasMark())
1723 {
1724 pDoc->DeleteAndJoin(rCursor);
1725 }
1726 if (rString.getLength())
1727 {
1728 String aText(rString);
1729 const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR(
1730 *pDoc, rCursor, aText, false ) );
1731 DBG_ASSERT( bSuccess, "DocInsertStringSplitCR" );
1732 (void) bSuccess;
1733 SwUnoCursorHelper::SelectPam(rCursor, true);
1734 rCursor.Left(rString.getLength(), CRSR_SKIP_CHARS, sal_False, sal_False);
1735 }
1736 pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
1737 }
1738
1739 /******************************************************************
1740 * SwXParaFrameEnumeration
1741 ******************************************************************/
1742
1743 class SwXParaFrameEnumeration::Impl
1744 : public SwClient
1745 {
1746
1747 public:
1748
1749 // created by hasMoreElements
1750 uno::Reference< text::XTextContent > m_xNextObject;
1751 FrameDependList_t m_Frames;
1752
Impl(SwPaM const & rPaM)1753 Impl(SwPaM const & rPaM)
1754 : SwClient(rPaM.GetDoc()->CreateUnoCrsr(*rPaM.GetPoint(), sal_False))
1755 {
1756 if (rPaM.HasMark())
1757 {
1758 GetCursor()->SetMark();
1759 *GetCursor()->GetMark() = *rPaM.GetMark();
1760 }
1761 }
1762
~Impl()1763 ~Impl() {
1764 // Impl owns the cursor; delete it here: SolarMutex is locked
1765 delete GetRegisteredIn();
1766 }
1767
GetCursor()1768 SwUnoCrsr * GetCursor() {
1769 return static_cast<SwUnoCrsr*>(
1770 const_cast<SwModify*>(GetRegisteredIn()));
1771 }
1772 protected:
1773 // SwClient
1774 virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew);
1775
1776 };
1777
1778 struct InvalidFrameDepend {
operator ()InvalidFrameDepend1779 bool operator() (::boost::shared_ptr<SwDepend> const & rEntry)
1780 { return !rEntry->GetRegisteredIn(); }
1781 };
1782
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)1783 void SwXParaFrameEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew)
1784 {
1785 ClientModify(this, pOld, pNew);
1786 if(!GetRegisteredIn())
1787 {
1788 m_Frames.clear();
1789 m_xNextObject = 0;
1790 }
1791 else
1792 {
1793 // check if any frame went away...
1794 FrameDependList_t::iterator const iter =
1795 ::std::remove_if(m_Frames.begin(), m_Frames.end(),
1796 InvalidFrameDepend());
1797 m_Frames.erase(iter, m_Frames.end());
1798 }
1799 }
1800
1801 static sal_Bool
lcl_CreateNextObject(SwUnoCrsr & i_rUnoCrsr,uno::Reference<text::XTextContent> & o_rNextObject,FrameDependList_t & i_rFrames)1802 lcl_CreateNextObject(SwUnoCrsr& i_rUnoCrsr,
1803 uno::Reference<text::XTextContent> & o_rNextObject,
1804 FrameDependList_t & i_rFrames)
1805 {
1806 if (!i_rFrames.size())
1807 return sal_False;
1808
1809 SwFrmFmt *const pFormat = static_cast<SwFrmFmt*>(const_cast<SwModify*>(
1810 i_rFrames.front()->GetRegisteredIn()));
1811 i_rFrames.pop_front();
1812 // the format should be valid here, otherwise the client
1813 // would have been removed in ::Modify
1814 // check for a shape first
1815 SwDrawContact* const pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement( *pFormat );
1816 if (pContact)
1817 {
1818 SdrObject * const pSdr = pContact->GetMaster();
1819 if (pSdr)
1820 {
1821 o_rNextObject.set(pSdr->getUnoShape(), uno::UNO_QUERY);
1822 }
1823 }
1824 else
1825 {
1826 const SwNodeIndex* pIdx = pFormat->GetCntnt().GetCntntIdx();
1827 DBG_ASSERT(pIdx, "where is the index?");
1828 SwNode const*const pNd =
1829 i_rUnoCrsr.GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ];
1830
1831 const FlyCntType eType = (!pNd->IsNoTxtNode()) ? FLYCNTTYPE_FRM
1832 : ( (pNd->IsGrfNode()) ? FLYCNTTYPE_GRF : FLYCNTTYPE_OLE );
1833
1834 const uno::Reference< container::XNamed > xFrame =
1835 SwXFrames::GetObject(*pFormat, eType);
1836 o_rNextObject.set(xFrame, uno::UNO_QUERY);
1837 }
1838
1839 return o_rNextObject.is();
1840 }
1841
1842 /* -----------------------------03.04.00 10:15--------------------------------
1843 Description: Search for a FLYCNT text attribute at the cursor point
1844 and fill the frame into the array
1845 ---------------------------------------------------------------------------*/
1846 static void
lcl_FillFrame(SwClient & rEnum,SwUnoCrsr & rUnoCrsr,FrameDependList_t & rFrames)1847 lcl_FillFrame(SwClient & rEnum, SwUnoCrsr& rUnoCrsr,
1848 FrameDependList_t & rFrames)
1849 {
1850 // search for objects at the cursor - anchored at/as char
1851 SwTxtAttr const*const pTxtAttr =
1852 rUnoCrsr.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
1853 rUnoCrsr.GetPoint()->nContent.GetIndex(), RES_TXTATR_FLYCNT);
1854 if (pTxtAttr)
1855 {
1856 const SwFmtFlyCnt& rFlyCnt = pTxtAttr->GetFlyCnt();
1857 SwFrmFmt * const pFrmFmt = rFlyCnt.GetFrmFmt();
1858 SwDepend * const pNewDepend = new SwDepend(&rEnum, pFrmFmt);
1859 rFrames.push_back( ::boost::shared_ptr<SwDepend>(pNewDepend) );
1860 }
1861 }
1862
SwXParaFrameEnumeration(const SwPaM & rPaM,const enum ParaFrameMode eParaFrameMode,SwFrmFmt * const pFmt)1863 SwXParaFrameEnumeration::SwXParaFrameEnumeration(
1864 const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode,
1865 SwFrmFmt *const pFmt)
1866 : m_pImpl( new SwXParaFrameEnumeration::Impl(rPaM) )
1867 {
1868 if (PARAFRAME_PORTION_PARAGRAPH == eParaFrameMode)
1869 {
1870 FrameDependSortList_t frames;
1871 ::CollectFrameAtNode(*m_pImpl.get(), rPaM.GetPoint()->nNode,
1872 frames, false);
1873 ::std::transform(frames.begin(), frames.end(),
1874 ::std::back_inserter(m_pImpl->m_Frames),
1875 ::boost::bind(&FrameDependSortListEntry::pFrameDepend, _1));
1876 }
1877 else if (pFmt)
1878 {
1879 // create SwDepend for frame and insert into array
1880 SwDepend *const pNewDepend = new SwDepend(m_pImpl.get(), pFmt);
1881 m_pImpl->m_Frames.push_back(::boost::shared_ptr<SwDepend>(pNewDepend));
1882 }
1883 else if ((PARAFRAME_PORTION_CHAR == eParaFrameMode) ||
1884 (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode))
1885 {
1886 if (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode)
1887 {
1888 //get all frames that are bound at paragraph or at character
1889 SwPosFlyFrms aFlyFrms(rPaM.GetDoc()->GetAllFlyFmts(m_pImpl->GetCursor()));
1890
1891 for(SwPosFlyFrms::const_iterator aIter(aFlyFrms.begin()); aIter != aFlyFrms.end(); aIter++)
1892 {
1893 SwFrmFmt *const pFrmFmt = const_cast<SwFrmFmt*>(&((*aIter)->GetFmt()));
1894
1895 // create SwDepend for frame and insert into array
1896 SwDepend *const pNewDepend = new SwDepend(m_pImpl.get(), pFrmFmt);
1897 m_pImpl->m_Frames.push_back(::boost::shared_ptr<SwDepend>(pNewDepend));
1898 }
1899
1900 //created from any text range
1901 if (m_pImpl->GetCursor()->HasMark())
1902 {
1903 m_pImpl->GetCursor()->Normalize();
1904 do
1905 {
1906 lcl_FillFrame(*m_pImpl.get(), *m_pImpl->GetCursor(),
1907 m_pImpl->m_Frames);
1908 m_pImpl->GetCursor()->Right(
1909 1, CRSR_SKIP_CHARS, sal_False, sal_False);
1910 }
1911 while (*m_pImpl->GetCursor()->GetPoint() <
1912 *m_pImpl->GetCursor()->GetMark());
1913 }
1914 }
1915
1916 lcl_FillFrame(*m_pImpl.get(), *m_pImpl->GetCursor(), m_pImpl->m_Frames);
1917 }
1918 }
1919
~SwXParaFrameEnumeration()1920 SwXParaFrameEnumeration::~SwXParaFrameEnumeration()
1921 {
1922 }
1923
1924 sal_Bool SAL_CALL
hasMoreElements()1925 SwXParaFrameEnumeration::hasMoreElements() throw (uno::RuntimeException)
1926 {
1927 vos::OGuard aGuard(Application::GetSolarMutex());
1928
1929 if (!m_pImpl->GetCursor())
1930 throw uno::RuntimeException();
1931
1932 return (m_pImpl->m_xNextObject.is())
1933 ? sal_True
1934 : lcl_CreateNextObject(*m_pImpl->GetCursor(),
1935 m_pImpl->m_xNextObject, m_pImpl->m_Frames);
1936 }
1937
nextElement()1938 uno::Any SAL_CALL SwXParaFrameEnumeration::nextElement()
1939 throw (container::NoSuchElementException,
1940 lang::WrappedTargetException, uno::RuntimeException)
1941 {
1942 vos::OGuard aGuard(Application::GetSolarMutex());
1943
1944 if (!m_pImpl->GetCursor())
1945 {
1946 throw uno::RuntimeException();
1947 }
1948
1949 if (!m_pImpl->m_xNextObject.is() && m_pImpl->m_Frames.size())
1950 {
1951 lcl_CreateNextObject(*m_pImpl->GetCursor(),
1952 m_pImpl->m_xNextObject, m_pImpl->m_Frames);
1953 }
1954 if (!m_pImpl->m_xNextObject.is())
1955 {
1956 throw container::NoSuchElementException();
1957 }
1958 uno::Any aRet;
1959 aRet <<= m_pImpl->m_xNextObject;
1960 m_pImpl->m_xNextObject = 0;
1961 return aRet;
1962 }
1963
1964 OUString SAL_CALL
getImplementationName()1965 SwXParaFrameEnumeration::getImplementationName() throw (uno::RuntimeException)
1966 {
1967 return C2U("SwXParaFrameEnumeration");
1968 }
1969
1970 static char const*const g_ServicesParaFrameEnum[] =
1971 {
1972 "com.sun.star.util.ContentEnumeration",
1973 };
1974 static const size_t g_nServicesParaFrameEnum(
1975 sizeof(g_ServicesParaFrameEnum)/sizeof(g_ServicesParaFrameEnum[0]));
1976
1977 sal_Bool SAL_CALL
supportsService(const OUString & rServiceName)1978 SwXParaFrameEnumeration::supportsService(const OUString& rServiceName)
1979 throw (uno::RuntimeException)
1980 {
1981 return ::sw::SupportsServiceImpl(
1982 g_nServicesParaFrameEnum, g_ServicesParaFrameEnum, rServiceName);
1983 }
1984
1985 uno::Sequence< OUString > SAL_CALL
getSupportedServiceNames()1986 SwXParaFrameEnumeration::getSupportedServiceNames()
1987 throw (uno::RuntimeException)
1988 {
1989 return ::sw::GetSupportedServiceNamesImpl(
1990 g_nServicesParaFrameEnum, g_ServicesParaFrameEnum);
1991 }
1992
1993