summaryrefslogtreecommitdiffstats
path: root/formula/source/ui/dlg/funcutl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'formula/source/ui/dlg/funcutl.cxx')
-rw-r--r--formula/source/ui/dlg/funcutl.cxx486
1 files changed, 486 insertions, 0 deletions
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 <vcl/event.hxx>
+
+#include <formula/funcutl.hxx>
+#include <formula/IControlReferenceHandler.hxx>
+#include <vcl/svapp.hxx>
+#include "ControlHelper.hxx"
+#include "parawin.hxx"
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <core_resource.hxx>
+
+namespace formula
+{
+
+ArgEdit::ArgEdit(std::unique_ptr<weld::Entry> 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<tools::Long>(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<weld::Entry> 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<weld::Button> 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: */