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 362 : 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 ( &m_aLock ,
84 : &m_aTransactionManager ,
85 : sal_False ) // sal_False => dont release shared mutex on calling us!
86 : , OWeakObject ( )
87 :
88 : // Init member
89 : , m_xFactory ( xFactory )
90 : , m_xTabWin ( )
91 : , m_pTabWin ( NULL )
92 : , m_lTabPageInfos ( )
93 0 : , m_lListener ( m_aLock.getShareableOslMutex())
94 : , m_nPageIndexCounter ( 1 )
95 0 : , m_nCurrentPageIndex ( 0 )
96 : {
97 : // Safe impossible cases.
98 : // Method not defined for all incoming parameter.
99 : LOG_ASSERT( xFactory.is(), "TabWindowService::TabWindowService()\nInvalid parameter detected!\n" )
100 0 : }
101 :
102 : //*****************************************************************************************************************
103 : // destructor
104 : //*****************************************************************************************************************
105 0 : TabWindowService::~TabWindowService()
106 : {
107 : // SAFE->
108 0 : ResetableGuard aGuard(m_aLock);
109 :
110 0 : if (m_pTabWin)
111 0 : m_pTabWin->RemoveEventListener( LINK( this, TabWindowService, EventListener ) );
112 0 : }
113 :
114 : //*****************************************************************************************************************
115 : // XSimpleTabController
116 : //*****************************************************************************************************************
117 0 : ::sal_Int32 SAL_CALL TabWindowService::insertTab()
118 : throw ( css::uno::RuntimeException )
119 : {
120 : // SAFE ->
121 0 : ResetableGuard aGuard( m_aLock );
122 :
123 0 : ::sal_Int32 nID = m_nPageIndexCounter++;
124 0 : TTabPageInfo aInfo(nID);
125 :
126 0 : m_lTabPageInfos[nID] = aInfo;
127 :
128 0 : return nID;
129 : }
130 :
131 : //*****************************************************************************************************************
132 : // XSimpleTabController
133 : //*****************************************************************************************************************
134 0 : void SAL_CALL TabWindowService::removeTab(::sal_Int32 nID)
135 : throw (css::lang::IndexOutOfBoundsException,
136 : css::uno::RuntimeException )
137 : {
138 : // SAFE ->
139 0 : ResetableGuard aGuard(m_aLock);
140 :
141 : // throws suitable IndexOutOfBoundsException .-)
142 0 : TTabPageInfoHash::iterator pIt = impl_getTabPageInfo (nID);
143 0 : m_lTabPageInfos.erase(pIt);
144 :
145 0 : FwkTabWindow* pTabWin = mem_TabWin ();
146 0 : if (pTabWin)
147 0 : pTabWin->RemovePage(nID);
148 0 : }
149 :
150 : //*****************************************************************************************************************
151 : // XSimpleTabController
152 : //*****************************************************************************************************************
153 0 : void SAL_CALL TabWindowService::setTabProps( ::sal_Int32 nID ,
154 : const css::uno::Sequence< css::beans::NamedValue >& lProperties)
155 : throw (css::lang::IndexOutOfBoundsException,
156 : css::uno::RuntimeException )
157 : {
158 : // SAFE ->
159 0 : ResetableGuard aGuard(m_aLock);
160 :
161 : // throws suitable IndexOutOfBoundsException .-)
162 0 : TTabPageInfoHash::iterator pIt = impl_getTabPageInfo (nID);
163 0 : TTabPageInfo& rInfo = pIt->second;
164 0 : rInfo.m_lProperties = lProperties;
165 :
166 0 : if ( ! rInfo.m_bCreated)
167 : {
168 0 : FwkTabWindow* pTabWin = mem_TabWin ();
169 0 : if (pTabWin)
170 : {
171 0 : pTabWin->AddTabPage(rInfo.m_nIndex, rInfo.m_lProperties);
172 0 : rInfo.m_bCreated = sal_True;
173 : }
174 0 : }
175 0 : }
176 :
177 : //*****************************************************************************************************************
178 : // XSimpleTabController
179 : //*****************************************************************************************************************
180 0 : css::uno::Sequence< css::beans::NamedValue > SAL_CALL TabWindowService::getTabProps(::sal_Int32 nID)
181 : throw (css::lang::IndexOutOfBoundsException,
182 : css::uno::RuntimeException )
183 : {
184 : // SAFE ->
185 0 : ResetableGuard aGuard(m_aLock);
186 :
187 : // throws suitable IndexOutOfBoundsException .-)
188 0 : TTabPageInfoHash::const_iterator pIt = impl_getTabPageInfo (nID);
189 0 : const TTabPageInfo& rInfo = pIt->second;
190 :
191 0 : return rInfo.m_lProperties;
192 : }
193 :
194 : //*****************************************************************************************************************
195 : // XSimpleTabController
196 : //*****************************************************************************************************************
197 0 : void SAL_CALL TabWindowService::activateTab(::sal_Int32 nID)
198 : throw (css::lang::IndexOutOfBoundsException,
199 : css::uno::RuntimeException )
200 : {
201 : // SAFE ->
202 0 : ResetableGuard aGuard(m_aLock);
203 :
204 : // throws suitable IndexOutOfBoundsException .-)
205 0 : impl_checkTabIndex (nID);
206 0 : m_nCurrentPageIndex = nID;
207 :
208 0 : FwkTabWindow* pTabWin = mem_TabWin ();
209 0 : if (pTabWin)
210 0 : pTabWin->ActivatePage(nID);
211 0 : }
212 :
213 : //*****************************************************************************************************************
214 : // XSimpleTabController
215 : //*****************************************************************************************************************
216 0 : ::sal_Int32 SAL_CALL TabWindowService::getActiveTabID()
217 : throw (css::uno::RuntimeException)
218 : {
219 : // SAFE->
220 0 : ResetableGuard aGuard( m_aLock );
221 0 : return m_nCurrentPageIndex;
222 : }
223 :
224 : //*****************************************************************************************************************
225 : // XSimpleTabController
226 : //*****************************************************************************************************************
227 0 : void SAL_CALL TabWindowService::addTabListener(const css::uno::Reference< css::awt::XTabListener >& xListener)
228 : throw (css::uno::RuntimeException)
229 : {
230 0 : m_lListener.addInterface(::getCppuType((const css::uno::Reference< css::awt::XTabListener >*)NULL), xListener);
231 0 : }
232 :
233 : //*****************************************************************************************************************
234 : // XSimpleTabController
235 : //*****************************************************************************************************************
236 0 : void SAL_CALL TabWindowService::removeTabListener(const css::uno::Reference< css::awt::XTabListener >& xListener)
237 : throw (css::uno::RuntimeException)
238 : {
239 0 : m_lListener.removeInterface(::getCppuType((const css::uno::Reference< css::awt::XTabListener >*)NULL), xListener);
240 0 : }
241 :
242 : //*****************************************************************************************************************
243 : // XComponent
244 : //*****************************************************************************************************************
245 0 : void SAL_CALL TabWindowService::dispose()
246 : throw (css::uno::RuntimeException)
247 : {
248 : // SAFE->
249 0 : ResetableGuard aGuard(m_aLock);
250 :
251 0 : css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
252 0 : css::lang::EventObject aEvent(xThis);
253 :
254 0 : m_lListener.disposeAndClear (aEvent);
255 :
256 0 : if (m_pTabWin)
257 0 : m_pTabWin->RemoveEventListener( LINK( this, TabWindowService, EventListener ) );
258 :
259 0 : m_pTabWin = NULL;
260 0 : m_xTabWin.clear();
261 0 : }
262 :
263 : //*****************************************************************************************************************
264 : // XComponent
265 : //*****************************************************************************************************************
266 0 : void SAL_CALL TabWindowService::addEventListener(const css::uno::Reference< css::lang::XEventListener >& xListener)
267 : throw (css::uno::RuntimeException)
268 : {
269 0 : m_lListener.addInterface(::getCppuType((const css::uno::Reference< css::lang::XEventListener >*)NULL), xListener);
270 0 : }
271 :
272 : //*****************************************************************************************************************
273 : // XComponent
274 : //*****************************************************************************************************************
275 0 : void SAL_CALL TabWindowService::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener)
276 : throw (css::uno::RuntimeException)
277 : {
278 0 : m_lListener.removeInterface(::getCppuType((const css::uno::Reference< css::lang::XEventListener >*)NULL), xListener);
279 0 : }
280 :
281 : //*****************************************************************************************************************
282 0 : void TabWindowService::impl_initializePropInfo()
283 : {
284 0 : impl_setPropertyChangeBroadcaster(static_cast< css::awt::XSimpleTabController* >(this));
285 :
286 : impl_addPropertyInfo(
287 : css::beans::Property(
288 : OUString("Window"),
289 : TABWINDOWSERVICE_PROPHANDLE_WINDOW,
290 0 : ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
291 0 : css::beans::PropertyAttribute::TRANSIENT));
292 0 : }
293 :
294 : //*****************************************************************************************************************
295 0 : void SAL_CALL TabWindowService::impl_setPropertyValue(const OUString& /*sProperty*/,
296 : sal_Int32 /*nHandle */,
297 : const css::uno::Any& /*aValue */)
298 :
299 : {
300 0 : }
301 :
302 : //*****************************************************************************************************************
303 0 : css::uno::Any SAL_CALL TabWindowService::impl_getPropertyValue(const OUString& /*sProperty*/,
304 : sal_Int32 nHandle )
305 : {
306 : /* There is no need to lock any mutex here. Because we share the
307 : solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
308 : see ctor of PropertySetHelper for further information.
309 : */
310 0 : css::uno::Any aValue;
311 :
312 0 : switch (nHandle)
313 : {
314 : case TABWINDOWSERVICE_PROPHANDLE_WINDOW:
315 : {
316 0 : mem_TabWin (); // force "creation on demand" of m_xTabWin :-)
317 0 : aValue <<= m_xTabWin;
318 : }
319 0 : break;
320 : }
321 :
322 0 : return aValue;
323 : }
324 :
325 : //*****************************************************************************************************************
326 : // TabWindowService
327 : //*****************************************************************************************************************
328 0 : IMPL_LINK( TabWindowService, EventListener, VclSimpleEvent*, pEvent )
329 : {
330 :
331 0 : if ( !pEvent && !pEvent->ISA(VclWindowEvent))
332 0 : return 0;
333 :
334 0 : sal_uLong nEventId = pEvent->GetId();
335 0 : VclWindowEvent* pWinEvt = static_cast< VclWindowEvent* >(pEvent);
336 :
337 0 : css::uno::Reference< css::uno::XInterface > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
338 0 : css::lang::EventObject aEvent( xThis );
339 :
340 0 : if (nEventId == VCLEVENT_OBJECT_DYING)
341 : {
342 0 : m_lListener.disposeAndClear (aEvent);
343 :
344 0 : m_pTabWin->RemoveEventListener( LINK( this, TabWindowService, EventListener ) );
345 0 : m_pTabWin = NULL;
346 0 : m_xTabWin.clear();
347 :
348 0 : return 0;
349 : }
350 :
351 0 : ::cppu::OInterfaceContainerHelper* pContainer = m_lListener.getContainer(::getCppuType((const css::uno::Reference< css::awt::XTabListener >*) NULL));
352 0 : if ( ! pContainer)
353 0 : return 0;
354 :
355 0 : ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
356 0 : while (pIterator.hasMoreElements())
357 : {
358 : try
359 : {
360 0 : css::awt::XTabListener* pListener = (css::awt::XTabListener*)pIterator.next();
361 :
362 0 : switch (nEventId)
363 : {
364 : case VCLEVENT_TABPAGE_ACTIVATE :
365 0 : pListener->activated( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
366 0 : break;
367 :
368 : case VCLEVENT_TABPAGE_DEACTIVATE :
369 0 : pListener->deactivated( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
370 0 : break;
371 :
372 : case VCLEVENT_TABPAGE_INSERTED :
373 0 : pListener->inserted( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
374 0 : break;
375 :
376 : case VCLEVENT_TABPAGE_REMOVED :
377 0 : pListener->removed( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
378 0 : break;
379 :
380 : case VCLEVENT_TABPAGE_PAGETEXTCHANGED :
381 : case VCLEVENT_TABPAGE_REMOVEDALL :
382 0 : break;
383 : }
384 : }
385 0 : catch(const css::uno::RuntimeException&)
386 : {
387 0 : pIterator.remove();
388 : }
389 : }
390 :
391 0 : return 0;
392 : }
393 :
394 : //*****************************************************************************************************************
395 : // TabWindowService
396 : //*****************************************************************************************************************
397 0 : void TabWindowService::impl_checkTabIndex (::sal_Int32 nID)
398 : throw (css::lang::IndexOutOfBoundsException)
399 : {
400 0 : if (
401 0 : (nID <= 0 ) ||
402 0 : (nID > m_nPageIndexCounter)
403 : )
404 : {
405 : throw css::lang::IndexOutOfBoundsException(
406 : OUString("Tab index out of bounds."),
407 0 : css::uno::Reference< css::uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY ));
408 : }
409 0 : }
410 :
411 : //*****************************************************************************************************************
412 : // TabWindowService
413 : //*****************************************************************************************************************
414 0 : TTabPageInfoHash::iterator TabWindowService::impl_getTabPageInfo(::sal_Int32 nID)
415 : throw (css::lang::IndexOutOfBoundsException)
416 : {
417 0 : TTabPageInfoHash::iterator pIt = m_lTabPageInfos.find(nID);
418 0 : if (pIt == m_lTabPageInfos.end ())
419 : throw css::lang::IndexOutOfBoundsException(
420 : OUString("Tab index out of bounds."),
421 0 : css::uno::Reference< css::uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY ));
422 0 : return pIt;
423 : }
424 :
425 : //*****************************************************************************************************************
426 : // TabWindowService
427 : //*****************************************************************************************************************
428 0 : FwkTabWindow* TabWindowService::mem_TabWin ()
429 : {
430 0 : FwkTabWindow* pWin = NULL;
431 :
432 0 : if ( ! m_xTabWin.is ())
433 : {
434 0 : Window* pFakeParent = dynamic_cast< Window* >(Application::GetDefaultDevice ());
435 :
436 0 : m_pTabWin = new FwkTabWindow (pFakeParent);
437 0 : m_xTabWin = VCLUnoHelper::GetInterface (m_pTabWin);
438 :
439 0 : m_pTabWin->AddEventListener( LINK( this, TabWindowService, EventListener ) );
440 : }
441 :
442 0 : if (m_xTabWin.is ())
443 0 : pWin = m_pTabWin;
444 :
445 0 : return pWin;
446 : }
447 :
448 402 : } // namespace framework
449 :
450 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|