From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- formula/source/ui/dlg/funcutl.cxx | 486 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 486 insertions(+) create mode 100644 formula/source/ui/dlg/funcutl.cxx (limited to 'formula/source/ui/dlg/funcutl.cxx') diff --git a/formula/source/ui/dlg/funcutl.cxx b/formula/source/ui/dlg/funcutl.cxx new file mode 100644 index 000000000..58c2492c5 --- /dev/null +++ b/formula/source/ui/dlg/funcutl.cxx @@ -0,0 +1,486 @@ +/* -*- 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 + +#include +#include +#include +#include "ControlHelper.hxx" +#include "parawin.hxx" +#include +#include +#include + +namespace formula +{ + +ArgEdit::ArgEdit(std::unique_ptr xControl) + : RefEdit(std::move(xControl)) + , pEdPrev(nullptr) + , pEdNext(nullptr) + , pSlider(nullptr) + , pParaWin(nullptr) + , nArgs(0) +{ +} + +void ArgEdit::Init(ArgEdit* pPrevEdit, ArgEdit* pNextEdit, + weld::ScrolledWindow& rArgSlider, + ParaWin& rParaWin, sal_uInt16 nArgCount) +{ + pEdPrev = pPrevEdit; + pEdNext = pNextEdit; + pSlider = &rArgSlider; + pParaWin = &rParaWin; + nArgs = nArgCount; +} + +// Cursor control for Edit Fields in Argument Dialog +bool ArgEdit::KeyInput(const KeyEvent& rKEvt) +{ + vcl::KeyCode aCode = rKEvt.GetKeyCode(); + bool bUp = (aCode.GetCode() == KEY_UP); + bool bDown = (aCode.GetCode() == KEY_DOWN); + + if ( pSlider + && ( !aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() ) + && ( bUp || bDown ) ) + { + if ( nArgs > 1 ) + { + ArgEdit* pEd = nullptr; + int nThumb = pSlider->vadjustment_get_value(); + bool bDoScroll = false; + bool bChangeFocus = false; + + if ( bDown ) + { + if ( nArgs > 4 ) + { + if ( !pEdNext ) + { + nThumb++; + bDoScroll = ( nThumb+3 < static_cast(nArgs) ); + } + else + { + pEd = pEdNext; + bChangeFocus = true; + } + } + else if ( pEdNext ) + { + pEd = pEdNext; + bChangeFocus = true; + } + } + else // if ( bUp ) + { + if ( nArgs > 4 ) + { + if ( !pEdPrev ) + { + nThumb--; + bDoScroll = ( nThumb >= 0 ); + } + else + { + pEd = pEdPrev; + bChangeFocus = true; + } + } + else if ( pEdPrev ) + { + pEd = pEdPrev; + bChangeFocus = true; + } + } + + if ( bDoScroll ) + { + pSlider->vadjustment_set_value( nThumb ); + pParaWin->SliderMoved(); + } + else if ( bChangeFocus ) + { + pEd->GrabFocus(); + } + } + return true; + } + return RefEdit::KeyInput(rKEvt); +} + +ArgInput::ArgInput() +{ + pFtArg=nullptr; + pBtnFx=nullptr; + pEdArg=nullptr; + pRefBtn=nullptr; +} + +void ArgInput::InitArgInput(weld::Label* pftArg, weld::Button* pbtnFx, + ArgEdit* pedArg, RefButton* prefBtn) +{ + pFtArg =pftArg; + pBtnFx =pbtnFx; + pEdArg =pedArg; + pRefBtn=prefBtn; + + if(pBtnFx!=nullptr) + { + pBtnFx->connect_clicked( LINK( this, ArgInput, FxBtnClickHdl ) ); + pBtnFx->connect_focus_in( LINK( this, ArgInput, FxBtnFocusHdl ) ); + } + if(pEdArg!=nullptr) + { + pEdArg->SetGetFocusHdl ( LINK( this, ArgInput, EdFocusHdl ) ); + pEdArg->SetModifyHdl ( LINK( this, ArgInput, EdModifyHdl ) ); + } +} + +// Sets the Name for the Argument +void ArgInput::SetArgName(const OUString &aArg) +{ + if (pFtArg) + pFtArg->set_label(aArg ); +} + +// Returns the Name for the Argument +OUString ArgInput::GetArgName() const +{ + OUString aPrivArgName; + if (pFtArg) + aPrivArgName = pFtArg->get_label(); + return aPrivArgName; +} + +//Sets the Name for the Argument +void ArgInput::SetArgNameFont(const vcl::Font &aFont) +{ + if (pFtArg) + pFtArg->set_font(aFont); +} + +//Sets up the Selection for the EditBox. +void ArgInput::SelectAll() +{ + if (pEdArg) + pEdArg->SelectAll(); +} + +//Sets the Value for the Argument +void ArgInput::SetArgVal(const OUString &rVal) +{ + if (pEdArg) + pEdArg->SetRefString(rVal); +} + +//Returns the Value for the Argument +OUString ArgInput::GetArgVal() const +{ + OUString aResult; + if (pEdArg) + aResult=pEdArg->GetText(); + return aResult; +} + +//Hides the Controls +void ArgInput::Hide() +{ + if (pFtArg && pBtnFx && pEdArg && pRefBtn) + { + pFtArg->hide(); + pBtnFx->hide(); + pEdArg->GetWidget()->hide(); + pRefBtn->GetWidget()->hide(); + } +} + +//Casts the Controls again. +void ArgInput::Show() +{ + if (pFtArg && pBtnFx && pEdArg && pRefBtn) + { + pFtArg->show(); + pBtnFx->show(); + pEdArg->GetWidget()->show(); + pRefBtn->GetWidget()->show(); + } +} + +void ArgInput::UpdateAccessibleNames() +{ + OUString aArgName = ":" + pFtArg->get_label(); + + OUString aName = pBtnFx->get_tooltip_text() + aArgName; + pBtnFx->set_accessible_name(aName); + + aName = pRefBtn->GetWidget()->get_tooltip_text() + aArgName; + pRefBtn->GetWidget()->set_accessible_name(aName); +} + +IMPL_LINK(ArgInput, FxBtnClickHdl, weld::Button&, rBtn, void) +{ + if (&rBtn == pBtnFx) + aFxClickLink.Call(*this); +} + +IMPL_LINK( ArgInput, FxBtnFocusHdl, weld::Widget&, rControl, void ) +{ + if (&rControl == pBtnFx) + aFxFocusLink.Call(*this); +} + +IMPL_LINK( ArgInput, EdFocusHdl, RefEdit&, rControl, void ) +{ + if (&rControl == pEdArg) + aEdFocusLink.Call(*this); +} + +IMPL_LINK( ArgInput, EdModifyHdl, RefEdit&, rEdit, void ) +{ + if (&rEdit == pEdArg) + aEdModifyLink.Call(*this); +} + +RefEdit::RefEdit(std::unique_ptr xControl) + : xEntry(std::move(xControl)) + , aIdle("formula RefEdit Idle") + , pAnyRefDlg(nullptr) + , pLabelWidget(nullptr) + , mpFocusInEvent(nullptr) + , mpFocusOutEvent(nullptr) +{ + xEntry->connect_focus_in(LINK(this, RefEdit, GetFocusHdl)); + xEntry->connect_focus_out(LINK(this, RefEdit, LoseFocusHdl)); + xEntry->connect_key_press(LINK(this, RefEdit, KeyInputHdl)); + xEntry->connect_changed(LINK(this, RefEdit, Modify)); + aIdle.SetInvokeHandler( LINK( this, RefEdit, UpdateHdl ) ); +} + +RefEdit::~RefEdit() +{ + if (mpFocusInEvent) + Application::RemoveUserEvent(mpFocusInEvent); + if (mpFocusOutEvent) + Application::RemoveUserEvent(mpFocusOutEvent); + aIdle.ClearInvokeHandler(); + aIdle.Stop(); +} + +void RefEdit::SetRefString( const OUString& rStr ) +{ + // Prevent unwanted side effects by setting only a differing string. + // See commit message for reasons. + if (xEntry->get_text() != rStr) + xEntry->set_text(rStr); +} + +void RefEdit::SetRefValid(bool bValid) +{ + xEntry->set_message_type(bValid ? weld::EntryMessageType::Normal : weld::EntryMessageType::Error); +} + +void RefEdit::SetText(const OUString& rStr) +{ + xEntry->set_text(rStr); + UpdateHdl( &aIdle ); +} + +void RefEdit::StartUpdateData() +{ + aIdle.Start(); +} + +void RefEdit::SetReferences(IControlReferenceHandler* pDlg, weld::Label* pLabel) +{ + pAnyRefDlg = pDlg; + pLabelWidget = pLabel; + + if( pDlg ) + { + aIdle.SetInvokeHandler(LINK(this, RefEdit, UpdateHdl)); + } + else + { + aIdle.ClearInvokeHandler(); + aIdle.Stop(); + } +} + +IMPL_LINK_NOARG(RefEdit, Modify, weld::Entry&, void) +{ + maModifyHdl.Call(*this); + if (pAnyRefDlg) + pAnyRefDlg->HideReference(); +} + +IMPL_LINK(RefEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + return KeyInput(rKEvt); +} + +bool RefEdit::KeyInput(const KeyEvent& rKEvt) +{ + const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); + if (pAnyRefDlg && !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_F2) + { + pAnyRefDlg->ReleaseFocus( this ); + return true; + } + + switch (rKeyCode.GetCode()) + { + case KEY_RETURN: + case KEY_ESCAPE: + return maActivateHdl.Call(*GetWidget()); + } + + return false; +} + +void RefEdit::GetFocus() +{ + maGetFocusHdl.Call(*this); + StartUpdateData(); +} + +void RefEdit::LoseFocus() +{ + maLoseFocusHdl.Call(*this); + if( pAnyRefDlg ) + pAnyRefDlg->HideReference(); +} + +IMPL_LINK_NOARG(RefEdit, GetFocusHdl, weld::Widget&, void) +{ + // in e.g. function wizard RefEdits we want to select all when we get focus + // but in the gtk case there are pending gtk handlers which change selection + // after our handler, so post our focus in event to happen after those complete + if (mpFocusInEvent) + Application::RemoveUserEvent(mpFocusInEvent); + mpFocusInEvent = Application::PostUserEvent(LINK(this, RefEdit, AsyncFocusInHdl)); +} + +IMPL_LINK_NOARG(RefEdit, LoseFocusHdl, weld::Widget&, void) +{ + // tdf#127262 because focus in is async, focus out must not appear out + // of sequence to focus in + if (mpFocusOutEvent) + Application::RemoveUserEvent(mpFocusOutEvent); + mpFocusOutEvent = Application::PostUserEvent(LINK(this, RefEdit, AsyncFocusOutHdl)); +} + +IMPL_LINK_NOARG(RefEdit, AsyncFocusInHdl, void*, void) +{ + mpFocusInEvent = nullptr; + GetFocus(); +} + +IMPL_LINK_NOARG(RefEdit, AsyncFocusOutHdl, void*, void) +{ + mpFocusOutEvent = nullptr; + LoseFocus(); +} + +IMPL_LINK_NOARG(RefEdit, UpdateHdl, Timer *, void) +{ + if( pAnyRefDlg ) + pAnyRefDlg->ShowReference(xEntry->get_text()); +} + +RefButton::RefButton(std::unique_ptr xControl) + : xButton(std::move(xControl)) + , pAnyRefDlg( nullptr ) + , pRefEdit( nullptr ) +{ + xButton->connect_focus_in(LINK(this, RefButton, GetFocus)); + xButton->connect_focus_out(LINK(this, RefButton, LoseFocus)); + xButton->connect_key_press(LINK(this, RefButton, KeyInput)); + xButton->connect_clicked(LINK(this, RefButton, Click)); + SetStartImage(); +} + +RefButton::~RefButton() +{ +} + +void RefButton::SetStartImage() +{ + xButton->set_from_icon_name(RID_BMP_REFBTN1); + xButton->set_tooltip_text(ForResId(RID_STR_SHRINK)); +} + +void RefButton::SetEndImage() +{ + xButton->set_from_icon_name(RID_BMP_REFBTN2); + xButton->set_tooltip_text(ForResId(RID_STR_EXPAND)); +} + +void RefButton::SetReferences( IControlReferenceHandler* pDlg, RefEdit* pEdit ) +{ + pAnyRefDlg = pDlg; + pRefEdit = pEdit; +} + +IMPL_LINK_NOARG(RefButton, Click, weld::Button&, void) +{ + maClickHdl.Call(*this); + if( pAnyRefDlg ) + pAnyRefDlg->ToggleCollapsed( pRefEdit, this ); +} + +IMPL_LINK(RefButton, KeyInput, const KeyEvent&, rKEvt, bool) +{ + const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); + if (pAnyRefDlg && !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_F2) + { + pAnyRefDlg->ReleaseFocus( pRefEdit ); + return true; + } + + switch (rKeyCode.GetCode()) + { + case KEY_RETURN: + case KEY_ESCAPE: + return maActivateHdl.Call(*GetWidget()); + } + + return false; +} + +IMPL_LINK_NOARG(RefButton, GetFocus, weld::Widget&, void) +{ + maGetFocusHdl.Call(*this); + if (pRefEdit) + pRefEdit->StartUpdateData(); +} + +IMPL_LINK_NOARG(RefButton, LoseFocus, weld::Widget&, void) +{ + maLoseFocusHdl.Call(*this); + if (pRefEdit) + pRefEdit->DoModify(); +} + +} // formula + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3