1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 #include "spelldialog.hxx"
27
28 #include <sfx2/app.hxx>
29 #include <sfx2/bindings.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <svx/svxids.hrc>
32 #include <editeng/editstat.hxx>
33 #include <editeng/editview.hxx>
34 #include <editeng/unolingu.hxx>
35 #include "selectionstate.hxx"
36
37 #include "spelleng.hxx"
38 #include "tabvwsh.hxx"
39 #include "docsh.hxx"
40 #include "scmod.hxx"
41 #include "editable.hxx"
42 #include "undoblk.hxx"
43
44 // ============================================================================
45
SFX_IMPL_CHILDWINDOW(ScSpellDialogChildWindow,SID_SPELL_DIALOG)46 SFX_IMPL_CHILDWINDOW( ScSpellDialogChildWindow, SID_SPELL_DIALOG )
47
48 ScSpellDialogChildWindow::ScSpellDialogChildWindow( Window* pParentP, sal_uInt16 nId,
49 SfxBindings* pBindings, SfxChildWinInfo* pInfo ) :
50 ::svx::SpellDialogChildWindow( pParentP, nId, pBindings, pInfo ),
51 mpViewShell( 0 ),
52 mpViewData( 0 ),
53 mpDocShell( 0 ),
54 mpDoc( 0 ),
55 mbNeedNextObj( false ),
56 mbOldIdleDisabled( false )
57 {
58 Init();
59 }
60
~ScSpellDialogChildWindow()61 ScSpellDialogChildWindow::~ScSpellDialogChildWindow()
62 {
63 Reset();
64 }
65
GetInfo() const66 SfxChildWinInfo ScSpellDialogChildWindow::GetInfo() const
67 {
68 return ::svx::SpellDialogChildWindow::GetInfo();
69 }
70
InvalidateSpellDialog()71 void ScSpellDialogChildWindow::InvalidateSpellDialog()
72 {
73 ::svx::SpellDialogChildWindow::InvalidateSpellDialog();
74 }
75
76 // protected ------------------------------------------------------------------
77
GetNextWrongSentence(bool)78 ::svx::SpellPortions ScSpellDialogChildWindow::GetNextWrongSentence( bool /*bRecheck*/ )
79 {
80 ::svx::SpellPortions aPortions;
81 if( mxEngine.get() && mpViewData )
82 {
83 if( EditView* pEditView = mpViewData->GetSpellingView() )
84 {
85 // edit engine handles cell iteration internally
86 do
87 {
88 if( mbNeedNextObj )
89 mxEngine->SpellNextDocument();
90 mbNeedNextObj = !mxEngine->IsFinished() && !mxEngine->SpellSentence( *pEditView, aPortions, false );
91 }
92 while( mbNeedNextObj );
93 }
94
95 // finished? - close the spelling dialog
96 if( mxEngine->IsFinished() )
97 GetBindings().GetDispatcher()->Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON );
98 }
99 return aPortions;
100 }
101
ApplyChangedSentence(const::svx::SpellPortions & rChanged,bool bRecheck)102 void ScSpellDialogChildWindow::ApplyChangedSentence( const ::svx::SpellPortions& rChanged, bool bRecheck )
103 {
104 if( mxEngine.get() && mpViewData )
105 if( EditView* pEditView = mpViewData->GetSpellingView() )
106 mxEngine->ApplyChangedSentence( *pEditView, rChanged, bRecheck );
107 }
108
GetFocus()109 void ScSpellDialogChildWindow::GetFocus()
110 {
111 if( IsSelectionChanged() )
112 {
113 Reset();
114 InvalidateSpellDialog();
115 Init();
116 }
117 }
118
LoseFocus()119 void ScSpellDialogChildWindow::LoseFocus()
120 {
121 }
122
123 // private --------------------------------------------------------------------
124
Reset()125 void ScSpellDialogChildWindow::Reset()
126 {
127 if( mpViewShell && (mpViewShell == PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) )
128 {
129 if( mxEngine.get() && mxEngine->IsAnyModified() )
130 {
131 const ScAddress& rCursor = mxOldSel->GetCellCursor();
132 SCTAB nTab = rCursor.Tab();
133 SCCOL nOldCol = rCursor.Col();
134 SCROW nOldRow = rCursor.Row();
135 SCCOL nNewCol = mpViewData->GetCurX();
136 SCROW nNewRow = mpViewData->GetCurY();
137 mpDocShell->GetUndoManager()->AddUndoAction( new ScUndoConversion(
138 mpDocShell, mpViewData->GetMarkData(),
139 nOldCol, nOldRow, nTab, mxUndoDoc.release(),
140 nNewCol, nNewRow, nTab, mxRedoDoc.release(),
141 ScConversionParam( SC_CONVERSION_SPELLCHECK ) ) );
142 mpDoc->SetDirty();
143 mpDocShell->SetDocumentModified();
144 }
145
146 mpViewData->SetSpellingView( 0 );
147 mpViewShell->KillEditView( sal_True );
148 mpDocShell->PostPaintGridAll();
149 mpViewShell->UpdateInputHandler();
150 mpDoc->DisableIdle( mbOldIdleDisabled );
151 }
152 mxEngine.reset();
153 mxUndoDoc.reset();
154 mxRedoDoc.reset();
155 mxOldSel.reset();
156 mpViewShell = 0;
157 mpViewData = 0;
158 mpDocShell = 0;
159 mpDoc = 0;
160 mbNeedNextObj = false;
161 mbOldIdleDisabled = false;
162 }
163
Init()164 void ScSpellDialogChildWindow::Init()
165 {
166 if( mpViewShell )
167 return;
168 if( (mpViewShell = PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) == 0 )
169 return;
170
171 mpViewData = mpViewShell->GetViewData();
172
173 // exit edit mode - TODO support spelling in edit mode
174 if( mpViewData->HasEditView( mpViewData->GetActivePart() ) )
175 SC_MOD()->InputEnterHandler();
176
177 mxOldSel.reset( new ScSelectionState( *mpViewData ) );
178
179 mpDocShell = mpViewData->GetDocShell();
180 mpDoc = mpDocShell->GetDocument();
181
182 const ScAddress& rCursor = mxOldSel->GetCellCursor();
183 SCCOL nCol = rCursor.Col();
184 SCROW nRow = rCursor.Row();
185 SCTAB nTab = rCursor.Tab();
186
187 ScMarkData& rMarkData = mpViewData->GetMarkData();
188 rMarkData.MarkToMulti();
189
190 switch( mxOldSel->GetSelectionType() )
191 {
192 case SC_SELECTTYPE_NONE:
193 case SC_SELECTTYPE_SHEET:
194 {
195 // test if there is something editable
196 ScEditableTester aTester( mpDoc, rMarkData );
197 if( !aTester.IsEditable() )
198 {
199 // #i85751# Don't show a ErrorMessage here, because the vcl
200 // parent of the InfoBox is not fully initialized yet.
201 // This leads to problems in the modality behaviour of the
202 // ScSpellDialogChildWindow.
203
204 //mpViewShell->ErrorMessage( aTester.GetMessageId() );
205 return;
206 }
207 }
208 break;
209
210 // edit mode exited, see TODO above
211 // case SC_SELECTTYPE_EDITCELL:
212 // break;
213
214 default:
215 DBG_ERRORFILE( "ScSpellDialogChildWindow::Init - unknown selection type" );
216 }
217
218 mbOldIdleDisabled = mpDoc->IsIdleDisabled();
219 mpDoc->DisableIdle( sal_True ); // #42726# stop online spelling
220
221 // *** create Undo/Redo documents *** -------------------------------------
222
223 mxUndoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
224 mxUndoDoc->InitUndo( mpDoc, nTab, nTab );
225 mxRedoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
226 mxRedoDoc->InitUndo( mpDoc, nTab, nTab );
227
228 if ( rMarkData.GetSelectCount() > 1 )
229 {
230 SCTAB nTabCount = mpDoc->GetTableCount();
231 for( SCTAB nOtherTab = 0; nOtherTab < nTabCount; ++nOtherTab )
232 {
233 if( rMarkData.GetTableSelect( nOtherTab ) && (nOtherTab != nTab) )
234 {
235 mxUndoDoc->AddUndoTab( nOtherTab, nOtherTab );
236 mxRedoDoc->AddUndoTab( nOtherTab, nOtherTab );
237 }
238 }
239 }
240
241 // *** create and init the edit engine *** --------------------------------
242
243 mxEngine.reset( new ScSpellingEngine(
244 mpDoc->GetEnginePool(), *mpViewData, mxUndoDoc.get(), mxRedoDoc.get(), LinguMgr::GetSpellChecker() ) );
245 mxEngine->SetRefDevice( mpViewData->GetActiveWin() );
246
247 mpViewShell->MakeEditView( mxEngine.get(), nCol, nRow );
248 EditView* pEditView = mpViewData->GetEditView( mpViewData->GetActivePart() );
249 mpViewData->SetSpellingView( pEditView );
250 Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
251 pEditView->SetOutputArea( aRect );
252 mxEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS );
253 mxEngine->EnableUndo( sal_False );
254 mxEngine->SetPaperSize( aRect.GetSize() );
255 mxEngine->SetText( EMPTY_STRING );
256 mxEngine->ClearModifyFlag();
257
258 mbNeedNextObj = true;
259 }
260
IsSelectionChanged()261 bool ScSpellDialogChildWindow::IsSelectionChanged()
262 {
263 if( !mxOldSel.get() || !mpViewShell || (mpViewShell != PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) )
264 return true;
265
266 if( EditView* pEditView = mpViewData->GetSpellingView() )
267 if( pEditView->GetEditEngine() != mxEngine.get() )
268 return true;
269
270 ScSelectionState aNewSel( *mpViewData );
271 return mxOldSel->GetSheetSelection() != aNewSel.GetSheetSelection();
272 }
273
274 // ============================================================================
275
276