Files
libreoffice/sc/source/ui/view/spelleng.cxx

405 lines
13 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
re-base on ALv2 code. Includes: Patches contributed by Herbert Duerr i#118735 prevent endless loop if vlookup/hlookup doesn't find anything http://svn.apache.org/viewvc?view=revision&revision=1239673 Patches contributed by Andre Fischer remove lp_solver http://svn.apache.org/viewvc?view=revision&revision=1199180 i#118160: Added external CoinMP library. http://svn.apache.org/viewvc?view=revision&revision=1233909 Patches contributed by Armin Le-Grand i#118485 - Styles for OLEs are not saved. http://svn.apache.org/viewvc?view=revision&revision=1182166 i#118524: apply patch, followup fixes to 118485 http://svn.apache.org/viewvc?view=revision&revision=1186077 Patches contributed by lihuiibm i#108860 - Fix range validation. http://svn.apache.org/viewvc?view=revision&revision=1242846 i#118954 Chart data will lost after copy to different file http://svn.apache.org/viewvc?view=revision&revision=1301345 Patches contributed by Ariel Constenla-Haile Fix Linux build breaker: extra qualification on member http://svn.apache.org/viewvc?view=revision&revision=1301591 i#118696 - i#118697 - Fix some Sheet Tab Color API issues http://svn.apache.org/viewvc?view=revision&revision=1225428 i#118697 - Fix uninitialized variable http://svn.apache.org/viewvc?view=revision&revision=1225859 i#118771 - ScUndoImportTab should preserve tab background color http://svn.apache.org/viewvc?view=revision&revision=1230356 i#118921 - Repaint linked sheet tab background color after updating link http://svn.apache.org/viewvc?view=revision&revision=1245177 i#118927 - Undo/Redo "Update Link" does not reset sheet tab color http://svn.apache.org/viewvc?view=revision&revision=1245241 i#118747 - Copy tab color when transferring sheets across documents http://svn.apache.org/viewvc?view=revision&revision=1230355 Patch contributed by Oliver Rainer-Wittman i#118012 - methods <ScBroadcastAreaSlot::AreaBroadcast(..)> and <ScBroadcastAreaSlot::AreaBroadcastInRange(..)> adapt stl-container iteration in order to avoid destroyed iterators during iteration. http://svn.apache.org/viewvc?view=revision&revision=1297916 Patches contributed by Mathias Bauer gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394707 http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 Patch contributed by Daniel Rentz calc69: #i116936# fix VBA symbol Cells http://svn.apache.org/viewvc?view=revision&revision=1172135 Patches contributed by leiw: i#118546 CPU 100% on switched off AutoCalculate with Conditional Formatting on date values http://svn.apache.org/viewvc?view=revision&revision=1301380 Re-add new function documentation. Many various cleanups. Add missing calc66: #o11817313# also look at formula result number format, remove redundant binaries.
2012-11-30 12:23:25 +00:00
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "spelleng.hxx"
#include <com/sun/star/i18n/TextConversionOption.hpp>
2000-09-18 16:07:07 +00:00
#include "scitems.hxx"
#include <editeng/eeitem.hxx>
#include <editeng/langitem.hxx>
#include <editeng/editobj.hxx>
#include <editeng/editview.hxx>
#include <sfx2/viewfrm.hxx>
2000-09-18 16:07:07 +00:00
#include <vcl/msgbox.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
2000-09-18 16:07:07 +00:00
#include "spelldialog.hxx"
2000-09-18 16:07:07 +00:00
#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "formulacell.hxx"
2000-09-18 16:07:07 +00:00
#include "patattr.hxx"
#include "waitoff.hxx"
#include "globstr.hrc"
#include "markdata.hxx"
#include <boost/scoped_ptr.hpp>
using namespace ::com::sun::star;
ScConversionEngineBase::ScConversionEngineBase(
SfxItemPool* pEnginePoolP, ScViewData& rViewData,
ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
ScEditEngineDefaulter( pEnginePoolP ),
mrViewData( rViewData ),
mrDocShell( *rViewData.GetDocShell() ),
mrDoc( rViewData.GetDocShell()->GetDocument() ),
maSelState( rViewData ),
mpUndoDoc( pUndoDoc ),
mpRedoDoc( pRedoDoc ),
meCurrLang( LANGUAGE_ENGLISH_US ),
mbIsAnyModified( false ),
mbInitialState( true ),
mbWrappedInTable( false ),
mbFinished( false )
2000-09-18 16:07:07 +00:00
{
maSelState.GetCellCursor().GetVars( mnStartCol, mnStartRow, mnStartTab );
// start with cell A1 in cell/range/multi-selection, will seek to first selected
if( maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET )
{
mnStartCol = 0;
mnStartRow = 0;
}
mnCurrCol = mnStartCol;
mnCurrRow = mnStartRow;
}
ScConversionEngineBase::~ScConversionEngineBase()
{
}
bool ScConversionEngineBase::FindNextConversionCell()
{
ScMarkData& rMark = mrViewData.GetMarkData();
ScTabViewShell* pViewShell = mrViewData.GetViewShell();
2000-09-18 16:07:07 +00:00
const ScPatternAttr* pPattern = NULL;
const ScPatternAttr* pLastPattern = NULL;
boost::scoped_ptr<SfxItemSet> pEditDefaults(new SfxItemSet(GetEmptyItemSet()));
2000-09-18 16:07:07 +00:00
if( IsModified() )
2000-09-18 16:07:07 +00:00
{
mbIsAnyModified = true;
2000-09-18 16:07:07 +00:00
OUString aNewStr = GetText();
2000-09-18 16:07:07 +00:00
bool bMultiTab = (rMark.GetSelectCount() > 1);
OUString aVisibleStr;
if( bMultiTab )
aVisibleStr = mrDoc.GetString(mnCurrCol, mnCurrRow, mnStartTab);
2000-09-18 16:07:07 +00:00
for( SCTAB nTab = 0, nTabCount = mrDoc.GetTableCount(); nTab < nTabCount; ++nTab )
2000-09-18 16:07:07 +00:00
{
2011-03-02 21:32:00 +01:00
// always change the cell on the visible tab,
2000-09-18 16:07:07 +00:00
// on the other selected tabs only if they contain the same text
if ((nTab == mnStartTab) ||
(bMultiTab && rMark.GetTableSelect(nTab) && mrDoc.GetString(mnCurrCol, mnCurrRow, nTab) == aVisibleStr))
2000-09-18 16:07:07 +00:00
{
ScAddress aPos( mnCurrCol, mnCurrRow, nTab );
CellType eCellType = mrDoc.GetCellType( aPos );
bool bEmptyCell = eCellType == CELLTYPE_NONE;
if (mpUndoDoc && !bEmptyCell)
mrDoc.CopyCellToDocument(aPos, aPos, *mpUndoDoc);
if (eCellType == CELLTYPE_EDIT)
2000-09-18 16:07:07 +00:00
{
boost::scoped_ptr<EditTextObject> pEditObj(CreateTextObject());
mrDoc.SetEditText(aPos, *pEditObj, GetEditTextObjectPool());
2000-09-18 16:07:07 +00:00
}
else
mrDoc.SetString(aPos, aNewStr);
if (mpRedoDoc && !bEmptyCell)
mrDoc.CopyCellToDocument(aPos, aPos, *mpRedoDoc);
mrDocShell.PostPaintCell(aPos);
2000-09-18 16:07:07 +00:00
}
}
}
SCCOL nNewCol = mnCurrCol;
SCROW nNewRow = mnCurrRow;
if( mbInitialState )
2000-09-18 16:07:07 +00:00
{
/* On very first call, decrement row to let GetNextSpellingCell() find
the first cell of current range. */
mbInitialState = false;
--nNewRow;
2000-09-18 16:07:07 +00:00
}
bool bSheetSel = maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET;
bool bLoop = true;
bool bFound = false;
while( bLoop && !bFound )
2000-09-18 16:07:07 +00:00
{
bLoop = mrDoc.GetNextSpellingCell( nNewCol, nNewRow, mnStartTab, bSheetSel, rMark );
if( bLoop )
2000-09-18 16:07:07 +00:00
{
FillFromCell( mnCurrCol, mnCurrRow, mnStartTab );
2000-09-18 16:07:07 +00:00
if( mbWrappedInTable && ((nNewCol > mnStartCol) || ((nNewCol == mnStartCol) && (nNewRow >= mnStartRow))) )
{
ShowFinishDialog();
bLoop = false;
mbFinished = true;
2000-09-18 16:07:07 +00:00
}
else if( nNewCol > MAXCOL )
2000-09-18 16:07:07 +00:00
{
// no more cells in the sheet - try to restart at top of sheet
2000-09-18 16:07:07 +00:00
if( bSheetSel || ((mnStartCol == 0) && (mnStartRow == 0)) )
{
// conversion started at cell A1 or in selection, do not query to restart at top
ShowFinishDialog();
bLoop = false;
mbFinished = true;
2000-09-18 16:07:07 +00:00
}
else if( ShowTableWrapDialog() )
2000-09-18 16:07:07 +00:00
{
// conversion started anywhere but in cell A1, user wants to restart
nNewRow = MAXROW + 2;
mbWrappedInTable = true;
2000-09-18 16:07:07 +00:00
}
else
{
bLoop = false;
mbFinished = true;
}
2000-09-18 16:07:07 +00:00
}
else
2000-09-18 16:07:07 +00:00
{
pPattern = mrDoc.GetPattern( nNewCol, nNewRow, mnStartTab );
if( pPattern && (pPattern != pLastPattern) )
2000-09-18 16:07:07 +00:00
{
pPattern->FillEditItemSet( pEditDefaults.get() );
2000-09-18 16:07:07 +00:00
SetDefaults( *pEditDefaults );
pLastPattern = pPattern;
}
// language changed?
const SfxPoolItem* pItem = mrDoc.GetAttr( nNewCol, nNewRow, mnStartTab, ATTR_FONT_LANGUAGE );
if( const SvxLanguageItem* pLangItem = PTR_CAST( SvxLanguageItem, pItem ) )
2000-09-18 16:07:07 +00:00
{
LanguageType eLang = static_cast< LanguageType >( pLangItem->GetValue() );
if( eLang == LANGUAGE_SYSTEM )
eLang = Application::GetSettings().GetLanguageTag().getLanguageType(); // never use SYSTEM for spelling
if( eLang != meCurrLang )
2000-09-18 16:07:07 +00:00
{
meCurrLang = eLang;
SetDefaultLanguage( eLang );
2000-09-18 16:07:07 +00:00
}
}
FillFromCell( nNewCol, nNewRow, mnStartTab );
bFound = bLoop && NeedsConversion();
2000-09-18 16:07:07 +00:00
}
}
}
if( bFound )
{
pViewShell->AlignToCursor( nNewCol, nNewRow, SC_FOLLOW_JUMP );
pViewShell->SetCursor( nNewCol, nNewRow, true );
mrViewData.GetView()->MakeEditView( this, nNewCol, nNewRow );
EditView* pEditView = mrViewData.GetSpellingView();
// maSelState.GetEditSelection() returns (0,0) if not in edit mode -> ok
pEditView->SetSelection( maSelState.GetEditSelection() );
ClearModifyFlag();
mnCurrCol = nNewCol;
mnCurrRow = nNewRow;
}
return bFound;
}
void ScConversionEngineBase::RestoreCursorPos()
{
const ScAddress& rPos = maSelState.GetCellCursor();
mrViewData.GetViewShell()->SetCursor( rPos.Col(), rPos.Row() );
}
bool ScConversionEngineBase::ShowTableWrapDialog()
{
// default: no dialog, always restart at top
return true;
}
void ScConversionEngineBase::ShowFinishDialog()
{
// default: no dialog
}
// private --------------------------------------------------------------------
void ScConversionEngineBase::FillFromCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
{
ScAddress aPos(nCol, nRow, nTab);
switch (mrDoc.GetCellType(aPos))
{
case CELLTYPE_STRING:
{
OUString aText = mrDoc.GetString(aPos);
SetText( aText );
}
break;
case CELLTYPE_EDIT:
{
const EditTextObject* pNewEditObj = mrDoc.GetEditText(aPos);
if (pNewEditObj)
SetText(*pNewEditObj);
}
break;
default:
SetText(EMPTY_OUSTRING);
2000-09-18 16:07:07 +00:00
}
}
ScSpellingEngine::ScSpellingEngine(
SfxItemPool* pEnginePoolP, ScViewData& rViewData,
ScDocument* pUndoDoc, ScDocument* pRedoDoc,
css::uno::Reference< css::linguistic2::XSpellChecker1 > xSpeller ) :
ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc )
{
SetSpeller( xSpeller );
}
void ScSpellingEngine::ConvertAll( EditView& rEditView )
{
EESpellState eState = EE_SPELL_OK;
if( FindNextConversionCell() )
eState = rEditView.StartSpeller( true );
OSL_ENSURE( eState != EE_SPELL_NOSPELLER, "ScSpellingEngine::Convert - no spell checker" );
if( eState == EE_SPELL_NOLANGUAGE )
2000-09-18 16:07:07 +00:00
{
vcl::Window* pParent = GetDialogParent();
ScWaitCursorOff aWaitOff( pParent );
ScopedVclPtr<InfoBox>::Create( pParent, ScGlobal::GetRscString( STR_NOLANGERR ) )->Execute();
2000-09-18 16:07:07 +00:00
}
}
bool ScSpellingEngine::SpellNextDocument()
{
return FindNextConversionCell();
}
bool ScSpellingEngine::NeedsConversion()
{
return HasSpellErrors() != EE_SPELL_OK;
}
bool ScSpellingEngine::ShowTableWrapDialog()
{
vcl::Window* pParent = GetDialogParent();
ScWaitCursorOff aWaitOff( pParent );
ScopedVclPtrInstance<MessBox> aMsgBox( pParent, WinBits( WB_YES_NO | WB_DEF_YES ),
ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
ScGlobal::GetRscString( STR_SPELLING_BEGIN_TAB) );
return aMsgBox->Execute() == RET_YES;
}
void ScSpellingEngine::ShowFinishDialog()
{
vcl::Window* pParent = GetDialogParent();
ScWaitCursorOff aWaitOff( pParent );
ScopedVclPtr<InfoBox>::Create( pParent, ScGlobal::GetRscString( STR_SPELLING_STOP_OK ) )->Execute();
}
vcl::Window* ScSpellingEngine::GetDialogParent()
{
sal_uInt16 nWinId = ScSpellDialogChildWindow::GetChildWindowId();
SfxViewFrame* pViewFrm = mrViewData.GetViewShell()->GetViewFrame();
if( pViewFrm->HasChildWindow( nWinId ) )
if( SfxChildWindow* pChild = pViewFrm->GetChildWindow( nWinId ) )
if( vcl::Window* pWin = pChild->GetWindow() )
if( pWin->IsVisible() )
return pWin;
// fall back to standard dialog parent
return ScDocShell::GetActiveDialogParent();
}
ScConversionParam::ScConversionParam( ScConversionType eConvType ) :
meConvType( eConvType ),
meSourceLang( LANGUAGE_NONE ),
meTargetLang( LANGUAGE_NONE ),
mnOptions( 0 ),
mbUseTargetFont( false ),
mbIsInteractive( false )
{
}
ScConversionParam::ScConversionParam( ScConversionType eConvType,
LanguageType eLang, sal_Int32 nOptions, bool bIsInteractive ) :
meConvType( eConvType ),
meSourceLang( eLang ),
meTargetLang( eLang ),
mnOptions( nOptions ),
mbUseTargetFont( false ),
mbIsInteractive( bIsInteractive )
{
if (LANGUAGE_KOREAN == eLang)
mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
}
ScConversionParam::ScConversionParam( ScConversionType eConvType,
LanguageType eSourceLang, LanguageType eTargetLang, const vcl::Font& rTargetFont,
sal_Int32 nOptions, bool bIsInteractive ) :
meConvType( eConvType ),
meSourceLang( eSourceLang ),
meTargetLang( eTargetLang ),
maTargetFont( rTargetFont ),
mnOptions( nOptions ),
mbUseTargetFont( true ),
mbIsInteractive( bIsInteractive )
{
if (LANGUAGE_KOREAN == meSourceLang && LANGUAGE_KOREAN == meTargetLang)
mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
}
ScTextConversionEngine::ScTextConversionEngine(
SfxItemPool* pEnginePoolP, ScViewData& rViewData,
const ScConversionParam& rConvParam,
ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc ),
maConvParam( rConvParam )
{
}
void ScTextConversionEngine::ConvertAll( EditView& rEditView )
{
if( FindNextConversionCell() )
{
rEditView.StartTextConversion(
maConvParam.GetSourceLang(), maConvParam.GetTargetLang(), maConvParam.GetTargetFont(),
maConvParam.GetOptions(), maConvParam.IsInteractive(), true );
// #i34769# restore initial cursor position
RestoreCursorPos();
}
}
2000-09-18 16:07:07 +00:00
bool ScTextConversionEngine::ConvertNextDocument()
{
return FindNextConversionCell();
}
bool ScTextConversionEngine::NeedsConversion()
{
return HasConvertibleTextPortion( maConvParam.GetSourceLang() );
}
2000-09-18 16:07:07 +00:00
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */