Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "spelleng.hxx"
30 : : #include <com/sun/star/i18n/TextConversionOption.hpp>
31 : :
32 : : #include <memory>
33 : :
34 : : #include "scitems.hxx"
35 : : #include <editeng/eeitem.hxx>
36 : :
37 : :
38 : : #include <editeng/langitem.hxx>
39 : : #include <editeng/editobj.hxx>
40 : : #include <editeng/editview.hxx>
41 : : #include <sfx2/viewfrm.hxx>
42 : : #include <vcl/msgbox.hxx>
43 : : #include <vcl/svapp.hxx>
44 : :
45 : : #include "spelldialog.hxx"
46 : : #include "tabvwsh.hxx"
47 : : #include "docsh.hxx"
48 : : #include "cell.hxx"
49 : : #include "patattr.hxx"
50 : : #include "waitoff.hxx"
51 : : #include "globstr.hrc"
52 : : #include "markdata.hxx"
53 : :
54 : : using namespace ::com::sun::star;
55 : :
56 : : // ============================================================================
57 : :
58 : : namespace {
59 : :
60 : 0 : bool lclHasString( ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString )
61 : : {
62 [ # # ]: 0 : String aCompStr;
63 [ # # ]: 0 : rDoc.GetString( nCol, nRow, nTab, aCompStr );
64 [ # # ][ # # ]: 0 : return aCompStr == rString; //! case-insensitive?
65 : : }
66 : :
67 : : } // namespace
68 : :
69 : : // ----------------------------------------------------------------------------
70 : :
71 : 0 : ScConversionEngineBase::ScConversionEngineBase(
72 : : SfxItemPool* pEnginePoolP, ScViewData& rViewData,
73 : : ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
74 : : ScEditEngineDefaulter( pEnginePoolP ),
75 : : mrViewData( rViewData ),
76 : 0 : mrDocShell( *rViewData.GetDocShell() ),
77 : 0 : mrDoc( *rViewData.GetDocShell()->GetDocument() ),
78 : : maSelState( rViewData ),
79 : : mpUndoDoc( pUndoDoc ),
80 : : mpRedoDoc( pRedoDoc ),
81 : : meCurrLang( LANGUAGE_ENGLISH_US ),
82 : : mbIsAnyModified( false ),
83 : : mbInitialState( true ),
84 : : mbWrappedInTable( false ),
85 [ # # ]: 0 : mbFinished( false )
86 : : {
87 : 0 : maSelState.GetCellCursor().GetVars( mnStartCol, mnStartRow, mnStartTab );
88 : : // start with cell A1 in cell/range/multi-selection, will seek to first selected
89 [ # # ]: 0 : if( maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET )
90 : : {
91 : 0 : mnStartCol = 0;
92 : 0 : mnStartRow = 0;
93 : : }
94 : 0 : mnCurrCol = mnStartCol;
95 : 0 : mnCurrRow = mnStartRow;
96 : 0 : }
97 : :
98 [ # # ]: 0 : ScConversionEngineBase::~ScConversionEngineBase()
99 : : {
100 [ # # ]: 0 : }
101 : :
102 : 0 : bool ScConversionEngineBase::FindNextConversionCell()
103 : : {
104 [ # # ]: 0 : ScMarkData& rMark = mrViewData.GetMarkData();
105 : 0 : ScTabViewShell* pViewShell = mrViewData.GetViewShell();
106 : 0 : ScBaseCell* pCell = NULL;
107 : 0 : const ScPatternAttr* pPattern = NULL;
108 : 0 : const ScPatternAttr* pLastPattern = NULL;
109 [ # # ][ # # ]: 0 : ::std::auto_ptr< SfxItemSet > pEditDefaults( new SfxItemSet( GetEmptyItemSet() ) );
[ # # ]
110 : :
111 [ # # ][ # # ]: 0 : if( IsModified() )
112 : : {
113 : 0 : mbIsAnyModified = true;
114 : :
115 [ # # ]: 0 : String aNewStr = GetText();
116 : :
117 [ # # ]: 0 : sal_Bool bMultiTab = (rMark.GetSelectCount() > 1);
118 [ # # ]: 0 : String aVisibleStr;
119 [ # # ]: 0 : if( bMultiTab )
120 [ # # ]: 0 : mrDoc.GetString( mnCurrCol, mnCurrRow, mnStartTab, aVisibleStr );
121 : :
122 [ # # ][ # # ]: 0 : for( SCTAB nTab = 0, nTabCount = mrDoc.GetTableCount(); nTab < nTabCount; ++nTab )
123 : : {
124 : : // always change the cell on the visible tab,
125 : : // on the other selected tabs only if they contain the same text
126 : :
127 [ # # ][ # # ]: 0 : if( (nTab == mnStartTab) ||
[ # # ][ # # ]
[ # # ]
128 [ # # ]: 0 : (bMultiTab && rMark.GetTableSelect( nTab ) &&
129 [ # # ]: 0 : lclHasString( mrDoc, mnCurrCol, mnCurrRow, nTab, aVisibleStr )) )
130 : : {
131 : 0 : ScAddress aPos( mnCurrCol, mnCurrRow, nTab );
132 [ # # ]: 0 : CellType eCellType = mrDoc.GetCellType( aPos );
133 [ # # ]: 0 : pCell = mrDoc.GetCell( aPos );
134 : :
135 [ # # ][ # # ]: 0 : if( mpUndoDoc && pCell )
136 : : {
137 [ # # ]: 0 : ScBaseCell* pUndoCell = pCell->Clone( *mpUndoDoc );
138 [ # # ]: 0 : mpUndoDoc->PutCell( aPos, pUndoCell );
139 : : }
140 : :
141 [ # # ]: 0 : if( eCellType == CELLTYPE_EDIT )
142 : : {
143 [ # # ]: 0 : if( pCell )
144 : : {
145 : 0 : ScEditCell* pEditCell = static_cast< ScEditCell* >( pCell );
146 [ # # ]: 0 : ::std::auto_ptr< EditTextObject > pEditObj( CreateTextObject() );
147 [ # # ][ # # ]: 0 : pEditCell->SetData( pEditObj.get(), GetEditTextObjectPool() );
[ # # ]
148 : : }
149 : : }
150 : : else
151 : : {
152 [ # # ][ # # ]: 0 : mrDoc.SetString( mnCurrCol, mnCurrRow, nTab, aNewStr );
153 [ # # ]: 0 : pCell = mrDoc.GetCell( aPos );
154 : : }
155 : :
156 [ # # ][ # # ]: 0 : if( mpRedoDoc && pCell )
157 : : {
158 [ # # ]: 0 : ScBaseCell* pRedoCell = pCell->Clone( *mpRedoDoc );
159 [ # # ]: 0 : mpRedoDoc->PutCell( aPos, pRedoCell );
160 : : }
161 : :
162 [ # # ]: 0 : mrDocShell.PostPaintCell( mnCurrCol, mnCurrRow, nTab );
163 : : }
164 [ # # ][ # # ]: 0 : }
165 : : }
166 : 0 : pCell = NULL;
167 : 0 : SCCOL nNewCol = mnCurrCol;
168 : 0 : SCROW nNewRow = mnCurrRow;
169 : :
170 [ # # ]: 0 : if( mbInitialState )
171 : : {
172 : : /* On very first call, decrement row to let GetNextSpellingCell() find
173 : : the first cell of current range. */
174 : 0 : mbInitialState = false;
175 : 0 : --nNewRow;
176 : : }
177 : :
178 : 0 : bool bSheetSel = maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET;
179 : 0 : bool bLoop = true;
180 : 0 : bool bFound = false;
181 [ # # ][ # # ]: 0 : while( bLoop && !bFound )
[ # # ]
182 : : {
183 [ # # ]: 0 : bLoop = mrDoc.GetNextSpellingCell( nNewCol, nNewRow, mnStartTab, bSheetSel, rMark );
184 [ # # ]: 0 : if( bLoop )
185 : : {
186 [ # # ]: 0 : FillFromCell( mnCurrCol, mnCurrRow, mnStartTab );
187 : :
188 [ # # ][ # # ]: 0 : if( mbWrappedInTable && ((nNewCol > mnStartCol) || ((nNewCol == mnStartCol) && (nNewRow >= mnStartRow))) )
[ # # ][ # # ]
189 : : {
190 [ # # ]: 0 : ShowFinishDialog();
191 : 0 : bLoop = false;
192 : 0 : mbFinished = true;
193 : : }
194 [ # # ]: 0 : else if( nNewCol > MAXCOL )
195 : : {
196 : : // no more cells in the sheet - try to restart at top of sheet
197 : :
198 [ # # ][ # # ]: 0 : if( bSheetSel || ((mnStartCol == 0) && (mnStartRow == 0)) )
[ # # ]
199 : : {
200 : : // conversion started at cell A1 or in selection, do not query to restart at top
201 [ # # ]: 0 : ShowFinishDialog();
202 : 0 : bLoop = false;
203 : 0 : mbFinished = true;
204 : : }
205 [ # # ][ # # ]: 0 : else if( ShowTableWrapDialog() )
206 : : {
207 : : // conversion started anywhere but in cell A1, user wants to restart
208 : 0 : nNewRow = MAXROW + 2;
209 : 0 : mbWrappedInTable = true;
210 : : }
211 : : else
212 : : {
213 : 0 : bLoop = false;
214 : 0 : mbFinished = true;
215 : : }
216 : : }
217 : : else
218 : : {
219 [ # # ]: 0 : pPattern = mrDoc.GetPattern( nNewCol, nNewRow, mnStartTab );
220 [ # # ][ # # ]: 0 : if( pPattern && (pPattern != pLastPattern) )
221 : : {
222 [ # # ]: 0 : pPattern->FillEditItemSet( pEditDefaults.get() );
223 [ # # ]: 0 : SetDefaults( *pEditDefaults );
224 : 0 : pLastPattern = pPattern;
225 : : }
226 : :
227 : : // language changed?
228 [ # # ]: 0 : const SfxPoolItem* pItem = mrDoc.GetAttr( nNewCol, nNewRow, mnStartTab, ATTR_FONT_LANGUAGE );
229 [ # # ][ # # ]: 0 : if( const SvxLanguageItem* pLangItem = PTR_CAST( SvxLanguageItem, pItem ) )
[ # # ][ # # ]
[ # # ]
230 : : {
231 : 0 : LanguageType eLang = static_cast< LanguageType >( pLangItem->GetValue() );
232 [ # # ]: 0 : if( eLang == LANGUAGE_SYSTEM )
233 [ # # ][ # # ]: 0 : eLang = Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling
234 [ # # ]: 0 : if( eLang != meCurrLang )
235 : : {
236 : 0 : meCurrLang = eLang;
237 [ # # ]: 0 : SetDefaultLanguage( eLang );
238 : : }
239 : : }
240 : :
241 [ # # ]: 0 : FillFromCell( nNewCol, nNewRow, mnStartTab );
242 : :
243 [ # # ][ # # ]: 0 : bFound = bLoop && NeedsConversion();
[ # # ]
244 : : }
245 : : }
246 : : }
247 : :
248 [ # # ]: 0 : if( bFound )
249 : : {
250 [ # # ]: 0 : pViewShell->AlignToCursor( nNewCol, nNewRow, SC_FOLLOW_JUMP );
251 [ # # ]: 0 : pViewShell->SetCursor( nNewCol, nNewRow, sal_True );
252 [ # # ]: 0 : mrViewData.GetView()->MakeEditView( this, nNewCol, nNewRow );
253 : 0 : EditView* pEditView = mrViewData.GetSpellingView();
254 : : // maSelState.GetEditSelection() returns (0,0) if not in edit mode -> ok
255 [ # # ]: 0 : pEditView->SetSelection( maSelState.GetEditSelection() );
256 : :
257 [ # # ]: 0 : ClearModifyFlag();
258 : 0 : mnCurrCol = nNewCol;
259 : 0 : mnCurrRow = nNewRow;
260 : : }
261 : :
262 [ # # ]: 0 : return bFound;
263 : : }
264 : :
265 : 0 : void ScConversionEngineBase::RestoreCursorPos()
266 : : {
267 : 0 : const ScAddress& rPos = maSelState.GetCellCursor();
268 : 0 : mrViewData.GetViewShell()->SetCursor( rPos.Col(), rPos.Row() );
269 : 0 : }
270 : :
271 : 0 : bool ScConversionEngineBase::ShowTableWrapDialog()
272 : : {
273 : : // default: no dialog, always restart at top
274 : 0 : return true;
275 : : }
276 : :
277 : 0 : void ScConversionEngineBase::ShowFinishDialog()
278 : : {
279 : : // default: no dialog
280 : 0 : }
281 : :
282 : : // private --------------------------------------------------------------------
283 : :
284 : 0 : void ScConversionEngineBase::FillFromCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
285 : : {
286 : : CellType eCellType;
287 [ # # ]: 0 : mrDoc.GetCellType( nCol, nRow, nTab, eCellType );
288 : :
289 [ # # # ]: 0 : switch( eCellType )
290 : : {
291 : : case CELLTYPE_STRING:
292 : : {
293 [ # # ]: 0 : String aText;
294 [ # # ]: 0 : mrDoc.GetString( nCol, nRow, nTab, aText );
295 [ # # ][ # # ]: 0 : SetText( aText );
296 : : }
297 : 0 : break;
298 : : case CELLTYPE_EDIT:
299 : : {
300 : 0 : ScBaseCell* pCell = NULL;
301 [ # # ]: 0 : mrDoc.GetCell( nCol, nRow, nTab, pCell );
302 [ # # ]: 0 : if( pCell )
303 : : {
304 : 0 : const EditTextObject* pNewEditObj = NULL;
305 [ # # ]: 0 : static_cast< ScEditCell* >( pCell )->GetData( pNewEditObj );
306 [ # # ]: 0 : if( pNewEditObj )
307 [ # # ]: 0 : SetText( *pNewEditObj );
308 : : }
309 : : }
310 : 0 : break;
311 : : default:
312 [ # # ][ # # ]: 0 : SetText( EMPTY_STRING );
313 : : }
314 : 0 : }
315 : :
316 : : // ============================================================================
317 : :
318 : 0 : ScSpellingEngine::ScSpellingEngine(
319 : : SfxItemPool* pEnginePoolP, ScViewData& rViewData,
320 : : ScDocument* pUndoDoc, ScDocument* pRedoDoc,
321 : : XSpellCheckerRef xSpeller ) :
322 : 0 : ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc )
323 : : {
324 [ # # ]: 0 : SetSpeller( xSpeller );
325 : 0 : }
326 : :
327 : 0 : void ScSpellingEngine::ConvertAll( EditView& rEditView )
328 : : {
329 : 0 : EESpellState eState = EE_SPELL_OK;
330 [ # # ]: 0 : if( FindNextConversionCell() )
331 : 0 : eState = rEditView.StartSpeller( static_cast< sal_Bool >( sal_True ) );
332 : :
333 : : OSL_ENSURE( eState != EE_SPELL_NOSPELLER, "ScSpellingEngine::Convert - no spell checker" );
334 [ # # ]: 0 : if( eState == EE_SPELL_NOLANGUAGE )
335 : : {
336 [ # # ]: 0 : Window* pParent = GetDialogParent();
337 [ # # ]: 0 : ScWaitCursorOff aWaitOff( pParent );
338 [ # # ][ # # ]: 0 : InfoBox( pParent, ScGlobal::GetRscString( STR_NOLANGERR ) ).Execute();
[ # # ][ # # ]
[ # # ]
339 : : }
340 : 0 : }
341 : :
342 : 0 : sal_Bool ScSpellingEngine::SpellNextDocument()
343 : : {
344 : 0 : return FindNextConversionCell();
345 : : }
346 : :
347 : 0 : bool ScSpellingEngine::NeedsConversion()
348 : : {
349 : 0 : return HasSpellErrors() != EE_SPELL_OK;
350 : : }
351 : :
352 : 0 : bool ScSpellingEngine::ShowTableWrapDialog()
353 : : {
354 [ # # ]: 0 : Window* pParent = GetDialogParent();
355 [ # # ]: 0 : ScWaitCursorOff aWaitOff( pParent );
356 : : MessBox aMsgBox( pParent, WinBits( WB_YES_NO | WB_DEF_YES ),
357 [ # # ]: 0 : ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
358 [ # # ][ # # ]: 0 : ScGlobal::GetRscString( STR_SPELLING_BEGIN_TAB) );
359 [ # # ][ # # ]: 0 : return aMsgBox.Execute() == RET_YES;
[ # # ]
360 : : }
361 : :
362 : 0 : void ScSpellingEngine::ShowFinishDialog()
363 : : {
364 [ # # ]: 0 : Window* pParent = GetDialogParent();
365 [ # # ]: 0 : ScWaitCursorOff aWaitOff( pParent );
366 [ # # ][ # # ]: 0 : InfoBox( pParent, ScGlobal::GetRscString( STR_SPELLING_STOP_OK ) ).Execute();
[ # # ][ # # ]
[ # # ]
367 : 0 : }
368 : :
369 : 0 : Window* ScSpellingEngine::GetDialogParent()
370 : : {
371 : 0 : sal_uInt16 nWinId = ScSpellDialogChildWindow::GetChildWindowId();
372 : 0 : SfxViewFrame* pViewFrm = mrViewData.GetViewShell()->GetViewFrame();
373 [ # # ]: 0 : if( pViewFrm->HasChildWindow( nWinId ) )
374 [ # # ]: 0 : if( SfxChildWindow* pChild = pViewFrm->GetChildWindow( nWinId ) )
375 [ # # ]: 0 : if( Window* pWin = pChild->GetWindow() )
376 [ # # ]: 0 : if( pWin->IsVisible() )
377 : 0 : return pWin;
378 : :
379 : : // fall back to standard dialog parent
380 : 0 : return mrDocShell.GetActiveDialogParent();
381 : : }
382 : :
383 : : // ============================================================================
384 : :
385 : 0 : ScConversionParam::ScConversionParam( ScConversionType eConvType ) :
386 : : meConvType( eConvType ),
387 : : meSourceLang( LANGUAGE_NONE ),
388 : : meTargetLang( LANGUAGE_NONE ),
389 : : mnOptions( 0 ),
390 : : mbUseTargetFont( false ),
391 : 0 : mbIsInteractive( false )
392 : : {
393 : 0 : }
394 : :
395 : 0 : ScConversionParam::ScConversionParam( ScConversionType eConvType,
396 : : LanguageType eLang, sal_Int32 nOptions, bool bIsInteractive ) :
397 : : meConvType( eConvType ),
398 : : meSourceLang( eLang ),
399 : : meTargetLang( eLang ),
400 : : mnOptions( nOptions ),
401 : : mbUseTargetFont( false ),
402 : 0 : mbIsInteractive( bIsInteractive )
403 : : {
404 [ # # ]: 0 : if (LANGUAGE_KOREAN == eLang)
405 : 0 : mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
406 : 0 : }
407 : :
408 : 0 : ScConversionParam::ScConversionParam( ScConversionType eConvType,
409 : : LanguageType eSourceLang, LanguageType eTargetLang, const Font& rTargetFont,
410 : : sal_Int32 nOptions, bool bIsInteractive ) :
411 : : meConvType( eConvType ),
412 : : meSourceLang( eSourceLang ),
413 : : meTargetLang( eTargetLang ),
414 : : maTargetFont( rTargetFont ),
415 : : mnOptions( nOptions ),
416 : : mbUseTargetFont( true ),
417 : 0 : mbIsInteractive( bIsInteractive )
418 : : {
419 [ # # ][ # # ]: 0 : if (LANGUAGE_KOREAN == meSourceLang && LANGUAGE_KOREAN == meTargetLang)
420 : 0 : mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
421 : 0 : }
422 : :
423 : : // ----------------------------------------------------------------------------
424 : :
425 : 0 : ScTextConversionEngine::ScTextConversionEngine(
426 : : SfxItemPool* pEnginePoolP, ScViewData& rViewData,
427 : : const ScConversionParam& rConvParam,
428 : : ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
429 : : ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc ),
430 [ # # ]: 0 : maConvParam( rConvParam )
431 : : {
432 : 0 : }
433 : :
434 : 0 : void ScTextConversionEngine::ConvertAll( EditView& rEditView )
435 : : {
436 [ # # ]: 0 : if( FindNextConversionCell() )
437 : : {
438 : : rEditView.StartTextConversion(
439 : 0 : maConvParam.GetSourceLang(), maConvParam.GetTargetLang(), maConvParam.GetTargetFont(),
440 : 0 : maConvParam.GetOptions(), maConvParam.IsInteractive(), sal_True );
441 : : // #i34769# restore initial cursor position
442 : 0 : RestoreCursorPos();
443 : : }
444 : 0 : }
445 : :
446 : 0 : sal_Bool ScTextConversionEngine::ConvertNextDocument()
447 : : {
448 : 0 : return FindNextConversionCell();
449 : : }
450 : :
451 : 0 : bool ScTextConversionEngine::NeedsConversion()
452 : : {
453 : 0 : return HasConvertibleTextPortion( maConvParam.GetSourceLang() );
454 : : }
455 : :
456 : : // ============================================================================
457 : :
458 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|