tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / editsh.cxx
blob3e8a5abe7b1d09c81b671caed70491b35864f587
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/string.hxx>
21 #include <comphelper/lok.hxx>
22 #include <scitems.hxx>
23 #include <editeng/eeitem.hxx>
24 #include <i18nutil/unicode.hxx>
25 #include <i18nutil/transliteration.hxx>
27 #include <svx/clipfmtitem.hxx>
28 #include <svx/svxdlg.hxx>
29 #include <editeng/contouritem.hxx>
30 #include <editeng/outliner.hxx>
31 #include <editeng/crossedoutitem.hxx>
32 #include <editeng/editeng.hxx>
33 #include <editeng/editview.hxx>
34 #include <editeng/escapementitem.hxx>
35 #include <editeng/flditem.hxx>
36 #include <editeng/flstitem.hxx>
37 #include <editeng/fontitem.hxx>
38 #include <editeng/urlfieldhelper.hxx>
39 #include <editeng/editund2.hxx>
40 #include <svx/hlnkitem.hxx>
41 #include <vcl/EnumContext.hxx>
42 #include <editeng/postitem.hxx>
43 #include <editeng/scripttypeitem.hxx>
44 #include <editeng/shdditem.hxx>
45 #include <editeng/udlnitem.hxx>
46 #include <editeng/wghtitem.hxx>
47 #include <sfx2/bindings.hxx>
48 #include <sfx2/dispatch.hxx>
49 #include <sfx2/docfile.hxx>
50 #include <sfx2/docfilt.hxx>
51 #include <sfx2/namedcolor.hxx>
52 #include <sfx2/msg.hxx>
53 #include <sfx2/objface.hxx>
54 #include <sfx2/objsh.hxx>
55 #include <sfx2/request.hxx>
56 #include <sfx2/viewfrm.hxx>
57 #include <svtools/cliplistener.hxx>
58 #include <svl/whiter.hxx>
59 #include <sot/formats.hxx>
60 #include <vcl/transfer.hxx>
61 #include <vcl/unohelp2.hxx>
62 #include <svl/stritem.hxx>
63 #include <editeng/colritem.hxx>
65 #include <editsh.hxx>
66 #include <global.hxx>
67 #include <appoptio.hxx>
68 #include <scmod.hxx>
69 #include <sc.hrc>
70 #include <inputhdl.hxx>
71 #include <viewutil.hxx>
72 #include <viewdata.hxx>
73 #include <document.hxx>
74 #include <reffind.hxx>
75 #include <tabvwsh.hxx>
76 #include <editutil.hxx>
77 #include <globstr.hrc>
78 #include <scresid.hxx>
79 #include <gridwin.hxx>
81 #define ShellClass_ScEditShell
82 #include <scslots.hxx>
84 #include <scui_def.hxx>
85 #include <scabstdlg.hxx>
86 #include <memory>
88 using namespace ::com::sun::star;
91 SFX_IMPL_INTERFACE(ScEditShell, SfxShell)
93 void ScEditShell::InitInterface_Impl()
95 GetStaticInterface()->RegisterPopupMenu(u"celledit"_ustr);
98 ScEditShell::ScEditShell(EditView* pView, ScViewData& rData) :
99 pEditView (pView),
100 rViewData (rData),
101 bPastePossible (false),
102 bIsInsertMode (true)
104 SetPool( pEditView->getEditEngine().GetEmptyItemSet().GetPool() );
105 SetUndoManager( &pEditView->getEditEngine().GetUndoManager() );
106 SetName(u"EditCell"_ustr);
107 SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::EditCell));
110 ScEditShell::~ScEditShell()
112 if ( mxClipEvtLstnr.is() )
114 mxClipEvtLstnr->RemoveListener( rViewData.GetActiveWin() );
116 // The listener may just now be waiting for the SolarMutex and call the link
117 // afterwards, in spite of RemoveListener. So the link has to be reset, too.
118 mxClipEvtLstnr->ClearCallbackLink();
122 ScInputHandler* ScEditShell::GetMyInputHdl()
124 return ScModule::get()->GetInputHdl(rViewData.GetViewShell());
127 void ScEditShell::SetEditView(EditView* pView)
129 pEditView = pView;
130 pEditView->SetInsertMode( bIsInsertMode );
131 SetPool( pEditView->getEditEngine().GetEmptyItemSet().GetPool() );
132 SetUndoManager( &pEditView->getEditEngine().GetUndoManager() );
135 static void lcl_RemoveAttribs( EditView& rEditView )
137 ScEditEngineDefaulter* pEngine = static_cast<ScEditEngineDefaulter*>(&rEditView.getEditEngine());
139 bool bOld = pEngine->SetUpdateLayout(false);
141 OUString aName = ScResId( STR_UNDO_DELETECONTENTS );
142 ViewShellId nViewShellId(-1);
143 if (ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell())
144 nViewShellId = pViewSh->GetViewShellId();
145 pEngine->GetUndoManager().EnterListAction( aName, aName, 0, nViewShellId );
147 rEditView.RemoveAttribs(true);
148 pEngine->RepeatDefaults(); // paragraph attributes from cell formats must be preserved
150 pEngine->GetUndoManager().LeaveListAction();
152 pEngine->SetUpdateLayout(bOld);
155 static void lclInsertCharacter( EditView* pTableView, EditView* pTopView, sal_Unicode cChar )
157 OUString aString( cChar );
158 if( pTableView )
159 pTableView->InsertText( aString );
160 if( pTopView )
161 pTopView->InsertText( aString );
164 void ScEditShell::Execute( SfxRequest& rReq )
166 const SfxItemSet* pReqArgs = rReq.GetArgs();
167 sal_uInt16 nSlot = rReq.GetSlot();
168 SfxBindings& rBindings = rViewData.GetBindings();
170 ScInputHandler* pHdl = GetMyInputHdl();
171 OSL_ENSURE(pHdl,"no ScInputHandler");
173 EditView* pTopView = pHdl->GetTopView(); // Has thee input cell the focus?
174 EditView* pTableView = pHdl->GetTableView();
176 OSL_ENSURE(pTableView,"no EditView :-(");
177 /* #i91683# No EditView if spell-check dialog is active and positioned on
178 * an error and user immediately (without double click or F2) selected a
179 * text portion of that cell with the mouse and wanted to modify it. */
180 /* FIXME: Bailing out only cures the symptom and prevents a crash, no edit
181 * action is possible. A real fix somehow would need to create a valid
182 * EditView from the spell-check view. */
183 if (!pTableView)
184 return;
186 EditEngine& rEngine = pTableView->getEditEngine();
188 pHdl->DataChanging();
189 bool bSetSelIsRef = false;
190 bool bSetModified = true;
192 switch ( nSlot )
194 case SID_ATTR_INSERT:
195 case FID_INS_CELL_CONTENTS: // Insert taste, while defined as Acc
196 bIsInsertMode = !pTableView->IsInsertMode();
197 pTableView->SetInsertMode( bIsInsertMode );
198 if (pTopView)
199 pTopView->SetInsertMode( bIsInsertMode );
200 rBindings.Invalidate( SID_ATTR_INSERT );
201 break;
203 case SID_THES:
205 OUString aReplaceText;
206 const SfxStringItem* pItem2 = rReq.GetArg(FN_PARAM_THES_WORD_REPLACE);
207 if (pItem2)
208 aReplaceText = pItem2->GetValue();
209 if (!aReplaceText.isEmpty())
210 ReplaceTextWithSynonym( *pEditView, aReplaceText );
212 break;
214 case SID_COPY:
215 pTableView->Copy();
216 bSetModified = false;
217 break;
219 case SID_CUT:
220 pTableView->Cut();
221 if (pTopView)
222 pTopView->DeleteSelected();
223 break;
225 case SID_PASTE:
227 EVControlBits nControl = pTableView->GetControlWord();
228 if (pTopView)
230 pTopView->Paste();
231 pTableView->SetControlWord(nControl | EVControlBits::SINGLELINEPASTE);
234 pTableView->PasteSpecial();
235 pTableView->SetControlWord(nControl);
237 break;
239 case SID_DELETE:
240 pTableView->DeleteSelected();
241 if (pTopView)
242 pTopView->DeleteSelected();
243 break;
245 case SID_CELL_FORMAT_RESET: // "Standard"
246 lcl_RemoveAttribs( *pTableView );
247 if ( pTopView )
248 lcl_RemoveAttribs( *pTopView );
249 break;
251 case SID_CLIPBOARD_FORMAT_ITEMS:
253 SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
254 const SfxPoolItem* pItem;
255 if ( pReqArgs && pReqArgs->GetItemState(nSlot, true, &pItem) == SfxItemState::SET )
256 if (auto pIntItem = dynamic_cast<const SfxUInt32Item*>( pItem))
257 nFormat = static_cast<SotClipboardFormatId>(pIntItem->GetValue());
259 if ( nFormat != SotClipboardFormatId::NONE )
261 if (SotClipboardFormatId::STRING == nFormat)
262 pTableView->Paste();
263 else
264 pTableView->PasteSpecial();
266 if (pTopView)
267 pTopView->Paste();
270 break;
272 case SID_PASTE_SPECIAL:
274 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
275 ScopedVclPtr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog(rViewData.GetDialogParent()));
276 SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
277 pDlg->Insert( SotClipboardFormatId::STRING, OUString() );
278 pDlg->Insert( SotClipboardFormatId::RTF, OUString() );
279 pDlg->Insert( SotClipboardFormatId::RICHTEXT, OUString() );
280 // Do not offer SotClipboardFormatId::STRING_TSVC for
281 // in-cell paste.
283 TransferableDataHelper aDataHelper(
284 TransferableDataHelper::CreateFromSystemClipboard( rViewData.GetActiveWin() ) );
286 nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() );
287 pDlg.disposeAndClear();
289 // while the dialog was open, edit mode may have been stopped
290 if (!ScModule::get()->IsInputMode())
291 return;
293 if (nFormat != SotClipboardFormatId::NONE)
295 if (SotClipboardFormatId::STRING == nFormat)
296 pTableView->Paste();
297 else
298 pTableView->PasteSpecial();
300 if (pTopView)
301 pTopView->Paste();
304 if (vcl::Window* pViewWindow = pTopView ? pTopView->GetWindow() : nullptr)
305 pViewWindow->GrabFocus();
307 break;
309 case SID_PASTE_UNFORMATTED:
311 pTableView->Paste();
313 if (pTopView)
315 pTopView->Paste();
316 if (vcl::Window* pViewWindow = pTopView->GetWindow())
317 pViewWindow->GrabFocus();
320 break;
322 case SID_SELECTALL:
324 sal_Int32 nPar = rEngine.GetParagraphCount();
325 if (nPar)
327 sal_Int32 nLen = rEngine.GetTextLen(nPar-1);
328 pTableView->SetSelection(ESelection(0,0,nPar-1,nLen));
329 if (pTopView)
330 pTopView->SetSelection(ESelection(0,0,nPar-1,nLen));
331 rBindings.Invalidate( SID_ATTR_CHAR_FONT );
332 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
333 rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
334 rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
335 rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
336 rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT );
337 rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED );
338 rBindings.Invalidate( SID_ATTR_CHAR_KERNING );
339 rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
340 rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
341 rBindings.Invalidate( SID_SET_SUB_SCRIPT );
344 return;
345 case SID_UNICODE_NOTATION_TOGGLE:
347 EditView* pActiveView = pHdl->GetActiveView();
348 if( pActiveView )
350 ESelection aSel( pActiveView->GetSelection() );
351 OUString sInput(aSel.HasRange() ? pActiveView->GetSelected()
352 : rEngine.GetText());
354 if (aSel.start.nIndex > aSel.end.nIndex)
355 aSel.end.nIndex = aSel.start.nIndex;
357 //calculate a valid end-position by reading logical characters
358 sal_Int32 nUtf16Pos=0;
359 while ((nUtf16Pos < sInput.getLength()) && (nUtf16Pos < aSel.end.nIndex))
361 sInput.iterateCodePoints(&nUtf16Pos);
362 if (nUtf16Pos > aSel.end.nIndex)
363 aSel.end.nIndex = nUtf16Pos;
366 ToggleUnicodeCodepoint aToggle;
367 while( nUtf16Pos && aToggle.AllowMoreInput( sInput[nUtf16Pos-1]) )
368 --nUtf16Pos;
369 OUString sReplacement = aToggle.ReplacementString();
370 if( !sReplacement.isEmpty() )
372 aSel.start.nIndex = aSel.end.nIndex - aToggle.StringToReplace().getLength();
373 pTableView->SetSelection( aSel );
374 pTableView->InsertText(sReplacement, true);
375 if( pTopView )
377 pTopView->SetSelection( aSel );
378 pTopView->InsertText(sReplacement, true);
383 break;
385 case SID_CHARMAP:
387 SvtScriptType nScript = pTableView->GetSelectedScriptType();
388 sal_uInt16 nFontWhich = ( nScript == SvtScriptType::ASIAN ) ? EE_CHAR_FONTINFO_CJK :
389 ( ( nScript == SvtScriptType::COMPLEX ) ? EE_CHAR_FONTINFO_CTL :
390 EE_CHAR_FONTINFO );
391 auto const attribs = pTableView->GetAttribs();
392 const SvxFontItem& rItem = static_cast<const SvxFontItem&>(
393 attribs.Get(nFontWhich));
395 OUString aString;
396 std::shared_ptr<SvxFontItem> aNewItem(std::make_shared<SvxFontItem>(EE_CHAR_FONTINFO));
398 const SfxItemSet *pArgs = rReq.GetArgs();
399 const SfxPoolItem* pItem = nullptr;
400 if( pArgs )
401 pArgs->GetItemState(SID_CHARMAP, false, &pItem);
403 if ( pItem )
405 aString = static_cast<const SfxStringItem*>(pItem)->GetValue();
406 const SfxStringItem* pFontItem = pArgs->GetItemIfSet( SID_ATTR_SPECIALCHAR, false);
407 if ( pFontItem )
409 const OUString& aFontName(pFontItem->GetValue());
410 vcl::Font aFont(aFontName, Size(1,1)); // Size just because CTOR
411 // tdf#125054 see comment in drtxob.cxx, same ID
412 aNewItem = std::make_shared<SvxFontItem>(
413 aFont.GetFamilyType(), aFont.GetFamilyName(),
414 aFont.GetStyleName(), aFont.GetPitch(),
415 aFont.GetCharSet(), ATTR_FONT);
417 else
419 aNewItem.reset(rItem.Clone());
422 // tdf#125054 force Item to correct intended ID
423 aNewItem->SetWhich(EE_CHAR_FONTINFO);
425 else
427 ScViewUtil::ExecuteCharMap(rItem, *rViewData.GetViewShell());
429 // while the dialog was open, edit mode may have been stopped
430 if (!ScModule::get()->IsInputMode())
431 return;
434 if ( !aString.isEmpty() )
436 // if string contains WEAK characters, set all fonts
437 SvtScriptType nSetScript;
438 ScDocument& rDoc = rViewData.GetDocument();
439 if ( rDoc.HasStringWeakCharacters( aString ) )
440 nSetScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
441 else
442 nSetScript = rDoc.GetStringScriptType( aString );
444 SfxItemSet aSet( pTableView->GetEmptyItemSet() );
445 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, GetPool() );
446 aSetItem.PutItemForScriptType( nSetScript, *aNewItem );
447 aSet.Put( aSetItem.GetItemSet(), false );
449 // SetAttribs on the View selects a word, when nothing is selected
450 pTableView->getEditEngine().QuickSetAttribs( aSet, pTableView->GetSelection() );
451 pTableView->InsertText(aString);
452 if (pTopView)
453 pTopView->InsertText(aString);
455 SfxStringItem aStringItem( SID_CHARMAP, aString );
456 SfxStringItem aFontItem( SID_ATTR_SPECIALCHAR, aNewItem->GetFamilyName() );
457 rReq.AppendItem( aFontItem );
458 rReq.AppendItem( aStringItem );
459 rReq.Done();
463 if (vcl::Window* pViewWindow = pTopView ? pTopView->GetWindow() : nullptr)
464 pViewWindow->GrabFocus();
466 break;
468 case FID_INSERT_NAME:
470 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
472 ScopedVclPtr<AbstractScNamePasteDlg> pDlg(pFact->CreateScNamePasteDlg(rViewData.GetDialogParent(), rViewData.GetDocShell()));
473 short nRet = pDlg->Execute();
474 // pDlg is needed below
476 // while the dialog was open, edit mode may have been stopped
477 if (!ScModule::get()->IsInputMode())
478 return;
480 if ( nRet == BTN_PASTE_NAME )
482 std::vector<OUString> aNames = pDlg->GetSelectedNames();
483 if (!aNames.empty())
485 OUStringBuffer aBuffer;
486 for (const auto& rName : aNames)
488 aBuffer.append(rName + " ");
490 const OUString s = aBuffer.makeStringAndClear();
491 pTableView->InsertText(s);
492 if (pTopView)
493 pTopView->InsertText(s);
496 pDlg.disposeAndClear();
498 if (vcl::Window* pViewWindow = pTopView ? pTopView->GetWindow() : nullptr)
499 pViewWindow->GrabFocus();
501 break;
503 case SID_CHAR_DLG_EFFECT:
504 case SID_CHAR_DLG:
506 SfxItemSet aAttrs( pTableView->GetAttribs() );
508 SfxObjectShell* pObjSh = rViewData.GetSfxDocShell();
510 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
512 ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScCharDlg(
513 rViewData.GetDialogParent(), &aAttrs, pObjSh, false));
514 if (nSlot == SID_CHAR_DLG_EFFECT)
516 pDlg->SetCurPageId(u"fonteffects"_ustr);
518 short nRet = pDlg->Execute();
519 // pDlg is needed below
521 // while the dialog was open, edit mode may have been stopped
522 if (!ScModule::get()->IsInputMode())
523 return;
525 if ( nRet == RET_OK )
527 const SfxItemSet* pOut = pDlg->GetOutputItemSet();
528 pTableView->SetAttribs( *pOut );
531 break;
533 case SID_TOGGLE_REL:
535 /* TODO: MLFORMULA: this should work also with multi-line formulas. */
536 if (rEngine.GetParagraphCount() == 1)
538 OUString aText = rEngine.GetText();
539 ESelection aSel = pEditView->GetSelection(); // current View
541 ScDocument& rDoc = rViewData.GetDocument();
542 ScRefFinder aFinder(aText, rViewData.GetCurPos(), rDoc, rDoc.GetAddressConvention());
543 aFinder.ToggleRel(aSel.start.nIndex, aSel.end.nIndex);
544 if (aFinder.GetFound())
546 const OUString& aNew = aFinder.GetText();
547 ESelection aNewSel( 0,aFinder.GetSelStart(), 0,aFinder.GetSelEnd() );
548 rEngine.SetText( aNew );
549 pTableView->SetSelection( aNewSel );
550 if ( pTopView )
552 pTopView->getEditEngine().SetText( aNew );
553 pTopView->SetSelection( aNewSel );
556 // reference is being selected -> do not overwrite when typing
557 bSetSelIsRef = true;
561 break;
563 case SID_HYPERLINK_SETLINK:
564 if( pReqArgs )
566 const SfxPoolItem* pItem;
567 if ( pReqArgs->GetItemState( SID_HYPERLINK_SETLINK, true, &pItem ) == SfxItemState::SET )
569 const SvxHyperlinkItem* pHyper = static_cast<const SvxHyperlinkItem*>(pItem);
570 const OUString& rName = pHyper->GetName();
571 const OUString& rURL = pHyper->GetURL();
572 const OUString& rTarget = pHyper->GetTargetFrame();
573 SvxLinkInsertMode eMode = pHyper->GetInsertMode();
575 bool bCellLinksOnly
576 = (ScModule::get()->GetAppOptions().GetLinksInsertedLikeMSExcel()
577 && rViewData.GetSfxDocShell()->GetMedium()->GetFilter()->IsMSOFormat())
578 || comphelper::LibreOfficeKit::isActive();
580 bool bDone = false;
581 if ( (eMode == HLINK_DEFAULT || eMode == HLINK_FIELD) && !bCellLinksOnly )
583 std::unique_ptr<const SvxFieldData> aSvxFieldDataPtr(GetURLField());
584 const SvxURLField* pURLField(static_cast<const SvxURLField*>(aSvxFieldDataPtr.get()));
585 if ( pURLField )
587 // select old field
589 ESelection aSel = pTableView->GetSelection();
590 aSel.Adjust();
591 aSel.end.nPara = aSel.start.nPara;
592 aSel.end.nIndex = aSel.start.nIndex + 1;
593 pTableView->SetSelection( aSel );
595 // insert new field
597 SvxURLField aURLField( rURL, rName, SvxURLFormat::Repr );
598 aURLField.SetTargetFrame( rTarget );
599 SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD );
600 pTableView->InsertField( aURLItem );
601 pTableView->SetSelection( aSel ); // select inserted field
603 // now also fields in the Top-View
605 if ( pTopView )
607 aSel = pTopView->GetSelection();
608 aSel.end.nPara = aSel.start.nPara;
609 aSel.end.nIndex = aSel.start.nIndex + 1;
610 pTopView->SetSelection( aSel );
611 pTopView->InsertField( aURLItem );
612 pTopView->SetSelection( aSel ); // select inserted field
615 bDone = true;
619 if (!bDone)
621 if (bCellLinksOnly)
623 sal_Int32 nPar = rEngine.GetParagraphCount();
624 if (nPar)
626 sal_Int32 nLen = rEngine.GetTextLen(nPar - 1);
627 pTableView->SetSelection(ESelection(0, 0, nPar - 1, nLen));
628 if (pTopView)
629 pTopView->SetSelection(ESelection(0, 0, nPar - 1, nLen));
632 rViewData.GetViewShell()->
633 InsertURL( rName, rURL, rTarget, static_cast<sal_uInt16>(eMode) );
635 // when "Button", the InsertURL in ViewShell turns the EditShell off
636 // thus the immediate return statement
637 return;
641 break;
642 case SID_EDIT_HYPERLINK:
644 // Ensure the field is selected first
645 pEditView->SelectFieldAtCursor();
646 rViewData.GetViewShell()->GetViewFrame().GetDispatcher()->Execute(
647 SID_HYPERLINK_DIALOG);
649 break;
650 case SID_COPY_HYPERLINK_LOCATION:
652 const SvxFieldItem* pFieldItem
653 = pEditView->GetFieldAtSelection(/*AlsoCheckBeforeCursor=*/true);
654 const SvxFieldData* pField = pFieldItem ? pFieldItem->GetField() : nullptr;
655 if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField))
657 uno::Reference<datatransfer::clipboard::XClipboard> xClipboard
658 = pEditView->GetClipboard();
659 vcl::unohelper::TextDataObject::CopyStringTo(pURLField->GetURL(), xClipboard, SfxViewShell::Current());
662 break;
663 case SID_REMOVE_HYPERLINK:
665 URLFieldHelper::RemoveURLField(*pEditView);
667 break;
669 case FN_INSERT_SOFT_HYPHEN:
670 lclInsertCharacter( pTableView, pTopView, CHAR_SHY );
671 break;
672 case FN_INSERT_HARDHYPHEN:
673 lclInsertCharacter( pTableView, pTopView, CHAR_NBHY );
674 break;
675 case FN_INSERT_HARD_SPACE:
676 lclInsertCharacter( pTableView, pTopView, CHAR_NBSP );
677 break;
678 case FN_INSERT_NNBSP:
679 lclInsertCharacter( pTableView, pTopView, CHAR_NNBSP );
680 break;
681 case SID_INSERT_RLM:
682 lclInsertCharacter( pTableView, pTopView, CHAR_RLM );
683 break;
684 case SID_INSERT_LRM:
685 lclInsertCharacter( pTableView, pTopView, CHAR_LRM );
686 break;
687 case SID_INSERT_ZWSP:
688 lclInsertCharacter( pTableView, pTopView, CHAR_ZWSP );
689 break;
690 case SID_INSERT_WJ:
691 lclInsertCharacter( pTableView, pTopView, CHAR_WJ );
692 break;
693 case SID_INSERT_FIELD_SHEET:
695 SvxTableField aField(rViewData.GetTabNo());
696 SvxFieldItem aItem(aField, EE_FEATURE_FIELD);
697 pTableView->InsertField(aItem);
699 break;
700 case SID_INSERT_FIELD_TITLE:
702 SvxFileField aField;
703 SvxFieldItem aItem(aField, EE_FEATURE_FIELD);
704 pTableView->InsertField(aItem);
706 break;
707 case SID_INSERT_FIELD_DATE_VAR:
709 SvxDateField aField;
710 SvxFieldItem aItem(aField, EE_FEATURE_FIELD);
711 pTableView->InsertField(aItem);
713 break;
716 pHdl->DataChanged(false, bSetModified);
717 if (bSetSelIsRef)
718 pHdl->SetSelIsRef(true);
721 static void lcl_DisableAll( SfxItemSet& rSet ) // disable all slots
723 SfxWhichIter aIter( rSet );
724 sal_uInt16 nWhich = aIter.FirstWhich();
725 while (nWhich)
727 rSet.DisableItem( nWhich );
728 nWhich = aIter.NextWhich();
732 void ScEditShell::GetState( SfxItemSet& rSet )
734 // When deactivating the view, edit mode is stopped, but the EditShell is left active
735 // (a shell can't be removed from within Deactivate). In that state, the EditView isn't inserted
736 // into the EditEngine, so it can have an invalid selection and must not be used.
737 ScInputHandler* pHdl = GetMyInputHdl();
738 if ( !rViewData.HasEditView( rViewData.GetActivePart() ) )
740 lcl_DisableAll( rSet );
742 // Some items are actually useful and still applicable when in formula building mode: enable
743 if (pHdl && pHdl->IsFormulaMode())
745 rSet.ClearItem(SID_TOGGLE_REL); // F4 Cycle Cell Reference Types
746 rSet.ClearItem(SID_CHARMAP); // Insert Special Characters
748 return;
751 EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
753 SfxWhichIter aIter( rSet );
754 sal_uInt16 nWhich = aIter.FirstWhich();
755 while (nWhich)
757 switch (nWhich)
759 case SID_ATTR_INSERT: // Status row
761 if ( pActiveView )
762 rSet.Put( SfxBoolItem( nWhich, pActiveView->IsInsertMode() ) );
763 else
765 // Here the code used to pass the value 42 and it used
766 // to "work" without warnings because the SfxBoolItem
767 // was based on 'sal_Bool', which is actually 'unsigned
768 // char'. But now it uses actual 'bool', and passing 42
769 // for a 'bool' parameter causes a warning at least with
770 // MSVC. So use 'true'. I really really hope there is
771 // not code somewhere that retrieves this "boolean" item
772 // and checks it value for the magic value 42...
773 rSet.Put( SfxBoolItem( nWhich, true) );
776 break;
778 case SID_HYPERLINK_GETLINK:
780 SvxHyperlinkItem aHLinkItem;
781 bool bCellLinksOnly
782 = (ScModule::get()->GetAppOptions().GetLinksInsertedLikeMSExcel()
783 && rViewData.GetSfxDocShell()->GetMedium()->GetFilter()->IsMSOFormat())
784 || comphelper::LibreOfficeKit::isActive();
785 std::unique_ptr<const SvxFieldData> aSvxFieldDataPtr(GetURLField());
786 const SvxURLField* pURLField(static_cast<const SvxURLField*>(aSvxFieldDataPtr.get()));
787 if (!bCellLinksOnly)
789 if (pURLField)
791 aHLinkItem.SetName(pURLField->GetRepresentation());
792 aHLinkItem.SetURL(pURLField->GetURL());
793 aHLinkItem.SetTargetFrame(pURLField->GetTargetFrame());
795 else if (pActiveView)
797 // use selected text as name for urls
798 OUString sReturn = pActiveView->GetSelected();
799 sReturn = sReturn.copy(
800 0, std::min(sReturn.getLength(), static_cast<sal_Int32>(255)));
801 aHLinkItem.SetName(comphelper::string::stripEnd(sReturn, ' '));
804 else
806 if (!pURLField)
808 aSvxFieldDataPtr = GetFirstURLFieldFromCell();
809 pURLField = static_cast<const SvxURLField*>(aSvxFieldDataPtr.get());
811 if (pURLField)
813 aHLinkItem.SetURL(pURLField->GetURL());
814 aHLinkItem.SetTargetFrame(pURLField->GetTargetFrame());
816 ScDocument& rDoc = rViewData.GetDocument();
817 SCCOL nPosX = rViewData.GetCurX();
818 SCROW nPosY = rViewData.GetCurY();
819 SCTAB nTab = rViewData.GetTabNo();
820 aHLinkItem.SetName(rDoc.GetString(nPosX, nPosY, nTab));
822 rSet.Put(aHLinkItem);
824 break;
826 case SID_EDIT_HYPERLINK:
827 case SID_COPY_HYPERLINK_LOCATION:
828 case SID_REMOVE_HYPERLINK:
830 if (!URLFieldHelper::IsCursorAtURLField(*pEditView,
831 /*AlsoCheckBeforeCursor=*/true))
832 rSet.DisableItem (nWhich);
834 break;
836 case SID_TRANSLITERATE_HALFWIDTH:
837 case SID_TRANSLITERATE_FULLWIDTH:
838 case SID_TRANSLITERATE_HIRAGANA:
839 case SID_TRANSLITERATE_KATAKANA:
840 case SID_INSERT_RLM:
841 case SID_INSERT_LRM:
842 ScViewUtil::HideDisabledSlot( rSet, rViewData.GetBindings(), nWhich );
843 break;
845 case SID_THES:
847 OUString aStatusVal;
848 LanguageType nLang = LANGUAGE_NONE;
849 bool bIsLookUpWord = pActiveView &&
850 GetStatusValueForThesaurusFromContext(aStatusVal, nLang, *pActiveView);
851 rSet.Put( SfxStringItem( SID_THES, aStatusVal ) );
853 // disable thesaurus context menu entry if there is nothing to look up
854 bool bCanDoThesaurus = ScModule::HasThesaurusLanguage( nLang );
855 if (!bIsLookUpWord || !bCanDoThesaurus)
856 rSet.DisableItem( SID_THES );
858 break;
859 case SID_INSERT_FIELD_SHEET:
860 case SID_INSERT_FIELD_TITLE:
861 case SID_INSERT_FIELD_DATE_VAR:
862 break;
863 case SID_COPY:
864 case SID_CUT:
865 if (GetObjectShell() && GetObjectShell()->isContentExtractionLocked())
867 rSet.DisableItem(SID_COPY);
868 rSet.DisableItem(SID_CUT);
870 break;
873 nWhich = aIter.NextWhich();
877 std::unique_ptr<const SvxFieldData> ScEditShell::GetURLField()
879 ScInputHandler* pHdl = GetMyInputHdl();
880 EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
881 if (!pActiveView)
882 return std::unique_ptr<const SvxFieldData>();
884 const SvxFieldData* pField = pActiveView->GetFieldUnderMouseOrInSelectionOrAtCursor();
885 if (auto pURLField = dynamic_cast<const SvxURLField*>(pField))
886 return pURLField->Clone();
888 return std::unique_ptr<const SvxFieldData>();
891 std::unique_ptr<const SvxFieldData> ScEditShell::GetFirstURLFieldFromCell()
893 EditEngine& rEditEngine = GetEditView()->getEditEngine();
894 sal_Int32 nParaCount = rEditEngine.GetParagraphCount();
895 for (sal_Int32 nPara = 0; nPara < nParaCount; ++nPara)
897 ESelection aSel(nPara, 0);
898 std::vector<sal_Int32> aPosList;
899 rEditEngine.GetPortions(nPara, aPosList);
900 for (const auto& rPos : aPosList)
902 aSel.end.nIndex = rPos;
904 SfxItemSet aEditSet(rEditEngine.GetAttribs(aSel));
905 if (aSel.start.nIndex + 1 == aSel.end.nIndex)
907 // test if the character is a text field
908 if (const SvxFieldItem* pItem = aEditSet.GetItemIfSet(EE_FEATURE_FIELD, false))
910 const SvxFieldData* pField = pItem->GetField();
911 if (const SvxURLField* pUrlField = dynamic_cast<const SvxURLField*>(pField))
913 return pUrlField->Clone();
917 aSel.start.nIndex = aSel.end.nIndex;
921 return std::unique_ptr<const SvxFieldData>();
924 IMPL_LINK( ScEditShell, ClipboardChanged, TransferableDataHelper*, pDataHelper, void )
926 bPastePossible = ( pDataHelper->HasFormat( SotClipboardFormatId::STRING )
927 || pDataHelper->HasFormat( SotClipboardFormatId::RTF )
928 || pDataHelper->HasFormat( SotClipboardFormatId::RICHTEXT ));
930 SfxBindings& rBindings = rViewData.GetBindings();
931 rBindings.Invalidate( SID_PASTE );
932 rBindings.Invalidate( SID_PASTE_SPECIAL );
933 rBindings.Invalidate( SID_PASTE_UNFORMATTED );
934 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
937 void ScEditShell::GetClipState( SfxItemSet& rSet )
939 // Do not offer SotClipboardFormatId::STRING_TSVC for in-cell paste.
941 if ( !mxClipEvtLstnr.is() )
943 // create listener
944 mxClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScEditShell, ClipboardChanged ) );
945 vcl::Window* pWin = rViewData.GetActiveWin();
946 mxClipEvtLstnr->AddListener( pWin );
948 // get initial state
949 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( rViewData.GetActiveWin() ) );
950 bPastePossible = ( aDataHelper.HasFormat( SotClipboardFormatId::STRING )
951 || aDataHelper.HasFormat( SotClipboardFormatId::RTF )
952 || aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) );
955 SfxWhichIter aIter( rSet );
956 sal_uInt16 nWhich = aIter.FirstWhich();
957 while (nWhich)
959 switch (nWhich)
961 case SID_PASTE:
962 case SID_PASTE_SPECIAL:
963 case SID_PASTE_UNFORMATTED:
964 if( !bPastePossible )
965 rSet.DisableItem( nWhich );
966 break;
967 case SID_CLIPBOARD_FORMAT_ITEMS:
968 if( bPastePossible )
970 SvxClipboardFormatItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
971 TransferableDataHelper aDataHelper(
972 TransferableDataHelper::CreateFromSystemClipboard( rViewData.GetActiveWin() ) );
974 if ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) )
975 aFormats.AddClipbrdFormat( SotClipboardFormatId::STRING );
976 if ( aDataHelper.HasFormat( SotClipboardFormatId::RTF ) )
977 aFormats.AddClipbrdFormat( SotClipboardFormatId::RTF );
979 rSet.Put( aFormats );
981 else
982 rSet.DisableItem( nWhich );
983 break;
985 nWhich = aIter.NextWhich();
989 static void lcl_InvalidateUnder( SfxBindings& rBindings )
991 rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
992 rBindings.Invalidate( SID_ULINE_VAL_NONE );
993 rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
994 rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
995 rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
998 void ScEditShell::ExecuteAttr(SfxRequest& rReq)
1000 SfxItemSet aSet( pEditView->GetEmptyItemSet() );
1001 SfxBindings& rBindings = rViewData.GetBindings();
1002 const SfxItemSet* pArgs = rReq.GetArgs();
1003 sal_uInt16 nSlot = rReq.GetSlot();
1005 switch ( nSlot )
1007 case SID_ATTR_CHAR_FONTHEIGHT:
1008 case SID_ATTR_CHAR_FONT:
1010 if (pArgs)
1012 // #i78017 establish the same behaviour as in Writer
1013 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
1014 if (nSlot == SID_ATTR_CHAR_FONT)
1016 nScript = pEditView->GetSelectedScriptType();
1017 if (nScript == SvtScriptType::NONE) nScript = ScGlobal::GetDefaultScriptType();
1020 SfxItemPool& rPool = GetPool();
1021 SvxScriptSetItem aSetItem( nSlot, rPool );
1022 sal_uInt16 nWhich = rPool.GetWhichIDFromSlotID( nSlot );
1023 aSetItem.PutItemForScriptType( nScript, pArgs->Get( nWhich ) );
1025 aSet.Put( aSetItem.GetItemSet(), false );
1028 break;
1030 case SID_ATTR_CHAR_COLOR:
1031 case SID_ATTR_CHAR_BACK_COLOR:
1033 if (pArgs)
1035 aSet.Put( pArgs->Get( pArgs->GetPool()->GetWhichIDFromSlotID( nSlot ) ) );
1036 rBindings.Invalidate( nSlot );
1038 else
1040 const sal_uInt16 nEEWhich = GetPool().GetWhichIDFromSlotID(nSlot);
1041 const std::optional<NamedColor> oColor
1042 = rViewData.GetDocShell()->GetRecentColor(nSlot);
1043 if (oColor.has_value())
1045 const model::ComplexColor aCol = (*oColor).getComplexColor();
1046 aSet.Put(SvxColorItem(aCol.getFinalColor(), aCol, nEEWhich));
1050 break;
1052 // Toggles
1054 case SID_ATTR_CHAR_WEIGHT:
1056 // #i78017 establish the same behaviour as in Writer
1057 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
1059 SfxItemPool& rPool = GetPool();
1061 bool bOld = false;
1062 SvxScriptSetItem aOldSetItem( nSlot, rPool );
1063 aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), false );
1064 const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
1065 if ( pCore && static_cast<const SvxWeightItem*>(pCore)->GetWeight() > WEIGHT_NORMAL )
1066 bOld = true;
1068 SvxScriptSetItem aSetItem( nSlot, rPool );
1069 aSetItem.PutItemForScriptType( nScript,
1070 SvxWeightItem( bOld ? WEIGHT_NORMAL : WEIGHT_BOLD, EE_CHAR_WEIGHT ) );
1071 aSet.Put( aSetItem.GetItemSet(), false );
1073 rBindings.Invalidate( nSlot );
1075 break;
1077 case SID_ATTR_CHAR_POSTURE:
1079 // #i78017 establish the same behaviour as in Writer
1080 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
1082 SfxItemPool& rPool = GetPool();
1084 bool bOld = false;
1085 SvxScriptSetItem aOldSetItem( nSlot, rPool );
1086 aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), false );
1087 const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
1088 if ( pCore && static_cast<const SvxPostureItem*>(pCore)->GetValue() != ITALIC_NONE )
1089 bOld = true;
1091 SvxScriptSetItem aSetItem( nSlot, rPool );
1092 aSetItem.PutItemForScriptType( nScript,
1093 SvxPostureItem( bOld ? ITALIC_NONE : ITALIC_NORMAL, EE_CHAR_ITALIC ) );
1094 aSet.Put( aSetItem.GetItemSet(), false );
1096 rBindings.Invalidate( nSlot );
1098 break;
1100 case SID_ULINE_VAL_NONE:
1101 aSet.Put( SvxUnderlineItem( LINESTYLE_NONE, EE_CHAR_UNDERLINE ) );
1102 lcl_InvalidateUnder( rBindings );
1103 break;
1105 case SID_ATTR_CHAR_UNDERLINE:
1106 case SID_ULINE_VAL_SINGLE:
1107 case SID_ULINE_VAL_DOUBLE:
1108 case SID_ULINE_VAL_DOTTED:
1110 FontLineStyle eOld = pEditView->GetAttribs().Get(EE_CHAR_UNDERLINE).GetLineStyle();
1111 FontLineStyle eNew = eOld;
1112 switch (nSlot)
1114 case SID_ATTR_CHAR_UNDERLINE:
1115 if ( pArgs )
1117 const SvxTextLineItem& rTextLineItem = static_cast< const SvxTextLineItem& >( pArgs->Get( pArgs->GetPool()->GetWhichIDFromSlotID(nSlot) ) );
1118 eNew = rTextLineItem.GetLineStyle();
1120 else
1122 eNew = ( eOld != LINESTYLE_NONE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
1124 break;
1125 case SID_ULINE_VAL_SINGLE:
1126 eNew = ( eOld == LINESTYLE_SINGLE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
1127 break;
1128 case SID_ULINE_VAL_DOUBLE:
1129 eNew = ( eOld == LINESTYLE_DOUBLE ) ? LINESTYLE_NONE : LINESTYLE_DOUBLE;
1130 break;
1131 case SID_ULINE_VAL_DOTTED:
1132 eNew = ( eOld == LINESTYLE_DOTTED ) ? LINESTYLE_NONE : LINESTYLE_DOTTED;
1133 break;
1135 aSet.Put( SvxUnderlineItem( eNew, EE_CHAR_UNDERLINE ) );
1136 lcl_InvalidateUnder( rBindings );
1138 break;
1140 case SID_ATTR_CHAR_OVERLINE:
1142 FontLineStyle eOld = pEditView->GetAttribs().Get(EE_CHAR_OVERLINE).GetLineStyle();
1143 FontLineStyle eNew = ( eOld != LINESTYLE_NONE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
1144 aSet.Put( SvxOverlineItem( eNew, EE_CHAR_OVERLINE ) );
1145 rBindings.Invalidate( nSlot );
1147 break;
1149 case SID_ATTR_CHAR_STRIKEOUT:
1151 bool bOld = pEditView->GetAttribs().Get(EE_CHAR_STRIKEOUT).GetValue() != STRIKEOUT_NONE;
1152 aSet.Put( SvxCrossedOutItem( bOld ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT ) );
1153 rBindings.Invalidate( nSlot );
1155 break;
1157 case SID_ATTR_CHAR_SHADOWED:
1159 bool bOld = pEditView->GetAttribs().Get(EE_CHAR_SHADOW).GetValue();
1160 aSet.Put( SvxShadowedItem( !bOld, EE_CHAR_SHADOW ) );
1161 rBindings.Invalidate( nSlot );
1163 break;
1165 case SID_ATTR_CHAR_CONTOUR:
1167 bool bOld = pEditView->GetAttribs().Get(EE_CHAR_OUTLINE).GetValue();
1168 aSet.Put( SvxContourItem( !bOld, EE_CHAR_OUTLINE ) );
1169 rBindings.Invalidate( nSlot );
1171 break;
1173 case SID_SET_SUPER_SCRIPT:
1175 SvxEscapement eOld = static_cast<SvxEscapement>(pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT).GetEnumValue());
1176 SvxEscapement eNew = (eOld == SvxEscapement::Superscript) ?
1177 SvxEscapement::Off : SvxEscapement::Superscript;
1178 aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
1179 rBindings.Invalidate( nSlot );
1181 break;
1182 case SID_SET_SUB_SCRIPT:
1184 SvxEscapement eOld = static_cast<SvxEscapement>(pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT).GetEnumValue());
1185 SvxEscapement eNew = (eOld == SvxEscapement::Subscript) ?
1186 SvxEscapement::Off : SvxEscapement::Subscript;
1187 aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
1188 rBindings.Invalidate( nSlot );
1190 break;
1191 case SID_ATTR_CHAR_KERNING:
1193 if(pArgs)
1195 aSet.Put ( pArgs->Get(pArgs->GetPool()->GetWhichIDFromSlotID(nSlot)));
1196 rBindings.Invalidate( nSlot );
1199 break;
1201 case SID_GROW_FONT_SIZE:
1202 case SID_SHRINK_FONT_SIZE:
1204 SfxObjectShell* pObjSh = SfxObjectShell::Current();
1205 const SvxFontListItem* pFontListItem = static_cast<const SvxFontListItem*>
1206 (pObjSh ? pObjSh->GetItem(SID_ATTR_CHAR_FONTLIST) : nullptr);
1207 const FontList* pFontList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
1208 pEditView->ChangeFontSize( nSlot == SID_GROW_FONT_SIZE, pFontList );
1209 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
1211 break;
1214 // apply
1216 EditEngine& rEngine = pEditView->getEditEngine();
1217 bool bOld = rEngine.SetUpdateLayout(false);
1219 pEditView->SetAttribs( aSet );
1221 rEngine.SetUpdateLayout(bOld);
1222 pEditView->Invalidate();
1224 ScInputHandler* pHdl = GetMyInputHdl();
1225 pHdl->SetModified();
1227 rReq.Done();
1230 void ScEditShell::GetAttrState(SfxItemSet &rSet)
1232 if ( !rViewData.HasEditView( rViewData.GetActivePart() ) )
1234 lcl_DisableAll( rSet );
1235 return;
1238 SfxItemSet aAttribs = pEditView->GetAttribs();
1239 rSet.Put( aAttribs );
1241 // choose font info according to selection script type
1243 SvtScriptType nScript = pEditView->GetSelectedScriptType();
1244 if (nScript == SvtScriptType::NONE) nScript = ScGlobal::GetDefaultScriptType();
1246 // #i55929# input-language-dependent script type (depends on input language if nothing selected)
1247 SvtScriptType nInputScript = nScript;
1248 if ( !pEditView->GetSelection().HasRange() )
1250 LanguageType nInputLang = rViewData.GetActiveWin()->GetInputLanguage();
1251 if (nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM)
1252 nInputScript = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
1255 // #i55929# according to spec, nInputScript is used for font and font height only
1256 if ( rSet.GetItemState( EE_CHAR_FONTINFO ) != SfxItemState::UNKNOWN )
1257 ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTINFO, nInputScript );
1258 if ( rSet.GetItemState( EE_CHAR_FONTHEIGHT ) != SfxItemState::UNKNOWN )
1259 ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTHEIGHT, nInputScript );
1260 if ( rSet.GetItemState( EE_CHAR_WEIGHT ) != SfxItemState::UNKNOWN )
1261 ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_WEIGHT, nScript );
1262 if ( rSet.GetItemState( EE_CHAR_ITALIC ) != SfxItemState::UNKNOWN )
1263 ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_ITALIC, nScript );
1265 // underline
1266 SfxItemState eState = aAttribs.GetItemState( EE_CHAR_UNDERLINE );
1267 if ( eState == SfxItemState::INVALID )
1269 rSet.InvalidateItem( SID_ULINE_VAL_NONE );
1270 rSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
1271 rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
1272 rSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
1274 else
1276 FontLineStyle eUnderline = aAttribs.Get(EE_CHAR_UNDERLINE).GetLineStyle();
1277 rSet.Put(SfxBoolItem(SID_ULINE_VAL_SINGLE, eUnderline == LINESTYLE_SINGLE));
1278 rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOUBLE, eUnderline == LINESTYLE_DOUBLE));
1279 rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOTTED, eUnderline == LINESTYLE_DOTTED));
1280 rSet.Put(SfxBoolItem(SID_ULINE_VAL_NONE, eUnderline == LINESTYLE_NONE));
1283 //! Testing whether brace highlighting is active !!!!
1284 ScInputHandler* pHdl = GetMyInputHdl();
1285 if ( pHdl && pHdl->IsFormulaMode() )
1286 rSet.ClearItem( EE_CHAR_WEIGHT ); // Highlighted brace not here
1288 SvxEscapement eEsc = static_cast<SvxEscapement>(aAttribs.Get( EE_CHAR_ESCAPEMENT ).GetEnumValue());
1289 rSet.Put(SfxBoolItem(SID_SET_SUPER_SCRIPT, eEsc == SvxEscapement::Superscript));
1290 rSet.Put(SfxBoolItem(SID_SET_SUB_SCRIPT, eEsc == SvxEscapement::Subscript));
1291 rViewData.GetBindings().Invalidate( SID_SET_SUPER_SCRIPT );
1292 rViewData.GetBindings().Invalidate( SID_SET_SUB_SCRIPT );
1294 eState = aAttribs.GetItemState( EE_CHAR_KERNING );
1295 rViewData.GetBindings().Invalidate( SID_ATTR_CHAR_KERNING );
1296 if ( eState == SfxItemState::INVALID )
1298 rSet.InvalidateItem(EE_CHAR_KERNING);
1302 OUString ScEditShell::GetSelectionText( bool bWholeWord )
1304 OUString aStrSelection;
1306 if ( rViewData.HasEditView( rViewData.GetActivePart() ) )
1308 if ( bWholeWord )
1310 EditEngine& rEngine = pEditView->getEditEngine();
1311 ESelection aSel = pEditView->GetSelection();
1312 OUString aStrCurrentDelimiters = rEngine.GetWordDelimiters();
1314 rEngine.SetWordDelimiters(u" .,;\"'"_ustr);
1315 aStrSelection = rEngine.GetWord(aSel.end);
1316 rEngine.SetWordDelimiters( aStrCurrentDelimiters );
1318 else
1320 aStrSelection = pEditView->GetSelected();
1324 return aStrSelection;
1327 void ScEditShell::ExecuteUndo(const SfxRequest& rReq)
1329 // Undo must be handled here because it's called for both EditViews
1331 ScInputHandler* pHdl = GetMyInputHdl();
1332 OSL_ENSURE(pHdl,"no ScInputHandler");
1333 EditView* pTopView = pHdl->GetTopView();
1334 EditView* pTableView = pHdl->GetTableView();
1335 OSL_ENSURE(pTableView,"no EditView");
1337 pHdl->DataChanging();
1339 const SfxItemSet* pReqArgs = rReq.GetArgs();
1340 sal_uInt16 nSlot = rReq.GetSlot();
1341 switch ( nSlot )
1343 case SID_UNDO:
1344 case SID_REDO:
1346 bool bIsUndo = ( nSlot == SID_UNDO );
1348 sal_uInt16 nCount = 1;
1349 const SfxPoolItem* pItem;
1350 if ( pReqArgs && pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
1351 nCount = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
1353 for (sal_uInt16 i=0; i<nCount; i++)
1355 if ( bIsUndo )
1357 pTableView->Undo();
1358 if (pTopView)
1359 pTopView->Undo();
1361 else
1363 pTableView->Redo();
1364 if (pTopView)
1365 pTopView->Redo();
1369 break;
1371 rViewData.GetBindings().InvalidateAll(false);
1373 pHdl->DataChanged();
1376 void ScEditShell::GetUndoState(SfxItemSet &rSet)
1378 // Undo state is taken from normal ViewFrame state function
1380 SfxViewFrame& rViewFrm = rViewData.GetViewShell()->GetViewFrame();
1381 if ( GetUndoManager() )
1383 SfxWhichIter aIter(rSet);
1384 sal_uInt16 nWhich = aIter.FirstWhich();
1385 while( nWhich )
1387 rViewFrm.GetSlotState( nWhich, nullptr, &rSet );
1388 nWhich = aIter.NextWhich();
1392 // disable if no action in input line EditView
1394 ScInputHandler* pHdl = GetMyInputHdl();
1395 OSL_ENSURE(pHdl,"no ScInputHandler");
1396 EditView* pTopView = pHdl->GetTopView();
1397 if (pTopView)
1399 SfxUndoManager& rTopMgr = pTopView->getEditEngine().GetUndoManager();
1400 if ( rTopMgr.GetUndoActionCount() == 0 )
1401 rSet.DisableItem( SID_UNDO );
1402 if ( rTopMgr.GetRedoActionCount() == 0 )
1403 rSet.DisableItem( SID_REDO );
1407 void ScEditShell::ExecuteTrans( const SfxRequest& rReq )
1409 TransliterationFlags nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() );
1410 if ( nType == TransliterationFlags::NONE )
1411 return;
1413 ScInputHandler* pHdl = GetMyInputHdl();
1414 assert(pHdl && "no ScInputHandler");
1416 EditView* pTopView = pHdl->GetTopView();
1417 EditView* pTableView = pHdl->GetTableView();
1418 assert(pTableView && "no EditView");
1420 pHdl->DataChanging();
1422 pTableView->TransliterateText( nType );
1423 if (pTopView)
1424 pTopView->TransliterateText( nType );
1426 pHdl->DataChanged();
1429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */