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