diff options
Diffstat (limited to 'sc/source/ui/view/spelldialog.cxx')
-rw-r--r-- | sc/source/ui/view/spelldialog.cxx | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/sc/source/ui/view/spelldialog.cxx b/sc/source/ui/view/spelldialog.cxx new file mode 100644 index 000000000..da1e90698 --- /dev/null +++ b/sc/source/ui/view/spelldialog.cxx @@ -0,0 +1,281 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 <spelldialog.hxx> + +#include <sfx2/bindings.hxx> +#include <svx/svxids.hrc> +#include <editeng/editstat.hxx> +#include <editeng/editview.hxx> +#include <editeng/unolingu.hxx> +#include <selectionstate.hxx> +#include <osl/diagnose.h> + +#include <spelleng.hxx> +#include <tabvwsh.hxx> +#include <docsh.hxx> +#include <scmod.hxx> +#include <editable.hxx> +#include <undoblk.hxx> +#include <gridwin.hxx> +#include <refupdatecontext.hxx> +#include <vcl/svapp.hxx> + +SFX_IMPL_CHILDWINDOW_WITHID( ScSpellDialogChildWindow, SID_SPELL_DIALOG ) + +ScSpellDialogChildWindow::ScSpellDialogChildWindow( vcl::Window* pParentP, sal_uInt16 nId, + SfxBindings* pBindings, SAL_UNUSED_PARAMETER SfxChildWinInfo* /*pInfo*/ ) : + svx::SpellDialogChildWindow( pParentP, nId, pBindings ), + mpViewShell( nullptr ), + mpViewData( nullptr ), + mpDocShell( nullptr ), + mpDoc( nullptr ), + mbNeedNextObj( false ), + mbOldIdleEnabled(true) +{ + Init(); +} + +ScSpellDialogChildWindow::~ScSpellDialogChildWindow() +{ + Reset(); +} + +SfxChildWinInfo ScSpellDialogChildWindow::GetInfo() const +{ + return svx::SpellDialogChildWindow::GetInfo(); +} + +void ScSpellDialogChildWindow::InvalidateSpellDialog() +{ + svx::SpellDialogChildWindow::InvalidateSpellDialog(); +} + +// protected ------------------------------------------------------------------ + +svx::SpellPortions ScSpellDialogChildWindow::GetNextWrongSentence( bool /*bRecheck*/ ) +{ + svx::SpellPortions aPortions; + if( mxEngine && mpViewData ) + { + if( EditView* pEditView = mpViewData->GetSpellingView() ) + { + // edit engine handles cell iteration internally + do + { + if( mbNeedNextObj ) + mxEngine->SpellNextDocument(); + mbNeedNextObj = !mxEngine->IsFinished() && !mxEngine->SpellSentence( *pEditView, aPortions ); + } + while( mbNeedNextObj ); + } + } + return aPortions; +} + +void ScSpellDialogChildWindow::ApplyChangedSentence( const svx::SpellPortions& rChanged, bool bRecheck ) +{ + if( mxEngine && mpViewData ) + if( EditView* pEditView = mpViewData->GetSpellingView() ) + { + mxEngine->ApplyChangedSentence( *pEditView, rChanged, bRecheck ); + + // Reset the spell checking results to clear the markers. + mpViewData->GetActiveWin()->ResetAutoSpell(); + } +} + +void ScSpellDialogChildWindow::GetFocus() +{ + SolarMutexGuard aGuard; + + if( IsSelectionChanged() ) + { + Reset(); + InvalidateSpellDialog(); + Init(); + } +} + +void ScSpellDialogChildWindow::LoseFocus() +{ +} + +// private -------------------------------------------------------------------- + +void ScSpellDialogChildWindow::Reset() +{ + if( mpViewShell && (mpViewShell == dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() )) ) + { + if( mxEngine && mxEngine->IsAnyModified() ) + { + const ScAddress& rCursor = mxOldSel->GetCellCursor(); + SCTAB nTab = rCursor.Tab(); + SCCOL nOldCol = rCursor.Col(); + SCROW nOldRow = rCursor.Row(); + SCCOL nNewCol = mpViewData->GetCurX(); + SCROW nNewRow = mpViewData->GetCurY(); + mpDocShell->GetUndoManager()->AddUndoAction( std::make_unique<ScUndoConversion>( + mpDocShell, mpViewData->GetMarkData(), + nOldCol, nOldRow, nTab, std::move(mxUndoDoc), + nNewCol, nNewRow, nTab, std::move(mxRedoDoc), + ScConversionParam( SC_CONVERSION_SPELLCHECK ) ) ); + + sc::SetFormulaDirtyContext aCxt; + mpDoc->SetAllFormulasDirty(aCxt); + + mpDocShell->SetDocumentModified(); + } + + mpViewData->SetSpellingView( nullptr ); + mpViewShell->KillEditView( true ); + mpDocShell->PostPaintGridAll(); + mpViewShell->UpdateInputHandler(); + mpDoc->EnableIdle(mbOldIdleEnabled); + } + mxEngine.reset(); + mxUndoDoc.reset(); + mxRedoDoc.reset(); + mxOldSel.reset(); + mxOldRangeList.clear(); + mpViewShell = nullptr; + mpViewData = nullptr; + mpDocShell = nullptr; + mpDoc = nullptr; + mbNeedNextObj = false; + mbOldIdleEnabled = true; +} + +void ScSpellDialogChildWindow::Init() +{ + if( mpViewShell ) + return; + if( (mpViewShell = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() )) == nullptr ) + return; + + mpViewData = &mpViewShell->GetViewData(); + + // exit edit mode - TODO support spelling in edit mode + if( mpViewData->HasEditView( mpViewData->GetActivePart() ) ) + SC_MOD()->InputEnterHandler(); + + mxOldSel.reset( new ScSelectionState( *mpViewData ) ); + + mpDocShell = mpViewData->GetDocShell(); + mpDoc = &mpDocShell->GetDocument(); + + const ScAddress& rCursor = mxOldSel->GetCellCursor(); + SCCOL nCol = rCursor.Col(); + SCROW nRow = rCursor.Row(); + SCTAB nTab = rCursor.Tab(); + + ScMarkData& rMarkData = mpViewData->GetMarkData(); + + mxOldRangeList = new ScRangeList; + rMarkData.FillRangeListWithMarks(mxOldRangeList.get(), true); + + rMarkData.MarkToMulti(); + + switch( mxOldSel->GetSelectionType() ) + { + case SC_SELECTTYPE_NONE: + case SC_SELECTTYPE_SHEET: + { + // test if there is something editable + ScEditableTester aTester( *mpDoc, rMarkData ); + if( !aTester.IsEditable() ) + { + // #i85751# Don't show an ErrorMessage here, because the vcl + // parent of the InfoBox is not fully initialized yet. + // This leads to problems in the modality behaviour of the + // ScSpellDialogChildWindow. + + //mpViewShell->ErrorMessage( aTester.GetMessageId() ); + return; + } + } + break; + + // edit mode exited, see TODO above +// case SC_SELECTTYPE_EDITCELL: +// break; + + default: + OSL_FAIL( "ScSpellDialogChildWindow::Init - unknown selection type" ); + } + + mbOldIdleEnabled = mpDoc->IsIdleEnabled(); + mpDoc->EnableIdle(false); // stop online spelling + + // *** create Undo/Redo documents *** ------------------------------------- + + mxUndoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) ); + mxUndoDoc->InitUndo( *mpDoc, nTab, nTab ); + mxRedoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) ); + mxRedoDoc->InitUndo( *mpDoc, nTab, nTab ); + + if ( rMarkData.GetSelectCount() > 1 ) + { + for (const auto& rTab : rMarkData) + { + if( rTab != nTab ) + { + mxUndoDoc->AddUndoTab( rTab, rTab ); + mxRedoDoc->AddUndoTab( rTab, rTab ); + } + } + } + + // *** create and init the edit engine *** -------------------------------- + + mxEngine.reset( new ScSpellingEngine( + mpDoc->GetEnginePool(), *mpViewData, mxUndoDoc.get(), mxRedoDoc.get(), LinguMgr::GetSpellChecker() ) ); + mxEngine->SetRefDevice( mpViewData->GetActiveWin()->GetOutDev() ); + + mpViewShell->MakeEditView( mxEngine.get(), nCol, nRow ); + EditView* pEditView = mpViewData->GetEditView( mpViewData->GetActivePart() ); + mpViewData->SetSpellingView( pEditView ); + tools::Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) ); + pEditView->SetOutputArea( aRect ); + mxEngine->SetControlWord( EEControlBits::USECHARATTRIBS ); + mxEngine->EnableUndo( false ); + mxEngine->SetPaperSize( aRect.GetSize() ); + mxEngine->SetTextCurrentDefaults( OUString() ); + mxEngine->ClearModifyFlag(); + + mbNeedNextObj = true; +} + +bool ScSpellDialogChildWindow::IsSelectionChanged() +{ + if (!mxOldRangeList || !mpViewShell + || (mpViewShell != dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()))) + return true; + + if( EditView* pEditView = mpViewData->GetSpellingView() ) + if( pEditView->GetEditEngine() != mxEngine.get() ) + return true; + + ScRangeList aCurrentRangeList; + mpViewData->GetMarkData().FillRangeListWithMarks(&aCurrentRangeList, true); + + return (*mxOldRangeList != aCurrentRangeList); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |