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