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 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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