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