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>
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"
53 #include "patattr.hxx"
54 #include "waitoff.hxx"
55 #include "globstr.hrc"
58 using namespace ::com::sun::star
;
60 // ============================================================================
64 bool lclHasString( ScDocument
& rDoc
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const String
& rString
)
67 rDoc
.GetString( nCol
, nRow
, nTab
, aCompStr
);
68 return aCompStr
== rString
; //! case-insensitive?
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 ),
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
)
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() ) );
117 mbIsAnyModified
= true;
119 String aNewStr
= GetText();
121 BOOL bMultiTab
= (rMark
.GetSelectCount() > 1);
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
)
149 ScEditCell
* pEditCell
= static_cast< ScEditCell
* >( pCell
);
150 ::std::auto_ptr
< EditTextObject
> pEditObj( CreateTextObject() );
151 pEditCell
->SetData( pEditObj
.get(), GetEditTextObjectPool() );
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
);
171 SCCOL nNewCol
= mnCurrCol
;
172 SCROW nNewRow
= mnCurrRow
;
176 /* On very first call, decrement row to let GetNextSpellingCell() find
177 the first cell of current range. */
178 mbInitialState
= false;
182 bool bSheetSel
= maSelState
.GetSelectionType() == SC_SELECTTYPE_SHEET
;
185 while( bLoop
&& !bFound
)
187 bLoop
= mrDoc
.GetNextSpellingCell( nNewCol
, nNewRow
, mnStartTab
, bSheetSel
, rMark
);
190 FillFromCell( mnCurrCol
, mnCurrRow
, mnStartTab
);
192 if( mbWrappedInTable
&& ((nNewCol
> mnStartCol
) || ((nNewCol
== mnStartCol
) && (nNewRow
>= mnStartRow
))) )
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
209 else if( ShowTableWrapDialog() )
211 // conversion started anywhere but in cell A1, user wants to restart
212 nNewRow
= MAXROW
+ 2;
213 mbWrappedInTable
= true;
223 pPattern
= mrDoc
.GetPattern( nNewCol
, nNewRow
, mnStartTab
);
224 if( pPattern
&& (pPattern
!= pLastPattern
) )
226 pPattern
->FillEditItemSet( pEditDefaults
.get() );
227 SetDefaults( *pEditDefaults
);
228 pLastPattern
= pPattern
;
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
)
241 SetDefaultLanguage( eLang
);
245 FillFromCell( nNewCol
, nNewRow
, mnStartTab
);
247 bFound
= bLoop
&& NeedsConversion();
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() );
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
281 void ScConversionEngineBase::ShowFinishDialog()
283 // default: no dialog
286 // private --------------------------------------------------------------------
288 void ScConversionEngineBase::FillFromCell( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
291 mrDoc
.GetCellType( nCol
, nRow
, nTab
, eCellType
);
295 case CELLTYPE_STRING
:
298 mrDoc
.GetString( nCol
, nRow
, nTab
, aText
);
304 ScBaseCell
* pCell
= NULL
;
305 mrDoc
.GetCell( nCol
, nRow
, nTab
, pCell
);
308 const EditTextObject
* pNewEditObj
= NULL
;
309 static_cast< ScEditCell
* >( pCell
)->GetData( pNewEditObj
);
311 SetText( *pNewEditObj
);
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() )
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
),
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
450 BOOL
ScTextConversionEngine::ConvertNextDocument()
452 return FindNextConversionCell();
455 bool ScTextConversionEngine::NeedsConversion()
457 return HasConvertibleTextPortion( maConvParam
.GetSourceLang() );
460 // ============================================================================