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