Line data Source code
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/builder.hxx>
21 : #include <vcl/svapp.hxx>
22 : #include <vcl/scrbar.hxx>
23 : #include <vcl/builderfactory.hxx>
24 :
25 : #include "formula/funcutl.hxx"
26 : #include "formula/IControlReferenceHandler.hxx"
27 : #include "ControlHelper.hxx"
28 : #include "ModuleHelper.hxx"
29 : #include "ForResId.hrc"
30 : #include "com/sun/star/accessibility/AccessibleRole.hpp"
31 :
32 :
33 : namespace formula
34 : {
35 :
36 : // class ArgEdit
37 0 : ArgEdit::ArgEdit( vcl::Window* pParent, WinBits nBits )
38 : : RefEdit( pParent, NULL, nBits ),
39 : pEdPrev ( NULL ),
40 : pEdNext ( NULL ),
41 : pSlider ( NULL ),
42 0 : nArgs ( 0 )
43 : {
44 0 : }
45 :
46 0 : ArgEdit::~ArgEdit()
47 : {
48 0 : disposeOnce();
49 0 : }
50 :
51 0 : void ArgEdit::dispose()
52 : {
53 0 : pEdPrev.clear();
54 0 : pEdNext.clear();
55 0 : pSlider.clear();
56 0 : RefEdit::dispose();
57 0 : }
58 :
59 0 : VCL_BUILDER_FACTORY_ARGS(ArgEdit, WB_BORDER)
60 :
61 0 : void ArgEdit::Init( ArgEdit* pPrevEdit, ArgEdit* pNextEdit,
62 : ScrollBar& rArgSlider, sal_uInt16 nArgCount )
63 : {
64 0 : pEdPrev = pPrevEdit;
65 0 : pEdNext = pNextEdit;
66 0 : pSlider = &rArgSlider;
67 0 : nArgs = nArgCount;
68 0 : }
69 :
70 : // Cursor control for Edit Fields in Argument Dialog
71 0 : void ArgEdit::KeyInput( const KeyEvent& rKEvt )
72 : {
73 0 : vcl::KeyCode aCode = rKEvt.GetKeyCode();
74 0 : bool bUp = (aCode.GetCode() == KEY_UP);
75 0 : bool bDown = (aCode.GetCode() == KEY_DOWN);
76 :
77 0 : if ( pSlider
78 0 : && ( !aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() )
79 0 : && ( bUp || bDown ) )
80 : {
81 0 : if ( nArgs > 1 )
82 : {
83 0 : ArgEdit* pEd = NULL;
84 0 : long nThumb = pSlider->GetThumbPos();
85 0 : bool bDoScroll = false;
86 0 : bool bChangeFocus = false;
87 :
88 0 : if ( bDown )
89 : {
90 0 : if ( nArgs > 4 )
91 : {
92 0 : if ( !pEdNext )
93 : {
94 0 : nThumb++;
95 0 : bDoScroll = ( nThumb+3 < (long)nArgs );
96 : }
97 : else
98 : {
99 0 : pEd = pEdNext;
100 0 : bChangeFocus = true;
101 : }
102 : }
103 0 : else if ( pEdNext )
104 : {
105 0 : pEd = pEdNext;
106 0 : bChangeFocus = true;
107 : }
108 : }
109 : else // if ( bUp )
110 : {
111 0 : if ( nArgs > 4 )
112 : {
113 0 : if ( !pEdPrev )
114 : {
115 0 : nThumb--;
116 0 : bDoScroll = ( nThumb >= 0 );
117 : }
118 : else
119 : {
120 0 : pEd = pEdPrev;
121 0 : bChangeFocus = true;
122 : }
123 : }
124 0 : else if ( pEdPrev )
125 : {
126 0 : pEd = pEdPrev;
127 0 : bChangeFocus = true;
128 : }
129 : }
130 :
131 0 : if ( bDoScroll )
132 : {
133 0 : pSlider->SetThumbPos( nThumb );
134 0 : ((Link<>&)pSlider->GetEndScrollHdl()).Call( pSlider );
135 : }
136 0 : else if ( bChangeFocus )
137 : {
138 0 : pEd->GrabFocus();
139 : }
140 : }
141 : }
142 : else
143 0 : RefEdit::KeyInput( rKEvt );
144 0 : }
145 :
146 : // class ArgInput
147 0 : ArgInput::ArgInput()
148 : {
149 0 : pFtArg=NULL;
150 0 : pBtnFx=NULL;
151 0 : pEdArg=NULL;
152 0 : pRefBtn=NULL;
153 0 : }
154 :
155 0 : void ArgInput::InitArgInput( FixedText* pftArg, PushButton* pbtnFx,
156 : ArgEdit* pedArg, RefButton* prefBtn)
157 : {
158 0 : pFtArg =pftArg;
159 0 : pBtnFx =pbtnFx;
160 0 : pEdArg =pedArg;
161 0 : pRefBtn=prefBtn;
162 :
163 0 : if(pBtnFx!=nullptr)
164 : {
165 0 : pBtnFx->SetClickHdl ( LINK( this, ArgInput, FxBtnClickHdl ) );
166 0 : pBtnFx->SetGetFocusHdl( LINK( this, ArgInput, FxBtnFocusHdl ) );
167 : }
168 0 : if(pRefBtn!=nullptr)
169 : {
170 0 : pRefBtn->SetClickHdl ( LINK( this, ArgInput, RefBtnClickHdl ) );
171 0 : pRefBtn->SetGetFocusHdl( LINK( this, ArgInput, RefBtnFocusHdl ) );
172 : }
173 0 : if(pEdArg!=nullptr)
174 : {
175 0 : pEdArg->SetGetFocusHdl ( LINK( this, ArgInput, EdFocusHdl ) );
176 0 : pEdArg->SetModifyHdl ( LINK( this, ArgInput, EdModifyHdl ) );
177 : }
178 :
179 0 : }
180 :
181 : // Sets the Name for the Argument
182 0 : void ArgInput::SetArgName(const OUString &aArg)
183 : {
184 0 : if(pFtArg !=nullptr) pFtArg->SetText(aArg );
185 0 : }
186 :
187 : // Returns the Name for the Argument
188 0 : OUString ArgInput::GetArgName()
189 : {
190 0 : OUString aPrivArgName;
191 0 : if(pFtArg !=nullptr)
192 0 : aPrivArgName=pFtArg->GetText();
193 :
194 0 : return aPrivArgName;
195 : }
196 :
197 : //Sets the Name for the Argument
198 0 : void ArgInput::SetArgNameFont (const vcl::Font &aFont)
199 : {
200 0 : if(pFtArg !=nullptr) pFtArg->SetFont(aFont);
201 0 : }
202 :
203 : //Sets up the Selection for the EditBox.
204 0 : void ArgInput::SetArgSelection (const Selection& rSel )
205 : {
206 0 : if(pEdArg !=nullptr) pEdArg ->SetSelection(rSel );
207 0 : }
208 :
209 : //Sets the Value for the Argument
210 0 : void ArgInput::SetArgVal(const OUString &rVal)
211 : {
212 0 : if(pEdArg != nullptr)
213 : {
214 0 : pEdArg ->SetRefString(rVal);
215 : }
216 0 : }
217 :
218 : //Returns the Value for the Argument
219 0 : OUString ArgInput::GetArgVal()
220 : {
221 0 : OUString aResult;
222 0 : if(pEdArg!=nullptr)
223 : {
224 0 : aResult=pEdArg->GetText();
225 : }
226 0 : return aResult;
227 : }
228 :
229 : //Hides the Controls
230 0 : void ArgInput::Hide()
231 : {
232 0 : if ( pFtArg && pBtnFx && pEdArg && pRefBtn)
233 : {
234 0 : pFtArg->Hide();
235 0 : pBtnFx->Hide();
236 0 : pEdArg->Hide();
237 0 : pRefBtn->Hide();
238 : }
239 0 : }
240 :
241 : //Casts the Controls again.
242 0 : void ArgInput::Show()
243 : {
244 0 : if ( pFtArg && pBtnFx && pEdArg && pRefBtn)
245 : {
246 0 : pFtArg->Show();
247 0 : pBtnFx->Show();
248 0 : pEdArg->Show();
249 0 : pRefBtn->Show();
250 : }
251 0 : }
252 :
253 0 : void ArgInput::UpdateAccessibleNames()
254 : {
255 0 : OUString aArgName(":");
256 0 : aArgName += pFtArg->GetText();
257 :
258 0 : OUString aName = pBtnFx->GetQuickHelpText();
259 0 : aName += aArgName;
260 0 : pBtnFx->SetAccessibleName(aName);
261 :
262 0 : aName = pRefBtn->GetQuickHelpText();
263 0 : aName += aArgName;
264 0 : pRefBtn->SetAccessibleName(aName);
265 0 : }
266 :
267 0 : void ArgInput::FxClick()
268 : {
269 0 : aFxClickLink.Call(this);
270 0 : }
271 :
272 0 : void ArgInput::RefClick()
273 : {
274 0 : aRefClickLink.Call(this);
275 0 : }
276 :
277 0 : void ArgInput::FxFocus()
278 : {
279 0 : aFxFocusLink.Call(this);
280 0 : }
281 :
282 0 : void ArgInput::RefFocus()
283 : {
284 0 : aRefFocusLink.Call(this);
285 0 : }
286 :
287 0 : void ArgInput::EdFocus()
288 : {
289 0 : aEdFocusLink.Call(this);
290 0 : }
291 :
292 0 : void ArgInput::EdModify()
293 : {
294 0 : aEdModifyLink.Call(this);
295 0 : }
296 :
297 0 : IMPL_LINK( ArgInput, FxBtnClickHdl, ImageButton*, pBtn )
298 : {
299 0 : if(pBtn == pBtnFx)
300 0 : FxClick();
301 :
302 0 : return 0;
303 : }
304 :
305 0 : IMPL_LINK( ArgInput, RefBtnClickHdl,RefButton*, pBtn )
306 : {
307 0 : if(pRefBtn == pBtn)
308 0 : RefClick();
309 :
310 0 : return 0;
311 : }
312 :
313 0 : IMPL_LINK( ArgInput, FxBtnFocusHdl, ImageButton*, pBtn )
314 : {
315 0 : if(pBtn == pBtnFx)
316 0 : FxFocus();
317 :
318 0 : return 0;
319 : }
320 :
321 0 : IMPL_LINK( ArgInput, RefBtnFocusHdl,RefButton*, pBtn )
322 : {
323 0 : if(pRefBtn == pBtn)
324 0 : RefFocus();
325 :
326 0 : return 0;
327 : }
328 :
329 0 : IMPL_LINK( ArgInput, EdFocusHdl, ArgEdit*, pEd )
330 : {
331 0 : if(pEd == pEdArg)
332 0 : EdFocus();
333 :
334 0 : return 0;
335 : }
336 :
337 0 : IMPL_LINK( ArgInput, EdModifyHdl,ArgEdit*, pEd )
338 : {
339 0 : if(pEd == pEdArg)
340 0 : EdModify();
341 :
342 0 : return 0;
343 : }
344 :
345 : // class EditBox
346 :
347 0 : EditBox::EditBox( vcl::Window* pParent, WinBits nBits )
348 : :Control(pParent,nBits),
349 0 : bMouseFlag(false)
350 : {
351 0 : WinBits nStyle=GetStyle();
352 0 : SetStyle( nStyle| WB_DIALOGCONTROL);
353 :
354 0 : pMEdit=VclPtr<MultiLineEdit>::Create(this,WB_LEFT | WB_VSCROLL | (nStyle & WB_TABSTOP) |
355 0 : WB_NOBORDER | WB_NOHIDESELECTION | WB_IGNORETAB);
356 0 : pMEdit->Show();
357 0 : aOldSel=pMEdit->GetSelection();
358 0 : Resize();
359 0 : WinBits nWinStyle=GetStyle() | WB_DIALOGCONTROL;
360 0 : SetStyle(nWinStyle);
361 :
362 : // #105582# the HelpId from the resource must be set for the MultiLineEdit,
363 : // not for the control that contains it.
364 0 : pMEdit->SetHelpId( GetHelpId() );
365 0 : SetHelpId( "" );
366 0 : }
367 :
368 0 : VCL_BUILDER_FACTORY_ARGS(EditBox, WB_BORDER)
369 :
370 0 : EditBox::~EditBox()
371 : {
372 0 : disposeOnce();
373 0 : }
374 :
375 0 : void EditBox::dispose()
376 : {
377 0 : pMEdit->Disable();
378 0 : pMEdit.disposeAndClear();
379 0 : Control::dispose();
380 0 : }
381 :
382 : // When the selection is changed this function will be called
383 0 : void EditBox::SelectionChanged()
384 : {
385 0 : aSelChangedLink.Call(this);
386 0 : }
387 :
388 : // When the size is changed, MultiLineEdit must be adapted..
389 0 : void EditBox::Resize()
390 : {
391 0 : Size aSize=GetOutputSizePixel();
392 0 : if(pMEdit!=nullptr) pMEdit->SetOutputSizePixel(aSize);
393 0 : }
394 :
395 : // When the Control is activated, the Selection is repealed
396 : // and the Cursor set at the end.
397 0 : void EditBox::GetFocus()
398 : {
399 0 : if(pMEdit!=nullptr)
400 : {
401 0 : pMEdit->GrabFocus();
402 : }
403 0 : }
404 :
405 : //When an Event is cleared, this Routine is
406 : //first called and a PostUserEvent is sent.
407 0 : bool EditBox::PreNotify( NotifyEvent& rNEvt )
408 : {
409 0 : bool nResult = true;
410 :
411 0 : if(pMEdit==nullptr) return nResult;
412 :
413 0 : MouseNotifyEvent nSwitch=rNEvt.GetType();
414 0 : if(nSwitch==MouseNotifyEvent::KEYINPUT)// || nSwitch==MouseNotifyEvent::KEYUP)
415 : {
416 0 : const vcl::KeyCode& aKeyCode=rNEvt.GetKeyEvent()->GetKeyCode();
417 0 : sal_uInt16 nKey=aKeyCode.GetCode();
418 0 : if( (nKey==KEY_RETURN && !aKeyCode.IsShift()) || nKey==KEY_TAB )
419 : {
420 0 : nResult = GetParent()->Notify(rNEvt);
421 : }
422 : else
423 : {
424 0 : nResult=Control::PreNotify(rNEvt);
425 0 : Application::PostUserEvent( LINK( this, EditBox, ChangedHdl ), NULL, true );
426 : }
427 :
428 : }
429 : else
430 : {
431 0 : nResult=Control::PreNotify(rNEvt);
432 :
433 0 : if(nSwitch==MouseNotifyEvent::MOUSEBUTTONDOWN || nSwitch==MouseNotifyEvent::MOUSEBUTTONUP)
434 : {
435 0 : bMouseFlag=true;
436 0 : Application::PostUserEvent( LINK( this, EditBox, ChangedHdl ), NULL, true );
437 : }
438 : }
439 0 : return nResult;
440 : }
441 :
442 : //When an Event cleared wurde, this routine is
443 : //first called.
444 0 : IMPL_LINK_NOARG(EditBox, ChangedHdl)
445 : {
446 0 : if(pMEdit!=nullptr)
447 : {
448 0 : Selection aNewSel=pMEdit->GetSelection();
449 :
450 0 : if(aNewSel.Min()!=aOldSel.Min() || aNewSel.Max()!=aOldSel.Max())
451 : {
452 0 : SelectionChanged();
453 0 : aOldSel=aNewSel;
454 : }
455 : }
456 0 : return 0;
457 : }
458 :
459 0 : void EditBox::UpdateOldSel()
460 : {
461 : // if selection is set for editing a function, store it as aOldSel,
462 : // so SelectionChanged isn't called in the next ChangedHdl call
463 :
464 0 : if (pMEdit)
465 0 : aOldSel = pMEdit->GetSelection();
466 0 : }
467 :
468 : // class RefEdit
469 :
470 0 : RefEdit::RefEdit( vcl::Window* _pParent, vcl::Window* pShrinkModeLabel, WinBits nStyle )
471 : : Edit( _pParent, nStyle )
472 : , pAnyRefDlg( NULL )
473 0 : , pLabelWidget(pShrinkModeLabel)
474 : {
475 0 : aIdle.SetIdleHdl( LINK( this, RefEdit, UpdateHdl ) );
476 0 : aIdle.SetPriority( SchedulerPriority::LOW );
477 0 : }
478 :
479 0 : RefEdit::RefEdit( vcl::Window* _pParent,IControlReferenceHandler* pParent,
480 : vcl::Window* pShrinkModeLabel, const ResId& rResId )
481 : : Edit( _pParent, rResId )
482 : , pAnyRefDlg( pParent )
483 0 : , pLabelWidget(pShrinkModeLabel)
484 : {
485 0 : aIdle.SetIdleHdl( LINK( this, RefEdit, UpdateHdl ) );
486 0 : aIdle.SetPriority( SchedulerPriority::LOW );
487 0 : }
488 :
489 0 : VCL_BUILDER_DECL_FACTORY(RefEdit)
490 : {
491 : (void)rMap;
492 0 : rRet = VclPtr<RefEdit>::Create(pParent, nullptr, WB_BORDER);
493 0 : }
494 :
495 0 : RefEdit::~RefEdit()
496 : {
497 0 : disposeOnce();
498 0 : }
499 :
500 0 : void RefEdit::dispose()
501 : {
502 0 : aIdle.SetIdleHdl( Link<Idle *, void>() );
503 0 : aIdle.Stop();
504 0 : pLabelWidget.clear();
505 0 : Edit::dispose();
506 0 : }
507 :
508 0 : void RefEdit::SetRefString( const OUString& rStr )
509 : {
510 0 : Edit::SetText( rStr );
511 0 : }
512 :
513 0 : void RefEdit::SetRefValid(bool bValid)
514 : {
515 0 : if (bValid)
516 : {
517 0 : SetControlForeground();
518 0 : SetControlBackground();
519 : }
520 : else
521 : {
522 0 : SetControlForeground(COL_WHITE);
523 0 : SetControlBackground(0xff6563);
524 : }
525 0 : }
526 :
527 0 : void RefEdit::SetText(const OUString& rStr)
528 : {
529 0 : Edit::SetText( rStr );
530 0 : UpdateHdl( &aIdle );
531 0 : }
532 :
533 0 : void RefEdit::StartUpdateData()
534 : {
535 0 : aIdle.Start();
536 0 : }
537 :
538 0 : void RefEdit::SetReferences( IControlReferenceHandler* pDlg, vcl::Window* pLabel )
539 : {
540 0 : pAnyRefDlg = pDlg;
541 0 : pLabelWidget = pLabel;
542 :
543 0 : if( pDlg )
544 : {
545 0 : aIdle.SetIdleHdl( LINK( this, RefEdit, UpdateHdl ) );
546 0 : aIdle.SetPriority( SchedulerPriority::LOW );
547 : }
548 : else
549 : {
550 0 : aIdle.SetIdleHdl( Link<Idle *, void>() );
551 0 : aIdle.Stop();
552 : }
553 0 : }
554 :
555 0 : void RefEdit::Modify()
556 : {
557 0 : Edit::Modify();
558 0 : if( pAnyRefDlg )
559 0 : pAnyRefDlg->HideReference();
560 0 : }
561 :
562 0 : void RefEdit::KeyInput( const KeyEvent& rKEvt )
563 : {
564 0 : const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
565 0 : if( pAnyRefDlg && !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) )
566 0 : pAnyRefDlg->ReleaseFocus( this );
567 : else
568 0 : Edit::KeyInput( rKEvt );
569 0 : }
570 :
571 0 : void RefEdit::GetFocus()
572 : {
573 0 : Edit::GetFocus();
574 0 : StartUpdateData();
575 0 : }
576 :
577 0 : void RefEdit::LoseFocus()
578 : {
579 0 : Edit::LoseFocus();
580 0 : if( pAnyRefDlg )
581 0 : pAnyRefDlg->HideReference();
582 0 : }
583 :
584 0 : IMPL_LINK_NOARG_TYPED(RefEdit, UpdateHdl, Idle *, void)
585 : {
586 0 : if( pAnyRefDlg )
587 0 : pAnyRefDlg->ShowReference( GetText() );
588 0 : }
589 :
590 : //class RefButton
591 0 : RefButton::RefButton( vcl::Window* _pParent, WinBits nStyle ) :
592 : ImageButton( _pParent, nStyle ),
593 : aImgRefStart( ModuleRes( RID_BMP_REFBTN1 ) ),
594 : aImgRefDone( ModuleRes( RID_BMP_REFBTN2 ) ),
595 : aShrinkQuickHelp( ModuleRes( RID_STR_SHRINK ).toString() ),
596 : aExpandQuickHelp( ModuleRes( RID_STR_EXPAND ).toString() ),
597 : pAnyRefDlg( NULL ),
598 0 : pRefEdit( NULL )
599 : {
600 0 : SetStartImage();
601 0 : }
602 :
603 0 : RefButton::~RefButton()
604 : {
605 0 : disposeOnce();
606 0 : }
607 :
608 0 : void RefButton::dispose()
609 : {
610 0 : pRefEdit.clear();
611 0 : ImageButton::dispose();
612 0 : }
613 :
614 0 : VCL_BUILDER_FACTORY_ARGS(RefButton, 0)
615 :
616 0 : void RefButton::SetStartImage()
617 : {
618 0 : SetModeImage( aImgRefStart );
619 0 : SetQuickHelpText( aShrinkQuickHelp );
620 0 : }
621 :
622 0 : void RefButton::SetEndImage()
623 : {
624 0 : SetModeImage( aImgRefDone );
625 0 : SetQuickHelpText( aExpandQuickHelp );
626 0 : }
627 :
628 0 : void RefButton::SetReferences( IControlReferenceHandler* pDlg, RefEdit* pEdit )
629 : {
630 0 : pAnyRefDlg = pDlg;
631 0 : pRefEdit = pEdit;
632 0 : }
633 :
634 0 : void RefButton::Click()
635 : {
636 0 : if( pAnyRefDlg )
637 0 : pAnyRefDlg->ToggleCollapsed( pRefEdit, this );
638 0 : }
639 :
640 0 : void RefButton::KeyInput( const KeyEvent& rKEvt )
641 : {
642 0 : const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
643 0 : if( pAnyRefDlg && !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) )
644 0 : pAnyRefDlg->ReleaseFocus( pRefEdit );
645 : else
646 0 : ImageButton::KeyInput( rKEvt );
647 0 : }
648 :
649 0 : void RefButton::GetFocus()
650 : {
651 0 : ImageButton::GetFocus();
652 0 : if( pRefEdit )
653 0 : pRefEdit->StartUpdateData();
654 0 : }
655 :
656 0 : void RefButton::LoseFocus()
657 : {
658 0 : ImageButton::LoseFocus();
659 0 : if( pRefEdit )
660 0 : pRefEdit->Modify();
661 0 : }
662 :
663 183 : } // formula
664 :
665 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|