Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "dp_gui_shared.hxx"
22 : #include "dp_gui.h"
23 : #include "dp_gui_theextmgr.hxx"
24 : #include <cppuhelper/implbase2.hxx>
25 : #include <cppuhelper/implementationentry.hxx>
26 : #include <unotools/configmgr.hxx>
27 : #include <comphelper/processfactory.hxx>
28 : #include <comphelper/servicedecl.hxx>
29 : #include <comphelper/unwrapargs.hxx>
30 : #include <i18nlangtag/languagetag.hxx>
31 : #include <vcl/layout.hxx>
32 : #include <vcl/svapp.hxx>
33 : #include <vcl/settings.hxx>
34 : #include <com/sun/star/lang/XServiceInfo.hpp>
35 : #include <com/sun/star/task/XJobExecutor.hpp>
36 : #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
37 :
38 : #include <boost/optional.hpp>
39 : #include <boost/utility.hpp>
40 : #include "license_dialog.hxx"
41 : #include "dp_gui_dialog2.hxx"
42 : #include "dp_gui_extensioncmdqueue.hxx"
43 :
44 : using namespace ::dp_misc;
45 : using namespace ::com::sun::star;
46 : using namespace ::com::sun::star::uno;
47 :
48 :
49 : namespace dp_gui {
50 :
51 :
52 : class MyApp : public Application, private boost::noncopyable
53 : {
54 : public:
55 : MyApp();
56 : virtual ~MyApp();
57 :
58 : // Application
59 : virtual int Main() SAL_OVERRIDE;
60 : virtual void DeInit() SAL_OVERRIDE;
61 : };
62 :
63 :
64 0 : MyApp::~MyApp()
65 : {
66 0 : }
67 :
68 :
69 0 : MyApp::MyApp()
70 : {
71 0 : }
72 :
73 :
74 0 : int MyApp::Main()
75 : {
76 0 : return EXIT_SUCCESS;
77 : }
78 :
79 0 : void MyApp::DeInit()
80 : {
81 : css::uno::Reference< css::uno::XComponentContext > context(
82 0 : comphelper::getProcessComponentContext());
83 0 : dp_misc::disposeBridges(context);
84 : css::uno::Reference< css::lang::XComponent >(
85 0 : context, css::uno::UNO_QUERY_THROW)->dispose();
86 0 : comphelper::setProcessServiceFactory(0);
87 0 : }
88 :
89 : namespace
90 : {
91 : struct ProductName
92 : : public rtl::Static< OUString, ProductName > {};
93 : struct Version
94 : : public rtl::Static< OUString, Version > {};
95 : struct AboutBoxVersion
96 : : public rtl::Static< OUString, AboutBoxVersion > {};
97 : struct AboutBoxVersionSuffix
98 : : public rtl::Static< OUString, AboutBoxVersionSuffix > {};
99 : struct OOOVendor
100 : : public rtl::Static< OUString, OOOVendor > {};
101 : struct Extension
102 : : public rtl::Static< OUString, Extension > {};
103 : }
104 :
105 0 : OUString ReplaceProductNameHookProc( const OUString& rStr )
106 : {
107 0 : if (rStr.indexOf( "%PRODUCT" ) == -1)
108 0 : return rStr;
109 :
110 0 : OUString sProductName = ProductName::get();
111 0 : OUString sVersion = Version::get();
112 0 : OUString sAboutBoxVersion = AboutBoxVersion::get();
113 0 : OUString sAboutBoxVersionSuffix = AboutBoxVersionSuffix::get();
114 0 : OUString sExtension = Extension::get();
115 0 : OUString sOOOVendor = OOOVendor::get();
116 :
117 0 : if ( sProductName.isEmpty() )
118 : {
119 0 : sProductName = utl::ConfigManager::getProductName();
120 0 : sVersion = utl::ConfigManager::getProductVersion();
121 0 : sAboutBoxVersion = utl::ConfigManager::getAboutBoxProductVersion();
122 0 : sAboutBoxVersionSuffix = utl::ConfigManager::getAboutBoxProductVersionSuffix();
123 0 : sOOOVendor = utl::ConfigManager::getVendor();
124 0 : if ( sExtension.isEmpty() )
125 : {
126 0 : sExtension = utl::ConfigManager::getProductExtension();
127 : }
128 : }
129 :
130 0 : OUString sRet = rStr.replaceAll( "%PRODUCTNAME", sProductName );
131 0 : sRet = sRet.replaceAll( "%PRODUCTVERSION", sVersion );
132 0 : sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSIONSUFFIX", sAboutBoxVersionSuffix );
133 0 : sRet = sRet.replaceAll( "%ABOUTBOXPRODUCTVERSION", sAboutBoxVersion );
134 0 : sRet = sRet.replaceAll( "%OOOVENDOR", sOOOVendor );
135 0 : sRet = sRet.replaceAll( "%PRODUCTEXTENSION", sExtension );
136 0 : return sRet;
137 : }
138 :
139 :
140 2 : class ServiceImpl
141 : : public ::cppu::WeakImplHelper2<ui::dialogs::XAsynchronousExecutableDialog,
142 : task::XJobExecutor>
143 : {
144 : Reference<XComponentContext> const m_xComponentContext;
145 : boost::optional< Reference<awt::XWindow> > /* const */ m_parent;
146 : boost::optional<OUString> /* const */ m_view;
147 : /* if true then this service is running in an unopkg process and not in an office process */
148 : boost::optional<sal_Bool> /* const */ m_unopkg;
149 : boost::optional<OUString> m_extensionURL;
150 : OUString m_initialTitle;
151 : bool m_bShowUpdateOnly;
152 :
153 : public:
154 : ServiceImpl( Sequence<Any> const & args,
155 : Reference<XComponentContext> const & xComponentContext );
156 :
157 : // XAsynchronousExecutableDialog
158 : virtual void SAL_CALL setDialogTitle( OUString const & aTitle )
159 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
160 : virtual void SAL_CALL startExecuteModal(
161 : Reference< ui::dialogs::XDialogClosedListener > const & xListener )
162 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
163 :
164 : // XJobExecutor
165 : virtual void SAL_CALL trigger( OUString const & event )
166 : throw (RuntimeException, std::exception) SAL_OVERRIDE;
167 : };
168 :
169 :
170 2 : ServiceImpl::ServiceImpl( Sequence<Any> const& args,
171 : Reference<XComponentContext> const& xComponentContext)
172 : : m_xComponentContext(xComponentContext),
173 2 : m_bShowUpdateOnly( false )
174 : {
175 : try {
176 2 : comphelper::unwrapArgs( args, m_parent, m_view, m_unopkg );
177 4 : return;
178 0 : } catch ( const css::lang::IllegalArgumentException & ) {
179 : }
180 : try {
181 0 : comphelper::unwrapArgs( args, m_extensionURL);
182 0 : } catch ( const css::lang::IllegalArgumentException & ) {
183 : }
184 :
185 0 : ResHookProc pProc = ResMgr::GetReadStringHook();
186 0 : if ( !pProc )
187 0 : ResMgr::SetReadStringHook( ReplaceProductNameHookProc );
188 : }
189 :
190 : // XAsynchronousExecutableDialog
191 :
192 0 : void ServiceImpl::setDialogTitle( OUString const & title )
193 : throw (RuntimeException, std::exception)
194 : {
195 0 : if ( dp_gui::TheExtensionManager::s_ExtMgr.is() )
196 : {
197 0 : const SolarMutexGuard guard;
198 : ::rtl::Reference< ::dp_gui::TheExtensionManager > dialog(
199 : ::dp_gui::TheExtensionManager::get( m_xComponentContext,
200 0 : m_parent ? *m_parent : Reference<awt::XWindow>(),
201 0 : m_extensionURL ? *m_extensionURL : OUString() ) );
202 0 : dialog->SetText( title );
203 : }
204 : else
205 0 : m_initialTitle = title;
206 0 : }
207 :
208 :
209 0 : void ServiceImpl::startExecuteModal(
210 : Reference< ui::dialogs::XDialogClosedListener > const & xListener )
211 : throw (RuntimeException, std::exception)
212 : {
213 0 : bool bCloseDialog = true; // only used if m_bShowUpdateOnly is true
214 0 : ::std::unique_ptr<Application> app;
215 : //ToDo: synchronize access to s_dialog !!!
216 0 : if (! dp_gui::TheExtensionManager::s_ExtMgr.is())
217 : {
218 0 : const bool bAppUp = (GetpApp() != 0);
219 : bool bOfficePipePresent;
220 : try {
221 0 : bOfficePipePresent = dp_misc::office_is_running();
222 : }
223 0 : catch (const Exception & exc) {
224 0 : if (bAppUp) {
225 0 : const SolarMutexGuard guard;
226 : boost::scoped_ptr<MessageDialog> box(
227 : new MessageDialog(Application::GetActiveTopWindow(),
228 0 : exc.Message));
229 0 : box->Execute();
230 : }
231 0 : throw;
232 : }
233 :
234 0 : if (! bOfficePipePresent) {
235 : OSL_ASSERT( ! bAppUp );
236 0 : app.reset( new MyApp );
237 0 : if (! InitVCL() )
238 : throw RuntimeException( "Cannot initialize VCL!",
239 0 : static_cast<OWeakObject *>(this) );
240 0 : AllSettings as = Application::GetSettings();
241 0 : as.SetUILanguageTag( LanguageTag( utl::ConfigManager::getLocale() ).makeFallback() );
242 0 : Application::SetSettings( as );
243 : Application::SetDisplayName(
244 0 : utl::ConfigManager::getProductName() +
245 0 : OUString(" ") +
246 0 : utl::ConfigManager::getProductVersion());
247 0 : ExtensionCmdQueue::syncRepositories( m_xComponentContext );
248 : }
249 : }
250 : else
251 : {
252 : // When m_bShowUpdateOnly is set, we are inside the office and the user clicked
253 : // the update notification icon in the menu bar. We must not close the extensions
254 : // dialog after displaying the update dialog when it has been visible before
255 0 : if ( m_bShowUpdateOnly )
256 0 : bCloseDialog = ! dp_gui::TheExtensionManager::s_ExtMgr->isVisible();
257 : }
258 :
259 : {
260 0 : const SolarMutexGuard guard;
261 : ::rtl::Reference< ::dp_gui::TheExtensionManager > myExtMgr(
262 : ::dp_gui::TheExtensionManager::get(
263 : m_xComponentContext,
264 0 : m_parent ? *m_parent : Reference<awt::XWindow>(),
265 0 : m_extensionURL ? *m_extensionURL : OUString() ) );
266 0 : myExtMgr->createDialog( false );
267 0 : if (!m_initialTitle.isEmpty()) {
268 0 : myExtMgr->SetText( m_initialTitle );
269 0 : m_initialTitle = OUString();
270 : }
271 0 : if ( m_bShowUpdateOnly )
272 : {
273 0 : myExtMgr->checkUpdates( true, !bCloseDialog );
274 0 : if ( bCloseDialog )
275 0 : myExtMgr->Close();
276 : else
277 0 : myExtMgr->ToTop( TOTOP_RESTOREWHENMIN );
278 : }
279 : else
280 : {
281 0 : myExtMgr->Show();
282 0 : myExtMgr->ToTop( TOTOP_RESTOREWHENMIN );
283 0 : }
284 : }
285 :
286 0 : if (app.get() != 0) {
287 0 : Application::Execute();
288 0 : DeInitVCL();
289 : }
290 :
291 0 : if (xListener.is())
292 0 : xListener->dialogClosed(
293 : ui::dialogs::DialogClosedEvent(
294 : static_cast< ::cppu::OWeakObject * >(this),
295 0 : sal_Int16(0)) );
296 0 : }
297 :
298 : // XJobExecutor
299 :
300 0 : void ServiceImpl::trigger( OUString const &rEvent ) throw (RuntimeException, std::exception)
301 : {
302 0 : if ( rEvent == "SHOW_UPDATE_DIALOG" )
303 0 : m_bShowUpdateOnly = true;
304 : else
305 0 : m_bShowUpdateOnly = false;
306 :
307 0 : startExecuteModal( Reference< ui::dialogs::XDialogClosedListener >() );
308 0 : }
309 :
310 : namespace sdecl = comphelper::service_decl;
311 2 : sdecl::class_<ServiceImpl, sdecl::with_args<true> > serviceSI;
312 2 : sdecl::ServiceDecl const serviceDecl(
313 : serviceSI,
314 : "com.sun.star.comp.deployment.ui.PackageManagerDialog",
315 : "com.sun.star.deployment.ui.PackageManagerDialog" );
316 :
317 2 : sdecl::class_<LicenseDialog, sdecl::with_args<true> > licenseSI;
318 2 : sdecl::ServiceDecl const licenseDecl(
319 : licenseSI,
320 : "com.sun.star.comp.deployment.ui.LicenseDialog",
321 : "com.sun.star.deployment.ui.LicenseDialog" );
322 :
323 2 : sdecl::class_<UpdateRequiredDialogService, sdecl::with_args<true> > updateSI;
324 2 : sdecl::ServiceDecl const updateDecl(
325 : updateSI,
326 : "com.sun.star.comp.deployment.ui.UpdateRequiredDialog",
327 : "com.sun.star.deployment.ui.UpdateRequiredDialog" );
328 : } // namespace dp_gui
329 :
330 : extern "C" {
331 :
332 4 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL deploymentgui_component_getFactory(
333 : sal_Char const * pImplName,
334 : void * pServiceManager,
335 : void * pRegistryKey )
336 : {
337 : return component_getFactoryHelper(
338 4 : pImplName, static_cast<css::lang::XMultiServiceFactory *>(pServiceManager), static_cast<css::registry::XRegistryKey *>(pRegistryKey), dp_gui::serviceDecl, dp_gui::licenseDecl, dp_gui::updateDecl );
339 : }
340 :
341 6 : } // extern "C"
342 :
343 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|