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 1 : 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 1 : ServiceImpl::ServiceImpl( Sequence<Any> const& args,
171 : Reference<XComponentContext> const& xComponentContext)
172 : : m_xComponentContext(xComponentContext),
173 1 : m_bShowUpdateOnly( false )
174 : {
175 : try {
176 1 : comphelper::unwrapArgs( args, m_parent, m_view, m_unopkg );
177 2 : 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 : ScopedVclPtrInstance<MessageDialog> box(
227 0 : Application::GetActiveTopWindow(), exc.Message);
228 0 : box->Execute();
229 : }
230 0 : throw;
231 : }
232 :
233 0 : if (! bOfficePipePresent) {
234 : OSL_ASSERT( ! bAppUp );
235 0 : app.reset( new MyApp );
236 0 : if (! InitVCL() )
237 : throw RuntimeException( "Cannot initialize VCL!",
238 0 : static_cast<OWeakObject *>(this) );
239 : Application::SetDisplayName(
240 0 : utl::ConfigManager::getProductName() +
241 0 : " " +
242 0 : utl::ConfigManager::getProductVersion());
243 0 : ExtensionCmdQueue::syncRepositories( m_xComponentContext );
244 : }
245 : }
246 : else
247 : {
248 : // When m_bShowUpdateOnly is set, we are inside the office and the user clicked
249 : // the update notification icon in the menu bar. We must not close the extensions
250 : // dialog after displaying the update dialog when it has been visible before
251 0 : if ( m_bShowUpdateOnly )
252 0 : bCloseDialog = ! dp_gui::TheExtensionManager::s_ExtMgr->isVisible();
253 : }
254 :
255 : {
256 0 : const SolarMutexGuard guard;
257 : ::rtl::Reference< ::dp_gui::TheExtensionManager > myExtMgr(
258 : ::dp_gui::TheExtensionManager::get(
259 : m_xComponentContext,
260 0 : m_parent ? *m_parent : Reference<awt::XWindow>(),
261 0 : m_extensionURL ? *m_extensionURL : OUString() ) );
262 0 : myExtMgr->createDialog( false );
263 0 : if (!m_initialTitle.isEmpty()) {
264 0 : myExtMgr->SetText( m_initialTitle );
265 0 : m_initialTitle.clear();
266 : }
267 0 : if ( m_bShowUpdateOnly )
268 : {
269 0 : myExtMgr->checkUpdates( true, !bCloseDialog );
270 0 : if ( bCloseDialog )
271 0 : myExtMgr->Close();
272 : else
273 0 : myExtMgr->ToTop( ToTopFlags::RestoreWhenMin );
274 : }
275 : else
276 : {
277 0 : myExtMgr->Show();
278 0 : myExtMgr->ToTop( ToTopFlags::RestoreWhenMin );
279 0 : }
280 : }
281 :
282 0 : if (app.get() != 0) {
283 0 : Application::Execute();
284 0 : DeInitVCL();
285 : }
286 :
287 0 : if (xListener.is())
288 0 : xListener->dialogClosed(
289 : ui::dialogs::DialogClosedEvent(
290 : static_cast< ::cppu::OWeakObject * >(this),
291 0 : sal_Int16(0)) );
292 0 : }
293 :
294 : // XJobExecutor
295 :
296 0 : void ServiceImpl::trigger( OUString const &rEvent ) throw (RuntimeException, std::exception)
297 : {
298 0 : if ( rEvent == "SHOW_UPDATE_DIALOG" )
299 0 : m_bShowUpdateOnly = true;
300 : else
301 0 : m_bShowUpdateOnly = false;
302 :
303 0 : startExecuteModal( Reference< ui::dialogs::XDialogClosedListener >() );
304 0 : }
305 :
306 : namespace sdecl = comphelper::service_decl;
307 1 : sdecl::class_<ServiceImpl, sdecl::with_args<true> > serviceSI;
308 1 : sdecl::ServiceDecl const serviceDecl(
309 : serviceSI,
310 : "com.sun.star.comp.deployment.ui.PackageManagerDialog",
311 : "com.sun.star.deployment.ui.PackageManagerDialog" );
312 :
313 1 : sdecl::class_<LicenseDialog, sdecl::with_args<true> > licenseSI;
314 1 : sdecl::ServiceDecl const licenseDecl(
315 : licenseSI,
316 : "com.sun.star.comp.deployment.ui.LicenseDialog",
317 : "com.sun.star.deployment.ui.LicenseDialog" );
318 :
319 1 : sdecl::class_<UpdateRequiredDialogService, sdecl::with_args<true> > updateSI;
320 1 : sdecl::ServiceDecl const updateDecl(
321 : updateSI,
322 : "com.sun.star.comp.deployment.ui.UpdateRequiredDialog",
323 : "com.sun.star.deployment.ui.UpdateRequiredDialog" );
324 : } // namespace dp_gui
325 :
326 : extern "C" {
327 :
328 2 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL deploymentgui_component_getFactory(
329 : sal_Char const * pImplName, void *, void *)
330 : {
331 : return component_getFactoryHelper(
332 2 : pImplName, dp_gui::serviceDecl, dp_gui::licenseDecl, dp_gui::updateDecl );
333 : }
334 :
335 3 : } // extern "C"
336 :
337 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|