xref: /trunk/main/sw/source/core/unocore/unoobj.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 <com/sun/star/table/TableSortField.hpp>
28 
29 #include <osl/endian.h>
30 #include <rtl/ustrbuf.hxx>
31 #include <unotools/collatorwrapper.hxx>
32 #include <swtypes.hxx>
33 #include <hintids.hxx>
34 #include <cmdid.h>
35 #include <hints.hxx>
36 #include <IMark.hxx>
37 #include <frmfmt.hxx>
38 #include <doc.hxx>
39 #include <IDocumentUndoRedo.hxx>
40 #include <istyleaccess.hxx>
41 #include <ndtxt.hxx>
42 #include <ndnotxt.hxx>
43 #include <unocrsr.hxx>
44 #include <unocrsrhelper.hxx>
45 #include <swundo.hxx>
46 #include <rootfrm.hxx>
47 #include <flyfrm.hxx>
48 #include <ftnidx.hxx>
49 #include <sfx2/linkmgr.hxx>
50 #include <docary.hxx>
51 #include <paratr.hxx>
52 #include <tools/urlobj.hxx>
53 #include <pam.hxx>
54 #include <tools/cachestr.hxx>
55 #include <shellio.hxx>
56 #include <swerror.h>
57 #include <swtblfmt.hxx>
58 #include <fmtruby.hxx>
59 #include <docsh.hxx>
60 #include <docstyle.hxx>
61 #include <charfmt.hxx>
62 #include <txtfld.hxx>
63 #include <fmtfld.hxx>
64 #include <fmtpdsc.hxx>
65 #include <pagedesc.hxx>
66 #include <poolfmt.hrc>
67 #include <poolfmt.hxx>
68 #include <edimp.hxx>
69 #include <fchrfmt.hxx>
70 #include <fmtautofmt.hxx>
71 #include <cntfrm.hxx>
72 #include <pagefrm.hxx>
73 #include <doctxm.hxx>
74 #include <sfx2/docfilt.hxx>
75 #include <sfx2/docfile.hxx>
76 #include <sfx2/fcontnr.hxx>
77 #include <fmtrfmrk.hxx>
78 #include <txtrfmrk.hxx>
79 #include <unotextrange.hxx>
80 #include <unotextcursor.hxx>
81 #include <unomap.hxx>
82 #include <unosett.hxx>
83 #include <unoprnms.hxx>
84 #include <unotbl.hxx>
85 #include <unodraw.hxx>
86 #include <unocoll.hxx>
87 #include <unostyle.hxx>
88 #include <unofield.hxx>
89 #include <unometa.hxx>
90 #include <fmtanchr.hxx>
91 #include <editeng/flstitem.hxx>
92 #include <svtools/ctrltool.hxx>
93 #include <flypos.hxx>
94 #include <txtftn.hxx>
95 #include <fmtftn.hxx>
96 #include <com/sun/star/text/WrapTextMode.hpp>
97 #include <com/sun/star/text/TextContentAnchorType.hpp>
98 #include <com/sun/star/style/PageStyleLayout.hpp>
99 #include <com/sun/star/text/XTextDocument.hpp>
100 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
101 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
102 #include <com/sun/star/text/TextMarkupType.hpp>
103 #include <unoidx.hxx>
104 #include <unoframe.hxx>
105 #include <fmthdft.hxx>
106 #include <vos/mutex.hxx>
107 #include <vcl/svapp.hxx>
108 #include <fmtflcnt.hxx>
109 #define _SVSTDARR_USHORTS
110 #define _SVSTDARR_USHORTSSORT
111 #include <svl/svstdarr.hxx>
112 #include <editeng/brshitem.hxx>
113 #include <editeng/unolingu.hxx>
114 #include <fmtclds.hxx>
115 #include <dcontact.hxx>
116 #include <SwStyleNameMapper.hxx>
117 #include <crsskip.hxx>
118 #include <sortopt.hxx>
119 #include <com/sun/star/beans/PropertyAttribute.hpp>
120 #include <memory>
121 #include <unoparaframeenum.hxx>
122 #include <unoparagraph.hxx>
123 
124 
125 using namespace ::com::sun::star;
126 using ::rtl::OUString;
127 using ::rtl::OUStringBuffer;
128 
129 
130 /****************************************************************************
131     static methods
132 ****************************************************************************/
CreateUnoTunnelId()133 uno::Sequence< sal_Int8 >  CreateUnoTunnelId()
134 {
135     static osl::Mutex aCreateMutex;
136     osl::Guard<osl::Mutex> aGuard( aCreateMutex );
137     uno::Sequence< sal_Int8 > aSeq( 16 );
138     rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
139     return aSeq;
140 }
141 /****************************************************************************
142     Hilfsklassen
143 ****************************************************************************/
144 
145 /* -----------------13.05.98 12:15-------------------
146  *
147  * --------------------------------------------------*/
SwUnoInternalPaM(SwDoc & rDoc)148 SwUnoInternalPaM::SwUnoInternalPaM(SwDoc& rDoc) :
149     SwPaM(rDoc.GetNodes())
150 {
151 }
~SwUnoInternalPaM()152 SwUnoInternalPaM::~SwUnoInternalPaM()
153 {
154     while( GetNext() != this)
155     {
156         delete GetNext();
157     }
158 }
159 
operator =(const SwPaM & rPaM)160 SwUnoInternalPaM&   SwUnoInternalPaM::operator=(const SwPaM& rPaM)
161 {
162     const SwPaM* pTmp = &rPaM;
163     *GetPoint() = *rPaM.GetPoint();
164     if(rPaM.HasMark())
165     {
166         SetMark();
167         *GetMark() = *rPaM.GetMark();
168     }
169     else
170         DeleteMark();
171     while(&rPaM != (pTmp = (const SwPaM*)pTmp->GetNext()))
172     {
173         if(pTmp->HasMark())
174             new SwPaM(*pTmp->GetMark(), *pTmp->GetPoint(), this);
175         else
176             new SwPaM(*pTmp->GetPoint(), this);
177     }
178     return *this;
179 }
180 
181 /*-----------------09.03.98 08:29-------------------
182 
183 --------------------------------------------------*/
SelectPam(SwPaM & rPam,const bool bExpand)184 void SwUnoCursorHelper::SelectPam(SwPaM & rPam, const bool bExpand)
185 {
186     if (bExpand)
187     {
188         if (!rPam.HasMark())
189         {
190             rPam.SetMark();
191         }
192     }
193     else if (rPam.HasMark())
194     {
195         rPam.DeleteMark();
196     }
197 }
198 
199 /* -----------------20.05.98 14:59-------------------
200  *
201  * --------------------------------------------------*/
GetTextFromPam(SwPaM & rPam,OUString & rBuffer)202 void SwUnoCursorHelper::GetTextFromPam(SwPaM & rPam, OUString & rBuffer)
203 {
204     if (!rPam.HasMark())
205     {
206         return;
207     }
208     SvCacheStream aStream( 20480 );
209 #ifdef OSL_BIGENDIAN
210     aStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
211 #else
212     aStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
213 #endif
214     WriterRef xWrt;
215     // TODO/MBA: looks like a BaseURL doesn't make sense here
216     SwReaderWriter::GetWriter( C2S(FILTER_TEXT_DLG), String(), xWrt );
217     if( xWrt.Is() )
218     {
219         SwWriter aWriter( aStream, rPam );
220         xWrt->bASCII_NoLastLineEnd = sal_True;
221         xWrt->bExportPargraphNumbering = sal_False;
222         SwAsciiOptions aOpt = xWrt->GetAsciiOptions();
223         aOpt.SetCharSet( RTL_TEXTENCODING_UNICODE );
224         xWrt->SetAsciiOptions( aOpt );
225         xWrt->bUCS2_WithStartChar = sal_False;
226         // --> FME #i68522#
227         const sal_Bool bOldShowProgress = xWrt->bShowProgress;
228         xWrt->bShowProgress = sal_False;
229         // <--
230 
231         long lLen;
232         if( !IsError( aWriter.Write( xWrt ) ) &&
233             0x7ffffff > (( lLen  = aStream.GetSize() )
234                                     / sizeof( sal_Unicode )) + 1 )
235         {
236             aStream << (sal_Unicode)'\0';
237 
238             long lUniLen = (lLen / sizeof( sal_Unicode ));
239             ::rtl::OUStringBuffer aStrBuffer( lUniLen );
240             aStream.Seek( 0 );
241             aStream.ResetError();
242             while(lUniLen)
243             {
244                 String sBuf;
245                 sal_Int32 nLocalLen = 0;
246                 if( lUniLen >= STRING_MAXLEN )
247                 {
248                     nLocalLen =  STRING_MAXLEN - 1;
249                 }
250                 else
251                 {
252                     nLocalLen = lUniLen;
253                 }
254                 sal_Unicode *const pStrBuf =
255                     sBuf.AllocBuffer( xub_StrLen( nLocalLen + 1));
256                 aStream.Read( pStrBuf, 2 * nLocalLen );
257                 pStrBuf[ nLocalLen ] = '\0';
258                 aStrBuffer.append( pStrBuf, nLocalLen );
259                 lUniLen -= nLocalLen;
260             }
261             rBuffer = aStrBuffer.makeStringAndClear();
262         }
263         xWrt->bShowProgress = bOldShowProgress;
264     }
265 }
266 
267 /* -----------------06.07.98 07:33-------------------
268  *
269  * --------------------------------------------------*/
270 static void
lcl_setCharStyle(SwDoc * const pDoc,const uno::Any & rValue,SfxItemSet & rSet)271 lcl_setCharStyle(SwDoc *const pDoc, const uno::Any & rValue, SfxItemSet & rSet)
272 {
273     SwDocShell *const pDocSh = pDoc->GetDocShell();
274     if(pDocSh)
275     {
276         OUString uStyle;
277         if (!(rValue >>= uStyle))
278         {
279             throw lang::IllegalArgumentException();
280         }
281         String sStyle;
282         SwStyleNameMapper::FillUIName(uStyle, sStyle,
283                 nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, sal_True);
284         SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
285             pDocSh->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_CHAR));
286         if (!pStyle)
287         {
288             throw lang::IllegalArgumentException();
289         }
290         const SwFmtCharFmt aFmt(pStyle->GetCharFmt());
291         rSet.Put(aFmt);
292     }
293 };
294 /* -----------------08.06.06 10:43-------------------
295  *
296  * --------------------------------------------------*/
297 static void
lcl_setAutoStyle(IStyleAccess & rStyleAccess,const uno::Any & rValue,SfxItemSet & rSet,const bool bPara)298 lcl_setAutoStyle(IStyleAccess & rStyleAccess, const uno::Any & rValue,
299         SfxItemSet & rSet, const bool bPara)
300 {
301     OUString uStyle;
302     if (!(rValue >>= uStyle))
303     {
304          throw lang::IllegalArgumentException();
305     }
306     StylePool::SfxItemSet_Pointer_t pStyle = bPara ?
307         rStyleAccess.getByName(uStyle, IStyleAccess::AUTO_STYLE_PARA ):
308         rStyleAccess.getByName(uStyle, IStyleAccess::AUTO_STYLE_CHAR );
309     if(pStyle.get())
310     {
311         SwFmtAutoFmt aFmt( (bPara)
312             ? sal::static_int_cast< sal_uInt16 >(RES_AUTO_STYLE)
313             : sal::static_int_cast< sal_uInt16 >(RES_TXTATR_AUTOFMT) );
314         aFmt.SetStyleHandle( pStyle );
315         rSet.Put(aFmt);
316     }
317     else
318     {
319          throw lang::IllegalArgumentException();
320     }
321 };
322 /* -----------------30.06.98 08:46-------------------
323  *
324  * --------------------------------------------------*/
325 void
SetTxtFmtColl(const uno::Any & rAny,SwPaM & rPaM)326 SwUnoCursorHelper::SetTxtFmtColl(const uno::Any & rAny, SwPaM & rPaM)
327 {
328     SwDoc *const pDoc = rPaM.GetDoc();
329     SwDocShell *const pDocSh = pDoc->GetDocShell();
330     if(!pDocSh)
331         return;
332     OUString uStyle;
333     rAny >>= uStyle;
334     String sStyle;
335     SwStyleNameMapper::FillUIName(uStyle, sStyle,
336             nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True );
337     SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
338             pDocSh->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_PARA));
339     if (!pStyle)
340     {
341         throw lang::IllegalArgumentException();
342     }
343 
344     SwTxtFmtColl *const pLocal = pStyle->GetCollection();
345     UnoActionContext aAction(pDoc);
346     pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
347     SwPaM *pTmpCrsr = &rPaM;
348     do {
349         pDoc->SetTxtFmtColl(*pTmpCrsr, pLocal);
350         pTmpCrsr = static_cast<SwPaM*>(pTmpCrsr->GetNext());
351     } while ( pTmpCrsr != &rPaM );
352     pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
353 }
354 
355 /* -----------------06.07.98 07:38-------------------
356  *
357  * --------------------------------------------------*/
358 bool
SetPageDesc(const uno::Any & rValue,SwDoc & rDoc,SfxItemSet & rSet)359 SwUnoCursorHelper::SetPageDesc(
360         const uno::Any& rValue, SwDoc & rDoc, SfxItemSet & rSet)
361 {
362     OUString uDescName;
363     if (!(rValue >>= uDescName))
364     {
365         return false;
366     }
367     ::std::auto_ptr<SwFmtPageDesc> pNewDesc;
368     const SfxPoolItem* pItem;
369     if(SFX_ITEM_SET == rSet.GetItemState( RES_PAGEDESC, sal_True, &pItem ) )
370     {
371         pNewDesc.reset(new SwFmtPageDesc(
372                     *static_cast<const SwFmtPageDesc*>(pItem)));
373     }
374     if (!pNewDesc.get())
375     {
376         pNewDesc.reset(new SwFmtPageDesc());
377     }
378     String sDescName;
379     SwStyleNameMapper::FillUIName(uDescName, sDescName,
380             nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC, sal_True);
381     if (!pNewDesc->GetPageDesc() ||
382         (pNewDesc->GetPageDesc()->GetName() != sDescName))
383     {
384         sal_Bool bPut = sal_False;
385         if(sDescName.Len())
386         {
387             SwPageDesc *const pPageDesc =
388                 ::GetPageDescByName_Impl(rDoc, sDescName);
389             if (!pPageDesc)
390             {
391                 throw lang::IllegalArgumentException();
392             }
393             pNewDesc.get()->RegisterToPageDesc( *pPageDesc );
394             bPut = sal_True;
395         }
396         if(!bPut)
397         {
398             rSet.ClearItem(RES_BREAK);
399             rSet.Put(SwFmtPageDesc());
400         }
401         else
402         {
403             rSet.Put(*pNewDesc);
404         }
405     }
406     return true;
407 }
408 
409 /* -----------------30.06.98 10:29-------------------
410  *
411  * --------------------------------------------------*/
412 static void
lcl_SetNodeNumStart(SwPaM & rCrsr,uno::Any const & rValue)413 lcl_SetNodeNumStart(SwPaM & rCrsr, uno::Any const& rValue)
414 {
415     sal_Int16 nTmp = 1;
416     rValue >>= nTmp;
417     sal_uInt16 nStt = (nTmp < 0 ? USHRT_MAX : (sal_uInt16)nTmp);
418     SwDoc* pDoc = rCrsr.GetDoc();
419     UnoActionContext aAction(pDoc);
420 
421     if( rCrsr.GetNext() != &rCrsr )         // Mehrfachselektion ?
422     {
423         pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
424         SwPamRanges aRangeArr( rCrsr );
425         SwPaM aPam( *rCrsr.GetPoint() );
426         for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
427         {
428           pDoc->SetNumRuleStart(*aRangeArr.SetPam( n, aPam ).GetPoint());
429           pDoc->SetNodeNumStart(*aRangeArr.SetPam( n, aPam ).GetPoint(),
430                     nStt );
431         }
432         pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
433     }
434     else
435     {
436         pDoc->SetNumRuleStart( *rCrsr.GetPoint());
437         pDoc->SetNodeNumStart( *rCrsr.GetPoint(), nStt );
438     }
439 }
440 
441 static bool
lcl_setCharFmtSequence(SwPaM & rPam,uno::Any const & rValue)442 lcl_setCharFmtSequence(SwPaM & rPam, uno::Any const& rValue)
443 {
444     uno::Sequence<OUString> aCharStyles;
445     if (!(rValue >>= aCharStyles))
446     {
447         return false;
448     }
449 
450     for (sal_Int32 nStyle = 0; nStyle < aCharStyles.getLength(); nStyle++)
451     {
452         uno::Any aStyle;
453         rPam.GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_START, NULL);
454         aStyle <<= aCharStyles.getConstArray()[nStyle];
455         // create a local set and apply each format directly
456         SfxItemSet aSet(rPam.GetDoc()->GetAttrPool(),
457                 RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT);
458         lcl_setCharStyle(rPam.GetDoc(), aStyle, aSet);
459         // the first style should replace the current attributes,
460         // all other have to be added
461         SwUnoCursorHelper::SetCrsrAttr(rPam, aSet, (nStyle)
462                 ? nsSetAttrMode::SETATTR_DONTREPLACE
463                 : nsSetAttrMode::SETATTR_DEFAULT);
464         rPam.GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_START, NULL);
465     }
466     return true;
467 }
468 
469 static void
lcl_setDropcapCharStyle(SwPaM & rPam,SfxItemSet & rItemSet,uno::Any const & rValue)470 lcl_setDropcapCharStyle(SwPaM & rPam, SfxItemSet & rItemSet,
471         uno::Any const& rValue)
472 {
473     OUString uStyle;
474     if (!(rValue >>= uStyle))
475     {
476         throw lang::IllegalArgumentException();
477     }
478     String sStyle;
479     SwStyleNameMapper::FillUIName(uStyle, sStyle,
480             nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, sal_True);
481     SwDoc *const pDoc = rPam.GetDoc();
482     //default character style must not be set as default format
483     SwDocStyleSheet *const pStyle = static_cast<SwDocStyleSheet*>(
484             pDoc->GetDocShell()
485             ->GetStyleSheetPool()->Find(sStyle, SFX_STYLE_FAMILY_CHAR));
486     if (!pStyle ||
487         (static_cast<SwDocStyleSheet*>(pStyle)->GetCharFmt() ==
488              pDoc->GetDfltCharFmt()))
489     {
490         throw lang::IllegalArgumentException();
491     }
492     ::std::auto_ptr<SwFmtDrop> pDrop;
493     SfxPoolItem const* pItem(0);
494     if (SFX_ITEM_SET ==
495             rItemSet.GetItemState(RES_PARATR_DROP, sal_True, &pItem))
496     {
497         pDrop.reset(new SwFmtDrop(*static_cast<const SwFmtDrop*>(pItem)));
498     }
499     if (!pDrop.get())
500     {
501         pDrop.reset(new SwFmtDrop);
502     }
503     const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*pStyle));
504     pDrop->SetCharFmt(xStyle->GetCharFmt());
505     rItemSet.Put(*pDrop);
506 }
507 
508 static void
lcl_setRubyCharstyle(SfxItemSet & rItemSet,uno::Any const & rValue)509 lcl_setRubyCharstyle(SfxItemSet & rItemSet, uno::Any const& rValue)
510 {
511     OUString sTmp;
512     if (!(rValue >>= sTmp))
513     {
514         throw lang::IllegalArgumentException();
515     }
516 
517     ::std::auto_ptr<SwFmtRuby> pRuby;
518     const SfxPoolItem* pItem;
519     if (SFX_ITEM_SET ==
520             rItemSet.GetItemState(RES_TXTATR_CJK_RUBY, sal_True, &pItem))
521     {
522         pRuby.reset(new SwFmtRuby(*static_cast<const SwFmtRuby*>(pItem)));
523     }
524     if (!pRuby.get())
525     {
526         pRuby.reset(new SwFmtRuby(aEmptyStr));
527     }
528     String sStyle;
529     SwStyleNameMapper::FillUIName(sTmp, sStyle,
530             nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, sal_True );
531     pRuby->SetCharFmtName(sStyle);
532     pRuby->SetCharFmtId(0);
533     if (sStyle.Len() > 0)
534     {
535         const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
536                 sStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
537         pRuby->SetCharFmtId(nId);
538     }
539     rItemSet.Put(*pRuby);
540 }
541 
542 /* -----------------17.09.98 09:44-------------------
543  *
544  * --------------------------------------------------*/
545 bool
SetCursorPropertyValue(SfxItemPropertySimpleEntry const & rEntry,const uno::Any & rValue,SwPaM & rPam,SfxItemSet & rItemSet)546 SwUnoCursorHelper::SetCursorPropertyValue(
547         SfxItemPropertySimpleEntry const& rEntry, const uno::Any& rValue,
548         SwPaM & rPam, SfxItemSet & rItemSet)
549 {
550     if (!(rEntry.nFlags & beans::PropertyAttribute::MAYBEVOID) &&
551         (rValue.getValueType() == ::getCppuVoidType()))
552     {
553         return false;
554     }
555     bool bRet = true;
556     switch (rEntry.nWID)
557     {
558         case RES_TXTATR_CHARFMT:
559             lcl_setCharStyle(rPam.GetDoc(), rValue, rItemSet);
560         break;
561         case RES_TXTATR_AUTOFMT:
562             lcl_setAutoStyle(rPam.GetDoc()->GetIStyleAccess(),
563                     rValue, rItemSet, false);
564         break;
565         case FN_UNO_CHARFMT_SEQUENCE:
566             lcl_setCharFmtSequence(rPam, rValue);
567         break;
568         case FN_UNO_PARA_STYLE :
569             SwUnoCursorHelper::SetTxtFmtColl(rValue, rPam);
570         break;
571         case RES_AUTO_STYLE:
572             lcl_setAutoStyle(rPam.GetDoc()->GetIStyleAccess(),
573                     rValue, rItemSet, true);
574         break;
575         case FN_UNO_PAGE_STYLE:
576             //FIXME nothing here?
577         break;
578         case FN_UNO_NUM_START_VALUE:
579             lcl_SetNodeNumStart( rPam, rValue );
580         break;
581         case FN_UNO_NUM_LEVEL:
582         // --> OD 2008-07-14 #i91601#
583         case FN_UNO_LIST_ID:
584         // <--
585         case FN_UNO_IS_NUMBER:
586         {
587             // multi selection is not considered
588             SwTxtNode *const pTxtNd = rPam.GetNode()->GetTxtNode();
589             // --> OD 2008-05-14 #refactorlists# - check on list style not needed
590 //                const SwNumRule* pRule = pTxtNd->GetNumRule();
591 //                if( FN_UNO_NUM_LEVEL == rEntry.nWID  &&  pRule != NULL )
592             if (FN_UNO_NUM_LEVEL == rEntry.nWID)
593             // <--
594             {
595                 sal_Int16 nLevel = 0;
596                 if (rValue >>= nLevel)
597                 {
598                     pTxtNd->SetAttrListLevel(nLevel);
599                 }
600             }
601             // --> OD 2008-07-14 #i91601#
602             else if (FN_UNO_LIST_ID == rEntry.nWID)
603             {
604                 ::rtl::OUString sListId;
605                 if (rValue >>= sListId)
606                 {
607                     pTxtNd->SetListId( sListId );
608                 }
609             }
610             // <--
611             else if (FN_UNO_IS_NUMBER == rEntry.nWID)
612             {
613                 sal_Bool bIsNumber(sal_False);
614                 if (rValue >>= bIsNumber)
615                 {
616                     if (!bIsNumber)
617                     {
618                         pTxtNd->SetCountedInList( false );
619                     }
620                 }
621             }
622             //PROPERTY_MAYBEVOID!
623         }
624         break;
625         case FN_NUMBER_NEWSTART:
626         {
627             sal_Bool bVal = sal_False;
628             if (!(rValue >>= bVal))
629             {
630                 throw lang::IllegalArgumentException();
631             }
632             rPam.GetDoc()->SetNumRuleStart(*rPam.GetPoint(), bVal);
633         }
634         break;
635         case FN_UNO_NUM_RULES:
636             SwUnoCursorHelper::setNumberingProperty(rValue, rPam);
637         break;
638         case RES_PARATR_DROP:
639         {
640             if (MID_DROPCAP_CHAR_STYLE_NAME == rEntry.nMemberId)
641             {
642                 lcl_setDropcapCharStyle(rPam, rItemSet, rValue);
643             }
644             else
645             {
646                 bRet = false;
647             }
648         }
649         break;
650         case RES_TXTATR_CJK_RUBY:
651         {
652             if (MID_RUBY_CHARSTYLE == rEntry.nMemberId)
653             {
654                 lcl_setRubyCharstyle(rItemSet, rValue);
655             }
656             else
657             {
658                 bRet = false;
659             }
660         }
661         break;
662         case RES_PAGEDESC:
663         {
664             if (MID_PAGEDESC_PAGEDESCNAME == rEntry.nMemberId)
665             {
666                 SwUnoCursorHelper::SetPageDesc(
667                         rValue, *rPam.GetDoc(), rItemSet);
668             }
669             else
670             {
671                 bRet = false;
672             }
673         }
674         break;
675         default:
676             bRet = false;
677     }
678     return bRet;
679 }
680 
681 /* -----------------30.06.98 08:39-------------------
682  *
683  * --------------------------------------------------*/
684 SwFmtColl *
GetCurTxtFmtColl(SwPaM & rPaM,const bool bConditional)685 SwUnoCursorHelper::GetCurTxtFmtColl(SwPaM & rPaM, const bool bConditional)
686 {
687     static const sal_uInt16 nMaxLookup = 1000;
688     SwFmtColl *pFmt = 0;
689 
690 //  if ( GetCrsrCnt() > nMaxLookup )
691 //      return 0;
692     bool bError = false;
693     SwPaM *pTmpCrsr = &rPaM;
694     do
695     {
696         const sal_uLong nSttNd = pTmpCrsr->Start()->nNode.GetIndex();
697         const sal_uLong nEndNd = pTmpCrsr->End()->nNode.GetIndex();
698 
699         if( nEndNd - nSttNd >= nMaxLookup )
700         {
701             pFmt = 0;
702             break;
703         }
704 
705         const SwNodes& rNds = rPaM.GetDoc()->GetNodes();
706         for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
707         {
708             SwTxtNode const*const pNd = rNds[ n ]->GetTxtNode();
709             if( pNd )
710             {
711                 SwFmtColl *const pNdFmt = (bConditional)
712                     ? pNd->GetFmtColl() : &pNd->GetAnyFmtColl();
713                 if( !pFmt )
714                 {
715                     pFmt = pNdFmt;
716                 }
717                 else if( pFmt != pNdFmt )
718                 {
719                     bError = true;
720                     break;
721                 }
722             }
723         }
724 
725         pTmpCrsr = static_cast<SwPaM*>(pTmpCrsr->GetNext());
726     } while ( pTmpCrsr != &rPaM );
727     return (bError) ? 0 : pFmt;
728 }
729 
730 /* -----------------26.06.98 16:20-------------------
731  *  Hilfsfunktion fuer PageDesc
732  * --------------------------------------------------*/
GetPageDescByName_Impl(SwDoc & rDoc,const String & rName)733 SwPageDesc* GetPageDescByName_Impl(SwDoc& rDoc, const String& rName)
734 {
735     SwPageDesc* pRet = 0;
736     sal_uInt16 nDCount = rDoc.GetPageDescCnt();
737     sal_uInt16 i;
738 
739     for( i = 0; i < nDCount; i++ )
740     {
741         SwPageDesc* pDsc = &rDoc._GetPageDesc( i );
742         if(pDsc->GetName() == rName)
743         {
744             pRet = pDsc;
745             break;
746         }
747     }
748     if(!pRet)
749     {
750         for(i = RC_POOLPAGEDESC_BEGIN; i <= STR_POOLPAGE_LANDSCAPE; ++i)
751         {
752             const String aFmtName(SW_RES(i));
753             if(aFmtName == rName)
754             {
755                 pRet = rDoc.GetPageDescFromPool( static_cast< sal_uInt16 >(
756                             RES_POOLPAGE_BEGIN + i - RC_POOLPAGEDESC_BEGIN) );
757                 break;
758             }
759         }
760     }
761 
762     return pRet;
763  }
764 
765 /******************************************************************
766  * SwXTextCursor
767  ******************************************************************/
768 
769 class SwXTextCursor::Impl
770     : public SwClient
771 {
772 
773 public:
774 
775     const SfxItemPropertySet &  m_rPropSet;
776     const enum CursorType       m_eType;
777     const uno::Reference< text::XText > m_xParentText;
778     SwEventListenerContainer    m_ListenerContainer;
779     bool                        m_bIsDisposed;
780 
Impl(SwXTextCursor & rThis,SwDoc & rDoc,const enum CursorType eType,uno::Reference<text::XText> xParent,SwPosition const & rPoint,SwPosition const * const pMark)781     Impl(   SwXTextCursor & rThis,
782             SwDoc & rDoc,
783             const enum CursorType eType,
784             uno::Reference<text::XText> xParent,
785             SwPosition const& rPoint, SwPosition const*const pMark)
786         : SwClient(rDoc.CreateUnoCrsr(rPoint, sal_False))
787         , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
788         , m_eType(eType)
789         , m_xParentText(xParent)
790         , m_ListenerContainer(static_cast< ::cppu::OWeakObject* >(&rThis))
791         , m_bIsDisposed(false)
792     {
793         if (pMark)
794         {
795             GetCursor()->SetMark();
796             *GetCursor()->GetMark() = *pMark;
797         }
798     }
799 
~Impl()800     ~Impl() {
801         // Impl owns the cursor; delete it here: SolarMutex is locked
802         delete GetRegisteredIn();
803     }
804 
GetCursor()805     SwUnoCrsr * GetCursor() {
806         return (m_bIsDisposed) ? 0 :
807             static_cast<SwUnoCrsr*>(const_cast<SwModify*>(GetRegisteredIn()));
808     }
809 
GetCursorOrThrow()810     SwUnoCrsr & GetCursorOrThrow() {
811         SwUnoCrsr *const pUnoCursor( GetCursor() );
812         if (!pUnoCursor) {
813             throw uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
814                         "SwXTextCursor: disposed or invalid")), 0);
815         }
816         return *pUnoCursor;
817     }
818 
Invalidate()819     void Invalidate() {
820         m_bIsDisposed = true;
821         m_ListenerContainer.Disposing();
822     }
823 protected:
824     // SwClient
825     virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew);
826 
827 };
828 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)829 void SwXTextCursor::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
830 {
831     ClientModify(this, pOld, pNew);
832 
833     if (!GetRegisteredIn() ||
834         // if the cursor leaves its designated section, it becomes invalid
835         ((pOld != NULL) && (pOld->Which() == RES_UNOCURSOR_LEAVES_SECTION)))
836     {
837         Invalidate();
838     }
839 }
840 
841 
GetCursor() const842 SwUnoCrsr const* SwXTextCursor::GetCursor() const
843 {
844     return m_pImpl->GetCursor();
845 }
846 
GetCursor()847 SwUnoCrsr * SwXTextCursor::GetCursor()
848 {
849     return m_pImpl->GetCursor();
850 }
851 
852 /*-- 09.12.98 14:19:01---------------------------------------------------
853 
854   -----------------------------------------------------------------------*/
GetPaM() const855 SwPaM const* SwXTextCursor::GetPaM() const
856 {
857     return m_pImpl->GetCursor();
858 }
859 
GetPaM()860 SwPaM * SwXTextCursor::GetPaM()
861 {
862     return m_pImpl->GetCursor();
863 }
864 
865 /*-- 09.12.98 14:19:02---------------------------------------------------
866 
867   -----------------------------------------------------------------------*/
GetDoc() const868 SwDoc const* SwXTextCursor::GetDoc() const
869 {
870     return m_pImpl->GetCursor() ? m_pImpl->GetCursor()->GetDoc() : 0;
871 }
872 /* -----------------22.07.99 13:52-------------------
873 
874  --------------------------------------------------*/
GetDoc()875 SwDoc * SwXTextCursor::GetDoc()
876 {
877     return m_pImpl->GetCursor() ? m_pImpl->GetCursor()->GetDoc() : 0;
878 }
879 
880 
881 /*-- 09.12.98 14:19:19---------------------------------------------------
882 
883   -----------------------------------------------------------------------*/
SwXTextCursor(SwDoc & rDoc,uno::Reference<text::XText> const & xParent,const enum CursorType eType,const SwPosition & rPos,SwPosition const * const pMark)884 SwXTextCursor::SwXTextCursor(
885         SwDoc & rDoc,
886         uno::Reference< text::XText > const& xParent,
887         const enum CursorType eType,
888         const SwPosition& rPos,
889         SwPosition const*const pMark)
890     : m_pImpl( new SwXTextCursor::Impl(*this, rDoc, eType, xParent,
891                 rPos, pMark ) )
892 {
893 }
894 
895 /* -----------------04.03.99 09:02-------------------
896  *
897  * --------------------------------------------------*/
SwXTextCursor(uno::Reference<text::XText> const & xParent,SwPaM const & rSourceCursor,const enum CursorType eType)898 SwXTextCursor::SwXTextCursor(uno::Reference< text::XText > const& xParent,
899         SwPaM const& rSourceCursor, const enum CursorType eType)
900     : m_pImpl( new SwXTextCursor::Impl(*this, *rSourceCursor.GetDoc(), eType,
901                 xParent, *rSourceCursor.GetPoint(),
902                 rSourceCursor.HasMark() ? rSourceCursor.GetMark() : 0) )
903 {
904 }
905 
906 /*-- 09.12.98 14:19:20---------------------------------------------------
907 
908   -----------------------------------------------------------------------*/
~SwXTextCursor()909 SwXTextCursor::~SwXTextCursor()
910 {
911 }
912 
913 /*-- 09.12.98 14:19:18---------------------------------------------------
914 
915   -----------------------------------------------------------------------*/
DeleteAndInsert(const::rtl::OUString & rText,const bool bForceExpandHints)916 void SwXTextCursor::DeleteAndInsert(const ::rtl::OUString& rText,
917         const bool bForceExpandHints)
918 {
919     SwUnoCrsr *const pUnoCrsr = m_pImpl->GetCursor();
920     if(pUnoCrsr)
921     {
922         // Start/EndAction
923         SwDoc* pDoc = pUnoCrsr->GetDoc();
924         UnoActionContext aAction(pDoc);
925         const xub_StrLen nTxtLen = rText.getLength();
926         pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
927         SwCursor * pCurrent = pUnoCrsr;
928         do
929         {
930             if (pCurrent->HasMark())
931             {
932                 pDoc->DeleteAndJoin(*pCurrent);
933             }
934             if(nTxtLen)
935             {
936                 const bool bSuccess(
937                     SwUnoCursorHelper::DocInsertStringSplitCR(
938                         *pDoc, *pCurrent, rText, bForceExpandHints ) );
939                 DBG_ASSERT( bSuccess, "Doc->Insert(Str) failed." );
940                 (void) bSuccess;
941 
942                 SwUnoCursorHelper::SelectPam(*pUnoCrsr, true);
943                 pCurrent->Left(rText.getLength(),
944                         CRSR_SKIP_CHARS, sal_False, sal_False);
945             }
946             pCurrent = static_cast<SwCursor *>(pCurrent->GetNext());
947         } while (pCurrent != pUnoCrsr);
948         pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
949     }
950 }
951 
952 
953 enum ForceIntoMetaMode { META_CHECK_BOTH, META_INIT_START, META_INIT_END };
954 
955 static sal_Bool
lcl_ForceIntoMeta(SwPaM & rCursor,uno::Reference<text::XText> const & xParentText,const enum ForceIntoMetaMode eMode)956 lcl_ForceIntoMeta(SwPaM & rCursor,
957         uno::Reference<text::XText> const & xParentText,
958         const enum ForceIntoMetaMode eMode)
959 {
960     sal_Bool bRet( sal_True ); // means not forced in META_CHECK_BOTH
961     SwXMeta const * const pXMeta( dynamic_cast<SwXMeta*>(xParentText.get()) );
962     ASSERT(pXMeta, "no parent?");
963     if (!pXMeta)
964         throw uno::RuntimeException();
965     SwTxtNode * pTxtNode;
966     xub_StrLen nStart;
967     xub_StrLen nEnd;
968     const bool bSuccess( pXMeta->SetContentRange(pTxtNode, nStart, nEnd) );
969     ASSERT(bSuccess, "no pam?");
970     if (!bSuccess)
971         throw uno::RuntimeException();
972     // force the cursor back into the meta if it has moved outside
973     SwPosition start(*pTxtNode, nStart);
974     SwPosition end(*pTxtNode, nEnd);
975     switch (eMode)
976     {
977         case META_INIT_START:
978             *rCursor.GetPoint() = start;
979             break;
980         case META_INIT_END:
981             *rCursor.GetPoint() = end;
982             break;
983         case META_CHECK_BOTH:
984             if (*rCursor.Start() < start)
985             {
986                 *rCursor.Start() = start;
987                 bRet = sal_False;
988             }
989             if (*rCursor.End() > end)
990             {
991                 *rCursor.End() = end;
992                 bRet = sal_False;
993             }
994             break;
995     }
996     return bRet;
997 }
998 
IsAtEndOfMeta() const999 bool SwXTextCursor::IsAtEndOfMeta() const
1000 {
1001     if (CURSOR_META == m_pImpl->m_eType)
1002     {
1003         SwUnoCrsr const * const pCursor( m_pImpl->GetCursor() );
1004         SwXMeta const*const pXMeta(
1005                 dynamic_cast<SwXMeta*>(m_pImpl->m_xParentText.get()) );
1006         ASSERT(pXMeta, "no meta?");
1007         if (pCursor && pXMeta)
1008         {
1009             SwTxtNode * pTxtNode;
1010             xub_StrLen nStart;
1011             xub_StrLen nEnd;
1012             const bool bSuccess(
1013                     pXMeta->SetContentRange(pTxtNode, nStart, nEnd) );
1014             ASSERT(bSuccess, "no pam?");
1015             if (bSuccess)
1016             {
1017                 const SwPosition end(*pTxtNode, nEnd);
1018                 if (   (*pCursor->GetPoint() == end)
1019                     || (*pCursor->GetMark()  == end))
1020                 {
1021                     return true;
1022                 }
1023             }
1024         }
1025     }
1026     return false;
1027 }
1028 
1029 /*-- 09.12.98 14:19:19---------------------------------------------------
1030 
1031   -----------------------------------------------------------------------*/
getImplementationName()1032 OUString SwXTextCursor::getImplementationName()
1033 {
1034     return C2U("SwXTextCursor");
1035 }
1036 
1037 /*-- 09.12.98 14:19:19---------------------------------------------------
1038 
1039   -----------------------------------------------------------------------*/
1040 static char const*const g_ServicesTextCursor[] =
1041 {
1042     "com.sun.star.text.TextCursor",
1043     "com.sun.star.style.CharacterProperties",
1044     "com.sun.star.style.CharacterPropertiesAsian",
1045     "com.sun.star.style.CharacterPropertiesComplex",
1046     "com.sun.star.style.ParagraphProperties",
1047     "com.sun.star.style.ParagraphPropertiesAsian",
1048     "com.sun.star.style.ParagraphPropertiesComplex",
1049     "com.sun.star.text.TextSortable",
1050 };
1051 static const size_t g_nServicesTextCursor(
1052     sizeof(g_ServicesTextCursor)/sizeof(g_ServicesTextCursor[0]));
1053 
supportsService(const OUString & rServiceName)1054 sal_Bool SAL_CALL SwXTextCursor::supportsService(const OUString& rServiceName)
1055 {
1056     return ::sw::SupportsServiceImpl(
1057             g_nServicesTextCursor, g_ServicesTextCursor, rServiceName);
1058 }
1059 
1060 uno::Sequence< OUString > SAL_CALL
getSupportedServiceNames()1061 SwXTextCursor::getSupportedServiceNames()
1062 {
1063     return ::sw::GetSupportedServiceNamesImpl(
1064             g_nServicesTextCursor, g_ServicesTextCursor);
1065 }
1066 
1067 /* -----------------------------10.03.00 18:02--------------------------------
1068 
1069  ---------------------------------------------------------------------------*/
getUnoTunnelId()1070 const uno::Sequence< sal_Int8 > & SwXTextCursor::getUnoTunnelId()
1071 {
1072     static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
1073     return aSeq;
1074 }
1075 /* -----------------------------10.03.00 18:04--------------------------------
1076 
1077  ---------------------------------------------------------------------------*/
1078 sal_Int64 SAL_CALL
getSomething(const uno::Sequence<sal_Int8> & rId)1079 SwXTextCursor::getSomething(const uno::Sequence< sal_Int8 >& rId)
1080 {
1081     const sal_Int64 nRet( ::sw::UnoTunnelImpl<SwXTextCursor>(rId, this) );
1082     return (nRet) ? nRet : OTextCursorHelper::getSomething(rId);
1083 }
1084 
1085 /*-- 09.12.98 14:18:12---------------------------------------------------
1086 
1087   -----------------------------------------------------------------------*/
collapseToStart()1088 void SAL_CALL SwXTextCursor::collapseToStart()
1089 {
1090     vos::OGuard aGuard(Application::GetSolarMutex());
1091 
1092     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1093 
1094     if (rUnoCursor.HasMark())
1095     {
1096         if (*rUnoCursor.GetPoint() > *rUnoCursor.GetMark())
1097         {
1098             rUnoCursor.Exchange();
1099         }
1100         rUnoCursor.DeleteMark();
1101     }
1102 }
1103 /*-- 09.12.98 14:18:14---------------------------------------------------
1104 
1105   -----------------------------------------------------------------------*/
collapseToEnd()1106 void SAL_CALL SwXTextCursor::collapseToEnd()
1107 {
1108     vos::OGuard aGuard(Application::GetSolarMutex());
1109 
1110     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1111 
1112     if (rUnoCursor.HasMark())
1113     {
1114         if (*rUnoCursor.GetPoint() < *rUnoCursor.GetMark())
1115         {
1116             rUnoCursor.Exchange();
1117         }
1118         rUnoCursor.DeleteMark();
1119     }
1120 }
1121 /*-- 09.12.98 14:18:41---------------------------------------------------
1122 
1123   -----------------------------------------------------------------------*/
isCollapsed()1124 sal_Bool SAL_CALL SwXTextCursor::isCollapsed()
1125 {
1126     vos::OGuard aGuard(Application::GetSolarMutex());
1127 
1128     sal_Bool bRet = sal_True;
1129     SwUnoCrsr *const pUnoCrsr = m_pImpl->GetCursor();
1130     if(pUnoCrsr && pUnoCrsr->GetMark())
1131     {
1132         bRet = (*pUnoCrsr->GetPoint() == *pUnoCrsr->GetMark());
1133     }
1134     return bRet;
1135 }
1136 
1137 /*-- 09.12.98 14:18:42---------------------------------------------------
1138 
1139   -----------------------------------------------------------------------*/
1140 sal_Bool SAL_CALL
goLeft(sal_Int16 nCount,sal_Bool Expand)1141 SwXTextCursor::goLeft(sal_Int16 nCount, sal_Bool Expand)
1142 {
1143     vos::OGuard aGuard(Application::GetSolarMutex());
1144 
1145     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1146 
1147     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1148     sal_Bool bRet = rUnoCursor.Left( nCount, CRSR_SKIP_CHARS, sal_False, sal_False);
1149     if (CURSOR_META == m_pImpl->m_eType)
1150     {
1151         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1152                     META_CHECK_BOTH)
1153             && bRet;
1154     }
1155     return bRet;
1156 }
1157 /*-- 09.12.98 14:18:42---------------------------------------------------
1158 
1159   -----------------------------------------------------------------------*/
1160 sal_Bool SAL_CALL
goRight(sal_Int16 nCount,sal_Bool Expand)1161 SwXTextCursor::goRight(sal_Int16 nCount, sal_Bool Expand)
1162 {
1163     vos::OGuard aGuard(Application::GetSolarMutex());
1164 
1165     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1166 
1167     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1168     sal_Bool bRet = rUnoCursor.Right(nCount, CRSR_SKIP_CHARS, sal_False, sal_False);
1169     if (CURSOR_META == m_pImpl->m_eType)
1170     {
1171         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1172                     META_CHECK_BOTH)
1173             && bRet;
1174     }
1175     return bRet;
1176 }
1177 
1178 /*-- 09.12.98 14:18:43---------------------------------------------------
1179 
1180   -----------------------------------------------------------------------*/
1181 void SAL_CALL
gotoStart(sal_Bool Expand)1182 SwXTextCursor::gotoStart(sal_Bool Expand)
1183 {
1184     vos::OGuard aGuard(Application::GetSolarMutex());
1185 
1186     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1187 
1188     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1189     if (CURSOR_BODY == m_pImpl->m_eType)
1190     {
1191         rUnoCursor.Move( fnMoveBackward, fnGoDoc );
1192         //check, that the cursor is not in a table
1193         SwTableNode * pTblNode = rUnoCursor.GetNode()->FindTableNode();
1194         SwCntntNode * pCNode = 0;
1195         while (pTblNode)
1196         {
1197             rUnoCursor.GetPoint()->nNode = *pTblNode->EndOfSectionNode();
1198             pCNode = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode);
1199             pTblNode = (pCNode) ? pCNode->FindTableNode() : 0;
1200         }
1201         if (pCNode)
1202         {
1203             rUnoCursor.GetPoint()->nContent.Assign(pCNode, 0);
1204         }
1205         SwStartNode const*const pTmp =
1206             rUnoCursor.GetNode()->StartOfSectionNode();
1207         if (pTmp->IsSectionNode())
1208         {
1209             SwSectionNode const*const pSectionStartNode =
1210                 static_cast<SwSectionNode const*>(pTmp);
1211             if (pSectionStartNode->GetSection().IsHiddenFlag())
1212             {
1213                 pCNode = GetDoc()->GetNodes().GoNextSection(
1214                         &rUnoCursor.GetPoint()->nNode, sal_True, sal_False);
1215                 if (pCNode)
1216                 {
1217                     rUnoCursor.GetPoint()->nContent.Assign(pCNode, 0);
1218                 }
1219             }
1220         }
1221     }
1222     else if (   (CURSOR_FRAME   == m_pImpl->m_eType)
1223             ||  (CURSOR_TBLTEXT == m_pImpl->m_eType)
1224             ||  (CURSOR_HEADER  == m_pImpl->m_eType)
1225             ||  (CURSOR_FOOTER  == m_pImpl->m_eType)
1226             ||  (CURSOR_FOOTNOTE== m_pImpl->m_eType)
1227             ||  (CURSOR_REDLINE == m_pImpl->m_eType))
1228     {
1229         rUnoCursor.MoveSection(fnSectionCurr, fnSectionStart);
1230     }
1231     else if (CURSOR_META == m_pImpl->m_eType)
1232     {
1233         lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, META_INIT_START);
1234     }
1235 }
1236 /*-- 09.12.98 14:18:43---------------------------------------------------
1237 
1238   -----------------------------------------------------------------------*/
1239 void SAL_CALL
gotoEnd(sal_Bool Expand)1240 SwXTextCursor::gotoEnd(sal_Bool Expand)
1241 {
1242     vos::OGuard aGuard(Application::GetSolarMutex());
1243 
1244     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1245 
1246     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1247     if (CURSOR_BODY == m_pImpl->m_eType)
1248     {
1249         rUnoCursor.Move( fnMoveForward, fnGoDoc );
1250     }
1251     else if (   (CURSOR_FRAME   == m_pImpl->m_eType)
1252             ||  (CURSOR_TBLTEXT == m_pImpl->m_eType)
1253             ||  (CURSOR_HEADER  == m_pImpl->m_eType)
1254             ||  (CURSOR_FOOTER  == m_pImpl->m_eType)
1255             ||  (CURSOR_FOOTNOTE== m_pImpl->m_eType)
1256             ||  (CURSOR_REDLINE == m_pImpl->m_eType))
1257     {
1258         rUnoCursor.MoveSection( fnSectionCurr, fnSectionEnd);
1259     }
1260     else if (CURSOR_META == m_pImpl->m_eType)
1261     {
1262         lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText, META_INIT_END);
1263     }
1264 }
1265 
1266 void SAL_CALL
gotoRange(const uno::Reference<text::XTextRange> & xRange,sal_Bool bExpand)1267 SwXTextCursor::gotoRange(
1268     const uno::Reference< text::XTextRange > & xRange, sal_Bool bExpand)
1269 {
1270     vos::OGuard aGuard(Application::GetSolarMutex());
1271 
1272     if (!xRange.is())
1273     {
1274         throw uno::RuntimeException();
1275     }
1276 
1277     SwUnoCrsr & rOwnCursor( m_pImpl->GetCursorOrThrow() );
1278 
1279     uno::Reference<lang::XUnoTunnel> xRangeTunnel( xRange, uno::UNO_QUERY);
1280     SwXTextRange* pRange = 0;
1281     OTextCursorHelper* pCursor = 0;
1282     if(xRangeTunnel.is())
1283     {
1284         pRange  = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
1285         pCursor =
1286             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
1287     }
1288 
1289     if (!pRange && !pCursor)
1290     {
1291         throw uno::RuntimeException();
1292     }
1293 
1294     SwPaM aPam(GetDoc()->GetNodes());
1295     const SwPaM * pPam(0);
1296     if (pCursor)
1297     {
1298         pPam = pCursor->GetPaM();
1299     }
1300     else if (pRange)
1301     {
1302         if (pRange->GetPositions(aPam))
1303         {
1304             pPam = & aPam;
1305         }
1306     }
1307 
1308     if (!pPam)
1309     {
1310         throw uno::RuntimeException();
1311     }
1312 
1313     {
1314         SwStartNodeType eSearchNodeType = SwNormalStartNode;
1315         switch (m_pImpl->m_eType)
1316         {
1317         case CURSOR_FRAME:      eSearchNodeType = SwFlyStartNode;       break;
1318         case CURSOR_TBLTEXT:    eSearchNodeType = SwTableBoxStartNode;  break;
1319         case CURSOR_FOOTNOTE:   eSearchNodeType = SwFootnoteStartNode;  break;
1320         case CURSOR_HEADER:     eSearchNodeType = SwHeaderStartNode;    break;
1321         case CURSOR_FOOTER:     eSearchNodeType = SwFooterStartNode;    break;
1322             //case CURSOR_INVALID:
1323             //case CURSOR_BODY:
1324         default:
1325             ;
1326         }
1327 
1328         const SwStartNode* pOwnStartNode = rOwnCursor.GetNode()->FindSttNodeByType(eSearchNodeType);
1329         while ( pOwnStartNode != NULL
1330                 && pOwnStartNode->IsSectionNode())
1331         {
1332             pOwnStartNode = pOwnStartNode->StartOfSectionNode();
1333         }
1334 
1335         const SwStartNode* pTmp =
1336             pPam->GetNode()->FindSttNodeByType(eSearchNodeType);
1337         while ( pTmp != NULL
1338                 && pTmp->IsSectionNode() )
1339         {
1340             pTmp = pTmp->StartOfSectionNode();
1341         }
1342 
1343         if ( eSearchNodeType == SwTableBoxStartNode )
1344         {
1345             if ( pOwnStartNode->FindTableNode() != pTmp->FindTableNode() )
1346             {
1347                 throw uno::RuntimeException();
1348             }
1349         }
1350         else
1351         {
1352             if ( pOwnStartNode != pTmp )
1353             {
1354                 throw uno::RuntimeException();
1355             }
1356         }
1357     }
1358 
1359     if (CURSOR_META == m_pImpl->m_eType)
1360     {
1361         SwPaM CopyPam(*pPam->GetMark(), *pPam->GetPoint());
1362         const bool bNotForced( lcl_ForceIntoMeta(
1363                     CopyPam, m_pImpl->m_xParentText, META_CHECK_BOTH) );
1364         if (!bNotForced)
1365         {
1366             throw uno::RuntimeException(
1367                 C2U("gotoRange: parameter range not contained in nesting"
1368                     " text content for which this cursor was created"),
1369                 static_cast<text::XWordCursor*>(this));
1370         }
1371     }
1372 
1373     //jetzt muss die Selektion erweitert werden
1374     if(bExpand)
1375     {
1376         // der Cursor soll alles einschliessen, was bisher von ihm und dem uebergebenen
1377         // Range eingeschlossen wurde
1378         const SwPosition aOwnLeft(*rOwnCursor.Start());
1379         const SwPosition aOwnRight(*rOwnCursor.End());
1380         SwPosition const& rParamLeft  = *pPam->Start();
1381         SwPosition const& rParamRight = *pPam->End();
1382 
1383         // jetzt sind vier SwPositions da, zwei davon werden gebraucht, also welche?
1384         *rOwnCursor.GetPoint() = (aOwnRight > rParamRight)
1385             ? aOwnRight : *rOwnCursor.GetPoint() = rParamRight;
1386         rOwnCursor.SetMark();
1387         *rOwnCursor.GetMark() = (aOwnLeft < rParamLeft)
1388             ? aOwnLeft : *rOwnCursor.GetMark() = rParamLeft;
1389     }
1390     else
1391     {
1392         // cursor should be the given range
1393         *rOwnCursor.GetPoint() = *pPam->GetPoint();
1394         if (pPam->HasMark())
1395         {
1396             rOwnCursor.SetMark();
1397             *rOwnCursor.GetMark() = *pPam->GetMark();
1398         }
1399         else
1400         {
1401             rOwnCursor.DeleteMark();
1402         }
1403     }
1404 }
1405 
1406 /*-- 09.12.98 14:18:44---------------------------------------------------
1407 
1408   -----------------------------------------------------------------------*/
isStartOfWord()1409 sal_Bool SAL_CALL SwXTextCursor::isStartOfWord()
1410 {
1411     vos::OGuard aGuard(Application::GetSolarMutex());
1412 
1413     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1414 
1415     const sal_Bool bRet =
1416         rUnoCursor.IsStartWordWT( i18n::WordType::DICTIONARY_WORD );
1417     return bRet;
1418 }
1419 /*-- 09.12.98 14:18:44---------------------------------------------------
1420 
1421   -----------------------------------------------------------------------*/
isEndOfWord()1422 sal_Bool SAL_CALL SwXTextCursor::isEndOfWord()
1423 {
1424     vos::OGuard aGuard(Application::GetSolarMutex());
1425 
1426     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1427 
1428     const sal_Bool bRet =
1429         rUnoCursor.IsEndWordWT( i18n::WordType::DICTIONARY_WORD );
1430     return bRet;
1431 }
1432 
1433 /*-- 09.12.98 14:18:44---------------------------------------------------
1434 
1435   -----------------------------------------------------------------------*/
1436 sal_Bool SAL_CALL
gotoNextWord(sal_Bool Expand)1437 SwXTextCursor::gotoNextWord(sal_Bool Expand)
1438 {
1439     vos::OGuard aGuard(Application::GetSolarMutex());
1440 
1441     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1442 
1443     //Probleme gibt's noch mit einem Absatzanfang, an dem kein Wort beginnt.
1444     sal_Bool bRet = sal_False;
1445     // remember old position to check if cursor has moved
1446     // since the called functions are sometimes a bit unreliable
1447     // in specific cases...
1448     SwPosition  *const pPoint     = rUnoCursor.GetPoint();
1449     SwNode      *const pOldNode   = &pPoint->nNode.GetNode();
1450     xub_StrLen   const nOldIndex  = pPoint->nContent.GetIndex();
1451 
1452     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1453     // end of paragraph
1454     if (rUnoCursor.GetCntntNode() &&
1455             (pPoint->nContent == rUnoCursor.GetCntntNode()->Len()))
1456     {
1457         rUnoCursor.Right(1, CRSR_SKIP_CHARS, sal_False, sal_False);
1458     }
1459     else
1460     {
1461         const bool bTmp =
1462             rUnoCursor.GoNextWordWT( i18n::WordType::DICTIONARY_WORD );
1463         // if there is no next word within the current paragraph
1464         // try to go to the start of the next paragraph
1465         if (!bTmp)
1466         {
1467             rUnoCursor.MovePara(fnParaNext, fnParaStart);
1468         }
1469     }
1470 
1471     // return true if cursor has moved
1472     bRet =  (&pPoint->nNode.GetNode() != pOldNode)  ||
1473             (pPoint->nContent.GetIndex() != nOldIndex);
1474     if (bRet && (CURSOR_META == m_pImpl->m_eType))
1475     {
1476         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1477                     META_CHECK_BOTH);
1478     }
1479 
1480     return bRet;
1481 }
1482 
1483 /*-- 09.12.98 14:18:45---------------------------------------------------
1484 
1485   -----------------------------------------------------------------------*/
1486 sal_Bool SAL_CALL
gotoPreviousWord(sal_Bool Expand)1487 SwXTextCursor::gotoPreviousWord(sal_Bool Expand)
1488 {
1489     vos::OGuard aGuard(Application::GetSolarMutex());
1490 
1491     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1492 
1493     // hier machen Leerzeichen am Absatzanfang Probleme
1494     sal_Bool bRet = sal_False;
1495     SwPosition  *const pPoint     = rUnoCursor.GetPoint();
1496     SwNode      *const pOldNode   = &pPoint->nNode.GetNode();
1497     xub_StrLen   const nOldIndex  = pPoint->nContent.GetIndex();
1498 
1499     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1500     // start of paragraph?
1501     if (pPoint->nContent == 0)
1502     {
1503         rUnoCursor.Left(1, CRSR_SKIP_CHARS, sal_False, sal_False);
1504     }
1505     else
1506     {
1507         rUnoCursor.GoPrevWordWT( i18n::WordType::DICTIONARY_WORD );
1508         if (pPoint->nContent == 0)
1509         {
1510             rUnoCursor.Left(1, CRSR_SKIP_CHARS, sal_False, sal_False);
1511         }
1512     }
1513 
1514     // return true if cursor has moved
1515     bRet =  (&pPoint->nNode.GetNode() != pOldNode)  ||
1516             (pPoint->nContent.GetIndex() != nOldIndex);
1517     if (bRet && (CURSOR_META == m_pImpl->m_eType))
1518     {
1519         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1520                     META_CHECK_BOTH);
1521     }
1522 
1523     return bRet;
1524 }
1525 
1526 /*-- 09.12.98 14:18:45---------------------------------------------------
1527 
1528   -----------------------------------------------------------------------*/
1529 sal_Bool SAL_CALL
gotoEndOfWord(sal_Bool Expand)1530 SwXTextCursor::gotoEndOfWord(sal_Bool Expand)
1531 {
1532     vos::OGuard aGuard(Application::GetSolarMutex());
1533 
1534     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1535 
1536     sal_Bool bRet = sal_False;
1537     SwPosition  *const pPoint     = rUnoCursor.GetPoint();
1538     SwNode      &      rOldNode   = pPoint->nNode.GetNode();
1539     xub_StrLen   const nOldIndex  = pPoint->nContent.GetIndex();
1540 
1541     const sal_Int16 nWordType = i18n::WordType::DICTIONARY_WORD;
1542     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1543     if (!rUnoCursor.IsEndWordWT( nWordType ))
1544     {
1545         rUnoCursor.GoEndWordWT( nWordType );
1546     }
1547 
1548     // restore old cursor if we are not at the end of a word by now
1549     // otherwise use current one
1550     bRet = rUnoCursor.IsEndWordWT( nWordType );
1551     if (!bRet)
1552     {
1553         pPoint->nNode       = rOldNode;
1554         pPoint->nContent    = nOldIndex;
1555     }
1556     else if (CURSOR_META == m_pImpl->m_eType)
1557     {
1558         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1559                     META_CHECK_BOTH);
1560     }
1561 
1562     return bRet;
1563 }
1564 /*-- 09.12.98 14:18:46---------------------------------------------------
1565 
1566   -----------------------------------------------------------------------*/
1567 sal_Bool SAL_CALL
gotoStartOfWord(sal_Bool Expand)1568 SwXTextCursor::gotoStartOfWord(sal_Bool Expand)
1569 {
1570     vos::OGuard aGuard(Application::GetSolarMutex());
1571 
1572     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1573 
1574     sal_Bool bRet = sal_False;
1575     SwPosition  *const pPoint     = rUnoCursor.GetPoint();
1576     SwNode      &      rOldNode   = pPoint->nNode.GetNode();
1577     xub_StrLen   const nOldIndex  = pPoint->nContent.GetIndex();
1578 
1579     const sal_Int16 nWordType = i18n::WordType::DICTIONARY_WORD;
1580     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1581     if (!rUnoCursor.IsStartWordWT( nWordType ))
1582     {
1583         rUnoCursor.GoStartWordWT( nWordType );
1584     }
1585 
1586     // restore old cursor if we are not at the start of a word by now
1587     // otherwise use current one
1588     bRet = rUnoCursor.IsStartWordWT( nWordType );
1589     if (!bRet)
1590     {
1591         pPoint->nNode       = rOldNode;
1592         pPoint->nContent    = nOldIndex;
1593     }
1594     else if (CURSOR_META == m_pImpl->m_eType)
1595     {
1596         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1597                     META_CHECK_BOTH);
1598     }
1599 
1600     return bRet;
1601 }
1602 
1603 /*-- 09.12.98 14:18:46---------------------------------------------------
1604 
1605   -----------------------------------------------------------------------*/
1606 sal_Bool SAL_CALL
isStartOfSentence()1607 SwXTextCursor::isStartOfSentence()
1608 {
1609     vos::OGuard aGuard(Application::GetSolarMutex());
1610 
1611     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1612 
1613     // start of paragraph?
1614     sal_Bool bRet = rUnoCursor.GetPoint()->nContent == 0;
1615     // with mark ->no sentence start
1616     // (check if cursor is no selection, i.e. it does not have
1617     // a mark or else point and mark are identical)
1618     if (!bRet && (!rUnoCursor.HasMark() ||
1619                     *rUnoCursor.GetPoint() == *rUnoCursor.GetMark()))
1620     {
1621         SwCursor aCrsr(*rUnoCursor.GetPoint(),0,false);
1622         SwPosition aOrigPos = *aCrsr.GetPoint();
1623         aCrsr.GoSentence(SwCursor::START_SENT );
1624         bRet = aOrigPos == *aCrsr.GetPoint();
1625     }
1626     return bRet;
1627 }
1628 /*-- 09.12.98 14:18:47---------------------------------------------------
1629 
1630   -----------------------------------------------------------------------*/
1631 sal_Bool SAL_CALL
isEndOfSentence()1632 SwXTextCursor::isEndOfSentence()
1633 {
1634     vos::OGuard aGuard(Application::GetSolarMutex());
1635 
1636     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1637 
1638     // end of paragraph?
1639     sal_Bool bRet = rUnoCursor.GetCntntNode() &&
1640         (rUnoCursor.GetPoint()->nContent == rUnoCursor.GetCntntNode()->Len());
1641     // with mark->no sentence end
1642     // (check if cursor is no selection, i.e. it does not have
1643     // a mark or else point and mark are identical)
1644     if (!bRet && (!rUnoCursor.HasMark() ||
1645                     *rUnoCursor.GetPoint() == *rUnoCursor.GetMark()))
1646     {
1647         SwCursor aCrsr(*rUnoCursor.GetPoint(), 0, false);
1648         SwPosition aOrigPos = *aCrsr.GetPoint();
1649         aCrsr.GoSentence(SwCursor::END_SENT);
1650         bRet = aOrigPos == *aCrsr.GetPoint();
1651     }
1652     return bRet;
1653 }
1654 
1655 /*-- 09.12.98 14:18:47---------------------------------------------------
1656 
1657   -----------------------------------------------------------------------*/
1658 sal_Bool SAL_CALL
gotoNextSentence(sal_Bool Expand)1659 SwXTextCursor::gotoNextSentence(sal_Bool Expand)
1660 {
1661     vos::OGuard aGuard(Application::GetSolarMutex());
1662 
1663     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1664 
1665     const bool bWasEOS = isEndOfSentence();
1666     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1667     sal_Bool bRet = rUnoCursor.GoSentence(SwCursor::NEXT_SENT);
1668     if (!bRet)
1669     {
1670         bRet = rUnoCursor.MovePara(fnParaNext, fnParaStart);
1671     }
1672 
1673     // if at the end of the sentence (i.e. at the space after the '.')
1674     // advance to next word in order for GoSentence to work properly
1675     // next time and have isStartOfSentence return true after this call
1676     if (!rUnoCursor.IsStartWord())
1677     {
1678         const bool bNextWord = rUnoCursor.GoNextWord();
1679         if (bWasEOS && !bNextWord)
1680         {
1681             bRet = sal_False;
1682         }
1683     }
1684     if (CURSOR_META == m_pImpl->m_eType)
1685     {
1686         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1687                     META_CHECK_BOTH)
1688             && bRet;
1689     }
1690     return bRet;
1691 }
1692 /*-- 09.12.98 14:18:47---------------------------------------------------
1693 
1694   -----------------------------------------------------------------------*/
1695 sal_Bool SAL_CALL
gotoPreviousSentence(sal_Bool Expand)1696 SwXTextCursor::gotoPreviousSentence(sal_Bool Expand)
1697 {
1698     vos::OGuard aGuard(Application::GetSolarMutex());
1699 
1700     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1701 
1702     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1703     sal_Bool bRet = rUnoCursor.GoSentence(SwCursor::PREV_SENT);
1704     if (!bRet)
1705     {
1706         bRet = rUnoCursor.MovePara(fnParaPrev, fnParaStart);
1707         if (bRet)
1708         {
1709             rUnoCursor.MovePara(fnParaCurr, fnParaEnd);
1710             // at the end of a paragraph move to the sentence end again
1711             rUnoCursor.GoSentence(SwCursor::PREV_SENT);
1712         }
1713     }
1714     if (CURSOR_META == m_pImpl->m_eType)
1715     {
1716         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1717                     META_CHECK_BOTH)
1718             && bRet;
1719     }
1720     return bRet;
1721 }
1722 
1723 /* -----------------15.10.99 08:24-------------------
1724 
1725  --------------------------------------------------*/
1726 sal_Bool SAL_CALL
gotoStartOfSentence(sal_Bool Expand)1727 SwXTextCursor::gotoStartOfSentence(sal_Bool Expand)
1728 {
1729     vos::OGuard aGuard(Application::GetSolarMutex());
1730 
1731     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1732 
1733     sal_Bool bRet = sal_False;
1734     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1735     // if we're at the para start then we won't move
1736     // but bRet is also true if GoSentence failed but
1737     // the start of the sentence is reached
1738     bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor)
1739         || rUnoCursor.GoSentence(SwCursor::START_SENT)
1740         || SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
1741     if (CURSOR_META == m_pImpl->m_eType)
1742     {
1743         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1744                     META_CHECK_BOTH)
1745             && bRet;
1746     }
1747     return bRet;
1748 }
1749 /* -----------------15.10.99 08:24-------------------
1750 
1751  --------------------------------------------------*/
1752 sal_Bool SAL_CALL
gotoEndOfSentence(sal_Bool Expand)1753 SwXTextCursor::gotoEndOfSentence(sal_Bool Expand)
1754 {
1755     vos::OGuard aGuard(Application::GetSolarMutex());
1756 
1757     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1758 
1759     sal_Bool bRet = sal_False;
1760     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1761     // bRet is true if GoSentence() succeeded or if the
1762     // MovePara() succeeded while the end of the para is
1763     // not reached already
1764     sal_Bool bAlreadyParaEnd = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
1765     bRet = !bAlreadyParaEnd
1766             &&  (rUnoCursor.GoSentence(SwCursor::END_SENT)
1767                  || rUnoCursor.MovePara(fnParaCurr, fnParaEnd));
1768     if (CURSOR_META == m_pImpl->m_eType)
1769     {
1770         bRet = lcl_ForceIntoMeta(rUnoCursor, m_pImpl->m_xParentText,
1771                     META_CHECK_BOTH)
1772             && bRet;
1773     }
1774     return bRet;
1775 }
1776 
1777 /*-- 09.12.98 14:18:48---------------------------------------------------
1778 
1779   -----------------------------------------------------------------------*/
1780 sal_Bool SAL_CALL
isStartOfParagraph()1781 SwXTextCursor::isStartOfParagraph()
1782 {
1783     vos::OGuard aGuard(Application::GetSolarMutex());
1784 
1785     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1786 
1787     const sal_Bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
1788     return bRet;
1789 }
1790 /*-- 09.12.98 14:18:48---------------------------------------------------
1791 
1792   -----------------------------------------------------------------------*/
1793 sal_Bool SAL_CALL
isEndOfParagraph()1794 SwXTextCursor::isEndOfParagraph()
1795 {
1796     vos::OGuard aGuard(Application::GetSolarMutex());
1797 
1798     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1799 
1800     const sal_Bool bRet = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
1801     return bRet;
1802 }
1803 
1804 /*-- 09.12.98 14:18:49---------------------------------------------------
1805 
1806   -----------------------------------------------------------------------*/
1807 sal_Bool SAL_CALL
gotoStartOfParagraph(sal_Bool Expand)1808 SwXTextCursor::gotoStartOfParagraph(sal_Bool Expand)
1809 {
1810     vos::OGuard aGuard(Application::GetSolarMutex());
1811 
1812     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1813 
1814     if (CURSOR_META == m_pImpl->m_eType)
1815     {
1816         return sal_False;
1817     }
1818     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1819     sal_Bool bRet = SwUnoCursorHelper::IsStartOfPara(rUnoCursor);
1820     if (!bRet)
1821     {
1822         bRet = rUnoCursor.MovePara(fnParaCurr, fnParaStart);
1823     }
1824 
1825     // since MovePara(fnParaCurr, fnParaStart) only returns false
1826     // if we were already at the start of the paragraph this function
1827     // should always complete successfully.
1828     DBG_ASSERT( bRet, "gotoStartOfParagraph failed" );
1829     return bRet;
1830 }
1831 /*-- 09.12.98 14:18:49---------------------------------------------------
1832 
1833   -----------------------------------------------------------------------*/
1834 sal_Bool SAL_CALL
gotoEndOfParagraph(sal_Bool Expand)1835 SwXTextCursor::gotoEndOfParagraph(sal_Bool Expand)
1836 {
1837     vos::OGuard aGuard(Application::GetSolarMutex());
1838 
1839     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1840 
1841     if (CURSOR_META == m_pImpl->m_eType)
1842     {
1843         return sal_False;
1844     }
1845     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1846     sal_Bool bRet = SwUnoCursorHelper::IsEndOfPara(rUnoCursor);
1847     if (!bRet)
1848     {
1849         bRet = rUnoCursor.MovePara(fnParaCurr, fnParaEnd);
1850     }
1851 
1852     // since MovePara(fnParaCurr, fnParaEnd) only returns false
1853     // if we were already at the end of the paragraph this function
1854     // should always complete successfully.
1855     DBG_ASSERT( bRet, "gotoEndOfParagraph failed" );
1856     return bRet;
1857 }
1858 
1859 /*-- 09.12.98 14:18:50---------------------------------------------------
1860 
1861   -----------------------------------------------------------------------*/
1862 sal_Bool SAL_CALL
gotoNextParagraph(sal_Bool Expand)1863 SwXTextCursor::gotoNextParagraph(sal_Bool Expand)
1864 {
1865     vos::OGuard aGuard(Application::GetSolarMutex());
1866 
1867     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1868 
1869     if (CURSOR_META == m_pImpl->m_eType)
1870     {
1871         return sal_False;
1872     }
1873     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1874     const sal_Bool bRet = rUnoCursor.MovePara(fnParaNext, fnParaStart);
1875     return bRet;
1876 }
1877 /*-- 09.12.98 14:18:50---------------------------------------------------
1878 
1879   -----------------------------------------------------------------------*/
1880 sal_Bool SAL_CALL
gotoPreviousParagraph(sal_Bool Expand)1881 SwXTextCursor::gotoPreviousParagraph(sal_Bool Expand)
1882 {
1883     vos::OGuard aGuard(Application::GetSolarMutex());
1884 
1885     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1886 
1887     if (CURSOR_META == m_pImpl->m_eType)
1888     {
1889         return sal_False;
1890     }
1891     SwUnoCursorHelper::SelectPam(rUnoCursor, Expand);
1892     const sal_Bool bRet = rUnoCursor.MovePara(fnParaPrev, fnParaStart);
1893     return bRet;
1894 }
1895 
1896 /*-- 09.12.98 14:18:50---------------------------------------------------
1897 
1898   -----------------------------------------------------------------------*/
1899 uno::Reference< text::XText > SAL_CALL
getText()1900 SwXTextCursor::getText()
1901 {
1902     vos::OGuard g(Application::GetSolarMutex());
1903 
1904     return m_pImpl->m_xParentText;
1905 }
1906 
1907 /*-- 09.12.98 14:18:50---------------------------------------------------
1908 
1909   -----------------------------------------------------------------------*/
1910 uno::Reference< text::XTextRange > SAL_CALL
getStart()1911 SwXTextCursor::getStart()
1912 {
1913     vos::OGuard aGuard(Application::GetSolarMutex());
1914 
1915     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1916 
1917     uno::Reference< text::XTextRange > xRet;
1918     SwPaM aPam(*rUnoCursor.Start());
1919     const uno::Reference< text::XText >  xParent = getText();
1920     if (CURSOR_META == m_pImpl->m_eType)
1921     {
1922         // return cursor to prevent modifying SwXTextRange for META
1923         SwXTextCursor * const pXCursor(
1924             new SwXTextCursor(*rUnoCursor.GetDoc(), xParent, CURSOR_META,
1925                 *rUnoCursor.GetPoint()) );
1926         pXCursor->gotoStart(sal_False);
1927         xRet = static_cast<text::XWordCursor*>(pXCursor);
1928     }
1929     else
1930     {
1931         xRet = new SwXTextRange(aPam, xParent);
1932     }
1933     return xRet;
1934 }
1935 /*-- 09.12.98 14:18:51---------------------------------------------------
1936 
1937   -----------------------------------------------------------------------*/
1938 uno::Reference< text::XTextRange > SAL_CALL
getEnd()1939 SwXTextCursor::getEnd()
1940 {
1941     vos::OGuard aGuard(Application::GetSolarMutex());
1942 
1943     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1944 
1945     uno::Reference< text::XTextRange >  xRet;
1946     SwPaM aPam(*rUnoCursor.End());
1947     const uno::Reference< text::XText >  xParent = getText();
1948     if (CURSOR_META == m_pImpl->m_eType)
1949     {
1950         // return cursor to prevent modifying SwXTextRange for META
1951         SwXTextCursor * const pXCursor(
1952             new SwXTextCursor(*rUnoCursor.GetDoc(), xParent, CURSOR_META,
1953                 *rUnoCursor.GetPoint()) );
1954         pXCursor->gotoEnd(sal_False);
1955         xRet = static_cast<text::XWordCursor*>(pXCursor);
1956     }
1957     else
1958     {
1959         xRet = new SwXTextRange(aPam, xParent);
1960     }
1961     return xRet;
1962 }
1963 
1964 /*-- 09.12.98 14:18:51---------------------------------------------------
1965 
1966   -----------------------------------------------------------------------*/
getString()1967 OUString SAL_CALL SwXTextCursor::getString()
1968 {
1969     vos::OGuard aGuard(Application::GetSolarMutex());
1970 
1971     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1972 
1973     OUString aTxt;
1974     SwUnoCursorHelper::GetTextFromPam(rUnoCursor, aTxt);
1975     return aTxt;
1976 }
1977 /*-- 09.12.98 14:18:52---------------------------------------------------
1978 
1979   -----------------------------------------------------------------------*/
1980 void SAL_CALL
setString(const OUString & aString)1981 SwXTextCursor::setString(const OUString& aString)
1982 {
1983     vos::OGuard aGuard(Application::GetSolarMutex());
1984 
1985     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
1986     (void) rUnoCursor; // just to check if valid
1987 
1988     const bool bForceExpandHints( (CURSOR_META != m_pImpl->m_eType)
1989         ? false
1990         : dynamic_cast<SwXMeta*>(m_pImpl->m_xParentText.get())
1991                 ->CheckForOwnMemberMeta(*GetPaM(), true) );
1992     DeleteAndInsert(aString, bForceExpandHints);
1993 }
1994 
1995 /* -----------------------------03.05.00 12:56--------------------------------
1996 
1997  ---------------------------------------------------------------------------*/
GetPropertyValue(SwPaM & rPaM,const SfxItemPropertySet & rPropSet,const OUString & rPropertyName)1998 uno::Any SwUnoCursorHelper::GetPropertyValue(
1999     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
2000     const OUString& rPropertyName)
2001 {
2002     uno::Any aAny;
2003     SfxItemPropertySimpleEntry const*const pEntry =
2004         rPropSet.getPropertyMap()->getByName(rPropertyName);
2005 
2006     if (!pEntry)
2007     {
2008         throw beans::UnknownPropertyException(
2009             OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown property: "))
2010                 + rPropertyName, static_cast<cppu::OWeakObject *>(0));
2011     }
2012 
2013     beans::PropertyState eTemp;
2014     const sal_Bool bDone = SwUnoCursorHelper::getCrsrPropertyValue(
2015             *pEntry, rPaM, &aAny, eTemp );
2016 
2017     if (!bDone)
2018     {
2019         SfxItemSet aSet(rPaM.GetDoc()->GetAttrPool(),
2020             RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
2021             RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
2022             RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
2023             0L);
2024         SwUnoCursorHelper::GetCrsrAttr(rPaM, aSet);
2025 
2026         rPropSet.getPropertyValue(*pEntry, aSet, aAny);
2027     }
2028 
2029     return aAny;
2030 }
2031 /* -----------------------------03.05.00 12:57--------------------------------
2032 
2033  ---------------------------------------------------------------------------*/
SetPropertyValue(SwPaM & rPaM,const SfxItemPropertySet & rPropSet,const OUString & rPropertyName,const uno::Any & rValue,const SetAttrMode nAttrMode,const bool bTableMode)2034 void SwUnoCursorHelper::SetPropertyValue(
2035     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
2036     const OUString& rPropertyName,
2037     const uno::Any& rValue,
2038     const SetAttrMode nAttrMode, const bool bTableMode)
2039 {
2040     SwDoc *const pDoc = rPaM.GetDoc();
2041     SfxItemPropertySimpleEntry const*const pEntry =
2042         rPropSet.getPropertyMap()->getByName(rPropertyName);
2043     if (!pEntry)
2044     {
2045         throw beans::UnknownPropertyException(
2046             OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown property: "))
2047                 + rPropertyName,
2048             static_cast<cppu::OWeakObject *>(0));
2049     }
2050 
2051     if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
2052     {
2053         throw beans::PropertyVetoException(
2054             OUString(RTL_CONSTASCII_USTRINGPARAM("Property is read-only: "))
2055                 + rPropertyName,
2056             static_cast<cppu::OWeakObject *>(0));
2057     }
2058 
2059     SfxItemSet aItemSet( pDoc->GetAttrPool(), pEntry->nWID, pEntry->nWID );
2060     SwUnoCursorHelper::GetCrsrAttr( rPaM, aItemSet );
2061 
2062     if (!SwUnoCursorHelper::SetCursorPropertyValue(
2063                 *pEntry, rValue, rPaM, aItemSet))
2064     {
2065         rPropSet.setPropertyValue(*pEntry, rValue, aItemSet );
2066     }
2067     SwUnoCursorHelper::SetCrsrAttr(rPaM, aItemSet, nAttrMode, bTableMode);
2068 }
2069 
2070 /* -----------------------------03.05.00 13:16--------------------------------
2071 
2072  ---------------------------------------------------------------------------*/
2073 uno::Sequence< beans::PropertyState >
GetPropertyStates(SwPaM & rPaM,const SfxItemPropertySet & rPropSet,const uno::Sequence<OUString> & rPropertyNames,const SwGetPropertyStatesCaller eCaller)2074 SwUnoCursorHelper::GetPropertyStates(
2075             SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
2076             const uno::Sequence< OUString >& rPropertyNames,
2077             const SwGetPropertyStatesCaller eCaller)
2078 {
2079     const OUString* pNames = rPropertyNames.getConstArray();
2080     uno::Sequence< beans::PropertyState > aRet(rPropertyNames.getLength());
2081     beans::PropertyState* pStates = aRet.getArray();
2082     SfxItemPropertyMap const*const pMap = rPropSet.getPropertyMap();
2083     ::std::auto_ptr<SfxItemSet> pSet;
2084     ::std::auto_ptr<SfxItemSet> pSetParent;
2085 
2086     for (sal_Int32 i = 0, nEnd = rPropertyNames.getLength(); i < nEnd; i++)
2087     {
2088         SfxItemPropertySimpleEntry const*const pEntry =
2089                 pMap->getByName( pNames[i] );
2090         if(!pEntry)
2091         {
2092             if (pNames[i].equalsAsciiL( SW_PROP_NAME(UNO_NAME_IS_SKIP_HIDDEN_TEXT)) ||
2093                 pNames[i].equalsAsciiL( SW_PROP_NAME(UNO_NAME_IS_SKIP_PROTECTED_TEXT)))
2094             {
2095                 pStates[i] = beans::PropertyState_DEFAULT_VALUE;
2096                 continue;
2097             }
2098             else if (SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT ==
2099                         eCaller)
2100             {
2101                 //this values marks the element as unknown property
2102                 pStates[i] = beans::PropertyState_MAKE_FIXED_SIZE;
2103                 continue;
2104             }
2105             else
2106             {
2107                 throw beans::UnknownPropertyException(
2108                     OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown property: "))
2109                         + pNames[i],
2110                     static_cast<cppu::OWeakObject *>(0));
2111             }
2112         }
2113         if (((SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION == eCaller)  ||
2114              (SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT == eCaller)) &&
2115             pEntry->nWID < FN_UNO_RANGE_BEGIN &&
2116             pEntry->nWID > FN_UNO_RANGE_END  &&
2117             pEntry->nWID < RES_CHRATR_BEGIN &&
2118             pEntry->nWID > RES_TXTATR_END )
2119         {
2120             pStates[i] = beans::PropertyState_DEFAULT_VALUE;
2121         }
2122         else
2123         {
2124             if ( pEntry->nWID >= FN_UNO_RANGE_BEGIN &&
2125                  pEntry->nWID <= FN_UNO_RANGE_END )
2126             {
2127                 SwUnoCursorHelper::getCrsrPropertyValue(
2128                     *pEntry, rPaM, 0, pStates[i] );
2129             }
2130             else
2131             {
2132                 if (!pSet.get())
2133                 {
2134                     switch ( eCaller )
2135                     {
2136                         case SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION_TOLERANT:
2137                         case SW_PROPERTY_STATE_CALLER_SWX_TEXT_PORTION:
2138                             pSet.reset(
2139                                 new SfxItemSet( rPaM.GetDoc()->GetAttrPool(),
2140                                     RES_CHRATR_BEGIN,   RES_TXTATR_END ));
2141                         break;
2142                         case SW_PROPERTY_STATE_CALLER_SINGLE_VALUE_ONLY:
2143                             pSet.reset(
2144                                 new SfxItemSet( rPaM.GetDoc()->GetAttrPool(),
2145                                     pEntry->nWID, pEntry->nWID ));
2146                         break;
2147                         default:
2148                             pSet.reset( new SfxItemSet(
2149                                 rPaM.GetDoc()->GetAttrPool(),
2150                                 RES_CHRATR_BEGIN, RES_FRMATR_END - 1,
2151                                 RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
2152                                 RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
2153                                 0L ));
2154                     }
2155                     // --> OD 2006-07-12 #i63870#
2156                     SwUnoCursorHelper::GetCrsrAttr( rPaM, *pSet );
2157                     // <--
2158                 }
2159 
2160                 pStates[i] = ( pSet->Count() )
2161                     ? rPropSet.getPropertyState( *pEntry, *pSet )
2162                     : beans::PropertyState_DEFAULT_VALUE;
2163 
2164                 //try again to find out if a value has been inherited
2165                 if( beans::PropertyState_DIRECT_VALUE == pStates[i] )
2166                 {
2167                     if (!pSetParent.get())
2168                     {
2169                         pSetParent.reset( pSet->Clone( sal_False ) );
2170                         // --> OD 2006-07-12 #i63870#
2171                         SwUnoCursorHelper::GetCrsrAttr(
2172                                 rPaM, *pSetParent, sal_True, sal_False );
2173                         // <--
2174                     }
2175 
2176                     pStates[i] = ( (pSetParent)->Count() )
2177                         ? rPropSet.getPropertyState( *pEntry, *pSetParent )
2178                         : beans::PropertyState_DEFAULT_VALUE;
2179                 }
2180             }
2181         }
2182     }
2183     return aRet;
2184 }
2185 /* -----------------------------03.05.00 13:17--------------------------------
2186 
2187  ---------------------------------------------------------------------------*/
GetPropertyState(SwPaM & rPaM,const SfxItemPropertySet & rPropSet,const OUString & rPropertyName)2188 beans::PropertyState SwUnoCursorHelper::GetPropertyState(
2189     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
2190     const OUString& rPropertyName)
2191 {
2192     uno::Sequence< OUString > aStrings ( 1 );
2193     aStrings[0] = rPropertyName;
2194     uno::Sequence< beans::PropertyState > aSeq =
2195         GetPropertyStates(rPaM, rPropSet, aStrings,
2196                 SW_PROPERTY_STATE_CALLER_SINGLE_VALUE_ONLY );
2197     return aSeq[0];
2198 }
2199 /* -----------------------------03.05.00 13:20--------------------------------
2200 
2201  ---------------------------------------------------------------------------*/
2202 static void
lcl_SelectParaAndReset(SwPaM & rPaM,SwDoc & rDoc,SvUShortsSort const * const pWhichIds=0)2203 lcl_SelectParaAndReset( SwPaM &rPaM, SwDoc & rDoc,
2204         SvUShortsSort const*const pWhichIds = 0 )
2205 {
2206     // if we are reseting paragraph attributes, we need to select the full paragraph first
2207     SwPosition aStart = *rPaM.Start();
2208     SwPosition aEnd = *rPaM.End();
2209     ::std::auto_ptr< SwUnoCrsr > pTemp ( rDoc.CreateUnoCrsr(aStart, sal_False) );
2210     if(!SwUnoCursorHelper::IsStartOfPara(*pTemp))
2211     {
2212         pTemp->MovePara(fnParaCurr, fnParaStart);
2213     }
2214     pTemp->SetMark();
2215     *pTemp->GetPoint() = aEnd;
2216     SwUnoCursorHelper::SelectPam(*pTemp, true);
2217     if(!SwUnoCursorHelper::IsEndOfPara(*pTemp))
2218     {
2219         pTemp->MovePara(fnParaCurr, fnParaEnd);
2220     }
2221     rDoc.ResetAttrs(*pTemp, sal_True, pWhichIds);
2222 }
2223 
2224 
SetPropertyToDefault(SwPaM & rPaM,const SfxItemPropertySet & rPropSet,const OUString & rPropertyName)2225 void SwUnoCursorHelper::SetPropertyToDefault(
2226     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
2227     const OUString& rPropertyName)
2228 {
2229     SwDoc & rDoc = *rPaM.GetDoc();
2230     SfxItemPropertySimpleEntry const*const pEntry =
2231         rPropSet.getPropertyMap()->getByName(rPropertyName);
2232     if (!pEntry)
2233     {
2234         throw beans::UnknownPropertyException(
2235             OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown property: "))
2236                 + rPropertyName, static_cast<cppu::OWeakObject *>(0));
2237     }
2238 
2239     if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
2240     {
2241         throw uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
2242                 "setPropertyToDefault: property is read-only: "))
2243                 + rPropertyName, 0);
2244     }
2245 
2246     if (pEntry->nWID < RES_FRMATR_END)
2247     {
2248         SvUShortsSort aWhichIds;
2249         aWhichIds.Insert(pEntry->nWID);
2250         if (pEntry->nWID < RES_PARATR_BEGIN)
2251         {
2252             rDoc.ResetAttrs(rPaM, sal_True, &aWhichIds);
2253         }
2254         else
2255         {
2256             lcl_SelectParaAndReset ( rPaM, rDoc, &aWhichIds );
2257         }
2258     }
2259     else
2260     {
2261         SwUnoCursorHelper::resetCrsrPropertyValue(*pEntry, rPaM);
2262     }
2263 }
2264 
2265 /* -----------------------------03.05.00 13:19--------------------------------
2266 
2267  ---------------------------------------------------------------------------*/
GetPropertyDefault(SwPaM & rPaM,const SfxItemPropertySet & rPropSet,const OUString & rPropertyName)2268 uno::Any SwUnoCursorHelper::GetPropertyDefault(
2269     SwPaM& rPaM, const SfxItemPropertySet& rPropSet,
2270     const OUString& rPropertyName)
2271 {
2272     SfxItemPropertySimpleEntry const*const pEntry =
2273         rPropSet.getPropertyMap()->getByName(rPropertyName);
2274     if (!pEntry)
2275     {
2276         throw beans::UnknownPropertyException(
2277             OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown property: "))
2278                 + rPropertyName, static_cast<cppu::OWeakObject *>(0));
2279     }
2280 
2281     uno::Any aRet;
2282     if (pEntry->nWID < RES_FRMATR_END)
2283     {
2284         SwDoc & rDoc = *rPaM.GetDoc();
2285         const SfxPoolItem& rDefItem =
2286             rDoc.GetAttrPool().GetDefaultItem(pEntry->nWID);
2287         rDefItem.QueryValue(aRet, pEntry->nMemberId);
2288     }
2289     return aRet;
2290 }
2291 
2292 /*-- 09.12.98 14:18:54---------------------------------------------------
2293 
2294   -----------------------------------------------------------------------*/
2295 uno::Reference< beans::XPropertySetInfo > SAL_CALL
getPropertySetInfo()2296 SwXTextCursor::getPropertySetInfo()
2297 {
2298     vos::OGuard g(Application::GetSolarMutex());
2299 
2300     static uno::Reference< beans::XPropertySetInfo >  xRef;
2301     if(!xRef.is())
2302     {
2303         static SfxItemPropertyMapEntry aCrsrExtMap_Impl[] =
2304         {
2305             { SW_PROP_NAME(UNO_NAME_IS_SKIP_HIDDEN_TEXT), FN_SKIP_HIDDEN_TEXT, &::getBooleanCppuType(), PROPERTY_NONE,     0},
2306             { SW_PROP_NAME(UNO_NAME_IS_SKIP_PROTECTED_TEXT), FN_SKIP_PROTECTED_TEXT, &::getBooleanCppuType(), PROPERTY_NONE,     0},
2307             {0,0,0,0,0,0}
2308         };
2309         const uno::Reference< beans::XPropertySetInfo >  xInfo =
2310             m_pImpl->m_rPropSet.getPropertySetInfo();
2311         // PropertySetInfo verlaengern!
2312         const uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
2313         xRef = new SfxExtItemPropertySetInfo(
2314             aCrsrExtMap_Impl,
2315             aPropSeq );
2316     }
2317     return xRef;
2318 }
2319 
2320 /*-- 09.12.98 14:18:54---------------------------------------------------
2321 
2322   -----------------------------------------------------------------------*/
2323 void SAL_CALL
setPropertyValue(const OUString & rPropertyName,const uno::Any & rValue)2324 SwXTextCursor::setPropertyValue(
2325         const OUString& rPropertyName, const uno::Any& rValue)
2326 {
2327     vos::OGuard aGuard(Application::GetSolarMutex());
2328 
2329     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2330 
2331     if (rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_IS_SKIP_HIDDEN_TEXT)))
2332     {
2333         sal_Bool bSet(sal_False);
2334         if (!(rValue >>= bSet))
2335         {
2336             throw lang::IllegalArgumentException();
2337         }
2338         rUnoCursor.SetSkipOverHiddenSections(bSet);
2339     }
2340     else if (rPropertyName.equalsAsciiL(
2341                 SW_PROP_NAME(UNO_NAME_IS_SKIP_PROTECTED_TEXT)))
2342     {
2343         sal_Bool bSet(sal_False);
2344         if (!(rValue >>= bSet))
2345         {
2346             throw lang::IllegalArgumentException();
2347         }
2348         rUnoCursor.SetSkipOverProtectSections(bSet);
2349     }
2350     else
2351     {
2352         SwUnoCursorHelper::SetPropertyValue(rUnoCursor,
2353                 m_pImpl->m_rPropSet, rPropertyName, rValue);
2354     }
2355 }
2356 
2357 /*-- 09.12.98 14:18:55---------------------------------------------------
2358 
2359   -----------------------------------------------------------------------*/
2360 uno::Any SAL_CALL
getPropertyValue(const OUString & rPropertyName)2361 SwXTextCursor::getPropertyValue(const OUString& rPropertyName)
2362 {
2363     vos::OGuard aGuard(Application::GetSolarMutex());
2364 
2365     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2366 
2367     uno::Any aAny;
2368     if (rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_IS_SKIP_HIDDEN_TEXT)))
2369     {
2370         const sal_Bool bSet = rUnoCursor.IsSkipOverHiddenSections();
2371         aAny <<= bSet;
2372     }
2373     else if (rPropertyName.equalsAsciiL(
2374                 SW_PROP_NAME(UNO_NAME_IS_SKIP_PROTECTED_TEXT)))
2375     {
2376         const sal_Bool bSet = rUnoCursor.IsSkipOverProtectSections();
2377         aAny <<= bSet;
2378     }
2379     else
2380     {
2381         aAny = SwUnoCursorHelper::GetPropertyValue(rUnoCursor,
2382                 m_pImpl->m_rPropSet, rPropertyName);
2383     }
2384     return aAny;
2385 }
2386 
2387 /*-- 09.12.98 14:18:55---------------------------------------------------
2388 
2389   -----------------------------------------------------------------------*/
2390 void SAL_CALL
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)2391 SwXTextCursor::addPropertyChangeListener(
2392         const ::rtl::OUString& /*rPropertyName*/,
2393         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
2394 {
2395     OSL_ENSURE(false,
2396         "SwXTextCursor::addPropertyChangeListener(): not implemented");
2397 }
2398 
2399 /*-- 09.12.98 14:18:57---------------------------------------------------
2400 
2401   -----------------------------------------------------------------------*/
2402 void SAL_CALL
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)2403 SwXTextCursor::removePropertyChangeListener(
2404         const ::rtl::OUString& /*rPropertyName*/,
2405         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
2406 {
2407     OSL_ENSURE(false,
2408         "SwXTextCursor::removePropertyChangeListener(): not implemented");
2409 }
2410 
2411 /*-- 09.12.98 14:18:57---------------------------------------------------
2412 
2413   -----------------------------------------------------------------------*/
2414 void SAL_CALL
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)2415 SwXTextCursor::addVetoableChangeListener(
2416         const ::rtl::OUString& /*rPropertyName*/,
2417         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
2418 {
2419     OSL_ENSURE(false,
2420         "SwXTextCursor::addVetoableChangeListener(): not implemented");
2421 }
2422 
2423 /*-- 09.12.98 14:18:58---------------------------------------------------
2424 
2425   -----------------------------------------------------------------------*/
2426 void SAL_CALL
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)2427 SwXTextCursor::removeVetoableChangeListener(
2428         const ::rtl::OUString& /*rPropertyName*/,
2429         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
2430 {
2431     OSL_ENSURE(false,
2432         "SwXTextCursor::removeVetoableChangeListener(): not implemented");
2433 }
2434 
2435 /*-- 05.03.99 11:36:11---------------------------------------------------
2436 
2437   -----------------------------------------------------------------------*/
2438 beans::PropertyState SAL_CALL
getPropertyState(const OUString & rPropertyName)2439 SwXTextCursor::getPropertyState(const OUString& rPropertyName)
2440 {
2441     vos::OGuard aGuard(Application::GetSolarMutex());
2442 
2443     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2444 
2445     const beans::PropertyState eRet = SwUnoCursorHelper::GetPropertyState(
2446             rUnoCursor, m_pImpl->m_rPropSet, rPropertyName);
2447     return eRet;
2448 }
2449 /*-- 05.03.99 11:36:11---------------------------------------------------
2450 
2451   -----------------------------------------------------------------------*/
2452 uno::Sequence< beans::PropertyState > SAL_CALL
getPropertyStates(const uno::Sequence<OUString> & rPropertyNames)2453 SwXTextCursor::getPropertyStates(
2454         const uno::Sequence< OUString >& rPropertyNames)
2455 {
2456     vos::OGuard aGuard(Application::GetSolarMutex());
2457 
2458     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2459 
2460     return SwUnoCursorHelper::GetPropertyStates(
2461             rUnoCursor, m_pImpl->m_rPropSet, rPropertyNames);
2462 }
2463 
2464 /*-- 05.03.99 11:36:12---------------------------------------------------
2465 
2466   -----------------------------------------------------------------------*/
2467 void SAL_CALL
setPropertyToDefault(const OUString & rPropertyName)2468 SwXTextCursor::setPropertyToDefault(const OUString& rPropertyName)
2469 {
2470     // forward: need no solar mutex here
2471     uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
2472     setPropertiesToDefault ( aSequence );
2473 }
2474 /*-- 05.03.99 11:36:12---------------------------------------------------
2475 
2476   -----------------------------------------------------------------------*/
2477 uno::Any SAL_CALL
getPropertyDefault(const OUString & rPropertyName)2478 SwXTextCursor::getPropertyDefault(const OUString& rPropertyName)
2479 {
2480     // forward: need no solar mutex here
2481     const uno::Sequence < OUString > aSequence ( &rPropertyName, 1 );
2482     return getPropertyDefaults ( aSequence ).getConstArray()[0];
2483 }
2484 
2485 // para specific attribut ranges
2486 static sal_uInt16 g_ParaResetableSetRange[] = {
2487     RES_FRMATR_BEGIN, RES_FRMATR_END-1,
2488     RES_PARATR_BEGIN, RES_PARATR_END-1,
2489     // --> OD 2008-02-25 #refactorlists#
2490     RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
2491     // <--
2492     RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
2493     0
2494 };
2495 
2496 // selection specific attribut ranges
2497 static sal_uInt16 g_ResetableSetRange[] = {
2498     RES_CHRATR_BEGIN, RES_CHRATR_END-1,
2499     RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
2500     RES_TXTATR_CHARFMT, RES_TXTATR_CHARFMT,
2501     RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY,
2502     RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
2503     0
2504 };
2505 
2506 static void
lcl_EnumerateIds(sal_uInt16 const * pIdRange,SvUShortsSort & rWhichIds)2507 lcl_EnumerateIds(sal_uInt16 const* pIdRange, SvUShortsSort & rWhichIds)
2508 {
2509     while (*pIdRange)
2510     {
2511         const sal_uInt16 nStart = sal::static_int_cast<sal_uInt16>(*pIdRange++);
2512         const sal_uInt16 nEnd   = sal::static_int_cast<sal_uInt16>(*pIdRange++);
2513         for (sal_uInt16 nId = nStart + 1;  nId <= nEnd;  ++nId)
2514         {
2515             rWhichIds.Insert( nId );
2516         }
2517     }
2518 }
2519 
2520 void SAL_CALL
setAllPropertiesToDefault()2521 SwXTextCursor::setAllPropertiesToDefault()
2522 {
2523     vos::OGuard aGuard(Application::GetSolarMutex());
2524 
2525     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2526 
2527     SvUShortsSort aParaWhichIds;
2528     SvUShortsSort aWhichIds;
2529     lcl_EnumerateIds(g_ParaResetableSetRange, aParaWhichIds);
2530     lcl_EnumerateIds(g_ResetableSetRange, aWhichIds);
2531     if (aParaWhichIds.Count())
2532     {
2533         lcl_SelectParaAndReset(rUnoCursor, *rUnoCursor.GetDoc(),
2534             &aParaWhichIds);
2535     }
2536     if (aWhichIds.Count())
2537     {
2538         rUnoCursor.GetDoc()->ResetAttrs(rUnoCursor, sal_True, &aWhichIds);
2539     }
2540 }
2541 
2542 void SAL_CALL
setPropertiesToDefault(const uno::Sequence<OUString> & rPropertyNames)2543 SwXTextCursor::setPropertiesToDefault(
2544         const uno::Sequence< OUString >& rPropertyNames)
2545 {
2546     vos::OGuard aGuard(Application::GetSolarMutex());
2547 
2548     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2549 
2550     const sal_Int32 nCount = rPropertyNames.getLength();
2551     if ( nCount )
2552     {
2553         SwDoc & rDoc = *rUnoCursor.GetDoc();
2554         const OUString * pNames = rPropertyNames.getConstArray();
2555         SvUShortsSort aWhichIds;
2556         SvUShortsSort aParaWhichIds;
2557         for (sal_Int32 i = 0; i < nCount; i++)
2558         {
2559             SfxItemPropertySimpleEntry const*const  pEntry =
2560                 m_pImpl->m_rPropSet.getPropertyMap()->getByName( pNames[i] );
2561             if (!pEntry)
2562             {
2563                 if (pNames[i].equalsAsciiL(
2564                         SW_PROP_NAME(UNO_NAME_IS_SKIP_HIDDEN_TEXT)) ||
2565                     pNames[i].equalsAsciiL(
2566                         SW_PROP_NAME(UNO_NAME_IS_SKIP_PROTECTED_TEXT)))
2567                 {
2568                     continue;
2569                 }
2570                 throw beans::UnknownPropertyException(
2571                     OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown property: "))
2572                         + pNames[i],
2573                     static_cast<cppu::OWeakObject *>(this));
2574             }
2575             if (pEntry->nFlags & beans::PropertyAttribute::READONLY)
2576             {
2577                 throw uno::RuntimeException(
2578                     OUString(RTL_CONSTASCII_USTRINGPARAM(
2579                             "setPropertiesToDefault: property is read-only: "))
2580                         + pNames[i],
2581                     static_cast<cppu::OWeakObject *>(this));
2582             }
2583 
2584             if (pEntry->nWID < RES_FRMATR_END)
2585             {
2586                 if (pEntry->nWID < RES_PARATR_BEGIN)
2587                 {
2588                     aWhichIds.Insert(pEntry->nWID);
2589                 }
2590                 else
2591                 {
2592                     aParaWhichIds.Insert(pEntry->nWID);
2593                 }
2594             }
2595             else if (pEntry->nWID == FN_UNO_NUM_START_VALUE)
2596             {
2597                 SwUnoCursorHelper::resetCrsrPropertyValue(*pEntry, rUnoCursor);
2598             }
2599         }
2600 
2601         if (aParaWhichIds.Count())
2602         {
2603             lcl_SelectParaAndReset(rUnoCursor, rDoc, &aParaWhichIds);
2604         }
2605         if (aWhichIds.Count())
2606         {
2607             rDoc.ResetAttrs(rUnoCursor, sal_True, &aWhichIds);
2608         }
2609     }
2610 }
2611 
2612 uno::Sequence< uno::Any > SAL_CALL
getPropertyDefaults(const uno::Sequence<OUString> & rPropertyNames)2613 SwXTextCursor::getPropertyDefaults(
2614         const uno::Sequence< OUString >& rPropertyNames)
2615 {
2616     vos::OGuard aGuard(Application::GetSolarMutex());
2617 
2618     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2619 
2620     const sal_Int32 nCount = rPropertyNames.getLength();
2621     uno::Sequence< uno::Any > aRet(nCount);
2622     if ( nCount )
2623     {
2624         SwDoc & rDoc = *rUnoCursor.GetDoc();
2625         const OUString *pNames = rPropertyNames.getConstArray();
2626         uno::Any *pAny = aRet.getArray();
2627         for (sal_Int32 i = 0; i < nCount; i++)
2628         {
2629             SfxItemPropertySimpleEntry const*const pEntry =
2630                 m_pImpl->m_rPropSet.getPropertyMap()->getByName( pNames[i] );
2631             if (!pEntry)
2632             {
2633                 if (pNames[i].equalsAsciiL(
2634                         SW_PROP_NAME(UNO_NAME_IS_SKIP_HIDDEN_TEXT)) ||
2635                     pNames[i].equalsAsciiL(
2636                         SW_PROP_NAME(UNO_NAME_IS_SKIP_PROTECTED_TEXT)))
2637                 {
2638                     continue;
2639                 }
2640                 throw beans::UnknownPropertyException(
2641                     OUString(RTL_CONSTASCII_USTRINGPARAM("Unknown property: "))
2642                         + pNames[i],
2643                     static_cast<cppu::OWeakObject *>(0));
2644             }
2645             if (pEntry->nWID < RES_FRMATR_END)
2646             {
2647                 const SfxPoolItem& rDefItem =
2648                     rDoc.GetAttrPool().GetDefaultItem(pEntry->nWID);
2649                 rDefItem.QueryValue(pAny[i], pEntry->nMemberId);
2650             }
2651         }
2652     }
2653     return aRet;
2654 }
2655 
invalidateMarkings(::sal_Int32 nType)2656 void SAL_CALL SwXTextCursor::invalidateMarkings(::sal_Int32 nType)
2657 {
2658     vos::OGuard aGuard(Application::GetSolarMutex());
2659 
2660     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2661 
2662     SwNode* node = rUnoCursor.GetNode();
2663 
2664     if (node == 0) return;
2665 
2666     SwTxtNode* txtNode = node->GetTxtNode();
2667 
2668     if (txtNode == 0) return;
2669 
2670     if ( text::TextMarkupType::SPELLCHECK == nType )
2671     {
2672         txtNode->SetWrongDirty(true);
2673         txtNode->SetWrong(0, true);
2674     }
2675     else if( text::TextMarkupType::PROOFREADING == nType )
2676     {
2677         txtNode->SetGrammarCheckDirty(true);
2678         txtNode->SetGrammarCheck(0,true);
2679     }
2680     else if ( text::TextMarkupType::SMARTTAG == nType )
2681     {
2682         txtNode->SetSmartTagDirty(true);
2683         txtNode->SetSmartTags (0, true);
2684     }
2685     else return;
2686 
2687     SwFmtColl* fmtColl=txtNode->GetFmtColl();
2688 
2689     if (fmtColl == 0) return;
2690 
2691     SwFmtChg aNew( fmtColl );
2692     txtNode->NotifyClients( 0, &aNew );
2693 }
2694 
2695 
2696 /*-- 10.03.2008 09:58:47---------------------------------------------------
2697 
2698   -----------------------------------------------------------------------*/
2699 void SAL_CALL
makeRedline(const::rtl::OUString & rRedlineType,const uno::Sequence<beans::PropertyValue> & rRedlineProperties)2700 SwXTextCursor::makeRedline(
2701     const ::rtl::OUString& rRedlineType,
2702     const uno::Sequence< beans::PropertyValue >& rRedlineProperties)
2703 {
2704     vos::OGuard aGuard(Application::GetSolarMutex());
2705 
2706     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2707 
2708     SwUnoCursorHelper::makeRedline(rUnoCursor, rRedlineType, rRedlineProperties);
2709 }
2710 
2711 /*-- 09.12.98 14:18:58---------------------------------------------------
2712 
2713   -----------------------------------------------------------------------*/
insertDocumentFromURL(const OUString & rURL,const uno::Sequence<beans::PropertyValue> & rOptions)2714 void SAL_CALL SwXTextCursor::insertDocumentFromURL(const OUString& rURL,
2715     const uno::Sequence< beans::PropertyValue >& rOptions)
2716 {
2717     vos::OGuard aGuard(Application::GetSolarMutex());
2718 
2719     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
2720 
2721     SwUnoCursorHelper::InsertFile(&rUnoCursor, rURL, rOptions);
2722 }
2723 
2724 /* -----------------------------15.12.00 14:01--------------------------------
2725 
2726  ---------------------------------------------------------------------------*/
2727 uno::Sequence< beans::PropertyValue >
CreateSortDescriptor(const bool bFromTable)2728 SwUnoCursorHelper::CreateSortDescriptor(const bool bFromTable)
2729 {
2730     uno::Sequence< beans::PropertyValue > aRet(5);
2731     beans::PropertyValue* pArray = aRet.getArray();
2732 
2733     uno::Any aVal;
2734     aVal.setValue( &bFromTable, ::getCppuBooleanType());
2735     pArray[0] = beans::PropertyValue(C2U("IsSortInTable"), -1, aVal,
2736                     beans::PropertyState_DIRECT_VALUE);
2737 
2738     aVal <<= sal_Unicode(' ');
2739     pArray[1] = beans::PropertyValue(C2U("Delimiter"), -1, aVal,
2740                     beans::PropertyState_DIRECT_VALUE);
2741 
2742     aVal <<= (sal_Bool) sal_False;
2743     pArray[2] = beans::PropertyValue(C2U("IsSortColumns"), -1, aVal,
2744                     beans::PropertyState_DIRECT_VALUE);
2745 
2746     aVal <<= (sal_Int32) 3;
2747     pArray[3] = beans::PropertyValue(C2U("MaxSortFieldsCount"), -1, aVal,
2748                     beans::PropertyState_DIRECT_VALUE);
2749 
2750     uno::Sequence< table::TableSortField > aFields(3);
2751     table::TableSortField* pFields = aFields.getArray();
2752 
2753     lang::Locale aLang( SvxCreateLocale( LANGUAGE_SYSTEM ) );
2754     // get collator algorithm to be used for the locale
2755     uno::Sequence< OUString > aSeq(
2756             GetAppCollator().listCollatorAlgorithms( aLang ) );
2757     const sal_Int32 nLen = aSeq.getLength();
2758     DBG_ASSERT( nLen > 0, "list of collator algorithms is empty!");
2759     OUString aCollAlg;
2760     if (nLen > 0)
2761     {
2762         aCollAlg = aSeq.getConstArray()[0];
2763     }
2764 
2765 #if OSL_DEBUG_LEVEL > 1
2766     const OUString *pTxt = aSeq.getConstArray();
2767     (void)pTxt;
2768 #endif
2769 
2770     pFields[0].Field = 1;
2771     pFields[0].IsAscending = sal_True;
2772     pFields[0].IsCaseSensitive = sal_False;
2773     pFields[0].FieldType = table::TableSortFieldType_ALPHANUMERIC;
2774     pFields[0].CollatorLocale = aLang;
2775     pFields[0].CollatorAlgorithm = aCollAlg;
2776 
2777     pFields[1].Field = 1;
2778     pFields[1].IsAscending = sal_True;
2779     pFields[1].IsCaseSensitive = sal_False;
2780     pFields[1].FieldType = table::TableSortFieldType_ALPHANUMERIC;
2781     pFields[1].CollatorLocale = aLang;
2782     pFields[1].CollatorAlgorithm = aCollAlg;
2783 
2784     pFields[2].Field = 1;
2785     pFields[2].IsAscending = sal_True;
2786     pFields[2].IsCaseSensitive = sal_False;
2787     pFields[2].FieldType = table::TableSortFieldType_ALPHANUMERIC;
2788     pFields[2].CollatorLocale = aLang;
2789     pFields[2].CollatorAlgorithm = aCollAlg;
2790 
2791     aVal <<= aFields;
2792     pArray[4] = beans::PropertyValue(C2U("SortFields"), -1, aVal,
2793                     beans::PropertyState_DIRECT_VALUE);
2794 
2795     return aRet;
2796 }
2797 
2798 /*-- 09.12.98 14:18:58---------------------------------------------------
2799 
2800   -----------------------------------------------------------------------*/
2801 uno::Sequence< beans::PropertyValue > SAL_CALL
createSortDescriptor()2802 SwXTextCursor::createSortDescriptor()
2803 {
2804     vos::OGuard aGuard(Application::GetSolarMutex());
2805 
2806     return SwUnoCursorHelper::CreateSortDescriptor(false);
2807 }
2808 
2809 /* -----------------------------15.12.00 14:06--------------------------------
2810 
2811  ---------------------------------------------------------------------------*/
ConvertSortProperties(const uno::Sequence<beans::PropertyValue> & rDescriptor,SwSortOptions & rSortOpt)2812 sal_Bool SwUnoCursorHelper::ConvertSortProperties(
2813     const uno::Sequence< beans::PropertyValue >& rDescriptor,
2814     SwSortOptions& rSortOpt)
2815 {
2816     sal_Bool bRet = sal_True;
2817     const beans::PropertyValue* pProperties = rDescriptor.getConstArray();
2818 
2819     rSortOpt.bTable = sal_False;
2820     rSortOpt.cDeli = ' ';
2821     rSortOpt.eDirection = SRT_COLUMNS;  //!! UI text may be contrary though !!
2822 
2823     SwSortKey* pKey1 = new SwSortKey;
2824     pKey1->nColumnId = USHRT_MAX;
2825     pKey1->bIsNumeric = sal_True;
2826     pKey1->eSortOrder = SRT_ASCENDING;
2827 
2828     SwSortKey* pKey2 = new SwSortKey;
2829     pKey2->nColumnId = USHRT_MAX;
2830     pKey2->bIsNumeric = sal_True;
2831     pKey2->eSortOrder = SRT_ASCENDING;
2832 
2833     SwSortKey* pKey3 = new SwSortKey;
2834     pKey3->nColumnId = USHRT_MAX;
2835     pKey3->bIsNumeric = sal_True;
2836     pKey3->eSortOrder = SRT_ASCENDING;
2837     SwSortKey* aKeys[3] = {pKey1, pKey2, pKey3};
2838 
2839     sal_Bool bOldSortdescriptor(sal_False);
2840     sal_Bool bNewSortdescriptor(sal_False);
2841 
2842     for (sal_Int32 n = 0; n < rDescriptor.getLength(); ++n)
2843     {
2844         uno::Any aValue( pProperties[n].Value );
2845 //      String sPropName = pProperties[n].Name;
2846         const OUString& rPropName = pProperties[n].Name;
2847 
2848         // old and new sortdescriptor
2849         if (rPropName.equalsAscii("IsSortInTable"))
2850         {
2851             if (aValue.getValueType() == ::getBooleanCppuType())
2852             {
2853                 rSortOpt.bTable = *(sal_Bool*)aValue.getValue();
2854             }
2855             else
2856             {
2857                 bRet = sal_False;
2858             }
2859         }
2860         else if (rPropName.equalsAscii("Delimiter"))
2861         {
2862             sal_Unicode uChar = sal_Unicode();
2863             if (aValue >>= uChar)
2864             {
2865                 rSortOpt.cDeli = uChar;
2866             }
2867             else
2868             {
2869                 bRet = sal_False;
2870             }
2871         }
2872         // old sortdescriptor
2873         else if (rPropName.equalsAscii("SortColumns"))
2874         {
2875             bOldSortdescriptor = sal_True;
2876             sal_Bool bTemp(sal_False);
2877             if (aValue >>= bTemp)
2878             {
2879                 rSortOpt.eDirection = bTemp ? SRT_COLUMNS : SRT_ROWS;
2880             }
2881             else
2882             {
2883                 bRet = sal_False;
2884             }
2885         }
2886         else if ( rPropName.equalsAscii("IsCaseSensitive"))
2887         {
2888             bOldSortdescriptor = sal_True;
2889             sal_Bool bTemp(sal_False);
2890             if (aValue >>= bTemp)
2891             {
2892                 rSortOpt.bIgnoreCase = !bTemp;
2893             }
2894             else
2895             {
2896                 bRet = sal_False;
2897             }
2898         }
2899         else if (rPropName.equalsAscii("CollatorLocale"))
2900         {
2901             bOldSortdescriptor = sal_True;
2902             lang::Locale aLocale;
2903             if (aValue >>= aLocale)
2904             {
2905                 rSortOpt.nLanguage = SvxLocaleToLanguage( aLocale );
2906             }
2907             else
2908             {
2909                 bRet = sal_False;
2910             }
2911         }
2912         else if (rPropName.matchAsciiL("CollatorAlgorithm", 17) &&
2913             rPropName.getLength() == 18 &&
2914             (rPropName.getStr()[17] >= '0' && rPropName.getStr()[17] <= '9'))
2915         {
2916             bOldSortdescriptor = sal_True;
2917             sal_uInt16 nIndex = rPropName.getStr()[17];
2918             nIndex -= '0';
2919             OUString aTxt;
2920             if ((aValue >>= aTxt) && nIndex < 3)
2921             {
2922                 aKeys[nIndex]->sSortType = aTxt;
2923             }
2924             else
2925             {
2926                 bRet = sal_False;
2927             }
2928         }
2929         else if (rPropName.matchAsciiL("SortRowOrColumnNo", 17) &&
2930             rPropName.getLength() == 18 &&
2931             (rPropName.getStr()[17] >= '0' && rPropName.getStr()[17] <= '9'))
2932         {
2933             bOldSortdescriptor = sal_True;
2934             sal_uInt16 nIndex = rPropName.getStr()[17];
2935             nIndex -= '0';
2936             sal_Int16 nCol = -1;
2937             if (aValue.getValueType() == ::getCppuType((const sal_Int16*)0)
2938                 && nIndex < 3)
2939             {
2940                 aValue >>= nCol;
2941             }
2942             if (nCol >= 0)
2943             {
2944                 aKeys[nIndex]->nColumnId = nCol;
2945             }
2946             else
2947             {
2948                 bRet = sal_False;
2949             }
2950         }
2951         else if (0 == rPropName.indexOf(C2U("IsSortNumeric")) &&
2952             rPropName.getLength() == 14 &&
2953             (rPropName.getStr()[13] >= '0' && rPropName.getStr()[13] <= '9'))
2954         {
2955             bOldSortdescriptor = sal_True;
2956             sal_uInt16 nIndex = rPropName.getStr()[13];
2957             nIndex = nIndex - '0';
2958             if (aValue.getValueType() == ::getBooleanCppuType() && nIndex < 3)
2959             {
2960                 sal_Bool bTemp = *(sal_Bool*)aValue.getValue();
2961                 aKeys[nIndex]->bIsNumeric = bTemp;
2962             }
2963             else
2964             {
2965                 bRet = sal_False;
2966             }
2967         }
2968         else if (0 == rPropName.indexOf(C2U("IsSortAscending")) &&
2969             rPropName.getLength() == 16 &&
2970             (rPropName.getStr()[15] >= '0' && rPropName.getStr()[15] <= '9'))
2971         {
2972             bOldSortdescriptor = sal_True;
2973             sal_uInt16 nIndex = rPropName.getStr()[15];
2974             nIndex -= '0';
2975             if (aValue.getValueType() == ::getBooleanCppuType() && nIndex < 3)
2976             {
2977                 sal_Bool bTemp = *(sal_Bool*)aValue.getValue();
2978                 aKeys[nIndex]->eSortOrder = (bTemp)
2979                     ? SRT_ASCENDING : SRT_DESCENDING;
2980             }
2981             else
2982             {
2983                 bRet = sal_False;
2984             }
2985         }
2986         // new sortdescriptor
2987         else if (rPropName.equalsAscii("IsSortColumns"))
2988         {
2989             bNewSortdescriptor = sal_True;
2990             if (aValue.getValueType() == ::getBooleanCppuType())
2991             {
2992                 sal_Bool bTemp = *(sal_Bool*)aValue.getValue();
2993                 rSortOpt.eDirection = bTemp ? SRT_COLUMNS : SRT_ROWS;
2994             }
2995             else
2996             {
2997                 bRet = sal_False;
2998             }
2999         }
3000         else if (rPropName.equalsAscii("SortFields"))
3001         {
3002             bNewSortdescriptor = sal_True;
3003             uno::Sequence < table::TableSortField > aFields;
3004             if (aValue >>= aFields)
3005             {
3006                 sal_Int32 nCount(aFields.getLength());
3007                 if (nCount <= 3)
3008                 {
3009                     table::TableSortField* pFields = aFields.getArray();
3010                     for (sal_Int32 i = 0; i < nCount; ++i)
3011                     {
3012                         rSortOpt.bIgnoreCase = !pFields[i].IsCaseSensitive;
3013                         rSortOpt.nLanguage =
3014                             SvxLocaleToLanguage( pFields[i].CollatorLocale );
3015                         aKeys[i]->sSortType = pFields[i].CollatorAlgorithm;
3016                         aKeys[i]->nColumnId =
3017                             static_cast<sal_uInt16>(pFields[i].Field);
3018                         aKeys[i]->bIsNumeric = (pFields[i].FieldType ==
3019                                 table::TableSortFieldType_NUMERIC);
3020                         aKeys[i]->eSortOrder = (pFields[i].IsAscending)
3021                             ? SRT_ASCENDING : SRT_DESCENDING;
3022                     }
3023                 }
3024                 else
3025                 {
3026                     bRet = sal_False;
3027                 }
3028             }
3029             else
3030             {
3031                 bRet = sal_False;
3032             }
3033         }
3034     }
3035 
3036     if (bNewSortdescriptor && bOldSortdescriptor)
3037     {
3038         DBG_ERROR("someone tried to set the old deprecated and "
3039             "the new sortdescriptor");
3040         bRet = sal_False;
3041     }
3042 
3043     if (pKey1->nColumnId != USHRT_MAX)
3044     {
3045         rSortOpt.aKeys.C40_INSERT(SwSortKey, pKey1, rSortOpt.aKeys.Count());
3046     }
3047     if (pKey2->nColumnId != USHRT_MAX)
3048     {
3049         rSortOpt.aKeys.C40_INSERT(SwSortKey, pKey2, rSortOpt.aKeys.Count());
3050     }
3051     if (pKey3->nColumnId != USHRT_MAX)
3052     {
3053         rSortOpt.aKeys.C40_INSERT(SwSortKey, pKey3, rSortOpt.aKeys.Count());
3054     }
3055 
3056     return bRet && rSortOpt.aKeys.Count() > 0;
3057 }
3058 
3059 /*-- 09.12.98 14:19:00---------------------------------------------------
3060 
3061   -----------------------------------------------------------------------*/
3062 void SAL_CALL
sort(const uno::Sequence<beans::PropertyValue> & rDescriptor)3063 SwXTextCursor::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
3064 {
3065     vos::OGuard aGuard(Application::GetSolarMutex());
3066 
3067     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
3068 
3069     if (rUnoCursor.HasMark())
3070     {
3071         SwSortOptions aSortOpt;
3072         if (!SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
3073         {
3074             throw uno::RuntimeException();
3075         }
3076         UnoActionContext aContext( rUnoCursor.GetDoc() );
3077 
3078         SwPosition & rStart = *rUnoCursor.Start();
3079         SwPosition & rEnd   = *rUnoCursor.End();
3080 
3081         SwNodeIndex aPrevIdx( rStart.nNode, -1 );
3082         const sal_uLong nOffset = rEnd.nNode.GetIndex() - rStart.nNode.GetIndex();
3083         const xub_StrLen nCntStt  = rStart.nContent.GetIndex();
3084 
3085         rUnoCursor.GetDoc()->SortText(rUnoCursor, aSortOpt);
3086 
3087         // Selektion wieder setzen
3088         rUnoCursor.DeleteMark();
3089         rUnoCursor.GetPoint()->nNode.Assign( aPrevIdx.GetNode(), +1 );
3090         SwCntntNode *const pCNd = rUnoCursor.GetCntntNode();
3091         xub_StrLen nLen = pCNd->Len();
3092         if (nLen > nCntStt)
3093         {
3094             nLen = nCntStt;
3095         }
3096         rUnoCursor.GetPoint()->nContent.Assign(pCNd, nLen );
3097         rUnoCursor.SetMark();
3098 
3099         rUnoCursor.GetPoint()->nNode += nOffset;
3100         SwCntntNode *const pCNd2 = rUnoCursor.GetCntntNode();
3101         rUnoCursor.GetPoint()->nContent.Assign( pCNd2, pCNd2->Len() );
3102     }
3103 }
3104 
3105 /* -----------------------------03.04.00 09:11--------------------------------
3106 
3107  ---------------------------------------------------------------------------*/
3108 uno::Reference< container::XEnumeration > SAL_CALL
createContentEnumeration(const OUString & rServiceName)3109 SwXTextCursor::createContentEnumeration(const OUString& rServiceName)
3110 {
3111     vos::OGuard g(Application::GetSolarMutex());
3112 
3113     if (!rServiceName.equalsAscii("com.sun.star.text.TextContent"))
3114     {
3115         throw uno::RuntimeException();
3116     }
3117 
3118     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
3119 
3120     uno::Reference< container::XEnumeration > xRet =
3121         new SwXParaFrameEnumeration(rUnoCursor, PARAFRAME_PORTION_TEXTRANGE);
3122     return xRet;
3123 }
3124 
3125 /* -----------------------------07.03.01 14:53--------------------------------
3126 
3127  ---------------------------------------------------------------------------*/
3128 uno::Reference< container::XEnumeration > SAL_CALL
createEnumeration()3129 SwXTextCursor::createEnumeration()
3130 {
3131     vos::OGuard g(Application::GetSolarMutex());
3132 
3133     SwUnoCrsr & rUnoCursor( m_pImpl->GetCursorOrThrow() );
3134 
3135     const uno::Reference<lang::XUnoTunnel> xTunnel(
3136             m_pImpl->m_xParentText, uno::UNO_QUERY);
3137     SwXText* pParentText = 0;
3138     if (xTunnel.is())
3139     {
3140         pParentText = ::sw::UnoTunnelGetImplementation<SwXText>(xTunnel);
3141     }
3142     DBG_ASSERT(pParentText, "parent is not a SwXText");
3143     if (!pParentText)
3144     {
3145         throw uno::RuntimeException();
3146     }
3147 
3148     ::std::auto_ptr<SwUnoCrsr> pNewCrsr(
3149         rUnoCursor.GetDoc()->CreateUnoCrsr(*rUnoCursor.GetPoint()) );
3150     if (rUnoCursor.HasMark())
3151     {
3152         pNewCrsr->SetMark();
3153         *pNewCrsr->GetMark() = *rUnoCursor.GetMark();
3154     }
3155     const CursorType eSetType = (CURSOR_TBLTEXT == m_pImpl->m_eType)
3156             ? CURSOR_SELECTION_IN_TABLE : CURSOR_SELECTION;
3157     SwTableNode const*const pStartNode( (CURSOR_TBLTEXT == m_pImpl->m_eType)
3158             ? rUnoCursor.GetPoint()->nNode.GetNode().FindTableNode()
3159             : 0);
3160     SwTable const*const pTable(
3161             (pStartNode) ? & pStartNode->GetTable() : 0 );
3162     const uno::Reference< container::XEnumeration > xRet =
3163         new SwXParagraphEnumeration(
3164                 pParentText, pNewCrsr, eSetType, pStartNode, pTable);
3165 
3166     return xRet;
3167 }
3168 
3169 /* -----------------------------07.03.01 15:43--------------------------------
3170 
3171  ---------------------------------------------------------------------------*/
3172 uno::Type SAL_CALL
getElementType()3173 SwXTextCursor::getElementType()
3174 {
3175     return text::XTextRange::static_type();
3176 }
3177 
3178 /* -----------------------------07.03.01 15:43--------------------------------
3179 
3180  ---------------------------------------------------------------------------*/
hasElements()3181 sal_Bool SAL_CALL SwXTextCursor::hasElements()
3182 {
3183     return sal_True;
3184 }
3185 
3186 /* -----------------------------03.04.00 09:11--------------------------------
3187 
3188  ---------------------------------------------------------------------------*/
3189 uno::Sequence< OUString > SAL_CALL
getAvailableServiceNames()3190 SwXTextCursor::getAvailableServiceNames()
3191 {
3192     uno::Sequence< OUString > aRet(1);
3193     OUString* pArray = aRet.getArray();
3194     pArray[0] = OUString::createFromAscii("com.sun.star.text.TextContent");
3195     return aRet;
3196 }
3197 
3198 // ---------------------------------------------------------------------------
IMPLEMENT_FORWARD_REFCOUNT(SwXTextCursor,SwXTextCursor_Base)3199 IMPLEMENT_FORWARD_REFCOUNT( SwXTextCursor,SwXTextCursor_Base )
3200 
3201 uno::Any SAL_CALL
3202 SwXTextCursor::queryInterface(const uno::Type& rType)
3203 {
3204     return (rType == lang::XUnoTunnel::static_type())
3205         ? OTextCursorHelper::queryInterface(rType)
3206         : SwXTextCursor_Base::queryInterface(rType);
3207 }
3208