Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <com/sun/star/linguistic2/ProofreadingResult.hpp>
31 : : #include <com/sun/star/linguistic2/XProofreader.hpp>
32 : : #include <com/sun/star/linguistic2/XProofreadingIterator.hpp>
33 : : #include <com/sun/star/text/XFlatParagraph.hpp>
34 : : #include <comphelper/string.hxx>
35 : :
36 : : #include <unoflatpara.hxx>
37 : :
38 : : #include <comcore.hrc>
39 : : #include <hintids.hxx>
40 : : #include <linguistic/lngprops.hxx>
41 : : #include <vcl/msgbox.hxx>
42 : : #include <editeng/unolingu.hxx>
43 : : #include <editeng/svxacorr.hxx>
44 : : #include <editeng/langitem.hxx>
45 : : #include <editeng/SpellPortions.hxx>
46 : : #include <editeng/scripttypeitem.hxx>
47 : : #include <charatr.hxx>
48 : : #include <editsh.hxx>
49 : : #include <doc.hxx>
50 : : #include <IDocumentUndoRedo.hxx>
51 : : #include <rootfrm.hxx> // SwRootFrm
52 : : #include <pam.hxx>
53 : : #include <swundo.hxx> // fuer die UndoIds
54 : : #include <ndtxt.hxx> // AdjHyphPos
55 : : #include <viewopt.hxx> // HyphStart/End
56 : : #include <viscrs.hxx> // SwShellCrsr
57 : : #include <SwGrammarMarkUp.hxx> // SwWrongList
58 : : #include <mdiexp.hxx> // Statusanzeige
59 : : #include <statstr.hrc> // StatLine-String
60 : : #include <cntfrm.hxx>
61 : : #include <crsskip.hxx>
62 : : #include <splargs.hxx>
63 : : #include <redline.hxx> // SwRedline
64 : : #include <docary.hxx> // SwRedlineTbl
65 : : #include <docsh.hxx>
66 : : #include <txatbase.hxx>
67 : : #include <txtfrm.hxx>
68 : :
69 : : using namespace ::svx;
70 : : using namespace ::com::sun::star;
71 : : using namespace ::com::sun::star::uno;
72 : : using namespace ::com::sun::star::beans;
73 : : using namespace ::com::sun::star::linguistic2;
74 : :
75 : : /*************************************************************************
76 : : * class SwLinguIter
77 : : *************************************************************************/
78 : :
79 : : class SwLinguIter
80 : : {
81 : : SwEditShell *pSh;
82 : : SwPosition *pStart;
83 : : SwPosition *pEnd;
84 : : SwPosition *pCurr;
85 : : SwPosition *pCurrX;
86 : : sal_uInt16 nCrsrCnt;
87 : : public:
88 : : SwLinguIter();
89 : :
90 : 0 : inline SwEditShell *GetSh() { return pSh; }
91 : : inline const SwEditShell *GetSh() const { return pSh; }
92 : :
93 : 0 : inline const SwPosition *GetEnd() const { return pEnd; }
94 [ # # ]: 0 : inline void SetEnd( SwPosition* pNew ){ delete pEnd; pEnd = pNew; }
95 : :
96 : 0 : inline const SwPosition *GetStart() const { return pStart; }
97 [ # # ]: 0 : inline void SetStart( SwPosition* pNew ){ delete pStart; pStart = pNew; }
98 : :
99 : 0 : inline const SwPosition *GetCurr() const { return pCurr; }
100 [ # # ]: 0 : inline void SetCurr( SwPosition* pNew ){ delete pCurr; pCurr = pNew; }
101 : :
102 : 0 : inline const SwPosition *GetCurrX() const { return pCurrX; }
103 [ # # ]: 0 : inline void SetCurrX( SwPosition* pNew ){ delete pCurrX; pCurrX = pNew; }
104 : :
105 : 0 : inline sal_uInt16& GetCrsrCnt(){ return nCrsrCnt; }
106 : :
107 : : // Der UI-Bauchladen:
108 : : void _Start( SwEditShell *pSh, SwDocPositions eStart,
109 : : SwDocPositions eEnd );
110 : : void _End(bool bRestoreSelection = true);
111 : : };
112 : :
113 : : /*************************************************************************
114 : : * class SwSpellIter
115 : : *************************************************************************/
116 : :
117 : : // #i18881# to be able to identify the postions of the changed words
118 : : // the content positions of each portion need to be saved
119 : : struct SpellContentPosition
120 : : {
121 : : sal_uInt16 nLeft;
122 : : sal_uInt16 nRight;
123 : : };
124 : : typedef std::vector<SpellContentPosition> SpellContentPositions;
125 : 0 : class SwSpellIter : public SwLinguIter
126 : : {
127 : : uno::Reference< XSpellChecker1 > xSpeller;
128 : : ::svx::SpellPortions aLastPortions;
129 : :
130 : : SpellContentPositions aLastPositions;
131 : : bool bBackToStartOfSentence;
132 : : bool bMoveToEndOfSentence;
133 : :
134 : :
135 : : void CreatePortion(uno::Reference< XSpellAlternatives > xAlt,
136 : : linguistic2::ProofreadingResult* pGrammarResult,
137 : : bool bIsField, bool bIsHidden);
138 : :
139 : : void AddPortion(uno::Reference< XSpellAlternatives > xAlt,
140 : : linguistic2::ProofreadingResult* pGrammarResult,
141 : : const SpellContentPositions& rDeletedRedlines);
142 : : public:
143 : 0 : SwSpellIter() :
144 [ # # ][ # # ]: 0 : bBackToStartOfSentence(false), bMoveToEndOfSentence(false) {}
145 : :
146 : : void Start( SwEditShell *pSh, SwDocPositions eStart, SwDocPositions eEnd );
147 : :
148 : : uno::Any Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt );
149 : :
150 : : bool SpellSentence(::svx::SpellPortions& rPortions, bool bIsGrammarCheck);
151 : : void ToSentenceStart();
152 : 0 : const ::svx::SpellPortions GetLastPortions() const { return aLastPortions;}
153 : 0 : SpellContentPositions GetLastPositions() const {return aLastPositions;}
154 : 0 : void ContinueAfterThisSentence() { bMoveToEndOfSentence = true; }
155 : : };
156 : :
157 : : /*************************************************************************
158 : : * class SwConvIter
159 : : * used for text conversion
160 : : *************************************************************************/
161 : :
162 : : class SwConvIter : public SwLinguIter
163 : : {
164 : : SwConversionArgs &rArgs;
165 : : public:
166 : 0 : SwConvIter( SwConversionArgs &rConvArgs ) :
167 : 0 : rArgs( rConvArgs )
168 : 0 : {}
169 : :
170 : : void Start( SwEditShell *pSh, SwDocPositions eStart, SwDocPositions eEnd );
171 : :
172 : : uno::Any Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt );
173 : : };
174 : :
175 : : /*************************************************************************
176 : : * class SwHyphIter
177 : : *************************************************************************/
178 : :
179 : : class SwHyphIter : public SwLinguIter
180 : : {
181 : : sal_Bool bOldIdle;
182 : : void DelSoftHyph( SwPaM &rPam );
183 : :
184 : : public:
185 : 0 : SwHyphIter() : bOldIdle(sal_False) {}
186 : :
187 : : void Start( SwEditShell *pSh, SwDocPositions eStart, SwDocPositions eEnd );
188 : : void End();
189 : :
190 : : void Ignore();
191 : :
192 : : uno::Any Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt );
193 : :
194 : : sal_Bool IsAuto();
195 : : void InsertSoftHyph( const xub_StrLen nHyphPos );
196 : : void ShowSelection();
197 : : };
198 : :
199 : : static SwSpellIter* pSpellIter = 0;
200 : : static SwConvIter* pConvIter = 0;
201 : : static SwHyphIter* pHyphIter = 0;
202 : :
203 : : // Wir ersparen uns in Hyphenate ein GetFrm()
204 : : // Achtung: in txtedt.cxx stehen extern-Deklarationen auf diese Pointer!
205 : : const SwTxtNode *pLinguNode;
206 : : SwTxtFrm *pLinguFrm;
207 : :
208 : : /*************************************************************************
209 : : * SwLinguIter::SwLinguIter
210 : : *************************************************************************/
211 : :
212 : 0 : SwLinguIter::SwLinguIter()
213 : 0 : : pSh( 0 ), pStart( 0 ), pEnd( 0 ), pCurr( 0 ), pCurrX( 0 )
214 : : {
215 : : // @@@ es fehlt: Sicherstellen der Reentrance, OSL_ENSURE( etc.
216 : 0 : }
217 : :
218 : : /*************************************************************************
219 : : * SwLinguIter::Start
220 : : *************************************************************************/
221 : :
222 : :
223 : :
224 : 0 : void SwLinguIter::_Start( SwEditShell *pShell, SwDocPositions eStart,
225 : : SwDocPositions eEnd )
226 : : {
227 : : // es fehlt: Sicherstellen der Reentrance, Locking
228 [ # # ]: 0 : if( pSh )
229 : 0 : return;
230 : :
231 : : sal_Bool bSetCurr;
232 : :
233 : 0 : pSh = pShell;
234 : :
235 [ # # ]: 0 : SET_CURR_SHELL( pSh );
236 : :
237 : : OSL_ENSURE( !pEnd, "LinguStart ohne End?");
238 : :
239 [ # # ]: 0 : SwPaM *pCrsr = pSh->GetCrsr();
240 : :
241 [ # # ][ # # ]: 0 : if( pShell->HasSelection() || pCrsr != pCrsr->GetNext() )
[ # # ][ # # ]
242 : : {
243 : 0 : bSetCurr = 0 != GetCurr();
244 [ # # ]: 0 : nCrsrCnt = pSh->GetCrsrCnt();
245 [ # # ]: 0 : if( pSh->IsTableMode() )
246 [ # # ]: 0 : pSh->TblCrsrToCursor();
247 : :
248 [ # # ]: 0 : pSh->Push();
249 : : sal_uInt16 n;
250 [ # # ]: 0 : for( n = 0; n < nCrsrCnt; ++n )
251 : : {
252 [ # # ]: 0 : pSh->Push();
253 [ # # ]: 0 : pSh->DestroyCrsr();
254 : : }
255 [ # # ]: 0 : pSh->Pop( sal_False );
256 : : }
257 : : else
258 : : {
259 : 0 : bSetCurr = sal_False;
260 : 0 : nCrsrCnt = 1;
261 [ # # ]: 0 : pSh->Push();
262 [ # # ]: 0 : pSh->SetLinguRange( eStart, eEnd );
263 : : }
264 : :
265 [ # # ]: 0 : pCrsr = pSh->GetCrsr();
266 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
267 : 0 : pCrsr->Exchange();
268 : :
269 [ # # ][ # # ]: 0 : pStart = new SwPosition( *pCrsr->GetPoint() );
270 [ # # ][ # # ]: 0 : pEnd = new SwPosition( *pCrsr->GetMark() );
271 [ # # ]: 0 : if( bSetCurr )
272 : : {
273 [ # # ][ # # ]: 0 : SwPosition* pNew = new SwPosition( *GetStart() );
274 [ # # ]: 0 : SetCurr( pNew );
275 [ # # ][ # # ]: 0 : pNew = new SwPosition( *pNew );
276 [ # # ]: 0 : SetCurrX( pNew );
277 : : }
278 : :
279 [ # # ]: 0 : pCrsr->SetMark();
280 : :
281 : 0 : pLinguFrm = 0;
282 [ # # ]: 0 : pLinguNode = 0;
283 : : }
284 : :
285 : : /*************************************************************************
286 : : * SwLinguIter::End
287 : : *************************************************************************/
288 : :
289 : :
290 : :
291 : 0 : void SwLinguIter::_End(bool bRestoreSelection)
292 : : {
293 [ # # ]: 0 : if( !pSh )
294 : 0 : return;
295 : :
296 : : OSL_ENSURE( pEnd, "SwEditShell::SpellEnd() ohne Start?");
297 [ # # ]: 0 : if(bRestoreSelection)
298 : : {
299 [ # # ]: 0 : while( nCrsrCnt-- )
300 : 0 : pSh->Pop( sal_False );
301 : :
302 : 0 : pSh->KillPams();
303 : 0 : pSh->ClearMark();
304 : : }
305 [ # # ]: 0 : DELETEZ(pStart);
306 [ # # ]: 0 : DELETEZ(pEnd);
307 [ # # ]: 0 : DELETEZ(pCurr);
308 [ # # ]: 0 : DELETEZ(pCurrX);
309 : :
310 : 0 : pSh = 0;
311 : : }
312 : :
313 : : /*************************************************************************
314 : : * virtual SwSpellIter::Start()
315 : : *************************************************************************/
316 : :
317 : :
318 : :
319 : 0 : void SwSpellIter::Start( SwEditShell *pShell, SwDocPositions eStart,
320 : : SwDocPositions eEnd )
321 : : {
322 [ # # ]: 0 : if( GetSh() )
323 : 0 : return;
324 : :
325 [ # # ]: 0 : uno::Reference< beans::XPropertySet > xProp( ::GetLinguPropertySet() );
326 [ # # ][ # # ]: 0 : xSpeller = ::GetSpellChecker();
327 [ # # ]: 0 : if ( xSpeller.is() )
328 [ # # ]: 0 : _Start( pShell, eStart, eEnd );
329 : 0 : aLastPortions.clear();
330 : 0 : aLastPositions.clear();
331 : : }
332 : :
333 : : /*************************************************************************
334 : : * SwSpellIter::Continue
335 : : *************************************************************************/
336 : :
337 : : // SwSpellIter::Continue ist das alte Original von
338 : : // SwEditShell::SpellContinue()
339 : :
340 : 0 : uno::Any SwSpellIter::Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
341 : : {
342 : : //!!
343 : : //!! Please check SwConvIter also when modifying this
344 : : //!!
345 : :
346 : 0 : uno::Any aSpellRet;
347 : 0 : SwEditShell *pMySh = GetSh();
348 [ # # ]: 0 : if( !pMySh )
349 : : return aSpellRet;
350 : :
351 : : OSL_ENSURE( GetEnd(), "SwEditShell::SpellContinue() ohne Start?");
352 : :
353 : 0 : uno::Reference< uno::XInterface > xSpellRet;
354 : 0 : sal_Bool bGoOn = sal_True;
355 [ # # ]: 0 : do {
356 [ # # ]: 0 : SwPaM *pCrsr = pMySh->GetCrsr();
357 [ # # ]: 0 : if ( !pCrsr->HasMark() )
358 [ # # ]: 0 : pCrsr->SetMark();
359 : :
360 [ # # ]: 0 : uno::Reference< beans::XPropertySet > xProp( GetLinguPropertySet() );
361 [ # # ][ # # ]: 0 : *pMySh->GetCrsr()->GetPoint() = *GetCurr();
362 [ # # ][ # # ]: 0 : *pMySh->GetCrsr()->GetMark() = *GetEnd();
363 [ # # ]: 0 : pMySh->GetDoc()->Spell(*pMySh->GetCrsr(),
364 [ # # ][ # # ]: 0 : xSpeller, pPageCnt, pPageSt, false ) >>= xSpellRet;
365 : 0 : bGoOn = GetCrsrCnt() > 1;
366 [ # # ]: 0 : if( xSpellRet.is() )
367 : : {
368 : 0 : bGoOn = sal_False;
369 [ # # ][ # # ]: 0 : SwPosition* pNewPoint = new SwPosition( *pCrsr->GetPoint() );
370 [ # # ][ # # ]: 0 : SwPosition* pNewMark = new SwPosition( *pCrsr->GetMark() );
371 [ # # ]: 0 : SetCurr( pNewPoint );
372 [ # # ]: 0 : SetCurrX( pNewMark );
373 : : }
374 [ # # ]: 0 : if( bGoOn )
375 : : {
376 [ # # ]: 0 : pMySh->Pop( sal_False );
377 [ # # ]: 0 : pCrsr = pMySh->GetCrsr();
378 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
379 : 0 : pCrsr->Exchange();
380 [ # # ][ # # ]: 0 : SwPosition* pNew = new SwPosition( *pCrsr->GetPoint() );
381 [ # # ]: 0 : SetStart( pNew );
382 [ # # ][ # # ]: 0 : pNew = new SwPosition( *pCrsr->GetMark() );
383 [ # # ]: 0 : SetEnd( pNew );
384 [ # # ][ # # ]: 0 : pNew = new SwPosition( *GetStart() );
385 [ # # ]: 0 : SetCurr( pNew );
386 [ # # ][ # # ]: 0 : pNew = new SwPosition( *pNew );
387 [ # # ]: 0 : SetCurrX( pNew );
388 [ # # ]: 0 : pCrsr->SetMark();
389 : 0 : --GetCrsrCnt();
390 : 0 : }
391 : : }while ( bGoOn );
392 [ # # ]: 0 : aSpellRet <<= xSpellRet;
393 : 0 : return aSpellRet;
394 : : }
395 : :
396 : : /*************************************************************************
397 : : * virtual SwConvIter::Start()
398 : : *************************************************************************/
399 : :
400 : :
401 : :
402 : 0 : void SwConvIter::Start( SwEditShell *pShell, SwDocPositions eStart,
403 : : SwDocPositions eEnd )
404 : : {
405 [ # # ]: 0 : if( GetSh() )
406 : 0 : return;
407 : 0 : _Start( pShell, eStart, eEnd );
408 : : }
409 : :
410 : : /*************************************************************************
411 : : * SwConvIter::Continue
412 : : *************************************************************************/
413 : :
414 : 0 : uno::Any SwConvIter::Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
415 : : {
416 : : //!!
417 : : //!! Please check SwSpellIter also when modifying this
418 : : //!!
419 : :
420 [ # # ]: 0 : uno::Any aConvRet( makeAny( rtl::OUString() ) );
421 : 0 : SwEditShell *pMySh = GetSh();
422 [ # # ]: 0 : if( !pMySh )
423 : 0 : return aConvRet;
424 : :
425 : : OSL_ENSURE( GetEnd(), "SwConvIter::Continue() ohne Start?");
426 : :
427 : 0 : rtl::OUString aConvText;
428 : 0 : sal_Bool bGoOn = sal_True;
429 [ # # ]: 0 : do {
430 [ # # ]: 0 : SwPaM *pCrsr = pMySh->GetCrsr();
431 [ # # ]: 0 : if ( !pCrsr->HasMark() )
432 [ # # ]: 0 : pCrsr->SetMark();
433 : :
434 [ # # ][ # # ]: 0 : *pMySh->GetCrsr()->GetPoint() = *GetCurr();
435 [ # # ][ # # ]: 0 : *pMySh->GetCrsr()->GetMark() = *GetEnd();
436 : :
437 : : // call function to find next text portion to be converted
438 : 0 : uno::Reference< linguistic2::XSpellChecker1 > xEmpty;
439 [ # # ]: 0 : pMySh->GetDoc()->Spell( *pMySh->GetCrsr(),
440 [ # # ]: 0 : xEmpty, pPageCnt, pPageSt, false, &rArgs ) >>= aConvText;
441 : :
442 : 0 : bGoOn = GetCrsrCnt() > 1;
443 [ # # ]: 0 : if( !aConvText.isEmpty() )
444 : : {
445 : 0 : bGoOn = sal_False;
446 [ # # ][ # # ]: 0 : SwPosition* pNewPoint = new SwPosition( *pCrsr->GetPoint() );
447 [ # # ][ # # ]: 0 : SwPosition* pNewMark = new SwPosition( *pCrsr->GetMark() );
448 : :
449 [ # # ]: 0 : SetCurr( pNewPoint );
450 [ # # ]: 0 : SetCurrX( pNewMark );
451 : : }
452 [ # # ]: 0 : if( bGoOn )
453 : : {
454 [ # # ]: 0 : pMySh->Pop( sal_False );
455 [ # # ]: 0 : pCrsr = pMySh->GetCrsr();
456 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
457 : 0 : pCrsr->Exchange();
458 [ # # ][ # # ]: 0 : SwPosition* pNew = new SwPosition( *pCrsr->GetPoint() );
459 [ # # ]: 0 : SetStart( pNew );
460 [ # # ][ # # ]: 0 : pNew = new SwPosition( *pCrsr->GetMark() );
461 [ # # ]: 0 : SetEnd( pNew );
462 [ # # ][ # # ]: 0 : pNew = new SwPosition( *GetStart() );
463 [ # # ]: 0 : SetCurr( pNew );
464 [ # # ][ # # ]: 0 : pNew = new SwPosition( *pNew );
465 [ # # ]: 0 : SetCurrX( pNew );
466 [ # # ]: 0 : pCrsr->SetMark();
467 : 0 : --GetCrsrCnt();
468 : 0 : }
469 : : }while ( bGoOn );
470 [ # # ]: 0 : return makeAny( aConvText );
471 : : }
472 : :
473 : :
474 : : /*************************************************************************
475 : : * SwHyphIter
476 : : *************************************************************************/
477 : :
478 : :
479 : 0 : sal_Bool SwHyphIter::IsAuto()
480 : : {
481 [ # # ]: 0 : uno::Reference< beans::XPropertySet > xProp( ::GetLinguPropertySet() );
482 [ # # ]: 0 : return xProp.is() ? *(sal_Bool*)xProp->getPropertyValue(
483 [ # # ][ # # ]: 0 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UPN_IS_HYPH_AUTO)) ).getValue()
[ # # ][ # # ]
[ # # # # ]
484 [ # # ]: 0 : : sal_False;
485 : : }
486 : :
487 : :
488 : 0 : void SwHyphIter::ShowSelection()
489 : : {
490 : 0 : SwEditShell *pMySh = GetSh();
491 [ # # ]: 0 : if( pMySh )
492 : : {
493 : 0 : pMySh->StartAction();
494 : : // Ganz fatal: durch das EndAction() werden Formatierungen
495 : : // angeregt, die dazu fuehren koennen, dass im Hyphenator
496 : : // neue Worte eingestellt werden. Deswegen sichern!
497 : 0 : pMySh->EndAction();
498 : : }
499 : 0 : }
500 : :
501 : : /*************************************************************************
502 : : * virtual SwHyphIter::Start()
503 : : *************************************************************************/
504 : :
505 : :
506 : :
507 : 0 : void SwHyphIter::Start( SwEditShell *pShell, SwDocPositions eStart, SwDocPositions eEnd )
508 : : {
509 : : // robust
510 [ # # ][ # # ]: 0 : if( GetSh() || GetEnd() )
[ # # ]
511 : : {
512 : : OSL_ENSURE( !GetSh(), "+SwEditShell::HyphStart: missing HyphEnd()" );
513 : 0 : return;
514 : : }
515 : :
516 : : // nothing to be done (at least not in the way as in the "else" part)
517 : 0 : bOldIdle = pShell->GetViewOptions()->IsIdle();
518 : 0 : ((SwViewOption*)pShell->GetViewOptions())->SetIdle( sal_False );
519 : 0 : _Start( pShell, eStart, eEnd );
520 : : }
521 : :
522 : : /*************************************************************************
523 : : * virtual SwHyphIter::End
524 : : *************************************************************************/
525 : :
526 : : // Selektionen wiederherstellen
527 : :
528 : :
529 : :
530 : 0 : void SwHyphIter::End()
531 : : {
532 [ # # ]: 0 : if( !GetSh() )
533 : 0 : return;
534 : 0 : ((SwViewOption*)GetSh()->GetViewOptions())->SetIdle( bOldIdle );
535 : 0 : _End();
536 : : }
537 : :
538 : : /*************************************************************************
539 : : * SwHyphIter::Continue
540 : : *************************************************************************/
541 : :
542 : 0 : uno::Any SwHyphIter::Continue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
543 : : {
544 : 0 : uno::Any aHyphRet;
545 : 0 : SwEditShell *pMySh = GetSh();
546 [ # # ]: 0 : if( !pMySh )
547 : : return aHyphRet;
548 : :
549 [ # # ]: 0 : const sal_Bool bAuto = IsAuto();
550 : 0 : uno::Reference< XHyphenatedWord > xHyphWord;
551 : 0 : sal_Bool bGoOn = sal_False;
552 [ # # ]: 0 : do {
553 : : SwPaM *pCrsr;
554 [ # # # # ]: 0 : do {
[ # # ]
555 : : OSL_ENSURE( GetEnd(), "SwEditShell::SpellContinue() ohne Start?" );
556 [ # # ]: 0 : pCrsr = pMySh->GetCrsr();
557 [ # # ]: 0 : if ( !pCrsr->HasMark() )
558 [ # # ]: 0 : pCrsr->SetMark();
559 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() < *pCrsr->GetMark() )
560 : : {
561 : 0 : pCrsr->Exchange();
562 [ # # ]: 0 : pCrsr->SetMark();
563 : : }
564 : :
565 [ # # ][ # # ]: 0 : if ( *pCrsr->End() <= *GetEnd() )
[ # # ]
566 : : {
567 [ # # ]: 0 : *pCrsr->GetMark() = *GetEnd();
568 : :
569 : : // Muss an der aktuellen Cursorpos das Wort getrennt werden ?
570 : 0 : const Point aCrsrPos( pMySh->GetCharRect().Pos() );
571 : : xHyphWord = pMySh->GetDoc()->Hyphenate( pCrsr, aCrsrPos,
572 [ # # ][ # # ]: 0 : pPageCnt, pPageSt );
573 : : }
574 : :
575 [ # # ][ # # ]: 0 : if( bAuto && xHyphWord.is() )
[ # # ]
576 : : {
577 [ # # ][ # # ]: 0 : pMySh->InsertSoftHyph( xHyphWord->getHyphenationPos() + 1);
[ # # ]
578 : : }
579 : 0 : } while( bAuto && xHyphWord.is() ); //end of do-while
580 [ # # ][ # # ]: 0 : bGoOn = !xHyphWord.is() && GetCrsrCnt() > 1;
581 : :
582 [ # # ]: 0 : if( bGoOn )
583 : : {
584 [ # # ]: 0 : pMySh->Pop( sal_False );
585 [ # # ]: 0 : pCrsr = pMySh->GetCrsr();
586 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
587 : 0 : pCrsr->Exchange();
588 [ # # ][ # # ]: 0 : SwPosition* pNew = new SwPosition(*pCrsr->End());
[ # # ]
589 [ # # ]: 0 : SetEnd( pNew );
590 [ # # ]: 0 : pCrsr->SetMark();
591 : 0 : --GetCrsrCnt();
592 : : }
593 : : } while ( bGoOn );
594 [ # # ]: 0 : aHyphRet <<= xHyphWord;
595 : 0 : return aHyphRet;
596 : : }
597 : :
598 : : /*************************************************************************
599 : : * SwHyphIter::HyphIgnore
600 : : *************************************************************************/
601 : :
602 : : // Beschreibung: Trennstelle ignorieren
603 : :
604 : 0 : void SwHyphIter::Ignore()
605 : : {
606 : 0 : SwEditShell *pMySh = GetSh();
607 : 0 : SwPaM *pCrsr = pMySh->GetCrsr();
608 : :
609 : : // Alten SoftHyphen loeschen
610 : 0 : DelSoftHyph( *pCrsr );
611 : :
612 : : // und weiter
613 : 0 : pCrsr->Start()->nContent = pCrsr->End()->nContent;
614 : 0 : pCrsr->SetMark();
615 : 0 : }
616 : :
617 : : /*************************************************************************
618 : : * SwHyphIter::DelSoftHyph
619 : : *************************************************************************/
620 : :
621 : 0 : void SwHyphIter::DelSoftHyph( SwPaM &rPam )
622 : : {
623 : 0 : const SwPosition* pStt = rPam.Start();
624 : 0 : const xub_StrLen nStart = pStt->nContent.GetIndex();
625 : 0 : const xub_StrLen nEnd = rPam.End()->nContent.GetIndex();
626 : 0 : SwTxtNode *pNode = pStt->nNode.GetNode().GetTxtNode();
627 : 0 : pNode->DelSoftHyph( nStart, nEnd );
628 : 0 : }
629 : :
630 : : /*************************************************************************
631 : : * SwHyphIter::InsertSoftHyph
632 : : *************************************************************************/
633 : :
634 : :
635 : 0 : void SwHyphIter::InsertSoftHyph( const xub_StrLen nHyphPos )
636 : : {
637 : 0 : SwEditShell *pMySh = GetSh();
638 : : OSL_ENSURE( pMySh, "+SwEditShell::InsertSoftHyph: missing HyphStart()");
639 [ # # ]: 0 : if( !pMySh )
640 : 0 : return;
641 : :
642 : 0 : SwPaM *pCrsr = pMySh->GetCrsr();
643 : 0 : SwPosition* pSttPos = pCrsr->Start();
644 : 0 : SwPosition* pEndPos = pCrsr->End();
645 : :
646 : 0 : xub_StrLen nLastHyphLen = GetEnd()->nContent.GetIndex() -
647 : 0 : pSttPos->nContent.GetIndex();
648 : :
649 [ # # ][ # # ]: 0 : if( pSttPos->nNode != pEndPos->nNode || !nLastHyphLen )
[ # # ]
650 : : {
651 : : OSL_ENSURE( pSttPos->nNode == pEndPos->nNode,
652 : : "+SwEditShell::InsertSoftHyph: node warp during hyphenation" );
653 : : OSL_ENSURE(nLastHyphLen, "+SwEditShell::InsertSoftHyph: missing HyphContinue()");
654 : 0 : *pSttPos = *pEndPos;
655 : 0 : return;
656 : : }
657 : :
658 : 0 : pMySh->StartAction();
659 : : {
660 : 0 : SwDoc *pDoc = pMySh->GetDoc();
661 [ # # ]: 0 : DelSoftHyph( *pCrsr );
662 [ # # ]: 0 : pSttPos->nContent += nHyphPos;
663 [ # # ]: 0 : SwPaM aRg( *pSttPos );
664 [ # # ][ # # ]: 0 : pDoc->InsertString( aRg, rtl::OUString(CHAR_SOFTHYPHEN) );
[ # # ][ # # ]
665 : : // Durch das Einfuegen des SoftHyphs ist ein Zeichen hinzugekommen
666 : : //JP 18.07.95: warum, ist doch ein SwIndex, dieser wird doch mitverschoben !!
667 : : // pSttPos->nContent++;
668 : : }
669 : : // Die Selektion wird wieder aufgehoben
670 : 0 : pCrsr->DeleteMark();
671 : 0 : pMySh->EndAction();
672 : 0 : pCrsr->SetMark();
673 : : }
674 : :
675 : : // --------------------- Methoden der SwEditShell ------------------------
676 : :
677 : 0 : bool SwEditShell::HasLastSentenceGotGrammarChecked() const
678 : : {
679 : 0 : bool bTextWasGrammarChecked = false;
680 [ # # ]: 0 : if (pSpellIter)
681 : : {
682 [ # # ]: 0 : ::svx::SpellPortions aLastPortions( pSpellIter->GetLastPortions() );
683 [ # # ][ # # ]: 0 : for (size_t i = 0; i < aLastPortions.size() && !bTextWasGrammarChecked; ++i)
[ # # ]
684 : : {
685 : : // bIsGrammarError is also true if the text was only checked but no
686 : : // grammar error was found. (That is if a ProofreadingResult was obtained in
687 : : // SwDoc::Spell and in turn bIsGrammarError was set in SwSpellIter::CreatePortion)
688 [ # # ]: 0 : if (aLastPortions[i].bIsGrammarError)
689 : 0 : bTextWasGrammarChecked = true;
690 : 0 : }
691 : : }
692 : 0 : return bTextWasGrammarChecked;
693 : : }
694 : :
695 : : /*************************************************************************
696 : : * SwEditShell::HasConvIter
697 : : *************************************************************************/
698 : :
699 : 0 : sal_Bool SwEditShell::HasConvIter() const
700 : : {
701 : 0 : return 0 != pConvIter;
702 : : }
703 : :
704 : : /*************************************************************************
705 : : * SwEditShell::HasHyphIter
706 : : *************************************************************************/
707 : :
708 : 0 : sal_Bool SwEditShell::HasHyphIter() const
709 : : {
710 : 0 : return 0 != pHyphIter;
711 : : }
712 : :
713 : : /*************************************************************************
714 : : * SwEditShell::SetFindRange
715 : : *************************************************************************/
716 : :
717 : 0 : void SwEditShell::SetLinguRange( SwDocPositions eStart, SwDocPositions eEnd )
718 : : {
719 : 0 : SwPaM *pCrsr = GetCrsr();
720 : 0 : MakeFindRange( static_cast<sal_uInt16>(eStart), static_cast<sal_uInt16>(eEnd), pCrsr );
721 [ # # ]: 0 : if( *pCrsr->GetPoint() > *pCrsr->GetMark() )
722 : 0 : pCrsr->Exchange();
723 : 0 : }
724 : :
725 : : /*************************************************************************
726 : : * SwEditShell::SpellStart
727 : : *************************************************************************/
728 : :
729 : 0 : void SwEditShell::SpellStart(
730 : : SwDocPositions eStart, SwDocPositions eEnd, SwDocPositions eCurr,
731 : : SwConversionArgs *pConvArgs )
732 : : {
733 : 0 : SwLinguIter *pLinguIter = 0;
734 : :
735 : : // do not spell if interactive spelling is active elsewhere
736 [ # # ][ # # ]: 0 : if (!pConvArgs && !pSpellIter)
737 : : {
738 : : OSL_ENSURE( !pSpellIter, "wer ist da schon am spellen?" );
739 [ # # ]: 0 : pSpellIter = new SwSpellIter;
740 : 0 : pLinguIter = pSpellIter;
741 : : }
742 : : // do not do text conversion if it is active elsewhere
743 [ # # ][ # # ]: 0 : if (pConvArgs && !pConvIter)
744 : : {
745 : : OSL_ENSURE( !pConvIter, "text conversion already active!" );
746 [ # # ]: 0 : pConvIter = new SwConvIter( *pConvArgs );
747 : 0 : pLinguIter = pConvIter;
748 : : }
749 : :
750 [ # # ]: 0 : if (pLinguIter)
751 : : {
752 : 0 : SwCursor* pSwCrsr = GetSwCrsr();
753 : :
754 [ # # ]: 0 : SwPosition *pTmp = new SwPosition( *pSwCrsr->GetPoint() );
755 : 0 : pSwCrsr->FillFindPos( eCurr, *pTmp );
756 : 0 : pLinguIter->SetCurr( pTmp );
757 : :
758 [ # # ]: 0 : pTmp = new SwPosition( *pTmp );
759 : 0 : pLinguIter->SetCurrX( pTmp );
760 : : }
761 : :
762 [ # # ][ # # ]: 0 : if (!pConvArgs && pSpellIter)
763 : 0 : pSpellIter->Start( this, eStart, eEnd );
764 [ # # ][ # # ]: 0 : if (pConvArgs && pConvIter)
765 : 0 : pConvIter->Start( this, eStart, eEnd );
766 : 0 : }
767 : :
768 : : /*************************************************************************
769 : : * SwEditShell::SpellEnd
770 : : *************************************************************************/
771 : :
772 : 0 : void SwEditShell::SpellEnd( SwConversionArgs *pConvArgs, bool bRestoreSelection )
773 : : {
774 [ # # ][ # # ]: 0 : if (!pConvArgs && pSpellIter && pSpellIter->GetSh() == this)
[ # # ][ # # ]
775 : : {
776 : : OSL_ENSURE( pSpellIter, "wo ist mein Iterator?" );
777 : 0 : pSpellIter->_End(bRestoreSelection);
778 [ # # ]: 0 : delete pSpellIter, pSpellIter = 0;
779 : : }
780 [ # # ][ # # ]: 0 : if (pConvArgs && pConvIter && pConvIter->GetSh() == this)
[ # # ][ # # ]
781 : : {
782 : : OSL_ENSURE( pConvIter, "wo ist mein Iterator?" );
783 : 0 : pConvIter->_End();
784 : 0 : delete pConvIter, pConvIter = 0;
785 : : }
786 : 0 : }
787 : :
788 : : /*************************************************************************
789 : : * SwEditShell::SpellContinue
790 : : *************************************************************************/
791 : :
792 : : // liefert Rueckgabewerte entsprechend SPL_ in splchk.hxx
793 : :
794 : 0 : uno::Any SwEditShell::SpellContinue(
795 : : sal_uInt16* pPageCnt, sal_uInt16* pPageSt,
796 : : SwConversionArgs *pConvArgs )
797 : : {
798 : 0 : uno::Any aRes;
799 : :
800 [ # # ]: 0 : if ((!pConvArgs && pSpellIter->GetSh() != this) ||
[ # # # # ]
[ # # ][ # # ]
801 : 0 : ( pConvArgs && pConvIter->GetSh() != this))
802 : : return aRes;
803 : :
804 [ # # ][ # # ]: 0 : if( pPageCnt && !*pPageCnt )
805 : : {
806 [ # # ]: 0 : sal_uInt16 nEndPage = GetLayout()->GetPageNum();
807 : 0 : nEndPage += nEndPage * 10 / 100;
808 : 0 : *pPageCnt = nEndPage;
809 [ # # ]: 0 : if( nEndPage )
810 [ # # ]: 0 : ::StartProgress( STR_STATSTR_SPELL, 0, nEndPage, GetDoc()->GetDocShell() );
811 : : }
812 : :
813 : : OSL_ENSURE( pConvArgs || pSpellIter, "SpellIter missing" );
814 : : OSL_ENSURE( !pConvArgs || pConvIter, "ConvIter missing" );
815 : : //JP 18.07.95: verhinder bei Fehlermeldungen die Anzeige der Selektionen
816 : : // KEIN StartAction, da damit auch die Paints abgeschaltet
817 : : // werden !!!!!
818 : 0 : ++nStartAction;
819 : 0 : rtl::OUString aRet;
820 : 0 : uno::Reference< uno::XInterface > xRet;
821 [ # # ]: 0 : if (pConvArgs)
822 : : {
823 [ # # ]: 0 : pConvIter->Continue( pPageCnt, pPageSt ) >>= aRet;
824 [ # # ]: 0 : aRes <<= aRet;
825 : : }
826 : : else
827 : : {
828 [ # # ][ # # ]: 0 : pSpellIter->Continue( pPageCnt, pPageSt ) >>= xRet;
829 [ # # ]: 0 : aRes <<= xRet;
830 : : }
831 : 0 : --nStartAction;
832 : :
833 [ # # ][ # # ]: 0 : if( !aRet.isEmpty() || xRet.is() )
[ # # ]
834 : : {
835 : : // dann die awt::Selection sichtbar machen
836 [ # # ]: 0 : StartAction();
837 [ # # ]: 0 : EndAction();
838 : : }
839 : 0 : return aRes;
840 : : }
841 : : /*************************************************************************
842 : : * SwEditShell::HyphStart
843 : : *************************************************************************/
844 : :
845 : : /* Interaktive Trennung, BP 10.03.93
846 : : *
847 : : * 1) HyphStart
848 : : * - Aufheben aller Selektionen
849 : : * - Sichern des aktuellen Cursors
850 : : * - falls keine Selektion vorhanden:
851 : : * - neue Selektion bis zum Dokumentende
852 : : * 2) HyphContinue
853 : : * - nLastHyphLen wird auf den Selektionsstart addiert
854 : : * - iteriert ueber alle selektierten Bereiche
855 : : * - pDoc->Hyphenate() iteriert ueber alle Nodes der Selektion
856 : : * - pTxtNode->Hyphenate() ruft das SwTxtFrm::Hyphenate zur EditShell
857 : : * - SwTxtFrm:Hyphenate() iteriert ueber die Zeilen des Pams
858 : : * - LineIter::Hyphenate() stellt den Hyphenator
859 : : * und den Pam auf das zu trennende Wort ein.
860 : : * - Es gibt nur zwei Returnwerte sal_True, wenn eine Trennstelle anliegt
861 : : * und sal_False, wenn der Pam abgearbeitet wurde.
862 : : * - Bei sal_True wird das selektierte Wort zur Anzeige gebracht und
863 : : * nLastHyphLen gesetzt.
864 : : * - Bei sal_False wird die aktuelle Selektion geloescht und die naechste
865 : : * zur aktuellen gewaehlt. Return HYPH_OK, wenn keine mehr vorhanden.
866 : : * 3) InsertSoftHyph (wird ggf. von der UI gerufen)
867 : : * - Der aktuelle Cursor wird plaziert und das Attribut eingefuegt.
868 : : * 4) HyphEnd
869 : : * - Wiederherstellen des alten Cursors, EndAction
870 : : */
871 : :
872 : :
873 : :
874 : 0 : void SwEditShell::HyphStart( SwDocPositions eStart, SwDocPositions eEnd )
875 : : {
876 : : // do not hyphenate if interactive hyphenationg is active elsewhere
877 [ # # ]: 0 : if (!pHyphIter)
878 : : {
879 : : OSL_ENSURE( !pHyphIter, "wer ist da schon am hyphinieren?" );
880 [ # # ]: 0 : pHyphIter = new SwHyphIter;
881 : 0 : pHyphIter->Start( this, eStart, eEnd );
882 : : }
883 : 0 : }
884 : :
885 : : /*************************************************************************
886 : : * SwEditShell::HyphEnd
887 : : *************************************************************************/
888 : :
889 : : // Selektionen wiederherstellen
890 : :
891 : :
892 : :
893 : 0 : void SwEditShell::HyphEnd()
894 : : {
895 [ # # ]: 0 : if (pHyphIter->GetSh() == this)
896 : : {
897 : : OSL_ENSURE( pHyphIter, "wo ist mein Iterator?" );
898 : 0 : pHyphIter->End();
899 : 0 : delete pHyphIter, pHyphIter = 0;
900 : : }
901 : 0 : }
902 : :
903 : : /*************************************************************************
904 : : * SwEditShell::HyphContinue
905 : : *************************************************************************/
906 : :
907 : : // Returnwerte: (BP: ich wuerde es genau umdrehen, aber die UI wuenscht es so)
908 : : // HYPH_CONTINUE, wenn eine Trennstelle anliegt
909 : : // HYPH_OK, wenn der selektierte Bereich abgearbeitet wurde.
910 : :
911 : :
912 : : uno::Reference< uno::XInterface >
913 : 0 : SwEditShell::HyphContinue( sal_uInt16* pPageCnt, sal_uInt16* pPageSt )
914 : : {
915 [ # # ]: 0 : if (pHyphIter->GetSh() != this)
916 [ # # ]: 0 : return 0;
917 : :
918 [ # # ][ # # ]: 0 : if( pPageCnt && !*pPageCnt && !*pPageSt )
[ # # ]
919 : : {
920 [ # # ]: 0 : sal_uInt16 nEndPage = GetLayout()->GetPageNum();
921 : 0 : nEndPage += nEndPage * 10 / 100;
922 [ # # ]: 0 : if( nEndPage > 14 )
923 : : {
924 : 0 : *pPageCnt = nEndPage;
925 [ # # ]: 0 : ::StartProgress( STR_STATSTR_HYPHEN, 0, nEndPage, GetDoc()->GetDocShell());
926 : : }
927 : : else // Hiermit unterdruecken wir ein fuer allemal
928 : 0 : *pPageSt = 1; // das StatLineStartPercent
929 : : }
930 : :
931 : : OSL_ENSURE( pHyphIter, "wo ist mein Iterator?" );
932 : : //JP 18.07.95: verhinder bei Fehlermeldungen die Anzeige der Selektionen
933 : : // KEIN StartAction, da damit auch die Paints abgeschaltet
934 : : // werden !!!!!
935 : 0 : ++nStartAction;
936 : 0 : uno::Reference< uno::XInterface > xRet;
937 [ # # ][ # # ]: 0 : pHyphIter->Continue( pPageCnt, pPageSt ) >>= xRet;
938 : 0 : --nStartAction;
939 : :
940 [ # # ]: 0 : if( xRet.is() )
941 [ # # ]: 0 : pHyphIter->ShowSelection();
942 : :
943 : 0 : return xRet;
944 : : }
945 : :
946 : :
947 : : /*************************************************************************
948 : : * SwEditShell::InsertSoftHyph
949 : : *************************************************************************/
950 : :
951 : : // Zum Einfuegen des SoftHyphens, Position ist der Offset
952 : : // innerhalb des getrennten Wortes.
953 : :
954 : :
955 : 0 : void SwEditShell::InsertSoftHyph( const xub_StrLen nHyphPos )
956 : : {
957 : : OSL_ENSURE( pHyphIter, "wo ist mein Iterator?" );
958 : 0 : pHyphIter->InsertSoftHyph( nHyphPos );
959 : 0 : }
960 : :
961 : :
962 : : /*************************************************************************
963 : : * SwEditShell::HyphIgnore
964 : : *************************************************************************/
965 : :
966 : : // Beschreibung: Trennstelle ignorieren
967 : :
968 : 0 : void SwEditShell::HyphIgnore()
969 : : {
970 : : OSL_ENSURE( pHyphIter, "wo ist mein Iterator?" );
971 : : //JP 18.07.95: verhinder bei Fehlermeldungen die Anzeige der Selektionen
972 : : // KEIN StartAction, da damit auch die Paints abgeschaltet
973 : : // werden !!!!!
974 : 0 : ++nStartAction;
975 : 0 : pHyphIter->Ignore();
976 : 0 : --nStartAction;
977 : :
978 : 0 : pHyphIter->ShowSelection();
979 : 0 : }
980 : :
981 : : /*************************************************************************
982 : : * SwEditShell::GetCorrection()
983 : : * liefert eine Liste von Vorschlaegen fuer falsch geschriebene Worte,
984 : : * ein NULL-Pointer signalisiert, dass das Wort richtig geschrieben ist,
985 : : * eine leere Liste, dass das Wort zwar unbekannt ist, aber keine Alternativen
986 : : * geliefert werden koennen.
987 : : *************************************************************************/
988 : :
989 : :
990 : : uno::Reference< XSpellAlternatives >
991 : 0 : SwEditShell::GetCorrection( const Point* pPt, SwRect& rSelectRect )
992 : : {
993 : 0 : uno::Reference< XSpellAlternatives > xSpellAlt;
994 : :
995 [ # # ]: 0 : if( IsTableMode() )
996 [ # # ]: 0 : return NULL;
997 [ # # ]: 0 : SwPaM* pCrsr = GetCrsr();
998 [ # # ]: 0 : SwPosition aPos( *pCrsr->GetPoint() );
999 : 0 : Point aPt( *pPt );
1000 : 0 : SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
1001 : : SwTxtNode *pNode;
1002 : : SwWrongList *pWrong;
1003 [ # # ]: 0 : if( GetLayout()->GetCrsrOfst( &aPos, aPt, &eTmpState ) &&
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1004 : 0 : 0 != (pNode = aPos.nNode.GetNode().GetTxtNode()) &&
1005 : : 0 != (pWrong = pNode->GetWrong()) &&
1006 [ # # ]: 0 : !pNode->IsInProtectSect() )
1007 : : {
1008 : 0 : xub_StrLen nBegin = aPos.nContent.GetIndex();
1009 : 0 : xub_StrLen nLen = 1;
1010 [ # # ][ # # ]: 0 : if( pWrong->InWrongWord(nBegin,nLen) && !pNode->IsSymbol(nBegin) )
[ # # ][ # # ]
[ # # ]
1011 : : {
1012 [ # # ]: 0 : String aText( pNode->GetTxt().Copy( nBegin, nLen ) );
1013 [ # # ]: 0 : String aWord( aText );
1014 [ # # ][ # # ]: 0 : aWord = comphelper::string::remove(aWord, CH_TXTATR_BREAKWORD);
1015 [ # # ][ # # ]: 0 : aWord = comphelper::string::remove(aWord, CH_TXTATR_INWORD);
1016 : :
1017 [ # # ]: 0 : uno::Reference< XSpellChecker1 > xSpell( ::GetSpellChecker() );
1018 [ # # ]: 0 : if( xSpell.is() )
1019 : : {
1020 [ # # ]: 0 : LanguageType eActLang = (LanguageType)pNode->GetLang( nBegin, nLen );
1021 [ # # ][ # # ]: 0 : if( xSpell->hasLanguage( eActLang ))
[ # # ]
1022 : : {
1023 : : // restrict the maximal number of suggestions displayed
1024 : : // in the context menu.
1025 : : // Note: That could of course be done by clipping the
1026 : : // resulting sequence but the current third party
1027 : : // implementations result differs greatly if the number of
1028 : : // suggestions to be retuned gets changed. Statistically
1029 : : // it gets much better if told to return e.g. only 7 strings
1030 : : // than returning e.g. 16 suggestions and using only the
1031 : : // first 7. Thus we hand down the value to use to that
1032 : : // implementation here by providing an additional parameter.
1033 [ # # ]: 0 : Sequence< PropertyValue > aPropVals(1);
1034 [ # # ]: 0 : PropertyValue &rVal = aPropVals.getArray()[0];
1035 [ # # ]: 0 : rVal.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( UPN_MAX_NUMBER_OF_SUGGESTIONS ));
1036 [ # # ]: 0 : rVal.Value <<= (sal_Int16) 7;
1037 : :
1038 [ # # ][ # # ]: 0 : xSpellAlt = xSpell->spell( aWord, eActLang, aPropVals );
[ # # ][ # # ]
[ # # ]
1039 : : }
1040 : : }
1041 : :
1042 [ # # ]: 0 : if ( xSpellAlt.is() ) // error found?
1043 : : {
1044 : : //save the start and end positons of the line and the starting point
1045 [ # # ]: 0 : Push();
1046 [ # # ]: 0 : LeftMargin();
1047 [ # # ]: 0 : xub_StrLen nLineStart = GetCrsr()->GetPoint()->nContent.GetIndex();
1048 [ # # ]: 0 : RightMargin();
1049 [ # # ]: 0 : xub_StrLen nLineEnd = GetCrsr()->GetPoint()->nContent.GetIndex();
1050 [ # # ]: 0 : Pop(sal_False);
1051 : :
1052 : : // make sure the selection build later from the data below does
1053 : : // not "in word" character to the left and right in order to
1054 : : // preserve those. Therefore count those "in words" in order to
1055 : : // modify the selection accordingly.
1056 : 0 : const sal_Unicode* pChar = aText.GetBuffer();
1057 : 0 : xub_StrLen nLeft = 0;
1058 [ # # ][ # # ]: 0 : while (pChar && *pChar++ == CH_TXTATR_INWORD)
[ # # ]
1059 : 0 : ++nLeft;
1060 [ # # ]: 0 : pChar = aText.Len() ? aText.GetBuffer() + aText.Len() - 1 : 0;
1061 : 0 : xub_StrLen nRight = 0;
1062 [ # # ][ # # ]: 0 : while (pChar && *pChar-- == CH_TXTATR_INWORD)
[ # # ]
1063 : 0 : ++nRight;
1064 : :
1065 [ # # ]: 0 : aPos.nContent = nBegin + nLeft;
1066 [ # # ]: 0 : pCrsr = GetCrsr();
1067 [ # # ]: 0 : *pCrsr->GetPoint() = aPos;
1068 [ # # ]: 0 : pCrsr->SetMark();
1069 [ # # ]: 0 : ExtendSelection( sal_True, nLen - nLeft - nRight );
1070 : : //no determine the rectangle in the current line
1071 : 0 : xub_StrLen nWordStart = (nBegin + nLeft) < nLineStart ? nLineStart : nBegin + nLeft;
1072 : : //take one less than the line end - otherwise the next line would be calculated
1073 : 0 : xub_StrLen nWordEnd = (nBegin + nLen - nLeft - nRight) > nLineEnd ? nLineEnd: (nBegin + nLen - nLeft - nRight);
1074 [ # # ]: 0 : Push();
1075 [ # # ]: 0 : pCrsr->DeleteMark();
1076 [ # # ]: 0 : SwIndex& rContent = GetCrsr()->GetPoint()->nContent;
1077 [ # # ]: 0 : rContent = nWordStart;
1078 : 0 : SwRect aStartRect;
1079 : 0 : SwCrsrMoveState aState;
1080 : 0 : aState.bRealWidth = sal_True;
1081 : 0 : SwCntntNode* pCntntNode = pCrsr->GetCntntNode();
1082 [ # # ][ # # ]: 0 : SwCntntFrm *pCntntFrame = pCntntNode->getLayoutFrm( GetLayout(), pPt, pCrsr->GetPoint(), sal_False);
1083 : :
1084 [ # # ]: 0 : pCntntFrame->GetCharRect( aStartRect, *pCrsr->GetPoint(), &aState );
1085 [ # # ]: 0 : rContent = nWordEnd - 1;
1086 : 0 : SwRect aEndRect;
1087 [ # # ]: 0 : pCntntFrame->GetCharRect( aEndRect, *pCrsr->GetPoint(),&aState );
1088 [ # # ]: 0 : rSelectRect = aStartRect.Union( aEndRect );
1089 [ # # ]: 0 : Pop(sal_False);
1090 [ # # ][ # # ]: 0 : }
1091 : : }
1092 : : }
1093 [ # # ]: 0 : return xSpellAlt;
1094 : : }
1095 : :
1096 : :
1097 : :
1098 : 0 : bool SwEditShell::GetGrammarCorrection(
1099 : : linguistic2::ProofreadingResult /*out*/ &rResult, // the complete result
1100 : : sal_Int32 /*out*/ &rErrorPosInText, // offset of error position in string that was grammar checked...
1101 : : sal_Int32 /*out*/ &rErrorIndexInResult, // index of error in rResult.aGrammarErrors
1102 : : uno::Sequence< rtl::OUString > /*out*/ &rSuggestions, // suggestions to be used for the error found
1103 : : const Point *pPt, SwRect &rSelectRect )
1104 : : {
1105 : 0 : bool bRes = false;
1106 : :
1107 [ # # ]: 0 : if( IsTableMode() )
1108 : 0 : return bRes;
1109 : :
1110 [ # # ]: 0 : SwPaM* pCrsr = GetCrsr();
1111 [ # # ]: 0 : SwPosition aPos( *pCrsr->GetPoint() );
1112 : 0 : Point aPt( *pPt );
1113 : 0 : SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
1114 : : SwTxtNode *pNode;
1115 : : SwGrammarMarkUp *pWrong;
1116 [ # # ]: 0 : if( GetLayout()->GetCrsrOfst( &aPos, aPt, &eTmpState ) &&
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1117 : 0 : 0 != (pNode = aPos.nNode.GetNode().GetTxtNode()) &&
1118 : : 0 != (pWrong = pNode->GetGrammarCheck()) &&
1119 [ # # ]: 0 : !pNode->IsInProtectSect() )
1120 : : {
1121 : 0 : xub_StrLen nBegin = aPos.nContent.GetIndex();
1122 : 0 : xub_StrLen nLen = 1;
1123 [ # # ][ # # ]: 0 : if (pWrong->InWrongWord(nBegin, nLen))
1124 : : {
1125 [ # # ]: 0 : String aText( pNode->GetTxt().Copy( nBegin, nLen ) );
1126 : :
1127 [ # # ]: 0 : uno::Reference< linguistic2::XProofreadingIterator > xGCIterator( pDoc->GetGCIterator() );
1128 [ # # ]: 0 : if (xGCIterator.is())
1129 : : {
1130 : : // LanguageType eActLang = (LanguageType)pNode->GetLang( nBegin, nLen );
1131 [ # # ][ # # ]: 0 : uno::Reference< lang::XComponent > xDoc( pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY );
1132 : :
1133 : : // Expand the string:
1134 [ # # ]: 0 : const ModelToViewHelper aConversionMap(*pNode);
1135 : 0 : rtl::OUString aExpandText = aConversionMap.getViewText();
1136 : : // get XFlatParagraph to use...
1137 [ # # ][ # # ]: 0 : uno::Reference< text::XFlatParagraph > xFlatPara = new SwXFlatParagraph( *pNode, aExpandText, aConversionMap );
[ # # ]
1138 : :
1139 : : // get error position of cursor in XFlatParagraph
1140 [ # # ]: 0 : rErrorPosInText = aConversionMap.ConvertToViewPosition( nBegin );
1141 : :
1142 [ # # ][ # # ]: 0 : sal_Int32 nStartOfSentence = aConversionMap.ConvertToViewPosition( pWrong->getSentenceStart( nBegin ) );
1143 [ # # ][ # # ]: 0 : sal_Int32 nEndOfSentence = aConversionMap.ConvertToViewPosition( pWrong->getSentenceEnd( nBegin ) );
1144 [ # # ]: 0 : if( nEndOfSentence == STRING_LEN )
1145 : : {
1146 : 0 : nEndOfSentence = aExpandText.getLength();
1147 : : }
1148 : :
1149 [ # # ]: 0 : rResult = xGCIterator->checkSentenceAtPosition(
1150 [ # # ][ # # ]: 0 : xDoc, xFlatPara, aExpandText, lang::Locale(), nStartOfSentence, nEndOfSentence, rErrorPosInText );
[ # # ]
1151 : 0 : bRes = true;
1152 : :
1153 : : // get suggestions to use for the specific error position
1154 : 0 : sal_Int32 nErrors = rResult.aErrors.getLength();
1155 [ # # ]: 0 : rSuggestions.realloc( 0 );
1156 [ # # ]: 0 : for (sal_Int32 i = 0; i < nErrors; ++i )
1157 : : {
1158 : : // return suggestions for first error that includes the given error position
1159 [ # # ]: 0 : const linguistic2::SingleProofreadingError &rError = rResult.aErrors[i];
1160 [ # # ][ # # ]: 0 : if (rError.nErrorStart <= rErrorPosInText &&
1161 : : rErrorPosInText + nLen <= rError.nErrorStart + rError.nErrorLength)
1162 : : {
1163 [ # # ]: 0 : rSuggestions = rError.aSuggestions;
1164 : 0 : rErrorIndexInResult = i;
1165 : 0 : break;
1166 : : }
1167 : 0 : }
1168 : : }
1169 : :
1170 [ # # ]: 0 : if (rResult.aErrors.getLength() > 0) // error found?
1171 : : {
1172 : : //save the start and end positons of the line and the starting point
1173 [ # # ]: 0 : Push();
1174 [ # # ]: 0 : LeftMargin();
1175 [ # # ]: 0 : xub_StrLen nLineStart = GetCrsr()->GetPoint()->nContent.GetIndex();
1176 [ # # ]: 0 : RightMargin();
1177 [ # # ]: 0 : xub_StrLen nLineEnd = GetCrsr()->GetPoint()->nContent.GetIndex();
1178 [ # # ]: 0 : Pop(sal_False);
1179 : :
1180 : : // make sure the selection build later from the data below does
1181 : : // not include "in word" character to the left and right in
1182 : : // order to preserve those. Therefore count those "in words" in
1183 : : // order to modify the selection accordingly.
1184 : 0 : const sal_Unicode* pChar = aText.GetBuffer();
1185 : 0 : xub_StrLen nLeft = 0;
1186 [ # # ][ # # ]: 0 : while (pChar && *pChar++ == CH_TXTATR_INWORD)
[ # # ]
1187 : 0 : ++nLeft;
1188 [ # # ]: 0 : pChar = aText.Len() ? aText.GetBuffer() + aText.Len() - 1 : 0;
1189 : 0 : xub_StrLen nRight = 0;
1190 [ # # ][ # # ]: 0 : while (pChar && *pChar-- == CH_TXTATR_INWORD)
[ # # ]
1191 : 0 : ++nRight;
1192 : :
1193 [ # # ]: 0 : aPos.nContent = nBegin + nLeft;
1194 [ # # ]: 0 : pCrsr = GetCrsr();
1195 [ # # ]: 0 : *pCrsr->GetPoint() = aPos;
1196 [ # # ]: 0 : pCrsr->SetMark();
1197 [ # # ]: 0 : ExtendSelection( sal_True, nLen - nLeft - nRight );
1198 : : //no determine the rectangle in the current line
1199 : 0 : xub_StrLen nWordStart = (nBegin + nLeft) < nLineStart ? nLineStart : nBegin + nLeft;
1200 : : //take one less than the line end - otherwise the next line would be calculated
1201 : 0 : xub_StrLen nWordEnd = (nBegin + nLen - nLeft - nRight) > nLineEnd ? nLineEnd: (nBegin + nLen - nLeft - nRight);
1202 [ # # ]: 0 : Push();
1203 [ # # ]: 0 : pCrsr->DeleteMark();
1204 [ # # ]: 0 : SwIndex& rContent = GetCrsr()->GetPoint()->nContent;
1205 [ # # ]: 0 : rContent = nWordStart;
1206 : 0 : SwRect aStartRect;
1207 : 0 : SwCrsrMoveState aState;
1208 : 0 : aState.bRealWidth = sal_True;
1209 : 0 : SwCntntNode* pCntntNode = pCrsr->GetCntntNode();
1210 [ # # ][ # # ]: 0 : SwCntntFrm *pCntntFrame = pCntntNode->getLayoutFrm( GetLayout(), pPt, pCrsr->GetPoint(), sal_False);
1211 : :
1212 [ # # ]: 0 : pCntntFrame->GetCharRect( aStartRect, *pCrsr->GetPoint(), &aState );
1213 [ # # ]: 0 : rContent = nWordEnd - 1;
1214 : 0 : SwRect aEndRect;
1215 [ # # ]: 0 : pCntntFrame->GetCharRect( aEndRect, *pCrsr->GetPoint(),&aState );
1216 [ # # ]: 0 : rSelectRect = aStartRect.Union( aEndRect );
1217 [ # # ]: 0 : Pop(sal_False);
1218 [ # # ]: 0 : }
1219 : : }
1220 : : }
1221 : :
1222 [ # # ]: 0 : return bRes;
1223 : : }
1224 : :
1225 : 0 : bool SwEditShell::SpellSentence(::svx::SpellPortions& rPortions, bool bIsGrammarCheck)
1226 : : {
1227 : : OSL_ENSURE( pSpellIter, "SpellIter missing" );
1228 [ # # ]: 0 : if(!pSpellIter)
1229 : 0 : return false;
1230 : 0 : bool bRet = pSpellIter->SpellSentence(rPortions, bIsGrammarCheck);
1231 : :
1232 : : // make Selection visible - this should simply move the
1233 : : // cursor to the end of the sentence
1234 : 0 : StartAction();
1235 : 0 : EndAction();
1236 : 0 : return bRet;
1237 : : }
1238 : : /*-------------------------------------------------------------------------
1239 : : make SpellIter start with the current sentence when called next time
1240 : : -----------------------------------------------------------------------*/
1241 : 0 : void SwEditShell::PutSpellingToSentenceStart()
1242 : : {
1243 : : OSL_ENSURE( pSpellIter, "SpellIter missing" );
1244 [ # # ]: 0 : if(!pSpellIter)
1245 : 0 : return;
1246 : 0 : pSpellIter->ToSentenceStart();
1247 : : }
1248 : :
1249 : 0 : sal_uInt32 lcl_CountRedlines(
1250 : : const ::svx::SpellPortions& rLastPortions)
1251 : : {
1252 : 0 : sal_uInt32 nRet = 0;
1253 : 0 : SpellPortions::const_iterator aIter = rLastPortions.begin();
1254 [ # # ][ # # ]: 0 : for( ; aIter != rLastPortions.end(); ++aIter)
1255 : : {
1256 [ # # ]: 0 : if( aIter->bIsHidden )
1257 : 0 : ++nRet;
1258 : : }
1259 : 0 : return nRet;
1260 : : }
1261 : :
1262 : 0 : void SwEditShell::MoveContinuationPosToEndOfCheckedSentence()
1263 : : {
1264 : : // give hint that continuation position for spell/grammar checking is
1265 : : // at the end of this sentence
1266 [ # # ]: 0 : if (pSpellIter)
1267 : : {
1268 [ # # ]: 0 : pSpellIter->SetCurr( new SwPosition( *pSpellIter->GetCurrX() ) );
1269 : 0 : pSpellIter->ContinueAfterThisSentence();
1270 : : }
1271 : 0 : }
1272 : :
1273 : :
1274 : 0 : void SwEditShell::ApplyChangedSentence(const ::svx::SpellPortions& rNewPortions, bool bRecheck)
1275 : : {
1276 : : // Note: rNewPortions.size() == 0 is valid and happens when the whole
1277 : : // sentence got removed in the dialog
1278 : :
1279 : : OSL_ENSURE( pSpellIter, "SpellIter missing" );
1280 [ # # # # ]: 0 : if(pSpellIter &&
[ # # ]
1281 [ # # ][ # # ]: 0 : pSpellIter->GetLastPortions().size() > 0) // no portions -> no text to be changed
[ # # ]
1282 : : {
1283 [ # # ]: 0 : const SpellPortions& rLastPortions = pSpellIter->GetLastPortions();
1284 [ # # ]: 0 : const SpellContentPositions rLastPositions = pSpellIter->GetLastPositions();
1285 : : OSL_ENSURE(rLastPortions.size() > 0 &&
1286 : : rLastPortions.size() == rLastPositions.size(),
1287 : : "last vectors of spelling results are not set or not equal");
1288 : :
1289 : : // iterate over the new portions, beginning at the end to take advantage of the previously
1290 : : // saved content positions
1291 : :
1292 [ # # ][ # # ]: 0 : pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_OVERWRITE, NULL );
1293 [ # # ]: 0 : StartAction();
1294 : :
1295 [ # # ]: 0 : SwPaM *pCrsr = GetCrsr();
1296 : : // save cursor position (which should be at the end of the current sentence)
1297 : : // for later restoration
1298 [ # # ]: 0 : Push();
1299 : :
1300 [ # # ]: 0 : sal_uInt32 nRedlinePortions = lcl_CountRedlines(rLastPortions);
1301 [ # # ]: 0 : if((rLastPortions.size() - nRedlinePortions) == rNewPortions.size())
1302 : : {
1303 : : OSL_ENSURE( !rNewPortions.empty(), "rNewPortions should not be empty here" );
1304 : : OSL_ENSURE( !rLastPortions.empty(), "rLastPortions should not be empty here" );
1305 : : OSL_ENSURE( !rLastPositions.empty(), "rLastPositions should not be empty here" );
1306 : :
1307 : : //the simple case: the same number of elements on both sides
1308 : : //each changed element has to be applied to the corresponding source element
1309 : 0 : svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.end();
1310 : 0 : SpellPortions::const_iterator aCurrentOldPortion = rLastPortions.end();
1311 : 0 : SpellContentPositions::const_iterator aCurrentOldPosition = rLastPositions.end();
1312 [ # # ][ # # ]: 0 : do
1313 : : {
1314 : 0 : --aCurrentNewPortion;
1315 : 0 : --aCurrentOldPortion;
1316 : 0 : --aCurrentOldPosition;
1317 : : //jump over redline portions
1318 [ # # ]: 0 : while(aCurrentOldPortion->bIsHidden)
1319 : : {
1320 [ # # ][ # # ]: 0 : if (aCurrentOldPortion != rLastPortions.begin() &&
[ # # ][ # # ]
[ # # # # ]
1321 [ # # ][ # # ]: 0 : aCurrentOldPosition != rLastPositions.begin())
[ # # ]
1322 : : {
1323 : 0 : --aCurrentOldPortion;
1324 : 0 : --aCurrentOldPosition;
1325 : : }
1326 : : else
1327 : : {
1328 : : OSL_FAIL("ApplyChangedSentence: iterator positions broken" );
1329 : 0 : break;
1330 : : }
1331 : : }
1332 [ # # ]: 0 : if ( !pCrsr->HasMark() )
1333 [ # # ]: 0 : pCrsr->SetMark();
1334 [ # # ]: 0 : pCrsr->GetPoint()->nContent = aCurrentOldPosition->nLeft;
1335 [ # # ]: 0 : pCrsr->GetMark()->nContent = aCurrentOldPosition->nRight;
1336 [ # # ]: 0 : sal_uInt16 nScriptType = GetI18NScriptTypeOfLanguage( aCurrentNewPortion->eLanguage );
1337 : 0 : sal_uInt16 nLangWhichId = RES_CHRATR_LANGUAGE;
1338 [ # # # ]: 0 : switch(nScriptType)
1339 : : {
1340 : 0 : case SCRIPTTYPE_ASIAN : nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
1341 : 0 : case SCRIPTTYPE_COMPLEX : nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
1342 : : }
1343 [ # # ]: 0 : if(aCurrentNewPortion->sText != aCurrentOldPortion->sText)
1344 : : {
1345 : : //change text ...
1346 [ # # ]: 0 : pDoc->DeleteAndJoin(*pCrsr);
1347 : : // ... and apply language if necessary
1348 [ # # ]: 0 : if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage)
1349 [ # # ][ # # ]: 0 : SetAttr( SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId), nLangWhichId );
[ # # ]
1350 [ # # ][ # # ]: 0 : pDoc->InsertString(*pCrsr, aCurrentNewPortion->sText);
[ # # ]
1351 : : }
1352 [ # # ]: 0 : else if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage)
1353 : : {
1354 : : //apply language
1355 [ # # ][ # # ]: 0 : SetAttr( SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId), nLangWhichId );
[ # # ]
1356 : : }
1357 [ # # ]: 0 : else if( aCurrentNewPortion->bIgnoreThisError )
1358 : : {
1359 : : //add the 'ignore' markup to the TextNode's grammar ignore markup list
1360 [ # # ]: 0 : IgnoreGrammarErrorAt( *pCrsr );
1361 : : OSL_FAIL("TODO: add ignore mark to text node");
1362 : : }
1363 [ # # ][ # # ]: 0 : if(aCurrentNewPortion == rNewPortions.begin())
1364 : 0 : break;
1365 : : }
1366 : 0 : while(aCurrentNewPortion != rNewPortions.begin());
1367 : : }
1368 : : else
1369 : : {
1370 : : OSL_ENSURE( !rLastPositions.empty(), "rLastPositions should not be empty here" );
1371 : :
1372 : : //select the complete sentence
1373 : 0 : SpellContentPositions::const_iterator aCurrentEndPosition = rLastPositions.end();
1374 : 0 : --aCurrentEndPosition;
1375 : 0 : SpellContentPositions::const_iterator aCurrentStartPosition = rLastPositions.begin();
1376 [ # # ]: 0 : pCrsr->GetPoint()->nContent = aCurrentStartPosition->nLeft;
1377 [ # # ]: 0 : pCrsr->GetMark()->nContent = aCurrentEndPosition->nRight;
1378 : :
1379 : : //delete the sentence completely
1380 [ # # ]: 0 : pDoc->DeleteAndJoin(*pCrsr);
1381 : 0 : svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.begin();
1382 [ # # ][ # # ]: 0 : while(aCurrentNewPortion != rNewPortions.end())
1383 : : {
1384 : : //set the language attribute
1385 [ # # ]: 0 : sal_uInt16 nScriptType = GetScriptType();
1386 : 0 : sal_uInt16 nLangWhichId = RES_CHRATR_LANGUAGE;
1387 [ # # # ]: 0 : switch(nScriptType)
1388 : : {
1389 : 0 : case SCRIPTTYPE_ASIAN : nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
1390 : 0 : case SCRIPTTYPE_COMPLEX : nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
1391 : : }
1392 [ # # ][ # # ]: 0 : SfxItemSet aSet(GetAttrPool(), nLangWhichId, nLangWhichId, 0);
1393 [ # # ]: 0 : GetCurAttr( aSet );
1394 [ # # ]: 0 : const SvxLanguageItem& rLang = static_cast<const SvxLanguageItem& >(aSet.Get(nLangWhichId));
1395 [ # # ]: 0 : if(rLang.GetLanguage() != aCurrentNewPortion->eLanguage)
1396 [ # # ][ # # ]: 0 : SetAttr( SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId) );
[ # # ]
1397 : : //insert the new string
1398 [ # # ][ # # ]: 0 : pDoc->InsertString(*pCrsr, aCurrentNewPortion->sText);
[ # # ]
1399 : :
1400 : : //set the cursor to the end of the inserted string
1401 [ # # ][ # # ]: 0 : *pCrsr->Start() = *pCrsr->End();
[ # # ]
1402 : 0 : ++aCurrentNewPortion;
1403 [ # # ]: 0 : }
1404 : : }
1405 : :
1406 : : // restore cursor to the end of the sentence
1407 : : // (will work also if the sentence length has changed,
1408 : : // since cursors get updated automatically!)
1409 [ # # ]: 0 : Pop( sal_False );
1410 : :
1411 : : // collapse cursor to the end of the modified sentence
1412 [ # # ][ # # ]: 0 : *pCrsr->Start() = *pCrsr->End();
[ # # ]
1413 [ # # ]: 0 : if (bRecheck)
1414 : : {
1415 : : //in grammar check the current sentence has to be checked again
1416 [ # # ]: 0 : GoStartSentence();
1417 : : }
1418 : : // set continuation position for spell/grammar checking to the end of this sentence
1419 [ # # ][ # # ]: 0 : pSpellIter->SetCurr( new SwPosition( *pCrsr->Start() ) );
[ # # ][ # # ]
1420 : :
1421 [ # # ][ # # ]: 0 : pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_OVERWRITE, NULL );
1422 [ # # ]: 0 : EndAction();
1423 : : }
1424 : 0 : }
1425 : : /*-------------------------------------------------------------------------
1426 : : collect all deleted redlines of the current text node beginning at the
1427 : : start of the cursor position
1428 : : -----------------------------------------------------------------------*/
1429 : 0 : SpellContentPositions lcl_CollectDeletedRedlines(SwEditShell* pSh)
1430 : : {
1431 : 0 : SpellContentPositions aRedlines;
1432 : 0 : SwDoc* pDoc = pSh->GetDoc();
1433 [ # # ]: 0 : const bool bShowChg = IDocumentRedlineAccess::IsShowChanges( pDoc->GetRedlineMode() );
1434 [ # # ]: 0 : if ( bShowChg )
1435 : : {
1436 [ # # ]: 0 : SwPaM *pCrsr = pSh->GetCrsr();
1437 [ # # ]: 0 : const SwPosition* pStartPos = pCrsr->Start();
1438 : 0 : const SwTxtNode* pTxtNode = pCrsr->GetNode()->GetTxtNode();
1439 : :
1440 [ # # ]: 0 : sal_uInt16 nAct = pDoc->GetRedlinePos( *pTxtNode, USHRT_MAX );
1441 : 0 : const xub_StrLen nStartIndex = pStartPos->nContent.GetIndex();
1442 [ # # ][ # # ]: 0 : for ( ; nAct < pDoc->GetRedlineTbl().size(); nAct++ )
1443 : : {
1444 [ # # ][ # # ]: 0 : const SwRedline* pRed = pDoc->GetRedlineTbl()[ nAct ];
1445 : :
1446 [ # # ][ # # ]: 0 : if ( pRed->Start()->nNode > pTxtNode->GetIndex() )
1447 : 0 : break;
1448 : :
1449 [ # # ][ # # ]: 0 : if( nsRedlineType_t::REDLINE_DELETE == pRed->GetType() )
1450 : : {
1451 : : xub_StrLen nStart, nEnd;
1452 [ # # ]: 0 : pRed->CalcStartEnd( pTxtNode->GetIndex(), nStart, nEnd );
1453 [ # # ][ # # ]: 0 : if(nStart >= nStartIndex || nEnd >= nStartIndex)
1454 : : {
1455 : : SpellContentPosition aAdd;
1456 : 0 : aAdd.nLeft = nStart;
1457 : 0 : aAdd.nRight = nEnd;
1458 [ # # ]: 0 : aRedlines.push_back(aAdd);
1459 : : }
1460 : : }
1461 : : }
1462 : : }
1463 : 0 : return aRedlines;
1464 : : }
1465 : : /*-------------------------------------------------------------------------
1466 : : remove the redline positions after the current selection
1467 : : -----------------------------------------------------------------------*/
1468 : 0 : void lcl_CutRedlines( SpellContentPositions& aDeletedRedlines, SwEditShell* pSh )
1469 : : {
1470 [ # # ]: 0 : if(!aDeletedRedlines.empty())
1471 : : {
1472 : 0 : SwPaM *pCrsr = pSh->GetCrsr();
1473 : 0 : const SwPosition* pEndPos = pCrsr->End();
1474 : 0 : xub_StrLen nEnd = pEndPos->nContent.GetIndex();
1475 [ # # # # ]: 0 : while(!aDeletedRedlines.empty() &&
[ # # ]
1476 : 0 : aDeletedRedlines.back().nLeft > nEnd)
1477 : : {
1478 : 0 : aDeletedRedlines.pop_back();
1479 : : }
1480 : : }
1481 : 0 : }
1482 : :
1483 : 0 : SpellContentPosition lcl_FindNextDeletedRedline(
1484 : : const SpellContentPositions& rDeletedRedlines,
1485 : : xub_StrLen nSearchFrom )
1486 : : {
1487 : : SpellContentPosition aRet;
1488 : 0 : aRet.nLeft = aRet.nRight = STRING_MAXLEN;
1489 [ # # ]: 0 : if(!rDeletedRedlines.empty())
1490 : : {
1491 : 0 : SpellContentPositions::const_iterator aIter = rDeletedRedlines.begin();
1492 [ # # ][ # # ]: 0 : for( ; aIter != rDeletedRedlines.end(); ++aIter)
1493 : : {
1494 [ # # ]: 0 : if(aIter->nLeft < nSearchFrom)
1495 : 0 : continue;
1496 : 0 : aRet = *aIter;
1497 : 0 : break;
1498 : : }
1499 : : }
1500 : 0 : return aRet;
1501 : : }
1502 : :
1503 : 0 : bool SwSpellIter::SpellSentence(::svx::SpellPortions& rPortions, bool bIsGrammarCheck)
1504 : : {
1505 : 0 : bool bRet = false;
1506 : 0 : aLastPortions.clear();
1507 : 0 : aLastPositions.clear();
1508 : :
1509 : 0 : SwEditShell *pMySh = GetSh();
1510 [ # # ]: 0 : if( !pMySh )
1511 : 0 : return false;
1512 : :
1513 : : OSL_ENSURE( GetEnd(), "SwEditShell::SpellSentence() ohne Start?");
1514 : :
1515 : 0 : uno::Reference< XSpellAlternatives > xSpellRet;
1516 [ # # ]: 0 : linguistic2::ProofreadingResult aGrammarResult;
1517 : 0 : sal_Bool bGoOn = sal_True;
1518 : 0 : bool bGrammarErrorFound = false;
1519 [ # # ]: 0 : do {
1520 [ # # ]: 0 : SwPaM *pCrsr = pMySh->GetCrsr();
1521 [ # # ]: 0 : if ( !pCrsr->HasMark() )
1522 [ # # ]: 0 : pCrsr->SetMark();
1523 : :
1524 [ # # ]: 0 : *pCrsr->GetPoint() = *GetCurr();
1525 [ # # ]: 0 : *pCrsr->GetMark() = *GetEnd();
1526 : :
1527 [ # # ]: 0 : if( bBackToStartOfSentence )
1528 : : {
1529 [ # # ]: 0 : pMySh->GoStartSentence();
1530 : 0 : bBackToStartOfSentence = false;
1531 : : }
1532 : : uno::Any aSpellRet =
1533 : : pMySh->GetDoc()->Spell(*pCrsr,
1534 [ # # ]: 0 : xSpeller, 0, 0, bIsGrammarCheck );
1535 [ # # ]: 0 : aSpellRet >>= xSpellRet;
1536 [ # # ]: 0 : aSpellRet >>= aGrammarResult;
1537 : 0 : bGoOn = GetCrsrCnt() > 1;
1538 : 0 : bGrammarErrorFound = aGrammarResult.aErrors.getLength() > 0;
1539 [ # # ][ # # ]: 0 : if( xSpellRet.is() || bGrammarErrorFound )
[ # # ]
1540 : : {
1541 : 0 : bGoOn = sal_False;
1542 [ # # ][ # # ]: 0 : SwPosition* pNewPoint = new SwPosition( *pCrsr->GetPoint() );
1543 [ # # ][ # # ]: 0 : SwPosition* pNewMark = new SwPosition( *pCrsr->GetMark() );
1544 : :
1545 [ # # ]: 0 : SetCurr( pNewPoint );
1546 [ # # ]: 0 : SetCurrX( pNewMark );
1547 : : }
1548 [ # # ]: 0 : if( bGoOn )
1549 : : {
1550 [ # # ]: 0 : pMySh->Pop( sal_False );
1551 [ # # ]: 0 : pCrsr = pMySh->GetCrsr();
1552 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
1553 : 0 : pCrsr->Exchange();
1554 [ # # ][ # # ]: 0 : SwPosition* pNew = new SwPosition( *pCrsr->GetPoint() );
1555 [ # # ]: 0 : SetStart( pNew );
1556 [ # # ][ # # ]: 0 : pNew = new SwPosition( *pCrsr->GetMark() );
1557 [ # # ]: 0 : SetEnd( pNew );
1558 [ # # ][ # # ]: 0 : pNew = new SwPosition( *GetStart() );
1559 [ # # ]: 0 : SetCurr( pNew );
1560 [ # # ][ # # ]: 0 : pNew = new SwPosition( *pNew );
1561 [ # # ]: 0 : SetCurrX( pNew );
1562 [ # # ]: 0 : pCrsr->SetMark();
1563 : 0 : --GetCrsrCnt();
1564 : 0 : }
1565 : : }
1566 : : while ( bGoOn );
1567 [ # # ][ # # ]: 0 : if(xSpellRet.is() || bGrammarErrorFound)
[ # # ]
1568 : : {
1569 : : //an error has been found
1570 : : //To fill the spell portions the beginning of the sentence has to be found
1571 [ # # ]: 0 : SwPaM *pCrsr = pMySh->GetCrsr();
1572 : : //set the mark to the right if necessary
1573 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
1574 : 0 : pCrsr->Exchange();
1575 : : //the cursor has to be collapsed on the left to go to the start of the sentence - if sentence ends inside of the error
1576 [ # # ]: 0 : pCrsr->DeleteMark();
1577 [ # # ]: 0 : pCrsr->SetMark();
1578 [ # # ]: 0 : sal_Bool bStartSent = 0 != pMySh->GoStartSentence();
1579 [ # # ]: 0 : SpellContentPositions aDeletedRedlines = lcl_CollectDeletedRedlines(pMySh);
1580 [ # # ]: 0 : if(bStartSent)
1581 : : {
1582 : : //create a portion from the start part
1583 [ # # ][ # # ]: 0 : AddPortion(0, 0, aDeletedRedlines);
1584 : : }
1585 : : //Set the cursor to the error already found
1586 [ # # ]: 0 : *pCrsr->GetPoint() = *GetCurrX();
1587 [ # # ]: 0 : *pCrsr->GetMark() = *GetCurr();
1588 [ # # ]: 0 : AddPortion(xSpellRet, &aGrammarResult, aDeletedRedlines);
1589 : :
1590 : :
1591 : : //save the end position of the error to continue from here
1592 [ # # ][ # # ]: 0 : SwPosition aSaveStartPos = *pCrsr->End();
1593 : : //determine the end of the current sentence
1594 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() < *pCrsr->GetMark() )
1595 : 0 : pCrsr->Exchange();
1596 : : //again collapse to start marking after the end of the error
1597 [ # # ]: 0 : pCrsr->DeleteMark();
1598 [ # # ]: 0 : pCrsr->SetMark();
1599 : :
1600 [ # # ]: 0 : pMySh->GoEndSentence();
1601 [ # # ]: 0 : if( bGrammarErrorFound )
1602 : : {
1603 [ # # ][ # # ]: 0 : const ModelToViewHelper aConversionMap(*(SwTxtNode*)pCrsr->GetNode());
1604 : 0 : rtl::OUString aExpandText = aConversionMap.getViewText();
1605 [ # # ]: 0 : xub_StrLen nSentenceEnd = (xub_StrLen)aConversionMap.ConvertToViewPosition( aGrammarResult.nBehindEndOfSentencePosition );
1606 : : // remove trailing space
1607 [ # # ]: 0 : if( aExpandText[nSentenceEnd - 1] == ' ' )
1608 : 0 : --nSentenceEnd;
1609 [ # # ][ # # ]: 0 : if( pCrsr->End()->nContent.GetIndex() < nSentenceEnd )
1610 : : {
1611 [ # # ]: 0 : pCrsr->End()->nContent.Assign(
1612 [ # # ][ # # ]: 0 : pCrsr->End()->nNode.GetNode().GetCntntNode(), nSentenceEnd);
[ # # ]
1613 : 0 : }
1614 : : }
1615 : :
1616 [ # # ]: 0 : lcl_CutRedlines( aDeletedRedlines, pMySh );
1617 : : //save the 'global' end of the spellchecking
1618 [ # # ]: 0 : const SwPosition aSaveEndPos = *GetEnd();
1619 : : //set the sentence end as 'local' end
1620 [ # # ][ # # ]: 0 : SetEnd( new SwPosition( *pCrsr->End() ));
[ # # ][ # # ]
1621 : :
1622 [ # # ]: 0 : *pCrsr->GetPoint() = aSaveStartPos;
1623 [ # # ]: 0 : *pCrsr->GetMark() = *GetEnd();
1624 : : //now the rest of the sentence has to be searched for errors
1625 : : // for each error the non-error text between the current and the last error has
1626 : : // to be added to the portions - if necessary broken into same-language-portions
1627 [ # # ]: 0 : if( !bGrammarErrorFound ) //in grammar check there's only one error returned
1628 : : {
1629 [ # # ]: 0 : do
1630 : : {
1631 [ # # ]: 0 : xSpellRet = 0;
1632 : : // don't search for grammar errors here anymore!
1633 : : pMySh->GetDoc()->Spell(*pCrsr,
1634 [ # # ][ # # ]: 0 : xSpeller, 0, 0, false ) >>= xSpellRet;
1635 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
1636 : 0 : pCrsr->Exchange();
1637 [ # # ][ # # ]: 0 : SetCurr( new SwPosition( *pCrsr->GetPoint() ));
[ # # ]
1638 [ # # ][ # # ]: 0 : SetCurrX( new SwPosition( *pCrsr->GetMark() ));
[ # # ]
1639 : :
1640 : : //if an error has been found go back to the text
1641 : : //preceeding the error
1642 [ # # ]: 0 : if(xSpellRet.is())
1643 : : {
1644 [ # # ]: 0 : *pCrsr->GetPoint() = aSaveStartPos;
1645 [ # # ]: 0 : *pCrsr->GetMark() = *GetCurr();
1646 : : }
1647 : : //add the portion
1648 [ # # ][ # # ]: 0 : AddPortion(0, 0, aDeletedRedlines);
1649 : :
1650 [ # # ]: 0 : if(xSpellRet.is())
1651 : : {
1652 [ # # ]: 0 : *pCrsr->GetPoint() = *GetCurr();
1653 [ # # ]: 0 : *pCrsr->GetMark() = *GetCurrX();
1654 [ # # ]: 0 : AddPortion(xSpellRet, 0, aDeletedRedlines);
1655 : : //move the cursor to the end of the error string
1656 [ # # ]: 0 : *pCrsr->GetPoint() = *GetCurrX();
1657 : : //and save the end of the error as new start position
1658 [ # # ]: 0 : aSaveStartPos = *GetCurrX();
1659 : : //and the end of the sentence
1660 [ # # ]: 0 : *pCrsr->GetMark() = *GetEnd();
1661 : : }
1662 : : // if the end of the sentence has already been reached then break here
1663 [ # # ][ # # ]: 0 : if(*GetCurrX() >= *GetEnd())
1664 : 0 : break;
1665 : : }
1666 : 0 : while(xSpellRet.is());
1667 : : }
1668 : : else
1669 : : {
1670 : : //go to the end of sentence as the grammar check returned it
1671 : : // at this time the Point is behind the grammar error
1672 : : // and the mark points to the sentence end as
1673 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() < *pCrsr->GetMark() )
1674 : 0 : pCrsr->Exchange();
1675 : : }
1676 : :
1677 : : // the part between the last error and the end of the sentence has to be added
1678 [ # # ][ # # ]: 0 : *pMySh->GetCrsr()->GetPoint() = *GetEnd();
1679 [ # # ][ # # ]: 0 : if(*GetCurrX() < *GetEnd())
1680 : : {
1681 [ # # ][ # # ]: 0 : AddPortion(0, 0, aDeletedRedlines);
1682 : : }
1683 : : //set the shell cursor to the end of the sentence to prevent a visible selection
1684 [ # # ]: 0 : *pCrsr->GetMark() = *GetEnd();
1685 [ # # ]: 0 : if( !bIsGrammarCheck )
1686 : : {
1687 : : //set the current position to the end of the sentence
1688 [ # # ][ # # ]: 0 : SetCurr( new SwPosition(*GetEnd()) );
[ # # ]
1689 : : }
1690 : : //restore the 'global' end
1691 [ # # ][ # # ]: 0 : SetEnd( new SwPosition(aSaveEndPos) );
[ # # ]
1692 [ # # ]: 0 : rPortions = aLastPortions;
1693 [ # # ][ # # ]: 0 : bRet = true;
1694 : : }
1695 : : else
1696 : : {
1697 : : //if no error could be found the selection has to be corrected - at least if it's not in the body
1698 [ # # ][ # # ]: 0 : *pMySh->GetCrsr()->GetPoint() = *GetEnd();
1699 [ # # ][ # # ]: 0 : pMySh->GetCrsr()->DeleteMark();
1700 : : }
1701 : :
1702 [ # # ]: 0 : return bRet;
1703 : : }
1704 : :
1705 : 0 : void SwSpellIter::ToSentenceStart()
1706 : : {
1707 : 0 : bBackToStartOfSentence = true;
1708 : 0 : }
1709 : :
1710 : 0 : LanguageType lcl_GetLanguage(SwEditShell& rSh)
1711 : : {
1712 [ # # ]: 0 : sal_uInt16 nScriptType = rSh.GetScriptType();
1713 : 0 : sal_uInt16 nLangWhichId = RES_CHRATR_LANGUAGE;
1714 : :
1715 [ # # # ]: 0 : switch(nScriptType)
1716 : : {
1717 : 0 : case SCRIPTTYPE_ASIAN : nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
1718 : 0 : case SCRIPTTYPE_COMPLEX : nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
1719 : : }
1720 [ # # ][ # # ]: 0 : SfxItemSet aSet(rSh.GetAttrPool(), nLangWhichId, nLangWhichId, 0);
1721 [ # # ]: 0 : rSh.GetCurAttr( aSet );
1722 [ # # ]: 0 : const SvxLanguageItem& rLang = static_cast<const SvxLanguageItem& >(aSet.Get(nLangWhichId));
1723 [ # # ]: 0 : return rLang.GetLanguage();
1724 : : }
1725 : : /*-------------------------------------------------------------------------
1726 : : create a text portion at the given position
1727 : : -----------------------------------------------------------------------*/
1728 : 0 : void SwSpellIter::CreatePortion(uno::Reference< XSpellAlternatives > xAlt,
1729 : : linguistic2::ProofreadingResult* pGrammarResult,
1730 : : bool bIsField, bool bIsHidden)
1731 : : {
1732 [ # # ]: 0 : svx::SpellPortion aPortion;
1733 [ # # ]: 0 : String sText;
1734 [ # # ]: 0 : GetSh()->GetSelectedText( sText );
1735 [ # # ]: 0 : if(sText.Len())
1736 : : {
1737 : : //in case of redlined deletions the selection of an error is not
1738 : : //the same as the _real_ word
1739 [ # # ]: 0 : if(xAlt.is())
1740 [ # # ][ # # ]: 0 : aPortion.sText = xAlt->getWord();
1741 [ # # ]: 0 : else if(pGrammarResult)
1742 : : {
1743 : 0 : aPortion.bIsGrammarError = true;
1744 [ # # ]: 0 : if(pGrammarResult->aErrors.getLength())
1745 : : {
1746 [ # # ][ # # ]: 0 : aPortion.aGrammarError = pGrammarResult->aErrors[0];
1747 : 0 : aPortion.sText = pGrammarResult->aText.copy( aPortion.aGrammarError.nErrorStart, aPortion.aGrammarError.nErrorLength );
1748 [ # # ]: 0 : aPortion.xGrammarChecker = pGrammarResult->xProofreader;
1749 : 0 : const beans::PropertyValue* pProperties = pGrammarResult->aProperties.getConstArray();
1750 [ # # ]: 0 : for( sal_Int32 nProp = 0; nProp < pGrammarResult->aProperties.getLength(); ++nProp )
1751 : : {
1752 [ # # ]: 0 : if ( pProperties->Name == "DialogTitle" )
1753 : : {
1754 : 0 : pProperties->Value >>= aPortion.sDialogTitle;
1755 : 0 : break;
1756 : : }
1757 : : }
1758 : : }
1759 : : }
1760 : : else
1761 [ # # ]: 0 : aPortion.sText = sText;
1762 [ # # ]: 0 : aPortion.eLanguage = lcl_GetLanguage(*GetSh());
1763 : 0 : aPortion.bIsField = bIsField;
1764 : 0 : aPortion.bIsHidden = bIsHidden;
1765 [ # # ]: 0 : aPortion.xAlternatives = xAlt;
1766 : : SpellContentPosition aPosition;
1767 [ # # ]: 0 : SwPaM *pCrsr = GetSh()->GetCrsr();
1768 [ # # ]: 0 : aPosition.nLeft = pCrsr->Start()->nContent.GetIndex();
1769 [ # # ]: 0 : aPosition.nRight = pCrsr->End()->nContent.GetIndex();
1770 [ # # ]: 0 : aLastPortions.push_back(aPortion);
1771 [ # # ]: 0 : aLastPositions.push_back(aPosition);
1772 [ # # ][ # # ]: 0 : }
1773 : 0 : }
1774 : :
1775 : 0 : void SwSpellIter::AddPortion(uno::Reference< XSpellAlternatives > xAlt,
1776 : : linguistic2::ProofreadingResult* pGrammarResult,
1777 : : const SpellContentPositions& rDeletedRedlines)
1778 : : {
1779 : 0 : SwEditShell *pMySh = GetSh();
1780 [ # # ]: 0 : String sText;
1781 [ # # ]: 0 : pMySh->GetSelectedText( sText );
1782 [ # # ]: 0 : if(sText.Len())
1783 : : {
1784 [ # # ][ # # ]: 0 : if(xAlt.is() || pGrammarResult != 0)
[ # # ]
1785 : : {
1786 [ # # ]: 0 : CreatePortion(xAlt, pGrammarResult, false, false);
1787 : : }
1788 : : else
1789 : : {
1790 [ # # ]: 0 : SwPaM *pCrsr = GetSh()->GetCrsr();
1791 [ # # ][ # # ]: 0 : if ( *pCrsr->GetPoint() > *pCrsr->GetMark() )
1792 : 0 : pCrsr->Exchange();
1793 : : //save the start and end positions
1794 [ # # ]: 0 : SwPosition aStart(*pCrsr->GetPoint());
1795 [ # # ]: 0 : SwPosition aEnd(*pCrsr->GetMark());
1796 : : //iterate over the text to find changes in language
1797 : : //set the mark equal to the point
1798 [ # # ]: 0 : *pCrsr->GetMark() = aStart;
1799 : 0 : SwTxtNode* pTxtNode = pCrsr->GetNode()->GetTxtNode();
1800 [ # # ]: 0 : LanguageType eStartLanguage = lcl_GetLanguage(*GetSh());
1801 : : SpellContentPosition aNextRedline = lcl_FindNextDeletedRedline(
1802 [ # # ]: 0 : rDeletedRedlines, aStart.nContent.GetIndex() );
1803 [ # # ]: 0 : if( aNextRedline.nLeft == aStart.nContent.GetIndex() )
1804 : : {
1805 : : //select until the end of the current redline
1806 : 0 : xub_StrLen nEnd = aEnd.nContent.GetIndex() < aNextRedline.nRight ?
1807 [ # # ]: 0 : aEnd.nContent.GetIndex() : aNextRedline.nRight;
1808 [ # # ][ # # ]: 0 : pCrsr->GetPoint()->nContent.Assign( pTxtNode, nEnd );
1809 [ # # ]: 0 : CreatePortion(xAlt, pGrammarResult, false, true);
1810 [ # # ][ # # ]: 0 : aStart = *pCrsr->End();
1811 : : //search for next redline
1812 : : aNextRedline = lcl_FindNextDeletedRedline(
1813 [ # # ]: 0 : rDeletedRedlines, aStart.nContent.GetIndex() );
1814 : : }
1815 [ # # ][ # # ]: 0 : while(*pCrsr->GetPoint() < aEnd)
1816 : : {
1817 : : //#125786 in table cell with fixed row height the cursor might not move forward
1818 [ # # ][ # # ]: 0 : if(!GetSh()->Right(1, CRSR_SKIP_CELLS))
1819 : 0 : break;
1820 : :
1821 : 0 : bool bField = false;
1822 : : //read the character at the current position to check if it's a field
1823 : 0 : xub_Unicode cChar = pTxtNode->GetTxt().GetChar( pCrsr->GetMark()->nContent.GetIndex() );
1824 [ # # ][ # # ]: 0 : if( CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar)
1825 : : {
1826 : : const SwTxtAttr* pTxtAttr = pTxtNode->GetTxtAttrForCharAt(
1827 [ # # ]: 0 : pCrsr->GetMark()->nContent.GetIndex() );
1828 : : const sal_uInt16 nWhich = pTxtAttr
1829 : : ? pTxtAttr->Which()
1830 [ # # ][ # # ]: 0 : : static_cast<sal_uInt16>(RES_TXTATR_END);
1831 [ # # ]: 0 : switch (nWhich)
1832 : : {
1833 : : case RES_TXTATR_FIELD:
1834 : : case RES_TXTATR_FTN:
1835 : : case RES_TXTATR_FLYCNT:
1836 : 0 : bField = true;
1837 : 0 : break;
1838 : : }
1839 : : }
1840 : :
1841 [ # # ]: 0 : LanguageType eCurLanguage = lcl_GetLanguage(*GetSh());
1842 : 0 : bool bRedline = aNextRedline.nLeft == pCrsr->GetPoint()->nContent.GetIndex();
1843 : : // create a portion if the next character
1844 : : // - is a field,
1845 : : // - is at the beginning of a deleted redline
1846 : : // - has a different language
1847 [ # # ][ # # ]: 0 : if(bField || bRedline || eCurLanguage != eStartLanguage)
[ # # ]
1848 : : {
1849 : 0 : eStartLanguage = eCurLanguage;
1850 : : //go one step back - the cursor currently selects the first character
1851 : : //with a different language
1852 : : //in the case of redlining it's different
1853 [ # # ][ # # ]: 0 : if(eCurLanguage != eStartLanguage || bField)
1854 [ # # ]: 0 : *pCrsr->GetPoint() = *pCrsr->GetMark();
1855 : : //set to the last start
1856 [ # # ]: 0 : *pCrsr->GetMark() = aStart;
1857 : : //create portion should only be called if a selection exists
1858 : : //there's no selection if there's a field at the beginning
1859 [ # # ][ # # ]: 0 : if(*pCrsr->Start() != *pCrsr->End())
[ # # ][ # # ]
1860 [ # # ]: 0 : CreatePortion(xAlt, pGrammarResult, false, false);
1861 [ # # ][ # # ]: 0 : aStart = *pCrsr->End();
1862 : : //now export the field - if there is any
1863 [ # # ]: 0 : if(bField)
1864 : : {
1865 [ # # ]: 0 : *pCrsr->GetMark() = *pCrsr->GetPoint();
1866 [ # # ]: 0 : GetSh()->Right(1, CRSR_SKIP_CELLS);
1867 [ # # ]: 0 : CreatePortion(xAlt, pGrammarResult, true, false);
1868 [ # # ][ # # ]: 0 : aStart = *pCrsr->End();
1869 : : }
1870 : : }
1871 : : // if a redline start then create a portion for it
1872 [ # # ]: 0 : if(bRedline)
1873 : : {
1874 [ # # ]: 0 : *pCrsr->GetMark() = *pCrsr->GetPoint();
1875 : : //select until the end of the current redline
1876 : 0 : xub_StrLen nEnd = aEnd.nContent.GetIndex() < aNextRedline.nRight ?
1877 [ # # ]: 0 : aEnd.nContent.GetIndex() : aNextRedline.nRight;
1878 [ # # ][ # # ]: 0 : pCrsr->GetPoint()->nContent.Assign( pTxtNode, nEnd );
1879 [ # # ]: 0 : CreatePortion(xAlt, pGrammarResult, false, true);
1880 [ # # ][ # # ]: 0 : aStart = *pCrsr->End();
1881 : : //search for next redline
1882 : : aNextRedline = lcl_FindNextDeletedRedline(
1883 [ # # ]: 0 : rDeletedRedlines, aStart.nContent.GetIndex() );
1884 : : }
1885 [ # # ]: 0 : *pCrsr->GetMark() = *pCrsr->GetPoint();
1886 : : }
1887 [ # # ]: 0 : pCrsr->SetMark();
1888 [ # # ]: 0 : *pCrsr->GetMark() = aStart;
1889 [ # # ][ # # ]: 0 : CreatePortion(xAlt, pGrammarResult, false, false);
[ # # ]
1890 : : }
1891 [ # # ]: 0 : }
1892 : 0 : }
1893 : :
1894 : 0 : void SwEditShell::IgnoreGrammarErrorAt( SwPaM& rErrorPosition )
1895 : : {
1896 : : SwTxtNode *pNode;
1897 : : SwWrongList *pWrong;
1898 [ # # ][ # # ]: 0 : SwNodeIndex aIdx = rErrorPosition.Start()->nNode;
1899 [ # # ][ # # ]: 0 : SwNodeIndex aEndIdx = rErrorPosition.Start()->nNode;
1900 [ # # ]: 0 : xub_StrLen nStart = rErrorPosition.Start()->nContent.GetIndex();
1901 : 0 : xub_StrLen nEnd = STRING_LEN;
1902 [ # # ]: 0 : while( aIdx <= aEndIdx )
1903 : : {
1904 : 0 : pNode = aIdx.GetNode().GetTxtNode();
1905 [ # # ]: 0 : if( pNode ) {
1906 [ # # ]: 0 : if( aIdx == aEndIdx )
1907 [ # # ]: 0 : nEnd = rErrorPosition.End()->nContent.GetIndex();
1908 [ # # ]: 0 : pWrong = pNode->GetGrammarCheck();
1909 [ # # ]: 0 : if( pWrong )
1910 [ # # ]: 0 : pWrong->RemoveEntry( nStart, nEnd );
1911 [ # # ]: 0 : pWrong = pNode->GetWrong();
1912 [ # # ]: 0 : if( pWrong )
1913 [ # # ]: 0 : pWrong->RemoveEntry( nStart, nEnd );
1914 [ # # ]: 0 : SwTxtFrm::repaintTextFrames( *pNode );
1915 : : }
1916 [ # # ]: 0 : ++aIdx;
1917 : 0 : nStart = 0;
1918 [ # # ][ # # ]: 0 : }
1919 : 0 : }
1920 : :
1921 : :
1922 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|