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"
38 // ============================================================================
40 SFX_IMPL_CHILDWINDOW_WITHID( ScSpellDialogChildWindow
, SID_SPELL_DIALOG
)
42 ScSpellDialogChildWindow::ScSpellDialogChildWindow( 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
, SFX_CALLMODE_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 mpDocShell
->SetDocumentModified();
140 mpViewData
->SetSpellingView( 0 );
141 mpViewShell
->KillEditView( sal_True
);
142 mpDocShell
->PostPaintGridAll();
143 mpViewShell
->UpdateInputHandler();
144 mpDoc
->EnableIdle(mbOldIdleEnabled
);
150 mxOldRangeList
.reset();
155 mbNeedNextObj
= false;
156 mbOldIdleEnabled
= true;
159 void ScSpellDialogChildWindow::Init()
163 if( (mpViewShell
= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() )) == 0 )
166 mpViewData
= mpViewShell
->GetViewData();
168 // exit edit mode - TODO support spelling in edit mode
169 if( mpViewData
->HasEditView( mpViewData
->GetActivePart() ) )
170 SC_MOD()->InputEnterHandler();
172 mxOldSel
.reset( new ScSelectionState( *mpViewData
) );
174 mpDocShell
= mpViewData
->GetDocShell();
175 mpDoc
= mpDocShell
->GetDocument();
177 const ScAddress
& rCursor
= mxOldSel
->GetCellCursor();
178 SCCOL nCol
= rCursor
.Col();
179 SCROW nRow
= rCursor
.Row();
180 SCTAB nTab
= rCursor
.Tab();
182 ScMarkData
& rMarkData
= mpViewData
->GetMarkData();
184 mxOldRangeList
.reset(new ScRangeList
);
185 rMarkData
.FillRangeListWithMarks(mxOldRangeList
.get(), true);
187 rMarkData
.MarkToMulti();
189 switch( mxOldSel
->GetSelectionType() )
191 case SC_SELECTTYPE_NONE
:
192 case SC_SELECTTYPE_SHEET
:
194 // test if there is something editable
195 ScEditableTester
aTester( mpDoc
, rMarkData
);
196 if( !aTester
.IsEditable() )
198 // #i85751# Don't show a ErrorMessage here, because the vcl
199 // parent of the InfoBox is not fully initialized yet.
200 // This leads to problems in the modality behaviour of the
201 // ScSpellDialogChildWindow.
203 //mpViewShell->ErrorMessage( aTester.GetMessageId() );
209 // edit mode exited, see TODO above
210 // case SC_SELECTTYPE_EDITCELL:
214 OSL_FAIL( "ScSpellDialogChildWindow::Init - unknown selection type" );
217 mbOldIdleEnabled
= mpDoc
->IsIdleEnabled();
218 mpDoc
->EnableIdle(false); // stop online spelling
220 // *** create Undo/Redo documents *** -------------------------------------
222 mxUndoDoc
.reset( new ScDocument( SCDOCMODE_UNDO
) );
223 mxUndoDoc
->InitUndo( mpDoc
, nTab
, nTab
);
224 mxRedoDoc
.reset( new ScDocument( SCDOCMODE_UNDO
) );
225 mxRedoDoc
->InitUndo( mpDoc
, nTab
, nTab
);
227 if ( rMarkData
.GetSelectCount() > 1 )
229 ScMarkData::iterator itr
= rMarkData
.begin(), itrEnd
= rMarkData
.end();
230 for (; itr
!= itrEnd
; ++itr
)
234 mxUndoDoc
->AddUndoTab( *itr
, *itr
);
235 mxRedoDoc
->AddUndoTab( *itr
, *itr
);
240 // *** create and init the edit engine *** --------------------------------
242 mxEngine
.reset( new ScSpellingEngine(
243 mpDoc
->GetEnginePool(), *mpViewData
, mxUndoDoc
.get(), mxRedoDoc
.get(), LinguMgr::GetSpellChecker() ) );
244 mxEngine
->SetRefDevice( mpViewData
->GetActiveWin() );
246 mpViewShell
->MakeEditView( mxEngine
.get(), nCol
, nRow
);
247 EditView
* pEditView
= mpViewData
->GetEditView( mpViewData
->GetActivePart() );
248 mpViewData
->SetSpellingView( pEditView
);
249 Rectangle
aRect( Point( 0, 0 ), Point( 0, 0 ) );
250 pEditView
->SetOutputArea( aRect
);
251 mxEngine
->SetControlWord( EE_CNTRL_USECHARATTRIBS
);
252 mxEngine
->EnableUndo( false );
253 mxEngine
->SetPaperSize( aRect
.GetSize() );
254 mxEngine
->SetText( EMPTY_STRING
);
255 mxEngine
->ClearModifyFlag();
257 mbNeedNextObj
= true;
260 bool ScSpellDialogChildWindow::IsSelectionChanged()
262 if( !mxOldRangeList
.get() || !mpViewShell
|| (mpViewShell
!= PTR_CAST( ScTabViewShell
, SfxViewShell::Current() )) )
265 if( EditView
* pEditView
= mpViewData
->GetSpellingView() )
266 if( pEditView
->GetEditEngine() != mxEngine
.get() )
269 ScRangeList aCurrentRangeList
;
270 mpViewData
->GetMarkData().FillRangeListWithMarks(&aCurrentRangeList
, true);
272 return (*mxOldRangeList
!= aCurrentRangeList
);
275 // ============================================================================
277 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */