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