Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "spelldialog.hxx"
21 :
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"
30 :
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 <refupdatecontext.hxx>
38 :
39 0 : SFX_IMPL_CHILDWINDOW_WITHID( ScSpellDialogChildWindow, SID_SPELL_DIALOG )
40 :
41 0 : ScSpellDialogChildWindow::ScSpellDialogChildWindow( Window* pParentP, sal_uInt16 nId,
42 : SfxBindings* pBindings, SfxChildWinInfo* pInfo ) :
43 : ::svx::SpellDialogChildWindow( pParentP, nId, pBindings, pInfo ),
44 : mpViewShell( 0 ),
45 : mpViewData( 0 ),
46 : mpDocShell( 0 ),
47 : mpDoc( 0 ),
48 : mbNeedNextObj( false ),
49 0 : mbOldIdleEnabled(true)
50 : {
51 0 : Init();
52 0 : }
53 :
54 0 : ScSpellDialogChildWindow::~ScSpellDialogChildWindow()
55 : {
56 0 : Reset();
57 0 : }
58 :
59 0 : SfxChildWinInfo ScSpellDialogChildWindow::GetInfo() const
60 : {
61 0 : return ::svx::SpellDialogChildWindow::GetInfo();
62 : }
63 :
64 0 : void ScSpellDialogChildWindow::InvalidateSpellDialog()
65 : {
66 0 : ::svx::SpellDialogChildWindow::InvalidateSpellDialog();
67 0 : }
68 :
69 : // protected ------------------------------------------------------------------
70 :
71 0 : ::svx::SpellPortions ScSpellDialogChildWindow::GetNextWrongSentence( bool /*bRecheck*/ )
72 : {
73 0 : ::svx::SpellPortions aPortions;
74 0 : if( mxEngine.get() && mpViewData )
75 : {
76 0 : if( EditView* pEditView = mpViewData->GetSpellingView() )
77 : {
78 : // edit engine handles cell iteration internally
79 0 : do
80 : {
81 0 : if( mbNeedNextObj )
82 0 : mxEngine->SpellNextDocument();
83 0 : mbNeedNextObj = !mxEngine->IsFinished() && !mxEngine->SpellSentence( *pEditView, aPortions, false );
84 : }
85 : while( mbNeedNextObj );
86 : }
87 :
88 : // finished? - close the spelling dialog
89 0 : if( mxEngine->IsFinished() )
90 0 : GetBindings().GetDispatcher()->Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON );
91 : }
92 0 : return aPortions;
93 : }
94 :
95 0 : void ScSpellDialogChildWindow::ApplyChangedSentence( const ::svx::SpellPortions& rChanged, bool bRecheck )
96 : {
97 0 : if( mxEngine.get() && mpViewData )
98 0 : if( EditView* pEditView = mpViewData->GetSpellingView() )
99 0 : mxEngine->ApplyChangedSentence( *pEditView, rChanged, bRecheck );
100 0 : }
101 :
102 0 : void ScSpellDialogChildWindow::GetFocus()
103 : {
104 0 : if( IsSelectionChanged() )
105 : {
106 0 : Reset();
107 0 : InvalidateSpellDialog();
108 0 : Init();
109 : }
110 0 : }
111 :
112 0 : void ScSpellDialogChildWindow::LoseFocus()
113 : {
114 0 : }
115 :
116 : // private --------------------------------------------------------------------
117 :
118 0 : void ScSpellDialogChildWindow::Reset()
119 : {
120 0 : if( mpViewShell && (mpViewShell == PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) )
121 : {
122 0 : if( mxEngine.get() && mxEngine->IsAnyModified() )
123 : {
124 0 : const ScAddress& rCursor = mxOldSel->GetCellCursor();
125 0 : SCTAB nTab = rCursor.Tab();
126 0 : SCCOL nOldCol = rCursor.Col();
127 0 : SCROW nOldRow = rCursor.Row();
128 0 : SCCOL nNewCol = mpViewData->GetCurX();
129 0 : SCROW nNewRow = mpViewData->GetCurY();
130 0 : mpDocShell->GetUndoManager()->AddUndoAction( new ScUndoConversion(
131 0 : mpDocShell, mpViewData->GetMarkData(),
132 0 : nOldCol, nOldRow, nTab, mxUndoDoc.release(),
133 0 : nNewCol, nNewRow, nTab, mxRedoDoc.release(),
134 0 : ScConversionParam( SC_CONVERSION_SPELLCHECK ) ) );
135 :
136 0 : sc::SetFormulaDirtyContext aCxt;
137 0 : mpDoc->SetAllFormulasDirty(aCxt);
138 :
139 0 : mpDocShell->SetDocumentModified();
140 : }
141 :
142 0 : mpViewData->SetSpellingView( 0 );
143 0 : mpViewShell->KillEditView( true );
144 0 : mpDocShell->PostPaintGridAll();
145 0 : mpViewShell->UpdateInputHandler();
146 0 : mpDoc->EnableIdle(mbOldIdleEnabled);
147 : }
148 0 : mxEngine.reset();
149 0 : mxUndoDoc.reset();
150 0 : mxRedoDoc.reset();
151 0 : mxOldSel.reset();
152 0 : mxOldRangeList.reset();
153 0 : mpViewShell = 0;
154 0 : mpViewData = 0;
155 0 : mpDocShell = 0;
156 0 : mpDoc = 0;
157 0 : mbNeedNextObj = false;
158 0 : mbOldIdleEnabled = true;
159 0 : }
160 :
161 0 : void ScSpellDialogChildWindow::Init()
162 : {
163 0 : if( mpViewShell )
164 0 : return;
165 0 : if( (mpViewShell = PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) == 0 )
166 0 : return;
167 :
168 0 : mpViewData = mpViewShell->GetViewData();
169 :
170 : // exit edit mode - TODO support spelling in edit mode
171 0 : if( mpViewData->HasEditView( mpViewData->GetActivePart() ) )
172 0 : SC_MOD()->InputEnterHandler();
173 :
174 0 : mxOldSel.reset( new ScSelectionState( *mpViewData ) );
175 :
176 0 : mpDocShell = mpViewData->GetDocShell();
177 0 : mpDoc = mpDocShell->GetDocument();
178 :
179 0 : const ScAddress& rCursor = mxOldSel->GetCellCursor();
180 0 : SCCOL nCol = rCursor.Col();
181 0 : SCROW nRow = rCursor.Row();
182 0 : SCTAB nTab = rCursor.Tab();
183 :
184 0 : ScMarkData& rMarkData = mpViewData->GetMarkData();
185 :
186 0 : mxOldRangeList.reset(new ScRangeList);
187 0 : rMarkData.FillRangeListWithMarks(mxOldRangeList.get(), true);
188 :
189 0 : rMarkData.MarkToMulti();
190 :
191 0 : switch( mxOldSel->GetSelectionType() )
192 : {
193 : case SC_SELECTTYPE_NONE:
194 : case SC_SELECTTYPE_SHEET:
195 : {
196 : // test if there is something editable
197 0 : ScEditableTester aTester( mpDoc, rMarkData );
198 0 : if( !aTester.IsEditable() )
199 : {
200 : // #i85751# Don't show a ErrorMessage here, because the vcl
201 : // parent of the InfoBox is not fully initialized yet.
202 : // This leads to problems in the modality behaviour of the
203 : // ScSpellDialogChildWindow.
204 :
205 : //mpViewShell->ErrorMessage( aTester.GetMessageId() );
206 0 : return;
207 : }
208 : }
209 0 : break;
210 :
211 : // edit mode exited, see TODO above
212 : // case SC_SELECTTYPE_EDITCELL:
213 : // break;
214 :
215 : default:
216 : OSL_FAIL( "ScSpellDialogChildWindow::Init - unknown selection type" );
217 : }
218 :
219 0 : mbOldIdleEnabled = mpDoc->IsIdleEnabled();
220 0 : mpDoc->EnableIdle(false); // stop online spelling
221 :
222 : // *** create Undo/Redo documents *** -------------------------------------
223 :
224 0 : mxUndoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
225 0 : mxUndoDoc->InitUndo( mpDoc, nTab, nTab );
226 0 : mxRedoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
227 0 : mxRedoDoc->InitUndo( mpDoc, nTab, nTab );
228 :
229 0 : if ( rMarkData.GetSelectCount() > 1 )
230 : {
231 0 : ScMarkData::iterator itr = rMarkData.begin(), itrEnd = rMarkData.end();
232 0 : for (; itr != itrEnd; ++itr)
233 : {
234 0 : if( *itr != nTab )
235 : {
236 0 : mxUndoDoc->AddUndoTab( *itr, *itr );
237 0 : mxRedoDoc->AddUndoTab( *itr, *itr );
238 : }
239 : }
240 : }
241 :
242 : // *** create and init the edit engine *** --------------------------------
243 :
244 : mxEngine.reset( new ScSpellingEngine(
245 0 : mpDoc->GetEnginePool(), *mpViewData, mxUndoDoc.get(), mxRedoDoc.get(), LinguMgr::GetSpellChecker() ) );
246 0 : mxEngine->SetRefDevice( mpViewData->GetActiveWin() );
247 :
248 0 : mpViewShell->MakeEditView( mxEngine.get(), nCol, nRow );
249 0 : EditView* pEditView = mpViewData->GetEditView( mpViewData->GetActivePart() );
250 0 : mpViewData->SetSpellingView( pEditView );
251 0 : Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
252 0 : pEditView->SetOutputArea( aRect );
253 0 : mxEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS );
254 0 : mxEngine->EnableUndo( false );
255 0 : mxEngine->SetPaperSize( aRect.GetSize() );
256 0 : mxEngine->SetText( EMPTY_OUSTRING );
257 0 : mxEngine->ClearModifyFlag();
258 :
259 0 : mbNeedNextObj = true;
260 : }
261 :
262 0 : bool ScSpellDialogChildWindow::IsSelectionChanged()
263 : {
264 0 : if( !mxOldRangeList.get() || !mpViewShell || (mpViewShell != PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) )
265 0 : return true;
266 :
267 0 : if( EditView* pEditView = mpViewData->GetSpellingView() )
268 0 : if( pEditView->GetEditEngine() != mxEngine.get() )
269 0 : return true;
270 :
271 0 : ScRangeList aCurrentRangeList;
272 0 : mpViewData->GetMarkData().FillRangeListWithMarks(&aCurrentRangeList, true);
273 :
274 0 : return (*mxOldRangeList != aCurrentRangeList);
275 0 : }
276 :
277 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|