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
SpellStateSpellState104 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
~SpellStateSpellState127 ~SpellState() {delete pOtherCursor;}
128
129 // reset state in ::InvalidateSpellDialog
ResetSpellState130 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 -----------------------------------------------------------------------*/
lcl_LeaveDrawText(SwWrtShell & rSh)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 -----------------------------------------------------------------------*/
SwSpellDialogChildWindow(Window * _pParent,sal_uInt16 nId,SfxBindings * pBindings,SfxChildWinInfo * pInfo)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 -----------------------------------------------------------------------*/
~SwSpellDialogChildWindow()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 -----------------------------------------------------------------------*/
GetInfo(void) const188 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 -----------------------------------------------------------------------*/
GetNextWrongSentence(bool bRecheck)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, NULL );
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, NULL );
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, NULL );
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, NULL );
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, NULL );
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, NULL );
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, NULL );
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 -----------------------------------------------------------------------*/
ApplyChangedSentence(const svx::SpellPortions & rChanged,bool bRecheck)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 -----------------------------------------------------------------------*/
AddAutoCorrection(const String & rOld,const String & rNew,LanguageType eLanguage)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 -----------------------------------------------------------------------*/
HasAutoCorrection()500 bool SwSpellDialogChildWindow::HasAutoCorrection()
501 {
502 return true;
503 }
504 /*-- 16.06.2008 11:59:17---------------------------------------------------
505
506 -----------------------------------------------------------------------*/
HasGrammarChecking()507 bool SwSpellDialogChildWindow::HasGrammarChecking()
508 {
509 return SvtLinguConfig().HasGrammarChecker();
510 }
511 /*-- 18.06.2008 12:27:11---------------------------------------------------
512
513 -----------------------------------------------------------------------*/
IsGrammarChecking()514 bool SwSpellDialogChildWindow::IsGrammarChecking()
515 {
516 return m_bIsGrammarCheckingOn;
517 }
518 /*-- 18.06.2008 12:27:11---------------------------------------------------
519
520 -----------------------------------------------------------------------*/
SetGrammarChecking(bool bOn)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 -----------------------------------------------------------------------*/
GetFocus()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 -----------------------------------------------------------------------*/
LoseFocus()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 -----------------------------------------------------------------------*/
InvalidateSpellDialog()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 -----------------------------------------------------------------------*/
GetWrtShell_Impl()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 -----------------------------------------------------------------------*/
MakeTextSelection_Impl(SwWrtShell & rShell,ShellModes eSelMode)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 -----------------------------------------------------------------------*/
FindNextDrawTextError_Impl(SwWrtShell & rSh)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 -----------------------------------------------------------------------*/
SpellDrawText_Impl(SwWrtShell & rSh,::svx::SpellPortions & rPortions)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 -----------------------------------------------------------------------*/
LockFocusNotification(bool bLock)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