LibreOffice Module formula (master) 1
funcutl.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <vcl/event.hxx>
21
22#include <formula/funcutl.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>
30
31namespace formula
32{
33
34ArgEdit::ArgEdit(std::unique_ptr<weld::Entry> xControl)
35 : RefEdit(std::move(xControl))
36 , pEdPrev(nullptr)
37 , pEdNext(nullptr)
38 , pSlider(nullptr)
39 , pParaWin(nullptr)
40 , nArgs(0)
41{
42}
43
44void ArgEdit::Init(ArgEdit* pPrevEdit, ArgEdit* pNextEdit,
45 weld::ScrolledWindow& rArgSlider,
46 ParaWin& rParaWin, sal_uInt16 nArgCount)
47{
48 pEdPrev = pPrevEdit;
49 pEdNext = pNextEdit;
50 pSlider = &rArgSlider;
51 pParaWin = &rParaWin;
52 nArgs = nArgCount;
53}
54
55// Cursor control for Edit Fields in Argument Dialog
56bool ArgEdit::KeyInput(const KeyEvent& rKEvt)
57{
58 vcl::KeyCode aCode = rKEvt.GetKeyCode();
59 bool bUp = (aCode.GetCode() == KEY_UP);
60 bool bDown = (aCode.GetCode() == KEY_DOWN);
61
62 if ( pSlider
63 && ( !aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() )
64 && ( bUp || bDown ) )
65 {
66 if ( nArgs > 1 )
67 {
68 ArgEdit* pEd = nullptr;
69 int nThumb = pSlider->vadjustment_get_value();
70 bool bDoScroll = false;
71 bool bChangeFocus = false;
72
73 if ( bDown )
74 {
75 if ( nArgs > 4 )
76 {
77 if ( !pEdNext )
78 {
79 nThumb++;
80 bDoScroll = ( nThumb+3 < static_cast<tools::Long>(nArgs) );
81 }
82 else
83 {
84 pEd = pEdNext;
85 bChangeFocus = true;
86 }
87 }
88 else if ( pEdNext )
89 {
90 pEd = pEdNext;
91 bChangeFocus = true;
92 }
93 }
94 else // if ( bUp )
95 {
96 if ( nArgs > 4 )
97 {
98 if ( !pEdPrev )
99 {
100 nThumb--;
101 bDoScroll = ( nThumb >= 0 );
102 }
103 else
104 {
105 pEd = pEdPrev;
106 bChangeFocus = true;
107 }
108 }
109 else if ( pEdPrev )
110 {
111 pEd = pEdPrev;
112 bChangeFocus = true;
113 }
114 }
115
116 if ( bDoScroll )
117 {
120 }
121 else if ( bChangeFocus )
122 {
123 pEd->GrabFocus();
124 }
125 }
126 return true;
127 }
128 return RefEdit::KeyInput(rKEvt);
129}
130
132{
133 pFtArg=nullptr;
134 pBtnFx=nullptr;
135 pEdArg=nullptr;
136 pRefBtn=nullptr;
137}
138
140 ArgEdit* pedArg, RefButton* prefBtn)
141{
142 pFtArg =pftArg;
143 pBtnFx =pbtnFx;
144 pEdArg =pedArg;
145 pRefBtn=prefBtn;
146
147 if(pBtnFx!=nullptr)
148 {
149 pBtnFx->connect_clicked( LINK( this, ArgInput, FxBtnClickHdl ) );
150 pBtnFx->connect_focus_in( LINK( this, ArgInput, FxBtnFocusHdl ) );
151 }
152 if(pEdArg!=nullptr)
153 {
154 pEdArg->SetGetFocusHdl ( LINK( this, ArgInput, EdFocusHdl ) );
155 pEdArg->SetModifyHdl ( LINK( this, ArgInput, EdModifyHdl ) );
156 }
157}
158
159// Sets the Name for the Argument
160void ArgInput::SetArgName(const OUString &aArg)
161{
162 if (pFtArg)
163 pFtArg->set_label(aArg );
164}
165
166// Returns the Name for the Argument
167OUString ArgInput::GetArgName() const
168{
169 OUString aPrivArgName;
170 if (pFtArg)
171 aPrivArgName = pFtArg->get_label();
172 return aPrivArgName;
173}
174
175//Sets the Name for the Argument
177{
178 if (pFtArg)
179 pFtArg->set_font(aFont);
180}
181
182//Sets up the Selection for the EditBox.
184{
185 if (pEdArg)
186 pEdArg->SelectAll();
187}
188
189//Sets the Value for the Argument
190void ArgInput::SetArgVal(const OUString &rVal)
191{
192 if (pEdArg)
193 pEdArg->SetRefString(rVal);
194}
195
196//Returns the Value for the Argument
197OUString ArgInput::GetArgVal() const
198{
199 OUString aResult;
200 if (pEdArg)
201 aResult=pEdArg->GetText();
202 return aResult;
203}
204
205//Hides the Controls
207{
208 if (pFtArg && pBtnFx && pEdArg && pRefBtn)
209 {
210 pFtArg->hide();
211 pBtnFx->hide();
212 pEdArg->GetWidget()->hide();
213 pRefBtn->GetWidget()->hide();
214 }
215}
216
217//Casts the Controls again.
219{
220 if (pFtArg && pBtnFx && pEdArg && pRefBtn)
221 {
222 pFtArg->show();
223 pBtnFx->show();
224 pEdArg->GetWidget()->show();
225 pRefBtn->GetWidget()->show();
226 }
227}
228
230{
231 OUString aArgName = ":" + pFtArg->get_label();
232
233 OUString aName = pBtnFx->get_tooltip_text() + aArgName;
235
236 aName = pRefBtn->GetWidget()->get_tooltip_text() + aArgName;
238}
239
240IMPL_LINK(ArgInput, FxBtnClickHdl, weld::Button&, rBtn, void)
241{
242 if (&rBtn == pBtnFx)
243 aFxClickLink.Call(*this);
244}
245
246IMPL_LINK( ArgInput, FxBtnFocusHdl, weld::Widget&, rControl, void )
247{
248 if (&rControl == pBtnFx)
249 aFxFocusLink.Call(*this);
250}
251
252IMPL_LINK( ArgInput, EdFocusHdl, RefEdit&, rControl, void )
253{
254 if (&rControl == pEdArg)
255 aEdFocusLink.Call(*this);
256}
257
258IMPL_LINK( ArgInput, EdModifyHdl, RefEdit&, rEdit, void )
259{
260 if (&rEdit == pEdArg)
261 aEdModifyLink.Call(*this);
262}
263
264RefEdit::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)
271{
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 ) );
277}
278
280{
281 if (mpFocusInEvent)
283 if (mpFocusOutEvent)
286 aIdle.Stop();
287}
288
289void RefEdit::SetRefString( const OUString& rStr )
290{
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);
295}
296
297void RefEdit::SetRefValid(bool bValid)
298{
300}
301
302void RefEdit::SetText(const OUString& rStr)
303{
304 xEntry->set_text(rStr);
305 UpdateHdl( &aIdle );
306}
307
309{
310 aIdle.Start();
311}
312
314{
315 pAnyRefDlg = pDlg;
316 pLabelWidget = pLabel;
317
318 if( pDlg )
319 {
320 aIdle.SetInvokeHandler(LINK(this, RefEdit, UpdateHdl));
321 }
322 else
323 {
325 aIdle.Stop();
326 }
327}
328
330{
331 maModifyHdl.Call(*this);
332 if (pAnyRefDlg)
333 pAnyRefDlg->HideReference();
334}
335
336IMPL_LINK(RefEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool)
337{
338 return KeyInput(rKEvt);
339}
340
341bool RefEdit::KeyInput(const KeyEvent& rKEvt)
342{
343 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
344 if (pAnyRefDlg && !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_F2)
345 {
346 pAnyRefDlg->ReleaseFocus( this );
347 return true;
348 }
349
350 switch (rKeyCode.GetCode())
351 {
352 case KEY_RETURN:
353 case KEY_ESCAPE:
354 return maActivateHdl.Call(*GetWidget());
355 }
356
357 return false;
358}
359
361{
362 maGetFocusHdl.Call(*this);
364}
365
367{
368 maLoseFocusHdl.Call(*this);
369 if( pAnyRefDlg )
371}
372
374{
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
378 if (mpFocusInEvent)
379 Application::RemoveUserEvent(mpFocusInEvent);
380 mpFocusInEvent = Application::PostUserEvent(LINK(this, RefEdit, AsyncFocusInHdl));
381}
382
384{
385 // tdf#127262 because focus in is async, focus out must not appear out
386 // of sequence to focus in
387 if (mpFocusOutEvent)
388 Application::RemoveUserEvent(mpFocusOutEvent);
389 mpFocusOutEvent = Application::PostUserEvent(LINK(this, RefEdit, AsyncFocusOutHdl));
390}
391
392IMPL_LINK_NOARG(RefEdit, AsyncFocusInHdl, void*, void)
393{
394 mpFocusInEvent = nullptr;
395 GetFocus();
396}
397
398IMPL_LINK_NOARG(RefEdit, AsyncFocusOutHdl, void*, void)
399{
400 mpFocusOutEvent = nullptr;
401 LoseFocus();
402}
403
404IMPL_LINK_NOARG(RefEdit, UpdateHdl, Timer *, void)
405{
406 if( pAnyRefDlg )
407 pAnyRefDlg->ShowReference(xEntry->get_text());
408}
409
410RefButton::RefButton(std::unique_ptr<weld::Button> xControl)
411 : xButton(std::move(xControl))
412 , pAnyRefDlg( nullptr )
413 , pRefEdit( nullptr )
414{
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));
420}
421
423{
424}
425
427{
428 xButton->set_from_icon_name(RID_BMP_REFBTN1);
429 xButton->set_tooltip_text(ForResId(RID_STR_SHRINK));
430}
431
433{
434 xButton->set_from_icon_name(RID_BMP_REFBTN2);
435 xButton->set_tooltip_text(ForResId(RID_STR_EXPAND));
436}
437
439{
440 pAnyRefDlg = pDlg;
441 pRefEdit = pEdit;
442}
443
445{
446 maClickHdl.Call(*this);
447 if( pAnyRefDlg )
448 pAnyRefDlg->ToggleCollapsed( pRefEdit, this );
449}
450
451IMPL_LINK(RefButton, KeyInput, const KeyEvent&, rKEvt, bool)
452{
453 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
454 if (pAnyRefDlg && !rKeyCode.GetModifier() && rKeyCode.GetCode() == KEY_F2)
455 {
456 pAnyRefDlg->ReleaseFocus( pRefEdit );
457 return true;
458 }
459
460 switch (rKeyCode.GetCode())
461 {
462 case KEY_RETURN:
463 case KEY_ESCAPE:
464 return maActivateHdl.Call(*GetWidget());
465 }
466
467 return false;
468}
469
471{
472 maGetFocusHdl.Call(*this);
473 if (pRefEdit)
474 pRefEdit->StartUpdateData();
475}
476
478{
479 maLoseFocusHdl.Call(*this);
480 if (pRefEdit)
481 pRefEdit->DoModify();
482}
483
484} // formula
485
486/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
virtual void Start(bool bStartTimer=true) override
const vcl::KeyCode & GetKeyCode() const
void Stop()
void SetInvokeHandler(const Link< Timer *, void > &rLink)
void ClearInvokeHandler()
ArgEdit(std::unique_ptr< weld::Entry > xControl)
Definition: funcutl.cxx:34
virtual bool KeyInput(const KeyEvent &rKEvt) override
Definition: funcutl.cxx:56
void Init(ArgEdit *pPrevEdit, ArgEdit *pNextEdit, weld::ScrolledWindow &rArgSlider, ParaWin &rParaWin, sal_uInt16 nArgCount)
Definition: funcutl.cxx:44
weld::ScrolledWindow * pSlider
void SetArgNameFont(const vcl::Font &)
Definition: funcutl.cxx:176
OUString GetArgName() const
Definition: funcutl.cxx:167
void UpdateAccessibleNames()
Definition: funcutl.cxx:229
OUString GetArgVal() const
Definition: funcutl.cxx:197
void InitArgInput(weld::Label *pftArg, weld::Button *pbtnFx, ArgEdit *pedArg, RefButton *prefBtn)
Definition: funcutl.cxx:139
void SetArgName(const OUString &aArg)
Definition: funcutl.cxx:160
weld::Label * pFtArg
RefButton * pRefBtn
void SetArgVal(const OUString &aVal)
Definition: funcutl.cxx:190
weld::Button * pBtnFx
virtual void HideReference(bool bDoneRefMode=true)=0
virtual void ReleaseFocus(RefEdit *pEdit)=0
void SliderMoved()
Definition: parawin.cxx:471
void SetStartImage()
Definition: funcutl.cxx:426
std::unique_ptr< weld::Button > xButton
Definition: funcutl.hxx:148
void SetReferences(IControlReferenceHandler *pDlg, RefEdit *pEdit)
Definition: funcutl.cxx:438
RefEdit * pRefEdit
Definition: funcutl.hxx:150
RefButton(std::unique_ptr< weld::Button > xControl)
Definition: funcutl.cxx:410
IControlReferenceHandler * pAnyRefDlg
Definition: funcutl.hxx:149
weld::Button * GetWidget() const
Definition: funcutl.hxx:163
ImplSVEvent * mpFocusInEvent
Definition: funcutl.hxx:45
void SelectAll()
Definition: funcutl.hxx:101
Link< RefEdit &, void > maLoseFocusHdl
Definition: funcutl.hxx:49
ImplSVEvent * mpFocusOutEvent
Definition: funcutl.hxx:46
void GrabFocus()
Definition: funcutl.hxx:96
Link< RefEdit &, void > maGetFocusHdl
Definition: funcutl.hxx:48
void SetRefValid(bool bValid)
Flag reference valid or invalid, which in turn changes the visual appearance of the control according...
Definition: funcutl.cxx:297
weld::Label * pLabelWidget
Definition: funcutl.hxx:44
weld::Entry * GetWidget() const
Definition: funcutl.hxx:70
Link< weld::Widget &, bool > maActivateHdl
Definition: funcutl.hxx:51
void SetModifyHdl(const Link< RefEdit &, void > &rLink)
Definition: funcutl.hxx:140
std::unique_ptr< weld::Entry > xEntry
Definition: funcutl.hxx:39
RefEdit(std::unique_ptr< weld::Entry > xControl)
Definition: funcutl.cxx:264
void SetText(const OUString &rStr)
Definition: funcutl.cxx:302
void SetReferences(IControlReferenceHandler *pDlg, weld::Label *pLabelWidget)
Definition: funcutl.cxx:313
void StartUpdateData()
Definition: funcutl.cxx:308
void LoseFocus()
Definition: funcutl.cxx:366
void SetRefString(const OUString &rStr)
Definition: funcutl.cxx:289
void SetGetFocusHdl(const Link< RefEdit &, void > &rLink)
Definition: funcutl.hxx:138
virtual bool KeyInput(const KeyEvent &rKEvt)
Definition: funcutl.cxx:341
virtual ~RefEdit()
Definition: funcutl.cxx:279
IControlReferenceHandler * pAnyRefDlg
Definition: funcutl.hxx:43
OUString GetText() const
Definition: funcutl.hxx:82
bool IsMod1() const
sal_uInt16 GetCode() const
sal_uInt16 GetModifier() const
bool IsShift() const
bool IsMod2() const
void connect_clicked(const Link< Button &, void > &rLink)
virtual void set_font(const vcl::Font &rFont)=0
virtual void set_label(const OUString &rText)=0
virtual OUString get_label() const=0
virtual void vadjustment_set_value(int value)=0
virtual int vadjustment_get_value() const=0
virtual void show()=0
virtual void hide()=0
virtual void set_accessible_name(const OUString &rName)=0
virtual OUString get_tooltip_text() const=0
virtual void connect_focus_in(const Link< Widget &, void > &rLink)
Link< ColorFieldControl &, void > maModifyHdl
OUString ForResId(TranslateId aId)
OUString aName
constexpr sal_uInt16 KEY_RETURN
constexpr sal_uInt16 KEY_F2
constexpr sal_uInt16 KEY_ESCAPE
constexpr sal_uInt16 KEY_UP
constexpr sal_uInt16 KEY_DOWN
IMPL_LINK_NOARG(FormulaDlg_Impl, DblClkHdl, FuncPage &, void)
Definition: formula.cxx:1065
IMPL_LINK(FormulaDlg_Impl, BtnHdl, weld::Button &, rBtn, void)
Definition: formula.cxx:1022
long Long