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 #ifndef __FRAMEWORK_HELPER_TITLEBARUPDATE_HXX_ 28 #include <helper/titlebarupdate.hxx> 29 #endif 30 31 //_________________________________________________________________________________________________________________ 32 // my own includes 33 //_________________________________________________________________________________________________________________ 34 35 #ifndef __FRAMEWORK_PATTERN_WINDOW_HXX_ 36 #include <pattern/window.hxx> 37 #endif 38 39 #ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_ 40 #include <threadhelp/writeguard.hxx> 41 #endif 42 43 #ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_ 44 #include <threadhelp/readguard.hxx> 45 #endif 46 47 #ifndef __FRAMEWORK_MACROS_GENERIC_HXX_ 48 #include <macros/generic.hxx> 49 #endif 50 51 #ifndef __FRAMEWORK_SERVICES_H_ 52 #include <services.h> 53 #endif 54 55 #ifndef __FRAMEWORK_PROPETIES_H_ 56 #include <properties.h> 57 #endif 58 59 //_________________________________________________________________________________________________________________ 60 // interface includes 61 //_________________________________________________________________________________________________________________ 62 63 #ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_ 64 #include <com/sun/star/awt/XWindow.hpp> 65 #endif 66 67 #ifndef _COM_SUN_STAR_LANG_XSERVICXEINFO_HPP_ 68 #include <com/sun/star/lang/XServiceInfo.hpp> 69 #endif 70 71 #ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_ 72 #include <com/sun/star/lang/IllegalArgumentException.hpp> 73 #endif 74 75 #ifndef _COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_ 76 #include <com/sun/star/frame/XModuleManager.hpp> 77 #endif 78 79 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ 80 #include <com/sun/star/container/XNameAccess.hpp> 81 #endif 82 83 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ 84 #include <com/sun/star/beans/XPropertySet.hpp> 85 #endif 86 87 #ifndef _COM_SUN_STAR_BEANS_XMATERIALHOLDER_HPP_ 88 #include <com/sun/star/beans/XMaterialHolder.hpp> 89 #endif 90 91 #ifndef _COM_SUN_STAR_FRAME_XTITLECHANGEBROADCASTER_HPP_ 92 #include <com/sun/star/frame/XTitleChangeBroadcaster.hpp> 93 #endif 94 95 #ifndef _COM_SUN_STAR_BEANS_NAMEDVALUE_HPP_ 96 #include <com/sun/star/beans/NamedValue.hpp> 97 #endif 98 99 //_________________________________________________________________________________________________________________ 100 // other includes 101 //_________________________________________________________________________________________________________________ 102 103 #include <comphelper/sequenceashashmap.hxx> 104 #include <unotools/configmgr.hxx> 105 #include <unotools/bootstrap.hxx> 106 #include <vcl/window.hxx> 107 #include <vcl/syswin.hxx> 108 #include <toolkit/unohlp.hxx> 109 #include <vcl/svapp.hxx> 110 #include <vcl/wrkwin.hxx> 111 #include <tools/diagnose_ex.h> 112 113 //_________________________________________________________________________________________________________________ 114 // namespace 115 116 namespace framework{ 117 118 //_________________________________________________________________________________________________________________ 119 // const 120 121 static const ::sal_Int32 INVALID_ICON_ID = -1; 122 static const ::sal_Int32 DEFAULT_ICON_ID = 0; 123 124 //_________________________________________________________________________________________________________________ 125 // definitions 126 127 //***************************************************************************************************************** 128 // XInterface, XTypeProvider 129 130 DEFINE_XINTERFACE_5(TitleBarUpdate , 131 OWeakObject , 132 DIRECT_INTERFACE (css::lang::XTypeProvider ), 133 DIRECT_INTERFACE (css::lang::XInitialization ), 134 DIRECT_INTERFACE (css::frame::XFrameActionListener ), 135 DIRECT_INTERFACE (css::frame::XTitleChangeListener ), 136 DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener)) 137 138 DEFINE_XTYPEPROVIDER_5(TitleBarUpdate , 139 css::lang::XTypeProvider , 140 css::lang::XInitialization , 141 css::frame::XFrameActionListener, 142 css::frame::XTitleChangeListener, 143 css::lang::XEventListener ) 144 145 //***************************************************************************************************************** 146 TitleBarUpdate::TitleBarUpdate(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 147 : ThreadHelpBase (&Application::GetSolarMutex()) 148 , m_xSMGR (xSMGR ) 149 , m_xFrame ( ) 150 { 151 } 152 153 //***************************************************************************************************************** 154 TitleBarUpdate::~TitleBarUpdate() 155 { 156 } 157 158 //***************************************************************************************************************** 159 void SAL_CALL TitleBarUpdate::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) 160 throw(css::uno::Exception , 161 css::uno::RuntimeException) 162 { 163 // check arguments 164 css::uno::Reference< css::frame::XFrame > xFrame; 165 if (lArguments.getLength() < 1) 166 throw css::lang::IllegalArgumentException( 167 DECLARE_ASCII("Empty argument list!"), 168 static_cast< ::cppu::OWeakObject* >(this), 169 1); 170 171 lArguments[0] >>= xFrame; 172 if (!xFrame.is()) 173 throw css::lang::IllegalArgumentException( 174 DECLARE_ASCII("No valid frame specified!"), 175 static_cast< ::cppu::OWeakObject* >(this), 176 1); 177 178 // SYNCHRONIZED -> 179 WriteGuard aWriteLock(m_aLock); 180 // hold the frame as weak reference(!) so it can die everytimes :-) 181 m_xFrame = xFrame; 182 aWriteLock.unlock(); 183 // <- SYNCHRONIZED 184 185 // start listening 186 xFrame->addFrameActionListener(this); 187 188 css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(xFrame, css::uno::UNO_QUERY); 189 if (xBroadcaster.is ()) 190 xBroadcaster->addTitleChangeListener (this); 191 } 192 193 //***************************************************************************************************************** 194 void SAL_CALL TitleBarUpdate::frameAction(const css::frame::FrameActionEvent& aEvent) 195 throw(css::uno::RuntimeException) 196 { 197 // we are interested on events only, which must trigger a title bar update 198 // because component was changed. 199 if ( 200 (aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ) || 201 (aEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED) || 202 (aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING ) 203 ) 204 { 205 impl_forceUpdate (); 206 } 207 } 208 209 //***************************************************************************************************************** 210 void SAL_CALL TitleBarUpdate::titleChanged(const css::frame::TitleChangedEvent& /* aEvent */) 211 throw (css::uno::RuntimeException) 212 { 213 impl_forceUpdate (); 214 } 215 216 //***************************************************************************************************************** 217 void SAL_CALL TitleBarUpdate::disposing(const css::lang::EventObject&) 218 throw(css::uno::RuntimeException) 219 { 220 // nothing todo here - because we hold the frame as weak reference only 221 } 222 223 //***************************************************************************************************************** 224 ::sal_Bool TitleBarUpdate::implst_getModuleInfo(const css::uno::Reference< css::frame::XFrame >& xFrame, 225 TModuleInfo& rInfo ) 226 { 227 if ( ! xFrame.is ()) 228 return sal_False; 229 230 // SYNCHRONIZED -> 231 ReadGuard aReadLock(m_aLock); 232 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 233 aReadLock.unlock(); 234 // <- SYNCHRONIZED 235 236 try 237 { 238 css::uno::Reference< css::frame::XModuleManager > xModuleManager( 239 xSMGR->createInstance(SERVICENAME_MODULEMANAGER), 240 css::uno::UNO_QUERY_THROW); 241 242 css::uno::Reference< css::container::XNameAccess > xConfig( 243 xModuleManager, 244 css::uno::UNO_QUERY_THROW); 245 246 rInfo.sID = xModuleManager->identify(xFrame); 247 ::comphelper::SequenceAsHashMap lProps = xConfig->getByName (rInfo.sID); 248 249 rInfo.sUIName = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_UINAME, ::rtl::OUString()); 250 rInfo.nIcon = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_ICON , INVALID_ICON_ID ); 251 252 // Note: If we could retrieve a module id ... everything is OK. 253 // UIName and Icon ID are optional values ! 254 ::sal_Bool bSuccess = (rInfo.sID.getLength () > 0); 255 return bSuccess; 256 } 257 catch(const css::uno::Exception&) 258 {} 259 260 return sal_False; 261 } 262 263 //***************************************************************************************************************** 264 void TitleBarUpdate::impl_forceUpdate() 265 { 266 // SYNCHRONIZED -> 267 ReadGuard aReadLock(m_aLock); 268 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ; 269 css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY); 270 aReadLock.unlock(); 271 // <- SYNCHRONIZED 272 273 // frame already gone ? We hold it weak only ... 274 if ( ! xFrame.is()) 275 return; 276 277 // no window -> no chance to set/update title and icon 278 css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow(); 279 if ( ! xWindow.is()) 280 return; 281 282 impl_updateIcon (xFrame); 283 impl_updateTitle (xFrame); 284 } 285 286 //***************************************************************************************************************** 287 void TitleBarUpdate::impl_updateIcon(const css::uno::Reference< css::frame::XFrame >& xFrame) 288 { 289 css::uno::Reference< css::frame::XController > xController = xFrame->getController (); 290 css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow (); 291 292 if ( 293 ( ! xController.is() ) || 294 ( ! xWindow.is() ) 295 ) 296 return; 297 298 // a) set default value to an invalid one. So we can start further searches for right icon id, if 299 // first steps failed! 300 sal_Int32 nIcon = INVALID_ICON_ID; 301 302 // b) try to find information on controller property set directly 303 // Don't forget to catch possible exceptions - because these property is an optional one! 304 css::uno::Reference< css::beans::XPropertySet > xSet( xController, css::uno::UNO_QUERY ); 305 if ( xSet.is() ) 306 { 307 try 308 { 309 css::uno::Reference< css::beans::XPropertySetInfo > const xPSI( xSet->getPropertySetInfo(), css::uno::UNO_SET_THROW ); 310 if ( xPSI->hasPropertyByName( CONTROLLER_PROPNAME_ICONID ) ) 311 xSet->getPropertyValue( CONTROLLER_PROPNAME_ICONID ) >>= nIcon; 312 } 313 catch(const css::uno::Exception&) 314 { 315 DBG_UNHANDLED_EXCEPTION(); 316 } 317 } 318 319 // c) if b) failed ... identify the used module and retrieve set icon from module config. 320 // Tirck :-) Module was already specified outside and aInfo contains all needed informations. 321 if ( nIcon == INVALID_ICON_ID ) 322 { 323 TModuleInfo aInfo; 324 if (implst_getModuleInfo(xFrame, aInfo)) 325 nIcon = aInfo.nIcon; 326 } 327 328 // d) if all steps failed - use fallback :-) 329 // ... means using the global staroffice icon 330 if( nIcon == INVALID_ICON_ID ) 331 nIcon = DEFAULT_ICON_ID; 332 333 // e) set icon on container window now 334 // Don't forget SolarMutex! We use vcl directly :-( 335 // Check window pointer for right WorkWindow class too!!! 336 337 // VCL SYNCHRONIZED -> 338 ::vos::OClearableGuard aSolarLock( Application::GetSolarMutex() ); 339 340 Window* pWindow = (VCLUnoHelper::GetWindow( xWindow )); 341 if ( 342 ( pWindow ) && 343 ( pWindow->GetType() == WINDOW_WORKWINDOW ) 344 ) 345 { 346 WorkWindow* pWorkWindow = (WorkWindow*)pWindow; 347 pWorkWindow->SetIcon( (sal_uInt16)nIcon ); 348 349 css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); 350 rtl::OUString aURL; 351 if( xModel.is() ) 352 aURL = xModel->getURL(); 353 pWorkWindow->SetRepresentedURL( aURL ); 354 } 355 356 aSolarLock.clear(); 357 // <- VCL SYNCHRONIZED 358 } 359 360 //***************************************************************************************************************** 361 void TitleBarUpdate::impl_updateTitle(const css::uno::Reference< css::frame::XFrame >& xFrame) 362 { 363 // no window ... no chance to set any title -> return 364 css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow (); 365 if ( ! xWindow.is() ) 366 return; 367 368 css::uno::Reference< css::frame::XTitle > xTitle(xFrame, css::uno::UNO_QUERY); 369 if ( ! xTitle.is() ) 370 return; 371 372 const ::rtl::OUString sTitle = xTitle->getTitle (); 373 374 // VCL SYNCHRONIZED -> 375 ::vos::OClearableGuard aSolarLock( Application::GetSolarMutex() ); 376 377 Window* pWindow = (VCLUnoHelper::GetWindow( xWindow )); 378 if ( 379 ( pWindow ) && 380 ( pWindow->GetType() == WINDOW_WORKWINDOW ) 381 ) 382 { 383 WorkWindow* pWorkWindow = (WorkWindow*)pWindow; 384 pWorkWindow->SetText( sTitle ); 385 } 386 387 aSolarLock.clear(); 388 // <- VCL SYNCHRONIZED 389 } 390 391 } // namespace framework 392