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