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