bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / ui / dialog / SwSpellDialogChildWindow.cxx
blobfefcfd0dc043b837de9fea94b90b46e75506c9ca
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <SwSpellDialogChildWindow.hxx>
22 #include <vcl/msgbox.hxx>
23 #include <editeng/svxacorr.hxx>
24 #include <editeng/acorrcfg.hxx>
25 #include <svx/svxids.hrc>
26 #include <sfx2/app.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <editeng/unolingu.hxx>
30 #include <editeng/editeng.hxx>
31 #include <editeng/editview.hxx>
32 #include <wrtsh.hxx>
33 #include <sfx2/printer.hxx>
34 #include <svx/svdoutl.hxx>
35 #include <svx/svdview.hxx>
36 #include <svx/svditer.hxx>
37 #include <svx/svdogrp.hxx>
38 #include <unotools/linguprops.hxx>
39 #include <unotools/lingucfg.hxx>
40 #include <doc.hxx>
41 #include <docsh.hxx>
42 #include <docary.hxx>
43 #include <frmfmt.hxx>
44 #include <dcontact.hxx>
45 #include <edtwin.hxx>
46 #include <pam.hxx>
47 #include <drawbase.hxx>
48 #include <unotextrange.hxx>
49 #include <dialog.hrc>
50 #include <cmdid.h>
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::text;
56 using namespace ::com::sun::star::linguistic2;
57 using namespace ::com::sun::star::beans;
59 SFX_IMPL_CHILDWINDOW_WITHID(SwSpellDialogChildWindow, FN_SPELL_GRAMMAR_DIALOG)
62 #define SPELL_START_BODY 0 // body text area
63 #define SPELL_START_OTHER 1 // frame, footnote, header, footer
64 #define SPELL_START_DRAWTEXT 2 // started in a draw text object
66 struct SpellState
68 bool m_bInitialCall;
69 bool m_bLockFocus; //lock the focus notification while a modal dialog is active
70 bool m_bLostFocus;
72 //restart and progress information
73 sal_uInt16 m_SpellStartPosition;
74 bool m_bBodySpelled; //body already spelled
75 bool m_bOtherSpelled; //frames, footnotes, headers and footers spelled
76 bool m_bStartedInOther; //started the spelling insided of the _other_ area
77 bool m_bStartedInSelection; // there was an initial text selection
78 SwPaM* pOtherCursor; // position where the spelling inside the _other_ area started
79 bool m_bDrawingsSpelled; //all drawings spelled
80 Reference<XTextRange> m_xStartRange; //text range that marks the start of spelling
81 const SdrObject* m_pStartDrawing; //draw text object spelling started in
82 ESelection m_aStartDrawingSelection; //draw text start selection
83 bool m_bRestartDrawing; // the first selected drawing object is found again
85 //lose/get focus information to decide if spelling can be continued
86 ShellModes m_eSelMode;
87 const SwNode* m_pPointNode;
88 const SwNode* m_pMarkNode;
89 xub_StrLen m_nPointPos;
90 xub_StrLen m_nMarkPos;
91 const SdrOutliner* m_pOutliner;
92 ESelection m_aESelection;
94 //iterating over draw text objects
95 std::list<SdrTextObj*> m_aTextObjects;
96 bool m_bTextObjectsCollected;
98 SpellState() :
99 m_bInitialCall(true),
100 m_bLockFocus(false),
101 m_bLostFocus(false),
102 m_SpellStartPosition(SPELL_START_BODY),
103 m_bBodySpelled(false),
104 m_bOtherSpelled(false),
105 m_bStartedInOther(false),
106 m_bStartedInSelection(false),
107 pOtherCursor(0),
108 m_bDrawingsSpelled(false),
109 m_pStartDrawing(0),
110 m_bRestartDrawing(false),
112 m_eSelMode(SHELL_MODE_OBJECT), //initially invalid
113 m_pPointNode(0),
114 m_pMarkNode(0),
115 m_nPointPos(0),
116 m_nMarkPos(0),
117 m_pOutliner(0),
118 m_bTextObjectsCollected(false)
121 ~SpellState() {delete pOtherCursor;}
123 // reset state in ::InvalidateSpellDialog
124 void Reset()
125 { m_bInitialCall = true;
126 m_bBodySpelled = m_bOtherSpelled = m_bDrawingsSpelled = false;
127 m_xStartRange = 0;
128 m_pStartDrawing = 0;
129 m_bRestartDrawing = false;
130 m_bTextObjectsCollected = false;
131 m_aTextObjects.clear();
132 m_bStartedInOther = false;
133 delete pOtherCursor;
134 pOtherCursor = 0;
138 static void lcl_LeaveDrawText(SwWrtShell& rSh)
140 if(rSh.GetDrawView())
142 rSh.GetDrawView()->SdrEndTextEdit( sal_True );
143 Point aPt(LONG_MIN, LONG_MIN);
144 //go out of the frame
145 rSh.SelectObj(aPt, SW_LEAVE_FRAME);
146 rSh.EnterStdMode();
147 rSh.GetView().AttrChangedNotify(&rSh);
151 SwSpellDialogChildWindow::SwSpellDialogChildWindow (
152 Window* _pParent,
153 sal_uInt16 nId,
154 SfxBindings* pBindings,
155 SfxChildWinInfo* pInfo) :
156 svx::SpellDialogChildWindow (
157 _pParent, nId, pBindings, pInfo),
158 m_pSpellState(new SpellState)
160 OUString aPropName(UPN_IS_GRAMMAR_INTERACTIVE);
161 SvtLinguConfig().GetProperty( aPropName ) >>= m_bIsGrammarCheckingOn;
164 SwSpellDialogChildWindow::~SwSpellDialogChildWindow ()
166 SwWrtShell* pWrtShell = GetWrtShell_Impl();
167 if(!m_pSpellState->m_bInitialCall && pWrtShell)
168 pWrtShell->SpellEnd();
169 delete m_pSpellState;
173 SfxChildWinInfo SwSpellDialogChildWindow::GetInfo (void) const
175 SfxChildWinInfo aInfo = svx::SpellDialogChildWindow::GetInfo();
176 aInfo.bVisible = sal_False;
177 return aInfo;
181 svx::SpellPortions SwSpellDialogChildWindow::GetNextWrongSentence(bool bRecheck)
183 svx::SpellPortions aRet;
184 SwWrtShell* pWrtShell = GetWrtShell_Impl();
185 if(pWrtShell)
187 if (!bRecheck)
189 // first set continuation point for spell/grammar check to the
190 // end of the current sentence
191 pWrtShell->MoveContinuationPosToEndOfCheckedSentence();
194 ShellModes eSelMode = pWrtShell->GetView().GetShellMode();
195 bool bDrawText = SHELL_MODE_DRAWTEXT == eSelMode;
196 bool bNormalText =
197 SHELL_MODE_TABLE_TEXT == eSelMode ||
198 SHELL_MODE_LIST_TEXT == eSelMode ||
199 SHELL_MODE_TABLE_LIST_TEXT == eSelMode ||
200 SHELL_MODE_TEXT == eSelMode;
201 //Writer text outside of the body
202 bool bOtherText = false;
204 if( m_pSpellState->m_bInitialCall )
206 //if no text selection exists the cursor has to be set into the text
207 if(!bDrawText && !bNormalText)
209 if(!MakeTextSelection_Impl(*pWrtShell, eSelMode))
210 return aRet;
211 else
213 // the selection type has to be checked again - both text types are possible
214 if(0 != (pWrtShell->GetSelectionType()& nsSelectionType::SEL_DRW_TXT))
215 bDrawText = true;
216 bNormalText = !bDrawText;
219 if(bNormalText)
221 //set cursor to the start of the sentence
222 if(!pWrtShell->HasSelection())
223 pWrtShell->GoStartSentence();
224 else
226 pWrtShell->ExpandToSentenceBorders();
227 m_pSpellState->m_bStartedInSelection = true;
229 //determine if the selection is outside of the body text
230 bOtherText = !(pWrtShell->GetFrmType(0,sal_True) & FRMTYPE_BODY);
231 m_pSpellState->m_SpellStartPosition = bOtherText ? SPELL_START_OTHER : SPELL_START_BODY;
232 if(bOtherText)
234 m_pSpellState->pOtherCursor = new SwPaM(*pWrtShell->GetCrsr()->GetPoint());
235 m_pSpellState->m_bStartedInOther = true;
236 pWrtShell->SpellStart( DOCPOS_OTHERSTART, DOCPOS_OTHEREND, DOCPOS_CURR );
238 else
240 SwPaM* pCrsr = pWrtShell->GetCrsr();
241 //mark the start position only if not at start of doc
242 if(!pWrtShell->IsStartOfDoc())
244 m_pSpellState->m_xStartRange =
245 SwXTextRange::CreateXTextRange(
246 *pWrtShell->GetDoc(),
247 *pCrsr->Start(), pCrsr->End());
249 pWrtShell->SpellStart( DOCPOS_START, DOCPOS_END, DOCPOS_CURR );
252 else
254 SdrView* pSdrView = pWrtShell->GetDrawView();
255 m_pSpellState->m_SpellStartPosition = SPELL_START_DRAWTEXT;
256 m_pSpellState->m_pStartDrawing = pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
257 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
258 // start checking at the top of the drawing object
259 pOLV->SetSelection( ESelection() );
260 m_pSpellState->m_aStartDrawingSelection = ESelection();
262 Note: spelling in a selection only, or starting in a mid of a drawing object requires
263 further changes elsewhere. (Especially if it should work in sc and sd as well.)
264 The code below would only be part of the solution.
265 (Keeping it a as a comment for the time being)
266 ESelection aCurSel( pOLV->GetSelection() );
267 ESelection aSentenceSel( pOLV->GetEditView().GetEditEngine()->SelectSentence( aCurSel ) );
268 if (!aCurSel.HasRange())
270 aSentenceSel.nEndPara = aSentenceSel.nStartPara;
271 aSentenceSel.nEndPos = aSentenceSel.nStartPos;
273 pOLV->SetSelection( aSentenceSel );
274 m_pSpellState->m_aStartDrawingSelection = aSentenceSel;
278 m_pSpellState->m_bInitialCall = false;
280 if( bDrawText )
282 // spell inside of the current draw text
283 if(!SpellDrawText_Impl(*pWrtShell, aRet))
285 if(!FindNextDrawTextError_Impl(*pWrtShell) || !SpellDrawText_Impl(*pWrtShell, aRet))
287 lcl_LeaveDrawText(*pWrtShell);
288 //now the drawings have been spelled
289 m_pSpellState->m_bDrawingsSpelled = true;
290 //the spelling continues at the other content
291 //if there's any that has not been spelled yet
292 if(!m_pSpellState->m_bOtherSpelled && pWrtShell->HasOtherCnt())
294 pWrtShell->SpellStart(DOCPOS_OTHERSTART, DOCPOS_OTHEREND, DOCPOS_OTHERSTART );
295 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
297 pWrtShell->SpellEnd();
298 m_pSpellState->m_bOtherSpelled = true;
301 else
302 m_pSpellState->m_bOtherSpelled = true;
303 //if no result has been found try at the body text - completely
304 if(!m_pSpellState->m_bBodySpelled && !aRet.size())
306 pWrtShell->SpellStart(DOCPOS_START, DOCPOS_END, DOCPOS_START );
307 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
309 m_pSpellState->m_bBodySpelled = true;
310 pWrtShell->SpellEnd();
317 else
319 //spell inside of the Writer text
320 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
322 // if there is a selection (within body or header/footer text)
323 // then spell/grammar checking should not move outside of it.
324 if (!m_pSpellState->m_bStartedInSelection)
326 //find out which text has been spelled body or other
327 bOtherText = !(pWrtShell->GetFrmType(0,sal_True) & FRMTYPE_BODY);
328 if(bOtherText && m_pSpellState->m_bStartedInOther && m_pSpellState->pOtherCursor)
330 m_pSpellState->m_bStartedInOther = false;
331 pWrtShell->SetSelection(*m_pSpellState->pOtherCursor);
332 pWrtShell->SpellEnd();
333 delete m_pSpellState->pOtherCursor;
334 m_pSpellState->pOtherCursor = 0;
335 pWrtShell->SpellStart(DOCPOS_OTHERSTART, DOCPOS_CURR, DOCPOS_OTHERSTART );
336 pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn);
338 if(!aRet.size())
340 //end spelling
341 pWrtShell->SpellEnd();
342 if(bOtherText)
344 m_pSpellState->m_bOtherSpelled = true;
345 //has the body been spelled?
346 if(!m_pSpellState->m_bBodySpelled)
348 pWrtShell->SpellStart(DOCPOS_START, DOCPOS_END, DOCPOS_START );
349 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
351 m_pSpellState->m_bBodySpelled = true;
352 pWrtShell->SpellEnd();
356 else
358 m_pSpellState->m_bBodySpelled = true;
359 if(!m_pSpellState->m_bOtherSpelled && pWrtShell->HasOtherCnt())
361 pWrtShell->SpellStart(DOCPOS_OTHERSTART, DOCPOS_OTHEREND, DOCPOS_OTHERSTART );
362 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
364 pWrtShell->SpellEnd();
365 m_pSpellState->m_bOtherSpelled = true;
368 else
369 m_pSpellState->m_bOtherSpelled = true;
373 //search for a draw text object that contains error and spell it
374 if(!aRet.size() &&
375 (m_pSpellState->m_bDrawingsSpelled ||
376 !FindNextDrawTextError_Impl(*pWrtShell) || !SpellDrawText_Impl(*pWrtShell, aRet)))
378 lcl_LeaveDrawText(*pWrtShell);
379 m_pSpellState->m_bDrawingsSpelled = true;
384 // now only the rest of the body text can be spelled -
385 // if the spelling started inside of the body
387 bool bCloseMessage = true;
388 if(!aRet.size() && !m_pSpellState->m_bStartedInSelection)
390 OSL_ENSURE(m_pSpellState->m_bDrawingsSpelled &&
391 m_pSpellState->m_bOtherSpelled && m_pSpellState->m_bBodySpelled,
392 "not all parts of the document are already spelled");
393 if(m_pSpellState->m_xStartRange.is())
395 LockFocusNotification( true );
396 sal_uInt16 nRet = QueryBox( GetWindow(), SW_RES(RID_QB_SPELL_CONTINUE)).Execute();
397 if(RET_YES == nRet)
399 SwUnoInternalPaM aPam(*pWrtShell->GetDoc());
400 if (::sw::XTextRangeToSwPaM(aPam,
401 m_pSpellState->m_xStartRange))
403 pWrtShell->SetSelection(aPam);
404 pWrtShell->SpellStart(DOCPOS_START, DOCPOS_CURR, DOCPOS_START);
405 if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
406 pWrtShell->SpellEnd();
408 m_pSpellState->m_xStartRange = 0;
409 LockFocusNotification( false );
410 //take care that the now valid selection is stored
411 LoseFocus();
413 else
414 bCloseMessage = false; //no closing message if a wrap around has been denied
417 if(!aRet.size())
419 if(bCloseMessage)
421 LockFocusNotification( true );
422 String sInfo(SW_RES(STR_SPELLING_COMPLETED));
423 //#i84610#
424 Window* pTemp = GetWindow(); // temporary needed for g++ 3.3.5
425 InfoBox(pTemp, sInfo ).Execute();
426 LockFocusNotification( false );
427 //take care that the now valid selection is stored
428 LoseFocus();
431 //close the spelling dialog
432 GetBindings().GetDispatcher()->Execute(FN_SPELL_GRAMMAR_DIALOG, SFX_CALLMODE_ASYNCHRON);
435 return aRet;
439 void SwSpellDialogChildWindow::ApplyChangedSentence(const svx::SpellPortions& rChanged, bool bRecheck)
441 SwWrtShell* pWrtShell = GetWrtShell_Impl();
442 OSL_ENSURE(!m_pSpellState->m_bInitialCall, "ApplyChangedSentence in initial call or after resume");
443 if(pWrtShell && !m_pSpellState->m_bInitialCall)
445 ShellModes eSelMode = pWrtShell->GetView().GetShellMode();
446 bool bDrawText = SHELL_MODE_DRAWTEXT == eSelMode;
447 bool bNormalText =
448 SHELL_MODE_TABLE_TEXT == eSelMode ||
449 SHELL_MODE_LIST_TEXT == eSelMode ||
450 SHELL_MODE_TABLE_LIST_TEXT == eSelMode ||
451 SHELL_MODE_TEXT == eSelMode;
453 // evaluate if the same sentence should be rechecked or not.
454 // Sentences that got grammar checked should always be rechecked in order
455 // to detect possible errors that get introduced with the changes
456 bRecheck |= pWrtShell->HasLastSentenceGotGrammarChecked();
458 if(bNormalText)
459 pWrtShell->ApplyChangedSentence(rChanged, bRecheck);
460 else if(bDrawText )
462 SdrView* pDrView = pWrtShell->GetDrawView();
463 SdrOutliner *pOutliner = pDrView->GetTextEditOutliner();
464 pOutliner->ApplyChangedSentence(pDrView->GetTextEditOutlinerView()->GetEditView(), rChanged, bRecheck);
469 void SwSpellDialogChildWindow::AddAutoCorrection(
470 const String& rOld, const String& rNew, LanguageType eLanguage)
472 SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect();
473 pACorr->PutText( rOld, rNew, eLanguage );
476 bool SwSpellDialogChildWindow::HasAutoCorrection()
478 return true;
481 bool SwSpellDialogChildWindow::HasGrammarChecking()
483 return SvtLinguConfig().HasGrammarChecker();
486 bool SwSpellDialogChildWindow::IsGrammarChecking()
488 return m_bIsGrammarCheckingOn;
491 void SwSpellDialogChildWindow::SetGrammarChecking(bool bOn)
493 uno::Any aVal;
494 aVal <<= bOn;
495 m_bIsGrammarCheckingOn = bOn;
496 OUString aPropName(UPN_IS_GRAMMAR_INTERACTIVE);
497 SvtLinguConfig().SetProperty( aPropName, aVal );
498 // set current spell position to the start of the current sentence to
499 // continue with this sentence after grammar checking state has been changed
500 SwWrtShell* pWrtShell = GetWrtShell_Impl();
501 if(pWrtShell)
503 ShellModes eSelMode = pWrtShell->GetView().GetShellMode();
504 bool bDrawText = SHELL_MODE_DRAWTEXT == eSelMode;
505 bool bNormalText =
506 SHELL_MODE_TABLE_TEXT == eSelMode ||
507 SHELL_MODE_LIST_TEXT == eSelMode ||
508 SHELL_MODE_TABLE_LIST_TEXT == eSelMode ||
509 SHELL_MODE_TEXT == eSelMode;
510 if( bNormalText )
511 pWrtShell->PutSpellingToSentenceStart();
512 else if( bDrawText )
514 SdrView* pSdrView = pWrtShell->GetDrawView();
515 SdrOutliner* pOutliner = pSdrView ? pSdrView->GetTextEditOutliner() : 0;
516 OSL_ENSURE(pOutliner, "No Outliner in SwSpellDialogChildWindow::SetGrammarChecking");
517 if(pOutliner)
519 pOutliner->PutSpellingToSentenceStart( pSdrView->GetTextEditOutlinerView()->GetEditView() );
525 void SwSpellDialogChildWindow::GetFocus()
527 if(m_pSpellState->m_bLockFocus)
528 return;
529 bool bInvalidate = false;
530 SwWrtShell* pWrtShell = GetWrtShell_Impl();
531 if(pWrtShell && !m_pSpellState->m_bInitialCall)
533 ShellModes eSelMode = pWrtShell->GetView().GetShellMode();
534 if(eSelMode != m_pSpellState->m_eSelMode)
536 //prevent initial invalidation
537 if(m_pSpellState->m_bLostFocus)
538 bInvalidate = true;
540 else
542 switch(m_pSpellState->m_eSelMode)
544 case SHELL_MODE_TEXT:
545 case SHELL_MODE_LIST_TEXT:
546 case SHELL_MODE_TABLE_TEXT:
547 case SHELL_MODE_TABLE_LIST_TEXT:
549 SwPaM* pCursor = pWrtShell->GetCrsr();
550 if(m_pSpellState->m_pPointNode != pCursor->GetNode(sal_True) ||
551 m_pSpellState->m_pMarkNode != pCursor->GetNode(sal_False)||
552 m_pSpellState->m_nPointPos != pCursor->GetPoint()->nContent.GetIndex()||
553 m_pSpellState->m_nMarkPos != pCursor->GetMark()->nContent.GetIndex())
554 bInvalidate = true;
556 break;
557 case SHELL_MODE_DRAWTEXT:
559 SdrView* pSdrView = pWrtShell->GetDrawView();
560 SdrOutliner* pOutliner = pSdrView ? pSdrView->GetTextEditOutliner() : 0;
561 if(!pOutliner || m_pSpellState->m_pOutliner != pOutliner)
562 bInvalidate = true;
563 else
565 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
566 OSL_ENSURE(pOLV, "no OutlinerView in SwSpellDialogChildWindow::GetFocus()");
567 if(!pOLV || !m_pSpellState->m_aESelection.IsEqual(pOLV->GetSelection()))
568 bInvalidate = true;
571 break;
572 default: bInvalidate = true;
576 else
578 bInvalidate = true;
580 if(bInvalidate)
581 InvalidateSpellDialog();
584 void SwSpellDialogChildWindow::LoseFocus()
586 //prevent initial invalidation
587 m_pSpellState->m_bLostFocus = true;
588 if(m_pSpellState->m_bLockFocus)
589 return;
590 SwWrtShell* pWrtShell = GetWrtShell_Impl();
591 if(pWrtShell)
593 m_pSpellState->m_eSelMode = pWrtShell->GetView().GetShellMode();
594 m_pSpellState->m_pPointNode = m_pSpellState->m_pMarkNode = 0;
595 m_pSpellState->m_nPointPos = m_pSpellState->m_nMarkPos = 0;
596 m_pSpellState->m_pOutliner = 0;
598 switch(m_pSpellState->m_eSelMode)
600 case SHELL_MODE_TEXT:
601 case SHELL_MODE_LIST_TEXT:
602 case SHELL_MODE_TABLE_TEXT:
603 case SHELL_MODE_TABLE_LIST_TEXT:
605 //store a node pointer and a pam-position to be able to check on next GetFocus();
606 SwPaM* pCursor = pWrtShell->GetCrsr();
607 m_pSpellState->m_pPointNode = pCursor->GetNode(sal_True);
608 m_pSpellState->m_pMarkNode = pCursor->GetNode(sal_False);
609 m_pSpellState->m_nPointPos = pCursor->GetPoint()->nContent.GetIndex();
610 m_pSpellState->m_nMarkPos = pCursor->GetMark()->nContent.GetIndex();
613 break;
614 case SHELL_MODE_DRAWTEXT:
616 SdrView* pSdrView = pWrtShell->GetDrawView();
617 SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner();
618 m_pSpellState->m_pOutliner = pOutliner;
619 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
620 OSL_ENSURE(pOutliner && pOLV, "no Outliner/OutlinerView in SwSpellDialogChildWindow::LoseFocus()");
621 if(pOLV)
623 m_pSpellState->m_aESelection = pOLV->GetSelection();
626 break;
627 default:;//prevent warning
630 else
631 m_pSpellState->m_eSelMode = SHELL_MODE_OBJECT;
634 void SwSpellDialogChildWindow::InvalidateSpellDialog()
636 SwWrtShell* pWrtShell = GetWrtShell_Impl();
637 if(!m_pSpellState->m_bInitialCall && pWrtShell)
638 pWrtShell->SpellEnd(0, false);
639 m_pSpellState->Reset();
640 svx::SpellDialogChildWindow::InvalidateSpellDialog();
643 SwWrtShell* SwSpellDialogChildWindow::GetWrtShell_Impl()
645 SfxDispatcher* pDispatch = GetBindings().GetDispatcher();
646 SwView* pView = 0;
647 if(pDispatch)
649 sal_uInt16 nShellIdx = 0;
650 SfxShell* pShell;
651 while(0 != (pShell = pDispatch->GetShell(nShellIdx++)))
652 if(pShell->ISA(SwView))
654 pView = static_cast<SwView* >(pShell);
655 break;
658 return pView ? pView->GetWrtShellPtr(): 0;
661 /*-------------------------------------------------------------------------
662 set the cursor into the body text - necessary if any object is selected
663 on start of the spelling dialog
664 -----------------------------------------------------------------------*/
665 bool SwSpellDialogChildWindow::MakeTextSelection_Impl(SwWrtShell& rShell, ShellModes eSelMode)
667 SwView& rView = rShell.GetView();
668 switch(eSelMode)
670 case SHELL_MODE_TEXT:
671 case SHELL_MODE_LIST_TEXT:
672 case SHELL_MODE_TABLE_TEXT:
673 case SHELL_MODE_TABLE_LIST_TEXT:
674 case SHELL_MODE_DRAWTEXT:
675 OSL_FAIL("text already active in SwSpellDialogChildWindow::MakeTextSelection_Impl()");
676 break;
678 case SHELL_MODE_FRAME:
680 rShell.UnSelectFrm();
681 rShell.LeaveSelFrmMode();
682 rView.AttrChangedNotify(&rShell);
684 break;
686 case SHELL_MODE_DRAW:
687 case SHELL_MODE_DRAW_CTRL:
688 case SHELL_MODE_DRAW_FORM:
689 case SHELL_MODE_BEZIER:
690 if(FindNextDrawTextError_Impl(rShell))
692 rView.AttrChangedNotify(&rShell);
693 break;
695 //otherwise no break to deselect the object
696 case SHELL_MODE_GRAPHIC:
697 case SHELL_MODE_OBJECT:
699 if ( rShell.IsDrawCreate() )
701 rView.GetDrawFuncPtr()->BreakCreate();
702 rView.AttrChangedNotify(&rShell);
704 else if ( rShell.HasSelection() || rView.IsDrawMode() )
706 SdrView *pSdrView = rShell.GetDrawView();
707 if(pSdrView && pSdrView->AreObjectsMarked() &&
708 pSdrView->GetHdlList().GetFocusHdl())
710 ((SdrHdlList&)pSdrView->GetHdlList()).ResetFocusHdl();
712 else
714 rView.LeaveDrawCreate();
715 Point aPt(LONG_MIN, LONG_MIN);
716 //go out of the frame
717 rShell.SelectObj(aPt, SW_LEAVE_FRAME);
718 SfxBindings& rBind = rView.GetViewFrame()->GetBindings();
719 rBind.Invalidate( SID_ATTR_SIZE );
720 rShell.EnterStdMode();
721 rView.AttrChangedNotify(&rShell);
725 break;
726 default:; //prevent warning
728 return true;
730 /*-------------------------------------------------------------------------
731 select the next draw text object that has a spelling error
732 -----------------------------------------------------------------------*/
733 bool SwSpellDialogChildWindow::FindNextDrawTextError_Impl(SwWrtShell& rSh)
735 bool bNextDoc = false;
736 SdrView* pDrView = rSh.GetDrawView();
737 if(!pDrView)
738 return bNextDoc;
739 SwView& rView = rSh.GetView();
740 SwDoc* pDoc = rView.GetDocShell()->GetDoc();
741 const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
742 //start at the current draw object - if there is any selected
743 SdrTextObj* pCurrentTextObj = 0;
744 if ( rMarkList.GetMarkCount() == 1 )
746 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
747 if( pObj && pObj->ISA(SdrTextObj) )
748 pCurrentTextObj = static_cast<SdrTextObj*>(pObj);
750 //at first fill the list of drawing objects
751 if(!m_pSpellState->m_bTextObjectsCollected )
753 m_pSpellState->m_bTextObjectsCollected = true;
754 std::list<SdrTextObj*> aTextObjs;
755 SwDrawContact::GetTextObjectsFromFmt( aTextObjs, pDoc );
756 if(pCurrentTextObj)
758 m_pSpellState->m_aTextObjects.remove(pCurrentTextObj);
759 m_pSpellState->m_aTextObjects.push_back(pCurrentTextObj);
762 if(m_pSpellState->m_aTextObjects.size())
764 Reference< XSpellChecker1 > xSpell( GetSpellChecker() );
765 while(!bNextDoc && m_pSpellState->m_aTextObjects.size())
767 std::list<SdrTextObj*>::iterator aStart = m_pSpellState->m_aTextObjects.begin();
768 SdrTextObj* pTextObj = *aStart;
769 if(m_pSpellState->m_pStartDrawing == pTextObj)
770 m_pSpellState->m_bRestartDrawing = true;
771 m_pSpellState->m_aTextObjects.erase(aStart);
772 OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
773 if ( pParaObj )
775 bool bHasSpellError = false;
777 SdrOutliner aTmpOutliner(pDoc->GetDrawModel()->
778 GetDrawOutliner().GetEmptyItemSet().GetPool(),
779 OUTLINERMODE_TEXTOBJECT );
780 aTmpOutliner.SetRefDevice( pDoc->getPrinter( false ) );
781 MapMode aMapMode (MAP_TWIP);
782 aTmpOutliner.SetRefMapMode(aMapMode);
783 aTmpOutliner.SetPaperSize( pTextObj->GetLogicRect().GetSize() );
784 aTmpOutliner.SetSpeller( xSpell );
786 OutlinerView* pOutlView = new OutlinerView( &aTmpOutliner, &(rView.GetEditWin()) );
787 pOutlView->GetOutliner()->SetRefDevice( rSh.getIDocumentDeviceAccess()->getPrinter( false ) );
788 aTmpOutliner.InsertView( pOutlView );
789 Point aPt;
790 Size aSize(1,1);
791 Rectangle aRect( aPt, aSize );
792 pOutlView->SetOutputArea( aRect );
793 aTmpOutliner.SetText( *pParaObj );
794 aTmpOutliner.ClearModifyFlag();
795 bHasSpellError = EE_SPELL_OK != aTmpOutliner.HasSpellErrors();
796 aTmpOutliner.RemoveView( pOutlView );
797 delete pOutlView;
799 if(bHasSpellError)
801 //now the current one has to be deselected
802 if(pCurrentTextObj)
803 pDrView->SdrEndTextEdit( sal_True );
804 //and the found one should be activated
805 rSh.MakeVisible(pTextObj->GetLogicRect());
806 Point aTmp( 0,0 );
807 rSh.SelectObj( aTmp, 0, pTextObj );
808 SdrPageView* pPV = pDrView->GetSdrPageView();
809 rView.BeginTextEdit( pTextObj, pPV, &rView.GetEditWin(), sal_False, sal_True );
810 rView.AttrChangedNotify(&rSh);
811 bNextDoc = true;
816 return bNextDoc;
820 bool SwSpellDialogChildWindow::SpellDrawText_Impl(SwWrtShell& rSh, ::svx::SpellPortions& rPortions)
822 bool bRet = false;
823 SdrView* pSdrView = rSh.GetDrawView();
824 SdrOutliner* pOutliner = pSdrView ? pSdrView->GetTextEditOutliner() : 0;
825 OSL_ENSURE(pOutliner, "No Outliner in SwSpellDialogChildWindow::SpellDrawText_Impl");
826 if(pOutliner)
828 bRet = pOutliner->SpellSentence(pSdrView->GetTextEditOutlinerView()->GetEditView(), rPortions, m_bIsGrammarCheckingOn);
829 //find out if the current selection is in the first spelled drawing object
830 //and behind the initial selection
831 if(bRet && m_pSpellState->m_bRestartDrawing)
833 OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
834 ESelection aCurrentSelection = pOLV->GetSelection();
835 if(m_pSpellState->m_aStartDrawingSelection.nEndPara < aCurrentSelection.nEndPara ||
836 (m_pSpellState->m_aStartDrawingSelection.nEndPara == aCurrentSelection.nEndPara &&
837 m_pSpellState->m_aStartDrawingSelection.nEndPos < aCurrentSelection.nEndPos))
839 bRet = false;
840 rPortions.clear();
844 return bRet;
847 void SwSpellDialogChildWindow::LockFocusNotification(bool bLock)
849 OSL_ENSURE(m_pSpellState->m_bLockFocus != bLock, "invalid locking - no change of state");
850 m_pSpellState->m_bLockFocus = bLock;
854 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */