1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 #include <SwSpellDialogChildWindow.hxx> 32 #include <vcl/msgbox.hxx> 33 #include <editeng/svxacorr.hxx> 34 #include <editeng/acorrcfg.hxx> 35 #include <svx/svxids.hrc> 36 #include <sfx2/app.hxx> 37 #include <sfx2/bindings.hxx> 38 #include <sfx2/dispatch.hxx> 39 #include <editeng/unolingu.hxx> 40 #include <editeng/editeng.hxx> 41 #include <editeng/editview.hxx> 42 #include <wrtsh.hxx> 43 #include <sfx2/printer.hxx> 44 #include <svx/svdoutl.hxx> 45 #include <svx/svdview.hxx> 46 #include <svx/svditer.hxx> 47 #include <svx/svdogrp.hxx> 48 #include <unotools/linguprops.hxx> 49 #include <unotools/lingucfg.hxx> 50 #include <doc.hxx> 51 #include <docsh.hxx> 52 #include <docary.hxx> 53 #include <frmfmt.hxx> 54 #include <dcontact.hxx> 55 #include <edtwin.hxx> 56 #include <pam.hxx> 57 #include <drawbase.hxx> 58 #include <unotextrange.hxx> 59 #include <dialog.hrc> 60 #include <cmdid.h> 61 62 63 using namespace ::com::sun::star; 64 using namespace ::com::sun::star::uno; 65 using namespace ::com::sun::star::text; 66 using namespace ::com::sun::star::linguistic2; 67 using namespace ::com::sun::star::beans; 68 69 SFX_IMPL_CHILDWINDOW(SwSpellDialogChildWindow, FN_SPELL_GRAMMAR_DIALOG) 70 71 72 #define SPELL_START_BODY 0 // body text area 73 #define SPELL_START_OTHER 1 // frame, footnote, header, footer 74 #define SPELL_START_DRAWTEXT 2 // started in a draw text object 75 76 struct SpellState 77 { 78 bool m_bInitialCall; 79 bool m_bLockFocus; //lock the focus notification while a modal dialog is active 80 bool m_bLostFocus; 81 82 //restart and progress information 83 sal_uInt16 m_SpellStartPosition; 84 bool m_bBodySpelled; //body already spelled 85 bool m_bOtherSpelled; //frames, footnotes, headers and footers spelled 86 bool m_bStartedInOther; //started the spelling insided of the _other_ area 87 bool m_bStartedInSelection; // there was an initial text selection 88 SwPaM* pOtherCursor; // position where the spelling inside the _other_ area started 89 bool m_bDrawingsSpelled; //all drawings spelled 90 Reference<XTextRange> m_xStartRange; //text range that marks the start of spelling 91 const SdrObject* m_pStartDrawing; //draw text object spelling started in 92 ESelection m_aStartDrawingSelection; //draw text start selection 93 bool m_bRestartDrawing; // the first selected drawing object is found again 94 95 //lose/get focus information to decide if spelling can be continued 96 ShellModes m_eSelMode; 97 const SwNode* m_pPointNode; 98 const SwNode* m_pMarkNode; 99 xub_StrLen m_nPointPos; 100 xub_StrLen m_nMarkPos; 101 const SdrOutliner* m_pOutliner; 102 ESelection m_aESelection; 103 104 //iterating over draw text objects 105 std::list<SdrTextObj*> m_aTextObjects; 106 bool m_bTextObjectsCollected; 107 108 SpellState() : 109 m_bInitialCall(true), 110 m_bLockFocus(false), 111 m_bLostFocus(false), 112 m_SpellStartPosition(SPELL_START_BODY), 113 m_bBodySpelled(false), 114 m_bOtherSpelled(false), 115 m_bStartedInOther(false), 116 m_bStartedInSelection(false), 117 pOtherCursor(0), 118 m_bDrawingsSpelled(false), 119 m_pStartDrawing(0), 120 m_bRestartDrawing(false), 121 122 m_eSelMode(SHELL_MODE_OBJECT), //initially invalid 123 m_pPointNode(0), 124 m_pMarkNode(0), 125 m_nPointPos(0), 126 m_nMarkPos(0), 127 m_pOutliner(0), 128 m_bTextObjectsCollected(false) 129 {} 130 131 ~SpellState() {delete pOtherCursor;} 132 133 // reset state in ::InvalidateSpellDialog 134 void Reset() 135 { m_bInitialCall = true; 136 m_bBodySpelled = m_bOtherSpelled = m_bDrawingsSpelled = false; 137 m_xStartRange = 0; 138 m_pStartDrawing = 0; 139 m_bRestartDrawing = false; 140 m_bTextObjectsCollected = false; 141 m_aTextObjects.clear(); 142 m_bStartedInOther = false; 143 delete pOtherCursor; 144 pOtherCursor = 0; 145 } 146 }; 147 /*-- 30.10.2003 14:33:26--------------------------------------------------- 148 149 -----------------------------------------------------------------------*/ 150 void lcl_LeaveDrawText(SwWrtShell& rSh) 151 { 152 if(rSh.GetDrawView()) 153 { 154 rSh.GetDrawView()->SdrEndTextEdit( sal_True ); 155 Point aPt(LONG_MIN, LONG_MIN); 156 //go out of the frame 157 rSh.SelectObj(aPt, SW_LEAVE_FRAME); 158 rSh.EnterStdMode(); 159 rSh.GetView().AttrChangedNotify(&rSh); 160 } 161 } 162 /*-- 09.09.2003 10:39:22--------------------------------------------------- 163 164 -----------------------------------------------------------------------*/ 165 SwSpellDialogChildWindow::SwSpellDialogChildWindow ( 166 Window* _pParent, 167 sal_uInt16 nId, 168 SfxBindings* pBindings, 169 SfxChildWinInfo* pInfo) : 170 svx::SpellDialogChildWindow ( 171 _pParent, nId, pBindings, pInfo), 172 m_pSpellState(new SpellState) 173 { 174 175 String aPropName( String::CreateFromAscii(UPN_IS_GRAMMAR_INTERACTIVE ) ); 176 SvtLinguConfig().GetProperty( aPropName ) >>= m_bIsGrammarCheckingOn; 177 } 178 /*-- 09.09.2003 10:39:22--------------------------------------------------- 179 180 -----------------------------------------------------------------------*/ 181 SwSpellDialogChildWindow::~SwSpellDialogChildWindow () 182 { 183 SwWrtShell* pWrtShell = GetWrtShell_Impl(); 184 if(!m_pSpellState->m_bInitialCall && pWrtShell) 185 pWrtShell->SpellEnd(); 186 delete m_pSpellState; 187 } 188 189 /*-- 09.09.2003 12:40:07--------------------------------------------------- 190 191 -----------------------------------------------------------------------*/ 192 SfxChildWinInfo SwSpellDialogChildWindow::GetInfo (void) const 193 { 194 SfxChildWinInfo aInfo = svx::SpellDialogChildWindow::GetInfo(); 195 aInfo.bVisible = sal_False; 196 return aInfo; 197 } 198 199 /*-- 09.09.2003 10:39:40--------------------------------------------------- 200 201 202 -----------------------------------------------------------------------*/ 203 svx::SpellPortions SwSpellDialogChildWindow::GetNextWrongSentence(bool bRecheck) 204 { 205 svx::SpellPortions aRet; 206 SwWrtShell* pWrtShell = GetWrtShell_Impl(); 207 if(pWrtShell) 208 { 209 if (!bRecheck) 210 { 211 // first set continuation point for spell/grammar check to the 212 // end of the current sentence 213 pWrtShell->MoveContinuationPosToEndOfCheckedSentence(); 214 } 215 216 ShellModes eSelMode = pWrtShell->GetView().GetShellMode(); 217 bool bDrawText = SHELL_MODE_DRAWTEXT == eSelMode; 218 bool bNormalText = 219 SHELL_MODE_TABLE_TEXT == eSelMode || 220 SHELL_MODE_LIST_TEXT == eSelMode || 221 SHELL_MODE_TABLE_LIST_TEXT == eSelMode || 222 SHELL_MODE_TEXT == eSelMode; 223 //Writer text outside of the body 224 bool bOtherText = false; 225 226 if( m_pSpellState->m_bInitialCall ) 227 { 228 //if no text selection exists the cursor has to be set into the text 229 if(!bDrawText && !bNormalText) 230 { 231 if(!MakeTextSelection_Impl(*pWrtShell, eSelMode)) 232 return aRet; 233 else 234 { 235 // the selection type has to be checked again - both text types are possible 236 if(0 != (pWrtShell->GetSelectionType()& nsSelectionType::SEL_DRW_TXT)) 237 bDrawText = true; 238 bNormalText = !bDrawText; 239 } 240 } 241 if(bNormalText) 242 { 243 //set cursor to the start of the sentence 244 if(!pWrtShell->HasSelection()) 245 pWrtShell->GoStartSentence(); 246 else 247 { 248 pWrtShell->ExpandToSentenceBorders(); 249 m_pSpellState->m_bStartedInSelection = true; 250 } 251 //determine if the selection is outside of the body text 252 bOtherText = !(pWrtShell->GetFrmType(0,sal_True) & FRMTYPE_BODY); 253 m_pSpellState->m_SpellStartPosition = bOtherText ? SPELL_START_OTHER : SPELL_START_BODY; 254 if(bOtherText) 255 { 256 m_pSpellState->pOtherCursor = new SwPaM(*pWrtShell->GetCrsr()->GetPoint()); 257 m_pSpellState->m_bStartedInOther = true; 258 pWrtShell->SpellStart( DOCPOS_OTHERSTART, DOCPOS_OTHEREND, DOCPOS_CURR, sal_False ); 259 } 260 else 261 { 262 SwPaM* pCrsr = pWrtShell->GetCrsr(); 263 //mark the start position only if not at start of doc 264 if(!pWrtShell->IsStartOfDoc()) 265 { 266 m_pSpellState->m_xStartRange = 267 SwXTextRange::CreateXTextRange( 268 *pWrtShell->GetDoc(), 269 *pCrsr->Start(), pCrsr->End()); 270 } 271 pWrtShell->SpellStart( DOCPOS_START, DOCPOS_END, DOCPOS_CURR, sal_False ); 272 } 273 } 274 else 275 { 276 SdrView* pSdrView = pWrtShell->GetDrawView(); 277 m_pSpellState->m_SpellStartPosition = SPELL_START_DRAWTEXT; 278 m_pSpellState->m_pStartDrawing = pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); 279 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); 280 // start checking at the top of the drawing object 281 pOLV->SetSelection( ESelection() ); 282 m_pSpellState->m_aStartDrawingSelection = ESelection(); 283 /* 284 Note: spelling in a selection only, or starting in a mid of a drawing object requires 285 further changes elsewhere. (Especially if it should work in sc and sd as well.) 286 The code below would only be part of the solution. 287 (Keeping it a as a comment for the time being) 288 ESelection aCurSel( pOLV->GetSelection() ); 289 ESelection aSentenceSel( pOLV->GetEditView().GetEditEngine()->SelectSentence( aCurSel ) ); 290 if (!aCurSel.HasRange()) 291 { 292 aSentenceSel.nEndPara = aSentenceSel.nStartPara; 293 aSentenceSel.nEndPos = aSentenceSel.nStartPos; 294 } 295 pOLV->SetSelection( aSentenceSel ); 296 m_pSpellState->m_aStartDrawingSelection = aSentenceSel; 297 */ 298 } 299 300 m_pSpellState->m_bInitialCall = false; 301 } 302 if( bDrawText ) 303 { 304 // spell inside of the current draw text 305 if(!SpellDrawText_Impl(*pWrtShell, aRet)) 306 { 307 if(!FindNextDrawTextError_Impl(*pWrtShell) || !SpellDrawText_Impl(*pWrtShell, aRet)) 308 { 309 lcl_LeaveDrawText(*pWrtShell); 310 //now the drawings have been spelled 311 m_pSpellState->m_bDrawingsSpelled = true; 312 //the spelling continues at the other content 313 //if there's any that has not been spelled yet 314 if(!m_pSpellState->m_bOtherSpelled && pWrtShell->HasOtherCnt()) 315 { 316 pWrtShell->SpellStart(DOCPOS_OTHERSTART, DOCPOS_OTHEREND, DOCPOS_OTHERSTART, sal_False ); 317 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn)) 318 { 319 pWrtShell->SpellEnd(); 320 m_pSpellState->m_bOtherSpelled = true; 321 } 322 } 323 else 324 m_pSpellState->m_bOtherSpelled = true; 325 //if no result has been found try at the body text - completely 326 if(!m_pSpellState->m_bBodySpelled && !aRet.size()) 327 { 328 pWrtShell->SpellStart(DOCPOS_START, DOCPOS_END, DOCPOS_START, sal_False ); 329 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn)) 330 { 331 m_pSpellState->m_bBodySpelled = true; 332 pWrtShell->SpellEnd(); 333 } 334 } 335 336 } 337 } 338 } 339 else 340 { 341 //spell inside of the Writer text 342 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn)) 343 { 344 // if there is a selection (within body or header/footer text) 345 // then spell/grammar checking should not move outside of it. 346 if (!m_pSpellState->m_bStartedInSelection) 347 { 348 //find out which text has been spelled body or other 349 bOtherText = !(pWrtShell->GetFrmType(0,sal_True) & FRMTYPE_BODY); 350 if(bOtherText && m_pSpellState->m_bStartedInOther && m_pSpellState->pOtherCursor) 351 { 352 m_pSpellState->m_bStartedInOther = false; 353 pWrtShell->SetSelection(*m_pSpellState->pOtherCursor); 354 pWrtShell->SpellEnd(); 355 delete m_pSpellState->pOtherCursor; 356 m_pSpellState->pOtherCursor = 0; 357 pWrtShell->SpellStart(DOCPOS_OTHERSTART, DOCPOS_CURR, DOCPOS_OTHERSTART, sal_False ); 358 pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn); 359 } 360 if(!aRet.size()) 361 { 362 //end spelling 363 pWrtShell->SpellEnd(); 364 if(bOtherText) 365 { 366 m_pSpellState->m_bOtherSpelled = true; 367 //has the body been spelled? 368 if(!m_pSpellState->m_bBodySpelled) 369 { 370 pWrtShell->SpellStart(DOCPOS_START, DOCPOS_END, DOCPOS_START, sal_False ); 371 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn)) 372 { 373 m_pSpellState->m_bBodySpelled = true; 374 pWrtShell->SpellEnd(); 375 } 376 } 377 } 378 else 379 { 380 m_pSpellState->m_bBodySpelled = true; 381 if(!m_pSpellState->m_bOtherSpelled && pWrtShell->HasOtherCnt()) 382 { 383 pWrtShell->SpellStart(DOCPOS_OTHERSTART, DOCPOS_OTHEREND, DOCPOS_OTHERSTART, sal_False ); 384 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn)) 385 { 386 pWrtShell->SpellEnd(); 387 m_pSpellState->m_bOtherSpelled = true; 388 } 389 } 390 else 391 m_pSpellState->m_bOtherSpelled = true; 392 } 393 } 394 395 //search for a draw text object that contains error and spell it 396 if(!aRet.size() && 397 (m_pSpellState->m_bDrawingsSpelled || 398 !FindNextDrawTextError_Impl(*pWrtShell) || !SpellDrawText_Impl(*pWrtShell, aRet))) 399 { 400 lcl_LeaveDrawText(*pWrtShell); 401 m_pSpellState->m_bDrawingsSpelled = true; 402 } 403 } 404 } 405 } 406 // now only the rest of the body text can be spelled - 407 // if the spelling started inside of the body 408 // 409 bool bCloseMessage = true; 410 if(!aRet.size() && !m_pSpellState->m_bStartedInSelection) 411 { 412 DBG_ASSERT(m_pSpellState->m_bDrawingsSpelled && 413 m_pSpellState->m_bOtherSpelled && m_pSpellState->m_bBodySpelled, 414 "not all parts of the document are already spelled"); 415 if(m_pSpellState->m_xStartRange.is()) 416 { 417 LockFocusNotification( true ); 418 sal_uInt16 nRet = QueryBox( GetWindow(), SW_RES(RID_QB_SPELL_CONTINUE)).Execute(); 419 if(RET_YES == nRet) 420 { 421 SwUnoInternalPaM aPam(*pWrtShell->GetDoc()); 422 if (::sw::XTextRangeToSwPaM(aPam, 423 m_pSpellState->m_xStartRange)) 424 { 425 pWrtShell->SetSelection(aPam); 426 pWrtShell->SpellStart(DOCPOS_START, DOCPOS_CURR, DOCPOS_START); 427 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn)) 428 pWrtShell->SpellEnd(); 429 } 430 m_pSpellState->m_xStartRange = 0; 431 LockFocusNotification( false ); 432 //take care that the now valid selection is stored 433 LoseFocus(); 434 } 435 else 436 bCloseMessage = false; //no closing message if a wrap around has been denied 437 } 438 } 439 if(!aRet.size()) 440 { 441 if(bCloseMessage) 442 { 443 LockFocusNotification( true ); 444 String sInfo(SW_RES(STR_SPELLING_COMPLETED)); 445 //#i84610# 446 Window* pTemp = GetWindow(); // temporary needed for g++ 3.3.5 447 InfoBox(pTemp, sInfo ).Execute(); 448 LockFocusNotification( false ); 449 //take care that the now valid selection is stored 450 LoseFocus(); 451 } 452 453 //close the spelling dialog 454 GetBindings().GetDispatcher()->Execute(FN_SPELL_GRAMMAR_DIALOG, SFX_CALLMODE_ASYNCHRON); 455 } 456 } 457 return aRet; 458 459 } 460 /*-- 09.09.2003 10:39:40--------------------------------------------------- 461 462 -----------------------------------------------------------------------*/ 463 void SwSpellDialogChildWindow::ApplyChangedSentence(const svx::SpellPortions& rChanged, bool bRecheck) 464 { 465 SwWrtShell* pWrtShell = GetWrtShell_Impl(); 466 DBG_ASSERT(!m_pSpellState->m_bInitialCall, "ApplyChangedSentence in initial call or after resume"); 467 if(pWrtShell && !m_pSpellState->m_bInitialCall) 468 { 469 ShellModes eSelMode = pWrtShell->GetView().GetShellMode(); 470 bool bDrawText = SHELL_MODE_DRAWTEXT == eSelMode; 471 bool bNormalText = 472 SHELL_MODE_TABLE_TEXT == eSelMode || 473 SHELL_MODE_LIST_TEXT == eSelMode || 474 SHELL_MODE_TABLE_LIST_TEXT == eSelMode || 475 SHELL_MODE_TEXT == eSelMode; 476 477 // evaluate if the same sentence should be rechecked or not. 478 // Sentences that got grammar checked should always be rechecked in order 479 // to detect possible errors that get introduced with the changes 480 bRecheck |= pWrtShell->HasLastSentenceGotGrammarChecked(); 481 482 if(bNormalText) 483 pWrtShell->ApplyChangedSentence(rChanged, bRecheck); 484 else if(bDrawText ) 485 { 486 SdrView* pDrView = pWrtShell->GetDrawView(); 487 SdrOutliner *pOutliner = pDrView->GetTextEditOutliner(); 488 pOutliner->ApplyChangedSentence(pDrView->GetTextEditOutlinerView()->GetEditView(), rChanged, bRecheck); 489 } 490 } 491 } 492 /*-- 21.10.2003 09:33:57--------------------------------------------------- 493 494 -----------------------------------------------------------------------*/ 495 void SwSpellDialogChildWindow::AddAutoCorrection( 496 const String& rOld, const String& rNew, LanguageType eLanguage) 497 { 498 SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get()->GetAutoCorrect(); 499 pACorr->PutText( rOld, rNew, eLanguage ); 500 } 501 /*-- 21.10.2003 09:33:59--------------------------------------------------- 502 503 -----------------------------------------------------------------------*/ 504 bool SwSpellDialogChildWindow::HasAutoCorrection() 505 { 506 return true; 507 } 508 /*-- 16.06.2008 11:59:17--------------------------------------------------- 509 510 -----------------------------------------------------------------------*/ 511 bool SwSpellDialogChildWindow::HasGrammarChecking() 512 { 513 return SvtLinguConfig().HasGrammarChecker(); 514 } 515 /*-- 18.06.2008 12:27:11--------------------------------------------------- 516 517 -----------------------------------------------------------------------*/ 518 bool SwSpellDialogChildWindow::IsGrammarChecking() 519 { 520 return m_bIsGrammarCheckingOn; 521 } 522 /*-- 18.06.2008 12:27:11--------------------------------------------------- 523 524 -----------------------------------------------------------------------*/ 525 void SwSpellDialogChildWindow::SetGrammarChecking(bool bOn) 526 { 527 uno::Any aVal; 528 aVal <<= bOn; 529 m_bIsGrammarCheckingOn = bOn; 530 String aPropName( C2S(UPN_IS_GRAMMAR_INTERACTIVE ) ); 531 SvtLinguConfig().SetProperty( aPropName, aVal ); 532 // set current spell position to the start of the current sentence to 533 // continue with this sentence after grammar checking state has been changed 534 SwWrtShell* pWrtShell = GetWrtShell_Impl(); 535 if(pWrtShell) 536 { 537 ShellModes eSelMode = pWrtShell->GetView().GetShellMode(); 538 bool bDrawText = SHELL_MODE_DRAWTEXT == eSelMode; 539 bool bNormalText = 540 SHELL_MODE_TABLE_TEXT == eSelMode || 541 SHELL_MODE_LIST_TEXT == eSelMode || 542 SHELL_MODE_TABLE_LIST_TEXT == eSelMode || 543 SHELL_MODE_TEXT == eSelMode; 544 if( bNormalText ) 545 pWrtShell->PutSpellingToSentenceStart(); 546 else if( bDrawText ) 547 { 548 SdrView* pSdrView = pWrtShell->GetDrawView(); 549 SdrOutliner* pOutliner = pSdrView ? pSdrView->GetTextEditOutliner() : 0; 550 DBG_ASSERT(pOutliner, "No Outliner in SwSpellDialogChildWindow::SetGrammarChecking"); 551 if(pOutliner) 552 { 553 pOutliner->PutSpellingToSentenceStart( pSdrView->GetTextEditOutlinerView()->GetEditView() ); 554 } 555 } 556 } 557 } 558 /*-- 28.10.2003 08:41:09--------------------------------------------------- 559 560 -----------------------------------------------------------------------*/ 561 void SwSpellDialogChildWindow::GetFocus() 562 { 563 if(m_pSpellState->m_bLockFocus) 564 return; 565 bool bInvalidate = false; 566 SwWrtShell* pWrtShell = GetWrtShell_Impl(); 567 if(pWrtShell && !m_pSpellState->m_bInitialCall) 568 { 569 ShellModes eSelMode = pWrtShell->GetView().GetShellMode(); 570 if(eSelMode != m_pSpellState->m_eSelMode) 571 { 572 //prevent initial invalidation 573 if(m_pSpellState->m_bLostFocus) 574 bInvalidate = true; 575 } 576 else 577 { 578 switch(m_pSpellState->m_eSelMode) 579 { 580 case SHELL_MODE_TEXT: 581 case SHELL_MODE_LIST_TEXT: 582 case SHELL_MODE_TABLE_TEXT: 583 case SHELL_MODE_TABLE_LIST_TEXT: 584 { 585 SwPaM* pCursor = pWrtShell->GetCrsr(); 586 if(m_pSpellState->m_pPointNode != pCursor->GetNode(sal_True) || 587 m_pSpellState->m_pMarkNode != pCursor->GetNode(sal_False)|| 588 m_pSpellState->m_nPointPos != pCursor->GetPoint()->nContent.GetIndex()|| 589 m_pSpellState->m_nMarkPos != pCursor->GetMark()->nContent.GetIndex()) 590 bInvalidate = true; 591 } 592 break; 593 case SHELL_MODE_DRAWTEXT: 594 { 595 SdrView* pSdrView = pWrtShell->GetDrawView(); 596 SdrOutliner* pOutliner = pSdrView ? pSdrView->GetTextEditOutliner() : 0; 597 if(!pOutliner || m_pSpellState->m_pOutliner != pOutliner) 598 bInvalidate = true; 599 else 600 { 601 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); 602 DBG_ASSERT(pOLV, "no OutlinerView in SwSpellDialogChildWindow::GetFocus()"); 603 if(!pOLV || !m_pSpellState->m_aESelection.IsEqual(pOLV->GetSelection())) 604 bInvalidate = true; 605 } 606 } 607 break; 608 default: bInvalidate = true; 609 } 610 } 611 } 612 else 613 { 614 bInvalidate = true; 615 } 616 if(bInvalidate) 617 InvalidateSpellDialog(); 618 } 619 /*-- 28.10.2003 08:41:09--------------------------------------------------- 620 621 -----------------------------------------------------------------------*/ 622 void SwSpellDialogChildWindow::LoseFocus() 623 { 624 //prevent initial invalidation 625 m_pSpellState->m_bLostFocus = true; 626 if(m_pSpellState->m_bLockFocus) 627 return; 628 SwWrtShell* pWrtShell = GetWrtShell_Impl(); 629 if(pWrtShell) 630 { 631 m_pSpellState->m_eSelMode = pWrtShell->GetView().GetShellMode(); 632 m_pSpellState->m_pPointNode = m_pSpellState->m_pMarkNode = 0; 633 m_pSpellState->m_nPointPos = m_pSpellState->m_nMarkPos = 0; 634 m_pSpellState->m_pOutliner = 0; 635 636 switch(m_pSpellState->m_eSelMode) 637 { 638 case SHELL_MODE_TEXT: 639 case SHELL_MODE_LIST_TEXT: 640 case SHELL_MODE_TABLE_TEXT: 641 case SHELL_MODE_TABLE_LIST_TEXT: 642 { 643 //store a node pointer and a pam-position to be able to check on next GetFocus(); 644 SwPaM* pCursor = pWrtShell->GetCrsr(); 645 m_pSpellState->m_pPointNode = pCursor->GetNode(sal_True); 646 m_pSpellState->m_pMarkNode = pCursor->GetNode(sal_False); 647 m_pSpellState->m_nPointPos = pCursor->GetPoint()->nContent.GetIndex(); 648 m_pSpellState->m_nMarkPos = pCursor->GetMark()->nContent.GetIndex(); 649 650 } 651 break; 652 case SHELL_MODE_DRAWTEXT: 653 { 654 SdrView* pSdrView = pWrtShell->GetDrawView(); 655 SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner(); 656 m_pSpellState->m_pOutliner = pOutliner; 657 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); 658 DBG_ASSERT(pOutliner && pOLV, "no Outliner/OutlinerView in SwSpellDialogChildWindow::LoseFocus()"); 659 if(pOLV) 660 { 661 m_pSpellState->m_aESelection = pOLV->GetSelection(); 662 } 663 } 664 break; 665 default:;//prevent warning 666 } 667 } 668 else 669 m_pSpellState->m_eSelMode = SHELL_MODE_OBJECT; 670 } 671 /*-- 18.09.2003 12:50:18--------------------------------------------------- 672 673 -----------------------------------------------------------------------*/ 674 void SwSpellDialogChildWindow::InvalidateSpellDialog() 675 { 676 SwWrtShell* pWrtShell = GetWrtShell_Impl(); 677 if(!m_pSpellState->m_bInitialCall && pWrtShell) 678 pWrtShell->SpellEnd(0, false); 679 m_pSpellState->Reset(); 680 svx::SpellDialogChildWindow::InvalidateSpellDialog(); 681 } 682 683 /*-- 18.09.2003 12:54:59--------------------------------------------------- 684 685 -----------------------------------------------------------------------*/ 686 SwWrtShell* SwSpellDialogChildWindow::GetWrtShell_Impl() 687 { 688 SfxDispatcher* pDispatch = GetBindings().GetDispatcher(); 689 SwView* pView = 0; 690 if(pDispatch) 691 { 692 sal_uInt16 nShellIdx = 0; 693 SfxShell* pShell; 694 while(0 != (pShell = pDispatch->GetShell(nShellIdx++))) 695 if(pShell->ISA(SwView)) 696 { 697 pView = static_cast<SwView* >(pShell); 698 break; 699 } 700 } 701 return pView ? pView->GetWrtShellPtr(): 0; 702 } 703 704 /*-- 13.10.2003 15:19:04--------------------------------------------------- 705 set the cursor into the body text - necessary if any object is selected 706 on start of the spelling dialog 707 -----------------------------------------------------------------------*/ 708 bool SwSpellDialogChildWindow::MakeTextSelection_Impl(SwWrtShell& rShell, ShellModes eSelMode) 709 { 710 SwView& rView = rShell.GetView(); 711 switch(eSelMode) 712 { 713 case SHELL_MODE_TEXT: 714 case SHELL_MODE_LIST_TEXT: 715 case SHELL_MODE_TABLE_TEXT: 716 case SHELL_MODE_TABLE_LIST_TEXT: 717 case SHELL_MODE_DRAWTEXT: 718 DBG_ERROR("text already active in SwSpellDialogChildWindow::MakeTextSelection_Impl()"); 719 break; 720 721 case SHELL_MODE_FRAME: 722 { 723 rShell.UnSelectFrm(); 724 rShell.LeaveSelFrmMode(); 725 rView.AttrChangedNotify(&rShell); 726 } 727 break; 728 729 case SHELL_MODE_DRAW: 730 case SHELL_MODE_DRAW_CTRL: 731 case SHELL_MODE_DRAW_FORM: 732 case SHELL_MODE_BEZIER: 733 if(FindNextDrawTextError_Impl(rShell)) 734 { 735 rView.AttrChangedNotify(&rShell); 736 break; 737 } 738 //otherwise no break to deselect the object 739 case SHELL_MODE_GRAPHIC: 740 case SHELL_MODE_OBJECT: 741 { 742 if ( rShell.IsDrawCreate() ) 743 { 744 rView.GetDrawFuncPtr()->BreakCreate(); 745 rView.AttrChangedNotify(&rShell); 746 } 747 else if ( rShell.HasSelection() || rView.IsDrawMode() ) 748 { 749 SdrView *pSdrView = rShell.GetDrawView(); 750 if(pSdrView && pSdrView->AreObjectsMarked() && 751 pSdrView->GetHdlList().GetFocusHdl()) 752 { 753 ((SdrHdlList&)pSdrView->GetHdlList()).ResetFocusHdl(); 754 } 755 else 756 { 757 rView.LeaveDrawCreate(); 758 Point aPt(LONG_MIN, LONG_MIN); 759 //go out of the frame 760 rShell.SelectObj(aPt, SW_LEAVE_FRAME); 761 SfxBindings& rBind = rView.GetViewFrame()->GetBindings(); 762 rBind.Invalidate( SID_ATTR_SIZE ); 763 rShell.EnterStdMode(); 764 rView.AttrChangedNotify(&rShell); 765 } 766 } 767 } 768 break; 769 default:; //prevent warning 770 } 771 return true; 772 } 773 /*-- 13.10.2003 15:20:09--------------------------------------------------- 774 select the next draw text object that has a spelling error 775 -----------------------------------------------------------------------*/ 776 bool SwSpellDialogChildWindow::FindNextDrawTextError_Impl(SwWrtShell& rSh) 777 { 778 bool bNextDoc = false; 779 SdrView* pDrView = rSh.GetDrawView(); 780 if(!pDrView) 781 return bNextDoc; 782 SwView& rView = rSh.GetView(); 783 SwDoc* pDoc = rView.GetDocShell()->GetDoc(); 784 const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList(); 785 //start at the current draw object - if there is any selected 786 SdrTextObj* pCurrentTextObj = 0; 787 if ( rMarkList.GetMarkCount() == 1 ) 788 { 789 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); 790 if( pObj && pObj->ISA(SdrTextObj) ) 791 pCurrentTextObj = static_cast<SdrTextObj*>(pObj); 792 } 793 //at first fill the list of drawing objects 794 if(!m_pSpellState->m_bTextObjectsCollected ) 795 { 796 m_pSpellState->m_bTextObjectsCollected = true; 797 std::list<SdrTextObj*> aTextObjs; 798 SwDrawContact::GetTextObjectsFromFmt( aTextObjs, pDoc ); 799 if(pCurrentTextObj) 800 { 801 m_pSpellState->m_aTextObjects.remove(pCurrentTextObj); 802 m_pSpellState->m_aTextObjects.push_back(pCurrentTextObj); 803 } 804 } 805 if(m_pSpellState->m_aTextObjects.size()) 806 { 807 Reference< XSpellChecker1 > xSpell( GetSpellChecker() ); 808 while(!bNextDoc && m_pSpellState->m_aTextObjects.size()) 809 { 810 std::list<SdrTextObj*>::iterator aStart = m_pSpellState->m_aTextObjects.begin(); 811 SdrTextObj* pTextObj = *aStart; 812 if(m_pSpellState->m_pStartDrawing == pTextObj) 813 m_pSpellState->m_bRestartDrawing = true; 814 m_pSpellState->m_aTextObjects.erase(aStart); 815 OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject(); 816 if ( pParaObj ) 817 { 818 bool bHasSpellError = false; 819 { 820 SdrOutliner aTmpOutliner(pDoc->GetDrawModel()-> 821 GetDrawOutliner().GetEmptyItemSet().GetPool(), 822 OUTLINERMODE_TEXTOBJECT ); 823 aTmpOutliner.SetRefDevice( pDoc->getPrinter( false ) ); 824 MapMode aMapMode (MAP_TWIP); 825 aTmpOutliner.SetRefMapMode(aMapMode); 826 aTmpOutliner.SetPaperSize( pTextObj->GetLogicRect().GetSize() ); 827 aTmpOutliner.SetSpeller( xSpell ); 828 829 OutlinerView* pOutlView = new OutlinerView( &aTmpOutliner, &(rView.GetEditWin()) ); 830 pOutlView->GetOutliner()->SetRefDevice( rSh.getIDocumentDeviceAccess()->getPrinter( false ) ); 831 aTmpOutliner.InsertView( pOutlView ); 832 Point aPt; 833 Size aSize(1,1); 834 Rectangle aRect( aPt, aSize ); 835 pOutlView->SetOutputArea( aRect ); 836 aTmpOutliner.SetText( *pParaObj ); 837 aTmpOutliner.ClearModifyFlag(); 838 bHasSpellError = EE_SPELL_OK != aTmpOutliner.HasSpellErrors(); 839 aTmpOutliner.RemoveView( pOutlView ); 840 delete pOutlView; 841 } 842 if(bHasSpellError) 843 { 844 //now the current one has to be deselected 845 if(pCurrentTextObj) 846 pDrView->SdrEndTextEdit( sal_True ); 847 //and the found one should be activated 848 rSh.MakeVisible(pTextObj->GetLogicRect()); 849 Point aTmp( 0,0 ); 850 rSh.SelectObj( aTmp, 0, pTextObj ); 851 SdrPageView* pPV = pDrView->GetSdrPageView(); 852 rView.BeginTextEdit( pTextObj, pPV, &rView.GetEditWin(), sal_False, sal_True ); 853 rView.AttrChangedNotify(&rSh); 854 bNextDoc = true; 855 } 856 } 857 } 858 } 859 return bNextDoc; 860 } 861 862 /*-- 13.10.2003 15:24:27--------------------------------------------------- 863 864 -----------------------------------------------------------------------*/ 865 bool SwSpellDialogChildWindow::SpellDrawText_Impl(SwWrtShell& rSh, ::svx::SpellPortions& rPortions) 866 { 867 bool bRet = false; 868 SdrView* pSdrView = rSh.GetDrawView(); 869 SdrOutliner* pOutliner = pSdrView ? pSdrView->GetTextEditOutliner() : 0; 870 DBG_ASSERT(pOutliner, "No Outliner in SwSpellDialogChildWindow::SpellDrawText_Impl"); 871 if(pOutliner) 872 { 873 bRet = pOutliner->SpellSentence(pSdrView->GetTextEditOutlinerView()->GetEditView(), rPortions, m_bIsGrammarCheckingOn); 874 //find out if the current selection is in the first spelled drawing object 875 //and behind the initial selection 876 if(bRet && m_pSpellState->m_bRestartDrawing) 877 { 878 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); 879 ESelection aCurrentSelection = pOLV->GetSelection(); 880 if(m_pSpellState->m_aStartDrawingSelection.nEndPara < aCurrentSelection.nEndPara || 881 (m_pSpellState->m_aStartDrawingSelection.nEndPara == aCurrentSelection.nEndPara && 882 m_pSpellState->m_aStartDrawingSelection.nEndPos < aCurrentSelection.nEndPos)) 883 { 884 bRet = false; 885 rPortions.clear(); 886 } 887 } 888 } 889 return bRet; 890 } 891 /*-- 30.10.2003 14:54:59--------------------------------------------------- 892 893 -----------------------------------------------------------------------*/ 894 void SwSpellDialogChildWindow::LockFocusNotification(bool bLock) 895 { 896 DBG_ASSERT(m_pSpellState->m_bLockFocus != bLock, "invalid locking - no change of state"); 897 m_pSpellState->m_bLockFocus = bLock; 898 } 899 900 901