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 :
38 : // ============================================================================
39 :
40 10 : SFX_IMPL_CHILDWINDOW_WITHID( ScSpellDialogChildWindow, SID_SPELL_DIALOG )
41 :
42 0 : ScSpellDialogChildWindow::ScSpellDialogChildWindow( 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 : mbOldIdleDisabled( false )
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, SFX_CALLMODE_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 0 : mpDoc->SetDirty();
137 0 : mpDocShell->SetDocumentModified();
138 : }
139 :
140 0 : mpViewData->SetSpellingView( 0 );
141 0 : mpViewShell->KillEditView( sal_True );
142 0 : mpDocShell->PostPaintGridAll();
143 0 : mpViewShell->UpdateInputHandler();
144 0 : mpDoc->DisableIdle( mbOldIdleDisabled );
145 : }
146 0 : mxEngine.reset();
147 0 : mxUndoDoc.reset();
148 0 : mxRedoDoc.reset();
149 0 : mxOldSel.reset();
150 0 : mxOldRangeList.reset();
151 0 : mpViewShell = 0;
152 0 : mpViewData = 0;
153 0 : mpDocShell = 0;
154 0 : mpDoc = 0;
155 0 : mbNeedNextObj = false;
156 0 : mbOldIdleDisabled = false;
157 0 : }
158 :
159 0 : void ScSpellDialogChildWindow::Init()
160 : {
161 0 : if( mpViewShell )
162 : return;
163 0 : if( (mpViewShell = PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) == 0 )
164 : return;
165 :
166 0 : mpViewData = mpViewShell->GetViewData();
167 :
168 : // exit edit mode - TODO support spelling in edit mode
169 0 : if( mpViewData->HasEditView( mpViewData->GetActivePart() ) )
170 0 : SC_MOD()->InputEnterHandler();
171 :
172 0 : mxOldSel.reset( new ScSelectionState( *mpViewData ) );
173 :
174 0 : mpDocShell = mpViewData->GetDocShell();
175 0 : mpDoc = mpDocShell->GetDocument();
176 :
177 0 : const ScAddress& rCursor = mxOldSel->GetCellCursor();
178 0 : SCCOL nCol = rCursor.Col();
179 0 : SCROW nRow = rCursor.Row();
180 0 : SCTAB nTab = rCursor.Tab();
181 :
182 0 : ScMarkData& rMarkData = mpViewData->GetMarkData();
183 :
184 0 : mxOldRangeList.reset(new ScRangeList);
185 0 : rMarkData.FillRangeListWithMarks(mxOldRangeList.get(), true);
186 :
187 0 : rMarkData.MarkToMulti();
188 :
189 0 : switch( mxOldSel->GetSelectionType() )
190 : {
191 : case SC_SELECTTYPE_NONE:
192 : case SC_SELECTTYPE_SHEET:
193 : {
194 : // test if there is something editable
195 0 : ScEditableTester aTester( mpDoc, rMarkData );
196 0 : if( !aTester.IsEditable() )
197 : {
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.
202 :
203 : //mpViewShell->ErrorMessage( aTester.GetMessageId() );
204 : return;
205 0 : }
206 : }
207 0 : break;
208 :
209 : // edit mode exited, see TODO above
210 : // case SC_SELECTTYPE_EDITCELL:
211 : // break;
212 :
213 : default:
214 : OSL_FAIL( "ScSpellDialogChildWindow::Init - unknown selection type" );
215 : }
216 :
217 0 : mbOldIdleDisabled = mpDoc->IsIdleDisabled();
218 0 : mpDoc->DisableIdle( true ); // stop online spelling
219 :
220 : // *** create Undo/Redo documents *** -------------------------------------
221 :
222 0 : mxUndoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
223 0 : mxUndoDoc->InitUndo( mpDoc, nTab, nTab );
224 0 : mxRedoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
225 0 : mxRedoDoc->InitUndo( mpDoc, nTab, nTab );
226 :
227 0 : if ( rMarkData.GetSelectCount() > 1 )
228 : {
229 0 : ScMarkData::iterator itr = rMarkData.begin(), itrEnd = rMarkData.end();
230 0 : for (; itr != itrEnd; ++itr)
231 : {
232 0 : if( *itr != nTab )
233 : {
234 0 : mxUndoDoc->AddUndoTab( *itr, *itr );
235 0 : mxRedoDoc->AddUndoTab( *itr, *itr );
236 : }
237 : }
238 : }
239 :
240 : // *** create and init the edit engine *** --------------------------------
241 :
242 : mxEngine.reset( new ScSpellingEngine(
243 0 : mpDoc->GetEnginePool(), *mpViewData, mxUndoDoc.get(), mxRedoDoc.get(), LinguMgr::GetSpellChecker() ) );
244 0 : mxEngine->SetRefDevice( mpViewData->GetActiveWin() );
245 :
246 0 : mpViewShell->MakeEditView( mxEngine.get(), nCol, nRow );
247 0 : EditView* pEditView = mpViewData->GetEditView( mpViewData->GetActivePart() );
248 0 : mpViewData->SetSpellingView( pEditView );
249 0 : Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
250 0 : pEditView->SetOutputArea( aRect );
251 0 : mxEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS );
252 0 : mxEngine->EnableUndo( false );
253 0 : mxEngine->SetPaperSize( aRect.GetSize() );
254 0 : mxEngine->SetText( EMPTY_STRING );
255 0 : mxEngine->ClearModifyFlag();
256 :
257 0 : mbNeedNextObj = true;
258 : }
259 :
260 0 : bool ScSpellDialogChildWindow::IsSelectionChanged()
261 : {
262 0 : if( !mxOldRangeList.get() || !mpViewShell || (mpViewShell != PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) )
263 0 : return true;
264 :
265 0 : if( EditView* pEditView = mpViewData->GetSpellingView() )
266 0 : if( pEditView->GetEditEngine() != mxEngine.get() )
267 0 : return true;
268 :
269 0 : ScRangeList aCurrentRangeList;
270 0 : mpViewData->GetMarkData().FillRangeListWithMarks(&aCurrentRangeList, true);
271 :
272 0 : return (*mxOldRangeList != aCurrentRangeList);
273 15 : }
274 :
275 : // ============================================================================
276 :
277 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|