summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/view/editsh.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/view/editsh.cxx')
-rw-r--r--sc/source/ui/view/editsh.cxx1367
1 files changed, 1367 insertions, 0 deletions
diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx
new file mode 100644
index 000000000..796000efe
--- /dev/null
+++ b/sc/source/ui/view/editsh.cxx
@@ -0,0 +1,1367 @@
+/* -*- 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 <comphelper/string.hxx>
+#include <scitems.hxx>
+#include <editeng/eeitem.hxx>
+#include <i18nutil/unicode.hxx>
+#include <i18nutil/transliteration.hxx>
+
+#include <svx/clipfmtitem.hxx>
+#include <svx/svxdlg.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/urlfieldhelper.hxx>
+#include <svx/hlnkitem.hxx>
+#include <vcl/EnumContext.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svtools/cliplistener.hxx>
+#include <svl/whiter.hxx>
+#include <sot/formats.hxx>
+#include <vcl/transfer.hxx>
+#include <vcl/unohelp2.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/colritem.hxx>
+
+#include <editsh.hxx>
+#include <global.hxx>
+#include <sc.hrc>
+#include <scmod.hxx>
+#include <inputhdl.hxx>
+#include <viewutil.hxx>
+#include <viewdata.hxx>
+#include <document.hxx>
+#include <reffind.hxx>
+#include <tabvwsh.hxx>
+#include <editutil.hxx>
+#include <globstr.hrc>
+#include <scresid.hxx>
+#include <gridwin.hxx>
+
+#define ShellClass_ScEditShell
+#include <scslots.hxx>
+
+#include <scui_def.hxx>
+#include <scabstdlg.hxx>
+#include <memory>
+
+using namespace ::com::sun::star;
+
+
+SFX_IMPL_INTERFACE(ScEditShell, SfxShell)
+
+void ScEditShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterPopupMenu("celledit");
+}
+
+ScEditShell::ScEditShell(EditView* pView, ScViewData& rData) :
+ pEditView (pView),
+ rViewData (rData),
+ bPastePossible (false),
+ bIsInsertMode (true)
+{
+ SetPool( pEditView->GetEditEngine()->GetEmptyItemSet().GetPool() );
+ SetUndoManager( &pEditView->GetEditEngine()->GetUndoManager() );
+ SetName("EditCell");
+ SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::EditCell));
+}
+
+ScEditShell::~ScEditShell()
+{
+ if ( mxClipEvtLstnr.is() )
+ {
+ mxClipEvtLstnr->RemoveListener( rViewData.GetActiveWin() );
+
+ // The listener may just now be waiting for the SolarMutex and call the link
+ // afterwards, in spite of RemoveListener. So the link has to be reset, too.
+ mxClipEvtLstnr->ClearCallbackLink();
+ }
+}
+
+ScInputHandler* ScEditShell::GetMyInputHdl()
+{
+ return SC_MOD()->GetInputHdl( rViewData.GetViewShell() );
+}
+
+void ScEditShell::SetEditView(EditView* pView)
+{
+ pEditView = pView;
+ pEditView->SetInsertMode( bIsInsertMode );
+ SetPool( pEditView->GetEditEngine()->GetEmptyItemSet().GetPool() );
+ SetUndoManager( &pEditView->GetEditEngine()->GetUndoManager() );
+}
+
+static void lcl_RemoveAttribs( EditView& rEditView )
+{
+ ScEditEngineDefaulter* pEngine = static_cast<ScEditEngineDefaulter*>(rEditView.GetEditEngine());
+
+ bool bOld = pEngine->SetUpdateLayout(false);
+
+ OUString aName = ScResId( STR_UNDO_DELETECONTENTS );
+ ViewShellId nViewShellId(-1);
+ if (ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell())
+ nViewShellId = pViewSh->GetViewShellId();
+ pEngine->GetUndoManager().EnterListAction( aName, aName, 0, nViewShellId );
+
+ rEditView.RemoveAttribs(true);
+ pEngine->RepeatDefaults(); // paragraph attributes from cell formats must be preserved
+
+ pEngine->GetUndoManager().LeaveListAction();
+
+ pEngine->SetUpdateLayout(bOld);
+}
+
+static void lclInsertCharacter( EditView* pTableView, EditView* pTopView, sal_Unicode cChar )
+{
+ OUString aString( cChar );
+ if( pTableView )
+ pTableView->InsertText( aString );
+ if( pTopView )
+ pTopView->InsertText( aString );
+}
+
+void ScEditShell::Execute( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ SfxBindings& rBindings = rViewData.GetBindings();
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ OSL_ENSURE(pHdl,"no ScInputHandler");
+
+ EditView* pTopView = pHdl->GetTopView(); // Has thee input cell the focus?
+ EditView* pTableView = pHdl->GetTableView();
+
+ OSL_ENSURE(pTableView,"no EditView :-(");
+ /* #i91683# No EditView if spell-check dialog is active and positioned on
+ * an error and user immediately (without double click or F2) selected a
+ * text portion of that cell with the mouse and wanted to modify it. */
+ /* FIXME: Bailing out only cures the symptom and prevents a crash, no edit
+ * action is possible. A real fix somehow would need to create a valid
+ * EditView from the spell-check view. */
+ if (!pTableView)
+ return;
+
+ EditEngine* pEngine = pTableView->GetEditEngine();
+
+ pHdl->DataChanging();
+ bool bSetSelIsRef = false;
+ bool bSetModified = true;
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_INSERT:
+ case FID_INS_CELL_CONTENTS: // Insert taste, while defined as Acc
+ bIsInsertMode = !pTableView->IsInsertMode();
+ pTableView->SetInsertMode( bIsInsertMode );
+ if (pTopView)
+ pTopView->SetInsertMode( bIsInsertMode );
+ rBindings.Invalidate( SID_ATTR_INSERT );
+ break;
+
+ case SID_THES:
+ {
+ OUString aReplaceText;
+ const SfxStringItem* pItem2 = rReq.GetArg(FN_PARAM_THES_WORD_REPLACE);
+ if (pItem2)
+ aReplaceText = pItem2->GetValue();
+ if (!aReplaceText.isEmpty())
+ ReplaceTextWithSynonym( *pEditView, aReplaceText );
+ }
+ break;
+
+ case SID_COPY:
+ pTableView->Copy();
+ bSetModified = false;
+ break;
+
+ case SID_CUT:
+ pTableView->Cut();
+ if (pTopView)
+ pTopView->DeleteSelected();
+ break;
+
+ case SID_PASTE:
+ {
+ EVControlBits nControl = pTableView->GetControlWord();
+ if (pTopView)
+ {
+ pTopView->Paste();
+ pTableView->SetControlWord(nControl | EVControlBits::SINGLELINEPASTE);
+ }
+
+ pTableView->PasteSpecial();
+ pTableView->SetControlWord(nControl);
+ }
+ break;
+
+ case SID_DELETE:
+ pTableView->DeleteSelected();
+ if (pTopView)
+ pTopView->DeleteSelected();
+ break;
+
+ case SID_CELL_FORMAT_RESET: // "Standard"
+ lcl_RemoveAttribs( *pTableView );
+ if ( pTopView )
+ lcl_RemoveAttribs( *pTopView );
+ break;
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState(nSlot, true, &pItem) == SfxItemState::SET )
+ if (auto pIntItem = dynamic_cast<const SfxUInt32Item*>( pItem))
+ nFormat = static_cast<SotClipboardFormatId>(pIntItem->GetValue());
+
+ if ( nFormat != SotClipboardFormatId::NONE )
+ {
+ if (SotClipboardFormatId::STRING == nFormat)
+ pTableView->Paste();
+ else
+ pTableView->PasteSpecial();
+
+ if (pTopView)
+ pTopView->Paste();
+ }
+ }
+ break;
+
+ case SID_PASTE_SPECIAL:
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog(rViewData.GetDialogParent()));
+ SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
+ pDlg->Insert( SotClipboardFormatId::STRING, OUString() );
+ pDlg->Insert( SotClipboardFormatId::RTF, OUString() );
+ pDlg->Insert( SotClipboardFormatId::RICHTEXT, OUString() );
+ // Do not offer SotClipboardFormatId::STRING_TSVC for
+ // in-cell paste.
+
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( rViewData.GetActiveWin() ) );
+
+ nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() );
+ pDlg.disposeAndClear();
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ return;
+
+ if (nFormat != SotClipboardFormatId::NONE)
+ {
+ if (SotClipboardFormatId::STRING == nFormat)
+ pTableView->Paste();
+ else
+ pTableView->PasteSpecial();
+
+ if (pTopView)
+ pTopView->Paste();
+ }
+
+ if (vcl::Window* pViewWindow = pTopView ? pTopView->GetWindow() : nullptr)
+ pViewWindow->GrabFocus();
+ }
+ break;
+
+ case SID_PASTE_UNFORMATTED:
+ {
+ pTableView->Paste();
+
+ if (pTopView)
+ {
+ pTopView->Paste();
+ if (vcl::Window* pViewWindow = pTopView->GetWindow())
+ pViewWindow->GrabFocus();
+ }
+ }
+ break;
+
+ case SID_SELECTALL:
+ {
+ sal_Int32 nPar = pEngine->GetParagraphCount();
+ if (nPar)
+ {
+ sal_Int32 nLen = pEngine->GetTextLen(nPar-1);
+ pTableView->SetSelection(ESelection(0,0,nPar-1,nLen));
+ if (pTopView)
+ pTopView->SetSelection(ESelection(0,0,nPar-1,nLen));
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT );
+ rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED );
+ rBindings.Invalidate( SID_ATTR_CHAR_KERNING );
+ rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
+ rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
+ rBindings.Invalidate( SID_SET_SUB_SCRIPT );
+ }
+ }
+ return;
+ case SID_UNICODE_NOTATION_TOGGLE:
+ {
+ EditView* pActiveView = pHdl->GetActiveView();
+ if( pActiveView )
+ {
+ OUString sInput = pEngine->GetText();
+ ESelection aSel( pActiveView->GetSelection() );
+ if( aSel.HasRange() )
+ sInput = pActiveView->GetSelected();
+
+ if( aSel.nStartPos > aSel.nEndPos )
+ aSel.nEndPos = aSel.nStartPos;
+
+ //calculate a valid end-position by reading logical characters
+ sal_Int32 nUtf16Pos=0;
+ while( (nUtf16Pos < sInput.getLength()) && (nUtf16Pos < aSel.nEndPos) )
+ {
+ sInput.iterateCodePoints(&nUtf16Pos);
+ if( nUtf16Pos > aSel.nEndPos )
+ aSel.nEndPos = nUtf16Pos;
+ }
+
+ ToggleUnicodeCodepoint aToggle;
+ while( nUtf16Pos && aToggle.AllowMoreInput( sInput[nUtf16Pos-1]) )
+ --nUtf16Pos;
+ OUString sReplacement = aToggle.ReplacementString();
+ if( !sReplacement.isEmpty() )
+ {
+ aSel.nStartPos = aSel.nEndPos - aToggle.StringToReplace().getLength();
+ pTableView->SetSelection( aSel );
+ pTableView->InsertText(sReplacement, true);
+ if( pTopView )
+ {
+ pTopView->SetSelection( aSel );
+ pTopView->InsertText(sReplacement, true);
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_CHARMAP:
+ {
+ SvtScriptType nScript = pTableView->GetSelectedScriptType();
+ sal_uInt16 nFontWhich = ( nScript == SvtScriptType::ASIAN ) ? EE_CHAR_FONTINFO_CJK :
+ ( ( nScript == SvtScriptType::COMPLEX ) ? EE_CHAR_FONTINFO_CTL :
+ EE_CHAR_FONTINFO );
+ const SvxFontItem& rItem = static_cast<const SvxFontItem&>(
+ pTableView->GetAttribs().Get(nFontWhich));
+
+ OUString aString;
+ std::shared_ptr<SvxFontItem> aNewItem(std::make_shared<SvxFontItem>(EE_CHAR_FONTINFO));
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = nullptr;
+ if( pArgs )
+ pArgs->GetItemState(SID_CHARMAP, false, &pItem);
+
+ if ( pItem )
+ {
+ aString = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_ATTR_SPECIALCHAR, false);
+ if ( pFontItem )
+ {
+ const OUString& aFontName(pFontItem->GetValue());
+ vcl::Font aFont(aFontName, Size(1,1)); // Size just because CTOR
+ // tdf#125054 see comment in drtxob.cxx, same ID
+ aNewItem = std::make_shared<SvxFontItem>(
+ aFont.GetFamilyType(), aFont.GetFamilyName(),
+ aFont.GetStyleName(), aFont.GetPitch(),
+ aFont.GetCharSet(), ATTR_FONT);
+ }
+ else
+ {
+ aNewItem.reset(rItem.Clone());
+ }
+
+ // tdf#125054 force Item to correct intended ID
+ aNewItem->SetWhich(EE_CHAR_FONTINFO);
+ }
+ else
+ {
+ ScViewUtil::ExecuteCharMap(rItem, *rViewData.GetViewShell());
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ return;
+ }
+
+ if ( !aString.isEmpty() )
+ {
+ // if string contains WEAK characters, set all fonts
+ SvtScriptType nSetScript;
+ ScDocument& rDoc = rViewData.GetDocument();
+ if ( rDoc.HasStringWeakCharacters( aString ) )
+ nSetScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
+ else
+ nSetScript = rDoc.GetStringScriptType( aString );
+
+ SfxItemSet aSet( pTableView->GetEmptyItemSet() );
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, GetPool() );
+ aSetItem.PutItemForScriptType( nSetScript, *aNewItem );
+ aSet.Put( aSetItem.GetItemSet(), false );
+
+ // SetAttribs on the View selects a word, when nothing is selected
+ pTableView->GetEditEngine()->QuickSetAttribs( aSet, pTableView->GetSelection() );
+ pTableView->InsertText(aString);
+ if (pTopView)
+ pTopView->InsertText(aString);
+
+ SfxStringItem aStringItem( SID_CHARMAP, aString );
+ SfxStringItem aFontItem( SID_ATTR_SPECIALCHAR, aNewItem->GetFamilyName() );
+ rReq.AppendItem( aFontItem );
+ rReq.AppendItem( aStringItem );
+ rReq.Done();
+
+ }
+
+ if (vcl::Window* pViewWindow = pTopView ? pTopView->GetWindow() : nullptr)
+ pViewWindow->GrabFocus();
+ }
+ break;
+
+ case FID_INSERT_NAME:
+ {
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+
+ ScopedVclPtr<AbstractScNamePasteDlg> pDlg(pFact->CreateScNamePasteDlg(rViewData.GetDialogParent(), rViewData.GetDocShell()));
+ short nRet = pDlg->Execute();
+ // pDlg is needed below
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ return;
+
+ if ( nRet == BTN_PASTE_NAME )
+ {
+ std::vector<OUString> aNames = pDlg->GetSelectedNames();
+ if (!aNames.empty())
+ {
+ OUStringBuffer aBuffer;
+ for (const auto& rName : aNames)
+ {
+ aBuffer.append(rName).append(' ');
+ }
+ const OUString s = aBuffer.makeStringAndClear();
+ pTableView->InsertText(s);
+ if (pTopView)
+ pTopView->InsertText(s);
+ }
+ }
+ pDlg.disposeAndClear();
+
+ if (vcl::Window* pViewWindow = pTopView ? pTopView->GetWindow() : nullptr)
+ pViewWindow->GrabFocus();
+ }
+ break;
+
+ case SID_CHAR_DLG_EFFECT:
+ case SID_CHAR_DLG:
+ {
+ SfxItemSet aAttrs( pTableView->GetAttribs() );
+
+ SfxObjectShell* pObjSh = rViewData.GetSfxDocShell();
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScCharDlg(
+ rViewData.GetDialogParent(), &aAttrs, pObjSh, false));
+ if (nSlot == SID_CHAR_DLG_EFFECT)
+ {
+ pDlg->SetCurPageId("fonteffects");
+ }
+ short nRet = pDlg->Execute();
+ // pDlg is needed below
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ return;
+
+ if ( nRet == RET_OK )
+ {
+ const SfxItemSet* pOut = pDlg->GetOutputItemSet();
+ pTableView->SetAttribs( *pOut );
+ }
+ }
+ break;
+
+ case SID_TOGGLE_REL:
+ {
+ /* TODO: MLFORMULA: this should work also with multi-line formulas. */
+ if (pEngine->GetParagraphCount() == 1)
+ {
+ OUString aText = pEngine->GetText();
+ ESelection aSel = pEditView->GetSelection(); // current View
+
+ ScDocument& rDoc = rViewData.GetDocument();
+ ScRefFinder aFinder(aText, rViewData.GetCurPos(), rDoc, rDoc.GetAddressConvention());
+ aFinder.ToggleRel( aSel.nStartPos, aSel.nEndPos );
+ if (aFinder.GetFound())
+ {
+ const OUString& aNew = aFinder.GetText();
+ ESelection aNewSel( 0,aFinder.GetSelStart(), 0,aFinder.GetSelEnd() );
+ pEngine->SetText( aNew );
+ pTableView->SetSelection( aNewSel );
+ if ( pTopView )
+ {
+ pTopView->GetEditEngine()->SetText( aNew );
+ pTopView->SetSelection( aNewSel );
+ }
+
+ // reference is being selected -> do not overwrite when typing
+ bSetSelIsRef = true;
+ }
+ }
+ }
+ break;
+
+ case SID_HYPERLINK_SETLINK:
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_HYPERLINK_SETLINK, true, &pItem ) == SfxItemState::SET )
+ {
+ const SvxHyperlinkItem* pHyper = static_cast<const SvxHyperlinkItem*>(pItem);
+ const OUString& rName = pHyper->GetName();
+ const OUString& rURL = pHyper->GetURL();
+ const OUString& rTarget = pHyper->GetTargetFrame();
+ SvxLinkInsertMode eMode = pHyper->GetInsertMode();
+
+ bool bDone = false;
+ if ( eMode == HLINK_DEFAULT || eMode == HLINK_FIELD )
+ {
+ const SvxURLField* pURLField = GetURLField();
+ if ( pURLField )
+ {
+ // select old field
+
+ ESelection aSel = pTableView->GetSelection();
+ aSel.Adjust();
+ aSel.nEndPara = aSel.nStartPara;
+ aSel.nEndPos = aSel.nStartPos + 1;
+ pTableView->SetSelection( aSel );
+
+ // insert new field
+
+ SvxURLField aURLField( rURL, rName, SvxURLFormat::Repr );
+ aURLField.SetTargetFrame( rTarget );
+ SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD );
+ pTableView->InsertField( aURLItem );
+ pTableView->SetSelection( aSel ); // select inserted field
+
+ // now also fields in the Top-View
+
+ if ( pTopView )
+ {
+ aSel = pTopView->GetSelection();
+ aSel.nEndPara = aSel.nStartPara;
+ aSel.nEndPos = aSel.nStartPos + 1;
+ pTopView->SetSelection( aSel );
+ pTopView->InsertField( aURLItem );
+ pTopView->SetSelection( aSel ); // select inserted field
+ }
+
+ bDone = true;
+ }
+ }
+
+ if (!bDone)
+ {
+ rViewData.GetViewShell()->
+ InsertURL( rName, rURL, rTarget, static_cast<sal_uInt16>(eMode) );
+
+ // when "Button", the InsertURL in ViewShell turns the EditShell off
+ // thus the immediate return statement
+ return;
+ }
+ }
+ }
+ break;
+ case SID_OPEN_HYPERLINK:
+ {
+ const SvxURLField* pURLField = GetURLField();
+ if ( pURLField )
+ ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame(), true );
+ return;
+ }
+ case SID_EDIT_HYPERLINK:
+ {
+ // Ensure the field is selected first
+ pEditView->SelectFieldAtCursor();
+ rViewData.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(
+ SID_HYPERLINK_DIALOG);
+ }
+ break;
+ case SID_COPY_HYPERLINK_LOCATION:
+ {
+ const SvxFieldData* pField = pEditView->GetFieldAtCursor();
+ if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField))
+ {
+ uno::Reference<datatransfer::clipboard::XClipboard> xClipboard
+ = pEditView->GetClipboard();
+ vcl::unohelper::TextDataObject::CopyStringTo(pURLField->GetURL(), xClipboard, SfxViewShell::Current());
+ }
+ }
+ break;
+ case SID_REMOVE_HYPERLINK:
+ {
+ URLFieldHelper::RemoveURLField(*pEditView);
+ }
+ break;
+
+ case FN_INSERT_SOFT_HYPHEN:
+ lclInsertCharacter( pTableView, pTopView, CHAR_SHY );
+ break;
+ case FN_INSERT_HARDHYPHEN:
+ lclInsertCharacter( pTableView, pTopView, CHAR_NBHY );
+ break;
+ case FN_INSERT_HARD_SPACE:
+ lclInsertCharacter( pTableView, pTopView, CHAR_NBSP );
+ break;
+ case FN_INSERT_NNBSP:
+ lclInsertCharacter( pTableView, pTopView, CHAR_NNBSP );
+ break;
+ case SID_INSERT_RLM:
+ lclInsertCharacter( pTableView, pTopView, CHAR_RLM );
+ break;
+ case SID_INSERT_LRM:
+ lclInsertCharacter( pTableView, pTopView, CHAR_LRM );
+ break;
+ case SID_INSERT_ZWSP:
+ lclInsertCharacter( pTableView, pTopView, CHAR_ZWSP );
+ break;
+ case SID_INSERT_WJ:
+ lclInsertCharacter( pTableView, pTopView, CHAR_WJ );
+ break;
+ case SID_INSERT_FIELD_SHEET:
+ {
+ SvxTableField aField(rViewData.GetTabNo());
+ SvxFieldItem aItem(aField, EE_FEATURE_FIELD);
+ pTableView->InsertField(aItem);
+ }
+ break;
+ case SID_INSERT_FIELD_TITLE:
+ {
+ SvxFileField aField;
+ SvxFieldItem aItem(aField, EE_FEATURE_FIELD);
+ pTableView->InsertField(aItem);
+ }
+ break;
+ case SID_INSERT_FIELD_DATE_VAR:
+ {
+ SvxDateField aField;
+ SvxFieldItem aItem(aField, EE_FEATURE_FIELD);
+ pTableView->InsertField(aItem);
+ }
+ break;
+ }
+
+ pHdl->DataChanged(false, bSetModified);
+ if (bSetSelIsRef)
+ pHdl->SetSelIsRef(true);
+}
+
+static void lcl_DisableAll( SfxItemSet& rSet ) // disable all slots
+{
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+}
+
+bool ScEditShell::ShouldDisableEditHyperlink() const
+{
+ return !rViewData.HasEditView(rViewData.GetActivePart()) || !URLFieldHelper::IsCursorAtURLField(*pEditView);
+}
+
+void ScEditShell::EnableEditHyperlink()
+{
+ moAtContextMenu_DisableEditHyperlink = false;
+}
+
+void ScEditShell::GetState( SfxItemSet& rSet )
+{
+ // When deactivating the view, edit mode is stopped, but the EditShell is left active
+ // (a shell can't be removed from within Deactivate). In that state, the EditView isn't inserted
+ // into the EditEngine, so it can have an invalid selection and must not be used.
+ if ( !rViewData.HasEditView( rViewData.GetActivePart() ) )
+ {
+ lcl_DisableAll( rSet );
+ return;
+ }
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
+
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_ATTR_INSERT: // Status row
+ {
+ if ( pActiveView )
+ rSet.Put( SfxBoolItem( nWhich, pActiveView->IsInsertMode() ) );
+ else
+ {
+ // Here the code used to pass the value 42 and it used
+ // to "work" without warnings because the SfxBoolItem
+ // was based on 'sal_Bool', which is actually 'unsigned
+ // char'. But now it uses actual 'bool', and passing 42
+ // for a 'bool' parameter causes a warning at least with
+ // MSVC. So use 'true'. I really really hope there is
+ // not code somewhere that retrieves this "boolean" item
+ // and checks it value for the magic value 42...
+ rSet.Put( SfxBoolItem( nWhich, true) );
+ }
+ }
+ break;
+
+ case SID_HYPERLINK_GETLINK:
+ {
+ SvxHyperlinkItem aHLinkItem;
+ const SvxURLField* pURLField = GetURLField();
+ if ( pURLField )
+ {
+ aHLinkItem.SetName( pURLField->GetRepresentation() );
+ aHLinkItem.SetURL( pURLField->GetURL() );
+ aHLinkItem.SetTargetFrame( pURLField->GetTargetFrame() );
+ }
+ else if ( pActiveView )
+ {
+ // use selected text as name for urls
+ OUString sReturn = pActiveView->GetSelected();
+ sReturn = sReturn.copy(0, std::min(sReturn.getLength(), static_cast<sal_Int32>(255)));
+ aHLinkItem.SetName(comphelper::string::stripEnd(sReturn, ' '));
+ }
+ rSet.Put(aHLinkItem);
+ }
+ break;
+
+ case SID_OPEN_HYPERLINK:
+ case SID_EDIT_HYPERLINK:
+ case SID_COPY_HYPERLINK_LOCATION:
+ case SID_REMOVE_HYPERLINK:
+ {
+ bool bDisableEditHyperlink;
+ if (!moAtContextMenu_DisableEditHyperlink)
+ bDisableEditHyperlink = ShouldDisableEditHyperlink();
+ else
+ {
+ // tdf#140361 if a popup menu was active, use the state as of when the popup was launched and then drop
+ // moAtContextMenu_DisableEditHyperlink
+ bDisableEditHyperlink = *moAtContextMenu_DisableEditHyperlink;
+ moAtContextMenu_DisableEditHyperlink.reset();
+ }
+
+ if (bDisableEditHyperlink)
+ rSet.DisableItem (nWhich);
+ }
+ break;
+
+ case SID_TRANSLITERATE_HALFWIDTH:
+ case SID_TRANSLITERATE_FULLWIDTH:
+ case SID_TRANSLITERATE_HIRAGANA:
+ case SID_TRANSLITERATE_KATAKANA:
+ case SID_INSERT_RLM:
+ case SID_INSERT_LRM:
+ ScViewUtil::HideDisabledSlot( rSet, rViewData.GetBindings(), nWhich );
+ break;
+
+ case SID_THES:
+ {
+ OUString aStatusVal;
+ LanguageType nLang = LANGUAGE_NONE;
+ bool bIsLookUpWord = pActiveView &&
+ GetStatusValueForThesaurusFromContext(aStatusVal, nLang, *pActiveView);
+ rSet.Put( SfxStringItem( SID_THES, aStatusVal ) );
+
+ // disable thesaurus context menu entry if there is nothing to look up
+ bool bCanDoThesaurus = ScModule::HasThesaurusLanguage( nLang );
+ if (!bIsLookUpWord || !bCanDoThesaurus)
+ rSet.DisableItem( SID_THES );
+ }
+ break;
+ case SID_INSERT_FIELD_SHEET:
+ case SID_INSERT_FIELD_TITLE:
+ case SID_INSERT_FIELD_DATE_VAR:
+ break;
+ case SID_COPY:
+ case SID_CUT:
+ if (GetObjectShell() && GetObjectShell()->isContentExtractionLocked())
+ {
+ rSet.DisableItem(SID_COPY);
+ rSet.DisableItem(SID_CUT);
+ }
+ break;
+
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+const SvxURLField* ScEditShell::GetURLField()
+{
+ ScInputHandler* pHdl = GetMyInputHdl();
+ EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
+ if (!pActiveView)
+ return nullptr;
+
+ const SvxFieldData* pField = pActiveView->GetFieldAtCursor();
+ if (auto pURLField = dynamic_cast<const SvxURLField*>(pField))
+ return pURLField;
+
+ return nullptr;
+}
+
+IMPL_LINK( ScEditShell, ClipboardChanged, TransferableDataHelper*, pDataHelper, void )
+{
+ bPastePossible = ( pDataHelper->HasFormat( SotClipboardFormatId::STRING )
+ || pDataHelper->HasFormat( SotClipboardFormatId::RTF )
+ || pDataHelper->HasFormat( SotClipboardFormatId::RICHTEXT ));
+
+ SfxBindings& rBindings = rViewData.GetBindings();
+ rBindings.Invalidate( SID_PASTE );
+ rBindings.Invalidate( SID_PASTE_SPECIAL );
+ rBindings.Invalidate( SID_PASTE_UNFORMATTED );
+ rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
+}
+
+void ScEditShell::GetClipState( SfxItemSet& rSet )
+{
+ // Do not offer SotClipboardFormatId::STRING_TSVC for in-cell paste.
+
+ if ( !mxClipEvtLstnr.is() )
+ {
+ // create listener
+ mxClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScEditShell, ClipboardChanged ) );
+ vcl::Window* pWin = rViewData.GetActiveWin();
+ mxClipEvtLstnr->AddListener( pWin );
+
+ // get initial state
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( rViewData.GetActiveWin() ) );
+ bPastePossible = ( aDataHelper.HasFormat( SotClipboardFormatId::STRING )
+ || aDataHelper.HasFormat( SotClipboardFormatId::RTF )
+ || aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) );
+ }
+
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_PASTE:
+ case SID_PASTE_SPECIAL:
+ case SID_PASTE_UNFORMATTED:
+ if( !bPastePossible )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ if( bPastePossible )
+ {
+ SvxClipboardFormatItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( rViewData.GetActiveWin() ) );
+
+ if ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) )
+ aFormats.AddClipbrdFormat( SotClipboardFormatId::STRING );
+ if ( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) )
+ aFormats.AddClipbrdFormat( SotClipboardFormatId::RTF );
+
+ rSet.Put( aFormats );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+static void lcl_InvalidateUnder( SfxBindings& rBindings )
+{
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ULINE_VAL_NONE );
+ rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
+}
+
+void ScEditShell::ExecuteAttr(SfxRequest& rReq)
+{
+ SfxItemSet aSet( pEditView->GetEmptyItemSet() );
+ SfxBindings& rBindings = rViewData.GetBindings();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ case SID_ATTR_CHAR_FONT:
+ {
+ if (pArgs)
+ {
+ // #i78017 establish the same behaviour as in Writer
+ SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
+ if (nSlot == SID_ATTR_CHAR_FONT)
+ {
+ nScript = pEditView->GetSelectedScriptType();
+ if (nScript == SvtScriptType::NONE) nScript = ScGlobal::GetDefaultScriptType();
+ }
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ sal_uInt16 nWhich = rPool.GetWhich( nSlot );
+ aSetItem.PutItemForScriptType( nScript, pArgs->Get( nWhich ) );
+
+ aSet.Put( aSetItem.GetItemSet(), false );
+ }
+ }
+ break;
+
+ case SID_ATTR_CHAR_COLOR:
+ {
+ if (pArgs)
+ {
+ if ( const SfxStringItem* pColorStringItem = pArgs->GetItemIfSet( SID_ATTR_COLOR_STR, false ) )
+ {
+ Color aColor;
+ OUString sColor = pColorStringItem->GetValue();
+ if ( sColor == "transparent" )
+ aColor = COL_TRANSPARENT;
+ else
+ aColor = Color( ColorTransparency, sColor.toInt32( 16 ) );
+
+ aSet.Put( SvxColorItem( aColor, EE_CHAR_COLOR ) );
+ }
+ else
+ {
+ aSet.Put( pArgs->Get( pArgs->GetPool()->GetWhich( nSlot ) ) );
+ }
+ rBindings.Invalidate( nSlot );
+ }
+ }
+ break;
+
+ // Toggles
+
+ case SID_ATTR_CHAR_WEIGHT:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+
+ bool bOld = false;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), false );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && static_cast<const SvxWeightItem*>(pCore)->GetWeight() > WEIGHT_NORMAL )
+ bOld = true;
+
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ aSetItem.PutItemForScriptType( nScript,
+ SvxWeightItem( bOld ? WEIGHT_NORMAL : WEIGHT_BOLD, EE_CHAR_WEIGHT ) );
+ aSet.Put( aSetItem.GetItemSet(), false );
+
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+
+ bool bOld = false;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), false );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && static_cast<const SvxPostureItem*>(pCore)->GetValue() != ITALIC_NONE )
+ bOld = true;
+
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ aSetItem.PutItemForScriptType( nScript,
+ SvxPostureItem( bOld ? ITALIC_NONE : ITALIC_NORMAL, EE_CHAR_ITALIC ) );
+ aSet.Put( aSetItem.GetItemSet(), false );
+
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ULINE_VAL_NONE:
+ aSet.Put( SvxUnderlineItem( LINESTYLE_NONE, EE_CHAR_UNDERLINE ) );
+ lcl_InvalidateUnder( rBindings );
+ break;
+
+ case SID_ATTR_CHAR_UNDERLINE:
+ case SID_ULINE_VAL_SINGLE:
+ case SID_ULINE_VAL_DOUBLE:
+ case SID_ULINE_VAL_DOTTED:
+ {
+ FontLineStyle eOld = pEditView->GetAttribs().Get(EE_CHAR_UNDERLINE).GetLineStyle();
+ FontLineStyle eNew = eOld;
+ switch (nSlot)
+ {
+ case SID_ATTR_CHAR_UNDERLINE:
+ if ( pArgs )
+ {
+ const SvxTextLineItem& rTextLineItem = static_cast< const SvxTextLineItem& >( pArgs->Get( pArgs->GetPool()->GetWhich(nSlot) ) );
+ eNew = rTextLineItem.GetLineStyle();
+ }
+ else
+ {
+ eNew = ( eOld != LINESTYLE_NONE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
+ }
+ break;
+ case SID_ULINE_VAL_SINGLE:
+ eNew = ( eOld == LINESTYLE_SINGLE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
+ break;
+ case SID_ULINE_VAL_DOUBLE:
+ eNew = ( eOld == LINESTYLE_DOUBLE ) ? LINESTYLE_NONE : LINESTYLE_DOUBLE;
+ break;
+ case SID_ULINE_VAL_DOTTED:
+ eNew = ( eOld == LINESTYLE_DOTTED ) ? LINESTYLE_NONE : LINESTYLE_DOTTED;
+ break;
+ }
+ aSet.Put( SvxUnderlineItem( eNew, EE_CHAR_UNDERLINE ) );
+ lcl_InvalidateUnder( rBindings );
+ }
+ break;
+
+ case SID_ATTR_CHAR_OVERLINE:
+ {
+ FontLineStyle eOld = pEditView->GetAttribs().Get(EE_CHAR_OVERLINE).GetLineStyle();
+ FontLineStyle eNew = ( eOld != LINESTYLE_NONE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
+ aSet.Put( SvxOverlineItem( eNew, EE_CHAR_OVERLINE ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_STRIKEOUT:
+ {
+ bool bOld = pEditView->GetAttribs().Get(EE_CHAR_STRIKEOUT).GetValue() != STRIKEOUT_NONE;
+ aSet.Put( SvxCrossedOutItem( bOld ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_SHADOWED:
+ {
+ bool bOld = pEditView->GetAttribs().Get(EE_CHAR_SHADOW).GetValue();
+ aSet.Put( SvxShadowedItem( !bOld, EE_CHAR_SHADOW ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_CONTOUR:
+ {
+ bool bOld = pEditView->GetAttribs().Get(EE_CHAR_OUTLINE).GetValue();
+ aSet.Put( SvxContourItem( !bOld, EE_CHAR_OUTLINE ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_SET_SUPER_SCRIPT:
+ {
+ SvxEscapement eOld = static_cast<SvxEscapement>(pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT).GetEnumValue());
+ SvxEscapement eNew = (eOld == SvxEscapement::Superscript) ?
+ SvxEscapement::Off : SvxEscapement::Superscript;
+ aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+ case SID_SET_SUB_SCRIPT:
+ {
+ SvxEscapement eOld = static_cast<SvxEscapement>(pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT).GetEnumValue());
+ SvxEscapement eNew = (eOld == SvxEscapement::Subscript) ?
+ SvxEscapement::Off : SvxEscapement::Subscript;
+ aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+ case SID_ATTR_CHAR_KERNING:
+ {
+ if(pArgs)
+ {
+ aSet.Put ( pArgs->Get(pArgs->GetPool()->GetWhich(nSlot)));
+ rBindings.Invalidate( nSlot );
+ }
+ }
+ break;
+
+ case SID_GROW_FONT_SIZE:
+ case SID_SHRINK_FONT_SIZE:
+ {
+ SfxObjectShell* pObjSh = SfxObjectShell::Current();
+ const SvxFontListItem* pFontListItem = static_cast<const SvxFontListItem*>
+ (pObjSh ? pObjSh->GetItem(SID_ATTR_CHAR_FONTLIST) : nullptr);
+ const FontList* pFontList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
+ pEditView->ChangeFontSize( nSlot == SID_GROW_FONT_SIZE, pFontList );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ }
+ break;
+ }
+
+ // apply
+
+ EditEngine* pEngine = pEditView->GetEditEngine();
+ bool bOld = pEngine->SetUpdateLayout(false);
+
+ pEditView->SetAttribs( aSet );
+
+ pEngine->SetUpdateLayout(bOld);
+ pEditView->Invalidate();
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ pHdl->SetModified();
+
+ rReq.Done();
+}
+
+void ScEditShell::GetAttrState(SfxItemSet &rSet)
+{
+ if ( !rViewData.HasEditView( rViewData.GetActivePart() ) )
+ {
+ lcl_DisableAll( rSet );
+ return;
+ }
+
+ SfxItemSet aAttribs = pEditView->GetAttribs();
+ rSet.Put( aAttribs );
+
+ // choose font info according to selection script type
+
+ SvtScriptType nScript = pEditView->GetSelectedScriptType();
+ if (nScript == SvtScriptType::NONE) nScript = ScGlobal::GetDefaultScriptType();
+
+ // #i55929# input-language-dependent script type (depends on input language if nothing selected)
+ SvtScriptType nInputScript = nScript;
+ if ( !pEditView->GetSelection().HasRange() )
+ {
+ LanguageType nInputLang = rViewData.GetActiveWin()->GetInputLanguage();
+ if (nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM)
+ nInputScript = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
+ }
+
+ // #i55929# according to spec, nInputScript is used for font and font height only
+ if ( rSet.GetItemState( EE_CHAR_FONTINFO ) != SfxItemState::UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTINFO, nInputScript );
+ if ( rSet.GetItemState( EE_CHAR_FONTHEIGHT ) != SfxItemState::UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTHEIGHT, nInputScript );
+ if ( rSet.GetItemState( EE_CHAR_WEIGHT ) != SfxItemState::UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_WEIGHT, nScript );
+ if ( rSet.GetItemState( EE_CHAR_ITALIC ) != SfxItemState::UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_ITALIC, nScript );
+
+ // underline
+ SfxItemState eState = aAttribs.GetItemState( EE_CHAR_UNDERLINE );
+ if ( eState == SfxItemState::DONTCARE )
+ {
+ rSet.InvalidateItem( SID_ULINE_VAL_NONE );
+ rSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
+ }
+ else
+ {
+ FontLineStyle eUnderline = aAttribs.Get(EE_CHAR_UNDERLINE).GetLineStyle();
+ rSet.Put(SfxBoolItem(SID_ULINE_VAL_SINGLE, eUnderline == LINESTYLE_SINGLE));
+ rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOUBLE, eUnderline == LINESTYLE_DOUBLE));
+ rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOTTED, eUnderline == LINESTYLE_DOTTED));
+ rSet.Put(SfxBoolItem(SID_ULINE_VAL_NONE, eUnderline == LINESTYLE_NONE));
+ }
+
+ //! Testing whether brace highlighting is active !!!!
+ ScInputHandler* pHdl = GetMyInputHdl();
+ if ( pHdl && pHdl->IsFormulaMode() )
+ rSet.ClearItem( EE_CHAR_WEIGHT ); // Highlighted brace not here
+
+ SvxEscapement eEsc = static_cast<SvxEscapement>(aAttribs.Get( EE_CHAR_ESCAPEMENT ).GetEnumValue());
+ rSet.Put(SfxBoolItem(SID_SET_SUPER_SCRIPT, eEsc == SvxEscapement::Superscript));
+ rSet.Put(SfxBoolItem(SID_SET_SUB_SCRIPT, eEsc == SvxEscapement::Subscript));
+ rViewData.GetBindings().Invalidate( SID_SET_SUPER_SCRIPT );
+ rViewData.GetBindings().Invalidate( SID_SET_SUB_SCRIPT );
+
+ eState = aAttribs.GetItemState( EE_CHAR_KERNING );
+ rViewData.GetBindings().Invalidate( SID_ATTR_CHAR_KERNING );
+ if ( eState == SfxItemState::DONTCARE )
+ {
+ rSet.InvalidateItem(EE_CHAR_KERNING);
+ }
+}
+
+OUString ScEditShell::GetSelectionText( bool bWholeWord )
+{
+ OUString aStrSelection;
+
+ if ( rViewData.HasEditView( rViewData.GetActivePart() ) )
+ {
+ if ( bWholeWord )
+ {
+ EditEngine* pEngine = pEditView->GetEditEngine();
+ ESelection aSel = pEditView->GetSelection();
+ OUString aStrCurrentDelimiters = pEngine->GetWordDelimiters();
+
+ pEngine->SetWordDelimiters(" .,;\"'");
+ aStrSelection = pEngine->GetWord( aSel.nEndPara, aSel.nEndPos );
+ pEngine->SetWordDelimiters( aStrCurrentDelimiters );
+ }
+ else
+ {
+ aStrSelection = pEditView->GetSelected();
+ }
+ }
+
+ return aStrSelection;
+}
+
+void ScEditShell::ExecuteUndo(const SfxRequest& rReq)
+{
+ // Undo must be handled here because it's called for both EditViews
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ OSL_ENSURE(pHdl,"no ScInputHandler");
+ EditView* pTopView = pHdl->GetTopView();
+ EditView* pTableView = pHdl->GetTableView();
+ OSL_ENSURE(pTableView,"no EditView");
+
+ pHdl->DataChanging();
+
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_UNDO:
+ case SID_REDO:
+ {
+ bool bIsUndo = ( nSlot == SID_UNDO );
+
+ sal_uInt16 nCount = 1;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
+ nCount = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ if ( bIsUndo )
+ {
+ pTableView->Undo();
+ if (pTopView)
+ pTopView->Undo();
+ }
+ else
+ {
+ pTableView->Redo();
+ if (pTopView)
+ pTopView->Redo();
+ }
+ }
+ }
+ break;
+ }
+ rViewData.GetBindings().InvalidateAll(false);
+
+ pHdl->DataChanged();
+}
+
+void ScEditShell::GetUndoState(SfxItemSet &rSet)
+{
+ // Undo state is taken from normal ViewFrame state function
+
+ SfxViewFrame* pViewFrm = rViewData.GetViewShell()->GetViewFrame();
+ if ( pViewFrm && GetUndoManager() )
+ {
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ pViewFrm->GetSlotState( nWhich, nullptr, &rSet );
+ nWhich = aIter.NextWhich();
+ }
+ }
+
+ // disable if no action in input line EditView
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ OSL_ENSURE(pHdl,"no ScInputHandler");
+ EditView* pTopView = pHdl->GetTopView();
+ if (pTopView)
+ {
+ SfxUndoManager& rTopMgr = pTopView->GetEditEngine()->GetUndoManager();
+ if ( rTopMgr.GetUndoActionCount() == 0 )
+ rSet.DisableItem( SID_UNDO );
+ if ( rTopMgr.GetRedoActionCount() == 0 )
+ rSet.DisableItem( SID_REDO );
+ }
+}
+
+void ScEditShell::ExecuteTrans( const SfxRequest& rReq )
+{
+ TransliterationFlags nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() );
+ if ( nType == TransliterationFlags::NONE )
+ return;
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ assert(pHdl && "no ScInputHandler");
+
+ EditView* pTopView = pHdl->GetTopView();
+ EditView* pTableView = pHdl->GetTableView();
+ assert(pTableView && "no EditView");
+
+ pHdl->DataChanging();
+
+ pTableView->TransliterateText( nType );
+ if (pTopView)
+ pTopView->TransliterateText( nType );
+
+ pHdl->DataChanged();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */