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 <sal/config.h>
21 #include <sal/log.hxx>
22 
23 #include <cassert>
24 
25 #include <dlged.hxx>
26 #include <dlgeddef.hxx>
27 #include <dlgedlist.hxx>
28 #include <dlgedobj.hxx>
29 #include <dlgedpage.hxx>
30 #include <dlgedview.hxx>
31 #include <localizationmgr.hxx>
32 #include <strings.hxx>
33 
34 #include <com/sun/star/beans/NamedValue.hpp>
35 #include <com/sun/star/form/binding/XBindableValue.hpp>
36 #include <com/sun/star/form/binding/XValueBinding.hpp>
37 #include <com/sun/star/form/binding/XListEntrySink.hpp>
38 #include <com/sun/star/awt/XUnoControlContainer.hpp>
39 #include <com/sun/star/awt/XVclContainerPeer.hpp>
40 #include <com/sun/star/container/XContainer.hpp>
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
43 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
44 #include <com/sun/star/table/CellAddress.hpp>
45 #include <cppuhelper/exc_hlp.hxx>
46 #include <o3tl/functional.hxx>
47 #include <svx/svdpagv.hxx>
48 #include <unotools/sharedunocomponent.hxx>
49 #include <vcl/svapp.hxx>
50 #include <tools/debug.hxx>
51 
52 namespace basctl
53 {
54 
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::container;
59 using namespace ::com::sun::star::script;
60 
61 
GetDialogEditor()62 DlgEditor& DlgEdObj::GetDialogEditor ()
63 {
64     if (DlgEdForm* pFormThis = dynamic_cast<DlgEdForm*>(this))
65         return pFormThis->GetDlgEditor();
66     else
67         return pDlgEdForm->GetDlgEditor();
68 }
69 
DlgEdObj(SdrModel & rSdrModel)70 DlgEdObj::DlgEdObj(SdrModel& rSdrModel)
71 :   SdrUnoObj(rSdrModel, OUString())
72     ,bIsListening(false)
73     ,pDlgEdForm( nullptr )
74 {
75 }
76 
DlgEdObj(SdrModel & rSdrModel,DlgEdObj const & rSource)77 DlgEdObj::DlgEdObj(SdrModel& rSdrModel, DlgEdObj const & rSource)
78 :   SdrUnoObj(rSdrModel, rSource)
79     ,bIsListening(false)
80 {
81     // set parent form
82     pDlgEdForm = rSource.pDlgEdForm;
83 
84     // add child to parent form
85     pDlgEdForm->AddChild( this );
86 
87     Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
88     if ( xPSet.is() )
89     {
90         // set new name
91         OUString aOUniqueName( GetUniqueName() );
92         Any aUniqueName;
93         aUniqueName <<= aOUniqueName;
94         xPSet->setPropertyValue( DLGED_PROP_NAME, aUniqueName );
95 
96         Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
97         if ( xCont.is() )
98         {
99             // set tabindex
100             Sequence< OUString > aNames = xCont->getElementNames();
101             xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(aNames.getLength())) );
102 
103             // insert control model in dialog model
104             Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
105             xCont->insertByName( aOUniqueName, Any(xCtrl) );
106 
107             pDlgEdForm->UpdateTabOrderAndGroups();
108         }
109     }
110 
111     // start listening
112     StartListening();
113 }
114 
DlgEdObj(SdrModel & rSdrModel,const OUString & rModelName,const css::uno::Reference<css::lang::XMultiServiceFactory> & rxSFac)115 DlgEdObj::DlgEdObj(
116     SdrModel& rSdrModel,
117     const OUString& rModelName,
118     const css::uno::Reference< css::lang::XMultiServiceFactory >& rxSFac)
119 :   SdrUnoObj(rSdrModel, rModelName, rxSFac)
120     ,bIsListening(false)
121     ,pDlgEdForm( nullptr )
122 {
123 }
124 
~DlgEdObj()125 DlgEdObj::~DlgEdObj()
126 {
127     if ( isListening() )
128         EndListening(true);
129 }
130 
131 namespace
132 {
133     /* returns the DlgEdForm which the given DlgEdObj belongs to
134         (which might in fact be the object itself)
135 
136         Failure to obtain the form will be reported with an assertion in the non-product
137         version.
138      */
lcl_getDlgEdForm(DlgEdObj * _pObject,DlgEdForm * & _out_pDlgEdForm)139     bool lcl_getDlgEdForm( DlgEdObj* _pObject, DlgEdForm*& _out_pDlgEdForm )
140     {
141         _out_pDlgEdForm = dynamic_cast< DlgEdForm* >( _pObject );
142         if ( !_out_pDlgEdForm )
143             _out_pDlgEdForm = _pObject->GetDlgEdForm();
144         DBG_ASSERT( _out_pDlgEdForm, "lcl_getDlgEdForm: no form!" );
145         return ( _out_pDlgEdForm != nullptr );
146     }
147 }
148 
GetControl() const149 uno::Reference< awt::XControl > DlgEdObj::GetControl() const
150 {
151     uno::Reference< awt::XControl > xControl;
152     if (DlgEdForm const* pForm = GetDlgEdForm())
153     {
154         DlgEditor const& rEditor = pForm->GetDlgEditor();
155         xControl = GetUnoControl(rEditor.GetView(), *rEditor.GetWindow().GetOutDev());
156     }
157     return xControl;
158 }
159 
TransformSdrToControlCoordinates(sal_Int32 nXIn,sal_Int32 nYIn,sal_Int32 nWidthIn,sal_Int32 nHeightIn,sal_Int32 & nXOut,sal_Int32 & nYOut,sal_Int32 & nWidthOut,sal_Int32 & nHeightOut)160 bool DlgEdObj::TransformSdrToControlCoordinates(
161     sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
162     sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
163 {
164     // input position and size
165     Size aPos( nXIn, nYIn );
166     Size aSize( nWidthIn, nHeightIn );
167 
168     // form position
169     DlgEdForm* pForm = nullptr;
170     if ( !lcl_getDlgEdForm( this, pForm ) )
171         return false;
172     tools::Rectangle aFormRect = pForm->GetSnapRect();
173     Size aFormPos( aFormRect.Left(), aFormRect.Top() );
174 
175     // convert 100th_mm to pixel
176     OutputDevice* pDevice = Application::GetDefaultDevice();
177     DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToControlCoordinates: missing default device!" );
178     if ( !pDevice )
179         return false;
180     aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
181     aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
182     aFormPos = pDevice->LogicToPixel( aFormPos, MapMode( MapUnit::Map100thMM ) );
183 
184     // subtract form position
185     aPos.AdjustWidth( -(aFormPos.Width()) );
186     aPos.AdjustHeight( -(aFormPos.Height()) );
187 
188     // take window borders into account
189     Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
190     DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
191     if ( !xPSetForm.is() )
192         return false;
193     bool bDecoration = true;
194     xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
195     if( bDecoration )
196     {
197         awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
198         aPos.AdjustWidth( -(aDeviceInfo.LeftInset) );
199         aPos.AdjustHeight( -(aDeviceInfo.TopInset) );
200     }
201 
202     // convert pixel to logic units
203     aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
204     aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
205 
206     // set out parameters
207     nXOut = aPos.Width();
208     nYOut = aPos.Height();
209     nWidthOut = aSize.Width();
210     nHeightOut = aSize.Height();
211 
212     return true;
213 }
214 
TransformSdrToFormCoordinates(sal_Int32 nXIn,sal_Int32 nYIn,sal_Int32 nWidthIn,sal_Int32 nHeightIn,sal_Int32 & nXOut,sal_Int32 & nYOut,sal_Int32 & nWidthOut,sal_Int32 & nHeightOut)215 bool DlgEdObj::TransformSdrToFormCoordinates(
216     sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
217     sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
218 {
219     // input position and size
220     Size aPos( nXIn, nYIn );
221     Size aSize( nWidthIn, nHeightIn );
222 
223     // convert 100th_mm to pixel
224     OutputDevice* pDevice = Application::GetDefaultDevice();
225     DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToFormCoordinates: missing default device!" );
226     if ( !pDevice )
227         return false;
228     aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
229     aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
230 
231     // take window borders into account
232     DlgEdForm* pForm = nullptr;
233     if ( !lcl_getDlgEdForm( this, pForm ) )
234         return false;
235 
236     // take window borders into account
237     Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
238     DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
239     if ( !xPSetForm.is() )
240         return false;
241     bool bDecoration = true;
242     xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
243     if( bDecoration )
244     {
245         awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
246         aSize.AdjustWidth( -(aDeviceInfo.LeftInset + aDeviceInfo.RightInset) );
247         aSize.AdjustHeight( -(aDeviceInfo.TopInset + aDeviceInfo.BottomInset) );
248     }
249     // convert pixel to logic units
250     aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
251     aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
252 
253     // set out parameters
254     nXOut = aPos.Width();
255     nYOut = aPos.Height();
256     nWidthOut = aSize.Width();
257     nHeightOut = aSize.Height();
258 
259     return true;
260 }
261 
TransformControlToSdrCoordinates(sal_Int32 nXIn,sal_Int32 nYIn,sal_Int32 nWidthIn,sal_Int32 nHeightIn,sal_Int32 & nXOut,sal_Int32 & nYOut,sal_Int32 & nWidthOut,sal_Int32 & nHeightOut)262 bool DlgEdObj::TransformControlToSdrCoordinates(
263     sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
264     sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
265 {
266     // input position and size
267     Size aPos( nXIn, nYIn );
268     Size aSize( nWidthIn, nHeightIn );
269 
270     // form position
271     DlgEdForm* pForm = nullptr;
272     if ( !lcl_getDlgEdForm( this, pForm ) )
273         return false;
274 
275     Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
276     DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformControlToSdrCoordinates: no form property set!" );
277     if ( !xPSetForm.is() )
278         return false;
279     sal_Int32 nFormX = 0, nFormY = 0;
280     xPSetForm->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nFormX;
281     xPSetForm->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nFormY;
282     Size aFormPos( nFormX, nFormY );
283 
284     // convert logic units to pixel
285     OutputDevice* pDevice = Application::GetDefaultDevice();
286     DBG_ASSERT( pDevice, "DlgEdObj::TransformControlToSdrCoordinates: missing default device!" );
287     if ( !pDevice )
288         return false;
289     aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
290     aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
291     aFormPos = pDevice->LogicToPixel(aFormPos, MapMode(MapUnit::MapAppFont));
292 
293     // add form position
294     aPos.AdjustWidth(aFormPos.Width() );
295     aPos.AdjustHeight(aFormPos.Height() );
296 
297     // take window borders into account
298     bool bDecoration = true;
299     xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
300     if( bDecoration )
301     {
302         awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
303         aPos.AdjustWidth(aDeviceInfo.LeftInset );
304         aPos.AdjustHeight(aDeviceInfo.TopInset );
305     }
306 
307     // convert pixel to 100th_mm
308     aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
309     aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
310 
311     // set out parameters
312     nXOut = aPos.Width();
313     nYOut = aPos.Height();
314     nWidthOut = aSize.Width();
315     nHeightOut = aSize.Height();
316 
317     return true;
318 }
319 
TransformFormToSdrCoordinates(sal_Int32 nXIn,sal_Int32 nYIn,sal_Int32 nWidthIn,sal_Int32 nHeightIn,sal_Int32 & nXOut,sal_Int32 & nYOut,sal_Int32 & nWidthOut,sal_Int32 & nHeightOut)320 bool DlgEdObj::TransformFormToSdrCoordinates(
321     sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
322     sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
323 {
324     // input position and size
325     Size aPos( nXIn, nYIn );
326     Size aSize( nWidthIn, nHeightIn );
327 
328     // convert logic units to pixel
329     OutputDevice* pDevice = Application::GetDefaultDevice();
330     DBG_ASSERT( pDevice, "DlgEdObj::TransformFormToSdrCoordinates: missing default device!" );
331     if ( !pDevice )
332         return false;
333 
334     // take window borders into account
335     DlgEdForm* pForm = nullptr;
336     if ( !lcl_getDlgEdForm( this, pForm ) )
337         return false;
338 
339     aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
340     aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
341 
342     // take window borders into account
343     Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
344     DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
345     if ( !xPSetForm.is() )
346         return false;
347     bool bDecoration = true;
348     xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
349     if( bDecoration )
350     {
351         awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
352         aSize.AdjustWidth(aDeviceInfo.LeftInset + aDeviceInfo.RightInset );
353         aSize.AdjustHeight(aDeviceInfo.TopInset + aDeviceInfo.BottomInset );
354     }
355 
356     // convert pixel to 100th_mm
357     aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
358     aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
359 
360     // set out parameters
361     nXOut = aPos.Width();
362     nYOut = aPos.Height();
363     nWidthOut = aSize.Width();
364     nHeightOut = aSize.Height();
365 
366     return true;
367 }
368 
SetRectFromProps()369 void DlgEdObj::SetRectFromProps()
370 {
371     // get control position and size from properties
372     Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
373     if ( !xPSet.is() )
374         return;
375 
376     sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
377     xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
378     xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
379     xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
380     xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
381 
382     // transform coordinates
383     sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
384     if ( TransformControlToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
385     {
386         // set rectangle position and size
387         Point aPoint( nXOut, nYOut );
388         Size aSize( nWidthOut, nHeightOut );
389         SetSnapRect( tools::Rectangle( aPoint, aSize ) );
390     }
391 }
392 
SetPropsFromRect()393 void DlgEdObj::SetPropsFromRect()
394 {
395     // get control position and size from rectangle
396     tools::Rectangle aRect_ = GetSnapRect();
397     sal_Int32 nXIn = aRect_.Left();
398     sal_Int32 nYIn = aRect_.Top();
399     sal_Int32 nWidthIn = aRect_.GetWidth();
400     sal_Int32 nHeightIn = aRect_.GetHeight();
401 
402     // transform coordinates
403     sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
404     if ( TransformSdrToControlCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
405     {
406         // set properties
407         Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
408         if ( xPSet.is() )
409         {
410             xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
411             xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
412             xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
413             xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
414         }
415     }
416 }
417 
PositionAndSizeChange(const beans::PropertyChangeEvent & evt)418 void DlgEdObj::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
419 {
420     DBG_ASSERT( pDlgEdForm, "DlgEdObj::PositionAndSizeChange: no form!" );
421     DlgEdPage& rPage = pDlgEdForm->GetDlgEditor().GetPage();
422     {
423         Size aPageSize = rPage.GetSize();
424         sal_Int32 nPageWidthIn = aPageSize.Width();
425         sal_Int32 nPageHeightIn = aPageSize.Height();
426         sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
427         if ( TransformSdrToControlCoordinates( 0/*nPageXIn*/, 0/*nPageYIn*/, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
428         {
429             Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
430             if ( xPSet.is() )
431             {
432                 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
433                 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
434                 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
435                 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
436                 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
437 
438                 sal_Int32 nValue = 0;
439                 evt.NewValue >>= nValue;
440                 sal_Int32 nNewValue = nValue;
441 
442                 if ( evt.PropertyName == DLGED_PROP_POSITIONX )
443                 {
444                     if ( nNewValue + nWidth > nPageX + nPageWidth )
445                         nNewValue = nPageX + nPageWidth - nWidth;
446                     if ( nNewValue < nPageX )
447                         nNewValue = nPageX;
448                 }
449                 else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
450                 {
451                     if ( nNewValue + nHeight > nPageY + nPageHeight )
452                         nNewValue = nPageY + nPageHeight - nHeight;
453                     if ( nNewValue < nPageY )
454                         nNewValue = nPageY;
455                 }
456                 else if ( evt.PropertyName == DLGED_PROP_WIDTH )
457                 {
458                     if ( nX + nNewValue > nPageX + nPageWidth )
459                         nNewValue = nPageX + nPageWidth - nX;
460                     if ( nNewValue < 1 )
461                         nNewValue = 1;
462                 }
463                 else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
464                 {
465                     if ( nY + nNewValue > nPageY + nPageHeight )
466                         nNewValue = nPageY + nPageHeight - nY;
467                     if ( nNewValue < 1 )
468                         nNewValue = 1;
469                 }
470 
471                 if ( nNewValue != nValue )
472                 {
473                     EndListening( false );
474                     xPSet->setPropertyValue( evt.PropertyName, Any(nNewValue) );
475                     StartListening();
476                 }
477             }
478         }
479     }
480 
481     SetRectFromProps();
482 }
483 
NameChange(const css::beans::PropertyChangeEvent & evt)484 void DlgEdObj::NameChange( const  css::beans::PropertyChangeEvent& evt )
485 {
486     // get old name
487     OUString aOldName;
488     evt.OldValue >>= aOldName;
489 
490     // get new name
491     OUString aNewName;
492     evt.NewValue >>= aNewName;
493 
494     if ( aNewName == aOldName )
495         return;
496 
497     Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), UNO_QUERY);
498     if ( !(xNameAcc.is() && xNameAcc->hasByName(aOldName)) )
499         return;
500 
501     if (!xNameAcc->hasByName(aNewName) && !aNewName.isEmpty())
502     {
503         // remove the control by the old name and insert the control by the new name in the container
504         Reference< container::XNameContainer > xCont(xNameAcc, UNO_QUERY );
505         if ( xCont.is() )
506         {
507             Reference< awt::XControlModel > xCtrl = GetUnoControlModel();
508             Any aAny;
509             aAny <<= xCtrl;
510             xCont->removeByName( aOldName );
511             xCont->insertByName( aNewName , aAny );
512 
513             LocalizationMgr::renameControlResourceIDsForEditorObject(
514                 &GetDialogEditor(), aAny, aNewName
515             );
516         }
517     }
518     else
519     {
520         // set old name property
521         EndListening(false);
522         Reference< beans::XPropertySet >  xPSet(GetUnoControlModel(), UNO_QUERY);
523         xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOldName) );
524         StartListening();
525     }
526 }
527 
GetStep() const528 sal_Int32 DlgEdObj::GetStep() const
529 {
530     // get step property
531     sal_Int32 nStep = 0;
532     uno::Reference< beans::XPropertySet >  xPSet( GetUnoControlModel(), uno::UNO_QUERY );
533     if (xPSet.is())
534     {
535         xPSet->getPropertyValue( DLGED_PROP_STEP ) >>= nStep;
536     }
537     return nStep;
538 }
539 
UpdateStep()540 void DlgEdObj::UpdateStep()
541 {
542     sal_Int32 nCurStep = GetDlgEdForm()->GetStep();
543     sal_Int32 nStep = GetStep();
544 
545     SdrLayerAdmin& rLayerAdmin(getSdrModelFromSdrObject().GetLayerAdmin());
546     SdrLayerID nHiddenLayerId   = rLayerAdmin.GetLayerID( "HiddenLayer" );
547     SdrLayerID nControlLayerId   = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName() );
548 
549     if( nCurStep )
550     {
551         if ( nStep && (nStep != nCurStep) )
552         {
553             SetLayer( nHiddenLayerId );
554         }
555         else
556         {
557             SetLayer( nControlLayerId );
558         }
559     }
560     else
561     {
562         SetLayer( nControlLayerId );
563     }
564 }
565 
TabIndexChange(const beans::PropertyChangeEvent & evt)566 void DlgEdObj::TabIndexChange( const beans::PropertyChangeEvent& evt )
567 {
568     DlgEdForm* pForm = GetDlgEdForm();
569     if ( !pForm )
570         return;
571 
572     // stop listening with all children
573     std::vector<DlgEdObj*> aChildList = pForm->GetChildren();
574     for (auto const& child : aChildList)
575     {
576         child->EndListening( false );
577     }
578 
579     Reference< container::XNameAccess > xNameAcc( pForm->GetUnoControlModel() , UNO_QUERY );
580     if ( xNameAcc.is() )
581     {
582         // get sequence of control names
583         Sequence< OUString > aNames = xNameAcc->getElementNames();
584         const OUString* pNames = aNames.getConstArray();
585         sal_Int32 nCtrls = aNames.getLength();
586 
587         // create a map of tab indices and control names, sorted by tab index
588         IndexToNameMap aIndexToNameMap;
589         for ( sal_Int32 i = 0; i < nCtrls; ++i )
590         {
591             // get control name
592             OUString aName( pNames[i] );
593 
594             // get tab index
595             sal_Int16 nTabIndex = -1;
596             Any aCtrl = xNameAcc->getByName( aName );
597             Reference< beans::XPropertySet > xPSet;
598             aCtrl >>= xPSet;
599             if ( xPSet.is() && xPSet == Reference< beans::XPropertySet >( evt.Source, UNO_QUERY ) )
600                 evt.OldValue >>= nTabIndex;
601             else if ( xPSet.is() )
602                 xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
603 
604             // insert into map
605             aIndexToNameMap.emplace( nTabIndex, aName );
606         }
607 
608         // create a helper list of control names, sorted by tab index
609         std::vector< OUString > aNameList( aIndexToNameMap.size() );
610         std::transform(
611                 aIndexToNameMap.begin(), aIndexToNameMap.end(),
612                 aNameList.begin(),
613                 ::o3tl::select2nd< IndexToNameMap::value_type >( )
614             );
615 
616         // check tab index
617         sal_Int16 nOldTabIndex = 0;
618         evt.OldValue >>= nOldTabIndex;
619         sal_Int16 nNewTabIndex = 0;
620         evt.NewValue >>= nNewTabIndex;
621         if ( nNewTabIndex < 0 )
622             nNewTabIndex = 0;
623         else if ( nNewTabIndex > nCtrls - 1 )
624             nNewTabIndex = sal::static_int_cast<sal_Int16>( nCtrls - 1 );
625 
626         // reorder helper list
627         OUString aCtrlName = aNameList[nOldTabIndex];
628         aNameList.erase( aNameList.begin() + nOldTabIndex );
629         aNameList.insert( aNameList.begin() + nNewTabIndex , aCtrlName );
630 
631         // set new tab indices
632         for ( sal_Int32 i = 0; i < nCtrls; ++i )
633         {
634             Any aCtrl = xNameAcc->getByName( aNameList[i] );
635             Reference< beans::XPropertySet > xPSet;
636             aCtrl >>= xPSet;
637             if ( xPSet.is() )
638             {
639                 assert(i >= SAL_MIN_INT16);
640                 if (i > SAL_MAX_INT16)
641                 {
642                     SAL_WARN("basctl", "tab " << i << " > SAL_MAX_INT16");
643                     continue;
644                 }
645                 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(i)) );
646             }
647         }
648 
649         // reorder objects in drawing page
650         getSdrModelFromSdrObject().GetPage(0)->SetObjectOrdNum( nOldTabIndex + 1, nNewTabIndex + 1 );
651 
652         pForm->UpdateTabOrderAndGroups();
653     }
654 
655     // start listening with all children
656     for (auto const& child : aChildList)
657     {
658         child->StartListening();
659     }
660 }
661 
supportsService(OUString const & serviceName) const662 bool DlgEdObj::supportsService( OUString const & serviceName ) const
663 {
664     bool bSupports = false;
665 
666     Reference< lang::XServiceInfo > xServiceInfo( GetUnoControlModel() , UNO_QUERY );
667         // TODO: cache xServiceInfo as member?
668     if ( xServiceInfo.is() )
669         bSupports = xServiceInfo->supportsService( serviceName );
670 
671     return bSupports;
672 }
673 
GetDefaultName() const674 OUString DlgEdObj::GetDefaultName() const
675 {
676     OUString sResId;
677     OUString aDefaultName;
678     if ( supportsService( "com.sun.star.awt.UnoControlDialogModel" ) )
679     {
680         sResId = RID_STR_CLASS_DIALOG;
681     }
682     else if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ) )
683     {
684         sResId = RID_STR_CLASS_BUTTON;
685     }
686     else if ( supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) )
687     {
688         sResId = RID_STR_CLASS_RADIOBUTTON;
689     }
690     else if ( supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) )
691     {
692         sResId = RID_STR_CLASS_CHECKBOX;
693     }
694     else if ( supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) )
695     {
696         sResId = RID_STR_CLASS_LISTBOX;
697     }
698     else if ( supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) )
699     {
700         sResId = RID_STR_CLASS_COMBOBOX;
701     }
702     else if ( supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) )
703     {
704         sResId = RID_STR_CLASS_GROUPBOX;
705     }
706     else if ( supportsService( "com.sun.star.awt.UnoControlEditModel" ) )
707     {
708         sResId = RID_STR_CLASS_EDIT;
709     }
710     else if ( supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
711     {
712         sResId = RID_STR_CLASS_FIXEDTEXT;
713     }
714     else if ( supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) )
715     {
716         sResId = RID_STR_CLASS_IMAGECONTROL;
717     }
718     else if ( supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) )
719     {
720         sResId = RID_STR_CLASS_PROGRESSBAR;
721     }
722     else if ( supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) )
723     {
724         sResId = RID_STR_CLASS_SCROLLBAR;
725     }
726     else if ( supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ) )
727     {
728         sResId = RID_STR_CLASS_FIXEDLINE;
729     }
730     else if ( supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ) )
731     {
732         sResId = RID_STR_CLASS_DATEFIELD;
733     }
734     else if ( supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ) )
735     {
736         sResId = RID_STR_CLASS_TIMEFIELD;
737     }
738     else if ( supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ) )
739     {
740         sResId = RID_STR_CLASS_NUMERICFIELD;
741     }
742     else if ( supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ) )
743     {
744         sResId = RID_STR_CLASS_CURRENCYFIELD;
745     }
746     else if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
747     {
748         sResId = RID_STR_CLASS_FORMATTEDFIELD;
749     }
750     else if ( supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ) )
751     {
752         sResId = RID_STR_CLASS_PATTERNFIELD;
753     }
754     else if ( supportsService( "com.sun.star.awt.UnoControlFileControlModel" ) )
755     {
756         sResId = RID_STR_CLASS_FILECONTROL;
757     }
758     else if ( supportsService( "com.sun.star.awt.tree.TreeControlModel" ) )
759     {
760         sResId = RID_STR_CLASS_TREECONTROL;
761     }
762     else if ( supportsService( "com.sun.star.awt.grid.UnoControlGridModel" ) )
763     {
764         sResId = RID_STR_CLASS_GRIDCONTROL;
765     }
766     else if ( supportsService( "com.sun.star.awt.UnoControlFixedHyperlinkModel" ) )
767     {
768         sResId = RID_STR_CLASS_HYPERLINKCONTROL;
769     }
770     else if ( supportsService( "com.sun.star.awt.UnoControlSpinButtonModel" ) )
771     {
772         sResId = RID_STR_CLASS_SPINCONTROL;
773     }
774     else
775     {
776         sResId = RID_STR_CLASS_CONTROL;
777     }
778 
779     if (!sResId.isEmpty())
780         aDefaultName = sResId;
781 
782     return aDefaultName;
783 }
784 
GetUniqueName() const785 OUString DlgEdObj::GetUniqueName() const
786 {
787     OUString aUniqueName;
788     uno::Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), uno::UNO_QUERY);
789 
790     if ( xNameAcc.is() )
791     {
792         sal_Int32 n = 0;
793         OUString aDefaultName = GetDefaultName();
794 
795         do
796         {
797             aUniqueName = aDefaultName + OUString::number(++n);
798         }   while (xNameAcc->hasByName(aUniqueName));
799     }
800 
801     return aUniqueName;
802 }
803 
GetObjInventor() const804 SdrInventor DlgEdObj::GetObjInventor()   const
805 {
806     return SdrInventor::BasicDialog;
807 }
808 
GetObjIdentifier() const809 SdrObjKind DlgEdObj::GetObjIdentifier() const
810 {
811     if ( supportsService( "com.sun.star.awt.UnoControlDialogModel" ))
812     {
813         return OBJ_DLG_DIALOG;
814     }
815     else if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ))
816     {
817         return OBJ_DLG_PUSHBUTTON;
818     }
819     else if ( supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ))
820     {
821         return OBJ_DLG_RADIOBUTTON;
822     }
823     else if ( supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ))
824     {
825         return OBJ_DLG_CHECKBOX;
826     }
827     else if ( supportsService( "com.sun.star.awt.UnoControlListBoxModel" ))
828     {
829         return OBJ_DLG_LISTBOX;
830     }
831     else if ( supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ))
832     {
833         return OBJ_DLG_COMBOBOX;
834     }
835     else if ( supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ))
836     {
837         return OBJ_DLG_GROUPBOX;
838     }
839     else if ( supportsService( "com.sun.star.awt.UnoControlEditModel" ))
840     {
841         return OBJ_DLG_EDIT;
842     }
843     else if ( supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ))
844     {
845         return OBJ_DLG_FIXEDTEXT;
846     }
847     else if ( supportsService( "com.sun.star.awt.UnoControlImageControlModel" ))
848     {
849         return OBJ_DLG_IMAGECONTROL;
850     }
851     else if ( supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ))
852     {
853         return OBJ_DLG_PROGRESSBAR;
854     }
855     else if ( supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ))
856     {
857         return OBJ_DLG_HSCROLLBAR;
858     }
859     else if ( supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ))
860     {
861         return OBJ_DLG_HFIXEDLINE;
862     }
863     else if ( supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ))
864     {
865         return OBJ_DLG_DATEFIELD;
866     }
867     else if ( supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ))
868     {
869         return OBJ_DLG_TIMEFIELD;
870     }
871     else if ( supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ))
872     {
873         return OBJ_DLG_NUMERICFIELD;
874     }
875     else if ( supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ))
876     {
877         return OBJ_DLG_CURRENCYFIELD;
878     }
879     else if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ))
880     {
881         return OBJ_DLG_FORMATTEDFIELD;
882     }
883     else if ( supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ))
884     {
885         return OBJ_DLG_PATTERNFIELD;
886     }
887     else if ( supportsService( "com.sun.star.awt.UnoControlFileControlModel" ))
888     {
889         return OBJ_DLG_FILECONTROL;
890     }
891     else if ( supportsService( "com.sun.star.awt.tree.TreeControlModel" ))
892     {
893         return OBJ_DLG_TREECONTROL;
894     }
895     else if ( supportsService( "com.sun.star.awt.grid.UnoControlGridModel" ))
896     {
897         return OBJ_DLG_GRIDCONTROL;
898     }
899     else if ( supportsService( "com.sun.star.awt.UnoControlFixedHyperlinkModel" ))
900     {
901         return OBJ_DLG_HYPERLINKCONTROL;
902     }
903     else
904     {
905         return OBJ_DLG_CONTROL;
906     }
907 }
908 
CloneSdrObject(SdrModel & rTargetModel) const909 DlgEdObj* DlgEdObj::CloneSdrObject(SdrModel& rTargetModel) const
910 {
911     return new DlgEdObj(rTargetModel, *this);
912 }
913 
getFullDragClone() const914 SdrObjectUniquePtr DlgEdObj::getFullDragClone() const
915 {
916     // no need to really add the clone for dragging, it's a temporary
917     // object
918     return SdrObjectUniquePtr(new SdrUnoObj(getSdrModelFromSdrObject(), *this));
919 }
920 
NbcMove(const Size & rSize)921 void DlgEdObj::NbcMove( const Size& rSize )
922 {
923     SdrUnoObj::NbcMove( rSize );
924 
925     // stop listening
926     EndListening(false);
927 
928     // set geometry properties
929     SetPropsFromRect();
930 
931     // start listening
932     StartListening();
933 
934     // dialog model changed
935     GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
936 }
937 
NbcResize(const Point & rRef,const Fraction & xFract,const Fraction & yFract)938 void DlgEdObj::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
939 {
940     SdrUnoObj::NbcResize( rRef, xFract, yFract );
941 
942     // stop listening
943     EndListening(false);
944 
945     // set geometry properties
946     SetPropsFromRect();
947 
948     // start listening
949     StartListening();
950 
951     // dialog model changed
952     GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
953 }
954 
EndCreate(SdrDragStat & rStat,SdrCreateCmd eCmd)955 bool DlgEdObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
956 {
957     bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
958 
959     // tdf#120674 after interactive creation, the SdrObject (this) has no SdrPage yet
960     // due to not being inserted. Usually this should be handled in a ::handlePageChange
961     // implementation. For historical reasons, the SdrPage (which is the DlgEdPage) was
962     // already set. For now, get it from the SdrDragStat and use it to access and set
963     // the local pDlgEdForm
964     if(nullptr == pDlgEdForm && nullptr != rStat.GetPageView())
965     {
966         const DlgEdPage* pDlgEdPage(dynamic_cast<const DlgEdPage*>(rStat.GetPageView()->GetPage()));
967 
968         if(nullptr != pDlgEdPage)
969         {
970             // set parent form
971             pDlgEdForm = pDlgEdPage->GetDlgEdForm();
972         }
973     }
974 
975     SetDefaults();
976     StartListening();
977 
978     return bResult;
979 }
980 
SetDefaults()981 void DlgEdObj::SetDefaults()
982 {
983     if ( !pDlgEdForm )
984         return;
985 
986     // add child to parent form
987     pDlgEdForm->AddChild( this );
988 
989     Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
990     if ( xPSet.is() )
991     {
992         // get unique name
993         OUString aOUniqueName( GetUniqueName() );
994 
995         // set name property
996         xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOUniqueName) );
997 
998         // set labels
999         if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ) ||
1000             supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) ||
1001             supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) ||
1002             supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) ||
1003             supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
1004         {
1005             xPSet->setPropertyValue( DLGED_PROP_LABEL, Any(aOUniqueName) );
1006         }
1007 
1008         // set number formats supplier for formatted field
1009         if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
1010         {
1011             Reference< util::XNumberFormatsSupplier > xSupplier = GetDlgEdForm()->GetDlgEditor().GetNumberFormatsSupplier();
1012             if ( xSupplier.is() )
1013             {
1014                 xPSet->setPropertyValue( DLGED_PROP_FORMATSSUPPLIER, Any(xSupplier) );
1015             }
1016         }
1017 
1018         // set geometry properties
1019         SetPropsFromRect();
1020 
1021         Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
1022         if ( xCont.is() )
1023         {
1024             // set tabindex
1025             Sequence< OUString > aNames = xCont->getElementNames();
1026             uno::Any aTabIndex;
1027             aTabIndex <<= static_cast<sal_Int16>(aNames.getLength());
1028             xPSet->setPropertyValue( DLGED_PROP_TABINDEX, aTabIndex );
1029 
1030             // set step
1031             Reference< beans::XPropertySet > xPSetForm( xCont, UNO_QUERY );
1032             if ( xPSetForm.is() )
1033             {
1034                 Any aStep = xPSetForm->getPropertyValue( DLGED_PROP_STEP );
1035                 xPSet->setPropertyValue( DLGED_PROP_STEP, aStep );
1036             }
1037 
1038             // insert control model in dialog model
1039             Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
1040             Any aAny;
1041             aAny <<= xCtrl;
1042             xCont->insertByName( aOUniqueName , aAny );
1043 
1044             LocalizationMgr::setControlResourceIDsForNewEditorObject(
1045                 &GetDialogEditor(), aAny, aOUniqueName
1046             );
1047 
1048             pDlgEdForm->UpdateTabOrderAndGroups();
1049         }
1050     }
1051 
1052     // dialog model changed
1053     pDlgEdForm->GetDlgEditor().SetDialogModelChanged();
1054 }
1055 
StartListening()1056 void DlgEdObj::StartListening()
1057 {
1058     DBG_ASSERT(!isListening(), "DlgEdObj::StartListening: already listening!");
1059 
1060     if (isListening())
1061         return;
1062 
1063     bIsListening = true;
1064 
1065     // XPropertyChangeListener
1066     Reference< XPropertySet > xControlModel( GetUnoControlModel() , UNO_QUERY );
1067     if (!m_xPropertyChangeListener.is() && xControlModel.is())
1068     {
1069         // create listener
1070         m_xPropertyChangeListener = new DlgEdPropListenerImpl(*this);
1071 
1072         // register listener to properties
1073         xControlModel->addPropertyChangeListener( OUString() , m_xPropertyChangeListener );
1074     }
1075 
1076     // XContainerListener
1077     Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
1078     if( !m_xContainerListener.is() && xEventsSupplier.is() )
1079     {
1080         // create listener
1081         m_xContainerListener = new DlgEdEvtContListenerImpl(*this);
1082 
1083         // register listener to script event container
1084         Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
1085         DBG_ASSERT(xEventCont.is(), "DlgEdObj::StartListening: control model has no script event container!");
1086         Reference< XContainer > xCont( xEventCont , UNO_QUERY );
1087         if (xCont.is())
1088             xCont->addContainerListener( m_xContainerListener );
1089     }
1090 }
1091 
EndListening(bool bRemoveListener)1092 void DlgEdObj::EndListening(bool bRemoveListener)
1093 {
1094     DBG_ASSERT(isListening(), "DlgEdObj::EndListening: not listening currently!");
1095 
1096     if (!isListening())
1097         return;
1098 
1099     bIsListening = false;
1100 
1101     if (!bRemoveListener)
1102         return;
1103 
1104     // XPropertyChangeListener
1105     Reference< XPropertySet > xControlModel(GetUnoControlModel(), UNO_QUERY);
1106     if ( m_xPropertyChangeListener.is() && xControlModel.is() )
1107     {
1108         // remove listener
1109         xControlModel->removePropertyChangeListener( OUString() , m_xPropertyChangeListener );
1110     }
1111     m_xPropertyChangeListener.clear();
1112 
1113     // XContainerListener
1114     Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
1115     if( m_xContainerListener.is() && xEventsSupplier.is() )
1116     {
1117         // remove listener
1118         Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
1119         DBG_ASSERT(xEventCont.is(), "DlgEdObj::EndListening: control model has no script event container!");
1120         Reference< XContainer > xCont( xEventCont , UNO_QUERY );
1121         if (xCont.is())
1122             xCont->removeContainerListener( m_xContainerListener );
1123     }
1124     m_xContainerListener.clear();
1125 }
1126 
_propertyChange(const css::beans::PropertyChangeEvent & evt)1127 void DlgEdObj::_propertyChange( const  css::beans::PropertyChangeEvent& evt )
1128 {
1129     if (!isListening())
1130         return;
1131 
1132     DlgEdForm* pRealDlgEdForm = dynamic_cast<DlgEdForm*>(this);
1133     if (!pRealDlgEdForm)
1134         pRealDlgEdForm = GetDlgEdForm();
1135     if (!pRealDlgEdForm)
1136         return;
1137     DlgEditor& rDlgEditor = pRealDlgEdForm->GetDlgEditor();
1138     if (rDlgEditor.isInPaint())
1139         return;
1140 
1141     // dialog model changed
1142     rDlgEditor.SetDialogModelChanged();
1143 
1144     // update position and size
1145     if ( evt.PropertyName == DLGED_PROP_POSITIONX || evt.PropertyName == DLGED_PROP_POSITIONY ||
1146          evt.PropertyName == DLGED_PROP_WIDTH || evt.PropertyName == DLGED_PROP_HEIGHT ||
1147          evt.PropertyName == DLGED_PROP_DECORATION )
1148     {
1149         PositionAndSizeChange( evt );
1150 
1151         if ( evt.PropertyName == DLGED_PROP_DECORATION )
1152             GetDialogEditor().ResetDialog();
1153     }
1154     // change name of control in dialog model
1155     else if ( evt.PropertyName == DLGED_PROP_NAME )
1156     {
1157         if (!dynamic_cast<DlgEdForm*>(this))
1158         {
1159             try
1160             {
1161                 NameChange(evt);
1162             }
1163             catch (container::NoSuchElementException const&)
1164             {
1165                 css::uno::Any anyEx = cppu::getCaughtException();
1166                 throw lang::WrappedTargetRuntimeException("", nullptr,
1167                         anyEx);
1168             }
1169         }
1170     }
1171     // update step
1172     else if ( evt.PropertyName == DLGED_PROP_STEP )
1173     {
1174         UpdateStep();
1175     }
1176     // change tabindex
1177     else if ( evt.PropertyName == DLGED_PROP_TABINDEX )
1178     {
1179         if (!dynamic_cast<DlgEdForm*>(this))
1180             TabIndexChange(evt);
1181     }
1182 }
1183 
_elementInserted()1184 void DlgEdObj::_elementInserted()
1185 {
1186     if (isListening())
1187     {
1188         // dialog model changed
1189         GetDialogEditor().SetDialogModelChanged();
1190     }
1191 }
1192 
_elementReplaced()1193 void DlgEdObj::_elementReplaced()
1194 {
1195     if (isListening())
1196     {
1197         // dialog model changed
1198         GetDialogEditor().SetDialogModelChanged();
1199     }
1200 }
1201 
_elementRemoved()1202 void DlgEdObj::_elementRemoved()
1203 {
1204     if (isListening())
1205     {
1206         // dialog model changed
1207         GetDialogEditor().SetDialogModelChanged();
1208     }
1209 }
1210 
SetLayer(SdrLayerID nLayer)1211 void DlgEdObj::SetLayer(SdrLayerID nLayer)
1212 {
1213     SdrLayerID nOldLayer = GetLayer();
1214 
1215     if ( nLayer != nOldLayer )
1216     {
1217         SdrUnoObj::SetLayer( nLayer );
1218 
1219         DlgEdHint aHint( DlgEdHint::LAYERCHANGED, this );
1220         GetDlgEdForm()->GetDlgEditor().Broadcast( aHint );
1221     }
1222 }
1223 
DlgEdForm(SdrModel & rSdrModel,DlgEditor & rDlgEditor_)1224 DlgEdForm::DlgEdForm(
1225     SdrModel& rSdrModel,
1226     DlgEditor& rDlgEditor_)
1227 :   DlgEdObj(rSdrModel),
1228     rDlgEditor(rDlgEditor_)
1229 {
1230 }
1231 
~DlgEdForm()1232 DlgEdForm::~DlgEdForm()
1233 {
1234 }
1235 
SetRectFromProps()1236 void DlgEdForm::SetRectFromProps()
1237 {
1238     // get form position and size from properties
1239     Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
1240     if ( !xPSet.is() )
1241         return;
1242 
1243     sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
1244     xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
1245     xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
1246     xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
1247     xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
1248 
1249     // transform coordinates
1250     sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
1251     if ( TransformFormToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
1252     {
1253         // set rectangle position and size
1254         Point aPoint( nXOut, nYOut );
1255         Size aSize( nWidthOut, nHeightOut );
1256         SetSnapRect( tools::Rectangle( aPoint, aSize ) );
1257     }
1258 }
1259 
SetPropsFromRect()1260 void DlgEdForm::SetPropsFromRect()
1261 {
1262     // get form position and size from rectangle
1263     tools::Rectangle aRect_ = GetSnapRect();
1264     sal_Int32 nXIn = aRect_.Left();
1265     sal_Int32 nYIn = aRect_.Top();
1266     sal_Int32 nWidthIn = aRect_.GetWidth();
1267     sal_Int32 nHeightIn = aRect_.GetHeight();
1268 
1269     // transform coordinates
1270     sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
1271     if ( TransformSdrToFormCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
1272     {
1273         // set properties
1274         Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
1275         if ( xPSet.is() )
1276         {
1277             xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
1278             xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
1279             xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
1280             xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
1281         }
1282     }
1283 }
1284 
AddChild(DlgEdObj * pDlgEdObj)1285 void DlgEdForm::AddChild( DlgEdObj* pDlgEdObj )
1286 {
1287     pChildren.push_back( pDlgEdObj );
1288 }
1289 
RemoveChild(DlgEdObj * pDlgEdObj)1290 void DlgEdForm::RemoveChild( DlgEdObj* pDlgEdObj )
1291 {
1292     pChildren.erase( std::remove( pChildren.begin() , pChildren.end() , pDlgEdObj ) );
1293 }
1294 
PositionAndSizeChange(const beans::PropertyChangeEvent & evt)1295 void DlgEdForm::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
1296 {
1297     DlgEditor& rEditor = GetDlgEditor();
1298     DlgEdPage& rPage = rEditor.GetPage();
1299 
1300     sal_Int32 nPageXIn = 0;
1301     sal_Int32 nPageYIn = 0;
1302     Size aPageSize = rPage.GetSize();
1303     sal_Int32 nPageWidthIn = aPageSize.Width();
1304     sal_Int32 nPageHeightIn = aPageSize.Height();
1305     sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
1306     if ( TransformSdrToFormCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
1307     {
1308         Reference< beans::XPropertySet > xPSetForm( GetUnoControlModel(), UNO_QUERY );
1309         if ( xPSetForm.is() )
1310         {
1311             sal_Int32 nValue = 0;
1312             evt.NewValue >>= nValue;
1313             sal_Int32 nNewValue = nValue;
1314 
1315             if ( evt.PropertyName == DLGED_PROP_POSITIONX )
1316             {
1317                 if ( nNewValue < nPageX )
1318                     nNewValue = nPageX;
1319             }
1320             else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
1321             {
1322                 if ( nNewValue < nPageY )
1323                     nNewValue = nPageY;
1324             }
1325             else if ( evt.PropertyName == DLGED_PROP_WIDTH )
1326             {
1327                 if ( nNewValue < 1 )
1328                     nNewValue = 1;
1329             }
1330             else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
1331             {
1332                 if ( nNewValue < 1 )
1333                     nNewValue = 1;
1334             }
1335 
1336             if ( nNewValue != nValue )
1337             {
1338                 EndListening( false );
1339                 xPSetForm->setPropertyValue( evt.PropertyName, Any(nNewValue) );
1340                 StartListening();
1341             }
1342         }
1343     }
1344 
1345     bool bAdjustedPageSize = rEditor.AdjustPageSize();
1346     SetRectFromProps();
1347     std::vector<DlgEdObj*> const& aChildList = GetChildren();
1348 
1349     if ( bAdjustedPageSize )
1350     {
1351         rEditor.InitScrollBars();
1352         aPageSize = rPage.GetSize();
1353         nPageWidthIn = aPageSize.Width();
1354         nPageHeightIn = aPageSize.Height();
1355         if ( TransformSdrToControlCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
1356         {
1357             for (auto const& child : aChildList)
1358             {
1359                 Reference< beans::XPropertySet > xPSet( child->GetUnoControlModel(), UNO_QUERY );
1360                 if ( xPSet.is() )
1361                 {
1362                     sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
1363                     xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
1364                     xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
1365                     xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
1366                     xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
1367 
1368                     sal_Int32 nNewX = nX;
1369                     if ( nX + nWidth > nPageX + nPageWidth )
1370                     {
1371                         nNewX = nPageX + nPageWidth - nWidth;
1372                         if ( nNewX < nPageX )
1373                             nNewX = nPageX;
1374                     }
1375                     if ( nNewX != nX )
1376                     {
1377                         EndListening( false );
1378                         xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nNewX) );
1379                         StartListening();
1380                     }
1381 
1382                     sal_Int32 nNewY = nY;
1383                     if ( nY + nHeight > nPageY + nPageHeight )
1384                     {
1385                         nNewY = nPageY + nPageHeight - nHeight;
1386                         if ( nNewY < nPageY )
1387                             nNewY = nPageY;
1388                     }
1389                     if ( nNewY != nY )
1390                     {
1391                         EndListening( false );
1392                         xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nNewY) );
1393                         StartListening();
1394                     }
1395                 }
1396             }
1397         }
1398     }
1399 
1400     for (auto const& child : aChildList)
1401         child->SetRectFromProps();
1402 }
1403 
UpdateStep()1404 void DlgEdForm::UpdateStep()
1405 {
1406     SdrPage* pSdrPage = getSdrPageFromSdrObject();
1407 
1408     if ( pSdrPage )
1409     {
1410         const size_t nObjCount = pSdrPage->GetObjCount();
1411         for ( size_t i = 0 ; i < nObjCount ; i++ )
1412         {
1413             DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pSdrPage->GetObj(i));
1414             if (pDlgEdObj && !dynamic_cast<DlgEdForm*>(pDlgEdObj))
1415                 pDlgEdObj->UpdateStep();
1416         }
1417     }
1418 }
1419 
UpdateTabIndices()1420 void DlgEdForm::UpdateTabIndices()
1421 {
1422     // stop listening with all children
1423     for (auto const& child : pChildren)
1424     {
1425         child->EndListening( false );
1426     }
1427 
1428     Reference< css::container::XNameAccess > xNameAcc( GetUnoControlModel() , UNO_QUERY );
1429     if ( xNameAcc.is() )
1430     {
1431         // get sequence of control names
1432         Sequence< OUString > aNames = xNameAcc->getElementNames();
1433         const OUString* pNames = aNames.getConstArray();
1434         sal_Int32 nCtrls = aNames.getLength();
1435 
1436         // create a map of tab indices and control names, sorted by tab index
1437         IndexToNameMap aIndexToNameMap;
1438         for ( sal_Int32 i = 0; i < nCtrls; ++i )
1439         {
1440             // get name
1441             OUString aName( pNames[i] );
1442 
1443             // get tab index
1444             sal_Int16 nTabIndex = -1;
1445             Any aCtrl = xNameAcc->getByName( aName );
1446             Reference< css::beans::XPropertySet > xPSet;
1447             aCtrl >>= xPSet;
1448             if ( xPSet.is() )
1449                 xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
1450 
1451             // insert into map
1452             aIndexToNameMap.emplace( nTabIndex, aName );
1453         }
1454 
1455         // set new tab indices
1456         sal_Int16 nNewTabIndex = 0;
1457         for (auto const& indexToName : aIndexToNameMap)
1458         {
1459             Any aCtrl = xNameAcc->getByName( indexToName.second );
1460             Reference< beans::XPropertySet > xPSet;
1461             aCtrl >>= xPSet;
1462             if ( xPSet.is() )
1463             {
1464                 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(nNewTabIndex) );
1465                 nNewTabIndex++;
1466             }
1467         }
1468 
1469         UpdateTabOrderAndGroups();
1470     }
1471 
1472     // start listening with all children
1473     for (auto const& child : pChildren)
1474     {
1475         child->StartListening();
1476     }
1477 }
1478 
UpdateTabOrder()1479 void DlgEdForm::UpdateTabOrder()
1480 {
1481     // When the tabindex of a control model changes, the dialog control is
1482     // notified about those changes. Due to #109067# (bad performance of
1483     // dialog editor) the dialog control doesn't activate the tab order
1484     // in design mode. When the dialog editor has reordered all
1485     // tabindices, this method allows to activate the taborder afterwards.
1486 
1487     Reference< awt::XUnoControlContainer > xCont( GetControl(), UNO_QUERY );
1488     if ( xCont.is() )
1489     {
1490         Sequence< Reference< awt::XTabController > > aSeqTabCtrls = xCont->getTabControllers();
1491         const Reference< awt::XTabController >* pTabCtrls = aSeqTabCtrls.getConstArray();
1492         sal_Int32 nCount = aSeqTabCtrls.getLength();
1493         for ( sal_Int32 i = 0; i < nCount; ++i )
1494             pTabCtrls[i]->activateTabOrder();
1495     }
1496 }
1497 
UpdateGroups()1498 void DlgEdForm::UpdateGroups()
1499 {
1500     // The grouping of radio buttons in a dialog is done by vcl.
1501     // In the dialog editor we have two views (=controls) for one
1502     // radio button model. One control is owned by the dialog control,
1503     // but not visible in design mode. The other control is owned by
1504     // the drawing layer object. Whereas the grouping of the first
1505     // control is done by vcl, the grouping of the control in the
1506     // drawing layer has to be done here.
1507 
1508     Reference< awt::XTabControllerModel > xTabModel( GetUnoControlModel() , UNO_QUERY );
1509     if ( !xTabModel.is() )
1510         return;
1511 
1512     // create a global list of controls that belong to the dialog
1513     std::vector<DlgEdObj*> aChildList = GetChildren();
1514     sal_uInt32 nSize = aChildList.size();
1515     Sequence< Reference< awt::XControl > > aSeqControls( nSize );
1516     for ( sal_uInt32 i = 0; i < nSize; ++i )
1517         aSeqControls.getArray()[i] = aChildList[i]->GetControl();
1518 
1519     sal_Int32 nGroupCount = xTabModel->getGroupCount();
1520     for ( sal_Int32 nGroup = 0; nGroup < nGroupCount; ++nGroup )
1521     {
1522         // get a list of control models that belong to this group
1523         OUString aName;
1524         Sequence< Reference< awt::XControlModel > > aSeqModels;
1525         xTabModel->getGroup( nGroup, aSeqModels, aName );
1526         const Reference< awt::XControlModel >* pModels = aSeqModels.getConstArray();
1527         sal_Int32 nModelCount = aSeqModels.getLength();
1528 
1529         // create a list of peers that belong to this group
1530         Sequence< Reference< awt::XWindow > > aSeqPeers( nModelCount );
1531         for ( sal_Int32 nModel = 0; nModel < nModelCount; ++nModel )
1532         {
1533             // for each control model find the corresponding control in the global list
1534             const Reference< awt::XControl >* pControls = aSeqControls.getConstArray();
1535             sal_Int32 nControlCount = aSeqControls.getLength();
1536             for ( sal_Int32 nControl = 0; nControl < nControlCount; ++nControl )
1537             {
1538                 const Reference< awt::XControl > xCtrl( pControls[nControl] );
1539                 if ( xCtrl.is() )
1540                 {
1541                     Reference< awt::XControlModel > xCtrlModel( xCtrl->getModel() );
1542                     if ( xCtrlModel.get() == pModels[nModel].get() )
1543                     {
1544                         // get the control peer and insert into the list of peers
1545                         aSeqPeers.getArray()[ nModel ].set( xCtrl->getPeer(), UNO_QUERY );
1546                         break;
1547                     }
1548                 }
1549             }
1550         }
1551 
1552         // set the group at the dialog peer
1553         Reference< awt::XControl > xDlg = GetControl();
1554         if ( xDlg.is() )
1555         {
1556             Reference< awt::XVclContainerPeer > xDlgPeer( xDlg->getPeer(), UNO_QUERY );
1557             if ( xDlgPeer.is() )
1558                 xDlgPeer->setGroup( aSeqPeers );
1559         }
1560     }
1561 }
1562 
UpdateTabOrderAndGroups()1563 void DlgEdForm::UpdateTabOrderAndGroups()
1564 {
1565     UpdateTabOrder();
1566     UpdateGroups();
1567 }
1568 
NbcMove(const Size & rSize)1569 void DlgEdForm::NbcMove( const Size& rSize )
1570 {
1571     SdrUnoObj::NbcMove( rSize );
1572 
1573     // set geometry properties of form
1574     EndListening(false);
1575     SetPropsFromRect();
1576     StartListening();
1577 
1578     // set geometry properties of all children
1579     for (auto const& child : pChildren)
1580     {
1581         child->EndListening(false);
1582         child->SetPropsFromRect();
1583         child->StartListening();
1584     }
1585 
1586     // dialog model changed
1587     GetDlgEditor().SetDialogModelChanged();
1588 }
1589 
NbcResize(const Point & rRef,const Fraction & xFract,const Fraction & yFract)1590 void DlgEdForm::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
1591 {
1592     SdrUnoObj::NbcResize( rRef, xFract, yFract );
1593 
1594     // set geometry properties of form
1595     EndListening(false);
1596     SetPropsFromRect();
1597     StartListening();
1598 
1599     // set geometry properties of all children
1600     for (auto const& child : pChildren)
1601     {
1602         child->EndListening(false);
1603         child->SetPropsFromRect();
1604         child->StartListening();
1605     }
1606 
1607     // dialog model changed
1608     GetDlgEditor().SetDialogModelChanged();
1609 }
1610 
EndCreate(SdrDragStat & rStat,SdrCreateCmd eCmd)1611 bool DlgEdForm::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
1612 {
1613     bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
1614 
1615     // stop listening
1616     EndListening(false);
1617 
1618     // set geometry properties
1619     SetPropsFromRect();
1620 
1621     // dialog model changed
1622     GetDlgEditor().SetDialogModelChanged();
1623 
1624     // start listening
1625     StartListening();
1626 
1627     return bResult;
1628 }
1629 
getDeviceInfo() const1630 awt::DeviceInfo DlgEdForm::getDeviceInfo() const
1631 {
1632     awt::DeviceInfo aDeviceInfo;
1633 
1634     DlgEditor& rEditor = GetDlgEditor();
1635     vcl::Window& rWindow = rEditor.GetWindow();
1636 
1637     // obtain an XControl
1638     ::utl::SharedUNOComponent< awt::XControl > xDialogControl; // ensures auto-disposal, if needed
1639     xDialogControl.reset( GetControl(), ::utl::SharedUNOComponent< awt::XControl >::NoTakeOwnership );
1640     if ( !xDialogControl.is() )
1641     {
1642         // don't create a temporary control all the time, this method here is called
1643         // way too often. Instead, use a cached DeviceInfo.
1644         // #i74065#
1645         if ( !!mpDeviceInfo )
1646             return *mpDeviceInfo;
1647 
1648         Reference< awt::XControlContainer > xEditorControlContainer( rEditor.GetWindowControlContainer() );
1649         xDialogControl.reset(
1650             GetTemporaryControlForWindow(rWindow, xEditorControlContainer),
1651             utl::SharedUNOComponent< awt::XControl >::TakeOwnership
1652         );
1653     }
1654 
1655     Reference< awt::XDevice > xDialogDevice;
1656     if ( xDialogControl.is() )
1657         xDialogDevice.set( xDialogControl->getPeer(), UNO_QUERY );
1658     DBG_ASSERT( xDialogDevice.is(), "DlgEdForm::getDeviceInfo: no device!" );
1659     if ( xDialogDevice.is() )
1660         aDeviceInfo = xDialogDevice->getInfo();
1661 
1662     mpDeviceInfo = aDeviceInfo;
1663 
1664     return aDeviceInfo;
1665 }
MakeDataAware(const Reference<frame::XModel> & xModel)1666 void DlgEdObj::MakeDataAware( const Reference< frame::XModel >& xModel )
1667 {
1668     // Need to flesh this out, currently we will only support data-aware controls for calc
1669     // and only handle a subset of functionality e.g. linked-cell and cell range data source. Of course later
1670     // we need to disambiguate for writer ( and others ? ) and also support the generic form (db) bindings
1671     // we need some more work in xmlscript to be able to handle that
1672     Reference< lang::XMultiServiceFactory > xFac( xModel, UNO_QUERY );
1673     Reference< form::binding::XBindableValue > xBindable( GetUnoControlModel(), UNO_QUERY );
1674     Reference< form::binding::XListEntrySink  > xListEntrySink( GetUnoControlModel(), UNO_QUERY );
1675     if ( !xFac.is() )
1676         return;
1677 
1678     css::table::CellAddress aApiAddress;
1679 
1680     //tdf#90361 CellValueBinding and CellRangeListSource are unusable
1681     //without being initialized, so use createInstanceWithArguments with a
1682     //dummy BoundCell instead of createInstance. This at least results in
1683     //the dialog editor not falling.
1684     css::beans::NamedValue aValue;
1685     aValue.Name = "BoundCell";
1686     aValue.Value <<= aApiAddress;
1687 
1688     Sequence< Any > aArgs( 1 );
1689     aArgs[ 0 ] <<= aValue;
1690 
1691     if ( xBindable.is() )
1692     {
1693         Reference< form::binding::XValueBinding > xBinding( xFac->createInstanceWithArguments( "com.sun.star.table.CellValueBinding", aArgs ), UNO_QUERY );
1694         xBindable->setValueBinding( xBinding );
1695     }
1696     if ( xListEntrySink.is() )
1697     {
1698         Reference< form::binding::XListEntrySource > xSource( xFac->createInstanceWithArguments( "com.sun.star.table.CellRangeListSource", aArgs ), UNO_QUERY );
1699         xListEntrySink->setListEntrySource( xSource );
1700     }
1701 }
1702 } // namespace basctl
1703 
1704 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1705