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