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