1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <vcl/event.hxx>
22 #include <formula/funcutl.hxx>
23 #include <formula/IControlReferenceHandler.hxx>
24 #include <vcl/svapp.hxx>
25 #include "ControlHelper.hxx"
26 #include "parawin.hxx"
27 #include <strings.hrc>
28 #include <bitmaps.hlst>
29 #include <core_resource.hxx>
34 ArgEdit::ArgEdit(std::unique_ptr
<weld::Entry
> xControl
)
35 : RefEdit(std::move(xControl
))
44 void ArgEdit::Init(ArgEdit
* pPrevEdit
, ArgEdit
* pNextEdit
,
45 weld::ScrolledWindow
& rArgSlider
,
46 ParaWin
& rParaWin
, sal_uInt16 nArgCount
)
50 pSlider
= &rArgSlider
;
55 // Cursor control for Edit Fields in Argument Dialog
56 bool ArgEdit::KeyInput(const KeyEvent
& rKEvt
)
58 vcl::KeyCode aCode
= rKEvt
.GetKeyCode();
59 bool bUp
= (aCode
.GetCode() == KEY_UP
);
60 bool bDown
= (aCode
.GetCode() == KEY_DOWN
);
63 && ( !aCode
.IsShift() && !aCode
.IsMod1() && !aCode
.IsMod2() )
68 ArgEdit
* pEd
= nullptr;
69 int nThumb
= pSlider
->vadjustment_get_value();
70 bool bDoScroll
= false;
71 bool bChangeFocus
= false;
80 bDoScroll
= ( nThumb
+3 < static_cast<tools::Long
>(nArgs
) );
101 bDoScroll
= ( nThumb
>= 0 );
118 pSlider
->vadjustment_set_value( nThumb
);
119 pParaWin
->SliderMoved();
121 else if ( bChangeFocus
)
128 return RefEdit::KeyInput(rKEvt
);
139 void ArgInput::InitArgInput(weld::Label
* pftArg
, weld::Button
* pbtnFx
,
140 ArgEdit
* pedArg
, RefButton
* prefBtn
)
149 pBtnFx
->connect_clicked( LINK( this, ArgInput
, FxBtnClickHdl
) );
150 pBtnFx
->connect_focus_in( LINK( this, ArgInput
, FxBtnFocusHdl
) );
154 pEdArg
->SetGetFocusHdl ( LINK( this, ArgInput
, EdFocusHdl
) );
155 pEdArg
->SetModifyHdl ( LINK( this, ArgInput
, EdModifyHdl
) );
159 // Sets the Name for the Argument
160 void ArgInput::SetArgName(const OUString
&aArg
)
163 pFtArg
->set_label(aArg
);
166 // Returns the Name for the Argument
167 OUString
ArgInput::GetArgName() const
169 OUString aPrivArgName
;
171 aPrivArgName
= pFtArg
->get_label();
175 //Sets the Name for the Argument
176 void ArgInput::SetArgNameFont(const vcl::Font
&aFont
)
179 pFtArg
->set_font(aFont
);
182 //Sets up the Selection for the EditBox.
183 void ArgInput::SelectAll()
189 //Sets the Value for the Argument
190 void ArgInput::SetArgVal(const OUString
&rVal
)
193 pEdArg
->SetRefString(rVal
);
196 //Returns the Value for the Argument
197 OUString
ArgInput::GetArgVal() const
201 aResult
=pEdArg
->GetText();
206 void ArgInput::Hide()
208 if (pFtArg
&& pBtnFx
&& pEdArg
&& pRefBtn
)
212 pEdArg
->GetWidget()->hide();
213 pRefBtn
->GetWidget()->hide();
217 //Casts the Controls again.
218 void ArgInput::Show()
220 if (pFtArg
&& pBtnFx
&& pEdArg
&& pRefBtn
)
224 pEdArg
->GetWidget()->show();
225 pRefBtn
->GetWidget()->show();
229 void ArgInput::UpdateAccessibleNames()
231 OUString aArgName
= ":" + pFtArg
->get_label();
233 OUString aName
= pBtnFx
->get_tooltip_text() + aArgName
;
234 pBtnFx
->set_accessible_name(aName
);
236 aName
= pRefBtn
->GetWidget()->get_tooltip_text() + aArgName
;
237 pRefBtn
->GetWidget()->set_accessible_name(aName
);
240 IMPL_LINK(ArgInput
, FxBtnClickHdl
, weld::Button
&, rBtn
, void)
243 aFxClickLink
.Call(*this);
246 IMPL_LINK( ArgInput
, FxBtnFocusHdl
, weld::Widget
&, rControl
, void )
248 if (&rControl
== pBtnFx
)
249 aFxFocusLink
.Call(*this);
252 IMPL_LINK( ArgInput
, EdFocusHdl
, RefEdit
&, rControl
, void )
254 if (&rControl
== pEdArg
)
255 aEdFocusLink
.Call(*this);
258 IMPL_LINK( ArgInput
, EdModifyHdl
, RefEdit
&, rEdit
, void )
260 if (&rEdit
== pEdArg
)
261 aEdModifyLink
.Call(*this);
264 RefEdit::RefEdit(std::unique_ptr
<weld::Entry
> xControl
)
265 : xEntry(std::move(xControl
))
266 , aIdle("formula RefEdit Idle")
267 , pAnyRefDlg(nullptr)
268 , pLabelWidget(nullptr)
269 , mpFocusInEvent(nullptr)
270 , mpFocusOutEvent(nullptr)
272 xEntry
->connect_focus_in(LINK(this, RefEdit
, GetFocusHdl
));
273 xEntry
->connect_focus_out(LINK(this, RefEdit
, LoseFocusHdl
));
274 xEntry
->connect_key_press(LINK(this, RefEdit
, KeyInputHdl
));
275 xEntry
->connect_changed(LINK(this, RefEdit
, Modify
));
276 aIdle
.SetInvokeHandler( LINK( this, RefEdit
, UpdateHdl
) );
282 Application::RemoveUserEvent(mpFocusInEvent
);
284 Application::RemoveUserEvent(mpFocusOutEvent
);
285 aIdle
.ClearInvokeHandler();
289 void RefEdit::SetRefString( const OUString
& rStr
)
291 // Prevent unwanted side effects by setting only a differing string.
292 // See commit message for reasons.
293 if (xEntry
->get_text() != rStr
)
294 xEntry
->set_text(rStr
);
297 void RefEdit::SetRefValid(bool bValid
)
299 xEntry
->set_message_type(bValid
? weld::EntryMessageType::Normal
: weld::EntryMessageType::Error
);
302 void RefEdit::SetText(const OUString
& rStr
)
304 xEntry
->set_text(rStr
);
308 void RefEdit::StartUpdateData()
313 void RefEdit::SetReferences(IControlReferenceHandler
* pDlg
, weld::Label
* pLabel
)
316 pLabelWidget
= pLabel
;
320 aIdle
.SetInvokeHandler(LINK(this, RefEdit
, UpdateHdl
));
324 aIdle
.ClearInvokeHandler();
329 IMPL_LINK_NOARG(RefEdit
, Modify
, weld::Entry
&, void)
331 maModifyHdl
.Call(*this);
333 pAnyRefDlg
->HideReference();
336 IMPL_LINK(RefEdit
, KeyInputHdl
, const KeyEvent
&, rKEvt
, bool)
338 return KeyInput(rKEvt
);
341 bool RefEdit::KeyInput(const KeyEvent
& rKEvt
)
343 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
344 if (pAnyRefDlg
&& !rKeyCode
.GetModifier() && rKeyCode
.GetCode() == KEY_F2
)
346 pAnyRefDlg
->ReleaseFocus( this );
350 switch (rKeyCode
.GetCode())
354 return maActivateHdl
.Call(*GetWidget());
360 void RefEdit::GetFocus()
362 maGetFocusHdl
.Call(*this);
366 void RefEdit::LoseFocus()
368 maLoseFocusHdl
.Call(*this);
370 pAnyRefDlg
->HideReference();
373 IMPL_LINK_NOARG(RefEdit
, GetFocusHdl
, weld::Widget
&, void)
375 // in e.g. function wizard RefEdits we want to select all when we get focus
376 // but in the gtk case there are pending gtk handlers which change selection
377 // after our handler, so post our focus in event to happen after those complete
379 Application::RemoveUserEvent(mpFocusInEvent
);
380 mpFocusInEvent
= Application::PostUserEvent(LINK(this, RefEdit
, AsyncFocusInHdl
));
383 IMPL_LINK_NOARG(RefEdit
, LoseFocusHdl
, weld::Widget
&, void)
385 // tdf#127262 because focus in is async, focus out must not appear out
386 // of sequence to focus in
388 Application::RemoveUserEvent(mpFocusOutEvent
);
389 mpFocusOutEvent
= Application::PostUserEvent(LINK(this, RefEdit
, AsyncFocusOutHdl
));
392 IMPL_LINK_NOARG(RefEdit
, AsyncFocusInHdl
, void*, void)
394 mpFocusInEvent
= nullptr;
398 IMPL_LINK_NOARG(RefEdit
, AsyncFocusOutHdl
, void*, void)
400 mpFocusOutEvent
= nullptr;
404 IMPL_LINK_NOARG(RefEdit
, UpdateHdl
, Timer
*, void)
407 pAnyRefDlg
->ShowReference(xEntry
->get_text());
410 RefButton::RefButton(std::unique_ptr
<weld::Button
> xControl
)
411 : xButton(std::move(xControl
))
412 , pAnyRefDlg( nullptr )
413 , pRefEdit( nullptr )
415 xButton
->connect_focus_in(LINK(this, RefButton
, GetFocus
));
416 xButton
->connect_focus_out(LINK(this, RefButton
, LoseFocus
));
417 xButton
->connect_key_press(LINK(this, RefButton
, KeyInput
));
418 xButton
->connect_clicked(LINK(this, RefButton
, Click
));
422 RefButton::~RefButton()
426 void RefButton::SetStartImage()
428 xButton
->set_from_icon_name(RID_BMP_REFBTN1
);
429 xButton
->set_tooltip_text(ForResId(RID_STR_SHRINK
));
432 void RefButton::SetEndImage()
434 xButton
->set_from_icon_name(RID_BMP_REFBTN2
);
435 xButton
->set_tooltip_text(ForResId(RID_STR_EXPAND
));
438 void RefButton::SetReferences( IControlReferenceHandler
* pDlg
, RefEdit
* pEdit
)
444 IMPL_LINK_NOARG(RefButton
, Click
, weld::Button
&, void)
446 maClickHdl
.Call(*this);
448 pAnyRefDlg
->ToggleCollapsed( pRefEdit
, this );
451 IMPL_LINK(RefButton
, KeyInput
, const KeyEvent
&, rKEvt
, bool)
453 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
454 if (pAnyRefDlg
&& !rKeyCode
.GetModifier() && rKeyCode
.GetCode() == KEY_F2
)
456 pAnyRefDlg
->ReleaseFocus( pRefEdit
);
460 switch (rKeyCode
.GetCode())
464 return maActivateHdl
.Call(*GetWidget());
470 IMPL_LINK_NOARG(RefButton
, GetFocus
, weld::Widget
&, void)
472 maGetFocusHdl
.Call(*this);
474 pRefEdit
->StartUpdateData();
477 IMPL_LINK_NOARG(RefButton
, LoseFocus
, weld::Widget
&, void)
479 maLoseFocusHdl
.Call(*this);
481 pRefEdit
->DoModify();
486 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */