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