1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <SwSpellDialogChildWindow.hxx>
22 #include <vcl/layout.hxx>
23 #include <editeng/svxacorr.hxx>
24 #include <editeng/acorrcfg.hxx>
25 #include <svx/svxids.hrc>
26 #include <sfx2/app.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <editeng/unolingu.hxx>
30 #include <editeng/editeng.hxx>
31 #include <editeng/editview.hxx>
33 #include <sfx2/printer.hxx>
34 #include <svx/svdoutl.hxx>
35 #include <svx/svdview.hxx>
36 #include <svx/svditer.hxx>
37 #include <svx/svdogrp.hxx>
38 #include <unotools/linguprops.hxx>
39 #include <unotools/lingucfg.hxx>
41 #include <IDocumentDeviceAccess.hxx>
42 #include <IDocumentDrawModelAccess.hxx>
45 #include <drawdoc.hxx>
47 #include <dcontact.hxx>
50 #include <drawbase.hxx>
51 #include <unotextrange.hxx>
55 using namespace ::com::sun::star
;
56 using namespace ::com::sun::star::uno
;
57 using namespace ::com::sun::star::text
;
58 using namespace ::com::sun::star::linguistic2
;
59 using namespace ::com::sun::star::beans
;
61 SFX_IMPL_CHILDWINDOW_WITHID(SwSpellDialogChildWindow
, FN_SPELL_GRAMMAR_DIALOG
)
63 #define SPELL_START_BODY 0 // body text area
64 #define SPELL_START_OTHER 1 // frame, footnote, header, footer
65 #define SPELL_START_DRAWTEXT 2 // started in a draw text object
70 bool m_bLockFocus
; // lock the focus notification while a modal dialog is active
73 // restart and progress information
74 sal_uInt16 m_SpellStartPosition
;
75 bool m_bBodySpelled
; // body already spelled
76 bool m_bOtherSpelled
; // frames, footnotes, headers and footers spelled
77 bool m_bStartedInOther
; // started the spelling inside of the _other_ area
78 bool m_bStartedInSelection
; // there was an initial text selection
79 std::unique_ptr
<SwPaM
>
80 pOtherCursor
; // position where the spelling inside the _other_ area started
81 bool m_bDrawingsSpelled
; // all drawings spelled
82 Reference
<XTextRange
> m_xStartRange
; // text range that marks the start of spelling
83 const SdrObject
* m_pStartDrawing
; // draw text object spelling started in
84 ESelection m_aStartDrawingSelection
; // draw text start selection
85 bool m_bRestartDrawing
; // the first selected drawing object is found again
87 // lose/get focus information to decide if spelling can be continued
89 const SwNode
* m_pPointNode
;
90 const SwNode
* m_pMarkNode
;
91 sal_Int32 m_nPointPos
;
93 const SdrOutliner
* m_pOutliner
;
94 ESelection m_aESelection
;
96 // iterating over draw text objects
97 std::list
<SdrTextObj
*> m_aTextObjects
;
98 bool m_bTextObjectsCollected
;
101 m_bInitialCall(true),
104 m_SpellStartPosition(SPELL_START_BODY
),
105 m_bBodySpelled(false),
106 m_bOtherSpelled(false),
107 m_bStartedInOther(false),
108 m_bStartedInSelection(false),
109 pOtherCursor(nullptr),
110 m_bDrawingsSpelled(false),
111 m_pStartDrawing(nullptr),
112 m_bRestartDrawing(false),
114 m_eSelMode(ShellMode::Object
), // initially invalid
115 m_pPointNode(nullptr),
116 m_pMarkNode(nullptr),
119 m_pOutliner(nullptr),
120 m_bTextObjectsCollected(false)
123 // reset state in ::InvalidateSpellDialog
125 { m_bInitialCall
= true;
126 m_bBodySpelled
= m_bOtherSpelled
= m_bDrawingsSpelled
= false;
127 m_xStartRange
= nullptr;
128 m_pStartDrawing
= nullptr;
129 m_bRestartDrawing
= false;
130 m_bTextObjectsCollected
= false;
131 m_aTextObjects
.clear();
132 m_bStartedInOther
= false;
133 pOtherCursor
.reset();
137 static void lcl_LeaveDrawText(SwWrtShell
& rSh
)
139 if(rSh
.GetDrawView())
141 rSh
.GetDrawView()->SdrEndTextEdit( true );
142 Point
aPt(LONG_MIN
, LONG_MIN
);
143 // go out of the frame
144 rSh
.SelectObj(aPt
, SW_LEAVE_FRAME
);
146 rSh
.GetView().AttrChangedNotify(&rSh
);
150 SwSpellDialogChildWindow::SwSpellDialogChildWindow (
151 vcl::Window
* _pParent
,
153 SfxBindings
* pBindings
,
154 SfxChildWinInfo
* /*pInfo*/)
155 : svx::SpellDialogChildWindow (
156 _pParent
, nId
, pBindings
)
157 , m_bIsGrammarCheckingOn(false)
158 , m_pSpellState(new SpellState
)
160 OUString
aPropName(UPN_IS_GRAMMAR_INTERACTIVE
);
161 SvtLinguConfig().GetProperty( aPropName
) >>= m_bIsGrammarCheckingOn
;
164 SwSpellDialogChildWindow::~SwSpellDialogChildWindow ()
166 SwWrtShell
* pWrtShell
= GetWrtShell_Impl();
167 if(!m_pSpellState
->m_bInitialCall
&& pWrtShell
)
168 pWrtShell
->SpellEnd();
169 delete m_pSpellState
;
172 SfxChildWinInfo
SwSpellDialogChildWindow::GetInfo() const
174 SfxChildWinInfo aInfo
= svx::SpellDialogChildWindow::GetInfo();
175 aInfo
.bVisible
= false;
179 svx::SpellPortions
SwSpellDialogChildWindow::GetNextWrongSentence(bool bRecheck
)
181 svx::SpellPortions aRet
;
182 SwWrtShell
* pWrtShell
= GetWrtShell_Impl();
187 // first set continuation point for spell/grammar check to the
188 // end of the current sentence
189 SwEditShell::MoveContinuationPosToEndOfCheckedSentence();
192 ShellMode eSelMode
= pWrtShell
->GetView().GetShellMode();
193 bool bDrawText
= ShellMode::DrawText
== eSelMode
;
195 ShellMode::TableText
== eSelMode
||
196 ShellMode::ListText
== eSelMode
||
197 ShellMode::TableListText
== eSelMode
||
198 ShellMode::Text
== eSelMode
;
199 // Writer text outside of the body
200 bool bOtherText
= false;
202 if( m_pSpellState
->m_bInitialCall
)
204 // if no text selection exists the cursor has to be set into the text
205 if(!bDrawText
&& !bNormalText
)
207 if(!MakeTextSelection_Impl(*pWrtShell
, eSelMode
))
211 // the selection type has to be checked again - both text types are possible
212 if(pWrtShell
->GetSelectionType() & SelectionType::DrawObjectEditMode
)
214 bNormalText
= !bDrawText
;
219 // set cursor to the start of the sentence
220 if(!pWrtShell
->HasSelection())
221 pWrtShell
->GoStartSentence();
224 pWrtShell
->ExpandToSentenceBorders();
225 m_pSpellState
->m_bStartedInSelection
= true;
227 // determine if the selection is outside of the body text
228 bOtherText
= !(pWrtShell
->GetFrameType(nullptr,true) & FrameTypeFlags::BODY
);
229 m_pSpellState
->m_SpellStartPosition
= bOtherText
? SPELL_START_OTHER
: SPELL_START_BODY
;
232 m_pSpellState
->pOtherCursor
.reset( new SwPaM(*pWrtShell
->GetCursor()->GetPoint()) );
233 m_pSpellState
->m_bStartedInOther
= true;
234 pWrtShell
->SpellStart( SwDocPositions::OtherStart
, SwDocPositions::OtherEnd
, SwDocPositions::Curr
);
238 SwPaM
* pCursor
= pWrtShell
->GetCursor();
239 // mark the start position only if not at start of doc
240 if(!pWrtShell
->IsStartOfDoc())
242 m_pSpellState
->m_xStartRange
=
243 SwXTextRange::CreateXTextRange(
244 *pWrtShell
->GetDoc(),
245 *pCursor
->Start(), pCursor
->End());
247 pWrtShell
->SpellStart( SwDocPositions::Start
, SwDocPositions::End
, SwDocPositions::Curr
);
252 SdrView
* pSdrView
= pWrtShell
->GetDrawView();
253 m_pSpellState
->m_SpellStartPosition
= SPELL_START_DRAWTEXT
;
254 m_pSpellState
->m_pStartDrawing
= pSdrView
->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj();
255 OutlinerView
* pOLV
= pSdrView
->GetTextEditOutlinerView();
256 // start checking at the top of the drawing object
257 pOLV
->SetSelection( ESelection() );
258 m_pSpellState
->m_aStartDrawingSelection
= ESelection();
260 Note: spelling in a selection only, or starting in a mid of a drawing object requires
261 further changes elsewhere. (Especially if it should work in sc and sd as well.)
262 The code below would only be part of the solution.
263 (Keeping it a as a comment for the time being)
264 ESelection aCurSel( pOLV->GetSelection() );
265 ESelection aSentenceSel( pOLV->GetEditView().GetEditEngine()->SelectSentence( aCurSel ) );
266 if (!aCurSel.HasRange())
268 aSentenceSel.nEndPara = aSentenceSel.nStartPara;
269 aSentenceSel.nEndPos = aSentenceSel.nStartPos;
271 pOLV->SetSelection( aSentenceSel );
272 m_pSpellState->m_aStartDrawingSelection = aSentenceSel;
276 m_pSpellState
->m_bInitialCall
= false;
280 // spell inside of the current draw text
281 if(!SpellDrawText_Impl(*pWrtShell
, aRet
))
283 if(!FindNextDrawTextError_Impl(*pWrtShell
) || !SpellDrawText_Impl(*pWrtShell
, aRet
))
285 lcl_LeaveDrawText(*pWrtShell
);
286 // now the drawings have been spelled
287 m_pSpellState
->m_bDrawingsSpelled
= true;
288 // the spelling continues at the other content
289 // if there's any that has not been spelled yet
290 if(!m_pSpellState
->m_bOtherSpelled
&& pWrtShell
->HasOtherCnt())
292 pWrtShell
->SpellStart(SwDocPositions::OtherStart
, SwDocPositions::OtherEnd
, SwDocPositions::OtherStart
);
293 if(!pWrtShell
->SpellSentence(aRet
, m_bIsGrammarCheckingOn
))
295 pWrtShell
->SpellEnd();
296 m_pSpellState
->m_bOtherSpelled
= true;
300 m_pSpellState
->m_bOtherSpelled
= true;
301 // if no result has been found try at the body text - completely
302 if(!m_pSpellState
->m_bBodySpelled
&& aRet
.empty())
304 pWrtShell
->SpellStart(SwDocPositions::Start
, SwDocPositions::End
, SwDocPositions::Start
);
305 if(!pWrtShell
->SpellSentence(aRet
, m_bIsGrammarCheckingOn
))
307 m_pSpellState
->m_bBodySpelled
= true;
308 pWrtShell
->SpellEnd();
317 // spell inside of the Writer text
318 if(!pWrtShell
->SpellSentence(aRet
, m_bIsGrammarCheckingOn
))
320 // if there is a selection (within body or header/footer text)
321 // then spell/grammar checking should not move outside of it.
322 if (!m_pSpellState
->m_bStartedInSelection
)
324 // find out which text has been spelled body or other
325 bOtherText
= !(pWrtShell
->GetFrameType(nullptr,true) & FrameTypeFlags::BODY
);
326 if(bOtherText
&& m_pSpellState
->m_bStartedInOther
&& m_pSpellState
->pOtherCursor
)
328 m_pSpellState
->m_bStartedInOther
= false;
329 pWrtShell
->SetSelection(*m_pSpellState
->pOtherCursor
);
330 pWrtShell
->SpellEnd();
331 m_pSpellState
->pOtherCursor
.reset();
332 pWrtShell
->SpellStart(SwDocPositions::OtherStart
, SwDocPositions::Curr
, SwDocPositions::OtherStart
);
333 (void)pWrtShell
->SpellSentence(aRet
, m_bIsGrammarCheckingOn
);
338 pWrtShell
->SpellEnd();
341 m_pSpellState
->m_bOtherSpelled
= true;
342 // has the body been spelled?
343 if(!m_pSpellState
->m_bBodySpelled
)
345 pWrtShell
->SpellStart(SwDocPositions::Start
, SwDocPositions::End
, SwDocPositions::Start
);
346 if(!pWrtShell
->SpellSentence(aRet
, m_bIsGrammarCheckingOn
))
348 m_pSpellState
->m_bBodySpelled
= true;
349 pWrtShell
->SpellEnd();
355 m_pSpellState
->m_bBodySpelled
= true;
356 if(!m_pSpellState
->m_bOtherSpelled
&& pWrtShell
->HasOtherCnt())
358 pWrtShell
->SpellStart(SwDocPositions::OtherStart
, SwDocPositions::OtherEnd
, SwDocPositions::OtherStart
);
359 if(!pWrtShell
->SpellSentence(aRet
, m_bIsGrammarCheckingOn
))
361 pWrtShell
->SpellEnd();
362 m_pSpellState
->m_bOtherSpelled
= true;
366 m_pSpellState
->m_bOtherSpelled
= true;
370 // search for a draw text object that contains error and spell it
372 (m_pSpellState
->m_bDrawingsSpelled
||
373 !FindNextDrawTextError_Impl(*pWrtShell
) || !SpellDrawText_Impl(*pWrtShell
, aRet
)))
375 lcl_LeaveDrawText(*pWrtShell
);
376 m_pSpellState
->m_bDrawingsSpelled
= true;
381 // now only the rest of the body text can be spelled -
382 // if the spelling started inside of the body
383 bool bCloseMessage
= true;
384 if(aRet
.empty() && !m_pSpellState
->m_bStartedInSelection
)
386 OSL_ENSURE(m_pSpellState
->m_bDrawingsSpelled
&&
387 m_pSpellState
->m_bOtherSpelled
&& m_pSpellState
->m_bBodySpelled
,
388 "not all parts of the document are already spelled");
389 if(m_pSpellState
->m_xStartRange
.is())
391 LockFocusNotification( true );
392 sal_uInt16 nRet
= ScopedVclPtrInstance
<MessageDialog
>(GetWindow(), SwResId(STR_QUERY_SPELL_CONTINUE
),
393 VclMessageType::Question
, VclButtonsType::YesNo
)->Execute();
396 SwUnoInternalPaM
aPam(*pWrtShell
->GetDoc());
397 if (::sw::XTextRangeToSwPaM(aPam
,
398 m_pSpellState
->m_xStartRange
))
400 pWrtShell
->SetSelection(aPam
);
401 pWrtShell
->SpellStart(SwDocPositions::Start
, SwDocPositions::Curr
, SwDocPositions::Start
);
402 if(!pWrtShell
->SpellSentence(aRet
, m_bIsGrammarCheckingOn
))
403 pWrtShell
->SpellEnd();
405 m_pSpellState
->m_xStartRange
= nullptr;
406 LockFocusNotification( false );
407 // take care that the now valid selection is stored
411 bCloseMessage
= false; // no closing message if a wrap around has been denied
418 LockFocusNotification( true );
419 OUString
sInfo(SwResId(STR_SPELLING_COMPLETED
));
421 vcl::Window
* pTemp
= GetWindow(); // temporary needed for g++ 3.3.5
422 ScopedVclPtrInstance
<MessageDialog
>(pTemp
, sInfo
, VclMessageType::Info
)->Execute();
423 LockFocusNotification( false );
424 // take care that the now valid selection is stored
432 void SwSpellDialogChildWindow::ApplyChangedSentence(const svx::SpellPortions
& rChanged
, bool bRecheck
)
434 SwWrtShell
* pWrtShell
= GetWrtShell_Impl();
435 OSL_ENSURE(!m_pSpellState
->m_bInitialCall
, "ApplyChangedSentence in initial call or after resume");
436 if(pWrtShell
&& !m_pSpellState
->m_bInitialCall
)
438 ShellMode eSelMode
= pWrtShell
->GetView().GetShellMode();
439 bool bDrawText
= ShellMode::DrawText
== eSelMode
;
441 ShellMode::TableText
== eSelMode
||
442 ShellMode::ListText
== eSelMode
||
443 ShellMode::TableListText
== eSelMode
||
444 ShellMode::Text
== eSelMode
;
446 // evaluate if the same sentence should be rechecked or not.
447 // Sentences that got grammar checked should always be rechecked in order
448 // to detect possible errors that get introduced with the changes
449 bRecheck
|= SwEditShell::HasLastSentenceGotGrammarChecked();
452 pWrtShell
->ApplyChangedSentence(rChanged
, bRecheck
);
455 SdrView
* pDrView
= pWrtShell
->GetDrawView();
456 SdrOutliner
*pOutliner
= pDrView
->GetTextEditOutliner();
457 pOutliner
->ApplyChangedSentence(pDrView
->GetTextEditOutlinerView()->GetEditView(), rChanged
, bRecheck
);
462 void SwSpellDialogChildWindow::AddAutoCorrection(
463 const OUString
& rOld
, const OUString
& rNew
, LanguageType eLanguage
)
465 SvxAutoCorrect
* pACorr
= SvxAutoCorrCfg::Get().GetAutoCorrect();
466 pACorr
->PutText( rOld
, rNew
, eLanguage
);
469 bool SwSpellDialogChildWindow::HasAutoCorrection()
474 bool SwSpellDialogChildWindow::HasGrammarChecking()
476 return SvtLinguConfig().HasGrammarChecker();
479 bool SwSpellDialogChildWindow::IsGrammarChecking()
481 return m_bIsGrammarCheckingOn
;
484 void SwSpellDialogChildWindow::SetGrammarChecking(bool bOn
)
488 m_bIsGrammarCheckingOn
= bOn
;
489 OUString
aPropName(UPN_IS_GRAMMAR_INTERACTIVE
);
490 SvtLinguConfig().SetProperty( aPropName
, aVal
);
491 // set current spell position to the start of the current sentence to
492 // continue with this sentence after grammar checking state has been changed
493 SwWrtShell
* pWrtShell
= GetWrtShell_Impl();
496 ShellMode eSelMode
= pWrtShell
->GetView().GetShellMode();
497 bool bDrawText
= ShellMode::DrawText
== eSelMode
;
499 ShellMode::TableText
== eSelMode
||
500 ShellMode::ListText
== eSelMode
||
501 ShellMode::TableListText
== eSelMode
||
502 ShellMode::Text
== eSelMode
;
504 SwEditShell::PutSpellingToSentenceStart();
507 SdrView
* pSdrView
= pWrtShell
->GetDrawView();
508 SdrOutliner
* pOutliner
= pSdrView
? pSdrView
->GetTextEditOutliner() : nullptr;
509 OSL_ENSURE(pOutliner
, "No Outliner in SwSpellDialogChildWindow::SetGrammarChecking");
512 pOutliner
->PutSpellingToSentenceStart( pSdrView
->GetTextEditOutlinerView()->GetEditView() );
518 void SwSpellDialogChildWindow::GetFocus()
520 if(m_pSpellState
->m_bLockFocus
)
522 bool bInvalidate
= false;
523 SwWrtShell
* pWrtShell
= GetWrtShell_Impl();
524 if(pWrtShell
&& !m_pSpellState
->m_bInitialCall
)
526 ShellMode eSelMode
= pWrtShell
->GetView().GetShellMode();
527 if(eSelMode
!= m_pSpellState
->m_eSelMode
)
529 // prevent initial invalidation
530 if(m_pSpellState
->m_bLostFocus
)
535 switch(m_pSpellState
->m_eSelMode
)
537 case ShellMode::Text
:
538 case ShellMode::ListText
:
539 case ShellMode::TableText
:
540 case ShellMode::TableListText
:
542 SwPaM
* pCursor
= pWrtShell
->GetCursor();
543 if(m_pSpellState
->m_pPointNode
!= &pCursor
->GetNode() ||
544 m_pSpellState
->m_pMarkNode
!= &pCursor
->GetNode(false)||
545 m_pSpellState
->m_nPointPos
!= pCursor
->GetPoint()->nContent
.GetIndex()||
546 m_pSpellState
->m_nMarkPos
!= pCursor
->GetMark()->nContent
.GetIndex())
550 case ShellMode::DrawText
:
552 SdrView
* pSdrView
= pWrtShell
->GetDrawView();
553 SdrOutliner
* pOutliner
= pSdrView
? pSdrView
->GetTextEditOutliner() : nullptr;
554 if(!pOutliner
|| m_pSpellState
->m_pOutliner
!= pOutliner
)
558 OutlinerView
* pOLV
= pSdrView
->GetTextEditOutlinerView();
559 OSL_ENSURE(pOLV
, "no OutlinerView in SwSpellDialogChildWindow::GetFocus()");
560 if(!pOLV
|| !m_pSpellState
->m_aESelection
.IsEqual(pOLV
->GetSelection()))
565 default: bInvalidate
= true;
574 InvalidateSpellDialog();
577 void SwSpellDialogChildWindow::LoseFocus()
579 // prevent initial invalidation
580 m_pSpellState
->m_bLostFocus
= true;
581 if(m_pSpellState
->m_bLockFocus
)
583 SwWrtShell
* pWrtShell
= GetWrtShell_Impl();
586 m_pSpellState
->m_eSelMode
= pWrtShell
->GetView().GetShellMode();
587 m_pSpellState
->m_pPointNode
= m_pSpellState
->m_pMarkNode
= nullptr;
588 m_pSpellState
->m_nPointPos
= m_pSpellState
->m_nMarkPos
= 0;
589 m_pSpellState
->m_pOutliner
= nullptr;
591 switch(m_pSpellState
->m_eSelMode
)
593 case ShellMode::Text
:
594 case ShellMode::ListText
:
595 case ShellMode::TableText
:
596 case ShellMode::TableListText
:
598 // store a node pointer and a pam-position to be able to check on next GetFocus();
599 SwPaM
* pCursor
= pWrtShell
->GetCursor();
600 m_pSpellState
->m_pPointNode
= &pCursor
->GetNode();
601 m_pSpellState
->m_pMarkNode
= &pCursor
->GetNode(false);
602 m_pSpellState
->m_nPointPos
= pCursor
->GetPoint()->nContent
.GetIndex();
603 m_pSpellState
->m_nMarkPos
= pCursor
->GetMark()->nContent
.GetIndex();
607 case ShellMode::DrawText
:
609 SdrView
* pSdrView
= pWrtShell
->GetDrawView();
610 SdrOutliner
* pOutliner
= pSdrView
->GetTextEditOutliner();
611 m_pSpellState
->m_pOutliner
= pOutliner
;
612 OutlinerView
* pOLV
= pSdrView
->GetTextEditOutlinerView();
613 OSL_ENSURE(pOutliner
&& pOLV
, "no Outliner/OutlinerView in SwSpellDialogChildWindow::LoseFocus()");
616 m_pSpellState
->m_aESelection
= pOLV
->GetSelection();
620 default:;// prevent warning
624 m_pSpellState
->m_eSelMode
= ShellMode::Object
;
627 void SwSpellDialogChildWindow::InvalidateSpellDialog()
629 SwWrtShell
* pWrtShell
= GetWrtShell_Impl();
630 if(!m_pSpellState
->m_bInitialCall
&& pWrtShell
)
631 pWrtShell
->SpellEnd(nullptr, false);
632 m_pSpellState
->Reset();
633 svx::SpellDialogChildWindow::InvalidateSpellDialog();
636 SwWrtShell
* SwSpellDialogChildWindow::GetWrtShell_Impl()
638 SfxDispatcher
* pDispatch
= GetBindings().GetDispatcher();
639 SwView
* pView
= nullptr;
642 sal_uInt16 nShellIdx
= 0;
644 while(nullptr != (pShell
= pDispatch
->GetShell(nShellIdx
++)))
645 if(dynamic_cast< const SwView
*>( pShell
) != nullptr)
647 pView
= static_cast<SwView
* >(pShell
);
651 return pView
? pView
->GetWrtShellPtr(): nullptr;
654 // set the cursor into the body text - necessary if any object is selected
655 // on start of the spelling dialog
656 bool SwSpellDialogChildWindow::MakeTextSelection_Impl(SwWrtShell
& rShell
, ShellMode eSelMode
)
658 SwView
& rView
= rShell
.GetView();
661 case ShellMode::Text
:
662 case ShellMode::ListText
:
663 case ShellMode::TableText
:
664 case ShellMode::TableListText
:
665 case ShellMode::DrawText
:
666 OSL_FAIL("text already active in SwSpellDialogChildWindow::MakeTextSelection_Impl()");
669 case ShellMode::Frame
:
671 rShell
.UnSelectFrame();
672 rShell
.LeaveSelFrameMode();
673 rView
.AttrChangedNotify(&rShell
);
677 case ShellMode::Draw
:
678 case ShellMode::DrawForm
:
679 case ShellMode::Bezier
:
680 if(FindNextDrawTextError_Impl(rShell
))
682 rView
.AttrChangedNotify(&rShell
);
685 SAL_FALLTHROUGH
; // to deselect the object
686 case ShellMode::Graphic
:
687 case ShellMode::Object
:
689 if ( rShell
.IsDrawCreate() )
691 rView
.GetDrawFuncPtr()->BreakCreate();
692 rView
.AttrChangedNotify(&rShell
);
694 else if ( rShell
.HasSelection() || rView
.IsDrawMode() )
696 SdrView
*pSdrView
= rShell
.GetDrawView();
697 if(pSdrView
&& pSdrView
->AreObjectsMarked() &&
698 pSdrView
->GetHdlList().GetFocusHdl())
700 const_cast<SdrHdlList
&>(pSdrView
->GetHdlList()).ResetFocusHdl();
704 rView
.LeaveDrawCreate();
705 Point
aPt(LONG_MIN
, LONG_MIN
);
706 // go out of the frame
707 rShell
.SelectObj(aPt
, SW_LEAVE_FRAME
);
708 SfxBindings
& rBind
= rView
.GetViewFrame()->GetBindings();
709 rBind
.Invalidate( SID_ATTR_SIZE
);
710 rShell
.EnterStdMode();
711 rView
.AttrChangedNotify(&rShell
);
716 default:; // prevent warning
721 // select the next draw text object that has a spelling error
722 bool SwSpellDialogChildWindow::FindNextDrawTextError_Impl(SwWrtShell
& rSh
)
724 bool bNextDoc
= false;
725 SdrView
* pDrView
= rSh
.GetDrawView();
728 SwView
& rView
= rSh
.GetView();
729 SwDoc
* pDoc
= rView
.GetDocShell()->GetDoc();
730 const SdrMarkList
& rMarkList
= pDrView
->GetMarkedObjectList();
731 // start at the current draw object - if there is any selected
732 SdrTextObj
* pCurrentTextObj
= nullptr;
733 if ( rMarkList
.GetMarkCount() == 1 )
735 SdrObject
* pObj
= rMarkList
.GetMark(0)->GetMarkedSdrObj();
736 if( pObj
&& dynamic_cast< const SdrTextObj
*>( pObj
) != nullptr )
737 pCurrentTextObj
= static_cast<SdrTextObj
*>(pObj
);
739 // at first fill the list of drawing objects
740 if(!m_pSpellState
->m_bTextObjectsCollected
)
742 m_pSpellState
->m_bTextObjectsCollected
= true;
743 std::list
<SdrTextObj
*> aTextObjs
;
744 SwDrawContact::GetTextObjectsFromFormat( aTextObjs
, pDoc
);
747 m_pSpellState
->m_aTextObjects
.remove(pCurrentTextObj
);
748 m_pSpellState
->m_aTextObjects
.push_back(pCurrentTextObj
);
751 if(!m_pSpellState
->m_aTextObjects
.empty())
753 Reference
< XSpellChecker1
> xSpell( GetSpellChecker() );
754 while(!bNextDoc
&& !m_pSpellState
->m_aTextObjects
.empty())
756 std::list
<SdrTextObj
*>::iterator aStart
= m_pSpellState
->m_aTextObjects
.begin();
757 SdrTextObj
* pTextObj
= *aStart
;
758 if(m_pSpellState
->m_pStartDrawing
== pTextObj
)
759 m_pSpellState
->m_bRestartDrawing
= true;
760 m_pSpellState
->m_aTextObjects
.erase(aStart
);
761 OutlinerParaObject
* pParaObj
= pTextObj
->GetOutlinerParaObject();
764 bool bHasSpellError
= false;
766 SdrOutliner
aTmpOutliner(pDoc
->getIDocumentDrawModelAccess().GetDrawModel()->
767 GetDrawOutliner().GetEmptyItemSet().GetPool(),
768 OutlinerMode::TextObject
);
769 aTmpOutliner
.SetRefDevice( pDoc
->getIDocumentDeviceAccess().getPrinter( false ) );
770 MapMode
aMapMode (MapUnit::MapTwip
);
771 aTmpOutliner
.SetRefMapMode(aMapMode
);
772 aTmpOutliner
.SetPaperSize( pTextObj
->GetLogicRect().GetSize() );
773 aTmpOutliner
.SetSpeller( xSpell
);
775 std::unique_ptr
<OutlinerView
> pOutlView( new OutlinerView( &aTmpOutliner
, &(rView
.GetEditWin()) ) );
776 pOutlView
->GetOutliner()->SetRefDevice( rSh
.getIDocumentDeviceAccess().getPrinter( false ) );
777 aTmpOutliner
.InsertView( pOutlView
.get() );
780 tools::Rectangle
aRect( aPt
, aSize
);
781 pOutlView
->SetOutputArea( aRect
);
782 aTmpOutliner
.SetText( *pParaObj
);
783 aTmpOutliner
.ClearModifyFlag();
784 bHasSpellError
= EESpellState::Ok
!= aTmpOutliner
.HasSpellErrors();
785 aTmpOutliner
.RemoveView( pOutlView
.get() );
789 // now the current one has to be deselected
791 pDrView
->SdrEndTextEdit( true );
792 // and the found one should be activated
793 rSh
.MakeVisible(pTextObj
->GetLogicRect());
795 rSh
.SelectObj( aTmp
, 0, pTextObj
);
796 SdrPageView
* pPV
= pDrView
->GetSdrPageView();
797 rView
.BeginTextEdit( pTextObj
, pPV
, &rView
.GetEditWin(), false, true );
798 rView
.AttrChangedNotify(&rSh
);
807 bool SwSpellDialogChildWindow::SpellDrawText_Impl(SwWrtShell
& rSh
, svx::SpellPortions
& rPortions
)
810 SdrView
* pSdrView
= rSh
.GetDrawView();
811 SdrOutliner
* pOutliner
= pSdrView
? pSdrView
->GetTextEditOutliner() : nullptr;
812 OSL_ENSURE(pOutliner
, "No Outliner in SwSpellDialogChildWindow::SpellDrawText_Impl");
815 bRet
= pOutliner
->SpellSentence(pSdrView
->GetTextEditOutlinerView()->GetEditView(), rPortions
);
816 // find out if the current selection is in the first spelled drawing object
817 // and behind the initial selection
818 if(bRet
&& m_pSpellState
->m_bRestartDrawing
)
820 OutlinerView
* pOLV
= pSdrView
->GetTextEditOutlinerView();
821 ESelection aCurrentSelection
= pOLV
->GetSelection();
822 if(m_pSpellState
->m_aStartDrawingSelection
.nEndPara
< aCurrentSelection
.nEndPara
||
823 (m_pSpellState
->m_aStartDrawingSelection
.nEndPara
== aCurrentSelection
.nEndPara
&&
824 m_pSpellState
->m_aStartDrawingSelection
.nEndPos
< aCurrentSelection
.nEndPos
))
834 void SwSpellDialogChildWindow::LockFocusNotification(bool bLock
)
836 OSL_ENSURE(m_pSpellState
->m_bLockFocus
!= bLock
, "invalid locking - no change of state");
837 m_pSpellState
->m_bLockFocus
= bLock
;
840 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */