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