Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / basctl / source / dlged / dlgedobj.cxx
blob008260b0bd219cbed43cfe9b56846ff05e738cf7
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>
22 #include <cassert>
24 #include <dlged.hxx>
25 #include <dlgeddef.hxx>
26 #include <dlgedlist.hxx>
27 #include <dlgedobj.hxx>
28 #include <dlgedpage.hxx>
29 #include <dlgedview.hxx>
30 #include <localizationmgr.hxx>
31 #include <strings.hxx>
33 #include <com/sun/star/beans/NamedValue.hpp>
34 #include <com/sun/star/form/binding/XBindableValue.hpp>
35 #include <com/sun/star/form/binding/XValueBinding.hpp>
36 #include <com/sun/star/form/binding/XListEntrySink.hpp>
37 #include <com/sun/star/awt/XUnoControlContainer.hpp>
38 #include <com/sun/star/awt/XVclContainerPeer.hpp>
39 #include <com/sun/star/container/XContainer.hpp>
40 #include <com/sun/star/lang/XServiceInfo.hpp>
41 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
42 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
43 #include <com/sun/star/table/CellAddress.hpp>
44 #include <o3tl/functional.hxx>
45 #include <unotools/sharedunocomponent.hxx>
46 #include <vcl/svapp.hxx>
48 namespace basctl
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::container;
55 using namespace ::com::sun::star::script;
58 DlgEditor& DlgEdObj::GetDialogEditor ()
60 if (DlgEdForm* pFormThis = dynamic_cast<DlgEdForm*>(this))
61 return pFormThis->GetDlgEditor();
62 else
63 return pDlgEdForm->GetDlgEditor();
66 DlgEdObj::DlgEdObj(SdrModel& rSdrModel)
67 : SdrUnoObj(rSdrModel, OUString())
68 ,bIsListening(false)
69 ,pDlgEdForm( nullptr )
73 DlgEdObj::DlgEdObj(
74 SdrModel& rSdrModel,
75 const OUString& rModelName,
76 const css::uno::Reference< css::lang::XMultiServiceFactory >& rxSFac)
77 : SdrUnoObj(rSdrModel, rModelName, rxSFac)
78 ,bIsListening(false)
79 ,pDlgEdForm( nullptr )
83 DlgEdObj::~DlgEdObj()
85 if ( isListening() )
86 EndListening(true);
89 namespace
91 /* returns the DlgEdForm which the given DlgEdObj belongs to
92 (which might in fact be the object itself)
94 Failure to obtain the form will be reported with an assertion in the non-product
95 version.
97 bool lcl_getDlgEdForm( DlgEdObj* _pObject, DlgEdForm*& _out_pDlgEdForm )
99 _out_pDlgEdForm = dynamic_cast< DlgEdForm* >( _pObject );
100 if ( !_out_pDlgEdForm )
101 _out_pDlgEdForm = _pObject->GetDlgEdForm();
102 DBG_ASSERT( _out_pDlgEdForm, "lcl_getDlgEdForm: no form!" );
103 return ( _out_pDlgEdForm != nullptr );
107 uno::Reference< awt::XControl > DlgEdObj::GetControl() const
109 uno::Reference< awt::XControl > xControl;
110 if (DlgEdForm const* pForm = GetDlgEdForm())
112 DlgEditor const& rEditor = pForm->GetDlgEditor();
113 xControl = GetUnoControl(rEditor.GetView(), rEditor.GetWindow());
115 return xControl;
118 bool DlgEdObj::TransformSdrToControlCoordinates(
119 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
120 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
122 // input position and size
123 Size aPos( nXIn, nYIn );
124 Size aSize( nWidthIn, nHeightIn );
126 // form position
127 DlgEdForm* pForm = nullptr;
128 if ( !lcl_getDlgEdForm( this, pForm ) )
129 return false;
130 tools::Rectangle aFormRect = pForm->GetSnapRect();
131 Size aFormPos( aFormRect.Left(), aFormRect.Top() );
133 // convert 100th_mm to pixel
134 OutputDevice* pDevice = Application::GetDefaultDevice();
135 DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToControlCoordinates: missing default device!" );
136 if ( !pDevice )
137 return false;
138 aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
139 aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
140 aFormPos = pDevice->LogicToPixel( aFormPos, MapMode( MapUnit::Map100thMM ) );
142 // subtract form position
143 aPos.AdjustWidth( -(aFormPos.Width()) );
144 aPos.AdjustHeight( -(aFormPos.Height()) );
146 // take window borders into account
147 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
148 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
149 if ( !xPSetForm.is() )
150 return false;
151 bool bDecoration = true;
152 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
153 if( bDecoration )
155 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
156 aPos.AdjustWidth( -(aDeviceInfo.LeftInset) );
157 aPos.AdjustHeight( -(aDeviceInfo.TopInset) );
160 // convert pixel to logic units
161 aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
162 aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
164 // set out parameters
165 nXOut = aPos.Width();
166 nYOut = aPos.Height();
167 nWidthOut = aSize.Width();
168 nHeightOut = aSize.Height();
170 return true;
173 bool DlgEdObj::TransformSdrToFormCoordinates(
174 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
175 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
177 // input position and size
178 Size aPos( nXIn, nYIn );
179 Size aSize( nWidthIn, nHeightIn );
181 // convert 100th_mm to pixel
182 OutputDevice* pDevice = Application::GetDefaultDevice();
183 DBG_ASSERT( pDevice, "DlgEdObj::TransformSdrToFormCoordinates: missing default device!" );
184 if ( !pDevice )
185 return false;
186 aPos = pDevice->LogicToPixel( aPos, MapMode( MapUnit::Map100thMM ) );
187 aSize = pDevice->LogicToPixel( aSize, MapMode( MapUnit::Map100thMM ) );
189 // take window borders into account
190 DlgEdForm* pForm = nullptr;
191 if ( !lcl_getDlgEdForm( this, pForm ) )
192 return false;
194 // take window borders into account
195 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
196 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
197 if ( !xPSetForm.is() )
198 return false;
199 bool bDecoration = true;
200 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
201 if( bDecoration )
203 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
204 aSize.AdjustWidth( -(aDeviceInfo.LeftInset + aDeviceInfo.RightInset) );
205 aSize.AdjustHeight( -(aDeviceInfo.TopInset + aDeviceInfo.BottomInset) );
207 // convert pixel to logic units
208 aPos = pDevice->PixelToLogic(aPos, MapMode(MapUnit::MapAppFont));
209 aSize = pDevice->PixelToLogic(aSize, MapMode(MapUnit::MapAppFont));
211 // set out parameters
212 nXOut = aPos.Width();
213 nYOut = aPos.Height();
214 nWidthOut = aSize.Width();
215 nHeightOut = aSize.Height();
217 return true;
220 bool DlgEdObj::TransformControlToSdrCoordinates(
221 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
222 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
224 // input position and size
225 Size aPos( nXIn, nYIn );
226 Size aSize( nWidthIn, nHeightIn );
228 // form position
229 DlgEdForm* pForm = nullptr;
230 if ( !lcl_getDlgEdForm( this, pForm ) )
231 return false;
233 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
234 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformControlToSdrCoordinates: no form property set!" );
235 if ( !xPSetForm.is() )
236 return false;
237 sal_Int32 nFormX = 0, nFormY = 0, nFormWidth, nFormHeight;
238 xPSetForm->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nFormX;
239 xPSetForm->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nFormY;
240 xPSetForm->getPropertyValue( DLGED_PROP_WIDTH ) >>= nFormWidth;
241 xPSetForm->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nFormHeight;
242 Size aFormPos( nFormX, nFormY );
244 // convert logic units to pixel
245 OutputDevice* pDevice = Application::GetDefaultDevice();
246 DBG_ASSERT( pDevice, "DlgEdObj::TransformControlToSdrCoordinates: missing default device!" );
247 if ( !pDevice )
248 return false;
249 aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
250 aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
251 aFormPos = pDevice->LogicToPixel(aFormPos, MapMode(MapUnit::MapAppFont));
253 // add form position
254 aPos.AdjustWidth(aFormPos.Width() );
255 aPos.AdjustHeight(aFormPos.Height() );
257 // take window borders into account
258 bool bDecoration = true;
259 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
260 if( bDecoration )
262 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
263 aPos.AdjustWidth(aDeviceInfo.LeftInset );
264 aPos.AdjustHeight(aDeviceInfo.TopInset );
267 // convert pixel to 100th_mm
268 aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
269 aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
271 // set out parameters
272 nXOut = aPos.Width();
273 nYOut = aPos.Height();
274 nWidthOut = aSize.Width();
275 nHeightOut = aSize.Height();
277 return true;
280 bool DlgEdObj::TransformFormToSdrCoordinates(
281 sal_Int32 nXIn, sal_Int32 nYIn, sal_Int32 nWidthIn, sal_Int32 nHeightIn,
282 sal_Int32& nXOut, sal_Int32& nYOut, sal_Int32& nWidthOut, sal_Int32& nHeightOut )
284 // input position and size
285 Size aPos( nXIn, nYIn );
286 Size aSize( nWidthIn, nHeightIn );
288 // convert logic units to pixel
289 OutputDevice* pDevice = Application::GetDefaultDevice();
290 DBG_ASSERT( pDevice, "DlgEdObj::TransformFormToSdrCoordinates: missing default device!" );
291 if ( !pDevice )
292 return false;
294 // take window borders into account
295 DlgEdForm* pForm = nullptr;
296 if ( !lcl_getDlgEdForm( this, pForm ) )
297 return false;
299 aPos = pDevice->LogicToPixel(aPos, MapMode(MapUnit::MapAppFont));
300 aSize = pDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
302 // take window borders into account
303 Reference< beans::XPropertySet > xPSetForm( pForm->GetUnoControlModel(), UNO_QUERY );
304 DBG_ASSERT( xPSetForm.is(), "DlgEdObj::TransformFormToSdrCoordinates: no form property set!" );
305 if ( !xPSetForm.is() )
306 return false;
307 bool bDecoration = true;
308 xPSetForm->getPropertyValue( DLGED_PROP_DECORATION ) >>= bDecoration;
309 if( bDecoration )
311 awt::DeviceInfo aDeviceInfo = pForm->getDeviceInfo();
312 aSize.AdjustWidth(aDeviceInfo.LeftInset + aDeviceInfo.RightInset );
313 aSize.AdjustHeight(aDeviceInfo.TopInset + aDeviceInfo.BottomInset );
316 // convert pixel to 100th_mm
317 aPos = pDevice->PixelToLogic( aPos, MapMode( MapUnit::Map100thMM ) );
318 aSize = pDevice->PixelToLogic( aSize, MapMode( MapUnit::Map100thMM ) );
320 // set out parameters
321 nXOut = aPos.Width();
322 nYOut = aPos.Height();
323 nWidthOut = aSize.Width();
324 nHeightOut = aSize.Height();
326 return true;
329 void DlgEdObj::SetRectFromProps()
331 // get control position and size from properties
332 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
333 if ( xPSet.is() )
335 sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
336 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
337 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
338 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
339 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
341 // transform coordinates
342 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
343 if ( TransformControlToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
345 // set rectangle position and size
346 Point aPoint( nXOut, nYOut );
347 Size aSize( nWidthOut, nHeightOut );
348 SetSnapRect( tools::Rectangle( aPoint, aSize ) );
353 void DlgEdObj::SetPropsFromRect()
355 // get control position and size from rectangle
356 tools::Rectangle aRect_ = GetSnapRect();
357 sal_Int32 nXIn = aRect_.Left();
358 sal_Int32 nYIn = aRect_.Top();
359 sal_Int32 nWidthIn = aRect_.GetWidth();
360 sal_Int32 nHeightIn = aRect_.GetHeight();
362 // transform coordinates
363 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
364 if ( TransformSdrToControlCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
366 // set properties
367 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
368 if ( xPSet.is() )
370 xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
371 xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
372 xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
373 xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
378 void DlgEdObj::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
380 DBG_ASSERT( pDlgEdForm, "DlgEdObj::PositionAndSizeChange: no form!" );
381 DlgEdPage& rPage = pDlgEdForm->GetDlgEditor().GetPage();
383 Size aPageSize = rPage.GetSize();
384 sal_Int32 nPageWidthIn = aPageSize.Width();
385 sal_Int32 nPageHeightIn = aPageSize.Height();
386 sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
387 if ( TransformSdrToControlCoordinates( 0/*nPageXIn*/, 0/*nPageYIn*/, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
389 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
390 if ( xPSet.is() )
392 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
393 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
394 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
395 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
396 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
398 sal_Int32 nValue = 0;
399 evt.NewValue >>= nValue;
400 sal_Int32 nNewValue = nValue;
402 if ( evt.PropertyName == DLGED_PROP_POSITIONX )
404 if ( nNewValue + nWidth > nPageX + nPageWidth )
405 nNewValue = nPageX + nPageWidth - nWidth;
406 if ( nNewValue < nPageX )
407 nNewValue = nPageX;
409 else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
411 if ( nNewValue + nHeight > nPageY + nPageHeight )
412 nNewValue = nPageY + nPageHeight - nHeight;
413 if ( nNewValue < nPageY )
414 nNewValue = nPageY;
416 else if ( evt.PropertyName == DLGED_PROP_WIDTH )
418 if ( nX + nNewValue > nPageX + nPageWidth )
419 nNewValue = nPageX + nPageWidth - nX;
420 if ( nNewValue < 1 )
421 nNewValue = 1;
423 else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
425 if ( nY + nNewValue > nPageY + nPageHeight )
426 nNewValue = nPageY + nPageHeight - nY;
427 if ( nNewValue < 1 )
428 nNewValue = 1;
431 if ( nNewValue != nValue )
433 EndListening( false );
434 xPSet->setPropertyValue( evt.PropertyName, Any(nNewValue) );
435 StartListening();
441 SetRectFromProps();
444 void DlgEdObj::NameChange( const css::beans::PropertyChangeEvent& evt )
446 // get old name
447 OUString aOldName;
448 evt.OldValue >>= aOldName;
450 // get new name
451 OUString aNewName;
452 evt.NewValue >>= aNewName;
454 if ( aNewName != aOldName )
456 Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), UNO_QUERY);
457 if ( xNameAcc.is() && xNameAcc->hasByName(aOldName) )
459 if (!xNameAcc->hasByName(aNewName) && !aNewName.isEmpty())
461 // remove the control by the old name and insert the control by the new name in the container
462 Reference< container::XNameContainer > xCont(xNameAcc, UNO_QUERY );
463 if ( xCont.is() )
465 Reference< awt::XControlModel > xCtrl(GetUnoControlModel(), UNO_QUERY);
466 Any aAny;
467 aAny <<= xCtrl;
468 xCont->removeByName( aOldName );
469 xCont->insertByName( aNewName , aAny );
471 LocalizationMgr::renameControlResourceIDsForEditorObject(
472 &GetDialogEditor(), aAny, aNewName
476 else
478 // set old name property
479 EndListening(false);
480 Reference< beans::XPropertySet > xPSet(GetUnoControlModel(), UNO_QUERY);
481 xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOldName) );
482 StartListening();
488 sal_Int32 DlgEdObj::GetStep() const
490 // get step property
491 sal_Int32 nStep = 0;
492 uno::Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), uno::UNO_QUERY );
493 if (xPSet.is())
495 xPSet->getPropertyValue( DLGED_PROP_STEP ) >>= nStep;
497 return nStep;
500 void DlgEdObj::UpdateStep()
502 sal_Int32 nCurStep = GetDlgEdForm()->GetStep();
503 sal_Int32 nStep = GetStep();
505 SdrLayerAdmin& rLayerAdmin(getSdrModelFromSdrObject().GetLayerAdmin());
506 SdrLayerID nHiddenLayerId = rLayerAdmin.GetLayerID( "HiddenLayer" );
507 SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName() );
509 if( nCurStep )
511 if ( nStep && (nStep != nCurStep) )
513 SetLayer( nHiddenLayerId );
515 else
517 SetLayer( nControlLayerId );
520 else
522 SetLayer( nControlLayerId );
526 void DlgEdObj::TabIndexChange( const beans::PropertyChangeEvent& evt )
528 DlgEdForm* pForm = GetDlgEdForm();
529 if ( pForm )
531 // stop listening with all children
532 std::vector<DlgEdObj*> aChildList = pForm->GetChildren();
533 for (auto const& child : aChildList)
535 child->EndListening( false );
538 Reference< container::XNameAccess > xNameAcc( pForm->GetUnoControlModel() , UNO_QUERY );
539 if ( xNameAcc.is() )
541 // get sequence of control names
542 Sequence< OUString > aNames = xNameAcc->getElementNames();
543 const OUString* pNames = aNames.getConstArray();
544 sal_Int32 nCtrls = aNames.getLength();
546 // create a map of tab indices and control names, sorted by tab index
547 IndexToNameMap aIndexToNameMap;
548 for ( sal_Int32 i = 0; i < nCtrls; ++i )
550 // get control name
551 OUString aName( pNames[i] );
553 // get tab index
554 sal_Int16 nTabIndex = -1;
555 Any aCtrl = xNameAcc->getByName( aName );
556 Reference< beans::XPropertySet > xPSet;
557 aCtrl >>= xPSet;
558 if ( xPSet.is() && xPSet == Reference< beans::XPropertySet >( evt.Source, UNO_QUERY ) )
559 evt.OldValue >>= nTabIndex;
560 else if ( xPSet.is() )
561 xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
563 // insert into map
564 aIndexToNameMap.emplace( nTabIndex, aName );
567 // create a helper list of control names, sorted by tab index
568 std::vector< OUString > aNameList( aIndexToNameMap.size() );
569 std::transform(
570 aIndexToNameMap.begin(), aIndexToNameMap.end(),
571 aNameList.begin(),
572 ::o3tl::select2nd< IndexToNameMap::value_type >( )
575 // check tab index
576 sal_Int16 nOldTabIndex = 0;
577 evt.OldValue >>= nOldTabIndex;
578 sal_Int16 nNewTabIndex = 0;
579 evt.NewValue >>= nNewTabIndex;
580 if ( nNewTabIndex < 0 )
581 nNewTabIndex = 0;
582 else if ( nNewTabIndex > nCtrls - 1 )
583 nNewTabIndex = sal::static_int_cast<sal_Int16>( nCtrls - 1 );
585 // reorder helper list
586 OUString aCtrlName = aNameList[nOldTabIndex];
587 aNameList.erase( aNameList.begin() + nOldTabIndex );
588 aNameList.insert( aNameList.begin() + nNewTabIndex , aCtrlName );
590 // set new tab indices
591 for ( sal_Int32 i = 0; i < nCtrls; ++i )
593 Any aCtrl = xNameAcc->getByName( aNameList[i] );
594 Reference< beans::XPropertySet > xPSet;
595 aCtrl >>= xPSet;
596 if ( xPSet.is() )
598 assert(i >= SAL_MIN_INT16);
599 if (i > SAL_MAX_INT16)
601 SAL_WARN("basctl", "tab " << i << " > SAL_MAX_INT16");
602 continue;
604 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(i)) );
608 // reorder objects in drawing page
609 getSdrModelFromSdrObject().GetPage(0)->SetObjectOrdNum( nOldTabIndex + 1, nNewTabIndex + 1 );
611 pForm->UpdateTabOrderAndGroups();
614 // start listening with all children
615 for (auto const& child : aChildList)
617 child->StartListening();
622 bool DlgEdObj::supportsService( OUString const & serviceName ) const
624 bool bSupports = false;
626 Reference< lang::XServiceInfo > xServiceInfo( GetUnoControlModel() , UNO_QUERY );
627 // TODO: cache xServiceInfo as member?
628 if ( xServiceInfo.is() )
629 bSupports = xServiceInfo->supportsService( serviceName );
631 return bSupports;
634 OUString DlgEdObj::GetDefaultName() const
636 OUString sResId;
637 OUString aDefaultName;
638 if ( supportsService( "com.sun.star.awt.UnoControlDialogModel" ) )
640 sResId = RID_STR_CLASS_DIALOG;
642 else if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ) )
644 sResId = RID_STR_CLASS_BUTTON;
646 else if ( supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) )
648 sResId = RID_STR_CLASS_RADIOBUTTON;
650 else if ( supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) )
652 sResId = RID_STR_CLASS_CHECKBOX;
654 else if ( supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) )
656 sResId = RID_STR_CLASS_LISTBOX;
658 else if ( supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) )
660 sResId = RID_STR_CLASS_COMBOBOX;
662 else if ( supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) )
664 sResId = RID_STR_CLASS_GROUPBOX;
666 else if ( supportsService( "com.sun.star.awt.UnoControlEditModel" ) )
668 sResId = RID_STR_CLASS_EDIT;
670 else if ( supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
672 sResId = RID_STR_CLASS_FIXEDTEXT;
674 else if ( supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) )
676 sResId = RID_STR_CLASS_IMAGECONTROL;
678 else if ( supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) )
680 sResId = RID_STR_CLASS_PROGRESSBAR;
682 else if ( supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) )
684 sResId = RID_STR_CLASS_SCROLLBAR;
686 else if ( supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ) )
688 sResId = RID_STR_CLASS_FIXEDLINE;
690 else if ( supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ) )
692 sResId = RID_STR_CLASS_DATEFIELD;
694 else if ( supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ) )
696 sResId = RID_STR_CLASS_TIMEFIELD;
698 else if ( supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ) )
700 sResId = RID_STR_CLASS_NUMERICFIELD;
702 else if ( supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ) )
704 sResId = RID_STR_CLASS_CURRENCYFIELD;
706 else if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
708 sResId = RID_STR_CLASS_FORMATTEDFIELD;
710 else if ( supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ) )
712 sResId = RID_STR_CLASS_PATTERNFIELD;
714 else if ( supportsService( "com.sun.star.awt.UnoControlFileControlModel" ) )
716 sResId = RID_STR_CLASS_FILECONTROL;
718 else if ( supportsService( "com.sun.star.awt.tree.TreeControlModel" ) )
720 sResId = RID_STR_CLASS_TREECONTROL;
722 else if ( supportsService( "com.sun.star.awt.UnoControlSpinButtonModel" ) )
724 sResId = RID_STR_CLASS_SPINCONTROL;
726 else
728 sResId = RID_STR_CLASS_CONTROL;
731 if (!sResId.isEmpty())
732 aDefaultName = sResId;
734 return aDefaultName;
737 OUString DlgEdObj::GetUniqueName() const
739 OUString aUniqueName;
740 uno::Reference< container::XNameAccess > xNameAcc((GetDlgEdForm()->GetUnoControlModel()), uno::UNO_QUERY);
742 if ( xNameAcc.is() )
744 sal_Int32 n = 0;
745 OUString aDefaultName = GetDefaultName();
749 aUniqueName = aDefaultName + OUString::number(++n);
750 } while (xNameAcc->hasByName(aUniqueName));
753 return aUniqueName;
756 SdrInventor DlgEdObj::GetObjInventor() const
758 return SdrInventor::BasicDialog;
761 sal_uInt16 DlgEdObj::GetObjIdentifier() const
763 if ( supportsService( "com.sun.star.awt.UnoControlDialogModel" ))
765 return OBJ_DLG_DIALOG;
767 else if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ))
769 return OBJ_DLG_PUSHBUTTON;
771 else if ( supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ))
773 return OBJ_DLG_RADIOBUTTON;
775 else if ( supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ))
777 return OBJ_DLG_CHECKBOX;
779 else if ( supportsService( "com.sun.star.awt.UnoControlListBoxModel" ))
781 return OBJ_DLG_LISTBOX;
783 else if ( supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ))
785 return OBJ_DLG_COMBOBOX;
787 else if ( supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ))
789 return OBJ_DLG_GROUPBOX;
791 else if ( supportsService( "com.sun.star.awt.UnoControlEditModel" ))
793 return OBJ_DLG_EDIT;
795 else if ( supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ))
797 return OBJ_DLG_FIXEDTEXT;
799 else if ( supportsService( "com.sun.star.awt.UnoControlImageControlModel" ))
801 return OBJ_DLG_IMAGECONTROL;
803 else if ( supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ))
805 return OBJ_DLG_PROGRESSBAR;
807 else if ( supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ))
809 return OBJ_DLG_HSCROLLBAR;
811 else if ( supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ))
813 return OBJ_DLG_HFIXEDLINE;
815 else if ( supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ))
817 return OBJ_DLG_DATEFIELD;
819 else if ( supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ))
821 return OBJ_DLG_TIMEFIELD;
823 else if ( supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ))
825 return OBJ_DLG_NUMERICFIELD;
827 else if ( supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ))
829 return OBJ_DLG_CURRENCYFIELD;
831 else if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ))
833 return OBJ_DLG_FORMATTEDFIELD;
835 else if ( supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ))
837 return OBJ_DLG_PATTERNFIELD;
839 else if ( supportsService( "com.sun.star.awt.UnoControlFileControlModel" ))
841 return OBJ_DLG_FILECONTROL;
843 else if ( supportsService( "com.sun.star.awt.tree.TreeControlModel" ))
845 return OBJ_DLG_TREECONTROL;
847 else
849 return OBJ_DLG_CONTROL;
853 void DlgEdObj::clonedFrom(const DlgEdObj* _pSource)
855 // set parent form
856 pDlgEdForm = _pSource->pDlgEdForm;
858 // add child to parent form
859 pDlgEdForm->AddChild( this );
861 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
862 if ( xPSet.is() )
864 // set new name
865 OUString aOUniqueName( GetUniqueName() );
866 Any aUniqueName;
867 aUniqueName <<= aOUniqueName;
868 xPSet->setPropertyValue( DLGED_PROP_NAME, aUniqueName );
870 Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
871 if ( xCont.is() )
873 // set tabindex
874 Sequence< OUString > aNames = xCont->getElementNames();
875 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(static_cast<sal_Int16>(aNames.getLength())) );
877 // insert control model in dialog model
878 Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
879 xCont->insertByName( aOUniqueName, Any(xCtrl) );
881 pDlgEdForm->UpdateTabOrderAndGroups();
885 // start listening
886 StartListening();
889 DlgEdObj* DlgEdObj::CloneSdrObject(SdrModel& rTargetModel) const
891 DlgEdObj* pDlgEdObj = CloneHelper< DlgEdObj >(rTargetModel);
892 DBG_ASSERT( pDlgEdObj != nullptr, "DlgEdObj::Clone: invalid clone!" );
893 if ( pDlgEdObj )
894 pDlgEdObj->clonedFrom( this );
896 return pDlgEdObj;
899 SdrObject* DlgEdObj::getFullDragClone() const
901 // no need to really add the clone for dragging, it's a temporary
902 // object
903 SdrObject* pObj = new SdrUnoObj(
904 getSdrModelFromSdrObject(),
905 OUString());
906 *pObj = *static_cast<const SdrUnoObj*>(this);
908 return pObj;
911 void DlgEdObj::NbcMove( const Size& rSize )
913 SdrUnoObj::NbcMove( rSize );
915 // stop listening
916 EndListening(false);
918 // set geometry properties
919 SetPropsFromRect();
921 // start listening
922 StartListening();
924 // dialog model changed
925 GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
928 void DlgEdObj::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
930 SdrUnoObj::NbcResize( rRef, xFract, yFract );
932 // stop listening
933 EndListening(false);
935 // set geometry properties
936 SetPropsFromRect();
938 // start listening
939 StartListening();
941 // dialog model changed
942 GetDlgEdForm()->GetDlgEditor().SetDialogModelChanged();
945 bool DlgEdObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
947 bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
949 SetDefaults();
950 StartListening();
952 return bResult;
955 void DlgEdObj::SetDefaults()
957 // set parent form
958 pDlgEdForm = static_cast<DlgEdPage*>(GetPage())->GetDlgEdForm();
960 if ( pDlgEdForm )
962 // add child to parent form
963 pDlgEdForm->AddChild( this );
965 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
966 if ( xPSet.is() )
968 // get unique name
969 OUString aOUniqueName( GetUniqueName() );
971 // set name property
972 xPSet->setPropertyValue( DLGED_PROP_NAME, Any(aOUniqueName) );
974 // set labels
975 if ( supportsService( "com.sun.star.awt.UnoControlButtonModel" ) ||
976 supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) ||
977 supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) ||
978 supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) ||
979 supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) )
981 xPSet->setPropertyValue( DLGED_PROP_LABEL, Any(aOUniqueName) );
984 // set number formats supplier for formatted field
985 if ( supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) )
987 Reference< util::XNumberFormatsSupplier > xSupplier = GetDlgEdForm()->GetDlgEditor().GetNumberFormatsSupplier();
988 if ( xSupplier.is() )
990 xPSet->setPropertyValue( DLGED_PROP_FORMATSSUPPLIER, Any(xSupplier) );
994 // set geometry properties
995 SetPropsFromRect();
997 Reference< container::XNameContainer > xCont( GetDlgEdForm()->GetUnoControlModel() , UNO_QUERY );
998 if ( xCont.is() )
1000 // set tabindex
1001 Sequence< OUString > aNames = xCont->getElementNames();
1002 uno::Any aTabIndex;
1003 aTabIndex <<= static_cast<sal_Int16>(aNames.getLength());
1004 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, aTabIndex );
1006 // set step
1007 Reference< beans::XPropertySet > xPSetForm( xCont, UNO_QUERY );
1008 if ( xPSetForm.is() )
1010 Any aStep = xPSetForm->getPropertyValue( DLGED_PROP_STEP );
1011 xPSet->setPropertyValue( DLGED_PROP_STEP, aStep );
1014 // insert control model in dialog model
1015 Reference< awt::XControlModel > xCtrl( xPSet , UNO_QUERY );
1016 Any aAny;
1017 aAny <<= xCtrl;
1018 xCont->insertByName( aOUniqueName , aAny );
1020 LocalizationMgr::setControlResourceIDsForNewEditorObject(
1021 &GetDialogEditor(), aAny, aOUniqueName
1024 pDlgEdForm->UpdateTabOrderAndGroups();
1028 // dialog model changed
1029 pDlgEdForm->GetDlgEditor().SetDialogModelChanged();
1033 void DlgEdObj::StartListening()
1035 DBG_ASSERT(!isListening(), "DlgEdObj::StartListening: already listening!");
1037 if (!isListening())
1039 bIsListening = true;
1041 // XPropertyChangeListener
1042 Reference< XPropertySet > xControlModel( GetUnoControlModel() , UNO_QUERY );
1043 if (!m_xPropertyChangeListener.is() && xControlModel.is())
1045 // create listener
1046 m_xPropertyChangeListener = new DlgEdPropListenerImpl(*this);
1048 // register listener to properties
1049 xControlModel->addPropertyChangeListener( OUString() , m_xPropertyChangeListener );
1052 // XContainerListener
1053 Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
1054 if( !m_xContainerListener.is() && xEventsSupplier.is() )
1056 // create listener
1057 m_xContainerListener = new DlgEdEvtContListenerImpl(*this);
1059 // register listener to script event container
1060 Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
1061 DBG_ASSERT(xEventCont.is(), "DlgEdObj::StartListening: control model has no script event container!");
1062 Reference< XContainer > xCont( xEventCont , UNO_QUERY );
1063 if (xCont.is())
1064 xCont->addContainerListener( m_xContainerListener );
1069 void DlgEdObj::EndListening(bool bRemoveListener)
1071 DBG_ASSERT(isListening(), "DlgEdObj::EndListening: not listening currently!");
1073 if (isListening())
1075 bIsListening = false;
1077 if (bRemoveListener)
1079 // XPropertyChangeListener
1080 Reference< XPropertySet > xControlModel(GetUnoControlModel(), UNO_QUERY);
1081 if ( m_xPropertyChangeListener.is() && xControlModel.is() )
1083 // remove listener
1084 xControlModel->removePropertyChangeListener( OUString() , m_xPropertyChangeListener );
1086 m_xPropertyChangeListener.clear();
1088 // XContainerListener
1089 Reference< XScriptEventsSupplier > xEventsSupplier( GetUnoControlModel() , UNO_QUERY );
1090 if( m_xContainerListener.is() && xEventsSupplier.is() )
1092 // remove listener
1093 Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
1094 DBG_ASSERT(xEventCont.is(), "DlgEdObj::EndListening: control model has no script event container!");
1095 Reference< XContainer > xCont( xEventCont , UNO_QUERY );
1096 if (xCont.is())
1097 xCont->removeContainerListener( m_xContainerListener );
1099 m_xContainerListener.clear();
1104 void DlgEdObj::_propertyChange( const css::beans::PropertyChangeEvent& evt )
1106 if (isListening())
1108 DlgEdForm* pRealDlgEdForm = dynamic_cast<DlgEdForm*>(this);
1109 if (!pRealDlgEdForm)
1110 pRealDlgEdForm = GetDlgEdForm();
1111 if (!pRealDlgEdForm)
1112 return;
1113 DlgEditor& rDlgEditor = pRealDlgEdForm->GetDlgEditor();
1114 if (rDlgEditor.isInPaint())
1115 return;
1117 // dialog model changed
1118 rDlgEditor.SetDialogModelChanged();
1120 // update position and size
1121 if ( evt.PropertyName == DLGED_PROP_POSITIONX || evt.PropertyName == DLGED_PROP_POSITIONY ||
1122 evt.PropertyName == DLGED_PROP_WIDTH || evt.PropertyName == DLGED_PROP_HEIGHT ||
1123 evt.PropertyName == DLGED_PROP_DECORATION )
1125 PositionAndSizeChange( evt );
1127 if ( evt.PropertyName == DLGED_PROP_DECORATION )
1128 GetDialogEditor().ResetDialog();
1130 // change name of control in dialog model
1131 else if ( evt.PropertyName == DLGED_PROP_NAME )
1133 if (!dynamic_cast<DlgEdForm*>(this))
1137 NameChange(evt);
1139 catch (container::NoSuchElementException const& e)
1141 throw lang::WrappedTargetRuntimeException("", nullptr,
1142 uno::Any(e));
1146 // update step
1147 else if ( evt.PropertyName == DLGED_PROP_STEP )
1149 UpdateStep();
1151 // change tabindex
1152 else if ( evt.PropertyName == DLGED_PROP_TABINDEX )
1154 if (!dynamic_cast<DlgEdForm*>(this))
1155 TabIndexChange(evt);
1160 void DlgEdObj::_elementInserted()
1162 if (isListening())
1164 // dialog model changed
1165 GetDialogEditor().SetDialogModelChanged();
1169 void DlgEdObj::_elementReplaced()
1171 if (isListening())
1173 // dialog model changed
1174 GetDialogEditor().SetDialogModelChanged();
1178 void DlgEdObj::_elementRemoved()
1180 if (isListening())
1182 // dialog model changed
1183 GetDialogEditor().SetDialogModelChanged();
1187 void DlgEdObj::SetLayer(SdrLayerID nLayer)
1189 SdrLayerID nOldLayer = GetLayer();
1191 if ( nLayer != nOldLayer )
1193 SdrUnoObj::SetLayer( nLayer );
1195 DlgEdHint aHint( DlgEdHint::LAYERCHANGED, this );
1196 GetDlgEdForm()->GetDlgEditor().Broadcast( aHint );
1200 DlgEdForm::DlgEdForm(
1201 SdrModel& rSdrModel,
1202 DlgEditor& rDlgEditor_)
1203 : DlgEdObj(rSdrModel),
1204 rDlgEditor(rDlgEditor_)
1208 DlgEdForm::~DlgEdForm()
1212 void DlgEdForm::SetRectFromProps()
1214 // get form position and size from properties
1215 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
1216 if ( xPSet.is() )
1218 sal_Int32 nXIn = 0, nYIn = 0, nWidthIn = 0, nHeightIn = 0;
1219 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nXIn;
1220 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nYIn;
1221 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidthIn;
1222 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeightIn;
1224 // transform coordinates
1225 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
1226 if ( TransformFormToSdrCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
1228 // set rectangle position and size
1229 Point aPoint( nXOut, nYOut );
1230 Size aSize( nWidthOut, nHeightOut );
1231 SetSnapRect( tools::Rectangle( aPoint, aSize ) );
1236 void DlgEdForm::SetPropsFromRect()
1238 // get form position and size from rectangle
1239 tools::Rectangle aRect_ = GetSnapRect();
1240 sal_Int32 nXIn = aRect_.Left();
1241 sal_Int32 nYIn = aRect_.Top();
1242 sal_Int32 nWidthIn = aRect_.GetWidth();
1243 sal_Int32 nHeightIn = aRect_.GetHeight();
1245 // transform coordinates
1246 sal_Int32 nXOut, nYOut, nWidthOut, nHeightOut;
1247 if ( TransformSdrToFormCoordinates( nXIn, nYIn, nWidthIn, nHeightIn, nXOut, nYOut, nWidthOut, nHeightOut ) )
1249 // set properties
1250 Reference< beans::XPropertySet > xPSet( GetUnoControlModel(), UNO_QUERY );
1251 if ( xPSet.is() )
1253 xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nXOut) );
1254 xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nYOut) );
1255 xPSet->setPropertyValue( DLGED_PROP_WIDTH, Any(nWidthOut) );
1256 xPSet->setPropertyValue( DLGED_PROP_HEIGHT, Any(nHeightOut) );
1261 void DlgEdForm::AddChild( DlgEdObj* pDlgEdObj )
1263 pChildren.push_back( pDlgEdObj );
1266 void DlgEdForm::RemoveChild( DlgEdObj* pDlgEdObj )
1268 pChildren.erase( std::remove( pChildren.begin() , pChildren.end() , pDlgEdObj ) );
1271 void DlgEdForm::PositionAndSizeChange( const beans::PropertyChangeEvent& evt )
1273 DlgEditor& rEditor = GetDlgEditor();
1274 DlgEdPage& rPage = rEditor.GetPage();
1276 sal_Int32 nPageXIn = 0;
1277 sal_Int32 nPageYIn = 0;
1278 Size aPageSize = rPage.GetSize();
1279 sal_Int32 nPageWidthIn = aPageSize.Width();
1280 sal_Int32 nPageHeightIn = aPageSize.Height();
1281 sal_Int32 nPageX, nPageY, nPageWidth, nPageHeight;
1282 if ( TransformSdrToFormCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
1284 Reference< beans::XPropertySet > xPSetForm( GetUnoControlModel(), UNO_QUERY );
1285 if ( xPSetForm.is() )
1287 sal_Int32 nValue = 0;
1288 evt.NewValue >>= nValue;
1289 sal_Int32 nNewValue = nValue;
1291 if ( evt.PropertyName == DLGED_PROP_POSITIONX )
1293 if ( nNewValue < nPageX )
1294 nNewValue = nPageX;
1296 else if ( evt.PropertyName == DLGED_PROP_POSITIONY )
1298 if ( nNewValue < nPageY )
1299 nNewValue = nPageY;
1301 else if ( evt.PropertyName == DLGED_PROP_WIDTH )
1303 if ( nNewValue < 1 )
1304 nNewValue = 1;
1306 else if ( evt.PropertyName == DLGED_PROP_HEIGHT )
1308 if ( nNewValue < 1 )
1309 nNewValue = 1;
1312 if ( nNewValue != nValue )
1314 EndListening( false );
1315 xPSetForm->setPropertyValue( evt.PropertyName, Any(nNewValue) );
1316 StartListening();
1321 bool bAdjustedPageSize = rEditor.AdjustPageSize();
1322 SetRectFromProps();
1323 std::vector<DlgEdObj*> const& aChildList = GetChildren();
1325 if ( bAdjustedPageSize )
1327 rEditor.InitScrollBars();
1328 aPageSize = rPage.GetSize();
1329 nPageWidthIn = aPageSize.Width();
1330 nPageHeightIn = aPageSize.Height();
1331 if ( TransformSdrToControlCoordinates( nPageXIn, nPageYIn, nPageWidthIn, nPageHeightIn, nPageX, nPageY, nPageWidth, nPageHeight ) )
1333 for (auto const& child : aChildList)
1335 Reference< beans::XPropertySet > xPSet( child->GetUnoControlModel(), UNO_QUERY );
1336 if ( xPSet.is() )
1338 sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
1339 xPSet->getPropertyValue( DLGED_PROP_POSITIONX ) >>= nX;
1340 xPSet->getPropertyValue( DLGED_PROP_POSITIONY ) >>= nY;
1341 xPSet->getPropertyValue( DLGED_PROP_WIDTH ) >>= nWidth;
1342 xPSet->getPropertyValue( DLGED_PROP_HEIGHT ) >>= nHeight;
1344 sal_Int32 nNewX = nX;
1345 if ( nX + nWidth > nPageX + nPageWidth )
1347 nNewX = nPageX + nPageWidth - nWidth;
1348 if ( nNewX < nPageX )
1349 nNewX = nPageX;
1351 if ( nNewX != nX )
1353 EndListening( false );
1354 xPSet->setPropertyValue( DLGED_PROP_POSITIONX, Any(nNewX) );
1355 StartListening();
1358 sal_Int32 nNewY = nY;
1359 if ( nY + nHeight > nPageY + nPageHeight )
1361 nNewY = nPageY + nPageHeight - nHeight;
1362 if ( nNewY < nPageY )
1363 nNewY = nPageY;
1365 if ( nNewY != nY )
1367 EndListening( false );
1368 xPSet->setPropertyValue( DLGED_PROP_POSITIONY, Any(nNewY) );
1369 StartListening();
1376 for (auto const& child : aChildList)
1377 child->SetRectFromProps();
1380 void DlgEdForm::UpdateStep()
1382 SdrPage* pSdrPage = GetPage();
1384 if ( pSdrPage )
1386 const size_t nObjCount = pSdrPage->GetObjCount();
1387 for ( size_t i = 0 ; i < nObjCount ; i++ )
1389 DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(pSdrPage->GetObj(i));
1390 if (pDlgEdObj && !dynamic_cast<DlgEdForm*>(pDlgEdObj))
1391 pDlgEdObj->UpdateStep();
1396 void DlgEdForm::UpdateTabIndices()
1398 // stop listening with all children
1399 for (auto const& child : pChildren)
1401 child->EndListening( false );
1404 Reference< css::container::XNameAccess > xNameAcc( GetUnoControlModel() , UNO_QUERY );
1405 if ( xNameAcc.is() )
1407 // get sequence of control names
1408 Sequence< OUString > aNames = xNameAcc->getElementNames();
1409 const OUString* pNames = aNames.getConstArray();
1410 sal_Int32 nCtrls = aNames.getLength();
1412 // create a map of tab indices and control names, sorted by tab index
1413 IndexToNameMap aIndexToNameMap;
1414 for ( sal_Int32 i = 0; i < nCtrls; ++i )
1416 // get name
1417 OUString aName( pNames[i] );
1419 // get tab index
1420 sal_Int16 nTabIndex = -1;
1421 Any aCtrl = xNameAcc->getByName( aName );
1422 Reference< css::beans::XPropertySet > xPSet;
1423 aCtrl >>= xPSet;
1424 if ( xPSet.is() )
1425 xPSet->getPropertyValue( DLGED_PROP_TABINDEX ) >>= nTabIndex;
1427 // insert into map
1428 aIndexToNameMap.emplace( nTabIndex, aName );
1431 // set new tab indices
1432 sal_Int16 nNewTabIndex = 0;
1433 for (auto const& indexToName : aIndexToNameMap)
1435 Any aCtrl = xNameAcc->getByName( indexToName.second );
1436 Reference< beans::XPropertySet > xPSet;
1437 aCtrl >>= xPSet;
1438 if ( xPSet.is() )
1440 xPSet->setPropertyValue( DLGED_PROP_TABINDEX, Any(nNewTabIndex) );
1441 nNewTabIndex++;
1445 UpdateTabOrderAndGroups();
1448 // start listening with all children
1449 for (auto const& child : pChildren)
1451 child->StartListening();
1455 void DlgEdForm::UpdateTabOrder()
1457 // When the tabindex of a control model changes, the dialog control is
1458 // notified about those changes. Due to #109067# (bad performance of
1459 // dialog editor) the dialog control doesn't activate the tab order
1460 // in design mode. When the dialog editor has reordered all
1461 // tabindices, this method allows to activate the taborder afterwards.
1463 Reference< awt::XUnoControlContainer > xCont( GetControl(), UNO_QUERY );
1464 if ( xCont.is() )
1466 Sequence< Reference< awt::XTabController > > aSeqTabCtrls = xCont->getTabControllers();
1467 const Reference< awt::XTabController >* pTabCtrls = aSeqTabCtrls.getConstArray();
1468 sal_Int32 nCount = aSeqTabCtrls.getLength();
1469 for ( sal_Int32 i = 0; i < nCount; ++i )
1470 pTabCtrls[i]->activateTabOrder();
1474 void DlgEdForm::UpdateGroups()
1476 // The grouping of radio buttons in a dialog is done by vcl.
1477 // In the dialog editor we have two views (=controls) for one
1478 // radio button model. One control is owned by the dialog control,
1479 // but not visible in design mode. The other control is owned by
1480 // the drawing layer object. Whereas the grouping of the first
1481 // control is done by vcl, the grouping of the control in the
1482 // drawing layer has to be done here.
1484 Reference< awt::XTabControllerModel > xTabModel( GetUnoControlModel() , UNO_QUERY );
1485 if ( xTabModel.is() )
1487 // create a global list of controls that belong to the dialog
1488 std::vector<DlgEdObj*> aChildList = GetChildren();
1489 sal_uInt32 nSize = aChildList.size();
1490 Sequence< Reference< awt::XControl > > aSeqControls( nSize );
1491 for ( sal_uInt32 i = 0; i < nSize; ++i )
1492 aSeqControls.getArray()[i].set( aChildList[i]->GetControl(), UNO_QUERY );
1494 sal_Int32 nGroupCount = xTabModel->getGroupCount();
1495 for ( sal_Int32 nGroup = 0; nGroup < nGroupCount; ++nGroup )
1497 // get a list of control models that belong to this group
1498 OUString aName;
1499 Sequence< Reference< awt::XControlModel > > aSeqModels;
1500 xTabModel->getGroup( nGroup, aSeqModels, aName );
1501 const Reference< awt::XControlModel >* pModels = aSeqModels.getConstArray();
1502 sal_Int32 nModelCount = aSeqModels.getLength();
1504 // create a list of peers that belong to this group
1505 Sequence< Reference< awt::XWindow > > aSeqPeers( nModelCount );
1506 for ( sal_Int32 nModel = 0; nModel < nModelCount; ++nModel )
1508 // for each control model find the corresponding control in the global list
1509 const Reference< awt::XControl >* pControls = aSeqControls.getConstArray();
1510 sal_Int32 nControlCount = aSeqControls.getLength();
1511 for ( sal_Int32 nControl = 0; nControl < nControlCount; ++nControl )
1513 const Reference< awt::XControl > xCtrl( pControls[nControl] );
1514 if ( xCtrl.is() )
1516 Reference< awt::XControlModel > xCtrlModel( xCtrl->getModel() );
1517 if ( xCtrlModel.get() == pModels[nModel].get() )
1519 // get the control peer and insert into the list of peers
1520 aSeqPeers.getArray()[ nModel ].set( xCtrl->getPeer(), UNO_QUERY );
1521 break;
1527 // set the group at the dialog peer
1528 Reference< awt::XControl > xDlg( GetControl(), UNO_QUERY );
1529 if ( xDlg.is() )
1531 Reference< awt::XVclContainerPeer > xDlgPeer( xDlg->getPeer(), UNO_QUERY );
1532 if ( xDlgPeer.is() )
1533 xDlgPeer->setGroup( aSeqPeers );
1539 void DlgEdForm::UpdateTabOrderAndGroups()
1541 UpdateTabOrder();
1542 UpdateGroups();
1545 void DlgEdForm::NbcMove( const Size& rSize )
1547 SdrUnoObj::NbcMove( rSize );
1549 // set geometry properties of form
1550 EndListening(false);
1551 SetPropsFromRect();
1552 StartListening();
1554 // set geometry properties of all children
1555 for (auto const& child : pChildren)
1557 child->EndListening(false);
1558 child->SetPropsFromRect();
1559 child->StartListening();
1562 // dialog model changed
1563 GetDlgEditor().SetDialogModelChanged();
1566 void DlgEdForm::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract)
1568 SdrUnoObj::NbcResize( rRef, xFract, yFract );
1570 // set geometry properties of form
1571 EndListening(false);
1572 SetPropsFromRect();
1573 StartListening();
1575 // set geometry properties of all children
1576 for (auto const& child : pChildren)
1578 child->EndListening(false);
1579 child->SetPropsFromRect();
1580 child->StartListening();
1583 // dialog model changed
1584 GetDlgEditor().SetDialogModelChanged();
1587 bool DlgEdForm::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
1589 bool bResult = SdrUnoObj::EndCreate(rStat, eCmd);
1591 // stop listening
1592 EndListening(false);
1594 // set geometry properties
1595 SetPropsFromRect();
1597 // dialog model changed
1598 GetDlgEditor().SetDialogModelChanged();
1600 // start listening
1601 StartListening();
1603 return bResult;
1606 awt::DeviceInfo DlgEdForm::getDeviceInfo() const
1608 awt::DeviceInfo aDeviceInfo;
1610 DlgEditor& rEditor = GetDlgEditor();
1611 vcl::Window& rWindow = rEditor.GetWindow();
1613 // obtain an XControl
1614 ::utl::SharedUNOComponent< awt::XControl > xDialogControl; // ensures auto-disposal, if needed
1615 xDialogControl.reset( GetControl(), ::utl::SharedUNOComponent< awt::XControl >::NoTakeOwnership );
1616 if ( !xDialogControl.is() )
1618 // don't create a temporary control all the time, this method here is called
1619 // way too often. Instead, use a cached DeviceInfo.
1620 // #i74065#
1621 if ( !!mpDeviceInfo )
1622 return *mpDeviceInfo;
1624 Reference< awt::XControlContainer > xEditorControlContainer( rEditor.GetWindowControlContainer() );
1625 xDialogControl.reset(
1626 GetTemporaryControlForWindow(rWindow, xEditorControlContainer),
1627 utl::SharedUNOComponent< awt::XControl >::TakeOwnership
1631 Reference< awt::XDevice > xDialogDevice;
1632 if ( xDialogControl.is() )
1633 xDialogDevice.set( xDialogControl->getPeer(), UNO_QUERY );
1634 DBG_ASSERT( xDialogDevice.is(), "DlgEdForm::getDeviceInfo: no device!" );
1635 if ( xDialogDevice.is() )
1636 aDeviceInfo = xDialogDevice->getInfo();
1638 mpDeviceInfo.reset( aDeviceInfo );
1640 return aDeviceInfo;
1642 void DlgEdObj::MakeDataAware( const Reference< frame::XModel >& xModel )
1644 // Need to flesh this out, currently we will only support data-aware controls for calc
1645 // and only handle a subset of functionality e.g. linked-cell and cell range data source. Of course later
1646 // we need to disambiguate for writer ( and others ? ) and also support the generic form (db) bindings
1647 // we need some more work in xmlscript to be able to handle that
1648 Reference< lang::XMultiServiceFactory > xFac( xModel, UNO_QUERY );
1649 Reference< form::binding::XBindableValue > xBindable( GetUnoControlModel(), UNO_QUERY );
1650 Reference< form::binding::XListEntrySink > xListEntrySink( GetUnoControlModel(), UNO_QUERY );
1651 if ( xFac.is() )
1653 css::table::CellAddress aApiAddress;
1655 //tdf#90361 CellValueBinding and CellRangeListSource are unusable
1656 //without being initialized, so use createInstanceWithArguments with a
1657 //dummy BoundCell instead of createInstance. This at least results in
1658 //the dialog editor not falling.
1659 css::beans::NamedValue aValue;
1660 aValue.Name = "BoundCell";
1661 aValue.Value <<= aApiAddress;
1663 Sequence< Any > aArgs( 1 );
1664 aArgs[ 0 ] <<= aValue;
1666 if ( xBindable.is() )
1668 Reference< form::binding::XValueBinding > xBinding( xFac->createInstanceWithArguments( "com.sun.star.table.CellValueBinding", aArgs ), UNO_QUERY );
1669 xBindable->setValueBinding( xBinding );
1671 if ( xListEntrySink.is() )
1673 Reference< form::binding::XListEntrySource > xSource( xFac->createInstanceWithArguments( "com.sun.star.table.CellRangeListSource", aArgs ), UNO_QUERY );
1674 xListEntrySink->setListEntrySource( xSource );
1678 } // namespace basctl
1680 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */