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 virtual void SAL_CALL startExecuteModal( 170 Reference< ui::dialogs::XDialogClosedListener > const & xListener ); 171 172 // XJobExecutor 173 virtual void SAL_CALL trigger( OUString const & event ); 174 }; 175 176 //______________________________________________________________________________ 177 ServiceImpl::ServiceImpl( Sequence<Any> const& args, 178 Reference<XComponentContext> const& xComponentContext) 179 : m_xComponentContext(xComponentContext), 180 m_bShowUpdateOnly( false ) 181 { 182 try { 183 comphelper::unwrapArgs( args, m_parent, m_view, m_unopkg ); 184 return; 185 } catch (css::lang::IllegalArgumentException & ) { 186 } 187 try { 188 comphelper::unwrapArgs( args, m_extensionURL); 189 } catch (css::lang::IllegalArgumentException & ) { 190 } 191 192 ResHookProc pProc = ResMgr::GetReadStringHook(); 193 if ( !pProc ) 194 ResMgr::SetReadStringHook( ReplaceProductNameHookProc ); 195 } 196 197 // XAsynchronousExecutableDialog 198 //______________________________________________________________________________ 199 void ServiceImpl::setDialogTitle( OUString const & title ) 200 { 201 if ( dp_gui::TheExtensionManager::s_ExtMgr.is() ) 202 { 203 const ::vos::OGuard guard( Application::GetSolarMutex() ); 204 ::rtl::Reference< ::dp_gui::TheExtensionManager > dialog( 205 ::dp_gui::TheExtensionManager::get( m_xComponentContext, 206 m_parent ? *m_parent : Reference<awt::XWindow>(), 207 m_extensionURL ? *m_extensionURL : OUString() ) ); 208 dialog->SetText( title ); 209 } 210 else 211 m_initialTitle = title; 212 } 213 214 //______________________________________________________________________________ 215 void ServiceImpl::startExecuteModal( 216 Reference< ui::dialogs::XDialogClosedListener > const & xListener ) 217 { 218 bool bCloseDialog = true; // only used if m_bShowUpdateOnly is true 219 ::std::auto_ptr<Application> app; 220 //ToDo: synchronize access to s_dialog !!! 221 if (! dp_gui::TheExtensionManager::s_ExtMgr.is()) 222 { 223 const bool bAppUp = (GetpApp() != 0); 224 bool bOfficePipePresent; 225 try { 226 bOfficePipePresent = dp_misc::office_is_running(); 227 } 228 catch (Exception & exc) { 229 if (bAppUp) { 230 const vos::OGuard guard( Application::GetSolarMutex() ); 231 std::auto_ptr<ErrorBox> box( 232 new ErrorBox( Application::GetActiveTopWindow(), 233 WB_OK, exc.Message ) ); 234 box->Execute(); 235 } 236 throw; 237 } 238 239 if (! bOfficePipePresent) { 240 OSL_ASSERT( ! bAppUp ); 241 app.reset( new MyApp ); 242 if (! InitVCL( Reference<lang::XMultiServiceFactory>( 243 m_xComponentContext->getServiceManager(), 244 UNO_QUERY_THROW ) )) 245 throw RuntimeException( OUSTR("Cannot initialize VCL!"), 246 static_cast<OWeakObject *>(this) ); 247 AllSettings as = app->GetSettings(); 248 OUString slang; 249 if (! (::utl::ConfigManager::GetDirectConfigProperty( 250 ::utl::ConfigManager::LOCALE ) >>= slang)) 251 throw RuntimeException( OUSTR("Cannot determine language!"), 252 static_cast<OWeakObject *>(this) ); 253 as.SetUILanguage( MsLangId::convertIsoStringToLanguage( slang ) ); 254 app->SetSettings( as ); 255 String sTitle = ::utl::ConfigManager::GetDirectConfigProperty( 256 ::utl::ConfigManager::PRODUCTNAME).get<OUString>() 257 + String(static_cast<sal_Unicode>(' ')) 258 + ::utl::ConfigManager::GetDirectConfigProperty( 259 ::utl::ConfigManager::PRODUCTVERSION).get<OUString>(); 260 app->SetDisplayName(sTitle); 261 ExtensionCmdQueue::syncRepositories( m_xComponentContext ); 262 } 263 } 264 else 265 { 266 // When m_bShowUpdateOnly is set, we are inside the office and the user clicked 267 // the update notification icon in the menu bar. We must not close the extensions 268 // dialog after displaying the update dialog when it has been visible before 269 if ( m_bShowUpdateOnly ) 270 bCloseDialog = ! dp_gui::TheExtensionManager::s_ExtMgr->isVisible(); 271 } 272 273 { 274 const ::vos::OGuard guard( Application::GetSolarMutex() ); 275 ::rtl::Reference< ::dp_gui::TheExtensionManager > myExtMgr( 276 ::dp_gui::TheExtensionManager::get( 277 m_xComponentContext, 278 m_parent ? *m_parent : Reference<awt::XWindow>(), 279 m_extensionURL ? *m_extensionURL : OUString() ) ); 280 myExtMgr->createDialog( false ); 281 if (m_initialTitle.getLength() > 0) { 282 myExtMgr->SetText( m_initialTitle ); 283 m_initialTitle = OUString(); 284 } 285 if ( m_bShowUpdateOnly ) 286 { 287 myExtMgr->checkUpdates( true, !bCloseDialog ); 288 if ( bCloseDialog ) 289 myExtMgr->Close(); 290 else 291 myExtMgr->ToTop( TOTOP_RESTOREWHENMIN ); 292 } 293 else 294 { 295 myExtMgr->Show(); 296 myExtMgr->ToTop( TOTOP_RESTOREWHENMIN ); 297 } 298 } 299 300 if (app.get() != 0) { 301 Application::Execute(); 302 DeInitVCL(); 303 } 304 305 if (xListener.is()) 306 xListener->dialogClosed( 307 ui::dialogs::DialogClosedEvent( 308 static_cast< ::cppu::OWeakObject * >(this), 309 sal_Int16(0)) ); 310 } 311 312 // XJobExecutor 313 //______________________________________________________________________________ 314 void ServiceImpl::trigger( OUString const &rEvent ) 315 { 316 if ( rEvent == OUSTR("SHOW_UPDATE_DIALOG") ) 317 m_bShowUpdateOnly = true; 318 else 319 m_bShowUpdateOnly = false; 320 321 startExecuteModal( Reference< ui::dialogs::XDialogClosedListener >() ); 322 } 323 324 namespace sdecl = comphelper::service_decl; 325 sdecl::class_<ServiceImpl, sdecl::with_args<true> > serviceSI; 326 sdecl::ServiceDecl const serviceDecl( 327 serviceSI, 328 "com.sun.star.comp.deployment.ui.PackageManagerDialog", 329 "com.sun.star.deployment.ui.PackageManagerDialog" ); 330 331 sdecl::class_<LicenseDialog, sdecl::with_args<true> > licenseSI; 332 sdecl::ServiceDecl const licenseDecl( 333 licenseSI, 334 "com.sun.star.comp.deployment.ui.LicenseDialog", 335 "com.sun.star.deployment.ui.LicenseDialog" ); 336 337 sdecl::class_<UpdateRequiredDialogService, sdecl::with_args<true> > updateSI; 338 sdecl::ServiceDecl const updateDecl( 339 updateSI, 340 "com.sun.star.comp.deployment.ui.UpdateRequiredDialog", 341 "com.sun.star.deployment.ui.UpdateRequiredDialog" ); 342 } // namespace dp_gui 343 344 extern "C" { 345 346 DESKTOP_DEPLOYMENTGUI_DLLPUBLIC 347 void SAL_CALL component_getImplementationEnvironment( 348 const sal_Char ** ppEnvTypeName, uno_Environment ** ) 349 { 350 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 351 } 352 353 DESKTOP_DEPLOYMENTGUI_DLLPUBLIC 354 void * SAL_CALL component_getFactory( 355 sal_Char const * pImplName, 356 lang::XMultiServiceFactory * pServiceManager, 357 registry::XRegistryKey * pRegistryKey ) 358 { 359 return component_getFactoryHelper( 360 pImplName, pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl, dp_gui::updateDecl ); 361 } 362 363 } // extern "C" 364