1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_toolkit.hxx"
30 
31 
32 #include <toolkit/awt/vclxcontainer.hxx>
33 #include <toolkit/helper/macros.hxx>
34 #include <toolkit/helper/vclunohelper.hxx>
35 #include <cppuhelper/typeprovider.hxx>
36 #include <rtl/memory.h>
37 #include <rtl/uuid.h>
38 
39 #include <vcl/window.hxx>
40 #include <tools/debug.hxx>
41 
42 //	----------------------------------------------------
43 //	class VCLXContainer
44 //	----------------------------------------------------
45 
46 void VCLXContainer::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
47 {
48     VCLXWindow::ImplGetPropertyIds( rIds );
49 }
50 
51 VCLXContainer::VCLXContainer()
52 {
53 }
54 
55 VCLXContainer::~VCLXContainer()
56 {
57 }
58 
59 // ::com::sun::star::uno::XInterface
60 ::com::sun::star::uno::Any VCLXContainer::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
61 {
62 	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
63 										SAL_STATIC_CAST( ::com::sun::star::awt::XVclContainer*, this ),
64 										SAL_STATIC_CAST( ::com::sun::star::awt::XVclContainerPeer*, this ) );
65 	return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType ));
66 }
67 
68 // ::com::sun::star::lang::XTypeProvider
69 IMPL_XTYPEPROVIDER_START( VCLXContainer )
70 	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XVclContainer>* ) NULL ),
71 	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XVclContainerPeer>* ) NULL ),
72 	VCLXWindow::getTypes()
73 IMPL_XTYPEPROVIDER_END
74 
75 
76 // ::com::sun::star::awt::XVclContainer
77 void VCLXContainer::addVclContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XVclContainerListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
78 {
79 	::vos::OGuard aGuard( GetMutex() );
80 
81 	GetContainerListeners().addInterface( rxListener );
82 }
83 
84 void VCLXContainer::removeVclContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XVclContainerListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
85 {
86 	::vos::OGuard aGuard( GetMutex() );
87 
88 	GetContainerListeners().removeInterface( rxListener );
89 }
90 
91 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > > VCLXContainer::getWindows(  ) throw(::com::sun::star::uno::RuntimeException)
92 {
93 	::vos::OGuard aGuard( GetMutex() );
94 
95 	// Bei allen Childs das Container-Interface abfragen...
96 	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > > aSeq;
97 	Window* pWindow = GetWindow();
98 	if ( pWindow )
99 	{
100 		sal_uInt16 nChilds = pWindow->GetChildCount();
101 		if ( nChilds )
102 		{
103 			aSeq = ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > >( nChilds );
104 			::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > * pChildRefs = aSeq.getArray();
105 			for ( sal_uInt16 n = 0; n < nChilds; n++ )
106 			{
107 				Window* pChild = pWindow->GetChild( n );
108 				::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >  xWP = pChild->GetComponentInterface( sal_True );
109 				::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > xW( xWP, ::com::sun::star::uno::UNO_QUERY );
110 				pChildRefs[n] = xW;
111 			}
112 		}
113 	}
114 	return aSeq;
115 }
116 
117 
118 // ::com::sun::star::awt::XVclContainerPeer
119 void VCLXContainer::enableDialogControl( sal_Bool bEnable ) throw(::com::sun::star::uno::RuntimeException)
120 {
121 	::vos::OGuard aGuard( GetMutex() );
122 
123 	Window* pWindow = GetWindow();
124 	if ( pWindow )
125 	{
126 		WinBits nStyle = pWindow->GetStyle();
127 		if ( bEnable )
128 			nStyle |= WB_DIALOGCONTROL;
129 		else
130 			nStyle &= (~WB_DIALOGCONTROL);
131 		pWindow->SetStyle( nStyle );
132 	}
133 }
134 
135 void VCLXContainer::setTabOrder( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > >& Components, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Tabs, sal_Bool bGroupControl ) throw(::com::sun::star::uno::RuntimeException)
136 {
137 	::vos::OGuard aGuard( GetMutex() );
138 
139 	sal_uInt32 nCount = Components.getLength();
140 	DBG_ASSERT( nCount == (sal_uInt32)Tabs.getLength(), "setTabOrder: TabCount != ComponentCount" );
141 	const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > * pComps = Components.getConstArray();
142 	const ::com::sun::star::uno::Any* pTabs = Tabs.getConstArray();
143 
144 	Window* pPrevWin = NULL;
145 	for ( sal_uInt32 n = 0; n < nCount; n++ )
146 	{
147 		// ::com::sun::star::style::TabStop
148 		Window* pWin = VCLUnoHelper::GetWindow( pComps[n] );
149 		// NULL kann vorkommen, wenn die ::com::sun::star::uno::Sequence vom TabController kommt und eine Peer fehlt!
150 		if ( pWin )
151 		{
152 			// Reihenfolge der Fenster vor der Manipulation des Styles,
153 			// weil z.B. der RadioButton in StateChanged das PREV-Window beruecksichtigt.
154 			if ( pPrevWin )
155 				pWin->SetZOrder( pPrevWin, WINDOW_ZORDER_BEHIND );
156 
157 			WinBits nStyle = pWin->GetStyle();
158 			nStyle &= ~(WB_TABSTOP|WB_NOTABSTOP|WB_GROUP);
159 			if ( pTabs[n].getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_BOOLEAN )
160 			{
161 				sal_Bool bTab = false;
162 				pTabs[n] >>= bTab;
163 				nStyle |= ( bTab ? WB_TABSTOP : WB_NOTABSTOP );
164 			}
165 			pWin->SetStyle( nStyle );
166 
167 			if ( bGroupControl )
168 			{
169 				if ( n == 0 )
170 					pWin->SetDialogControlStart( sal_True );
171 				else
172 					pWin->SetDialogControlStart( sal_False );
173 			}
174 
175 			pPrevWin = pWin;
176 		}
177 	}
178 }
179 
180 void VCLXContainer::setGroup( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > >& Components ) throw(::com::sun::star::uno::RuntimeException)
181 {
182 	::vos::OGuard aGuard( GetMutex() );
183 
184 	sal_uInt32 nCount = Components.getLength();
185 	const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > * pComps = Components.getConstArray();
186 
187 	Window* pPrevWin = NULL;
188 	Window* pPrevRadio = NULL;
189 	for ( sal_uInt32 n = 0; n < nCount; n++ )
190 	{
191 		Window* pWin = VCLUnoHelper::GetWindow( pComps[n] );
192 		if ( pWin )
193 		{
194 			Window* pSortBehind = pPrevWin;
195 			// #57096# Alle Radios hintereinander sortieren...
196 			sal_Bool bNewPrevWin = sal_True;
197 			if ( pWin->GetType() == WINDOW_RADIOBUTTON )
198 			{
199 				if ( pPrevRadio )
200 				{
201 					bNewPrevWin = ( pPrevWin == pPrevRadio );	// Radio-Button wurde vor das PreWin sortiert....
202 					pSortBehind = pPrevRadio;
203 				}
204 				pPrevRadio = pWin;
205 			}
206 
207 			// Z-Order
208 			if ( pSortBehind )
209 				pWin->SetZOrder( pSortBehind, WINDOW_ZORDER_BEHIND );
210 
211 			WinBits nStyle = pWin->GetStyle();
212 			if ( n == 0 )
213 				nStyle |= WB_GROUP;
214 			else
215 				nStyle &= (~WB_GROUP);
216 			pWin->SetStyle( nStyle );
217 
218 			// Ein WB_GROUP hinter die Gruppe, falls keine Gruppe mehr folgt.
219 			if ( n == ( nCount - 1 ) )
220 			{
221 				Window* pBehindLast = pWin->GetWindow( WINDOW_NEXT );
222 				if ( pBehindLast )
223 				{
224 					WinBits nLastStyle = pBehindLast->GetStyle();
225 					nLastStyle |= WB_GROUP;
226 					pBehindLast->SetStyle( nLastStyle );
227 				}
228 			}
229 
230 			if ( bNewPrevWin )
231 				pPrevWin = pWin;
232 		}
233 	}
234 }
235 
236 
237 
238 
239 
240