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 
21 #include <tools/debug.hxx>
22 #include <vcl/svapp.hxx>
23 #include <svl/zforlist.hxx>
24 #include <svtools/svmedit.hxx>
25 #include <filectrl.hxx>
26 #include <unoiface.hxx>
27 #include <com/sun/star/awt/LineEndFormat.hpp>
28 #include <cppuhelper/queryinterface.hxx>
29 #include <cppuhelper/typeprovider.hxx>
30 #include <toolkit/helper/convert.hxx>
31 #include <toolkit/helper/property.hxx>
32 #include <vcl/fmtfield.hxx>
33 #include <svl/numuno.hxx>
34 #include <svtools/calendar.hxx>
35 #include "treecontrolpeer.hxx"
36 #include "svtxgridcontrol.hxx"
37 #include <table/tablecontrol.hxx>
38 
39 namespace
40 {
lcl_setWinBits(vcl::Window * _pWindow,WinBits _nBits,bool _bSet)41     void lcl_setWinBits( vcl::Window* _pWindow, WinBits _nBits, bool _bSet )
42     {
43         WinBits nStyle = _pWindow->GetStyle();
44         if ( _bSet )
45             nStyle |= _nBits;
46         else
47             nStyle &= ~_nBits;
48         _pWindow->SetStyle( nStyle );
49     }
50 }
51 
52 
53 //  help function for the toolkit...
54 
55 
56 extern "C" {
57 
CreateWindow(VCLXWindow ** ppNewComp,const css::awt::WindowDescriptor * pDescriptor,vcl::Window * pParent,WinBits nWinBits)58 SAL_DLLPUBLIC_EXPORT vcl::Window* CreateWindow( VCLXWindow** ppNewComp, const css::awt::WindowDescriptor* pDescriptor, vcl::Window* pParent, WinBits nWinBits )
59 {
60     vcl::Window* pWindow = nullptr;
61     OUString aServiceName( pDescriptor->WindowServiceName );
62     if ( aServiceName.equalsIgnoreAsciiCase( "MultiLineEdit" ) )
63     {
64         if ( pParent )
65         {
66             pWindow = VclPtr<MultiLineEdit>::Create( pParent, nWinBits|WB_IGNORETAB);
67             static_cast< MultiLineEdit* >( pWindow )->DisableSelectionOnFocus();
68             *ppNewComp = new VCLXMultiLineEdit;
69         }
70         else
71         {
72             *ppNewComp = nullptr;
73             return nullptr;
74         }
75     }
76     else if ( aServiceName.equalsIgnoreAsciiCase( "FileControl" ) )
77     {
78         if ( pParent )
79         {
80             pWindow = VclPtr<FileControl>::Create( pParent, nWinBits );
81             *ppNewComp = new VCLXFileControl;
82         }
83         else
84         {
85             *ppNewComp = nullptr;
86             return nullptr;
87         }
88     }
89     else if (aServiceName.equalsIgnoreAsciiCase("FormattedField") )
90     {
91         pWindow = VclPtr<FormattedField>::Create( pParent, nWinBits );
92         *ppNewComp = new SVTXFormattedField;
93     }
94     else if (aServiceName.equalsIgnoreAsciiCase("NumericField") )
95     {
96         pWindow = VclPtr<DoubleNumericField>::Create( pParent, nWinBits );
97         *ppNewComp = new SVTXNumericField;
98     }
99     else if (aServiceName.equalsIgnoreAsciiCase("LongCurrencyField") )
100     {
101         pWindow = VclPtr<DoubleCurrencyField>::Create( pParent, nWinBits );
102         *ppNewComp = new SVTXCurrencyField;
103     }
104     else if (aServiceName.equalsIgnoreAsciiCase("datefield") )
105     {
106         pWindow = VclPtr<CalendarField>::Create( pParent, nWinBits);
107         static_cast<CalendarField*>(pWindow)->EnableToday();
108         static_cast<CalendarField*>(pWindow)->EnableNone();
109         static_cast<CalendarField*>(pWindow)->EnableEmptyFieldValue( true );
110         SVTXDateField * newComp = new SVTXDateField;
111         *ppNewComp = newComp;
112         newComp->SetFormatter( static_cast<FormatterBase*>(static_cast<DateField*>(pWindow)) );
113     }
114     else if ( aServiceName.equalsIgnoreAsciiCase( "Tree" ) )
115     {
116         TreeControlPeer* pPeer = new TreeControlPeer;
117         *ppNewComp = pPeer;
118         pWindow = pPeer->createVclControl( pParent, nWinBits );
119     }
120     else if ( aServiceName.equalsIgnoreAsciiCase( "Grid" ) )
121     {
122         if ( pParent )
123         {
124             pWindow = VclPtr< ::svt::table::TableControl>::Create(pParent, nWinBits);
125             *ppNewComp = new SVTXGridControl;
126         }
127         else
128         {
129             *ppNewComp = nullptr;
130             return nullptr;
131         }
132     }
133     return pWindow;
134 }
135 
136 }   // extern "C"
137 
138 
139 //  class VCLXMultiLineEdit
140 
VCLXMultiLineEdit()141 VCLXMultiLineEdit::VCLXMultiLineEdit()
142     :maTextListeners( *this )
143     ,meLineEndType( LINEEND_LF )    // default behavior before introducing this property: LF (unix-like)
144 {
145 }
146 
~VCLXMultiLineEdit()147 VCLXMultiLineEdit::~VCLXMultiLineEdit()
148 {
149 }
150 
queryInterface(const css::uno::Type & rType)151 css::uno::Any VCLXMultiLineEdit::queryInterface( const css::uno::Type & rType )
152 {
153     css::uno::Any aRet = ::cppu::queryInterface( rType,
154                                         static_cast< css::awt::XTextComponent* >(this),
155                                         static_cast< css::awt::XTextArea* >(this),
156                                         static_cast< css::awt::XTextLayoutConstrains* >(this),
157                                         static_cast< css::lang::XTypeProvider* >(this) );
158     return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
159 }
160 
IMPL_IMPLEMENTATION_ID(VCLXMultiLineEdit)161 IMPL_IMPLEMENTATION_ID( VCLXMultiLineEdit )
162 
163 // css::lang::XTypeProvider
164 css::uno::Sequence< css::uno::Type > VCLXMultiLineEdit::getTypes()
165 {
166     static const ::cppu::OTypeCollection aTypeList(
167         cppu::UnoType<css::lang::XTypeProvider>::get(),
168         cppu::UnoType<css::awt::XTextComponent>::get(),
169         cppu::UnoType<css::awt::XTextArea>::get(),
170         cppu::UnoType<css::awt::XTextLayoutConstrains>::get(),
171         VCLXWindow::getTypes()
172     );
173     return aTypeList.getTypes();
174 }
175 
addTextListener(const css::uno::Reference<css::awt::XTextListener> & l)176 void VCLXMultiLineEdit::addTextListener( const css::uno::Reference< css::awt::XTextListener > & l )
177 {
178     maTextListeners.addInterface( l );
179 }
180 
removeTextListener(const css::uno::Reference<css::awt::XTextListener> & l)181 void VCLXMultiLineEdit::removeTextListener( const css::uno::Reference< css::awt::XTextListener > & l )
182 {
183     maTextListeners.removeInterface( l );
184 }
185 
setText(const OUString & aText)186 void VCLXMultiLineEdit::setText( const OUString& aText )
187 {
188     SolarMutexGuard aGuard;
189 
190     VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
191     if ( pEdit )
192     {
193         pEdit->SetText( aText );
194 
195         // #107218# Call same listeners like VCL would do after user interaction
196         SetSynthesizingVCLEvent( true );
197         pEdit->SetModifyFlag();
198         pEdit->Modify();
199         SetSynthesizingVCLEvent( false );
200     }
201 }
202 
insertText(const css::awt::Selection & rSel,const OUString & aText)203 void VCLXMultiLineEdit::insertText( const css::awt::Selection& rSel, const OUString& aText )
204 {
205     SolarMutexGuard aGuard;
206 
207     VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
208     if ( pEdit )
209     {
210         setSelection( rSel );
211         pEdit->ReplaceSelected( aText );
212     }
213 }
214 
getText()215 OUString VCLXMultiLineEdit::getText()
216 {
217     SolarMutexGuard aGuard;
218 
219     OUString aText;
220     VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
221     if ( pEdit )
222         aText = pEdit->GetText( meLineEndType );
223     return aText;
224 }
225 
getSelectedText()226 OUString VCLXMultiLineEdit::getSelectedText()
227 {
228     SolarMutexGuard aGuard;
229 
230     OUString aText;
231     VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
232     if ( pMultiLineEdit)
233         aText = pMultiLineEdit->GetSelected( meLineEndType );
234     return aText;
235 
236 }
237 
setSelection(const css::awt::Selection & aSelection)238 void VCLXMultiLineEdit::setSelection( const css::awt::Selection& aSelection )
239 {
240     SolarMutexGuard aGuard;
241 
242     VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
243     if ( pMultiLineEdit )
244     {
245         pMultiLineEdit->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
246     }
247 }
248 
getSelection()249 css::awt::Selection VCLXMultiLineEdit::getSelection()
250 {
251     SolarMutexGuard aGuard;
252 
253     css::awt::Selection aSel;
254     VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
255     if ( pMultiLineEdit )
256     {
257         aSel.Min = pMultiLineEdit->GetSelection().Min();
258         aSel.Max = pMultiLineEdit->GetSelection().Max();
259     }
260     return aSel;
261 }
262 
isEditable()263 sal_Bool VCLXMultiLineEdit::isEditable()
264 {
265     SolarMutexGuard aGuard;
266 
267     VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
268     return pMultiLineEdit && !pMultiLineEdit->IsReadOnly() && pMultiLineEdit->IsEnabled();
269 }
270 
setEditable(sal_Bool bEditable)271 void VCLXMultiLineEdit::setEditable( sal_Bool bEditable )
272 {
273     SolarMutexGuard aGuard;
274 
275     VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
276     if ( pMultiLineEdit )
277         pMultiLineEdit->SetReadOnly( !bEditable );
278 }
279 
setMaxTextLen(sal_Int16 nLen)280 void VCLXMultiLineEdit::setMaxTextLen( sal_Int16 nLen )
281 {
282     SolarMutexGuard aGuard;
283 
284     VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
285     if ( pMultiLineEdit )
286         pMultiLineEdit->SetMaxTextLen( nLen );
287 }
288 
getMaxTextLen()289 sal_Int16 VCLXMultiLineEdit::getMaxTextLen()
290 {
291     SolarMutexGuard aGuard;
292 
293     VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
294     return pMultiLineEdit ? static_cast<sal_Int16>(pMultiLineEdit->GetMaxTextLen()) : sal_Int16(0);
295 }
296 
getTextLines()297 OUString VCLXMultiLineEdit::getTextLines()
298 {
299     SolarMutexGuard aGuard;
300 
301     OUString aText;
302     VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
303     if ( pEdit )
304         aText = pEdit->GetTextLines( meLineEndType );
305     return aText;
306 }
307 
getMinimumSize()308 css::awt::Size VCLXMultiLineEdit::getMinimumSize()
309 {
310     SolarMutexGuard aGuard;
311 
312     css::awt::Size aSz;
313     VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
314     if ( pEdit )
315         aSz = AWTSize(pEdit->CalcMinimumSize());
316     return aSz;
317 }
318 
getPreferredSize()319 css::awt::Size VCLXMultiLineEdit::getPreferredSize()
320 {
321     return getMinimumSize();
322 }
323 
calcAdjustedSize(const css::awt::Size & rNewSize)324 css::awt::Size VCLXMultiLineEdit::calcAdjustedSize( const css::awt::Size& rNewSize )
325 {
326     SolarMutexGuard aGuard;
327 
328     css::awt::Size aSz = rNewSize;
329     VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
330     if ( pEdit )
331         aSz = AWTSize(pEdit->CalcAdjustedSize( VCLSize(rNewSize )));
332     return aSz;
333 }
334 
getMinimumSize(sal_Int16 nCols,sal_Int16 nLines)335 css::awt::Size VCLXMultiLineEdit::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines )
336 {
337     SolarMutexGuard aGuard;
338 
339     css::awt::Size aSz;
340     VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
341     if ( pEdit )
342         aSz = AWTSize(pEdit->CalcBlockSize( nCols, nLines ));
343     return aSz;
344 }
345 
getColumnsAndLines(sal_Int16 & nCols,sal_Int16 & nLines)346 void VCLXMultiLineEdit::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines )
347 {
348     SolarMutexGuard aGuard;
349 
350     nCols = nLines = 0;
351     VclPtr< MultiLineEdit > pEdit = GetAs< MultiLineEdit >();
352     if ( pEdit )
353     {
354         sal_uInt16 nC, nL;
355         pEdit->GetMaxVisColumnsAndLines( nC, nL );
356         nCols = nC;
357         nLines = nL;
358     }
359 }
360 
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)361 void VCLXMultiLineEdit::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
362 {
363     switch ( rVclWindowEvent.GetId() )
364     {
365         case VclEventId::EditModify:
366         {
367             if ( maTextListeners.getLength() )
368             {
369                 css::awt::TextEvent aEvent;
370                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
371                 maTextListeners.textChanged( aEvent );
372             }
373         }
374         break;
375         default:
376         {
377             VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
378         }
379         break;
380     }
381 }
382 
setProperty(const OUString & PropertyName,const css::uno::Any & Value)383 void VCLXMultiLineEdit::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
384 {
385     SolarMutexGuard aGuard;
386 
387     VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
388     if ( !pMultiLineEdit )
389         return;
390 
391     sal_uInt16 nPropType = GetPropertyId( PropertyName );
392     switch ( nPropType )
393     {
394         case BASEPROPERTY_LINE_END_FORMAT:
395         {
396             sal_Int16 nLineEndType = css::awt::LineEndFormat::LINE_FEED;
397             OSL_VERIFY( Value >>= nLineEndType );
398             switch ( nLineEndType )
399             {
400             case css::awt::LineEndFormat::CARRIAGE_RETURN:           meLineEndType = LINEEND_CR; break;
401             case css::awt::LineEndFormat::LINE_FEED:                 meLineEndType = LINEEND_LF; break;
402             case css::awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED: meLineEndType = LINEEND_CRLF; break;
403             default: OSL_FAIL( "VCLXMultiLineEdit::setProperty: invalid line end value!" ); break;
404             }
405         }
406         break;
407 
408         case BASEPROPERTY_READONLY:
409         {
410             bool b;
411             if ( Value >>= b )
412                 pMultiLineEdit->SetReadOnly( b );
413         }
414         break;
415         case BASEPROPERTY_MAXTEXTLEN:
416         {
417             sal_Int16 n = sal_Int16();
418             if ( Value >>= n )
419                 pMultiLineEdit->SetMaxTextLen( n );
420         }
421         break;
422         case BASEPROPERTY_HIDEINACTIVESELECTION:
423         {
424             bool b;
425             if ( Value >>= b )
426             {
427                 pMultiLineEdit->EnableFocusSelectionHide( b );
428                 lcl_setWinBits( pMultiLineEdit, WB_NOHIDESELECTION, !b );
429             }
430         }
431         break;
432         default:
433         {
434             VCLXWindow::setProperty( PropertyName, Value );
435         }
436     }
437 }
438 
getProperty(const OUString & PropertyName)439 css::uno::Any VCLXMultiLineEdit::getProperty( const OUString& PropertyName )
440 {
441     SolarMutexGuard aGuard;
442 
443     css::uno::Any aProp;
444     VclPtr< MultiLineEdit > pMultiLineEdit = GetAs< MultiLineEdit >();
445     if ( pMultiLineEdit )
446     {
447         sal_uInt16 nPropType = GetPropertyId( PropertyName );
448         switch ( nPropType )
449         {
450             case BASEPROPERTY_LINE_END_FORMAT:
451             {
452                 sal_Int16 nLineEndType = css::awt::LineEndFormat::LINE_FEED;
453                 switch ( meLineEndType )
454                 {
455                 case LINEEND_CR:   nLineEndType = css::awt::LineEndFormat::CARRIAGE_RETURN; break;
456                 case LINEEND_LF:   nLineEndType = css::awt::LineEndFormat::LINE_FEED; break;
457                 case LINEEND_CRLF: nLineEndType = css::awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED; break;
458                 default: OSL_FAIL( "VCLXMultiLineEdit::getProperty: invalid line end value!" ); break;
459                 }
460                 aProp <<= nLineEndType;
461             }
462             break;
463 
464             case BASEPROPERTY_READONLY:
465             {
466                 aProp <<= pMultiLineEdit->IsReadOnly();
467             }
468             break;
469             case BASEPROPERTY_MAXTEXTLEN:
470             {
471                 aProp <<= static_cast<sal_Int16>(pMultiLineEdit->GetMaxTextLen());
472             }
473             break;
474             default:
475             {
476                 aProp = VCLXWindow::getProperty( PropertyName );
477             }
478         }
479     }
480     return aProp;
481 }
482 
setFocus()483 void SAL_CALL VCLXMultiLineEdit::setFocus(  )
484 {
485     SolarMutexGuard aGuard;
486 
487     // don't grab the focus if we already have it. Reason is that the only thing which the edit
488     // does is forwarding the focus to its text window. This text window then does a "select all".
489     // So if the text window already has the focus, and we give the focus to the multi line
490     // edit, then all which happens is that everything is selected.
491     // #i27072#
492     if ( GetWindow() && !GetWindow()->HasChildPathFocus() )
493         GetWindow()->GrabFocus();
494 }
495 
ImplGetPropertyIds(std::vector<sal_uInt16> & rIds)496 void VCLXMultiLineEdit::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
497 {
498     PushPropertyIds( rIds,
499                      // FIXME: elide duplication ?
500                      BASEPROPERTY_LINE_END_FORMAT,
501                      BASEPROPERTY_READONLY,
502                      BASEPROPERTY_MAXTEXTLEN,
503                      BASEPROPERTY_HIDEINACTIVESELECTION,
504                      0);
505     VCLXWindow::ImplGetPropertyIds( rIds, true );
506 }
507 
508 //  class VCLXFileControl
509 
VCLXFileControl()510 VCLXFileControl::VCLXFileControl() : maTextListeners( *this )
511 {
512 }
513 
~VCLXFileControl()514 VCLXFileControl::~VCLXFileControl()
515 {
516     VclPtr< FileControl > pControl = GetAs< FileControl >();
517     if ( pControl )
518         pControl->GetEdit().SetModifyHdl( Link<Edit&,void>() );
519 }
520 
queryInterface(const css::uno::Type & rType)521 css::uno::Any VCLXFileControl::queryInterface( const css::uno::Type & rType )
522 {
523     css::uno::Any aRet = ::cppu::queryInterface( rType,
524                                         static_cast< css::awt::XTextComponent* >(this),
525                                         static_cast< css::awt::XTextLayoutConstrains* >(this),
526                                         static_cast< css::lang::XTypeProvider* >(this) );
527     return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
528 }
529 
IMPL_IMPLEMENTATION_ID(VCLXFileControl)530 IMPL_IMPLEMENTATION_ID( VCLXFileControl )
531 
532 // css::lang::XTypeProvider
533 css::uno::Sequence< css::uno::Type > VCLXFileControl::getTypes()
534 {
535     static const ::cppu::OTypeCollection aTypeList(
536         cppu::UnoType<css::lang::XTypeProvider>::get(),
537         cppu::UnoType<css::awt::XTextComponent>::get(),
538         cppu::UnoType<css::awt::XTextLayoutConstrains>::get(),
539         VCLXWindow::getTypes()
540     );
541     return aTypeList.getTypes();
542 }
543 
setProperty(const OUString & PropertyName,const css::uno::Any & Value)544 void SAL_CALL VCLXFileControl::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
545 {
546     SolarMutexGuard aGuard;
547 
548     VclPtr< FileControl > pControl = GetAs< FileControl >();
549     if ( !pControl )
550         return;
551 
552     sal_uInt16 nPropType = GetPropertyId( PropertyName );
553     switch ( nPropType )
554     {
555     case BASEPROPERTY_HIDEINACTIVESELECTION:
556     {
557         bool bValue(false);
558         OSL_VERIFY( Value >>= bValue );
559 
560         lcl_setWinBits( pControl, WB_NOHIDESELECTION, !bValue );
561         lcl_setWinBits( &pControl->GetEdit(), WB_NOHIDESELECTION, !bValue );
562     }
563     break;
564 
565     default:
566         VCLXWindow::setProperty( PropertyName, Value );
567         break;
568     }
569 }
570 
SetWindow(const VclPtr<vcl::Window> & pWindow)571 void VCLXFileControl::SetWindow( const VclPtr< vcl::Window > &pWindow )
572 {
573     VclPtr< FileControl > pPrevFileControl = GetAsDynamic< FileControl >();
574     if ( pPrevFileControl )
575         pPrevFileControl->SetEditModifyHdl( Link<Edit&,void>() );
576 
577     FileControl* pNewFileControl = dynamic_cast<FileControl*>( pWindow.get() );
578     if ( pNewFileControl )
579         pNewFileControl->SetEditModifyHdl( LINK( this, VCLXFileControl, ModifyHdl ) );
580 
581     VCLXWindow::SetWindow( pWindow );
582 }
583 
addTextListener(const css::uno::Reference<css::awt::XTextListener> & l)584 void VCLXFileControl::addTextListener( const css::uno::Reference< css::awt::XTextListener > & l )
585 {
586     maTextListeners.addInterface( l );
587 }
588 
removeTextListener(const css::uno::Reference<css::awt::XTextListener> & l)589 void VCLXFileControl::removeTextListener( const css::uno::Reference< css::awt::XTextListener > & l )
590 {
591     maTextListeners.removeInterface( l );
592 }
593 
setText(const OUString & aText)594 void VCLXFileControl::setText( const OUString& aText )
595 {
596     SolarMutexGuard aGuard;
597 
598     VclPtr<vcl::Window> pWindow = GetWindow();
599     if ( pWindow )
600     {
601         pWindow->SetText( aText );
602 
603         // also in Java a textChanged is triggered, not in VCL.
604         // css::awt::Toolkit should be JAVA-compliant...
605         ModifyHdl();
606     }
607 }
608 
insertText(const css::awt::Selection & rSel,const OUString & aText)609 void VCLXFileControl::insertText( const css::awt::Selection& rSel, const OUString& aText )
610 {
611     SolarMutexGuard aGuard;
612 
613     VclPtr< FileControl > pFileControl = GetAs< FileControl >();
614     if ( pFileControl )
615     {
616         pFileControl->GetEdit().SetSelection( Selection( rSel.Min, rSel.Max ) );
617         pFileControl->GetEdit().ReplaceSelected( aText );
618     }
619 }
620 
getText()621 OUString VCLXFileControl::getText()
622 {
623     SolarMutexGuard aGuard;
624 
625     OUString aText;
626     VclPtr<vcl::Window> pWindow = GetWindow();
627     if ( pWindow )
628         aText = pWindow->GetText();
629     return aText;
630 }
631 
getSelectedText()632 OUString VCLXFileControl::getSelectedText()
633 {
634     SolarMutexGuard aGuard;
635 
636     OUString aText;
637     VclPtr< FileControl > pFileControl = GetAs< FileControl >();
638     if ( pFileControl)
639         aText = pFileControl->GetEdit().GetSelected();
640     return aText;
641 
642 }
643 
setSelection(const css::awt::Selection & aSelection)644 void VCLXFileControl::setSelection( const css::awt::Selection& aSelection )
645 {
646     SolarMutexGuard aGuard;
647 
648     VclPtr< FileControl > pFileControl = GetAs< FileControl >();
649     if ( pFileControl )
650         pFileControl->GetEdit().SetSelection( Selection( aSelection.Min, aSelection.Max ) );
651 }
652 
getSelection()653 css::awt::Selection VCLXFileControl::getSelection()
654 {
655     SolarMutexGuard aGuard;
656 
657     css::awt::Selection aSel;
658     VclPtr< FileControl > pFileControl = GetAs< FileControl >();
659     if ( pFileControl )
660     {
661         aSel.Min = pFileControl->GetEdit().GetSelection().Min();
662         aSel.Max = pFileControl->GetEdit().GetSelection().Max();
663     }
664     return aSel;
665 }
666 
isEditable()667 sal_Bool VCLXFileControl::isEditable()
668 {
669     SolarMutexGuard aGuard;
670 
671     VclPtr< FileControl > pFileControl = GetAs< FileControl >();
672     return pFileControl && !pFileControl->GetEdit().IsReadOnly() && pFileControl->GetEdit().IsEnabled();
673 }
674 
setEditable(sal_Bool bEditable)675 void VCLXFileControl::setEditable( sal_Bool bEditable )
676 {
677     SolarMutexGuard aGuard;
678 
679     VclPtr< FileControl > pFileControl = GetAs< FileControl >();
680     if ( pFileControl )
681         pFileControl->GetEdit().SetReadOnly( !bEditable );
682 }
683 
setMaxTextLen(sal_Int16 nLen)684 void VCLXFileControl::setMaxTextLen( sal_Int16 nLen )
685 {
686     SolarMutexGuard aGuard;
687 
688     VclPtr< FileControl > pFileControl = GetAs< FileControl >();
689     if ( pFileControl )
690         pFileControl->GetEdit().SetMaxTextLen( nLen );
691 }
692 
getMaxTextLen()693 sal_Int16 VCLXFileControl::getMaxTextLen()
694 {
695     SolarMutexGuard aGuard;
696 
697     VclPtr< FileControl > pFileControl = GetAs< FileControl >();
698     return pFileControl ? pFileControl->GetEdit().GetMaxTextLen() : 0;
699 }
700 
701 
IMPL_LINK_NOARG(VCLXFileControl,ModifyHdl,Edit &,void)702 IMPL_LINK_NOARG(VCLXFileControl, ModifyHdl, Edit&, void)
703 {
704     ModifyHdl();
705 }
706 
ModifyHdl()707 void VCLXFileControl::ModifyHdl()
708 {
709     css::awt::TextEvent aEvent;
710     aEvent.Source = static_cast<cppu::OWeakObject*>(this);
711     maTextListeners.textChanged( aEvent );
712 }
713 
getMinimumSize()714 css::awt::Size VCLXFileControl::getMinimumSize()
715 {
716     SolarMutexGuard aGuard;
717 
718     css::awt::Size aSz;
719     VclPtr< FileControl > pControl = GetAs< FileControl >();
720     if ( pControl )
721     {
722         Size aTmpSize = pControl->GetEdit().CalcMinimumSize();
723         aTmpSize.AdjustWidth(pControl->GetButton().CalcMinimumSize().Width() );
724         aSz = AWTSize(pControl->CalcWindowSize( aTmpSize ));
725     }
726     return aSz;
727 }
728 
getPreferredSize()729 css::awt::Size VCLXFileControl::getPreferredSize()
730 {
731     css::awt::Size aSz = getMinimumSize();
732     aSz.Height += 4;
733     return aSz;
734 }
735 
calcAdjustedSize(const css::awt::Size & rNewSize)736 css::awt::Size VCLXFileControl::calcAdjustedSize( const css::awt::Size& rNewSize )
737 {
738     SolarMutexGuard aGuard;
739 
740     css::awt::Size aSz =rNewSize;
741     VclPtr< FileControl > pControl = GetAs< FileControl >();
742     if ( pControl )
743     {
744         css::awt::Size aMinSz = getMinimumSize();
745         if ( aSz.Height != aMinSz.Height )
746             aSz.Height = aMinSz.Height;
747     }
748     return aSz;
749 }
750 
getMinimumSize(sal_Int16 nCols,sal_Int16)751 css::awt::Size VCLXFileControl::getMinimumSize( sal_Int16 nCols, sal_Int16 )
752 {
753     SolarMutexGuard aGuard;
754 
755     css::awt::Size aSz;
756     VclPtr< FileControl > pControl = GetAs< FileControl >();
757     if ( pControl )
758     {
759         aSz = AWTSize(pControl->GetEdit().CalcSize( nCols ));
760         aSz.Width += pControl->GetButton().CalcMinimumSize().Width();
761     }
762     return aSz;
763 }
764 
getColumnsAndLines(sal_Int16 & nCols,sal_Int16 & nLines)765 void VCLXFileControl::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines )
766 {
767     SolarMutexGuard aGuard;
768 
769     nCols = 0;
770     nLines = 1;
771     VclPtr< FileControl > pControl = GetAs< FileControl >();
772     if ( pControl )
773         nCols = pControl->GetEdit().GetMaxVisChars();
774 }
775 
ImplGetPropertyIds(std::vector<sal_uInt16> & rIds)776 void VCLXFileControl::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
777 {
778     PushPropertyIds( rIds,
779                      // FIXME: elide duplication ?
780                      BASEPROPERTY_HIDEINACTIVESELECTION,
781                      0);
782     VCLXWindow::ImplGetPropertyIds( rIds, true );
783 }
784 
785 
786 //  class SVTXFormattedField
787 
788 
SVTXFormattedField()789 SVTXFormattedField::SVTXFormattedField()
790     :bIsStandardSupplier(true)
791     ,nKeyToSetDelayed(-1)
792 {
793 }
794 
795 
~SVTXFormattedField()796 SVTXFormattedField::~SVTXFormattedField()
797 {
798 }
799 
800 
SetWindow(const VclPtr<vcl::Window> & _pWindow)801 void SVTXFormattedField::SetWindow( const VclPtr< vcl::Window > &_pWindow )
802 {
803     VCLXSpinField::SetWindow(_pWindow);
804     if (GetAs< FormattedField >())
805         GetAs< FormattedField >()->SetAutoColor(true);
806 }
807 
808 
setProperty(const OUString & PropertyName,const css::uno::Any & Value)809 void SVTXFormattedField::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
810 {
811     SolarMutexGuard aGuard;
812 
813     VclPtr<FormattedField> pField = GetAs< FormattedField >();
814     if ( pField )
815     {
816         sal_uInt16 nPropType = GetPropertyId( PropertyName );
817         switch (nPropType)
818         {
819             case BASEPROPERTY_ENFORCE_FORMAT:
820             {
821                 bool bEnable( true );
822                 if ( Value >>= bEnable )
823                     pField->EnableNotANumber( !bEnable );
824             }
825             break;
826 
827             case BASEPROPERTY_EFFECTIVE_MIN:
828             case BASEPROPERTY_VALUEMIN_DOUBLE:
829                 SetMinValue(Value);
830                 break;
831 
832             case BASEPROPERTY_EFFECTIVE_MAX:
833             case BASEPROPERTY_VALUEMAX_DOUBLE:
834                 SetMaxValue(Value);
835                 break;
836 
837             case BASEPROPERTY_EFFECTIVE_DEFAULT:
838                 SetDefaultValue(Value);
839                 break;
840 
841             case BASEPROPERTY_TREATASNUMBER:
842             {
843                 bool b;
844                 if ( Value >>= b )
845                     SetTreatAsNumber(b);
846             }
847             break;
848 
849             case BASEPROPERTY_FORMATSSUPPLIER:
850                 if (!Value.hasValue())
851                     setFormatsSupplier(css::uno::Reference< css::util::XNumberFormatsSupplier > (nullptr));
852                 else
853                 {
854                     css::uno::Reference< css::util::XNumberFormatsSupplier > xNFS;
855                     if ( Value >>= xNFS )
856                         setFormatsSupplier(xNFS);
857                 }
858                 break;
859             case BASEPROPERTY_FORMATKEY:
860                 if (!Value.hasValue())
861                     setFormatKey(0);
862                 else
863                 {
864                     sal_Int32 n = 0;
865                     if ( Value >>= n )
866                         setFormatKey(n);
867                 }
868                 break;
869 
870             case BASEPROPERTY_EFFECTIVE_VALUE:
871             case BASEPROPERTY_VALUE_DOUBLE:
872             {
873                 const css::uno::TypeClass rTC = Value.getValueType().getTypeClass();
874                 if (rTC != css::uno::TypeClass_STRING)
875                     // no string
876                     if (rTC != css::uno::TypeClass_DOUBLE)
877                         // no double
878                         if (Value.hasValue())
879                         {   // but a value
880                             // try if it is something convertible
881                             sal_Int32 nValue = 0;
882                             if (!(Value >>= nValue))
883                                 throw css::lang::IllegalArgumentException();
884                             SetValue(css::uno::makeAny(static_cast<double>(nValue)));
885                             break;
886                         }
887 
888                 SetValue(Value);
889             }
890             break;
891             case BASEPROPERTY_VALUESTEP_DOUBLE:
892             {
893                 double d = 0.0;
894                 if ( Value >>= d )
895                      pField->SetSpinSize( d );
896                 else
897                 {
898                     sal_Int32 n = 0;
899                     if ( Value >>= n )
900                          pField->SetSpinSize( n );
901                 }
902             }
903             break;
904             case BASEPROPERTY_DECIMALACCURACY:
905             {
906                 sal_Int32 n = 0;
907                 if ( Value >>= n )
908                      pField->SetDecimalDigits( static_cast<sal_uInt16>(n) );
909             }
910             break;
911             case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
912             {
913                     bool b;
914                     if ( Value >>= b )
915                      pField->SetThousandsSep( b );
916             }
917             break;
918 
919             default:
920                 VCLXSpinField::setProperty( PropertyName, Value );
921         }
922 
923         if (BASEPROPERTY_TEXTCOLOR == nPropType)
924         {   // after setting a new text color, think again about the AutoColor flag of the control
925             // 17.05.2001 - 86859 - frank.schoenheit@germany.sun.com
926             pField->SetAutoColor(!Value.hasValue());
927         }
928     }
929     else
930         VCLXSpinField::setProperty( PropertyName, Value );
931 }
932 
933 
getProperty(const OUString & PropertyName)934 css::uno::Any SVTXFormattedField::getProperty( const OUString& PropertyName )
935 {
936     SolarMutexGuard aGuard;
937 
938     css::uno::Any aReturn;
939 
940     VclPtr<FormattedField> pField = GetAs< FormattedField >();
941     if ( pField )
942     {
943         sal_uInt16 nPropType = GetPropertyId( PropertyName );
944         switch (nPropType)
945         {
946             case BASEPROPERTY_EFFECTIVE_MIN:
947             case BASEPROPERTY_VALUEMIN_DOUBLE:
948                 aReturn = GetMinValue();
949                 break;
950 
951             case BASEPROPERTY_EFFECTIVE_MAX:
952             case BASEPROPERTY_VALUEMAX_DOUBLE:
953                 aReturn = GetMaxValue();
954                 break;
955 
956             case BASEPROPERTY_EFFECTIVE_DEFAULT:
957                 aReturn = GetDefaultValue();
958                 break;
959 
960             case BASEPROPERTY_TREATASNUMBER:
961                 aReturn <<= GetTreatAsNumber();
962                 break;
963 
964             case BASEPROPERTY_EFFECTIVE_VALUE:
965             case BASEPROPERTY_VALUE_DOUBLE:
966                 aReturn = GetValue();
967                 break;
968 
969             case BASEPROPERTY_VALUESTEP_DOUBLE:
970                 aReturn <<= pField->GetSpinSize();
971                 break;
972 
973             case BASEPROPERTY_DECIMALACCURACY:
974                 aReturn <<= pField->GetDecimalDigits();
975                 break;
976 
977             case BASEPROPERTY_FORMATSSUPPLIER:
978             {
979                 if (!bIsStandardSupplier)
980                 {   // ansonsten void
981                     css::uno::Reference< css::util::XNumberFormatsSupplier >  xSupplier = m_xCurrentSupplier.get();
982                     aReturn <<= xSupplier;
983                 }
984             }
985             break;
986 
987             case BASEPROPERTY_FORMATKEY:
988             {
989                 if (!bIsStandardSupplier)
990                     aReturn <<= getFormatKey();
991             }
992             break;
993 
994             default:
995                 aReturn = VCLXSpinField::getProperty(PropertyName);
996         }
997     }
998     return aReturn;
999 }
1000 
convertEffectiveValue(const css::uno::Any & rValue)1001 css::uno::Any SVTXFormattedField::convertEffectiveValue(const css::uno::Any& rValue)
1002 {
1003     css::uno::Any aReturn;
1004 
1005     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1006     if (!pField)
1007         return aReturn;
1008 
1009     switch (rValue.getValueType().getTypeClass())
1010     {
1011         case css::uno::TypeClass_DOUBLE:
1012             if (pField->TreatingAsNumber())
1013             {
1014                 double d = 0.0;
1015                 rValue >>= d;
1016                 aReturn <<= d;
1017             }
1018             else
1019             {
1020                 SvNumberFormatter* pFormatter = pField->GetFormatter();
1021                 if (!pFormatter)
1022                     pFormatter = pField->StandardFormatter();
1023                     // should never fail
1024 
1025                 Color* pDum;
1026                 double d = 0.0;
1027                 rValue >>= d;
1028                 OUString sConverted;
1029                 pFormatter->GetOutputString(d, 0, sConverted, &pDum);
1030                 aReturn <<= sConverted;
1031             }
1032             break;
1033         case css::uno::TypeClass_STRING:
1034         {
1035             OUString aStr;
1036             rValue >>= aStr;
1037             if (pField->TreatingAsNumber())
1038             {
1039                 SvNumberFormatter* pFormatter = pField->GetFormatter();
1040                 if (!pFormatter)
1041                     pFormatter = pField->StandardFormatter();
1042 
1043                 double dVal;
1044                 sal_uInt32 nTestFormat(0);
1045                 if (!pFormatter->IsNumberFormat(aStr, nTestFormat, dVal))
1046                     aReturn.clear();
1047                 aReturn <<= dVal;
1048             }
1049             else
1050                 aReturn <<= aStr;
1051         }
1052         break;
1053         default:
1054             aReturn.clear();
1055             break;
1056     }
1057     return aReturn;
1058 }
1059 
1060 
SetMinValue(const css::uno::Any & rValue)1061 void SVTXFormattedField::SetMinValue(const css::uno::Any& rValue)
1062 {
1063     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1064     if (!pField)
1065         return;
1066 
1067     switch (rValue.getValueType().getTypeClass())
1068 
1069     {
1070         case css::uno::TypeClass_DOUBLE:
1071         {
1072             double d = 0.0;
1073             rValue >>= d;
1074             pField->SetMinValue(d);
1075         }
1076             break;
1077         default:
1078             DBG_ASSERT(rValue.getValueType().getTypeClass() == css::uno::TypeClass_VOID, "SVTXFormattedField::SetMinValue : invalid argument (an exception will be thrown) !");
1079             if ( rValue.getValueType().getTypeClass() != css::uno::TypeClass_VOID )
1080 
1081             {
1082                 throw css::lang::IllegalArgumentException();
1083             }
1084             pField->ClearMinValue();
1085             break;
1086     }
1087 }
1088 
1089 
GetMinValue() const1090 css::uno::Any SVTXFormattedField::GetMinValue() const
1091 {
1092     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1093     if (!pField || !pField->HasMinValue())
1094         return css::uno::Any();
1095 
1096     css::uno::Any aReturn;
1097     aReturn <<= pField->GetMinValue();
1098     return aReturn;
1099 }
1100 
1101 
SetMaxValue(const css::uno::Any & rValue)1102 void SVTXFormattedField::SetMaxValue(const css::uno::Any& rValue)
1103 {
1104     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1105     if (!pField)
1106         return;
1107 
1108     switch (rValue.getValueType().getTypeClass())
1109 
1110     {
1111         case css::uno::TypeClass_DOUBLE:
1112         {
1113             double d = 0.0;
1114             rValue >>= d;
1115             pField->SetMaxValue(d);
1116         }
1117             break;
1118         default:
1119             if (rValue.getValueType().getTypeClass() != css::uno::TypeClass_VOID)
1120 
1121             {
1122                 throw css::lang::IllegalArgumentException();
1123             }
1124             pField->ClearMaxValue();
1125             break;
1126     }
1127 }
1128 
1129 
GetMaxValue() const1130 css::uno::Any SVTXFormattedField::GetMaxValue() const
1131 {
1132     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1133     if (!pField || !pField->HasMaxValue())
1134         return css::uno::Any();
1135 
1136     css::uno::Any aReturn;
1137     aReturn <<= pField->GetMaxValue();
1138     return aReturn;
1139 }
1140 
1141 
SetDefaultValue(const css::uno::Any & rValue)1142 void SVTXFormattedField::SetDefaultValue(const css::uno::Any& rValue)
1143 {
1144     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1145     if (!pField)
1146         return;
1147 
1148     css::uno::Any aConverted = convertEffectiveValue(rValue);
1149 
1150     switch (aConverted.getValueType().getTypeClass())
1151 
1152     {
1153         case css::uno::TypeClass_DOUBLE:
1154         {
1155             double d = 0.0;
1156             aConverted >>= d;
1157             pField->SetDefaultValue(d);
1158         }
1159         break;
1160         case css::uno::TypeClass_STRING:
1161         {
1162             OUString aStr;
1163             aConverted >>= aStr;
1164             pField->SetDefaultText( aStr );
1165         }
1166         break;
1167         default:
1168             pField->EnableEmptyField(true);
1169                 // only void accepted
1170             break;
1171     }
1172 }
1173 
1174 
GetDefaultValue() const1175 css::uno::Any SVTXFormattedField::GetDefaultValue() const
1176 {
1177     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1178     if (!pField || pField->IsEmptyFieldEnabled())
1179         return css::uno::Any();
1180 
1181     css::uno::Any aReturn;
1182     if (pField->TreatingAsNumber())
1183         aReturn <<= pField->GetDefaultValue();
1184     else
1185         aReturn <<= pField->GetDefaultText();
1186     return aReturn;
1187 }
1188 
1189 
GetTreatAsNumber() const1190 bool SVTXFormattedField::GetTreatAsNumber() const
1191 {
1192     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1193     if (pField)
1194         return pField->TreatingAsNumber();
1195 
1196     return true;
1197 }
1198 
1199 
SetTreatAsNumber(bool bSet)1200 void SVTXFormattedField::SetTreatAsNumber(bool bSet)
1201 {
1202     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1203     if (pField)
1204         pField->TreatAsNumber(bSet);
1205 }
1206 
1207 
GetValue() const1208 css::uno::Any SVTXFormattedField::GetValue() const
1209 {
1210     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1211     if (!pField)
1212         return css::uno::Any();
1213 
1214     css::uno::Any aReturn;
1215     if (!pField->TreatingAsNumber())
1216     {
1217         OUString sText = pField->GetTextValue();
1218         aReturn <<= sText;
1219     }
1220     else
1221     {
1222         if (!pField->GetText().isEmpty())    // empty is returned as void by default
1223             aReturn <<= pField->GetValue();
1224     }
1225 
1226     return aReturn;
1227 }
1228 
1229 
SetValue(const css::uno::Any & rValue)1230 void SVTXFormattedField::SetValue(const css::uno::Any& rValue)
1231 {
1232     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1233     if (!pField)
1234         return;
1235 
1236     if (!rValue.hasValue())
1237     {
1238         pField->SetText("");
1239     }
1240     else
1241     {
1242         if (rValue.getValueType().getTypeClass() == css::uno::TypeClass_DOUBLE )
1243         {
1244             double d = 0.0;
1245             rValue >>= d;
1246             pField->SetValue(d);
1247         }
1248         else
1249         {
1250             DBG_ASSERT(rValue.getValueType().getTypeClass() == css::uno::TypeClass_STRING, "SVTXFormattedField::SetValue : invalid argument !");
1251 
1252             OUString sText;
1253             rValue >>= sText;
1254             if (!pField->TreatingAsNumber())
1255                 pField->SetTextFormatted(sText);
1256             else
1257                 pField->SetTextValue(sText);
1258         }
1259     }
1260 //  NotifyTextListeners();
1261 }
1262 
1263 
setFormatsSupplier(const css::uno::Reference<css::util::XNumberFormatsSupplier> & xSupplier)1264 void SVTXFormattedField::setFormatsSupplier(const css::uno::Reference< css::util::XNumberFormatsSupplier > & xSupplier)
1265 {
1266     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1267 
1268     SvNumberFormatsSupplierObj* pNew = nullptr;
1269     if (!xSupplier.is())
1270     {
1271         if (pField)
1272         {
1273             pNew = new SvNumberFormatsSupplierObj(pField->StandardFormatter());
1274             bIsStandardSupplier = true;
1275         }
1276     }
1277     else
1278     {
1279         pNew = comphelper::getUnoTunnelImplementation<SvNumberFormatsSupplierObj>(xSupplier);
1280         bIsStandardSupplier = false;
1281     }
1282 
1283     if (!pNew)
1284         return;     // TODO : how to process ?
1285 
1286     m_xCurrentSupplier = pNew;
1287     if (!pField)
1288         return;
1289 
1290     // save the actual value
1291     css::uno::Any aCurrent = GetValue();
1292     pField->SetFormatter(m_xCurrentSupplier->GetNumberFormatter(), false);
1293     if (nKeyToSetDelayed != -1)
1294     {
1295         pField->SetFormatKey(nKeyToSetDelayed);
1296         nKeyToSetDelayed = -1;
1297     }
1298     SetValue(aCurrent);
1299     NotifyTextListeners();
1300 }
1301 
1302 
getFormatKey() const1303 sal_Int32 SVTXFormattedField::getFormatKey() const
1304 {
1305     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1306     return pField ? pField->GetFormatKey() : 0;
1307 }
1308 
1309 
setFormatKey(sal_Int32 nKey)1310 void SVTXFormattedField::setFormatKey(sal_Int32 nKey)
1311 {
1312     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1313     if (!pField)
1314         return;
1315 
1316     if (pField->GetFormatter())
1317         pField->SetFormatKey(nKey);
1318     else
1319     {
1320         // probably I am in a block, in which first the key and next the formatter will be set,
1321         // initially this happens quite certain, as the properties are set in alphabetic sequence,
1322         // and the FormatsSupplier is processed before the FormatKey
1323         nKeyToSetDelayed = nKey;
1324     }
1325     NotifyTextListeners();
1326 }
1327 
1328 
NotifyTextListeners()1329 void SVTXFormattedField::NotifyTextListeners()
1330 {
1331     if ( GetTextListeners().getLength() )
1332     {
1333         css::awt::TextEvent aEvent;
1334         aEvent.Source = static_cast<cppu::OWeakObject*>(this);
1335         GetTextListeners().textChanged( aEvent );
1336     }
1337 }
1338 
ImplGetPropertyIds(std::vector<sal_uInt16> & rIds)1339 void SVTXFormattedField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
1340 {
1341     PushPropertyIds( rIds,
1342                      // FIXME: elide duplication ?
1343                      BASEPROPERTY_EFFECTIVE_MIN,
1344                      BASEPROPERTY_VALUEMIN_DOUBLE,
1345                      BASEPROPERTY_EFFECTIVE_MAX,
1346                      BASEPROPERTY_VALUEMAX_DOUBLE,
1347                      BASEPROPERTY_EFFECTIVE_DEFAULT,
1348                      BASEPROPERTY_TREATASNUMBER,
1349                      BASEPROPERTY_EFFECTIVE_VALUE,
1350                      BASEPROPERTY_VALUE_DOUBLE,
1351                      BASEPROPERTY_VALUESTEP_DOUBLE,
1352                      BASEPROPERTY_DECIMALACCURACY,
1353                      BASEPROPERTY_FORMATSSUPPLIER,
1354                      BASEPROPERTY_NUMSHOWTHOUSANDSEP,
1355                      BASEPROPERTY_FORMATKEY,
1356                      BASEPROPERTY_TREATASNUMBER,
1357                      BASEPROPERTY_ENFORCE_FORMAT,
1358                      0);
1359     VCLXWindow::ImplGetPropertyIds( rIds, true );
1360     VCLXSpinField::ImplGetPropertyIds( rIds );
1361 }
1362 
1363 
1364 //  class SVTXNumericField
1365 
SVTXNumericField()1366 SVTXNumericField::SVTXNumericField()
1367 {
1368 }
1369 
~SVTXNumericField()1370 SVTXNumericField::~SVTXNumericField()
1371 {
1372 }
1373 
queryInterface(const css::uno::Type & rType)1374 css::uno::Any SVTXNumericField::queryInterface( const css::uno::Type & rType )
1375 {
1376     css::uno::Any aRet = ::cppu::queryInterface( rType,
1377                                         static_cast< css::awt::XNumericField* >(this),
1378                                         static_cast< css::lang::XTypeProvider* >(this) );
1379     return (aRet.hasValue() ? aRet : SVTXFormattedField::queryInterface( rType ));
1380 }
1381 
IMPL_IMPLEMENTATION_ID(SVTXNumericField)1382 IMPL_IMPLEMENTATION_ID( SVTXNumericField )
1383 
1384 // css::lang::XTypeProvider
1385 css::uno::Sequence< css::uno::Type > SVTXNumericField::getTypes()
1386 {
1387     static const ::cppu::OTypeCollection aTypeList(
1388         cppu::UnoType<css::lang::XTypeProvider>::get(),
1389         cppu::UnoType<css::awt::XNumericField>::get(),
1390         SVTXFormattedField::getTypes()
1391     );
1392     return aTypeList.getTypes();
1393 }
1394 
1395 
setValue(double Value)1396 void SVTXNumericField::setValue( double Value )
1397 {
1398     SolarMutexGuard aGuard;
1399 
1400     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1401     if ( pField )
1402         pField->SetValue( Value );
1403 }
1404 
getValue()1405 double SVTXNumericField::getValue()
1406 {
1407     SolarMutexGuard aGuard;
1408 
1409     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1410     return pField ? pField->GetValue() : 0;
1411 }
1412 
setMin(double Value)1413 void SVTXNumericField::setMin( double Value )
1414 {
1415     SolarMutexGuard aGuard;
1416 
1417     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1418     if ( pField )
1419         pField->SetMinValue( Value );
1420 }
1421 
getMin()1422 double SVTXNumericField::getMin()
1423 {
1424     SolarMutexGuard aGuard;
1425 
1426     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1427     return pField ? pField->GetMinValue() : 0;
1428 }
1429 
setMax(double Value)1430 void SVTXNumericField::setMax( double Value )
1431 {
1432     SolarMutexGuard aGuard;
1433 
1434     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1435     if ( pField )
1436         pField->SetMaxValue( Value );
1437 }
1438 
getMax()1439 double SVTXNumericField::getMax()
1440 {
1441     SolarMutexGuard aGuard;
1442 
1443     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1444     return pField ? pField->GetMaxValue() : 0;
1445 }
1446 
setFirst(double Value)1447 void SVTXNumericField::setFirst( double Value )
1448 {
1449     SolarMutexGuard aGuard;
1450 
1451     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1452     if ( pField )
1453         pField->SetSpinFirst( Value );
1454 }
1455 
getFirst()1456 double SVTXNumericField::getFirst()
1457 {
1458     SolarMutexGuard aGuard;
1459 
1460     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1461     return pField ? pField->GetSpinFirst() : 0;
1462 }
1463 
setLast(double Value)1464 void SVTXNumericField::setLast( double Value )
1465 {
1466     SolarMutexGuard aGuard;
1467 
1468     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1469     if ( pField )
1470         pField->SetSpinLast( Value );
1471 }
1472 
getLast()1473 double SVTXNumericField::getLast()
1474 {
1475     SolarMutexGuard aGuard;
1476 
1477     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1478     return pField ? pField->GetSpinLast() : 0;
1479 }
1480 
setSpinSize(double Value)1481 void SVTXNumericField::setSpinSize( double Value )
1482 {
1483     SolarMutexGuard aGuard;
1484 
1485     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1486     if ( pField )
1487         pField->SetSpinSize( Value );
1488 }
1489 
getSpinSize()1490 double SVTXNumericField::getSpinSize()
1491 {
1492     SolarMutexGuard aGuard;
1493 
1494     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1495     return pField ? pField->GetSpinSize() : 0;
1496 }
1497 
setDecimalDigits(sal_Int16 Value)1498 void SVTXNumericField::setDecimalDigits( sal_Int16 Value )
1499 {
1500     SolarMutexGuard aGuard;
1501 
1502     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1503     if ( pField )
1504         pField->SetDecimalDigits( Value );
1505 }
1506 
getDecimalDigits()1507 sal_Int16 SVTXNumericField::getDecimalDigits()
1508 {
1509     SolarMutexGuard aGuard;
1510 
1511     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1512     return pField ? pField->GetDecimalDigits() : 0;
1513 }
1514 
setStrictFormat(sal_Bool bStrict)1515 void SVTXNumericField::setStrictFormat( sal_Bool bStrict )
1516 {
1517     SolarMutexGuard aGuard;
1518 
1519     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1520     if ( pField )
1521         pField->SetStrictFormat( bStrict );
1522 }
1523 
isStrictFormat()1524 sal_Bool SVTXNumericField::isStrictFormat()
1525 {
1526     SolarMutexGuard aGuard;
1527 
1528     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1529     return pField && pField->IsStrictFormat();
1530 }
1531 
GetPropertyIds(std::vector<sal_uInt16> & rIds)1532 void SVTXNumericField::GetPropertyIds( std::vector< sal_uInt16 > &rIds )
1533 {
1534     SVTXFormattedField::ImplGetPropertyIds( rIds );
1535 }
1536 
1537 
1538 //  class SVTXCurrencyField
1539 
SVTXCurrencyField()1540 SVTXCurrencyField::SVTXCurrencyField()
1541 {
1542 }
1543 
~SVTXCurrencyField()1544 SVTXCurrencyField::~SVTXCurrencyField()
1545 {
1546 }
1547 
queryInterface(const css::uno::Type & rType)1548 css::uno::Any SVTXCurrencyField::queryInterface( const css::uno::Type & rType )
1549 {
1550     css::uno::Any aRet = ::cppu::queryInterface( rType,
1551                                         static_cast< css::awt::XCurrencyField* >(this),
1552                                         static_cast< css::lang::XTypeProvider* >(this) );
1553     return (aRet.hasValue() ? aRet : SVTXFormattedField::queryInterface( rType ));
1554 }
1555 
IMPL_IMPLEMENTATION_ID(SVTXCurrencyField)1556 IMPL_IMPLEMENTATION_ID( SVTXCurrencyField )
1557 
1558 // css::lang::XTypeProvider
1559 css::uno::Sequence< css::uno::Type > SVTXCurrencyField::getTypes()
1560 {
1561     static const ::cppu::OTypeCollection aTypeList(
1562         cppu::UnoType<css::lang::XTypeProvider>::get(),
1563         cppu::UnoType<css::awt::XCurrencyField>::get(),
1564         SVTXFormattedField::getTypes()
1565     );
1566     return aTypeList.getTypes();
1567 }
1568 
setValue(double Value)1569 void SVTXCurrencyField::setValue( double Value )
1570 {
1571     SolarMutexGuard aGuard;
1572 
1573     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1574     if ( pField )
1575         pField->SetValue( Value );
1576 }
1577 
getValue()1578 double SVTXCurrencyField::getValue()
1579 {
1580     SolarMutexGuard aGuard;
1581 
1582     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1583     return pField ? pField->GetValue() : 0;
1584 }
1585 
setMin(double Value)1586 void SVTXCurrencyField::setMin( double Value )
1587 {
1588     SolarMutexGuard aGuard;
1589 
1590     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1591     if ( pField )
1592         pField->SetMinValue( Value );
1593 }
1594 
getMin()1595 double SVTXCurrencyField::getMin()
1596 {
1597     SolarMutexGuard aGuard;
1598 
1599     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1600     return pField ? pField->GetMinValue() : 0;
1601 }
1602 
setMax(double Value)1603 void SVTXCurrencyField::setMax( double Value )
1604 {
1605     SolarMutexGuard aGuard;
1606 
1607     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1608     if ( pField )
1609         pField->SetMaxValue( Value );
1610 }
1611 
getMax()1612 double SVTXCurrencyField::getMax()
1613 {
1614     SolarMutexGuard aGuard;
1615 
1616     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1617     return pField ? pField->GetMaxValue() : 0;
1618 }
1619 
setFirst(double Value)1620 void SVTXCurrencyField::setFirst( double Value )
1621 {
1622     SolarMutexGuard aGuard;
1623 
1624     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1625     if ( pField )
1626         pField->SetSpinFirst( Value );
1627 }
1628 
getFirst()1629 double SVTXCurrencyField::getFirst()
1630 {
1631     SolarMutexGuard aGuard;
1632 
1633     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1634     return pField ? pField->GetSpinFirst() : 0;
1635 }
1636 
setLast(double Value)1637 void SVTXCurrencyField::setLast( double Value )
1638 {
1639     SolarMutexGuard aGuard;
1640 
1641     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1642     if ( pField )
1643         pField->SetSpinLast( Value );
1644 }
1645 
getLast()1646 double SVTXCurrencyField::getLast()
1647 {
1648     SolarMutexGuard aGuard;
1649 
1650     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1651     return pField ? pField->GetSpinLast() : 0;
1652 }
1653 
setSpinSize(double Value)1654 void SVTXCurrencyField::setSpinSize( double Value )
1655 {
1656     SolarMutexGuard aGuard;
1657 
1658     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1659     if ( pField )
1660         pField->SetSpinSize( Value );
1661 }
1662 
getSpinSize()1663 double SVTXCurrencyField::getSpinSize()
1664 {
1665     SolarMutexGuard aGuard;
1666 
1667     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1668     return pField ? pField->GetSpinSize() : 0;
1669 }
1670 
setDecimalDigits(sal_Int16 Value)1671 void SVTXCurrencyField::setDecimalDigits( sal_Int16 Value )
1672 {
1673     SolarMutexGuard aGuard;
1674 
1675     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1676     if ( pField )
1677         pField->SetDecimalDigits( Value );
1678 }
1679 
getDecimalDigits()1680 sal_Int16 SVTXCurrencyField::getDecimalDigits()
1681 {
1682     SolarMutexGuard aGuard;
1683 
1684     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1685     return pField ? pField->GetDecimalDigits() : 0;
1686 }
1687 
setStrictFormat(sal_Bool bStrict)1688 void SVTXCurrencyField::setStrictFormat( sal_Bool bStrict )
1689 {
1690     SolarMutexGuard aGuard;
1691 
1692     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1693     if ( pField )
1694         pField->SetStrictFormat( bStrict );
1695 }
1696 
isStrictFormat()1697 sal_Bool SVTXCurrencyField::isStrictFormat()
1698 {
1699     SolarMutexGuard aGuard;
1700 
1701     VclPtr<FormattedField> pField = GetAs< FormattedField >();
1702     return pField && pField->IsStrictFormat();
1703 }
1704 
setProperty(const OUString & PropertyName,const css::uno::Any & Value)1705 void SVTXCurrencyField::setProperty( const OUString& PropertyName, const css::uno::Any& Value)
1706 {
1707     SolarMutexGuard aGuard;
1708 
1709     VclPtr< DoubleCurrencyField > pField = GetAs< DoubleCurrencyField >();
1710     if ( pField )
1711     {
1712         sal_uInt16 nPropType = GetPropertyId( PropertyName );
1713         switch (nPropType)
1714         {
1715             case BASEPROPERTY_CURRENCYSYMBOL:
1716             {
1717                 OUString aStr;
1718                 Value >>= aStr;
1719                 pField->setCurrencySymbol( aStr );
1720             }
1721             break;
1722             case BASEPROPERTY_CURSYM_POSITION:
1723             {
1724                 bool b = false;
1725                 Value >>= b;
1726                 pField->setPrependCurrSym(b);
1727             }
1728             break;
1729 
1730             default:
1731                 SVTXFormattedField::setProperty(PropertyName, Value);
1732         }
1733     }
1734     else
1735         SVTXFormattedField::setProperty(PropertyName, Value);
1736 }
1737 
getProperty(const OUString & PropertyName)1738 css::uno::Any SVTXCurrencyField::getProperty( const OUString& PropertyName )
1739 {
1740     SolarMutexGuard aGuard;
1741 
1742     css::uno::Any aReturn;
1743 
1744     VclPtr< DoubleCurrencyField > pField = GetAs< DoubleCurrencyField >();
1745     if ( pField )
1746     {
1747         sal_uInt16 nPropType = GetPropertyId( PropertyName );
1748         switch (nPropType)
1749         {
1750             case BASEPROPERTY_CURRENCYSYMBOL:
1751             {
1752                 aReturn <<= pField->getCurrencySymbol();
1753             }
1754             break;
1755             case BASEPROPERTY_CURSYM_POSITION:
1756             {
1757                 aReturn <<= pField->getPrependCurrSym();
1758             }
1759             break;
1760             default:
1761                 return SVTXFormattedField::getProperty(PropertyName);
1762         }
1763     }
1764     return SVTXFormattedField::getProperty(PropertyName);
1765 }
1766 
ImplGetPropertyIds(std::vector<sal_uInt16> & rIds)1767 void SVTXCurrencyField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
1768 {
1769     PushPropertyIds( rIds,
1770                      BASEPROPERTY_CURRENCYSYMBOL,
1771                      BASEPROPERTY_CURSYM_POSITION,
1772                      0);
1773     SVTXFormattedField::ImplGetPropertyIds( rIds );
1774 }
1775 
1776 
1777 //  class SVTXDateField
1778 
SVTXDateField()1779 SVTXDateField::SVTXDateField()
1780     :VCLXDateField()
1781 {
1782 }
1783 
~SVTXDateField()1784 SVTXDateField::~SVTXDateField()
1785 {
1786 }
1787 
setProperty(const OUString & PropertyName,const css::uno::Any & Value)1788 void SAL_CALL SVTXDateField::setProperty( const OUString& PropertyName, const css::uno::Any& Value )
1789 {
1790     VCLXDateField::setProperty( PropertyName, Value );
1791 
1792     // some properties need to be forwarded to the sub edit, too
1793     SolarMutexGuard g;
1794     VclPtr< Edit > pSubEdit = GetWindow() ? static_cast< Edit* >( GetWindow().get() )->GetSubEdit() : nullptr;
1795     if ( !pSubEdit )
1796         return;
1797 
1798     switch ( GetPropertyId( PropertyName ) )
1799     {
1800     case BASEPROPERTY_TEXTLINECOLOR:
1801         if ( !Value.hasValue() )
1802             pSubEdit->SetTextLineColor();
1803         else
1804         {
1805             sal_Int32 nColor = 0;
1806             if ( Value >>= nColor )
1807                 pSubEdit->SetTextLineColor( Color( nColor ) );
1808         }
1809         break;
1810     }
1811 }
1812 
ImplGetPropertyIds(std::vector<sal_uInt16> & rIds)1813 void SVTXDateField::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
1814 {
1815     PushPropertyIds( rIds,
1816                      BASEPROPERTY_TEXTLINECOLOR,
1817                      0);
1818     VCLXDateField::ImplGetPropertyIds( rIds );
1819 }
1820 
1821 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1822