xref: /trunk/main/sc/source/ui/view/spelldialog.cxx (revision b3f79822)
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