Update ooo320-m1
[ooovba.git] / sc / source / ui / view / spelleng.cxx
blob40b9ff5dbea75e059cfd69b8d687d524f9bfa56e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: spelleng.cxx,v $
10 * $Revision: 1.18.128.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
33 #include "spelleng.hxx"
34 #include <com/sun/star/i18n/TextConversionOption.hpp>
36 #include <memory>
38 #include "scitems.hxx"
39 #include <svx/eeitem.hxx>
42 #include <svx/langitem.hxx>
43 #include <svx/editobj.hxx>
44 #include <svx/editview.hxx>
45 #include <sfx2/viewfrm.hxx>
46 #include <vcl/msgbox.hxx>
47 #include <vcl/svapp.hxx>
49 #include "spelldialog.hxx"
50 #include "tabvwsh.hxx"
51 #include "docsh.hxx"
52 #include "cell.hxx"
53 #include "patattr.hxx"
54 #include "waitoff.hxx"
55 #include "globstr.hrc"
58 using namespace ::com::sun::star;
60 // ============================================================================
62 namespace {
64 bool lclHasString( ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString )
66 String aCompStr;
67 rDoc.GetString( nCol, nRow, nTab, aCompStr );
68 return aCompStr == rString; //! case-insensitive?
71 } // namespace
73 // ----------------------------------------------------------------------------
75 ScConversionEngineBase::ScConversionEngineBase(
76 SfxItemPool* pEnginePoolP, ScViewData& rViewData,
77 ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
78 ScEditEngineDefaulter( pEnginePoolP ),
79 mrViewData( rViewData ),
80 mrDocShell( *rViewData.GetDocShell() ),
81 mrDoc( *rViewData.GetDocShell()->GetDocument() ),
82 maSelState( rViewData ),
83 mpUndoDoc( pUndoDoc ),
84 mpRedoDoc( pRedoDoc ),
85 meCurrLang( LANGUAGE_ENGLISH_US ),
86 mbIsAnyModified( false ),
87 mbInitialState( true ),
88 mbWrappedInTable( false ),
89 mbFinished( false )
91 maSelState.GetCellCursor().GetVars( mnStartCol, mnStartRow, mnStartTab );
92 // start with cell A1 in cell/range/multi-selection, will seek to first selected
93 if( maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET )
95 mnStartCol = 0;
96 mnStartRow = 0;
98 mnCurrCol = mnStartCol;
99 mnCurrRow = mnStartRow;
102 ScConversionEngineBase::~ScConversionEngineBase()
106 bool ScConversionEngineBase::FindNextConversionCell()
108 ScMarkData& rMark = mrViewData.GetMarkData();
109 ScTabViewShell* pViewShell = mrViewData.GetViewShell();
110 ScBaseCell* pCell = NULL;
111 const ScPatternAttr* pPattern = NULL;
112 const ScPatternAttr* pLastPattern = NULL;
113 ::std::auto_ptr< SfxItemSet > pEditDefaults( new SfxItemSet( GetEmptyItemSet() ) );
115 if( IsModified() )
117 mbIsAnyModified = true;
119 String aNewStr = GetText();
121 BOOL bMultiTab = (rMark.GetSelectCount() > 1);
122 String aVisibleStr;
123 if( bMultiTab )
124 mrDoc.GetString( mnCurrCol, mnCurrRow, mnStartTab, aVisibleStr );
126 for( SCTAB nTab = 0, nTabCount = mrDoc.GetTableCount(); nTab < nTabCount; ++nTab )
128 // #69965# always change the cell on the visible tab,
129 // on the other selected tabs only if they contain the same text
131 if( (nTab == mnStartTab) ||
132 (bMultiTab && rMark.GetTableSelect( nTab ) &&
133 lclHasString( mrDoc, mnCurrCol, mnCurrRow, nTab, aVisibleStr )) )
135 ScAddress aPos( mnCurrCol, mnCurrRow, nTab );
136 CellType eCellType = mrDoc.GetCellType( aPos );
137 pCell = mrDoc.GetCell( aPos );
139 if( mpUndoDoc && pCell )
141 ScBaseCell* pUndoCell = pCell->CloneWithoutNote( *mpUndoDoc );
142 mpUndoDoc->PutCell( aPos, pUndoCell );
145 if( eCellType == CELLTYPE_EDIT )
147 if( pCell )
149 ScEditCell* pEditCell = static_cast< ScEditCell* >( pCell );
150 ::std::auto_ptr< EditTextObject > pEditObj( CreateTextObject() );
151 pEditCell->SetData( pEditObj.get(), GetEditTextObjectPool() );
154 else
156 mrDoc.SetString( mnCurrCol, mnCurrRow, nTab, aNewStr );
157 pCell = mrDoc.GetCell( aPos );
160 if( mpRedoDoc && pCell )
162 ScBaseCell* pRedoCell = pCell->CloneWithoutNote( *mpRedoDoc );
163 mpRedoDoc->PutCell( aPos, pRedoCell );
166 mrDocShell.PostPaintCell( mnCurrCol, mnCurrRow, nTab );
170 pCell = NULL;
171 SCCOL nNewCol = mnCurrCol;
172 SCROW nNewRow = mnCurrRow;
174 if( mbInitialState )
176 /* On very first call, decrement row to let GetNextSpellingCell() find
177 the first cell of current range. */
178 mbInitialState = false;
179 --nNewRow;
182 bool bSheetSel = maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET;
183 bool bLoop = true;
184 bool bFound = false;
185 while( bLoop && !bFound )
187 bLoop = mrDoc.GetNextSpellingCell( nNewCol, nNewRow, mnStartTab, bSheetSel, rMark );
188 if( bLoop )
190 FillFromCell( mnCurrCol, mnCurrRow, mnStartTab );
192 if( mbWrappedInTable && ((nNewCol > mnStartCol) || ((nNewCol == mnStartCol) && (nNewRow >= mnStartRow))) )
194 ShowFinishDialog();
195 bLoop = false;
196 mbFinished = true;
198 else if( nNewCol > MAXCOL )
200 // no more cells in the sheet - try to restart at top of sheet
202 if( bSheetSel || ((mnStartCol == 0) && (mnStartRow == 0)) )
204 // conversion started at cell A1 or in selection, do not query to restart at top
205 ShowFinishDialog();
206 bLoop = false;
207 mbFinished = true;
209 else if( ShowTableWrapDialog() )
211 // conversion started anywhere but in cell A1, user wants to restart
212 nNewRow = MAXROW + 2;
213 mbWrappedInTable = true;
215 else
217 bLoop = false;
218 mbFinished = true;
221 else
223 pPattern = mrDoc.GetPattern( nNewCol, nNewRow, mnStartTab );
224 if( pPattern && (pPattern != pLastPattern) )
226 pPattern->FillEditItemSet( pEditDefaults.get() );
227 SetDefaults( *pEditDefaults );
228 pLastPattern = pPattern;
231 // language changed?
232 const SfxPoolItem* pItem = mrDoc.GetAttr( nNewCol, nNewRow, mnStartTab, ATTR_FONT_LANGUAGE );
233 if( const SvxLanguageItem* pLangItem = PTR_CAST( SvxLanguageItem, pItem ) )
235 LanguageType eLang = static_cast< LanguageType >( pLangItem->GetValue() );
236 if( eLang == LANGUAGE_SYSTEM )
237 eLang = Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling
238 if( eLang != meCurrLang )
240 meCurrLang = eLang;
241 SetDefaultLanguage( eLang );
245 FillFromCell( nNewCol, nNewRow, mnStartTab );
247 bFound = bLoop && NeedsConversion();
252 if( bFound )
254 pViewShell->AlignToCursor( nNewCol, nNewRow, SC_FOLLOW_JUMP );
255 pViewShell->SetCursor( nNewCol, nNewRow, TRUE );
256 mrViewData.GetView()->MakeEditView( this, nNewCol, nNewRow );
257 EditView* pEditView = mrViewData.GetSpellingView();
258 // maSelState.GetEditSelection() returns (0,0) if not in edit mode -> ok
259 pEditView->SetSelection( maSelState.GetEditSelection() );
261 ClearModifyFlag();
262 mnCurrCol = nNewCol;
263 mnCurrRow = nNewRow;
266 return bFound;
269 void ScConversionEngineBase::RestoreCursorPos()
271 const ScAddress& rPos = maSelState.GetCellCursor();
272 mrViewData.GetViewShell()->SetCursor( rPos.Col(), rPos.Row() );
275 bool ScConversionEngineBase::ShowTableWrapDialog()
277 // default: no dialog, always restart at top
278 return true;
281 void ScConversionEngineBase::ShowFinishDialog()
283 // default: no dialog
286 // private --------------------------------------------------------------------
288 void ScConversionEngineBase::FillFromCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
290 CellType eCellType;
291 mrDoc.GetCellType( nCol, nRow, nTab, eCellType );
293 switch( eCellType )
295 case CELLTYPE_STRING:
297 String aText;
298 mrDoc.GetString( nCol, nRow, nTab, aText );
299 SetText( aText );
301 break;
302 case CELLTYPE_EDIT:
304 ScBaseCell* pCell = NULL;
305 mrDoc.GetCell( nCol, nRow, nTab, pCell );
306 if( pCell )
308 const EditTextObject* pNewEditObj = NULL;
309 static_cast< ScEditCell* >( pCell )->GetData( pNewEditObj );
310 if( pNewEditObj )
311 SetText( *pNewEditObj );
314 break;
315 default:
316 SetText( EMPTY_STRING );
320 // ============================================================================
322 ScSpellingEngine::ScSpellingEngine(
323 SfxItemPool* pEnginePoolP, ScViewData& rViewData,
324 ScDocument* pUndoDoc, ScDocument* pRedoDoc,
325 XSpellCheckerRef xSpeller ) :
326 ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc )
328 SetSpeller( xSpeller );
331 void ScSpellingEngine::ConvertAll( EditView& rEditView )
333 EESpellState eState = EE_SPELL_OK;
334 if( FindNextConversionCell() )
335 eState = rEditView.StartSpeller( static_cast< BOOL >( TRUE ) );
337 DBG_ASSERT( eState != EE_SPELL_NOSPELLER, "ScSpellingEngine::Convert - no spell checker" );
338 if( eState == EE_SPELL_NOLANGUAGE )
340 Window* pParent = GetDialogParent();
341 ScWaitCursorOff aWaitOff( pParent );
342 InfoBox( pParent, ScGlobal::GetRscString( STR_NOLANGERR ) ).Execute();
346 BOOL ScSpellingEngine::SpellNextDocument()
348 return FindNextConversionCell();
351 bool ScSpellingEngine::NeedsConversion()
353 return HasSpellErrors() != EE_SPELL_OK;
356 bool ScSpellingEngine::ShowTableWrapDialog()
358 Window* pParent = GetDialogParent();
359 ScWaitCursorOff aWaitOff( pParent );
360 MessBox aMsgBox( pParent, WinBits( WB_YES_NO | WB_DEF_YES ),
361 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
362 ScGlobal::GetRscString( STR_SPELLING_BEGIN_TAB) );
363 return aMsgBox.Execute() == RET_YES;
366 void ScSpellingEngine::ShowFinishDialog()
368 Window* pParent = GetDialogParent();
369 ScWaitCursorOff aWaitOff( pParent );
370 InfoBox( pParent, ScGlobal::GetRscString( STR_SPELLING_STOP_OK ) ).Execute();
373 Window* ScSpellingEngine::GetDialogParent()
375 USHORT nWinId = ScSpellDialogChildWindow::GetChildWindowId();
376 SfxViewFrame* pViewFrm = mrViewData.GetViewShell()->GetViewFrame();
377 if( pViewFrm->HasChildWindow( nWinId ) )
378 if( SfxChildWindow* pChild = pViewFrm->GetChildWindow( nWinId ) )
379 if( Window* pWin = pChild->GetWindow() )
380 if( pWin->IsVisible() )
381 return pWin;
383 // fall back to standard dialog parent
384 return mrDocShell.GetActiveDialogParent();
387 // ============================================================================
389 ScConversionParam::ScConversionParam( ScConversionType eConvType ) :
390 meConvType( eConvType ),
391 meSourceLang( LANGUAGE_NONE ),
392 meTargetLang( LANGUAGE_NONE ),
393 mnOptions( 0 ),
394 mbUseTargetFont( false ),
395 mbIsInteractive( false )
399 ScConversionParam::ScConversionParam( ScConversionType eConvType,
400 LanguageType eLang, sal_Int32 nOptions, bool bIsInteractive ) :
401 meConvType( eConvType ),
402 meSourceLang( eLang ),
403 meTargetLang( eLang ),
404 mnOptions( nOptions ),
405 mbUseTargetFont( false ),
406 mbIsInteractive( bIsInteractive )
408 if (LANGUAGE_KOREAN == eLang)
409 mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
412 ScConversionParam::ScConversionParam( ScConversionType eConvType,
413 LanguageType eSourceLang, LanguageType eTargetLang, const Font& rTargetFont,
414 sal_Int32 nOptions, bool bIsInteractive ) :
415 meConvType( eConvType ),
416 meSourceLang( eSourceLang ),
417 meTargetLang( eTargetLang ),
418 maTargetFont( rTargetFont ),
419 mnOptions( nOptions ),
420 mbUseTargetFont( true ),
421 mbIsInteractive( bIsInteractive )
423 if (LANGUAGE_KOREAN == meSourceLang && LANGUAGE_KOREAN == meTargetLang)
424 mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
427 // ----------------------------------------------------------------------------
429 ScTextConversionEngine::ScTextConversionEngine(
430 SfxItemPool* pEnginePoolP, ScViewData& rViewData,
431 const ScConversionParam& rConvParam,
432 ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
433 ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc ),
434 maConvParam( rConvParam )
438 void ScTextConversionEngine::ConvertAll( EditView& rEditView )
440 if( FindNextConversionCell() )
442 rEditView.StartTextConversion(
443 maConvParam.GetSourceLang(), maConvParam.GetTargetLang(), maConvParam.GetTargetFont(),
444 maConvParam.GetOptions(), maConvParam.IsInteractive(), TRUE );
445 // #i34769# restore initial cursor position
446 RestoreCursorPos();
450 BOOL ScTextConversionEngine::ConvertNextDocument()
452 return FindNextConversionCell();
455 bool ScTextConversionEngine::NeedsConversion()
457 return HasConvertibleTextPortion( maConvParam.GetSourceLang() );
460 // ============================================================================