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