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