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