summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/view/spelldialog.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/view/spelldialog.cxx')
-rw-r--r--sc/source/ui/view/spelldialog.cxx281
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: */