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 .
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"
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
),
49 mbNeedNextObj( false ),
50 mbOldIdleEnabled(true)
55 ScSpellDialogChildWindow::~ScSpellDialogChildWindow()
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
83 mxEngine
->SpellNextDocument();
84 mbNeedNextObj
= !mxEngine
->IsFinished() && !mxEngine
->SpellSentence( *pEditView
, aPortions
, false );
86 while( mbNeedNextObj
);
89 // finished? - close the spelling dialog
90 if( mxEngine
->IsFinished() )
91 GetBindings().GetDispatcher()->Execute( SID_SPELL_DIALOG
, SfxCallMode::ASYNCHRON
);
96 void ScSpellDialogChildWindow::ApplyChangedSentence( const svx::SpellPortions
& rChanged
, bool bRecheck
)
98 if( mxEngine
.get() && mpViewData
)
99 if( EditView
* pEditView
= mpViewData
->GetSpellingView() )
100 mxEngine
->ApplyChangedSentence( *pEditView
, rChanged
, bRecheck
);
103 void ScSpellDialogChildWindow::GetFocus()
105 if( IsSelectionChanged() )
108 InvalidateSpellDialog();
113 void ScSpellDialogChildWindow::LoseFocus()
117 // private --------------------------------------------------------------------
119 void ScSpellDialogChildWindow::Reset()
121 if( mpViewShell
&& (mpViewShell
== PTR_CAST( ScTabViewShell
, SfxViewShell::Current() )) )
123 if( mxEngine
.get() && mxEngine
->IsAnyModified() )
125 const ScAddress
& rCursor
= mxOldSel
->GetCellCursor();
126 SCTAB nTab
= rCursor
.Tab();
127 SCCOL nOldCol
= rCursor
.Col();
128 SCROW nOldRow
= rCursor
.Row();
129 SCCOL nNewCol
= mpViewData
->GetCurX();
130 SCROW nNewRow
= mpViewData
->GetCurY();
131 mpDocShell
->GetUndoManager()->AddUndoAction( new ScUndoConversion(
132 mpDocShell
, mpViewData
->GetMarkData(),
133 nOldCol
, nOldRow
, nTab
, mxUndoDoc
.release(),
134 nNewCol
, nNewRow
, nTab
, mxRedoDoc
.release(),
135 ScConversionParam( SC_CONVERSION_SPELLCHECK
) ) );
137 sc::SetFormulaDirtyContext aCxt
;
138 mpDoc
->SetAllFormulasDirty(aCxt
);
140 mpDocShell
->SetDocumentModified();
143 mpViewData
->SetSpellingView( 0 );
144 mpViewShell
->KillEditView( true );
145 mpDocShell
->PostPaintGridAll();
146 mpViewShell
->UpdateInputHandler();
147 mpDoc
->EnableIdle(mbOldIdleEnabled
);
153 mxOldRangeList
.reset();
158 mbNeedNextObj
= false;
159 mbOldIdleEnabled
= true;
162 void ScSpellDialogChildWindow::Init()
166 if( (mpViewShell
= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() )) == 0 )
169 mpViewData
= &mpViewShell
->GetViewData();
171 // exit edit mode - TODO support spelling in edit mode
172 if( mpViewData
->HasEditView( mpViewData
->GetActivePart() ) )
173 SC_MOD()->InputEnterHandler();
175 mxOldSel
.reset( new ScSelectionState( *mpViewData
) );
177 mpDocShell
= mpViewData
->GetDocShell();
178 mpDoc
= &mpDocShell
->GetDocument();
180 const ScAddress
& rCursor
= mxOldSel
->GetCellCursor();
181 SCCOL nCol
= rCursor
.Col();
182 SCROW nRow
= rCursor
.Row();
183 SCTAB nTab
= rCursor
.Tab();
185 ScMarkData
& rMarkData
= mpViewData
->GetMarkData();
187 mxOldRangeList
.reset(new ScRangeList
);
188 rMarkData
.FillRangeListWithMarks(mxOldRangeList
.get(), true);
190 rMarkData
.MarkToMulti();
192 switch( mxOldSel
->GetSelectionType() )
194 case SC_SELECTTYPE_NONE
:
195 case SC_SELECTTYPE_SHEET
:
197 // test if there is something editable
198 ScEditableTester
aTester( mpDoc
, rMarkData
);
199 if( !aTester
.IsEditable() )
201 // #i85751# Don't show a ErrorMessage here, because the vcl
202 // parent of the InfoBox is not fully initialized yet.
203 // This leads to problems in the modality behaviour of the
204 // ScSpellDialogChildWindow.
206 //mpViewShell->ErrorMessage( aTester.GetMessageId() );
212 // edit mode exited, see TODO above
213 // case SC_SELECTTYPE_EDITCELL:
217 OSL_FAIL( "ScSpellDialogChildWindow::Init - unknown selection type" );
220 mbOldIdleEnabled
= mpDoc
->IsIdleEnabled();
221 mpDoc
->EnableIdle(false); // stop online spelling
223 // *** create Undo/Redo documents *** -------------------------------------
225 mxUndoDoc
.reset( new ScDocument( SCDOCMODE_UNDO
) );
226 mxUndoDoc
->InitUndo( mpDoc
, nTab
, nTab
);
227 mxRedoDoc
.reset( new ScDocument( SCDOCMODE_UNDO
) );
228 mxRedoDoc
->InitUndo( mpDoc
, nTab
, nTab
);
230 if ( rMarkData
.GetSelectCount() > 1 )
232 ScMarkData::iterator itr
= rMarkData
.begin(), itrEnd
= rMarkData
.end();
233 for (; itr
!= itrEnd
; ++itr
)
237 mxUndoDoc
->AddUndoTab( *itr
, *itr
);
238 mxRedoDoc
->AddUndoTab( *itr
, *itr
);
243 // *** create and init the edit engine *** --------------------------------
245 mxEngine
.reset( new ScSpellingEngine(
246 mpDoc
->GetEnginePool(), *mpViewData
, mxUndoDoc
.get(), mxRedoDoc
.get(), LinguMgr::GetSpellChecker() ) );
247 mxEngine
->SetRefDevice( mpViewData
->GetActiveWin() );
249 mpViewShell
->MakeEditView( mxEngine
.get(), nCol
, nRow
);
250 EditView
* pEditView
= mpViewData
->GetEditView( mpViewData
->GetActivePart() );
251 mpViewData
->SetSpellingView( pEditView
);
252 Rectangle
aRect( Point( 0, 0 ), Point( 0, 0 ) );
253 pEditView
->SetOutputArea( aRect
);
254 mxEngine
->SetControlWord( EEControlBits::USECHARATTRIBS
);
255 mxEngine
->EnableUndo( false );
256 mxEngine
->SetPaperSize( aRect
.GetSize() );
257 mxEngine
->SetText( EMPTY_OUSTRING
);
258 mxEngine
->ClearModifyFlag();
260 mbNeedNextObj
= true;
263 bool ScSpellDialogChildWindow::IsSelectionChanged()
265 if( !mxOldRangeList
.get() || !mpViewShell
|| (mpViewShell
!= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() )) )
268 if( EditView
* pEditView
= mpViewData
->GetSpellingView() )
269 if( pEditView
->GetEditEngine() != mxEngine
.get() )
272 ScRangeList aCurrentRangeList
;
273 mpViewData
->GetMarkData().FillRangeListWithMarks(&aCurrentRangeList
, true);
275 return (*mxOldRangeList
!= aCurrentRangeList
);
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */