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