nss: upgrade to release 3.73
[LibreOffice.git] / basctl / source / dlged / dlgedobj.cxx
blob056006c4305eb3324411f06097e8bc555f188b6f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
23 #include <cassert>
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>
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>
52 namespace basctl
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;
62 DlgEditor& DlgEdObj::GetDialogEditor ()
64 if (DlgEdForm* pFormThis = dynamic_cast<DlgEdForm*>(this))
65 return pFormThis->GetDlgEditor();
66 else
67 return pDlgEdForm->GetDlgEditor();
70 DlgEdObj::DlgEdObj(SdrModel& rSdrModel)
71 : SdrUnoObj(rSdrModel, OUString())
72 ,bIsListening(false)
73 ,pDlgEdForm( nullptr )
77 DlgEdObj::DlgEdObj(
78 SdrModel& rSdrModel,
79 const OUString& rModelName,
80 const css::uno::Reference< css::lang::XMultiServiceFactory >& rxSFac)
81 : SdrUnoObj(rSdrModel, rModelName, rxSFac)
82 ,bIsListening(false)
83 ,pDlgEdForm( nullptr )
87 DlgEdObj::~DlgEdObj()
89 if ( isListening() )
90 EndListening(true);
93 namespace
95 /* returns the DlgEdForm which the given DlgEdObj belongs to
96 (which might in fact be the object itself)
98 Failure to obtain the form will be reported with an assertion in the non-product
99 version.
101 bool lcl_getDlgEdForm( DlgEdObj* _pObject, DlgEdForm*& _out_pDlgEdForm )
103 _out_pDlgEdForm = dynamic_cast< DlgEdForm* >( _pObject );
104 if ( !_out_pDlgEdForm )
105 _out_pDlgEdForm = _pObject->GetDlgEdForm();
106 DBG_ASSERT( _out_pDlgEdForm, "lcl_getDlgEdForm: no form!" );
107 return ( _out_pDlgEdForm != nullptr );
111 uno::Reference< awt::XControl > DlgEdObj::GetControl() const
113 uno::Reference< awt::XControl > xControl;
114 if (DlgEdForm const* pForm = GetDlgEdForm())
116 DlgEditor const& rEditor = pForm->GetDlgEditor();
117 xControl = GetUnoControl(rEditor.GetView(), rEditor.GetWindow());
119 return xControl;
122 bool DlgEdObj::TransformSdrToControlCoordinates(
123 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
124 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
126 // input position and size
127 Size aPos( nXIn, nYIn );
128 Size aSize( nWidthIn, nHeightIn );
130 // form position
131 DlgEdForm* pForm = nullptr;
132 if ( !lcl_getDlgEdForm( this, pForm ) )
133 return false;
134 tools::Rectangle aFormRect = pForm->GetSnapRect();
135 Size aFormPos( aFormRect.Left(), aFormRect.Top() );
137 // convert 100th_mm to pixel
138 OutputDevice* pDevice = Application::GetDefaultDevice();
139 DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToControlCoordinates: missing default device!" );
140 if ( !pDevice )
141 return false;
142 aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
143 aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
144 aFormPos = pDevice->LogicToPixel( aFormPos, MapMode( MapUnit::Map100thMM ) );
146 // subtract form position
147 aPos.AdjustWidth( -(aFormPos.Width()) );
148 aPos.AdjustHeight( -(aFormPos.Height()) );
150 // take window borders into account
151 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
152 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
153 if ( !xPSetForm.is() )
154 return false;
155 bool bDecoration = true;
156 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
157 if( bDecoration )
159 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
160 aPos.AdjustWidth( -(aDeviceInfo.LeftInset) );
161 aPos.AdjustHeight( -(aDeviceInfo.TopInset) );
164 // convert pixel to logic units
165 aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
166 aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
168 // set out parameters
169 nXOut = aPos.Width();
170 nYOut = aPos.Height();
171 nWidthOut = aSize.Width();
172 nHeightOut = aSize.Height();
174 return true;
177 bool DlgEdObj::TransformSdrToFormCoordinates(
178 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
179 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
181 // input position and size
182 Size aPos( nXIn, nYIn );
183 Size aSize( nWidthIn, nHeightIn );
185 // convert 100th_mm to pixel
186 OutputDevice* pDevice = Application::GetDefaultDevice();
187 DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToFormCoordinates: missing default device!" );
188 if ( !pDevice )
189 return false;
190 aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
191 aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
193 // take window borders into account
194 DlgEdForm* pForm = nullptr;
195 if ( !lcl_getDlgEdForm( this, pForm ) )
196 return false;
198 // take window borders into account
199 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
200 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
201 if ( !xPSetForm.is() )
202 return false;
203 bool bDecoration = true;
204 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
205 if( bDecoration )
207 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
208 aSize.AdjustWidth( -(aDeviceInfo.LeftInset + aDeviceInfo.RightInset) );
209 aSize.AdjustHeight( -(aDeviceInfo.TopInset + aDeviceInfo.BottomInset) );
211 // convert pixel to logic units
212 aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
213 aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
215 // set out parameters
216 nXOut = aPos.Width();
217 nYOut = aPos.Height();
218 nWidthOut = aSize.Width();
219 nHeightOut = aSize.Height();
221 return true;
224 bool DlgEdObj::TransformControlToSdrCoordinates(
225 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
226 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
228 // input position and size
229 Size aPos( nXIn, nYIn );
230 Size aSize( nWidthIn, nHeightIn );
232 // form position
233 DlgEdForm* pForm = nullptr;
234 if ( !lcl_getDlgEdForm( this, pForm ) )
235 return false;
237 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
238 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformControlToSdrCoordinates: no form property set!" );
239 if ( !xPSetForm.is() )
240 return false;
241 sal_Int32 nFormX = 0, nFormY = 0;
242 xPSetForm->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nFormX;
243 xPSetForm->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nFormY;
244 Size aFormPos( nFormX, nFormY );
246 // convert logic units to pixel
247 OutputDevice* pDevice = Application::GetDefaultDevice();
248 DBG_ASSERT( pDevice, "DlgEdObj::TransformControlToSdrCoordinates: missing default device!" );
249 if ( !pDevice )
250 return false;
251 aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
252 aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
253 aFormPos = pDevice->LogicToPixel(aFormPos, MapMode(MapUnit::MapAppFont));
255 // add form position
256 aPos.AdjustWidth(aFormPos.Width() );
257 aPos.AdjustHeight(aFormPos.Height() );
259 // take window borders into account
260 bool bDecoration = true;
261 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
262 if( bDecoration )
264 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
265 aPos.AdjustWidth(aDeviceInfo.LeftInset );
266 aPos.AdjustHeight(aDeviceInfo.TopInset );
269 // convert pixel to 100th_mm
270 aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
271 aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
273 // set out parameters
274 nXOut = aPos.Width();
275 nYOut = aPos.Height();
276 nWidthOut = aSize.Width();
277 nHeightOut = aSize.Height();
279 return true;
282 bool DlgEdObj::TransformFormToSdrCoordinates(
283 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
284 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
286 // input position and size
287 Size aPos( nXIn, nYIn );
288 Size aSize( nWidthIn, nHeightIn );
290 // convert logic units to pixel
291 OutputDevice* pDevice = Application::GetDefaultDevice();
292 DBG_ASSERT( pDevice, "DlgEdObj::TransformFormToSdrCoordinates: missing default device!" );
293 if ( !pDevice )
294 return false;
296 // take window borders into account
297 DlgEdForm* pForm = nullptr;
298 if ( !lcl_getDlgEdForm( this, pForm ) )
299 return false;
301 aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
302 aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
304 // take window borders into account
305 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
306 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
307 if ( !xPSetForm.is() )
308 return false;
309 bool bDecoration = true;
310 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
311 if( bDecoration )
313 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
314 aSize.AdjustWidth(aDeviceInfo.LeftInset + aDeviceInfo.RightInset );
315 aSize.AdjustHeight(aDeviceInfo.TopInset + aDeviceInfo.BottomInset );
318 // convert pixel to 100th_mm
319 aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
320 aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
322 // set out parameters
323 nXOut = aPos.Width();
324 nYOut = aPos.Height();
325 nWidthOut = aSize.Width();
326 nHeightOut = aSize.Height();
328 return true;
331 void DlgEdObj::SetRectFromProps()
333 // get control position and size from properties
334 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
335 if ( !xPSet.is() )
336 return;
338 sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
339 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
340 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
341 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
342 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
344 // transform coordinates
345 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
346 if ( TransformControlToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
348 // set rectangle position and size
349 Point aPoint( nXOut, nYOut );
350 Size aSize( nWidthOut, nHeightOut );
351 SetSnapRect( tools::Rectangle( aPoint, aSize ) );
355 void DlgEdObj::SetPropsFromRect()
357 // get control position and size from rectangle
358 tools::Rectangle aRect_ = GetSnapRect();
359 sal_Int32 nXIn = aRect_.Left();
360 sal_Int32 nYIn = aRect_.Top();
361 sal_Int32 nWidthIn = aRect_.GetWidth();
362 sal_Int32 nHeightIn = aRect_.GetHeight();
364 // transform coordinates
365 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
366 if ( TransformSdrToControlCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
368 // set properties
369 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
370 if ( xPSet.is() )
372 xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
373 xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
374 xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
375 xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
380 void DlgEdObj::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
382 DBG_ASSERT( pDlgEdForm, "DlgEdObj::PositionAndSizeChange: no form!" );
383 DlgEdPage& rPage = pDlgEdForm->GetDlgEditor().GetPage();
385 Size aPageSize = rPage.GetSize();
386 sal_Int32 nPageWidthIn = aPageSize.Width();
387 sal_Int32 nPageHeightIn = aPageSize.Height();
388 sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
389 if ( TransformSdrToControlCoordinates( 0/*nPageXIn*/, 0/*nPageYIn*/, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
391 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
392 if ( xPSet.is() )
394 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
395 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
396 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
397 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
398 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
400 sal_Int32 nValue = 0;
401 evt.NewValue >>= nValue;
402 sal_Int32 nNewValue = nValue;
404 if ( evt.PropertyName == DLGED_PROP_POSITIONX )
406 if ( nNewValue + nWidth > nPageX + nPageWidth )
407 nNewValue = nPageX + nPageWidth - nWidth;
408 if ( nNewValue < nPageX )
409 nNewValue = nPageX;
411 else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
413 if ( nNewValue + nHeight > nPageY + nPageHeight )
414 nNewValue = nPageY + nPageHeight - nHeight;
415 if ( nNewValue < nPageY )
416 nNewValue = nPageY;
418 else if ( evt.PropertyName == DLGED_PROP_WIDTH )
420 if ( nX + nNewValue > nPageX + nPageWidth )
421 nNewValue = nPageX + nPageWidth - nX;
422 if ( nNewValue < 1 )
423 nNewValue = 1;
425 else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
427 if ( nY + nNewValue > nPageY + nPageHeight )
428 nNewValue = nPageY + nPageHeight - nY;
429 if ( nNewValue < 1 )
430 nNewValue = 1;
433 if ( nNewValue != nValue )
435 EndListening( false );
436 xPSet->setPropertyValue( evt.PropertyName, Any(nNewValue) );
437 StartListening();
443 SetRectFromProps();
446 void DlgEdObj::NameChange( const css::beans::PropertyChangeEvent& evt )
448 // get old name
449 OUString aOldName;
450 evt.OldValue >>= aOldName;
452 // get new name
453 OUString aNewName;
454 evt.NewValue >>= aNewName;
456 if ( aNewName == aOldName )
457 return;
459 Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), UNO_QUERY);
460 if ( !(xNameAcc.is() && xNameAcc->hasByName(aOldName)) )
461 return;
463 if (!xNameAcc->hasByName(aNewName) && !aNewName.isEmpty())
465 // remove the control by the old name and insert the control by the new name in the container
466 Reference< container::XNameContainer > xCont(xNameAcc, UNO_QUERY );
467 if ( xCont.is() )
469 Reference< awt::XControlModel > xCtrl = GetUnoControlModel();
470 Any aAny;
471 aAny <<= xCtrl;
472 xCont->removeByName( aOldName );
473 xCont->insertByName( aNewName , aAny );
475 LocalizationMgr::renameControlResourceIDsForEditorObject(
476 &GetDialogEditor(), aAny, aNewName
480 else
482 // set old name property
483 EndListening(false);
484 Reference< beans::XPropertySet > xPSet(GetUnoControlModel(), UNO_QUERY);
485 xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOldName) );
486 StartListening();
490 sal_Int32 DlgEdObj::GetStep() const
492 // get step property
493 sal_Int32 nStep = 0;
494 uno::Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), uno::UNO_QUERY );
495 if (xPSet.is())
497 xPSet->getPropertyValue( DLGED_PROP_STEP ) >>= nStep;
499 return nStep;
502 void DlgEdObj::UpdateStep()
504 sal_Int32 nCurStep = GetDlgEdForm()->GetStep();
505 sal_Int32 nStep = GetStep();
507 SdrLayerAdmin& rLayerAdmin(getSdrModelFromSdrObject().GetLayerAdmin());
508 SdrLayerID nHiddenLayerId = rLayerAdmin.GetLayerID( "HiddenLayer" );
509 SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName() );
511 if( nCurStep )
513 if ( nStep && (nStep != nCurStep) )
515 SetLayer( nHiddenLayerId );
517 else
519 SetLayer( nControlLayerId );
522 else
524 SetLayer( nControlLayerId );
528 void DlgEdObj::TabIndexChange( const beans::PropertyChangeEvent& evt )
530 DlgEdForm* pForm = GetDlgEdForm();
531 if ( !pForm )
532 return;
534 // stop listening with all children
535 std::vector<DlgEdObj*> aChildList = pForm->GetChildren();
536 for (auto const& child : aChildList)
538 child->EndListening( false );
541 Reference< container::XNameAccess > xNameAcc( pForm->GetUnoControlModel() , UNO_QUERY );
542 if ( xNameAcc.is() )
544 // get sequence of control names
545 Sequence< OUString > aNames = xNameAcc->getElementNames();
546 const OUString* pNames = aNames.getConstArray();
547 sal_Int32 nCtrls = aNames.getLength();
549 // create a map of tab indices and control names, sorted by tab index
550 IndexToNameMap aIndexToNameMap;
551 for ( sal_Int32 i = 0; i < nCtrls; ++i )
553 // get control name
554 OUString aName( pNames[i] );
556 // get tab index
557 sal_Int16 nTabIndex = -1;
558 Any aCtrl = xNameAcc->getByName( aName );
559 Reference< beans::XPropertySet > xPSet;
560 aCtrl >>= xPSet;
561 if ( xPSet.is() && xPSet == Reference< beans::XPropertySet >( evt.Source, UNO_QUERY ) )
562 evt.OldValue >>= nTabIndex;
563 else if ( xPSet.is() )
564 xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
566 // insert into map
567 aIndexToNameMap.emplace( nTabIndex, aName );
570 // create a helper list of control names, sorted by tab index
571 std::vector< OUString > aNameList( aIndexToNameMap.size() );
572 std::transform(
573 aIndexToNameMap.begin(), aIndexToNameMap.end(),
574 aNameList.begin(),
575 ::o3tl::select2nd< IndexToNameMap::value_type >( )
578 // check tab index
579 sal_Int16 nOldTabIndex = 0;
580 evt.OldValue >>= nOldTabIndex;
581 sal_Int16 nNewTabIndex = 0;
582 evt.NewValue >>= nNewTabIndex;
583 if ( nNewTabIndex < 0 )
584 nNewTabIndex = 0;
585 else if ( nNewTabIndex > nCtrls - 1 )
586 nNewTabIndex = sal::static_int_cast<sal_Int16>( nCtrls - 1 );
588 // reorder helper list
589 OUString aCtrlName = aNameList[nOldTabIndex];
590 aNameList.erase( aNameList.begin() + nOldTabIndex );
591 aNameList.insert( aNameList.begin() + nNewTabIndex , aCtrlName );
593 // set new tab indices
594 for ( sal_Int32 i = 0; i < nCtrls; ++i )
596 Any aCtrl = xNameAcc->getByName( aNameList[i] );
597 Reference< beans::XPropertySet > xPSet;
598 aCtrl >>= xPSet;
599 if ( xPSet.is() )
601 assert(i >= SAL_MIN_INT16);
602 if (i > SAL_MAX_INT16)
604 SAL_WARN("basctl", "tab " << i << " > SAL_MAX_INT16");
605 continue;
607 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(i)) );
611 // reorder objects in drawing page
612 getSdrModelFromSdrObject().GetPage(0)->SetObjectOrdNum( nOldTabIndex + 1, nNewTabIndex + 1 );
614 pForm->UpdateTabOrderAndGroups();
617 // start listening with all children
618 for (auto const& child : aChildList)
620 child->StartListening();
624 bool DlgEdObj::supportsService( OUString const & serviceName ) const
626 bool bSupports = false;
628 Reference< lang::XServiceInfo > xServiceInfo( GetUnoControlModel() , UNO_QUERY );
629 // TODO: cache xServiceInfo as member?
630 if ( xServiceInfo.is() )
631 bSupports = xServiceInfo->supportsService( serviceName );
633 return bSupports;
636 OUString DlgEdObj::GetDefaultName() const
638 OUString sResId;
639 OUString aDefaultName;
640 if ( supportsService( "com.sun.star.awt.UnoControlDialogModel" ) )
642 sResId = RID_STR_CLASS_DIALOG;
644 else if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ) )
646 sResId = RID_STR_CLASS_BUTTON;
648 else if ( supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) )
650 sResId = RID_STR_CLASS_RADIOBUTTON;
652 else if ( supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) )
654 sResId = RID_STR_CLASS_CHECKBOX;
656 else if ( supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) )
658 sResId = RID_STR_CLASS_LISTBOX;
660 else if ( supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) )
662 sResId = RID_STR_CLASS_COMBOBOX;
664 else if ( supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) )
666 sResId = RID_STR_CLASS_GROUPBOX;
668 else if ( supportsService( "com.sun.star.awt.UnoControlEditModel" ) )
670 sResId = RID_STR_CLASS_EDIT;
672 else if ( supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
674 sResId = RID_STR_CLASS_FIXEDTEXT;
676 else if ( supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) )
678 sResId = RID_STR_CLASS_IMAGECONTROL;
680 else if ( supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) )
682 sResId = RID_STR_CLASS_PROGRESSBAR;
684 else if ( supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) )
686 sResId = RID_STR_CLASS_SCROLLBAR;
688 else if ( supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ) )
690 sResId = RID_STR_CLASS_FIXEDLINE;
692 else if ( supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ) )
694 sResId = RID_STR_CLASS_DATEFIELD;
696 else if ( supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ) )
698 sResId = RID_STR_CLASS_TIMEFIELD;
700 else if ( supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ) )
702 sResId = RID_STR_CLASS_NUMERICFIELD;
704 else if ( supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ) )
706 sResId = RID_STR_CLASS_CURRENCYFIELD;
708 else if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
710 sResId = RID_STR_CLASS_FORMATTEDFIELD;
712 else if ( supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ) )
714 sResId = RID_STR_CLASS_PATTERNFIELD;
716 else if ( supportsService( "com.sun.star.awt.UnoControlFileControlModel" ) )
718 sResId = RID_STR_CLASS_FILECONTROL;
720 else if ( supportsService( "com.sun.star.awt.tree.TreeControlModel" ) )
722 sResId = RID_STR_CLASS_TREECONTROL;
724 else if ( supportsService( "com.sun.star.awt.grid.UnoControlGridModel" ) )
726 sResId = RID_STR_CLASS_GRIDCONTROL;
728 else if ( supportsService( "com.sun.star.awt.UnoControlFixedHyperlinkModel" ) )
730 sResId = RID_STR_CLASS_HYPERLINKCONTROL;
732 else if ( supportsService( "com.sun.star.awt.UnoControlSpinButtonModel" ) )
734 sResId = RID_STR_CLASS_SPINCONTROL;
736 else
738 sResId = RID_STR_CLASS_CONTROL;
741 if (!sResId.isEmpty())
742 aDefaultName = sResId;
744 return aDefaultName;
747 OUString DlgEdObj::GetUniqueName() const
749 OUString aUniqueName;
750 uno::Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), uno::UNO_QUERY);
752 if ( xNameAcc.is() )
754 sal_Int32 n = 0;
755 OUString aDefaultName = GetDefaultName();
759 aUniqueName = aDefaultName + OUString::number(++n);
760 } while (xNameAcc->hasByName(aUniqueName));
763 return aUniqueName;
766 SdrInventor DlgEdObj::GetObjInventor() const
768 return SdrInventor::BasicDialog;
771 SdrObjKind DlgEdObj::GetObjIdentifier() const
773 if ( supportsService( "com.sun.star.awt.UnoControlDialogModel" ))
775 return OBJ_DLG_DIALOG;
777 else if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ))
779 return OBJ_DLG_PUSHBUTTON;
781 else if ( supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ))
783 return OBJ_DLG_RADIOBUTTON;
785 else if ( supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ))
787 return OBJ_DLG_CHECKBOX;
789 else if ( supportsService( "com.sun.star.awt.UnoControlListBoxModel" ))
791 return OBJ_DLG_LISTBOX;
793 else if ( supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ))
795 return OBJ_DLG_COMBOBOX;
797 else if ( supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ))
799 return OBJ_DLG_GROUPBOX;
801 else if ( supportsService( "com.sun.star.awt.UnoControlEditModel" ))
803 return OBJ_DLG_EDIT;
805 else if ( supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ))
807 return OBJ_DLG_FIXEDTEXT;
809 else if ( supportsService( "com.sun.star.awt.UnoControlImageControlModel" ))
811 return OBJ_DLG_IMAGECONTROL;
813 else if ( supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ))
815 return OBJ_DLG_PROGRESSBAR;
817 else if ( supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ))
819 return OBJ_DLG_HSCROLLBAR;
821 else if ( supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ))
823 return OBJ_DLG_HFIXEDLINE;
825 else if ( supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ))
827 return OBJ_DLG_DATEFIELD;
829 else if ( supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ))
831 return OBJ_DLG_TIMEFIELD;
833 else if ( supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ))
835 return OBJ_DLG_NUMERICFIELD;
837 else if ( supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ))
839 return OBJ_DLG_CURRENCYFIELD;
841 else if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ))
843 return OBJ_DLG_FORMATTEDFIELD;
845 else if ( supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ))
847 return OBJ_DLG_PATTERNFIELD;
849 else if ( supportsService( "com.sun.star.awt.UnoControlFileControlModel" ))
851 return OBJ_DLG_FILECONTROL;
853 else if ( supportsService( "com.sun.star.awt.tree.TreeControlModel" ))
855 return OBJ_DLG_TREECONTROL;
857 else if ( supportsService( "com.sun.star.awt.grid.UnoControlGridModel" ))
859 return OBJ_DLG_GRIDCONTROL;
861 else if ( supportsService( "com.sun.star.awt.UnoControlFixedHyperlinkModel" ))
863 return OBJ_DLG_HYPERLINKCONTROL;
865 else
867 return OBJ_DLG_CONTROL;
871 void DlgEdObj::clonedFrom(const DlgEdObj* _pSource)
873 // set parent form
874 pDlgEdForm = _pSource->pDlgEdForm;
876 // add child to parent form
877 pDlgEdForm->AddChild( this );
879 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
880 if ( xPSet.is() )
882 // set new name
883 OUString aOUniqueName( GetUniqueName() );
884 Any aUniqueName;
885 aUniqueName <<= aOUniqueName;
886 xPSet->setPropertyValue( DLGED_PROP_NAME, aUniqueName );
888 Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
889 if ( xCont.is() )
891 // set tabindex
892 Sequence< OUString > aNames = xCont->getElementNames();
893 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(aNames.getLength())) );
895 // insert control model in dialog model
896 Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
897 xCont->insertByName( aOUniqueName, Any(xCtrl) );
899 pDlgEdForm->UpdateTabOrderAndGroups();
903 // start listening
904 StartListening();
907 DlgEdObj* DlgEdObj::CloneSdrObject(SdrModel& rTargetModel) const
909 DlgEdObj* pDlgEdObj = CloneHelper< DlgEdObj >(rTargetModel);
910 DBG_ASSERT( pDlgEdObj != nullptr, "DlgEdObj::Clone: invalid clone!" );
911 if ( pDlgEdObj )
912 pDlgEdObj->clonedFrom( this );
914 return pDlgEdObj;
917 SdrObjectUniquePtr DlgEdObj::getFullDragClone() const
919 // no need to really add the clone for dragging, it's a temporary
920 // object
921 SdrObjectUniquePtr pObj( new SdrUnoObj(
922 getSdrModelFromSdrObject(),
923 OUString()) );
924 *pObj = *static_cast<const SdrUnoObj*>(this);
926 return pObj;
929 void DlgEdObj::NbcMove( const Size& rSize )
931 SdrUnoObj::NbcMove( rSize );
933 // stop listening
934 EndListening(false);
936 // set geometry properties
937 SetPropsFromRect();
939 // start listening
940 StartListening();
942 // dialog model changed
943 GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
946 void DlgEdObj::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
948 SdrUnoObj::NbcResize( rRef, xFract, yFract );
950 // stop listening
951 EndListening(false);
953 // set geometry properties
954 SetPropsFromRect();
956 // start listening
957 StartListening();
959 // dialog model changed
960 GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
963 bool DlgEdObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
965 bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
967 // tdf#120674 after interactive creation, the SdrObject (this) has no SdrPage yet
968 // due to not being inserted. Usually this should be handled in a ::handlePageChange
969 // implementation. For historical reasons, the SdrPage (which is the DlgEdPage) was
970 // already set. For now, get it from the SdrDragStat and use it to access and set
971 // the local pDlgEdForm
972 if(nullptr == pDlgEdForm && nullptr != rStat.GetPageView())
974 const DlgEdPage* pDlgEdPage(dynamic_cast<const DlgEdPage*>(rStat.GetPageView()->GetPage()));
976 if(nullptr != pDlgEdPage)
978 // set parent form
979 pDlgEdForm = pDlgEdPage->GetDlgEdForm();
983 SetDefaults();
984 StartListening();
986 return bResult;
989 void DlgEdObj::SetDefaults()
991 if ( !pDlgEdForm )
992 return;
994 // add child to parent form
995 pDlgEdForm->AddChild( this );
997 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
998 if ( xPSet.is() )
1000 // get unique name
1001 OUString aOUniqueName( GetUniqueName() );
1003 // set name property
1004 xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOUniqueName) );
1006 // set labels
1007 if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ) ||
1008 supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) ||
1009 supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) ||
1010 supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) ||
1011 supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
1013 xPSet->setPropertyValue( DLGED_PROP_LABEL, Any(aOUniqueName) );
1016 // set number formats supplier for formatted field
1017 if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
1019 Reference< util::XNumberFormatsSupplier > xSupplier = GetDlgEdForm()->GetDlgEditor().GetNumberFormatsSupplier();
1020 if ( xSupplier.is() )
1022 xPSet->setPropertyValue( DLGED_PROP_FORMATSSUPPLIER, Any(xSupplier) );
1026 // set geometry properties
1027 SetPropsFromRect();
1029 Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
1030 if ( xCont.is() )
1032 // set tabindex
1033 Sequence< OUString > aNames = xCont->getElementNames();
1034 uno::Any aTabIndex;
1035 aTabIndex <<= static_cast<sal_Int16>(aNames.getLength());
1036 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, aTabIndex );
1038 // set step
1039 Reference< beans::XPropertySet > xPSetForm( xCont, UNO_QUERY );
1040 if ( xPSetForm.is() )
1042 Any aStep = xPSetForm->getPropertyValue( DLGED_PROP_STEP );
1043 xPSet->setPropertyValue( DLGED_PROP_STEP, aStep );
1046 // insert control model in dialog model
1047 Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
1048 Any aAny;
1049 aAny <<= xCtrl;
1050 xCont->insertByName( aOUniqueName , aAny );
1052 LocalizationMgr::setControlResourceIDsForNewEditorObject(
1053 &GetDialogEditor(), aAny, aOUniqueName
1056 pDlgEdForm->UpdateTabOrderAndGroups();
1060 // dialog model changed
1061 pDlgEdForm->GetDlgEditor().SetDialogModelChanged();
1064 void DlgEdObj::StartListening()
1066 DBG_ASSERT(!isListening(), "DlgEdObj::StartListening: already listening!");
1068 if (isListening())
1069 return;
1071 bIsListening = true;
1073 // XPropertyChangeListener
1074 Reference< XPropertySet > xControlModel( GetUnoControlModel() , UNO_QUERY );
1075 if (!m_xPropertyChangeListener.is() && xControlModel.is())
1077 // create listener
1078 m_xPropertyChangeListener = new DlgEdPropListenerImpl(*this);
1080 // register listener to properties
1081 xControlModel->addPropertyChangeListener( OUString() , m_xPropertyChangeListener );
1084 // XContainerListener
1085 Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
1086 if( !m_xContainerListener.is() && xEventsSupplier.is() )
1088 // create listener
1089 m_xContainerListener = new DlgEdEvtContListenerImpl(*this);
1091 // register listener to script event container
1092 Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
1093 DBG_ASSERT(xEventCont.is(), "DlgEdObj::StartListening: control model has no script event container!");
1094 Reference< XContainer > xCont( xEventCont , UNO_QUERY );
1095 if (xCont.is())
1096 xCont->addContainerListener( m_xContainerListener );
1100 void DlgEdObj::EndListening(bool bRemoveListener)
1102 DBG_ASSERT(isListening(), "DlgEdObj::EndListening: not listening currently!");
1104 if (!isListening())
1105 return;
1107 bIsListening = false;
1109 if (!bRemoveListener)
1110 return;
1112 // XPropertyChangeListener
1113 Reference< XPropertySet > xControlModel(GetUnoControlModel(), UNO_QUERY);
1114 if ( m_xPropertyChangeListener.is() && xControlModel.is() )
1116 // remove listener
1117 xControlModel->removePropertyChangeListener( OUString() , m_xPropertyChangeListener );
1119 m_xPropertyChangeListener.clear();
1121 // XContainerListener
1122 Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
1123 if( m_xContainerListener.is() && xEventsSupplier.is() )
1125 // remove listener
1126 Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
1127 DBG_ASSERT(xEventCont.is(), "DlgEdObj::EndListening: control model has no script event container!");
1128 Reference< XContainer > xCont( xEventCont , UNO_QUERY );
1129 if (xCont.is())
1130 xCont->removeContainerListener( m_xContainerListener );
1132 m_xContainerListener.clear();
1135 void DlgEdObj::_propertyChange( const css::beans::PropertyChangeEvent& evt )
1137 if (!isListening())
1138 return;
1140 DlgEdForm* pRealDlgEdForm = dynamic_cast<DlgEdForm*>(this);
1141 if (!pRealDlgEdForm)
1142 pRealDlgEdForm = GetDlgEdForm();
1143 if (!pRealDlgEdForm)
1144 return;
1145 DlgEditor& rDlgEditor = pRealDlgEdForm->GetDlgEditor();
1146 if (rDlgEditor.isInPaint())
1147 return;
1149 // dialog model changed
1150 rDlgEditor.SetDialogModelChanged();
1152 // update position and size
1153 if ( evt.PropertyName == DLGED_PROP_POSITIONX || evt.PropertyName == DLGED_PROP_POSITIONY ||
1154 evt.PropertyName == DLGED_PROP_WIDTH || evt.PropertyName == DLGED_PROP_HEIGHT ||
1155 evt.PropertyName == DLGED_PROP_DECORATION )
1157 PositionAndSizeChange( evt );
1159 if ( evt.PropertyName == DLGED_PROP_DECORATION )
1160 GetDialogEditor().ResetDialog();
1162 // change name of control in dialog model
1163 else if ( evt.PropertyName == DLGED_PROP_NAME )
1165 if (!dynamic_cast<DlgEdForm*>(this))
1169 NameChange(evt);
1171 catch (container::NoSuchElementException const&)
1173 css::uno::Any anyEx = cppu::getCaughtException();
1174 throw lang::WrappedTargetRuntimeException("", nullptr,
1175 anyEx);
1179 // update step
1180 else if ( evt.PropertyName == DLGED_PROP_STEP )
1182 UpdateStep();
1184 // change tabindex
1185 else if ( evt.PropertyName == DLGED_PROP_TABINDEX )
1187 if (!dynamic_cast<DlgEdForm*>(this))
1188 TabIndexChange(evt);
1192 void DlgEdObj::_elementInserted()
1194 if (isListening())
1196 // dialog model changed
1197 GetDialogEditor().SetDialogModelChanged();
1201 void DlgEdObj::_elementReplaced()
1203 if (isListening())
1205 // dialog model changed
1206 GetDialogEditor().SetDialogModelChanged();
1210 void DlgEdObj::_elementRemoved()
1212 if (isListening())
1214 // dialog model changed
1215 GetDialogEditor().SetDialogModelChanged();
1219 void DlgEdObj::SetLayer(SdrLayerID nLayer)
1221 SdrLayerID nOldLayer = GetLayer();
1223 if ( nLayer != nOldLayer )
1225 SdrUnoObj::SetLayer( nLayer );
1227 DlgEdHint aHint( DlgEdHint::LAYERCHANGED, this );
1228 GetDlgEdForm()->GetDlgEditor().Broadcast( aHint );
1232 DlgEdForm::DlgEdForm(
1233 SdrModel& rSdrModel,
1234 DlgEditor& rDlgEditor_)
1235 : DlgEdObj(rSdrModel),
1236 rDlgEditor(rDlgEditor_)
1240 DlgEdForm::~DlgEdForm()
1244 void DlgEdForm::SetRectFromProps()
1246 // get form position and size from properties
1247 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
1248 if ( !xPSet.is() )
1249 return;
1251 sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
1252 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
1253 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
1254 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
1255 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
1257 // transform coordinates
1258 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
1259 if ( TransformFormToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
1261 // set rectangle position and size
1262 Point aPoint( nXOut, nYOut );
1263 Size aSize( nWidthOut, nHeightOut );
1264 SetSnapRect( tools::Rectangle( aPoint, aSize ) );
1268 void DlgEdForm::SetPropsFromRect()
1270 // get form position and size from rectangle
1271 tools::Rectangle aRect_ = GetSnapRect();
1272 sal_Int32 nXIn = aRect_.Left();
1273 sal_Int32 nYIn = aRect_.Top();
1274 sal_Int32 nWidthIn = aRect_.GetWidth();
1275 sal_Int32 nHeightIn = aRect_.GetHeight();
1277 // transform coordinates
1278 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
1279 if ( TransformSdrToFormCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
1281 // set properties
1282 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
1283 if ( xPSet.is() )
1285 xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
1286 xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
1287 xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
1288 xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
1293 void DlgEdForm::AddChild( DlgEdObj* pDlgEdObj )
1295 pChildren.push_back( pDlgEdObj );
1298 void DlgEdForm::RemoveChild( DlgEdObj* pDlgEdObj )
1300 pChildren.erase( std::remove( pChildren.begin() , pChildren.end() , pDlgEdObj ) );
1303 void DlgEdForm::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
1305 DlgEditor& rEditor = GetDlgEditor();
1306 DlgEdPage& rPage = rEditor.GetPage();
1308 sal_Int32 nPageXIn = 0;
1309 sal_Int32 nPageYIn = 0;
1310 Size aPageSize = rPage.GetSize();
1311 sal_Int32 nPageWidthIn = aPageSize.Width();
1312 sal_Int32 nPageHeightIn = aPageSize.Height();
1313 sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
1314 if ( TransformSdrToFormCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
1316 Reference< beans::XPropertySet > xPSetForm( GetUnoControlModel(), UNO_QUERY );
1317 if ( xPSetForm.is() )
1319 sal_Int32 nValue = 0;
1320 evt.NewValue >>= nValue;
1321 sal_Int32 nNewValue = nValue;
1323 if ( evt.PropertyName == DLGED_PROP_POSITIONX )
1325 if ( nNewValue < nPageX )
1326 nNewValue = nPageX;
1328 else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
1330 if ( nNewValue < nPageY )
1331 nNewValue = nPageY;
1333 else if ( evt.PropertyName == DLGED_PROP_WIDTH )
1335 if ( nNewValue < 1 )
1336 nNewValue = 1;
1338 else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
1340 if ( nNewValue < 1 )
1341 nNewValue = 1;
1344 if ( nNewValue != nValue )
1346 EndListening( false );
1347 xPSetForm->setPropertyValue( evt.PropertyName, Any(nNewValue) );
1348 StartListening();
1353 bool bAdjustedPageSize = rEditor.AdjustPageSize();
1354 SetRectFromProps();
1355 std::vector<DlgEdObj*> const& aChildList = GetChildren();
1357 if ( bAdjustedPageSize )
1359 rEditor.InitScrollBars();
1360 aPageSize = rPage.GetSize();
1361 nPageWidthIn = aPageSize.Width();
1362 nPageHeightIn = aPageSize.Height();
1363 if ( TransformSdrToControlCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
1365 for (auto const& child : aChildList)
1367 Reference< beans::XPropertySet > xPSet( child->GetUnoControlModel(), UNO_QUERY );
1368 if ( xPSet.is() )
1370 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
1371 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
1372 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
1373 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
1374 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
1376 sal_Int32 nNewX = nX;
1377 if ( nX + nWidth > nPageX + nPageWidth )
1379 nNewX = nPageX + nPageWidth - nWidth;
1380 if ( nNewX < nPageX )
1381 nNewX = nPageX;
1383 if ( nNewX != nX )
1385 EndListening( false );
1386 xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nNewX) );
1387 StartListening();
1390 sal_Int32 nNewY = nY;
1391 if ( nY + nHeight > nPageY + nPageHeight )
1393 nNewY = nPageY + nPageHeight - nHeight;
1394 if ( nNewY < nPageY )
1395 nNewY = nPageY;
1397 if ( nNewY != nY )
1399 EndListening( false );
1400 xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nNewY) );
1401 StartListening();
1408 for (auto const& child : aChildList)
1409 child->SetRectFromProps();
1412 void DlgEdForm::UpdateStep()
1414 SdrPage* pSdrPage = getSdrPageFromSdrObject();
1416 if ( pSdrPage )
1418 const size_t nObjCount = pSdrPage->GetObjCount();
1419 for ( size_t i = 0 ; i < nObjCount ; i++ )
1421 DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pSdrPage->GetObj(i));
1422 if (pDlgEdObj && !dynamic_cast<DlgEdForm*>(pDlgEdObj))
1423 pDlgEdObj->UpdateStep();
1428 void DlgEdForm::UpdateTabIndices()
1430 // stop listening with all children
1431 for (auto const& child : pChildren)
1433 child->EndListening( false );
1436 Reference< css::container::XNameAccess > xNameAcc( GetUnoControlModel() , UNO_QUERY );
1437 if ( xNameAcc.is() )
1439 // get sequence of control names
1440 Sequence< OUString > aNames = xNameAcc->getElementNames();
1441 const OUString* pNames = aNames.getConstArray();
1442 sal_Int32 nCtrls = aNames.getLength();
1444 // create a map of tab indices and control names, sorted by tab index
1445 IndexToNameMap aIndexToNameMap;
1446 for ( sal_Int32 i = 0; i < nCtrls; ++i )
1448 // get name
1449 OUString aName( pNames[i] );
1451 // get tab index
1452 sal_Int16 nTabIndex = -1;
1453 Any aCtrl = xNameAcc->getByName( aName );
1454 Reference< css::beans::XPropertySet > xPSet;
1455 aCtrl >>= xPSet;
1456 if ( xPSet.is() )
1457 xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
1459 // insert into map
1460 aIndexToNameMap.emplace( nTabIndex, aName );
1463 // set new tab indices
1464 sal_Int16 nNewTabIndex = 0;
1465 for (auto const& indexToName : aIndexToNameMap)
1467 Any aCtrl = xNameAcc->getByName( indexToName.second );
1468 Reference< beans::XPropertySet > xPSet;
1469 aCtrl >>= xPSet;
1470 if ( xPSet.is() )
1472 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(nNewTabIndex) );
1473 nNewTabIndex++;
1477 UpdateTabOrderAndGroups();
1480 // start listening with all children
1481 for (auto const& child : pChildren)
1483 child->StartListening();
1487 void DlgEdForm::UpdateTabOrder()
1489 // When the tabindex of a control model changes, the dialog control is
1490 // notified about those changes. Due to #109067# (bad performance of
1491 // dialog editor) the dialog control doesn't activate the tab order
1492 // in design mode. When the dialog editor has reordered all
1493 // tabindices, this method allows to activate the taborder afterwards.
1495 Reference< awt::XUnoControlContainer > xCont( GetControl(), UNO_QUERY );
1496 if ( xCont.is() )
1498 Sequence< Reference< awt::XTabController > > aSeqTabCtrls = xCont->getTabControllers();
1499 const Reference< awt::XTabController >* pTabCtrls = aSeqTabCtrls.getConstArray();
1500 sal_Int32 nCount = aSeqTabCtrls.getLength();
1501 for ( sal_Int32 i = 0; i < nCount; ++i )
1502 pTabCtrls[i]->activateTabOrder();
1506 void DlgEdForm::UpdateGroups()
1508 // The grouping of radio buttons in a dialog is done by vcl.
1509 // In the dialog editor we have two views (=controls) for one
1510 // radio button model. One control is owned by the dialog control,
1511 // but not visible in design mode. The other control is owned by
1512 // the drawing layer object. Whereas the grouping of the first
1513 // control is done by vcl, the grouping of the control in the
1514 // drawing layer has to be done here.
1516 Reference< awt::XTabControllerModel > xTabModel( GetUnoControlModel() , UNO_QUERY );
1517 if ( !xTabModel.is() )
1518 return;
1520 // create a global list of controls that belong to the dialog
1521 std::vector<DlgEdObj*> aChildList = GetChildren();
1522 sal_uInt32 nSize = aChildList.size();
1523 Sequence< Reference< awt::XControl > > aSeqControls( nSize );
1524 for ( sal_uInt32 i = 0; i < nSize; ++i )
1525 aSeqControls.getArray()[i] = aChildList[i]->GetControl();
1527 sal_Int32 nGroupCount = xTabModel->getGroupCount();
1528 for ( sal_Int32 nGroup = 0; nGroup < nGroupCount; ++nGroup )
1530 // get a list of control models that belong to this group
1531 OUString aName;
1532 Sequence< Reference< awt::XControlModel > > aSeqModels;
1533 xTabModel->getGroup( nGroup, aSeqModels, aName );
1534 const Reference< awt::XControlModel >* pModels = aSeqModels.getConstArray();
1535 sal_Int32 nModelCount = aSeqModels.getLength();
1537 // create a list of peers that belong to this group
1538 Sequence< Reference< awt::XWindow > > aSeqPeers( nModelCount );
1539 for ( sal_Int32 nModel = 0; nModel < nModelCount; ++nModel )
1541 // for each control model find the corresponding control in the global list
1542 const Reference< awt::XControl >* pControls = aSeqControls.getConstArray();
1543 sal_Int32 nControlCount = aSeqControls.getLength();
1544 for ( sal_Int32 nControl = 0; nControl < nControlCount; ++nControl )
1546 const Reference< awt::XControl > xCtrl( pControls[nControl] );
1547 if ( xCtrl.is() )
1549 Reference< awt::XControlModel > xCtrlModel( xCtrl->getModel() );
1550 if ( xCtrlModel.get() == pModels[nModel].get() )
1552 // get the control peer and insert into the list of peers
1553 aSeqPeers.getArray()[ nModel ].set( xCtrl->getPeer(), UNO_QUERY );
1554 break;
1560 // set the group at the dialog peer
1561 Reference< awt::XControl > xDlg = GetControl();
1562 if ( xDlg.is() )
1564 Reference< awt::XVclContainerPeer > xDlgPeer( xDlg->getPeer(), UNO_QUERY );
1565 if ( xDlgPeer.is() )
1566 xDlgPeer->setGroup( aSeqPeers );
1571 void DlgEdForm::UpdateTabOrderAndGroups()
1573 UpdateTabOrder();
1574 UpdateGroups();
1577 void DlgEdForm::NbcMove( const Size& rSize )
1579 SdrUnoObj::NbcMove( rSize );
1581 // set geometry properties of form
1582 EndListening(false);
1583 SetPropsFromRect();
1584 StartListening();
1586 // set geometry properties of all children
1587 for (auto const& child : pChildren)
1589 child->EndListening(false);
1590 child->SetPropsFromRect();
1591 child->StartListening();
1594 // dialog model changed
1595 GetDlgEditor().SetDialogModelChanged();
1598 void DlgEdForm::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
1600 SdrUnoObj::NbcResize( rRef, xFract, yFract );
1602 // set geometry properties of form
1603 EndListening(false);
1604 SetPropsFromRect();
1605 StartListening();
1607 // set geometry properties of all children
1608 for (auto const& child : pChildren)
1610 child->EndListening(false);
1611 child->SetPropsFromRect();
1612 child->StartListening();
1615 // dialog model changed
1616 GetDlgEditor().SetDialogModelChanged();
1619 bool DlgEdForm::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
1621 bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
1623 // stop listening
1624 EndListening(false);
1626 // set geometry properties
1627 SetPropsFromRect();
1629 // dialog model changed
1630 GetDlgEditor().SetDialogModelChanged();
1632 // start listening
1633 StartListening();
1635 return bResult;
1638 awt::DeviceInfo DlgEdForm::getDeviceInfo() const
1640 awt::DeviceInfo aDeviceInfo;
1642 DlgEditor& rEditor = GetDlgEditor();
1643 vcl::Window& rWindow = rEditor.GetWindow();
1645 // obtain an XControl
1646 ::utl::SharedUNOComponent< awt::XControl > xDialogControl; // ensures auto-disposal, if needed
1647 xDialogControl.reset( GetControl(), ::utl::SharedUNOComponent< awt::XControl >::NoTakeOwnership );
1648 if ( !xDialogControl.is() )
1650 // don't create a temporary control all the time, this method here is called
1651 // way too often. Instead, use a cached DeviceInfo.
1652 // #i74065#
1653 if ( !!mpDeviceInfo )
1654 return *mpDeviceInfo;
1656 Reference< awt::XControlContainer > xEditorControlContainer( rEditor.GetWindowControlContainer() );
1657 xDialogControl.reset(
1658 GetTemporaryControlForWindow(rWindow, xEditorControlContainer),
1659 utl::SharedUNOComponent< awt::XControl >::TakeOwnership
1663 Reference< awt::XDevice > xDialogDevice;
1664 if ( xDialogControl.is() )
1665 xDialogDevice.set( xDialogControl->getPeer(), UNO_QUERY );
1666 DBG_ASSERT( xDialogDevice.is(), "DlgEdForm::getDeviceInfo: no device!" );
1667 if ( xDialogDevice.is() )
1668 aDeviceInfo = xDialogDevice->getInfo();
1670 mpDeviceInfo = aDeviceInfo;
1672 return aDeviceInfo;
1674 void DlgEdObj::MakeDataAware( const Reference< frame::XModel >& xModel )
1676 // Need to flesh this out, currently we will only support data-aware controls for calc
1677 // and only handle a subset of functionality e.g. linked-cell and cell range data source. Of course later
1678 // we need to disambiguate for writer ( and others ? ) and also support the generic form (db) bindings
1679 // we need some more work in xmlscript to be able to handle that
1680 Reference< lang::XMultiServiceFactory > xFac( xModel, UNO_QUERY );
1681 Reference< form::binding::XBindableValue > xBindable( GetUnoControlModel(), UNO_QUERY );
1682 Reference< form::binding::XListEntrySink > xListEntrySink( GetUnoControlModel(), UNO_QUERY );
1683 if ( !xFac.is() )
1684 return;
1686 css::table::CellAddress aApiAddress;
1688 //tdf#90361 CellValueBinding and CellRangeListSource are unusable
1689 //without being initialized, so use createInstanceWithArguments with a
1690 //dummy BoundCell instead of createInstance. This at least results in
1691 //the dialog editor not falling.
1692 css::beans::NamedValue aValue;
1693 aValue.Name = "BoundCell";
1694 aValue.Value <<= aApiAddress;
1696 Sequence< Any > aArgs( 1 );
1697 aArgs[ 0 ] <<= aValue;
1699 if ( xBindable.is() )
1701 Reference< form::binding::XValueBinding > xBinding( xFac->createInstanceWithArguments( "com.sun.star.table.CellValueBinding", aArgs ), UNO_QUERY );
1702 xBindable->setValueBinding( xBinding );
1704 if ( xListEntrySink.is() )
1706 Reference< form::binding::XListEntrySource > xSource( xFac->createInstanceWithArguments( "com.sun.star.table.CellRangeListSource", aArgs ), UNO_QUERY );
1707 xListEntrySink->setListEntrySource( xSource );
1710 } // namespace basctl
1712 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */