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_desktop.hxx" 26 27 #include "dp_gui_shared.hxx" 28 #include "dp_gui.h" 29 #include "dp_gui_theextmgr.hxx" 30 #include "cppuhelper/implbase2.hxx" 31 #include "cppuhelper/implementationentry.hxx" 32 #include "unotools/configmgr.hxx" 33 #include "comphelper/servicedecl.hxx" 34 #include "comphelper/unwrapargs.hxx" 35 #include <i18npool/mslangid.hxx> 36 #include "vcl/svapp.hxx" 37 #include "vcl/msgbox.hxx" 38 #include "com/sun/star/lang/XServiceInfo.hpp" 39 #include "com/sun/star/task/XJobExecutor.hpp" 40 #include "com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp" 41 42 #include "boost/bind.hpp" 43 #include "license_dialog.hxx" 44 #include "dp_gui_dialog2.hxx" 45 #include "dp_gui_extensioncmdqueue.hxx" 46 47 using namespace ::dp_misc; 48 using namespace ::com::sun::star; 49 using namespace ::com::sun::star::uno; 50 51 using ::rtl::OUString; 52 53 namespace css = ::com::sun::star; 54 namespace dp_gui { 55 56 //============================================================================== 57 class MyApp : public Application, private boost::noncopyable 58 { 59 public: 60 MyApp(); 61 virtual ~MyApp(); 62 63 // Application 64 virtual void Main(); 65 }; 66 67 //______________________________________________________________________________ 68 MyApp::~MyApp() 69 { 70 } 71 72 //______________________________________________________________________________ 73 MyApp::MyApp() 74 { 75 } 76 77 //______________________________________________________________________________ 78 void MyApp::Main() 79 { 80 } 81 82 //############################################################################## 83 84 namespace 85 { 86 struct ProductName 87 : public rtl::Static< String, ProductName > {}; 88 struct Version 89 : public rtl::Static< String, Version > {}; 90 struct AboutBoxVersion 91 : public rtl::Static< String, AboutBoxVersion > {}; 92 struct OOOVendor 93 : public rtl::Static< String, OOOVendor > {}; 94 struct Extension 95 : public rtl::Static< String, Extension > {}; 96 } 97 98 void ReplaceProductNameHookProc( String& rStr ) 99 { 100 static int nAll = 0, nPro = 0; 101 102 nAll++; 103 if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND ) 104 { 105 String &rProductName = ProductName::get(); 106 String &rVersion = Version::get(); 107 String &rAboutBoxVersion = AboutBoxVersion::get(); 108 String &rExtension = Extension::get(); 109 String &rOOOVendor = OOOVendor::get(); 110 111 if ( !rProductName.Len() ) 112 { 113 rtl::OUString aTmp; 114 Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ); 115 aRet >>= aTmp; 116 rProductName = aTmp; 117 118 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION ); 119 aRet >>= aTmp; 120 rVersion = aTmp; 121 122 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::ABOUTBOXPRODUCTVERSION ); 123 aRet >>= aTmp; 124 rAboutBoxVersion = aTmp; 125 126 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::OOOVENDOR ); 127 aRet >>= aTmp; 128 rOOOVendor = aTmp; 129 130 if ( !rExtension.Len() ) 131 { 132 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION ); 133 aRet >>= aTmp; 134 rExtension = aTmp; 135 } 136 } 137 138 nPro++; 139 rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", rProductName ); 140 rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion ); 141 rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion ); 142 rStr.SearchAndReplaceAllAscii( "%OOOVENDOR", rOOOVendor ); 143 rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension ); 144 } 145 } 146 147 //============================================================================== 148 class ServiceImpl 149 : public ::cppu::WeakImplHelper2<ui::dialogs::XAsynchronousExecutableDialog, 150 task::XJobExecutor> 151 { 152 Reference<XComponentContext> const m_xComponentContext; 153 boost::optional< Reference<awt::XWindow> > /* const */ m_parent; 154 boost::optional<OUString> /* const */ m_view; 155 /* if true then this service is running in an unopkg process and not in an office process */ 156 boost::optional<sal_Bool> /* const */ m_unopkg; 157 boost::optional<OUString> m_extensionURL; 158 OUString m_initialTitle; 159 bool m_bShowUpdateOnly; 160 161 public: 162 ServiceImpl( Sequence<Any> const & args, 163 Reference<XComponentContext> const & xComponentContext ); 164 165 // XAsynchronousExecutableDialog 166 virtual void SAL_CALL setDialogTitle( OUString const & aTitle ) 167 throw (RuntimeException); 168 virtual void SAL_CALL startExecuteModal( 169 Reference< ui::dialogs::XDialogClosedListener > const & xListener ) 170 throw (RuntimeException); 171 172 // XJobExecutor 173 virtual void SAL_CALL trigger( OUString const & event ) 174 throw (RuntimeException); 175 }; 176 177 //______________________________________________________________________________ 178 ServiceImpl::ServiceImpl( Sequence<Any> const& args, 179 Reference<XComponentContext> const& xComponentContext) 180 : m_xComponentContext(xComponentContext), 181 m_bShowUpdateOnly( false ) 182 { 183 try { 184 comphelper::unwrapArgs( args, m_parent, m_view, m_unopkg ); 185 return; 186 } catch (css::lang::IllegalArgumentException & ) { 187 } 188 try { 189 comphelper::unwrapArgs( args, m_extensionURL); 190 } catch (css::lang::IllegalArgumentException & ) { 191 } 192 193 ResHookProc pProc = ResMgr::GetReadStringHook(); 194 if ( !pProc ) 195 ResMgr::SetReadStringHook( ReplaceProductNameHookProc ); 196 } 197 198 // XAsynchronousExecutableDialog 199 //______________________________________________________________________________ 200 void ServiceImpl::setDialogTitle( OUString const & title ) 201 throw (RuntimeException) 202 { 203 if ( dp_gui::TheExtensionManager::s_ExtMgr.is() ) 204 { 205 const ::vos::OGuard guard( Application::GetSolarMutex() ); 206 ::rtl::Reference< ::dp_gui::TheExtensionManager > dialog( 207 ::dp_gui::TheExtensionManager::get( m_xComponentContext, 208 m_parent ? *m_parent : Reference<awt::XWindow>(), 209 m_extensionURL ? *m_extensionURL : OUString() ) ); 210 dialog->SetText( title ); 211 } 212 else 213 m_initialTitle = title; 214 } 215 216 //______________________________________________________________________________ 217 void ServiceImpl::startExecuteModal( 218 Reference< ui::dialogs::XDialogClosedListener > const & xListener ) 219 throw (RuntimeException) 220 { 221 bool bCloseDialog = true; // only used if m_bShowUpdateOnly is true 222 ::std::auto_ptr<Application> app; 223 //ToDo: synchronize access to s_dialog !!! 224 if (! dp_gui::TheExtensionManager::s_ExtMgr.is()) 225 { 226 const bool bAppUp = (GetpApp() != 0); 227 bool bOfficePipePresent; 228 try { 229 bOfficePipePresent = dp_misc::office_is_running(); 230 } 231 catch (Exception & exc) { 232 if (bAppUp) { 233 const vos::OGuard guard( Application::GetSolarMutex() ); 234 std::auto_ptr<ErrorBox> box( 235 new ErrorBox( Application::GetActiveTopWindow(), 236 WB_OK, exc.Message ) ); 237 box->Execute(); 238 } 239 throw; 240 } 241 242 if (! bOfficePipePresent) { 243 OSL_ASSERT( ! bAppUp ); 244 app.reset( new MyApp ); 245 if (! InitVCL( Reference<lang::XMultiServiceFactory>( 246 m_xComponentContext->getServiceManager(), 247 UNO_QUERY_THROW ) )) 248 throw RuntimeException( OUSTR("Cannot initialize VCL!"), 249 static_cast<OWeakObject *>(this) ); 250 AllSettings as = app->GetSettings(); 251 OUString slang; 252 if (! (::utl::ConfigManager::GetDirectConfigProperty( 253 ::utl::ConfigManager::LOCALE ) >>= slang)) 254 throw RuntimeException( OUSTR("Cannot determine language!"), 255 static_cast<OWeakObject *>(this) ); 256 as.SetUILanguage( MsLangId::convertIsoStringToLanguage( slang ) ); 257 app->SetSettings( as ); 258 String sTitle = ::utl::ConfigManager::GetDirectConfigProperty( 259 ::utl::ConfigManager::PRODUCTNAME).get<OUString>() 260 + String(static_cast<sal_Unicode>(' ')) 261 + ::utl::ConfigManager::GetDirectConfigProperty( 262 ::utl::ConfigManager::PRODUCTVERSION).get<OUString>(); 263 app->SetDisplayName(sTitle); 264 ExtensionCmdQueue::syncRepositories( m_xComponentContext ); 265 } 266 } 267 else 268 { 269 // When m_bShowUpdateOnly is set, we are inside the office and the user clicked 270 // the update notification icon in the menu bar. We must not close the extensions 271 // dialog after displaying the update dialog when it has been visible before 272 if ( m_bShowUpdateOnly ) 273 bCloseDialog = ! dp_gui::TheExtensionManager::s_ExtMgr->isVisible(); 274 } 275 276 { 277 const ::vos::OGuard guard( Application::GetSolarMutex() ); 278 ::rtl::Reference< ::dp_gui::TheExtensionManager > myExtMgr( 279 ::dp_gui::TheExtensionManager::get( 280 m_xComponentContext, 281 m_parent ? *m_parent : Reference<awt::XWindow>(), 282 m_extensionURL ? *m_extensionURL : OUString() ) ); 283 myExtMgr->createDialog( false ); 284 if (m_initialTitle.getLength() > 0) { 285 myExtMgr->SetText( m_initialTitle ); 286 m_initialTitle = OUString(); 287 } 288 if ( m_bShowUpdateOnly ) 289 { 290 myExtMgr->checkUpdates( true, !bCloseDialog ); 291 if ( bCloseDialog ) 292 myExtMgr->Close(); 293 else 294 myExtMgr->ToTop( TOTOP_RESTOREWHENMIN ); 295 } 296 else 297 { 298 myExtMgr->Show(); 299 myExtMgr->ToTop( TOTOP_RESTOREWHENMIN ); 300 } 301 } 302 303 if (app.get() != 0) { 304 Application::Execute(); 305 DeInitVCL(); 306 } 307 308 if (xListener.is()) 309 xListener->dialogClosed( 310 ui::dialogs::DialogClosedEvent( 311 static_cast< ::cppu::OWeakObject * >(this), 312 sal_Int16(0)) ); 313 } 314 315 // XJobExecutor 316 //______________________________________________________________________________ 317 void ServiceImpl::trigger( OUString const &rEvent ) throw (RuntimeException) 318 { 319 if ( rEvent == OUSTR("SHOW_UPDATE_DIALOG") ) 320 m_bShowUpdateOnly = true; 321 else 322 m_bShowUpdateOnly = false; 323 324 startExecuteModal( Reference< ui::dialogs::XDialogClosedListener >() ); 325 } 326 327 namespace sdecl = comphelper::service_decl; 328 sdecl::class_<ServiceImpl, sdecl::with_args<true> > serviceSI; 329 sdecl::ServiceDecl const serviceDecl( 330 serviceSI, 331 "com.sun.star.comp.deployment.ui.PackageManagerDialog", 332 "com.sun.star.deployment.ui.PackageManagerDialog" ); 333 334 sdecl::class_<LicenseDialog, sdecl::with_args<true> > licenseSI; 335 sdecl::ServiceDecl const licenseDecl( 336 licenseSI, 337 "com.sun.star.comp.deployment.ui.LicenseDialog", 338 "com.sun.star.deployment.ui.LicenseDialog" ); 339 340 sdecl::class_<UpdateRequiredDialogService, sdecl::with_args<true> > updateSI; 341 sdecl::ServiceDecl const updateDecl( 342 updateSI, 343 "com.sun.star.comp.deployment.ui.UpdateRequiredDialog", 344 "com.sun.star.deployment.ui.UpdateRequiredDialog" ); 345 } // namespace dp_gui 346 347 extern "C" { 348 349 void SAL_CALL component_getImplementationEnvironment( 350 const sal_Char ** ppEnvTypeName, uno_Environment ** ) 351 { 352 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 353 } 354 355 void * SAL_CALL component_getFactory( 356 sal_Char const * pImplName, 357 lang::XMultiServiceFactory * pServiceManager, 358 registry::XRegistryKey * pRegistryKey ) 359 { 360 return component_getFactoryHelper( 361 pImplName, pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl, dp_gui::updateDecl ); 362 } 363 364 } // extern "C" 365