Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / view / spelldialog.cxx
blobdb43544df45ef7089b26ca44e35867161f375a43
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/app.hxx>
23 #include <sfx2/bindings.hxx>
24 #include <sfx2/dispatch.hxx>
25 #include <svx/svxids.hrc>
26 #include <editeng/editstat.hxx>
27 #include <editeng/editview.hxx>
28 #include <editeng/unolingu.hxx>
29 #include "selectionstate.hxx"
31 #include "spelleng.hxx"
32 #include "tabvwsh.hxx"
33 #include "docsh.hxx"
34 #include "scmod.hxx"
35 #include "editable.hxx"
36 #include "undoblk.hxx"
37 #include <gridwin.hxx>
38 #include <refupdatecontext.hxx>
40 SFX_IMPL_CHILDWINDOW_WITHID( ScSpellDialogChildWindow, SID_SPELL_DIALOG )
42 ScSpellDialogChildWindow::ScSpellDialogChildWindow( vcl::Window* pParentP, sal_uInt16 nId,
43 SfxBindings* pBindings, SfxChildWinInfo* pInfo ) :
44 svx::SpellDialogChildWindow( pParentP, nId, pBindings, pInfo ),
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.get() && 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, false );
86 while( mbNeedNextObj );
89 return aPortions;
92 void ScSpellDialogChildWindow::ApplyChangedSentence( const svx::SpellPortions& rChanged, bool bRecheck )
94 if( mxEngine.get() && mpViewData )
95 if( EditView* pEditView = mpViewData->GetSpellingView() )
96 mxEngine->ApplyChangedSentence( *pEditView, rChanged, bRecheck );
99 void ScSpellDialogChildWindow::GetFocus()
101 if( IsSelectionChanged() )
103 Reset();
104 InvalidateSpellDialog();
105 Init();
109 void ScSpellDialogChildWindow::LoseFocus()
113 // private --------------------------------------------------------------------
115 void ScSpellDialogChildWindow::Reset()
117 if( mpViewShell && (mpViewShell == dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() )) )
119 if( mxEngine.get() && mxEngine->IsAnyModified() )
121 const ScAddress& rCursor = mxOldSel->GetCellCursor();
122 SCTAB nTab = rCursor.Tab();
123 SCCOL nOldCol = rCursor.Col();
124 SCROW nOldRow = rCursor.Row();
125 SCCOL nNewCol = mpViewData->GetCurX();
126 SCROW nNewRow = mpViewData->GetCurY();
127 mpDocShell->GetUndoManager()->AddUndoAction( new ScUndoConversion(
128 mpDocShell, mpViewData->GetMarkData(),
129 nOldCol, nOldRow, nTab, mxUndoDoc.release(),
130 nNewCol, nNewRow, nTab, mxRedoDoc.release(),
131 ScConversionParam( SC_CONVERSION_SPELLCHECK ) ) );
133 sc::SetFormulaDirtyContext aCxt;
134 mpDoc->SetAllFormulasDirty(aCxt);
136 mpDocShell->SetDocumentModified();
139 mpViewData->SetSpellingView( nullptr );
140 mpViewShell->KillEditView( true );
141 mpDocShell->PostPaintGridAll();
142 mpViewShell->UpdateInputHandler();
143 mpDoc->EnableIdle(mbOldIdleEnabled);
145 mxEngine.reset();
146 mxUndoDoc.reset();
147 mxRedoDoc.reset();
148 mxOldSel.reset();
149 mxOldRangeList.reset();
150 mpViewShell = nullptr;
151 mpViewData = nullptr;
152 mpDocShell = nullptr;
153 mpDoc = nullptr;
154 mbNeedNextObj = false;
155 mbOldIdleEnabled = true;
158 void ScSpellDialogChildWindow::Init()
160 if( mpViewShell )
161 return;
162 if( (mpViewShell = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() )) == nullptr )
163 return;
165 mpViewData = &mpViewShell->GetViewData();
167 // exit edit mode - TODO support spelling in edit mode
168 if( mpViewData->HasEditView( mpViewData->GetActivePart() ) )
169 SC_MOD()->InputEnterHandler();
171 mxOldSel.reset( new ScSelectionState( *mpViewData ) );
173 mpDocShell = mpViewData->GetDocShell();
174 mpDoc = &mpDocShell->GetDocument();
176 const ScAddress& rCursor = mxOldSel->GetCellCursor();
177 SCCOL nCol = rCursor.Col();
178 SCROW nRow = rCursor.Row();
179 SCTAB nTab = rCursor.Tab();
181 ScMarkData& rMarkData = mpViewData->GetMarkData();
183 mxOldRangeList.reset(new ScRangeList);
184 rMarkData.FillRangeListWithMarks(mxOldRangeList.get(), true);
186 rMarkData.MarkToMulti();
188 switch( mxOldSel->GetSelectionType() )
190 case SC_SELECTTYPE_NONE:
191 case SC_SELECTTYPE_SHEET:
193 // test if there is something editable
194 ScEditableTester aTester( mpDoc, rMarkData );
195 if( !aTester.IsEditable() )
197 // #i85751# Don't show a ErrorMessage here, because the vcl
198 // parent of the InfoBox is not fully initialized yet.
199 // This leads to problems in the modality behaviour of the
200 // ScSpellDialogChildWindow.
202 //mpViewShell->ErrorMessage( aTester.GetMessageId() );
203 return;
206 break;
208 // edit mode exited, see TODO above
209 // case SC_SELECTTYPE_EDITCELL:
210 // break;
212 default:
213 OSL_FAIL( "ScSpellDialogChildWindow::Init - unknown selection type" );
216 mbOldIdleEnabled = mpDoc->IsIdleEnabled();
217 mpDoc->EnableIdle(false); // stop online spelling
219 // *** create Undo/Redo documents *** -------------------------------------
221 mxUndoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
222 mxUndoDoc->InitUndo( mpDoc, nTab, nTab );
223 mxRedoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
224 mxRedoDoc->InitUndo( mpDoc, nTab, nTab );
226 if ( rMarkData.GetSelectCount() > 1 )
228 ScMarkData::iterator itr = rMarkData.begin(), itrEnd = rMarkData.end();
229 for (; itr != itrEnd; ++itr)
231 if( *itr != nTab )
233 mxUndoDoc->AddUndoTab( *itr, *itr );
234 mxRedoDoc->AddUndoTab( *itr, *itr );
239 // *** create and init the edit engine *** --------------------------------
241 mxEngine.reset( new ScSpellingEngine(
242 mpDoc->GetEnginePool(), *mpViewData, mxUndoDoc.get(), mxRedoDoc.get(), LinguMgr::GetSpellChecker() ) );
243 mxEngine->SetRefDevice( mpViewData->GetActiveWin() );
245 mpViewShell->MakeEditView( mxEngine.get(), nCol, nRow );
246 EditView* pEditView = mpViewData->GetEditView( mpViewData->GetActivePart() );
247 mpViewData->SetSpellingView( pEditView );
248 Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
249 pEditView->SetOutputArea( aRect );
250 mxEngine->SetControlWord( EEControlBits::USECHARATTRIBS );
251 mxEngine->EnableUndo( false );
252 mxEngine->SetPaperSize( aRect.GetSize() );
253 mxEngine->SetText( EMPTY_OUSTRING );
254 mxEngine->ClearModifyFlag();
256 mbNeedNextObj = true;
259 bool ScSpellDialogChildWindow::IsSelectionChanged()
261 if( !mxOldRangeList.get() || !mpViewShell || (mpViewShell != dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() )) )
262 return true;
264 if( EditView* pEditView = mpViewData->GetSpellingView() )
265 if( pEditView->GetEditEngine() != mxEngine.get() )
266 return true;
268 ScRangeList aCurrentRangeList;
269 mpViewData->GetMarkData().FillRangeListWithMarks(&aCurrentRangeList, true);
271 return (*mxOldRangeList != aCurrentRangeList);
274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */