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