tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / spelldialog.cxx
blob8beba2e2d29109ac1bb0b0a80f169a939bb152bd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <spelldialog.hxx>
22 #include <sfx2/bindings.hxx>
23 #include <svx/svxids.hrc>
24 #include <editeng/editstat.hxx>
25 #include <editeng/editview.hxx>
26 #include <editeng/unolingu.hxx>
27 #include <selectionstate.hxx>
28 #include <osl/diagnose.h>
30 #include <spelleng.hxx>
31 #include <tabvwsh.hxx>
32 #include <docsh.hxx>
33 #include <scmod.hxx>
34 #include <editable.hxx>
35 #include <undoblk.hxx>
36 #include <gridwin.hxx>
37 #include <refupdatecontext.hxx>
38 #include <vcl/svapp.hxx>
40 SFX_IMPL_CHILDWINDOW_WITHID( ScSpellDialogChildWindow, SID_SPELL_DIALOG )
42 ScSpellDialogChildWindow::ScSpellDialogChildWindow( vcl::Window* pParentP, sal_uInt16 nId,
43 SfxBindings* pBindings, SAL_UNUSED_PARAMETER SfxChildWinInfo* /*pInfo*/ ) :
44 svx::SpellDialogChildWindow( pParentP, nId, pBindings ),
45 mpViewShell( nullptr ),
46 mpViewData( nullptr ),
47 mpDocShell( nullptr ),
48 mpDoc( nullptr ),
49 mbNeedNextObj( false ),
50 mbOldIdleEnabled(true)
52 Init();
55 ScSpellDialogChildWindow::~ScSpellDialogChildWindow()
57 Reset();
60 SfxChildWinInfo ScSpellDialogChildWindow::GetInfo() const
62 return svx::SpellDialogChildWindow::GetInfo();
65 void ScSpellDialogChildWindow::InvalidateSpellDialog()
67 svx::SpellDialogChildWindow::InvalidateSpellDialog();
70 // protected ------------------------------------------------------------------
72 svx::SpellPortions ScSpellDialogChildWindow::GetNextWrongSentence( bool /*bRecheck*/ )
74 svx::SpellPortions aPortions;
75 if( mxEngine && mpViewData )
77 if( EditView* pEditView = mpViewData->GetSpellingView() )
79 // edit engine handles cell iteration internally
82 if( mbNeedNextObj )
83 mxEngine->SpellNextDocument();
84 mbNeedNextObj = !mxEngine->IsFinished() && !mxEngine->SpellSentence( *pEditView, aPortions );
86 while( mbNeedNextObj );
89 return aPortions;
92 void ScSpellDialogChildWindow::ApplyChangedSentence( const svx::SpellPortions& rChanged, bool bRecheck )
94 if( mxEngine && mpViewData )
95 if( EditView* pEditView = mpViewData->GetSpellingView() )
97 mxEngine->ApplyChangedSentence( *pEditView, rChanged, bRecheck );
99 // Reset the spell checking results to clear the markers.
100 mpViewData->GetActiveWin()->ResetAutoSpell();
104 void ScSpellDialogChildWindow::GetFocus()
106 SolarMutexGuard aGuard;
108 if( IsSelectionChanged() )
110 Reset();
111 InvalidateSpellDialog();
112 Init();
116 void ScSpellDialogChildWindow::LoseFocus()
120 // private --------------------------------------------------------------------
122 void ScSpellDialogChildWindow::Reset()
124 if( mpViewShell && (mpViewShell == dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() )) )
126 if( mxEngine && mxEngine->IsAnyModified() )
128 const ScAddress& rCursor = mxOldSel->GetCellCursor();
129 SCTAB nTab = rCursor.Tab();
130 SCCOL nOldCol = rCursor.Col();
131 SCROW nOldRow = rCursor.Row();
132 SCCOL nNewCol = mpViewData->GetCurX();
133 SCROW nNewRow = mpViewData->GetCurY();
134 mpDocShell->GetUndoManager()->AddUndoAction( std::make_unique<ScUndoConversion>(
135 mpDocShell, mpViewData->GetMarkData(),
136 nOldCol, nOldRow, nTab, std::move(mxUndoDoc),
137 nNewCol, nNewRow, nTab, std::move(mxRedoDoc),
138 ScConversionParam( SC_CONVERSION_SPELLCHECK ) ) );
140 sc::SetFormulaDirtyContext aCxt;
141 mpDoc->SetAllFormulasDirty(aCxt);
143 mpDocShell->SetDocumentModified();
146 mpViewData->SetSpellingView( nullptr );
147 mpViewShell->KillEditView( true );
148 mpDocShell->PostPaintGridAll();
149 mpViewShell->UpdateInputHandler();
150 mpDoc->EnableIdle(mbOldIdleEnabled);
152 mxEngine.reset();
153 mxUndoDoc.reset();
154 mxRedoDoc.reset();
155 mxOldSel.reset();
156 mxOldRangeList.clear();
157 mpViewShell = nullptr;
158 mpViewData = nullptr;
159 mpDocShell = nullptr;
160 mpDoc = nullptr;
161 mbNeedNextObj = false;
162 mbOldIdleEnabled = true;
165 void ScSpellDialogChildWindow::Init()
167 if( mpViewShell )
168 return;
169 if( (mpViewShell = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() )) == nullptr )
170 return;
172 mpViewData = &mpViewShell->GetViewData();
174 // exit edit mode - TODO support spelling in edit mode
175 if( mpViewData->HasEditView( mpViewData->GetActivePart() ) )
176 ScModule::get()->InputEnterHandler();
178 mxOldSel.reset( new ScSelectionState( *mpViewData ) );
180 mpDocShell = mpViewData->GetDocShell();
181 mpDoc = &mpDocShell->GetDocument();
183 const ScAddress& rCursor = mxOldSel->GetCellCursor();
184 SCCOL nCol = rCursor.Col();
185 SCROW nRow = rCursor.Row();
186 SCTAB nTab = rCursor.Tab();
188 ScMarkData& rMarkData = mpViewData->GetMarkData();
190 mxOldRangeList = new ScRangeList;
191 rMarkData.FillRangeListWithMarks(mxOldRangeList.get(), true);
193 rMarkData.MarkToMulti();
195 switch( mxOldSel->GetSelectionType() )
197 case SC_SELECTTYPE_NONE:
198 case SC_SELECTTYPE_SHEET:
200 // test if there is something editable
201 ScEditableTester aTester( *mpDoc, rMarkData );
202 if( !aTester.IsEditable() )
204 // #i85751# Don't show an ErrorMessage here, because the vcl
205 // parent of the InfoBox is not fully initialized yet.
206 // This leads to problems in the modality behaviour of the
207 // ScSpellDialogChildWindow.
209 //mpViewShell->ErrorMessage( aTester.GetMessageId() );
210 return;
213 break;
215 // edit mode exited, see TODO above
216 // case SC_SELECTTYPE_EDITCELL:
217 // break;
219 default:
220 OSL_FAIL( "ScSpellDialogChildWindow::Init - unknown selection type" );
223 mbOldIdleEnabled = mpDoc->IsIdleEnabled();
224 mpDoc->EnableIdle(false); // stop online spelling
226 // *** create Undo/Redo documents *** -------------------------------------
228 mxUndoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
229 mxUndoDoc->InitUndo( *mpDoc, nTab, nTab );
230 mxRedoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
231 mxRedoDoc->InitUndo( *mpDoc, nTab, nTab );
233 if ( rMarkData.GetSelectCount() > 1 )
235 for (const auto& rTab : rMarkData)
237 if( rTab != nTab )
239 mxUndoDoc->AddUndoTab( rTab, rTab );
240 mxRedoDoc->AddUndoTab( rTab, rTab );
245 // *** create and init the edit engine *** --------------------------------
247 mxEngine.reset( new ScSpellingEngine(
248 mpDoc->GetEnginePool(), *mpViewData, mxUndoDoc.get(), mxRedoDoc.get(), LinguMgr::GetSpellChecker() ) );
249 mxEngine->SetRefDevice( mpViewData->GetActiveWin()->GetOutDev() );
251 mpViewShell->MakeEditView( mxEngine.get(), nCol, nRow );
252 EditView* pEditView = mpViewData->GetEditView( mpViewData->GetActivePart() );
253 mpViewData->SetSpellingView( pEditView );
254 tools::Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
255 pEditView->SetOutputArea( aRect );
256 mxEngine->SetControlWord( EEControlBits::USECHARATTRIBS );
257 mxEngine->EnableUndo( false );
258 mxEngine->SetPaperSize( aRect.GetSize() );
259 mxEngine->SetTextCurrentDefaults( OUString() );
260 mxEngine->ClearModifyFlag();
262 mbNeedNextObj = true;
265 bool ScSpellDialogChildWindow::IsSelectionChanged()
267 if (!mxOldRangeList || !mpViewShell
268 || (mpViewShell != dynamic_cast<ScTabViewShell*>(SfxViewShell::Current())))
269 return true;
271 if( EditView* pEditView = mpViewData->GetSpellingView() )
272 if (&pEditView->getEditEngine() != mxEngine.get())
273 return true;
275 ScRangeList aCurrentRangeList;
276 mpViewData->GetMarkData().FillRangeListWithMarks(&aCurrentRangeList, true);
278 return (*mxOldRangeList != aCurrentRangeList);
281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */