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