LibreOffice Module sw (master)  1
SwSpellDialogChildWindow.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
22 #include <vcl/svapp.hxx>
23 #include <vcl/weld.hxx>
24 #include <editeng/svxacorr.hxx>
25 #include <editeng/acorrcfg.hxx>
26 #include <sfx2/bindings.hxx>
27 #include <sfx2/dispatch.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <wrtsh.hxx>
30 #include <sfx2/printer.hxx>
31 #include <svx/svdoutl.hxx>
32 #include <svx/svdview.hxx>
33 #include <unotools/linguprops.hxx>
34 #include <unotools/lingucfg.hxx>
35 #include <doc.hxx>
38 #include <docsh.hxx>
39 #include <drawdoc.hxx>
40 #include <dcontact.hxx>
41 #include <edtwin.hxx>
42 #include <pam.hxx>
43 #include <drawbase.hxx>
44 #include <unotextrange.hxx>
45 #include <strings.hrc>
46 #include <cmdid.h>
47 
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::text;
51 using namespace ::com::sun::star::linguistic2;
52 using namespace ::com::sun::star::beans;
53 
55 
56 struct SpellState
57 {
59  bool m_bLockFocus; // lock the focus notification while a modal dialog is active
61 
62  // restart and progress information
63  bool m_bBodySpelled; // body already spelled
64  bool m_bOtherSpelled; // frames, footnotes, headers and footers spelled
65  bool m_bStartedInOther; // started the spelling inside of the _other_ area
66  bool m_bStartedInSelection; // there was an initial text selection
67  std::unique_ptr<SwPaM>
68  pOtherCursor; // position where the spelling inside the _other_ area started
69  bool m_bDrawingsSpelled; // all drawings spelled
70  Reference<XTextRange> m_xStartRange; // text range that marks the start of spelling
71  const SdrObject* m_pStartDrawing; // draw text object spelling started in
72  ESelection m_aStartDrawingSelection; // draw text start selection
73  bool m_bRestartDrawing; // the first selected drawing object is found again
74 
75  // lose/get focus information to decide if spelling can be continued
79  sal_Int32 m_nPointPos;
80  sal_Int32 m_nMarkPos;
83 
84  // iterating over draw text objects
85  std::list<SdrTextObj*> m_aTextObjects;
87 
89  m_bInitialCall(true),
90  m_bLockFocus(false),
91  m_bLostFocus(false),
92  m_bBodySpelled(false),
93  m_bOtherSpelled(false),
94  m_bStartedInOther(false),
95  m_bStartedInSelection(false),
96  m_bDrawingsSpelled(false),
97  m_pStartDrawing(nullptr),
98  m_bRestartDrawing(false),
99 
100  m_eSelMode(ShellMode::Object), // initially invalid
101  m_pPointNode(nullptr),
102  m_pMarkNode(nullptr),
103  m_nPointPos(0),
104  m_nMarkPos(0),
105  m_pOutliner(nullptr),
106  m_bTextObjectsCollected(false)
107  {}
108 
109  // reset state in ::InvalidateSpellDialog
110  void Reset()
111  { m_bInitialCall = true;
112  m_bBodySpelled = m_bOtherSpelled = m_bDrawingsSpelled = false;
113  m_xStartRange = nullptr;
114  m_pStartDrawing = nullptr;
115  m_bRestartDrawing = false;
116  m_bTextObjectsCollected = false;
117  m_aTextObjects.clear();
118  m_bStartedInOther = false;
119  pOtherCursor.reset();
120  }
121 };
122 
123 static void lcl_LeaveDrawText(SwWrtShell& rSh)
124 {
125  if(rSh.GetDrawView())
126  {
127  rSh.GetDrawView()->SdrEndTextEdit( true );
128  Point aPt(LONG_MIN, LONG_MIN);
129  // go out of the frame
130  rSh.SelectObj(aPt, SW_LEAVE_FRAME);
131  rSh.EnterStdMode();
132  rSh.GetView().AttrChangedNotify(nullptr);
133  }
134 }
135 
137  vcl::Window* _pParent,
138  sal_uInt16 nId,
139  SfxBindings* pBindings,
140  SfxChildWinInfo* /*pInfo*/)
141  : svx::SpellDialogChildWindow (
142  _pParent, nId, pBindings)
143  , m_bIsGrammarCheckingOn(false)
144  , m_pSpellState(new SpellState)
145 {
147 }
148 
150 {
151  SwWrtShell* pWrtShell = GetWrtShell_Impl();
152  if(!m_pSpellState->m_bInitialCall && pWrtShell)
153  pWrtShell->SpellEnd();
154  m_pSpellState.reset();
155 }
156 
157 SfxChildWinInfo SwSpellDialogChildWindow::GetInfo() const
158 {
159  SfxChildWinInfo aInfo = svx::SpellDialogChildWindow::GetInfo();
160  aInfo.bVisible = false;
161  return aInfo;
162 }
163 
165 {
166  svx::SpellPortions aRet;
167  SwWrtShell* pWrtShell = GetWrtShell_Impl();
168  if(pWrtShell)
169  {
170  bool bNoDictionaryAvailable = pWrtShell->GetDoc()->IsDictionaryMissing();
171 
172  if (!bRecheck)
173  {
174  // first set continuation point for spell/grammar check to the
175  // end of the current sentence
177  }
178 
179  ShellMode eSelMode = pWrtShell->GetView().GetShellMode();
180  bool bDrawText = ShellMode::DrawText == eSelMode;
181  bool bNormalText =
182  ShellMode::TableText == eSelMode ||
183  ShellMode::ListText == eSelMode ||
184  ShellMode::TableListText == eSelMode ||
185  ShellMode::Text == eSelMode;
186  // Writer text outside of the body
187  bool bOtherText = false;
188 
189  if( m_pSpellState->m_bInitialCall )
190  {
191  // if no text selection exists the cursor has to be set into the text
192  if(!bDrawText && !bNormalText)
193  {
194  MakeTextSelection_Impl(*pWrtShell, eSelMode);
195  // the selection type has to be checked again - both text types are possible
197  bDrawText = true;
198  bNormalText = !bDrawText;
199  }
200  if(bNormalText)
201  {
202  // set cursor to the start of the sentence
203  if(!pWrtShell->HasSelection())
204  pWrtShell->GoStartSentence();
205  else
206  {
207  pWrtShell->ExpandToSentenceBorders();
208  m_pSpellState->m_bStartedInSelection = true;
209  }
210  // determine if the selection is outside of the body text
211  bOtherText = !(pWrtShell->GetFrameType(nullptr,true) & FrameTypeFlags::BODY);
212  if(bOtherText)
213  {
214  m_pSpellState->pOtherCursor.reset( new SwPaM(*pWrtShell->GetCursor()->GetPoint()) );
215  m_pSpellState->m_bStartedInOther = true;
217  }
218  else
219  {
220  // mark the start position only if not at start of doc
221  if(!pWrtShell->IsStartOfDoc())
222  {
223  // Record the position *before* the current cursor, as
224  // the word at the current cursor can possibly be
225  // replaced by a spellcheck correction which invalidates
226  // an XTextRange at this position.
227  SwDoc *pDoc = pWrtShell->GetDoc();
228  auto pStart = pWrtShell->GetCursor()->Start();
229  auto pUnoCursor = pDoc->CreateUnoCursor(*pStart);
230  pUnoCursor->Left( 1 );
231  pStart = pUnoCursor->Start();
232  m_pSpellState->m_xStartRange
233  = SwXTextRange::CreateXTextRange(*pDoc, *pStart, nullptr);
234  }
236  }
237  }
238  else
239  {
240  SdrView* pSdrView = pWrtShell->GetDrawView();
241  m_pSpellState->m_pStartDrawing = pSdrView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
242  OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
243  // start checking at the top of the drawing object
244  pOLV->SetSelection( ESelection() );
245  m_pSpellState->m_aStartDrawingSelection = ESelection();
246 /*
247 Note: spelling in a selection only, or starting in a mid of a drawing object requires
248 further changes elsewhere. (Especially if it should work in sc and sd as well.)
249 The code below would only be part of the solution.
250 (Keeping it as a comment for the time being)
251  ESelection aCurSel( pOLV->GetSelection() );
252  ESelection aSentenceSel( pOLV->GetEditView().GetEditEngine()->SelectSentence( aCurSel ) );
253  if (!aCurSel.HasRange())
254  {
255  aSentenceSel.nEndPara = aSentenceSel.nStartPara;
256  aSentenceSel.nEndPos = aSentenceSel.nStartPos;
257  }
258  pOLV->SetSelection( aSentenceSel );
259  m_pSpellState->m_aStartDrawingSelection = aSentenceSel;
260 */
261  }
262 
263  m_pSpellState->m_bInitialCall = false;
264  }
265  if( bDrawText )
266  {
267  // spell inside of the current draw text
268  if(!SpellDrawText_Impl(*pWrtShell, aRet))
269  {
270  if(!FindNextDrawTextError_Impl(*pWrtShell) || !SpellDrawText_Impl(*pWrtShell, aRet))
271  {
272  lcl_LeaveDrawText(*pWrtShell);
273  // now the drawings have been spelled
274  m_pSpellState->m_bDrawingsSpelled = true;
275  // the spelling continues at the other content
276  // if there's any that has not been spelled yet
277  if(!m_pSpellState->m_bOtherSpelled && pWrtShell->HasOtherCnt())
278  {
280  if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
281  {
282  pWrtShell->SpellEnd();
283  m_pSpellState->m_bOtherSpelled = true;
284  }
285  }
286  else
287  m_pSpellState->m_bOtherSpelled = true;
288  // if no result has been found try at the body text - completely
289  if(!m_pSpellState->m_bBodySpelled && aRet.empty())
290  {
292  if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
293  {
294  m_pSpellState->m_bBodySpelled = true;
295  pWrtShell->SpellEnd();
296  }
297  }
298 
299  }
300  }
301  }
302  else
303  {
304  // spell inside of the Writer text
305  if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
306  {
307  // if there is a selection (within body or header/footer text)
308  // then spell/grammar checking should not move outside of it.
309  if (!m_pSpellState->m_bStartedInSelection)
310  {
311  // find out which text has been spelled body or other
312  bOtherText = !(pWrtShell->GetFrameType(nullptr,true) & FrameTypeFlags::BODY);
313  if(bOtherText && m_pSpellState->m_bStartedInOther && m_pSpellState->pOtherCursor)
314  {
315  m_pSpellState->m_bStartedInOther = false;
316  pWrtShell->SetSelection(*m_pSpellState->pOtherCursor);
317  pWrtShell->SpellEnd();
318  m_pSpellState->pOtherCursor.reset();
320  (void)pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn);
321  }
322  if(aRet.empty())
323  {
324  // end spelling
325  pWrtShell->SpellEnd();
326  if(bOtherText)
327  {
328  m_pSpellState->m_bOtherSpelled = true;
329  // has the body been spelled?
330  if(!m_pSpellState->m_bBodySpelled)
331  {
333  if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
334  {
335  m_pSpellState->m_bBodySpelled = true;
336  pWrtShell->SpellEnd();
337  }
338  }
339  }
340  else
341  {
342  m_pSpellState->m_bBodySpelled = true;
343  if(!m_pSpellState->m_bOtherSpelled && pWrtShell->HasOtherCnt())
344  {
346  if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
347  {
348  pWrtShell->SpellEnd();
349  m_pSpellState->m_bOtherSpelled = true;
350  }
351  }
352  else
353  m_pSpellState->m_bOtherSpelled = true;
354  }
355  }
356 
357  // search for a draw text object that contains error and spell it
358  if(aRet.empty() &&
359  (m_pSpellState->m_bDrawingsSpelled ||
360  !FindNextDrawTextError_Impl(*pWrtShell) || !SpellDrawText_Impl(*pWrtShell, aRet)))
361  {
362  lcl_LeaveDrawText(*pWrtShell);
363  m_pSpellState->m_bDrawingsSpelled = true;
364  }
365  }
366  }
367  }
368  // now only the rest of the body text can be spelled -
369  // if the spelling started inside of the body
370  bool bCloseMessage = true;
371  if(aRet.empty() && !m_pSpellState->m_bStartedInSelection)
372  {
373  OSL_ENSURE(m_pSpellState->m_bDrawingsSpelled &&
374  m_pSpellState->m_bOtherSpelled && m_pSpellState->m_bBodySpelled,
375  "not all parts of the document are already spelled");
376  if( m_pSpellState->m_xStartRange.is() && !bNoDictionaryAvailable )
377  {
378  LockFocusNotification( true );
379  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetController()->getDialog(),
380  VclMessageType::Question, VclButtonsType::YesNo, SwResId(STR_QUERY_SPELL_CONTINUE)));
381  sal_uInt16 nRet = xBox->run();
382  if (RET_YES == nRet)
383  {
384  SwUnoInternalPaM aPam(*pWrtShell->GetDoc());
385  if (::sw::XTextRangeToSwPaM(aPam,
386  m_pSpellState->m_xStartRange))
387  {
388  pWrtShell->SetSelection(aPam);
390  if(!pWrtShell->SpellSentence(aRet, m_bIsGrammarCheckingOn))
391  pWrtShell->SpellEnd();
392  }
393  m_pSpellState->m_xStartRange = nullptr;
394  LockFocusNotification( false );
395  // take care that the now valid selection is stored
396  LoseFocus();
397  }
398  else
399  bCloseMessage = false; // no closing message if a wrap around has been denied
400  }
401  }
402  if( aRet.empty() && bCloseMessage && !bNoDictionaryAvailable )
403  {
404  LockFocusNotification( true );
405  OUString sInfo( SwResId( bNoDictionaryAvailable ? STR_DICTIONARY_UNAVAILABLE : STR_SPELLING_COMPLETED ) );
406  auto xSpellController = GetController();
407  // #i84610#
408  std::unique_ptr<weld::MessageDialog> xBox(
409  Application::CreateMessageDialog( xSpellController->getDialog(),
410  VclMessageType::Info,
411  VclButtonsType::Ok,
412  sInfo ) );
413  xBox->run();
414  LockFocusNotification( false );
415  // take care that the now valid selection is stored
416  LoseFocus();
417  xSpellController->getDialog()->grab_focus();
418  }
419  }
420  return aRet;
421 }
422 
424 {
425  SwWrtShell* pWrtShell = GetWrtShell_Impl();
426  OSL_ENSURE(!m_pSpellState->m_bInitialCall, "ApplyChangedSentence in initial call or after resume");
427  if(pWrtShell && !m_pSpellState->m_bInitialCall)
428  {
429  ShellMode eSelMode = pWrtShell->GetView().GetShellMode();
430  bool bDrawText = ShellMode::DrawText == eSelMode;
431  bool bNormalText =
432  ShellMode::TableText == eSelMode ||
433  ShellMode::ListText == eSelMode ||
434  ShellMode::TableListText == eSelMode ||
435  ShellMode::Text == eSelMode;
436 
437  // evaluate if the same sentence should be rechecked or not.
438  // Sentences that got grammar checked should always be rechecked in order
439  // to detect possible errors that get introduced with the changes
441 
442  if(bNormalText)
443  pWrtShell->ApplyChangedSentence(rChanged, bRecheck);
444  else if(bDrawText )
445  {
446  SdrView* pDrView = pWrtShell->GetDrawView();
447  SdrOutliner *pOutliner = pDrView->GetTextEditOutliner();
448  pOutliner->ApplyChangedSentence(pDrView->GetTextEditOutlinerView()->GetEditView(), rChanged, bRecheck);
449  }
450  }
451 }
452 
454  const OUString& rOld, const OUString& rNew, LanguageType eLanguage)
455 {
457  pACorr->PutText( rOld, rNew, eLanguage );
458 }
459 
461 {
462  return true;
463 }
464 
466 {
468 }
469 
471 {
472  return m_bIsGrammarCheckingOn;
473 }
474 
476 {
477  uno::Any aVal;
478  aVal <<= bOn;
481  // set current spell position to the start of the current sentence to
482  // continue with this sentence after grammar checking state has been changed
483  SwWrtShell* pWrtShell = GetWrtShell_Impl();
484  if(pWrtShell)
485  {
486  ShellMode eSelMode = pWrtShell->GetView().GetShellMode();
487  bool bDrawText = ShellMode::DrawText == eSelMode;
488  bool bNormalText =
489  ShellMode::TableText == eSelMode ||
490  ShellMode::ListText == eSelMode ||
491  ShellMode::TableListText == eSelMode ||
492  ShellMode::Text == eSelMode;
493  if( bNormalText )
495  else if( bDrawText )
496  {
497  SdrView* pSdrView = pWrtShell->GetDrawView();
498  SdrOutliner* pOutliner = pSdrView ? pSdrView->GetTextEditOutliner() : nullptr;
499  OSL_ENSURE(pOutliner, "No Outliner in SwSpellDialogChildWindow::SetGrammarChecking");
500  if(pOutliner)
501  {
502  pOutliner->PutSpellingToSentenceStart( pSdrView->GetTextEditOutlinerView()->GetEditView() );
503  }
504  }
505  }
506 }
507 
509 {
510  if(m_pSpellState->m_bLockFocus)
511  return;
512  bool bInvalidate = false;
513  SwWrtShell* pWrtShell = GetWrtShell_Impl();
514  if(pWrtShell && !m_pSpellState->m_bInitialCall)
515  {
516  ShellMode eSelMode = pWrtShell->GetView().GetShellMode();
517  if(eSelMode != m_pSpellState->m_eSelMode)
518  {
519  // prevent initial invalidation
520  if(m_pSpellState->m_bLostFocus)
521  bInvalidate = true;
522  }
523  else
524  {
525  switch(m_pSpellState->m_eSelMode)
526  {
527  case ShellMode::Text:
528  case ShellMode::ListText:
531  {
532  SwPaM* pCursor = pWrtShell->GetCursor();
533  if(m_pSpellState->m_pPointNode != &pCursor->GetNode() ||
534  m_pSpellState->m_pMarkNode != &pCursor->GetNode(false)||
535  m_pSpellState->m_nPointPos != pCursor->GetPoint()->nContent.GetIndex()||
536  m_pSpellState->m_nMarkPos != pCursor->GetMark()->nContent.GetIndex())
537  bInvalidate = true;
538  }
539  break;
540  case ShellMode::DrawText:
541  {
542  SdrView* pSdrView = pWrtShell->GetDrawView();
543  SdrOutliner* pOutliner = pSdrView ? pSdrView->GetTextEditOutliner() : nullptr;
544  if(!pOutliner || m_pSpellState->m_pOutliner != pOutliner)
545  bInvalidate = true;
546  else
547  {
548  OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
549  OSL_ENSURE(pOLV, "no OutlinerView in SwSpellDialogChildWindow::GetFocus()");
550  if(!pOLV || m_pSpellState->m_aESelection != pOLV->GetSelection())
551  bInvalidate = true;
552  }
553  }
554  break;
555  default: bInvalidate = true;
556  }
557  }
558  }
559  else
560  {
561  bInvalidate = true;
562  }
563  if(bInvalidate)
565 }
566 
568 {
569  // prevent initial invalidation
570  m_pSpellState->m_bLostFocus = true;
571  if(m_pSpellState->m_bLockFocus)
572  return;
573  SwWrtShell* pWrtShell = GetWrtShell_Impl();
574  if(pWrtShell)
575  {
576  m_pSpellState->m_eSelMode = pWrtShell->GetView().GetShellMode();
577  m_pSpellState->m_pPointNode = m_pSpellState->m_pMarkNode = nullptr;
578  m_pSpellState->m_nPointPos = m_pSpellState->m_nMarkPos = 0;
579  m_pSpellState->m_pOutliner = nullptr;
580 
581  switch(m_pSpellState->m_eSelMode)
582  {
583  case ShellMode::Text:
584  case ShellMode::ListText:
587  {
588  // store a node pointer and a pam-position to be able to check on next GetFocus();
589  SwPaM* pCursor = pWrtShell->GetCursor();
590  m_pSpellState->m_pPointNode = &pCursor->GetNode();
591  m_pSpellState->m_pMarkNode = &pCursor->GetNode(false);
592  m_pSpellState->m_nPointPos = pCursor->GetPoint()->nContent.GetIndex();
593  m_pSpellState->m_nMarkPos = pCursor->GetMark()->nContent.GetIndex();
594 
595  }
596  break;
597  case ShellMode::DrawText:
598  {
599  SdrView* pSdrView = pWrtShell->GetDrawView();
600  SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner();
601  m_pSpellState->m_pOutliner = pOutliner;
602  OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
603  OSL_ENSURE(pOutliner && pOLV, "no Outliner/OutlinerView in SwSpellDialogChildWindow::LoseFocus()");
604  if(pOLV)
605  {
606  m_pSpellState->m_aESelection = pOLV->GetSelection();
607  }
608  }
609  break;
610  default:;// prevent warning
611  }
612  }
613  else
614  m_pSpellState->m_eSelMode = ShellMode::Object;
615 }
616 
618 {
619  SwWrtShell* pWrtShell = GetWrtShell_Impl();
620  if(!m_pSpellState->m_bInitialCall && pWrtShell)
621  pWrtShell->SpellEnd(nullptr, false);
622  m_pSpellState->Reset();
624 }
625 
627 {
628  SfxDispatcher* pDispatch = GetBindings().GetDispatcher();
629  SwView* pView = nullptr;
630  if(pDispatch)
631  {
632  sal_uInt16 nShellIdx = 0;
633  SfxShell* pShell;
634  while(nullptr != (pShell = pDispatch->GetShell(nShellIdx++)))
635  if(dynamic_cast< const SwView *>( pShell ) != nullptr)
636  {
637  pView = static_cast<SwView* >(pShell);
638  break;
639  }
640  }
641  return pView ? pView->GetWrtShellPtr(): nullptr;
642 }
643 
644 // set the cursor into the body text - necessary if any object is selected
645 // on start of the spelling dialog
647 {
648  SwView& rView = rShell.GetView();
649  switch(eSelMode)
650  {
651  case ShellMode::Text:
652  case ShellMode::ListText:
655  case ShellMode::DrawText:
656  OSL_FAIL("text already active in SwSpellDialogChildWindow::MakeTextSelection_Impl()");
657  break;
658 
659  case ShellMode::Frame:
660  {
661  rShell.UnSelectFrame();
662  rShell.LeaveSelFrameMode();
663  rView.AttrChangedNotify(nullptr);
664  }
665  break;
666 
667  case ShellMode::Draw:
668  case ShellMode::DrawForm:
669  case ShellMode::Bezier:
670  if(FindNextDrawTextError_Impl(rShell))
671  {
672  rView.AttrChangedNotify(nullptr);
673  break;
674  }
675  [[fallthrough]]; // to deselect the object
676  case ShellMode::Graphic:
677  case ShellMode::Object:
678  {
679  if ( rShell.IsDrawCreate() )
680  {
681  rView.GetDrawFuncPtr()->BreakCreate();
682  rView.AttrChangedNotify(nullptr);
683  }
684  else if ( rShell.HasSelection() || rView.IsDrawMode() )
685  {
686  SdrView *pSdrView = rShell.GetDrawView();
687  if(pSdrView && pSdrView->AreObjectsMarked() &&
688  pSdrView->GetHdlList().GetFocusHdl())
689  {
690  const_cast<SdrHdlList&>(pSdrView->GetHdlList()).ResetFocusHdl();
691  }
692  else
693  {
694  rView.LeaveDrawCreate();
695  Point aPt(LONG_MIN, LONG_MIN);
696  // go out of the frame
697  rShell.SelectObj(aPt, SW_LEAVE_FRAME);
698  SfxBindings& rBind = rView.GetViewFrame()->GetBindings();
699  rBind.Invalidate( SID_ATTR_SIZE );
700  rShell.EnterStdMode();
701  rView.AttrChangedNotify(nullptr);
702  }
703  }
704  }
705  break;
706  default:; // prevent warning
707  }
708 }
709 
710 // select the next draw text object that has a spelling error
712 {
713  bool bNextDoc = false;
714  SdrView* pDrView = rSh.GetDrawView();
715  if(!pDrView)
716  return bNextDoc;
717  SwView& rView = rSh.GetView();
718  SwDoc* pDoc = rView.GetDocShell()->GetDoc();
719  const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
720  // start at the current draw object - if there is any selected
721  SdrTextObj* pCurrentTextObj = nullptr;
722  if ( rMarkList.GetMarkCount() == 1 )
723  {
724  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
725  if( auto pSdrTextObj = dynamic_cast<SdrTextObj *>( pObj ) )
726  pCurrentTextObj = pSdrTextObj;
727  }
728  // at first fill the list of drawing objects
729  if(!m_pSpellState->m_bTextObjectsCollected )
730  {
731  m_pSpellState->m_bTextObjectsCollected = true;
733  if(pCurrentTextObj)
734  {
735  m_pSpellState->m_aTextObjects.remove(pCurrentTextObj);
736  m_pSpellState->m_aTextObjects.push_back(pCurrentTextObj);
737  }
738  }
739  if(!m_pSpellState->m_aTextObjects.empty())
740  {
741  Reference< XSpellChecker1 > xSpell( GetSpellChecker() );
742  while(!bNextDoc && !m_pSpellState->m_aTextObjects.empty())
743  {
744  std::list<SdrTextObj*>::iterator aStart = m_pSpellState->m_aTextObjects.begin();
745  SdrTextObj* pTextObj = *aStart;
746  if(m_pSpellState->m_pStartDrawing == pTextObj)
747  m_pSpellState->m_bRestartDrawing = true;
748  m_pSpellState->m_aTextObjects.erase(aStart);
749  OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
750  if ( pParaObj )
751  {
752  bool bHasSpellError = false;
753  {
754  SdrOutliner aTmpOutliner(pDoc->getIDocumentDrawModelAccess().GetDrawModel()->
755  GetDrawOutliner().GetEmptyItemSet().GetPool(),
756  OutlinerMode::TextObject );
757  aTmpOutliner.SetRefDevice( pDoc->getIDocumentDeviceAccess().getPrinter( false ) );
758  MapMode aMapMode (MapUnit::MapTwip);
759  aTmpOutliner.SetRefMapMode(aMapMode);
760  aTmpOutliner.SetPaperSize( pTextObj->GetLogicRect().GetSize() );
761  aTmpOutliner.SetSpeller( xSpell );
762 
763  std::unique_ptr<OutlinerView> pOutlView( new OutlinerView( &aTmpOutliner, &(rView.GetEditWin()) ) );
764  pOutlView->GetOutliner()->SetRefDevice( rSh.getIDocumentDeviceAccess().getPrinter( false ) );
765  aTmpOutliner.InsertView( pOutlView.get() );
766  Size aSize(1,1);
767  tools::Rectangle aRect( Point(), aSize );
768  pOutlView->SetOutputArea( aRect );
769  aTmpOutliner.SetText( *pParaObj );
770  aTmpOutliner.ClearModifyFlag();
771  bHasSpellError = EESpellState::Ok != aTmpOutliner.HasSpellErrors();
772  aTmpOutliner.RemoveView( pOutlView.get() );
773  }
774  if(bHasSpellError)
775  {
776  // now the current one has to be deselected
777  if(pCurrentTextObj)
778  pDrView->SdrEndTextEdit( true );
779  // and the found one should be activated
780  rSh.MakeVisible(pTextObj->GetLogicRect());
781  Point aTmp( 0,0 );
782  rSh.SelectObj( aTmp, 0, pTextObj );
783  SdrPageView* pPV = pDrView->GetSdrPageView();
784  rView.BeginTextEdit( pTextObj, pPV, &rView.GetEditWin(), false, true );
785  rView.AttrChangedNotify(nullptr);
786  bNextDoc = true;
787  }
788  }
789  }
790  }
791  return bNextDoc;
792 }
793 
795 {
796  bool bRet = false;
797  SdrView* pSdrView = rSh.GetDrawView();
798  SdrOutliner* pOutliner = pSdrView ? pSdrView->GetTextEditOutliner() : nullptr;
799  OSL_ENSURE(pOutliner, "No Outliner in SwSpellDialogChildWindow::SpellDrawText_Impl");
800  if(pOutliner)
801  {
802  bRet = pOutliner->SpellSentence(pSdrView->GetTextEditOutlinerView()->GetEditView(), rPortions);
803  // find out if the current selection is in the first spelled drawing object
804  // and behind the initial selection
805  if(bRet && m_pSpellState->m_bRestartDrawing)
806  {
807  OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView();
808  ESelection aCurrentSelection = pOLV->GetSelection();
809  if(m_pSpellState->m_aStartDrawingSelection.nEndPara < aCurrentSelection.nEndPara ||
810  (m_pSpellState->m_aStartDrawingSelection.nEndPara == aCurrentSelection.nEndPara &&
811  m_pSpellState->m_aStartDrawingSelection.nEndPos < aCurrentSelection.nEndPos))
812  {
813  bRet = false;
814  rPortions.clear();
815  }
816  }
817  }
818  return bRet;
819 }
820 
822 {
823  OSL_ENSURE(m_pSpellState->m_bLockFocus != bLock, "invalid locking - no change of state");
824  m_pSpellState->m_bLockFocus = bLock;
825 }
826 
827 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxViewFrame * GetViewFrame() const
std::shared_ptr< SwUnoCursor > CreateUnoCursor(const SwPosition &rPos, bool bTableCursor=false)
Definition: doc.cxx:1801
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
void ExpandToSentenceBorders()
Definition: crstrvl1.cxx:88
size_t GetMarkCount() const
static SvxAutoCorrCfg & Get()
virtual SdrEndTextEditKind SdrEndTextEdit(bool bDontDeleteReally=false)
bool IsDrawMode() const
Definition: view.hxx:526
SdrView * GetDrawView()
Definition: vnew.cxx:375
const SwNode * m_pMarkNode
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:188
bool FindNextDrawTextError_Impl(SwWrtShell &rSh)
bool BeginTextEdit(SdrObject *pObj, SdrPageView *pPV=nullptr, vcl::Window *pWin=nullptr, bool bIsNewObj=false, bool bSetSelectionToStart=false)
Definition: viewdraw.cxx:497
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:237
bool AreObjectsMarked() const
bool IsStartOfDoc() const
Definition: crsrsh.cxx:2723
static bool HasLastSentenceGotGrammarChecked()
Check SwSpellIter data to see if the last sentence got grammar checked.
Definition: edlingu.cxx:585
const SwPosition * GetMark() const
Definition: pam.hxx:209
bool SpellSentence(svx::SpellPortions &rToFill, bool bIsGrammarCheck)
Spells on a sentence basis - the SpellPortions are needed.
Definition: edlingu.cxx:1031
Definition: doc.hxx:185
void EnterStdMode()
Definition: select.cxx:550
SwEditWin & GetEditWin()
Definition: view.hxx:403
SdrMark * GetMark(size_t nNum) const
const SdrObject * m_pStartDrawing
Reference< XTextRange > m_xStartRange
void ApplyChangedSentence(const svx::SpellPortions &rNewPortions, bool bRecheck)
Applies a changed sentence.
Definition: edlingu.cxx:1070
void Invalidate(sal_uInt16 nId)
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:154
bool GoStartSentence()
Definition: crstrvl1.cxx:78
Used by the UI to modify the document model.
Definition: wrtsh.hxx:90
void BreakCreate()
Definition: drawbase.cxx:464
std::unique_ptr< SpellState > m_pSpellState
const SwView & GetView() const
Definition: wrtsh.hxx:428
RET_YES
SfxShell * GetShell(sal_uInt16 nIdx) const
SwIndex nContent
Definition: pam.hxx:38
void MakeTextSelection_Impl(SwWrtShell &rSh, ShellMode eSelMode)
const SdrOutliner * m_pOutliner
virtual void LoseFocus() override
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
bool SpellDrawText_Impl(SwWrtShell &rSh, svx::SpellPortions &rPortions)
sal_Int32 nEndPos
ShellMode
Definition: view.hxx:87
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange)
Definition: unoobj2.cxx:950
EditView & GetEditView() const
virtual ~SwSpellDialogChildWindow() override
void MakeVisible(const SwRect &)
Definition: viewsh.cxx:565
virtual bool HasGrammarChecking() override
#define UPN_IS_GRAMMAR_INTERACTIVE
virtual void GetFocus() override
SdrObject * GetMarkedSdrObj() const
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:203
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
const IDocumentDeviceAccess & getIDocumentDeviceAccess() const
Provides access to the document device interface.
Definition: viewsh.cxx:2580
bool HasOtherCnt() const
Are there frames, footnotes, etc.
Definition: edws.cxx:143
sal_Int32 nEndPara
const SdrOutliner * GetTextEditOutliner() const
bool HasSelection() const
Definition: wrtsh.hxx:141
SfxBindings & GetBindings() const
std::unique_ptr< SwPaM > pOtherCursor
ESelection m_aStartDrawingSelection
void SpellEnd(SwConversionArgs const *pConvArgs=nullptr, bool bRestoreSelection=true)
Restore selections.
Definition: edlingu.cxx:658
SwSpellDialogChildWindow(vcl::Window *pParent, sal_uInt16 nId, SfxBindings *pBindings, SfxChildWinInfo *pInfo)
bool HasGrammarChecker() const
const SwPosition * GetPoint() const
Definition: pam.hxx:207
virtual void ApplyChangedSentence(const svx::SpellPortions &rChanged, bool bRecheck) override
SvxAutoCorrect * GetAutoCorrect()
SfxBindings & GetBindings()
const SdrMarkList & GetMarkedObjectList() const
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
virtual svx::SpellPortions GetNextWrongSentence(bool bRecheck) override
void SetSelection(const SwPaM &rCursor)
Definition: crsrsh.cxx:3486
SFX_IMPL_CHILDWINDOW_WITHID(SearchResultsDlgWrapper, SID_SEARCH_RESULTS_DIALOG)
const OutlinerView * GetTextEditOutlinerView() const
OUString SwResId(const char *pId)
Definition: swmodule.cxx:178
virtual bool HasAutoCorrection() override
void LeaveDrawCreate()
Definition: view.hxx:525
SwDrawBase * GetDrawFuncPtr() const
Definition: view.hxx:513
virtual void SetGrammarChecking(bool bOn) override
virtual SfxPrinter * getPrinter(bool bCreate) const =0
Return the printer set at the document.
Size GetSize() const
const SwPosition * Start() const
Definition: pam.hxx:212
SwDocShell * GetDocShell()
Definition: view.cxx:1107
static void MoveContinuationPosToEndOfCheckedSentence()
Moves the continuation position to the end of the currently checked sentence.
Definition: edlingu.cxx:1060
ESelection GetSelection() const
bool IsDictionaryMissing() const
Returns true if no dictionary can be found for any content.
Definition: doc.hxx:1652
SdrHdl * GetFocusHdl() const
const SwNode * m_pPointNode
void SetSelection(const ESelection &)
SwWrtShell * GetWrtShellPtr() const
Definition: view.hxx:401
bool PutText(const OUString &rShort, const OUString &rLong, LanguageType eLang)
#define FN_SPELL_GRAMMAR_DIALOG
Definition: cmdid.h:593
virtual OutlinerParaObject * GetOutlinerParaObject() const override
sal_Int32 GetIndex() const
Definition: index.hxx:95
uno::Reference< linguistic2::XSpellChecker1 > GetSpellChecker()
Definition: swtypes.cxx:45
void SpellStart(SwDocPositions eStart, SwDocPositions eEnd, SwDocPositions eCurr, SwConversionArgs *pConvArgs=nullptr)
Functions used for spell checking and text conversion.
Definition: edlingu.cxx:621
bool SetProperty(const OUString &rPropertyName, const css::uno::Any &rValue)
void UnSelectFrame()
Definition: select.cxx:322
bool SelectObj(const Point &rSelPt, sal_uInt8 nFlag=0, SdrObject *pObj=nullptr)
If an object has been given, exactly this object is selected (instead of searching over position)...
Definition: feshview.cxx:176
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage)
SdrPageView * GetSdrPageView() const
void LeaveSelFrameMode()
Definition: select.cxx:719
static void lcl_LeaveDrawText(SwWrtShell &rSh)
SfxDispatcher * GetDispatcher() const
static void GetTextObjectsFromFormat(std::list< SdrTextObj * > &, SwDoc *)
get data collection of anchored objects, handled by with contact
Definition: dcontact.cxx:729
static void PutSpellingToSentenceStart()
Make SpellIter start with the current sentence when called next time.
Definition: edlingu.cxx:1046
virtual bool IsGrammarChecking() override
css::uno::Any GetProperty(const OUString &rPropertyName) const
const SdrHdlList & GetHdlList() const
#define SW_LEAVE_FRAME
Definition: fesh.hxx:167
std::vector< SpellPortion > SpellPortions
static css::uno::Reference< css::text::XTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1052
SelectionType GetSelectionType() const
Definition: wrtsh1.cxx:1388
bool IsDrawCreate() const
Definition: feshview.cxx:2140
ShellMode GetShellMode() const
Definition: view0.cxx:103
FrameTypeFlags GetFrameType(const Point *pPt, bool bStopAtFly) const
For return values see above FrameType.
Definition: fews.cxx:236
std::list< SdrTextObj * > m_aTextObjects
Definition: view.hxx:146
virtual void AddAutoCorrection(const OUString &rOld, const OUString &rNew, LanguageType eLanguage) override
virtual const tools::Rectangle & GetLogicRect() const override
Base class of the Writer document model elements.
Definition: node.hxx:79
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo