1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26
27 //_________________________________________________________________________________________________________________
28 // my own includes
29 //_________________________________________________________________________________________________________________
30
31 #include <services/tabwindowservice.hxx>
32 #include <classes/fwktabwindow.hxx>
33 #include <threadhelp/resetableguard.hxx>
34 #include <services.h>
35 #include <properties.h>
36
37 //_________________________________________________________________________________________________________________
38 // interface includes
39 //_________________________________________________________________________________________________________________
40
41 #include <com/sun/star/awt/PosSize.hpp>
42 #include <com/sun/star/beans/PropertyAttribute.hpp>
43
44 //_________________________________________________________________________________________________________________
45 // includes of other projects
46 //_________________________________________________________________________________________________________________
47
48 #include <toolkit/helper/vclunohelper.hxx>
49 #include <tools/urlobj.hxx>
50 #include <rtl/ustrbuf.hxx>
51 #include <vcl/svapp.hxx>
52
53 //_________________________________________________________________________________________________________________
54 // namespace
55 //_________________________________________________________________________________________________________________
56
57 namespace framework{
58
59 //_________________________________________________________________________________________________________________
60 // non exported definitions
61 //_________________________________________________________________________________________________________________
62
63 //_________________________________________________________________________________________________________________
64 // declarations
65 //_________________________________________________________________________________________________________________
66
67 //*****************************************************************************************************************
68 // css::uno::XInterface, XTypeProvider, XServiceInfo
69 //*****************************************************************************************************************
70
DEFINE_XINTERFACE_6(TabWindowService,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::lang::XServiceInfo),DIRECT_INTERFACE (css::lang::XComponent),DIRECT_INTERFACE (css::awt::XSimpleTabController),DIRECT_INTERFACE (css::beans::XPropertySet),DIRECT_INTERFACE (css::beans::XPropertySetInfo))71 DEFINE_XINTERFACE_6 ( TabWindowService ,
72 OWeakObject ,
73 DIRECT_INTERFACE(css::lang::XTypeProvider ),
74 DIRECT_INTERFACE(css::lang::XServiceInfo ),
75 DIRECT_INTERFACE(css::lang::XComponent),
76 DIRECT_INTERFACE(css::awt::XSimpleTabController),
77 DIRECT_INTERFACE(css::beans::XPropertySet ),
78 DIRECT_INTERFACE(css::beans::XPropertySetInfo )
79 )
80
81 DEFINE_XTYPEPROVIDER_6 ( TabWindowService ,
82 css::lang::XTypeProvider ,
83 css::lang::XServiceInfo ,
84 css::lang::XComponent ,
85 css::awt::XSimpleTabController ,
86 css::beans::XPropertySet ,
87 css::beans::XPropertySetInfo
88 )
89
90 DEFINE_XSERVICEINFO_MULTISERVICE ( TabWindowService ,
91 OWeakObject ,
92 SERVICENAME_TABWINDOWSERVICE ,
93 IMPLEMENTATIONNAME_TABWINDOWSERVICE
94 )
95
96 DEFINE_INIT_SERVICE ( TabWindowService,
97 {
98 impl_initializePropInfo();
99 m_aTransactionManager.setWorkingMode( E_WORK );
100 }
101 )
102
103 //*****************************************************************************************************************
104 // constructor
105 //*****************************************************************************************************************
106 TabWindowService::TabWindowService( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
107 // Init baseclasses first
108 // Attention:
109 // Don't change order of initialization!
110 // ThreadHelpBase is a struct with a mutex as member. We can't use a mutex as member, while
111 // we must garant right initialization and a valid value of this! First initialize
112 // baseclasses and then members. And we need the mutex for other baseclasses !!!
113 : ThreadHelpBase ( &Application::GetSolarMutex() )
114 , TransactionBase ( )
115 , PropertySetHelper ( xFactory ,
116 &m_aLock ,
117 &m_aTransactionManager ,
118 sal_False ) // sal_False => dont release shared mutex on calling us!
119 , OWeakObject ( )
120
121 // Init member
122 , m_xFactory ( xFactory )
123 , m_xTabWin ( )
124 , m_pTabWin ( NULL )
125 , m_lTabPageInfos ( )
126 , m_lListener ( m_aLock.getShareableOslMutex())
127 , m_nPageIndexCounter ( 1 )
128 , m_nCurrentPageIndex ( 0 )
129 {
130 // Safe impossible cases.
131 // Method not defined for all incoming parameter.
132 LOG_ASSERT( xFactory.is(), "TabWindowService::TabWindowService()\nInvalid parameter detected!\n" )
133 }
134
135 //*****************************************************************************************************************
136 // destructor
137 //*****************************************************************************************************************
~TabWindowService()138 TabWindowService::~TabWindowService()
139 {
140 // SAFE->
141 ResetableGuard aGuard(m_aLock);
142
143 if (m_pTabWin)
144 m_pTabWin->RemoveEventListener( LINK( this, TabWindowService, EventListener ) );
145 }
146
147 //*****************************************************************************************************************
148 // XSimpleTabController
149 //*****************************************************************************************************************
insertTab()150 ::sal_Int32 SAL_CALL TabWindowService::insertTab()
151 throw ( css::uno::RuntimeException )
152 {
153 // SAFE ->
154 ResetableGuard aGuard( m_aLock );
155
156 ::sal_Int32 nID = m_nPageIndexCounter++;
157 TTabPageInfo aInfo(nID);
158
159 m_lTabPageInfos[nID] = aInfo;
160
161 return nID;
162 }
163
164 //*****************************************************************************************************************
165 // XSimpleTabController
166 //*****************************************************************************************************************
removeTab(::sal_Int32 nID)167 void SAL_CALL TabWindowService::removeTab(::sal_Int32 nID)
168 throw (css::lang::IndexOutOfBoundsException,
169 css::uno::RuntimeException )
170 {
171 // SAFE ->
172 ResetableGuard aGuard(m_aLock);
173
174 // throws suitable IndexOutOfBoundsException .-)
175 TTabPageInfoHash::iterator pIt = impl_getTabPageInfo (nID);
176 m_lTabPageInfos.erase(pIt);
177
178 FwkTabWindow* pTabWin = mem_TabWin ();
179 if (pTabWin)
180 pTabWin->RemovePage(nID);
181 }
182
183 //*****************************************************************************************************************
184 // XSimpleTabController
185 //*****************************************************************************************************************
setTabProps(::sal_Int32 nID,const css::uno::Sequence<css::beans::NamedValue> & lProperties)186 void SAL_CALL TabWindowService::setTabProps( ::sal_Int32 nID ,
187 const css::uno::Sequence< css::beans::NamedValue >& lProperties)
188 throw (css::lang::IndexOutOfBoundsException,
189 css::uno::RuntimeException )
190 {
191 // SAFE ->
192 ResetableGuard aGuard(m_aLock);
193
194 // throws suitable IndexOutOfBoundsException .-)
195 TTabPageInfoHash::iterator pIt = impl_getTabPageInfo (nID);
196 TTabPageInfo& rInfo = pIt->second;
197 rInfo.m_lProperties = lProperties;
198
199 if ( ! rInfo.m_bCreated)
200 {
201 FwkTabWindow* pTabWin = mem_TabWin ();
202 if (pTabWin)
203 {
204 pTabWin->AddTabPage(rInfo.m_nIndex, rInfo.m_lProperties);
205 rInfo.m_bCreated = sal_True;
206 }
207 }
208 }
209
210 //*****************************************************************************************************************
211 // XSimpleTabController
212 //*****************************************************************************************************************
getTabProps(::sal_Int32 nID)213 css::uno::Sequence< css::beans::NamedValue > SAL_CALL TabWindowService::getTabProps(::sal_Int32 nID)
214 throw (css::lang::IndexOutOfBoundsException,
215 css::uno::RuntimeException )
216 {
217 // SAFE ->
218 ResetableGuard aGuard(m_aLock);
219
220 // throws suitable IndexOutOfBoundsException .-)
221 TTabPageInfoHash::const_iterator pIt = impl_getTabPageInfo (nID);
222 const TTabPageInfo& rInfo = pIt->second;
223
224 return rInfo.m_lProperties;
225 }
226
227 //*****************************************************************************************************************
228 // XSimpleTabController
229 //*****************************************************************************************************************
activateTab(::sal_Int32 nID)230 void SAL_CALL TabWindowService::activateTab(::sal_Int32 nID)
231 throw (css::lang::IndexOutOfBoundsException,
232 css::uno::RuntimeException )
233 {
234 // SAFE ->
235 ResetableGuard aGuard(m_aLock);
236
237 // throws suitable IndexOutOfBoundsException .-)
238 impl_checkTabIndex (nID);
239 m_nCurrentPageIndex = nID;
240
241 FwkTabWindow* pTabWin = mem_TabWin ();
242 if (pTabWin)
243 pTabWin->ActivatePage(nID);
244 }
245
246 //*****************************************************************************************************************
247 // XSimpleTabController
248 //*****************************************************************************************************************
getActiveTabID()249 ::sal_Int32 SAL_CALL TabWindowService::getActiveTabID()
250 throw (css::uno::RuntimeException)
251 {
252 // SAFE->
253 ResetableGuard aGuard( m_aLock );
254 return m_nCurrentPageIndex;
255 }
256
257 //*****************************************************************************************************************
258 // XSimpleTabController
259 //*****************************************************************************************************************
addTabListener(const css::uno::Reference<css::awt::XTabListener> & xListener)260 void SAL_CALL TabWindowService::addTabListener(const css::uno::Reference< css::awt::XTabListener >& xListener)
261 throw (css::uno::RuntimeException)
262 {
263 m_lListener.addInterface(::getCppuType((const css::uno::Reference< css::awt::XTabListener >*)NULL), xListener);
264 }
265
266 //*****************************************************************************************************************
267 // XSimpleTabController
268 //*****************************************************************************************************************
removeTabListener(const css::uno::Reference<css::awt::XTabListener> & xListener)269 void SAL_CALL TabWindowService::removeTabListener(const css::uno::Reference< css::awt::XTabListener >& xListener)
270 throw (css::uno::RuntimeException)
271 {
272 m_lListener.removeInterface(::getCppuType((const css::uno::Reference< css::awt::XTabListener >*)NULL), xListener);
273 }
274
275 //*****************************************************************************************************************
276 // XComponent
277 //*****************************************************************************************************************
dispose()278 void SAL_CALL TabWindowService::dispose()
279 throw (css::uno::RuntimeException)
280 {
281 // SAFE->
282 ResetableGuard aGuard(m_aLock);
283
284 css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
285 css::lang::EventObject aEvent(xThis);
286
287 m_lListener.disposeAndClear (aEvent);
288
289 if (m_pTabWin)
290 m_pTabWin->RemoveEventListener( LINK( this, TabWindowService, EventListener ) );
291
292 m_pTabWin = NULL;
293 m_xTabWin.clear();
294 }
295
296 //*****************************************************************************************************************
297 // XComponent
298 //*****************************************************************************************************************
addEventListener(const css::uno::Reference<css::lang::XEventListener> & xListener)299 void SAL_CALL TabWindowService::addEventListener(const css::uno::Reference< css::lang::XEventListener >& xListener)
300 throw (css::uno::RuntimeException)
301 {
302 m_lListener.addInterface(::getCppuType((const css::uno::Reference< css::lang::XEventListener >*)NULL), xListener);
303 }
304
305 //*****************************************************************************************************************
306 // XComponent
307 //*****************************************************************************************************************
removeEventListener(const css::uno::Reference<css::lang::XEventListener> & xListener)308 void SAL_CALL TabWindowService::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener)
309 throw (css::uno::RuntimeException)
310 {
311 m_lListener.removeInterface(::getCppuType((const css::uno::Reference< css::lang::XEventListener >*)NULL), xListener);
312 }
313
314 //*****************************************************************************************************************
impl_initializePropInfo()315 void TabWindowService::impl_initializePropInfo()
316 {
317 impl_setPropertyChangeBroadcaster(static_cast< css::awt::XSimpleTabController* >(this));
318
319 impl_addPropertyInfo(
320 css::beans::Property(
321 TABWINDOWSERVICE_PROPNAME_WINDOW,
322 TABWINDOWSERVICE_PROPHANDLE_WINDOW,
323 ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
324 css::beans::PropertyAttribute::TRANSIENT));
325 }
326
327 //*****************************************************************************************************************
impl_setPropertyValue(const::rtl::OUString &,sal_Int32,const css::uno::Any &)328 void SAL_CALL TabWindowService::impl_setPropertyValue(const ::rtl::OUString& /*sProperty*/,
329 sal_Int32 /*nHandle */,
330 const css::uno::Any& /*aValue */)
331
332 {
333 }
334
335 //*****************************************************************************************************************
impl_getPropertyValue(const::rtl::OUString &,sal_Int32 nHandle)336 css::uno::Any SAL_CALL TabWindowService::impl_getPropertyValue(const ::rtl::OUString& /*sProperty*/,
337 sal_Int32 nHandle )
338 {
339 /* There is no need to lock any mutex here. Because we share the
340 solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
341 see ctor of PropertySetHelper for further informations.
342 */
343 css::uno::Any aValue;
344
345 switch (nHandle)
346 {
347 case TABWINDOWSERVICE_PROPHANDLE_WINDOW:
348 {
349 mem_TabWin (); // force "creation on demand" of m_xTabWin :-)
350 aValue <<= m_xTabWin;
351 }
352 break;
353 }
354
355 return aValue;
356 }
357
358 //*****************************************************************************************************************
359 // TabWindowService
360 //*****************************************************************************************************************
IMPL_LINK(TabWindowService,EventListener,VclSimpleEvent *,pEvent)361 IMPL_LINK( TabWindowService, EventListener, VclSimpleEvent*, pEvent )
362 {
363
364 if ( !pEvent && !pEvent->ISA(VclWindowEvent))
365 return 0;
366
367 sal_uLong nEventId = pEvent->GetId();
368 VclWindowEvent* pWinEvt = static_cast< VclWindowEvent* >(pEvent);
369
370 css::uno::Reference< css::uno::XInterface > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
371 css::lang::EventObject aEvent( xThis );
372
373 if (nEventId == VCLEVENT_OBJECT_DYING)
374 {
375 m_lListener.disposeAndClear (aEvent);
376
377 m_pTabWin->RemoveEventListener( LINK( this, TabWindowService, EventListener ) );
378 m_pTabWin = NULL;
379 m_xTabWin.clear();
380
381 return 0;
382 }
383
384 ::cppu::OInterfaceContainerHelper* pContainer = m_lListener.getContainer(::getCppuType((const css::uno::Reference< css::awt::XTabListener >*) NULL));
385 if ( ! pContainer)
386 return 0;
387
388 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
389 while (pIterator.hasMoreElements())
390 {
391 try
392 {
393 css::awt::XTabListener* pListener = (css::awt::XTabListener*)pIterator.next();
394
395 switch (nEventId)
396 {
397 case VCLEVENT_TABPAGE_ACTIVATE :
398 pListener->activated( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
399 break;
400
401 case VCLEVENT_TABPAGE_DEACTIVATE :
402 pListener->deactivated( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
403 break;
404
405 case VCLEVENT_TABPAGE_INSERTED :
406 pListener->inserted( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
407 break;
408
409 case VCLEVENT_TABPAGE_REMOVED :
410 pListener->removed( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
411 break;
412
413 case VCLEVENT_TABPAGE_PAGETEXTCHANGED :
414 case VCLEVENT_TABPAGE_REMOVEDALL :
415 break;
416 }
417 }
418 catch(const css::uno::RuntimeException&)
419 {
420 pIterator.remove();
421 }
422 }
423
424 return 0;
425 }
426
427 //*****************************************************************************************************************
428 // TabWindowService
429 //*****************************************************************************************************************
impl_checkTabIndex(::sal_Int32 nID)430 void TabWindowService::impl_checkTabIndex (::sal_Int32 nID)
431 throw (css::lang::IndexOutOfBoundsException)
432 {
433 if (
434 (nID <= 0 ) ||
435 (nID > m_nPageIndexCounter)
436 )
437 {
438 throw css::lang::IndexOutOfBoundsException(
439 ::rtl::OUString::createFromAscii("Tab index out of bounds."),
440 css::uno::Reference< css::uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY ));
441 }
442 }
443
444 //*****************************************************************************************************************
445 // TabWindowService
446 //*****************************************************************************************************************
impl_getTabPageInfo(::sal_Int32 nID)447 TTabPageInfoHash::iterator TabWindowService::impl_getTabPageInfo(::sal_Int32 nID)
448 throw (css::lang::IndexOutOfBoundsException)
449 {
450 TTabPageInfoHash::iterator pIt = m_lTabPageInfos.find(nID);
451 if (pIt == m_lTabPageInfos.end ())
452 throw css::lang::IndexOutOfBoundsException(
453 ::rtl::OUString::createFromAscii("Tab index out of bounds."),
454 css::uno::Reference< css::uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY ));
455 return pIt;
456 }
457
458 //*****************************************************************************************************************
459 // TabWindowService
460 //*****************************************************************************************************************
mem_TabWin()461 FwkTabWindow* TabWindowService::mem_TabWin ()
462 {
463 FwkTabWindow* pWin = NULL;
464
465 if ( ! m_xTabWin.is ())
466 {
467 Window* pFakeParent = dynamic_cast< Window* >(Application::GetDefaultDevice ());
468
469 m_pTabWin = new FwkTabWindow (pFakeParent);
470 m_xTabWin = VCLUnoHelper::GetInterface (m_pTabWin);
471
472 m_pTabWin->AddEventListener( LINK( this, TabWindowService, EventListener ) );
473 }
474
475 if (m_xTabWin.is ())
476 pWin = m_pTabWin;
477
478 return pWin;
479 }
480
481 } // namespace framework
482