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 : #define _WIN32_WINNT 0x0500
21 :
22 :
23 :
24 :
25 :
26 : #include "sal/config.h"
27 :
28 : #include <cstddef>
29 :
30 : #include "com/sun/star/beans/NamedValue.hpp"
31 :
32 : #include "com/sun/star/deployment/DependencyException.hpp"
33 : #include "com/sun/star/deployment/LicenseException.hpp"
34 : #include "com/sun/star/deployment/VersionException.hpp"
35 : #include "com/sun/star/deployment/InstallException.hpp"
36 : #include "com/sun/star/deployment/PlatformException.hpp"
37 :
38 : #include "com/sun/star/deployment/ui/LicenseDialog.hpp"
39 : #include "com/sun/star/deployment/DeploymentException.hpp"
40 : #include "com/sun/star/deployment/UpdateInformationProvider.hpp"
41 : #include "com/sun/star/deployment/XPackage.hpp"
42 :
43 : #include "com/sun/star/task/InteractionHandler.hpp"
44 : #include "com/sun/star/task/XAbortChannel.hpp"
45 : #include "com/sun/star/task/XInteractionAbort.hpp"
46 : #include "com/sun/star/task/XInteractionApprove.hpp"
47 :
48 : #include "com/sun/star/ucb/CommandAbortedException.hpp"
49 : #include "com/sun/star/ucb/CommandFailedException.hpp"
50 : #include "com/sun/star/ucb/XCommandEnvironment.hpp"
51 :
52 : #include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
53 :
54 : #include "com/sun/star/uno/Reference.hxx"
55 : #include "com/sun/star/uno/RuntimeException.hpp"
56 : #include "com/sun/star/uno/Sequence.hxx"
57 : #include "com/sun/star/uno/XInterface.hpp"
58 : #include "com/sun/star/uno/TypeClass.hpp"
59 : #include "osl/diagnose.h"
60 : #include "osl/mutex.hxx"
61 : #include "rtl/ref.hxx"
62 : #include "rtl/ustring.h"
63 : #include "rtl/ustring.hxx"
64 : #include "sal/types.h"
65 : #include "salhelper/thread.hxx"
66 : #include "ucbhelper/content.hxx"
67 : #include "cppuhelper/exc_hlp.hxx"
68 : #include "cppuhelper/implbase3.hxx"
69 : #include "comphelper/anytostring.hxx"
70 : #include "vcl/msgbox.hxx"
71 : #include "toolkit/helper/vclunohelper.hxx"
72 :
73 : #include "dp_gui.h"
74 : #include "dp_gui_extensioncmdqueue.hxx"
75 : #include "dp_gui_dependencydialog.hxx"
76 : #include "dp_gui_dialog2.hxx"
77 : #include "dp_gui_shared.hxx"
78 : #include "dp_gui_theextmgr.hxx"
79 : #include "dp_gui_updatedialog.hxx"
80 : #include "dp_gui_updateinstalldialog.hxx"
81 : #include "dp_dependencies.hxx"
82 : #include "dp_identifier.hxx"
83 : #include "dp_version.hxx"
84 :
85 : #include <queue>
86 : #include <boost/shared_ptr.hpp>
87 : #include <boost/scoped_ptr.hpp>
88 :
89 : #ifdef WNT
90 : #define GradientStyle_RECT BLA_GradientStyle_RECT
91 : #if defined _MSC_VER
92 : #pragma warning (push, 1)
93 : #pragma warning (disable: 4005)
94 : #endif
95 : #include <windows.h>
96 : #if defined _MSC_VER
97 : #pragma warning (pop)
98 : #endif
99 : #include <objbase.h>
100 : #undef GradientStyle_RECT
101 : #endif
102 :
103 :
104 : using namespace ::com::sun::star;
105 : using ::rtl::OUString;
106 :
107 : namespace {
108 :
109 0 : OUString getVersion( OUString const & sVersion )
110 : {
111 0 : return ( sVersion.isEmpty() ) ? OUString( RTL_CONSTASCII_USTRINGPARAM( "0" ) ) : sVersion;
112 : }
113 :
114 0 : OUString getVersion( const uno::Reference< deployment::XPackage > &rPackage )
115 : {
116 0 : return getVersion( rPackage->getVersion());
117 : }
118 : }
119 :
120 :
121 : namespace dp_gui {
122 :
123 : //==============================================================================
124 :
125 : class ProgressCmdEnv
126 : : public ::cppu::WeakImplHelper3< ucb::XCommandEnvironment,
127 : task::XInteractionHandler,
128 : ucb::XProgressHandler >
129 : {
130 : uno::Reference< task::XInteractionHandler2> m_xHandler;
131 : uno::Reference< uno::XComponentContext > m_xContext;
132 : uno::Reference< task::XAbortChannel> m_xAbortChannel;
133 :
134 : DialogHelper *m_pDialogHelper;
135 : OUString m_sTitle;
136 : bool m_bAborted;
137 : bool m_bWarnUser;
138 : sal_Int32 m_nCurrentProgress;
139 :
140 : void updateProgress();
141 :
142 : void update_( uno::Any const & Status ) throw ( uno::RuntimeException );
143 :
144 : public:
145 : virtual ~ProgressCmdEnv();
146 :
147 : /** When param bAskWhenInstalling = true, then the user is asked if he
148 : agrees to install this extension. In case this extension is already installed
149 : then the user is also notified and asked if he wants to replace that existing
150 : extension. In first case an interaction request with an InstallException
151 : will be handled and in the second case a VersionException will be handled.
152 : */
153 :
154 0 : ProgressCmdEnv( const uno::Reference< uno::XComponentContext > rContext,
155 : DialogHelper *pDialogHelper,
156 : const OUString &rTitle )
157 : : m_xContext( rContext ),
158 : m_pDialogHelper( pDialogHelper ),
159 : m_sTitle( rTitle ),
160 : m_bAborted( false ),
161 0 : m_bWarnUser( false )
162 0 : {}
163 :
164 0 : Dialog * activeDialog() { return m_pDialogHelper ? m_pDialogHelper->getWindow() : NULL; }
165 :
166 : void setTitle( const OUString& rNewTitle ) { m_sTitle = rNewTitle; }
167 : void startProgress();
168 : void stopProgress();
169 : void progressSection( const OUString &rText,
170 : const uno::Reference< task::XAbortChannel > &xAbortChannel = 0 );
171 0 : inline bool isAborted() const { return m_bAborted; }
172 0 : inline void setWarnUser( bool bNewVal ) { m_bWarnUser = bNewVal; }
173 :
174 : // XCommandEnvironment
175 : virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler()
176 : throw ( uno::RuntimeException );
177 : virtual uno::Reference< ucb::XProgressHandler > SAL_CALL getProgressHandler()
178 : throw ( uno::RuntimeException );
179 :
180 : // XInteractionHandler
181 : virtual void SAL_CALL handle( uno::Reference< task::XInteractionRequest > const & xRequest )
182 : throw ( uno::RuntimeException );
183 :
184 : // XProgressHandler
185 : virtual void SAL_CALL push( uno::Any const & Status )
186 : throw ( uno::RuntimeException );
187 : virtual void SAL_CALL update( uno::Any const & Status )
188 : throw ( uno::RuntimeException );
189 : virtual void SAL_CALL pop() throw ( uno::RuntimeException );
190 : };
191 :
192 : //------------------------------------------------------------------------------
193 0 : struct ExtensionCmd
194 : {
195 : enum E_CMD_TYPE { ADD, ENABLE, DISABLE, REMOVE, CHECK_FOR_UPDATES, ACCEPT_LICENSE };
196 :
197 : E_CMD_TYPE m_eCmdType;
198 : bool m_bWarnUser;
199 : OUString m_sExtensionURL;
200 : OUString m_sRepository;
201 : uno::Reference< deployment::XPackage > m_xPackage;
202 : std::vector< uno::Reference< deployment::XPackage > > m_vExtensionList;
203 :
204 0 : ExtensionCmd( const E_CMD_TYPE eCommand,
205 : const OUString &rExtensionURL,
206 : const OUString &rRepository,
207 : const bool bWarnUser )
208 : : m_eCmdType( eCommand ),
209 : m_bWarnUser( bWarnUser ),
210 : m_sExtensionURL( rExtensionURL ),
211 0 : m_sRepository( rRepository ) {};
212 0 : ExtensionCmd( const E_CMD_TYPE eCommand,
213 : const uno::Reference< deployment::XPackage > &rPackage )
214 : : m_eCmdType( eCommand ),
215 : m_bWarnUser( false ),
216 0 : m_xPackage( rPackage ) {};
217 0 : ExtensionCmd( const E_CMD_TYPE eCommand,
218 : const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList )
219 : : m_eCmdType( eCommand ),
220 : m_bWarnUser( false ),
221 0 : m_vExtensionList( vExtensionList ) {};
222 : };
223 :
224 : typedef ::boost::shared_ptr< ExtensionCmd > TExtensionCmd;
225 :
226 : //------------------------------------------------------------------------------
227 : class ExtensionCmdQueue::Thread: public salhelper::Thread
228 : {
229 : public:
230 : Thread( DialogHelper *pDialogHelper,
231 : TheExtensionManager *pManager,
232 : const uno::Reference< uno::XComponentContext > & rContext );
233 :
234 : void addExtension( const OUString &rExtensionURL,
235 : const OUString &rRepository,
236 : const bool bWarnUser );
237 : void removeExtension( const uno::Reference< deployment::XPackage > &rPackage );
238 : void enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
239 : const bool bEnable );
240 : void checkForUpdates( const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList );
241 : void acceptLicense( const uno::Reference< deployment::XPackage > &rPackage );
242 : void stop();
243 : bool isBusy();
244 :
245 : private:
246 : virtual ~Thread();
247 :
248 : virtual void execute();
249 :
250 : void _insert(const TExtensionCmd& rExtCmd);
251 :
252 : void _addExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
253 : const OUString &rPackageURL,
254 : const OUString &rRepository,
255 : const bool bWarnUser );
256 : void _removeExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
257 : const uno::Reference< deployment::XPackage > &xPackage );
258 : void _enableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
259 : const uno::Reference< deployment::XPackage > &xPackage );
260 : void _disableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
261 : const uno::Reference< deployment::XPackage > &xPackage );
262 : void _checkForUpdates( const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList );
263 : void _acceptLicense( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
264 : const uno::Reference< deployment::XPackage > &xPackage );
265 :
266 : enum Input { NONE, START, STOP };
267 :
268 : uno::Reference< uno::XComponentContext > m_xContext;
269 : std::queue< TExtensionCmd > m_queue;
270 :
271 : DialogHelper *m_pDialogHelper;
272 : TheExtensionManager *m_pManager;
273 :
274 : const OUString m_sEnablingPackages;
275 : const OUString m_sDisablingPackages;
276 : const OUString m_sAddingPackages;
277 : const OUString m_sRemovingPackages;
278 : const OUString m_sDefaultCmd;
279 : const OUString m_sAcceptLicense;
280 : osl::Condition m_wakeup;
281 : osl::Mutex m_mutex;
282 : Input m_eInput;
283 : bool m_bStopped;
284 : bool m_bWorking;
285 : };
286 :
287 : //------------------------------------------------------------------------------
288 0 : void ProgressCmdEnv::startProgress()
289 : {
290 0 : m_nCurrentProgress = 0;
291 :
292 0 : if ( m_pDialogHelper )
293 0 : m_pDialogHelper->showProgress( true );
294 0 : }
295 :
296 : //------------------------------------------------------------------------------
297 0 : void ProgressCmdEnv::stopProgress()
298 : {
299 0 : if ( m_pDialogHelper )
300 0 : m_pDialogHelper->showProgress( false );
301 0 : }
302 :
303 : //------------------------------------------------------------------------------
304 0 : void ProgressCmdEnv::progressSection( const OUString &rText,
305 : const uno::Reference< task::XAbortChannel > &xAbortChannel )
306 : {
307 0 : m_xAbortChannel = xAbortChannel;
308 0 : if (! m_bAborted)
309 : {
310 0 : m_nCurrentProgress = 0;
311 0 : if ( m_pDialogHelper )
312 : {
313 0 : m_pDialogHelper->updateProgress( rText, xAbortChannel );
314 0 : m_pDialogHelper->updateProgress( 5 );
315 : }
316 : }
317 0 : }
318 :
319 : //------------------------------------------------------------------------------
320 0 : void ProgressCmdEnv::updateProgress()
321 : {
322 0 : if ( ! m_bAborted )
323 : {
324 0 : long nProgress = ((m_nCurrentProgress*5) % 100) + 5;
325 0 : if ( m_pDialogHelper )
326 0 : m_pDialogHelper->updateProgress( nProgress );
327 : }
328 0 : }
329 :
330 : //------------------------------------------------------------------------------
331 0 : ProgressCmdEnv::~ProgressCmdEnv()
332 : {
333 : // TODO: stop all threads and wait
334 0 : }
335 :
336 :
337 : //------------------------------------------------------------------------------
338 : // XCommandEnvironment
339 : //------------------------------------------------------------------------------
340 0 : uno::Reference< task::XInteractionHandler > ProgressCmdEnv::getInteractionHandler()
341 : throw ( uno::RuntimeException )
342 : {
343 0 : return this;
344 : }
345 :
346 : //------------------------------------------------------------------------------
347 0 : uno::Reference< ucb::XProgressHandler > ProgressCmdEnv::getProgressHandler()
348 : throw ( uno::RuntimeException )
349 : {
350 0 : return this;
351 : }
352 :
353 : //------------------------------------------------------------------------------
354 : // XInteractionHandler
355 : //------------------------------------------------------------------------------
356 0 : void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & xRequest )
357 : throw ( uno::RuntimeException )
358 : {
359 0 : uno::Any request( xRequest->getRequest() );
360 : OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
361 : dp_misc::TRACE( OUSTR("[dp_gui_cmdenv.cxx] incoming request:\n")
362 0 : + ::comphelper::anyToString(request) + OUSTR("\n"));
363 :
364 0 : lang::WrappedTargetException wtExc;
365 0 : deployment::DependencyException depExc;
366 0 : deployment::LicenseException licExc;
367 0 : deployment::VersionException verExc;
368 0 : deployment::InstallException instExc;
369 0 : deployment::PlatformException platExc;
370 :
371 : // selections:
372 0 : bool approve = false;
373 0 : bool abort = false;
374 :
375 0 : if (request >>= wtExc) {
376 : // handable deployment error signalled, e.g.
377 : // bundle item registration failed, notify cause only:
378 0 : uno::Any cause;
379 0 : deployment::DeploymentException dpExc;
380 0 : if (wtExc.TargetException >>= dpExc)
381 0 : cause = dpExc.Cause;
382 : else {
383 0 : ucb::CommandFailedException cfExc;
384 0 : if (wtExc.TargetException >>= cfExc)
385 0 : cause = cfExc.Reason;
386 : else
387 0 : cause = wtExc.TargetException;
388 : }
389 0 : update_( cause );
390 :
391 : // ignore intermediate errors of legacy packages, i.e.
392 : // former pkgchk behaviour:
393 0 : const uno::Reference< deployment::XPackage > xPackage( wtExc.Context, uno::UNO_QUERY );
394 : OSL_ASSERT( xPackage.is() );
395 0 : if ( xPackage.is() )
396 : {
397 0 : const uno::Reference< deployment::XPackageTypeInfo > xPackageType( xPackage->getPackageType() );
398 : OSL_ASSERT( xPackageType.is() );
399 0 : if (xPackageType.is())
400 : {
401 0 : approve = ( xPackage->isBundle() &&
402 0 : xPackageType->getMediaType().matchAsciiL(
403 : RTL_CONSTASCII_STRINGPARAM(
404 : "application/"
405 0 : "vnd.sun.star.legacy-package-bundle") ));
406 0 : }
407 : }
408 0 : abort = !approve;
409 : }
410 0 : else if (request >>= depExc)
411 : {
412 0 : std::vector< rtl::OUString > deps;
413 0 : for (sal_Int32 i = 0; i < depExc.UnsatisfiedDependencies.getLength();
414 : ++i)
415 : {
416 : deps.push_back(
417 0 : dp_misc::Dependencies::getErrorText( depExc.UnsatisfiedDependencies[i]) );
418 : }
419 : {
420 0 : SolarMutexGuard guard;
421 0 : short n = DependencyDialog( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, deps ).Execute();
422 : // Distinguish between closing the dialog and programatically
423 : // canceling the dialog (headless VCL):
424 : approve = n == RET_OK
425 0 : || (n == RET_CANCEL && !Application::IsDialogCancelEnabled());
426 0 : }
427 : }
428 0 : else if (request >>= licExc)
429 : {
430 : uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
431 : deployment::ui::LicenseDialog::create(
432 0 : m_xContext, VCLUnoHelper::GetInterface( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL ),
433 0 : licExc.ExtensionName, licExc.Text ) );
434 0 : sal_Int16 res = xDialog->execute();
435 0 : if ( res == ui::dialogs::ExecutableDialogResults::CANCEL )
436 0 : abort = true;
437 0 : else if ( res == ui::dialogs::ExecutableDialogResults::OK )
438 0 : approve = true;
439 : else
440 : {
441 : OSL_ASSERT(0);
442 0 : }
443 : }
444 0 : else if (request >>= verExc)
445 : {
446 : sal_uInt32 id;
447 0 : switch (dp_misc::compareVersions(
448 0 : verExc.NewVersion, verExc.Deployed->getVersion() ))
449 : {
450 : case dp_misc::LESS:
451 0 : id = RID_WARNINGBOX_VERSION_LESS;
452 0 : break;
453 : case dp_misc::EQUAL:
454 0 : id = RID_WARNINGBOX_VERSION_EQUAL;
455 0 : break;
456 : default: // dp_misc::GREATER
457 0 : id = RID_WARNINGBOX_VERSION_GREATER;
458 0 : break;
459 : }
460 : OSL_ASSERT( verExc.Deployed.is() );
461 : bool bEqualNames = verExc.NewDisplayName.equals(
462 0 : verExc.Deployed->getDisplayName());
463 : {
464 0 : SolarMutexGuard guard;
465 0 : WarningBox box( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, ResId(id, *DeploymentGuiResMgr::get()));
466 0 : String s;
467 0 : if (bEqualNames)
468 : {
469 0 : s = box.GetMessText();
470 : }
471 0 : else if (id == RID_WARNINGBOX_VERSION_EQUAL)
472 : {
473 : //hypothetical: requires two instances of an extension with the same
474 : //version to have different display names. Probably the developer forgot
475 : //to change the version.
476 0 : s = String(ResId(RID_STR_WARNINGBOX_VERSION_EQUAL_DIFFERENT_NAMES, *DeploymentGuiResMgr::get()));
477 : }
478 0 : else if (id == RID_WARNINGBOX_VERSION_LESS)
479 : {
480 0 : s = String(ResId(RID_STR_WARNINGBOX_VERSION_LESS_DIFFERENT_NAMES, *DeploymentGuiResMgr::get()));
481 : }
482 0 : else if (id == RID_WARNINGBOX_VERSION_GREATER)
483 : {
484 0 : s = String(ResId(RID_STR_WARNINGBOX_VERSION_GREATER_DIFFERENT_NAMES, *DeploymentGuiResMgr::get()));
485 : }
486 0 : s.SearchAndReplaceAllAscii( "$NAME", verExc.NewDisplayName);
487 0 : s.SearchAndReplaceAllAscii( "$OLDNAME", verExc.Deployed->getDisplayName());
488 0 : s.SearchAndReplaceAllAscii( "$NEW", getVersion(verExc.NewVersion) );
489 0 : s.SearchAndReplaceAllAscii( "$DEPLOYED", getVersion(verExc.Deployed) );
490 0 : box.SetMessText(s);
491 0 : approve = box.Execute() == RET_OK;
492 0 : abort = !approve;
493 : }
494 : }
495 0 : else if (request >>= instExc)
496 : {
497 0 : if ( ! m_bWarnUser )
498 : {
499 0 : approve = true;
500 : }
501 : else
502 : {
503 0 : if ( m_pDialogHelper )
504 : {
505 0 : SolarMutexGuard guard;
506 :
507 0 : approve = m_pDialogHelper->installExtensionWarn( instExc.displayName );
508 : }
509 : else
510 0 : approve = false;
511 0 : abort = !approve;
512 : }
513 : }
514 0 : else if (request >>= platExc)
515 : {
516 0 : SolarMutexGuard guard;
517 0 : String sMsg( ResId( RID_STR_UNSUPPORTED_PLATFORM, *DeploymentGuiResMgr::get() ) );
518 0 : sMsg.SearchAndReplaceAllAscii( "%Name", platExc.package->getDisplayName() );
519 0 : ErrorBox box( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, WB_OK, sMsg );
520 0 : box.Execute();
521 0 : approve = true;
522 : }
523 :
524 0 : if (approve == false && abort == false)
525 : {
526 : // forward to UUI handler:
527 0 : if (! m_xHandler.is()) {
528 : // late init:
529 0 : m_xHandler = task::InteractionHandler::createWithParentAndContext(m_xContext, NULL, m_sTitle);
530 : }
531 0 : m_xHandler->handle( xRequest );
532 : }
533 : else
534 : {
535 : // select:
536 : uno::Sequence< uno::Reference< task::XInteractionContinuation > > conts(
537 0 : xRequest->getContinuations() );
538 0 : uno::Reference< task::XInteractionContinuation > const * pConts = conts.getConstArray();
539 0 : sal_Int32 len = conts.getLength();
540 0 : for ( sal_Int32 pos = 0; pos < len; ++pos )
541 : {
542 0 : if (approve) {
543 0 : uno::Reference< task::XInteractionApprove > xInteractionApprove( pConts[ pos ], uno::UNO_QUERY );
544 0 : if (xInteractionApprove.is()) {
545 0 : xInteractionApprove->select();
546 : // don't query again for ongoing continuations:
547 0 : approve = false;
548 0 : }
549 : }
550 0 : else if (abort) {
551 0 : uno::Reference< task::XInteractionAbort > xInteractionAbort( pConts[ pos ], uno::UNO_QUERY );
552 0 : if (xInteractionAbort.is()) {
553 0 : xInteractionAbort->select();
554 : // don't query again for ongoing continuations:
555 0 : abort = false;
556 0 : }
557 : }
558 0 : }
559 0 : }
560 0 : }
561 :
562 : //------------------------------------------------------------------------------
563 : // XProgressHandler
564 : //------------------------------------------------------------------------------
565 0 : void ProgressCmdEnv::push( uno::Any const & rStatus )
566 : throw( uno::RuntimeException )
567 : {
568 0 : update_( rStatus );
569 0 : }
570 :
571 : //------------------------------------------------------------------------------
572 0 : void ProgressCmdEnv::update_( uno::Any const & rStatus )
573 : throw( uno::RuntimeException )
574 : {
575 0 : OUString text;
576 0 : if ( rStatus.hasValue() && !( rStatus >>= text) )
577 : {
578 0 : if ( rStatus.getValueTypeClass() == uno::TypeClass_EXCEPTION )
579 0 : text = static_cast< uno::Exception const *>( rStatus.getValue() )->Message;
580 0 : if ( text.isEmpty() )
581 0 : text = ::comphelper::anyToString( rStatus ); // fallback
582 :
583 0 : const SolarMutexGuard aGuard;
584 0 : const boost::scoped_ptr< ErrorBox > aBox( new ErrorBox( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, WB_OK, text ) );
585 0 : aBox->Execute();
586 : }
587 0 : ++m_nCurrentProgress;
588 0 : updateProgress();
589 0 : }
590 :
591 : //------------------------------------------------------------------------------
592 0 : void ProgressCmdEnv::update( uno::Any const & rStatus )
593 : throw( uno::RuntimeException )
594 : {
595 0 : update_( rStatus );
596 0 : }
597 :
598 : //------------------------------------------------------------------------------
599 0 : void ProgressCmdEnv::pop()
600 : throw( uno::RuntimeException )
601 : {
602 0 : update_( uno::Any() ); // no message
603 0 : }
604 :
605 : //------------------------------------------------------------------------------
606 0 : ExtensionCmdQueue::Thread::Thread( DialogHelper *pDialogHelper,
607 : TheExtensionManager *pManager,
608 : const uno::Reference< uno::XComponentContext > & rContext ) :
609 : salhelper::Thread( "dp_gui_extensioncmdqueue" ),
610 : m_xContext( rContext ),
611 : m_pDialogHelper( pDialogHelper ),
612 : m_pManager( pManager ),
613 : m_sEnablingPackages( DialogHelper::getResourceString( RID_STR_ENABLING_PACKAGES ) ),
614 : m_sDisablingPackages( DialogHelper::getResourceString( RID_STR_DISABLING_PACKAGES ) ),
615 : m_sAddingPackages( DialogHelper::getResourceString( RID_STR_ADDING_PACKAGES ) ),
616 : m_sRemovingPackages( DialogHelper::getResourceString( RID_STR_REMOVING_PACKAGES ) ),
617 : m_sDefaultCmd( DialogHelper::getResourceString( RID_STR_ADD_PACKAGES ) ),
618 : m_sAcceptLicense( DialogHelper::getResourceString( RID_STR_ACCEPT_LICENSE ) ),
619 : m_eInput( NONE ),
620 : m_bStopped( false ),
621 0 : m_bWorking( false )
622 : {
623 : OSL_ASSERT( pDialogHelper );
624 0 : }
625 :
626 : //------------------------------------------------------------------------------
627 0 : void ExtensionCmdQueue::Thread::addExtension( const ::rtl::OUString &rExtensionURL,
628 : const ::rtl::OUString &rRepository,
629 : const bool bWarnUser )
630 : {
631 0 : if ( !rExtensionURL.isEmpty() )
632 : {
633 0 : TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::ADD, rExtensionURL, rRepository, bWarnUser ) );
634 0 : _insert( pEntry );
635 : }
636 0 : }
637 :
638 : //------------------------------------------------------------------------------
639 0 : void ExtensionCmdQueue::Thread::removeExtension( const uno::Reference< deployment::XPackage > &rPackage )
640 : {
641 0 : if ( rPackage.is() )
642 : {
643 0 : TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::REMOVE, rPackage ) );
644 0 : _insert( pEntry );
645 : }
646 0 : }
647 :
648 : //------------------------------------------------------------------------------
649 0 : void ExtensionCmdQueue::Thread::acceptLicense( const uno::Reference< deployment::XPackage > &rPackage )
650 : {
651 0 : if ( rPackage.is() )
652 : {
653 0 : TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::ACCEPT_LICENSE, rPackage ) );
654 0 : _insert( pEntry );
655 : }
656 0 : }
657 :
658 : //------------------------------------------------------------------------------
659 0 : void ExtensionCmdQueue::Thread::enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
660 : const bool bEnable )
661 : {
662 0 : if ( rPackage.is() )
663 : {
664 : TExtensionCmd pEntry( new ExtensionCmd( bEnable ? ExtensionCmd::ENABLE :
665 : ExtensionCmd::DISABLE,
666 0 : rPackage ) );
667 0 : _insert( pEntry );
668 : }
669 0 : }
670 :
671 : //------------------------------------------------------------------------------
672 0 : void ExtensionCmdQueue::Thread::checkForUpdates(
673 : const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList )
674 : {
675 0 : TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::CHECK_FOR_UPDATES, vExtensionList ) );
676 0 : _insert( pEntry );
677 0 : }
678 :
679 : //------------------------------------------------------------------------------
680 : //Stopping this thread will not abort the installation of extensions.
681 0 : void ExtensionCmdQueue::Thread::stop()
682 : {
683 0 : osl::MutexGuard aGuard( m_mutex );
684 0 : m_bStopped = true;
685 0 : m_eInput = STOP;
686 0 : m_wakeup.set();
687 0 : }
688 :
689 : //------------------------------------------------------------------------------
690 0 : bool ExtensionCmdQueue::Thread::isBusy()
691 : {
692 0 : osl::MutexGuard aGuard( m_mutex );
693 0 : return m_bWorking;
694 : }
695 :
696 : //------------------------------------------------------------------------------
697 0 : ExtensionCmdQueue::Thread::~Thread() {}
698 :
699 : //------------------------------------------------------------------------------
700 0 : void ExtensionCmdQueue::Thread::execute()
701 : {
702 : #ifdef WNT
703 : //Needed for use of the service "com.sun.star.system.SystemShellExecute" in
704 : //DialogHelper::openWebBrowser
705 : CoUninitialize();
706 : (void) CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
707 : #endif
708 0 : for (;;)
709 : {
710 0 : if ( m_wakeup.wait() != osl::Condition::result_ok )
711 : {
712 : dp_misc::TRACE( "dp_gui::ExtensionCmdQueue::Thread::run: ignored "
713 0 : "osl::Condition::wait failure\n" );
714 : }
715 0 : m_wakeup.reset();
716 :
717 : int nSize;
718 : Input eInput;
719 : {
720 0 : osl::MutexGuard aGuard( m_mutex );
721 0 : eInput = m_eInput;
722 0 : m_eInput = NONE;
723 0 : nSize = m_queue.size();
724 0 : m_bWorking = false;
725 : }
726 :
727 : // If this thread has been woken up by anything else except start, stop
728 : // then input is NONE and we wait again.
729 : // We only install the extension which are currently in the queue.
730 : // The progressbar will be set to show the progress of the current number
731 : // of extensions. If we allowed to add extensions now then the progressbar may
732 : // have reached the end while we still install newly added extensions.
733 0 : if ( ( eInput == NONE ) || ( nSize == 0 ) )
734 0 : continue;
735 0 : if ( eInput == STOP )
736 : break;
737 :
738 0 : ::rtl::Reference< ProgressCmdEnv > currentCmdEnv( new ProgressCmdEnv( m_xContext, m_pDialogHelper, m_sDefaultCmd ) );
739 :
740 : // Do not lock the following part with addExtension. addExtension may be called in the main thread.
741 : // If the message box "Do you want to install the extension (or similar)" is shown and then
742 : // addExtension is called, which then blocks the main thread, then we deadlock.
743 0 : bool bStartProgress = true;
744 :
745 0 : while ( !currentCmdEnv->isAborted() && --nSize >= 0 )
746 : {
747 : {
748 0 : osl::MutexGuard aGuard( m_mutex );
749 0 : m_bWorking = true;
750 : }
751 :
752 : try
753 : {
754 0 : TExtensionCmd pEntry;
755 : {
756 0 : ::osl::MutexGuard queueGuard( m_mutex );
757 0 : pEntry = m_queue.front();
758 0 : m_queue.pop();
759 : }
760 :
761 0 : if ( bStartProgress && ( pEntry->m_eCmdType != ExtensionCmd::CHECK_FOR_UPDATES ) )
762 : {
763 0 : currentCmdEnv->startProgress();
764 0 : bStartProgress = false;
765 : }
766 :
767 0 : switch ( pEntry->m_eCmdType ) {
768 : case ExtensionCmd::ADD :
769 0 : _addExtension( currentCmdEnv, pEntry->m_sExtensionURL, pEntry->m_sRepository, pEntry->m_bWarnUser );
770 0 : break;
771 : case ExtensionCmd::REMOVE :
772 0 : _removeExtension( currentCmdEnv, pEntry->m_xPackage );
773 0 : break;
774 : case ExtensionCmd::ENABLE :
775 0 : _enableExtension( currentCmdEnv, pEntry->m_xPackage );
776 0 : break;
777 : case ExtensionCmd::DISABLE :
778 0 : _disableExtension( currentCmdEnv, pEntry->m_xPackage );
779 0 : break;
780 : case ExtensionCmd::CHECK_FOR_UPDATES :
781 0 : _checkForUpdates( pEntry->m_vExtensionList );
782 0 : break;
783 : case ExtensionCmd::ACCEPT_LICENSE :
784 0 : _acceptLicense( currentCmdEnv, pEntry->m_xPackage );
785 0 : break;
786 0 : }
787 : }
788 0 : catch ( const ucb::CommandAbortedException & )
789 : {
790 : //This exception is thrown when the user clicks cancel on the progressbar.
791 : //Then we cancel the installation of all extensions and remove them from
792 : //the queue.
793 : {
794 0 : ::osl::MutexGuard queueGuard2(m_mutex);
795 0 : while ( --nSize >= 0 )
796 0 : m_queue.pop();
797 : }
798 : break;
799 : }
800 0 : catch ( const ucb::CommandFailedException & )
801 : {
802 : //This exception is thrown when a user clicked cancel in the messagebox which was
803 : //startet by the interaction handler. For example the user will be asked if he/she
804 : //really wants to install the extension.
805 : //These interaction are run for exectly one extension at a time. Therefore we continue
806 : //with installing the remaining extensions.
807 0 : continue;
808 : }
809 0 : catch ( const uno::Exception & )
810 : {
811 : //Todo display the user an error
812 : //see also DialogImpl::SyncPushButton::Click()
813 0 : uno::Any exc( ::cppu::getCaughtException() );
814 0 : OUString msg;
815 0 : deployment::DeploymentException dpExc;
816 0 : if ((exc >>= dpExc) &&
817 0 : dpExc.Cause.getValueTypeClass() == uno::TypeClass_EXCEPTION)
818 : {
819 : // notify error cause only:
820 0 : msg = reinterpret_cast< uno::Exception const * >( dpExc.Cause.getValue() )->Message;
821 : }
822 0 : if (msg.isEmpty()) // fallback for debugging purposes
823 0 : msg = ::comphelper::anyToString(exc);
824 :
825 0 : const SolarMutexGuard guard;
826 : boost::scoped_ptr<ErrorBox> box(
827 0 : new ErrorBox( currentCmdEnv->activeDialog(), WB_OK, msg ) );
828 0 : if ( m_pDialogHelper )
829 0 : box->SetText( m_pDialogHelper->getWindow()->GetText() );
830 0 : box->Execute();
831 : //Continue with installation of the remaining extensions
832 : }
833 : {
834 0 : osl::MutexGuard aGuard( m_mutex );
835 0 : m_bWorking = false;
836 : }
837 : }
838 :
839 : {
840 : // when leaving the while loop with break, we should set working to false, too
841 0 : osl::MutexGuard aGuard( m_mutex );
842 0 : m_bWorking = false;
843 : }
844 :
845 0 : if ( !bStartProgress )
846 0 : currentCmdEnv->stopProgress();
847 0 : }
848 : //end for
849 : #ifdef WNT
850 : CoUninitialize();
851 : #endif
852 0 : }
853 :
854 : //------------------------------------------------------------------------------
855 0 : void ExtensionCmdQueue::Thread::_addExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
856 : const OUString &rPackageURL,
857 : const OUString &rRepository,
858 : const bool bWarnUser )
859 : {
860 : //check if we have a string in anyTitle. For example "unopkg gui \" caused anyTitle to be void
861 : //and anyTitle.get<OUString> throws as RuntimeException.
862 0 : uno::Any anyTitle;
863 : try
864 : {
865 0 : anyTitle = ::ucbhelper::Content( rPackageURL, rCmdEnv.get(), m_xContext ).getPropertyValue( OUSTR("Title") );
866 : }
867 0 : catch ( const uno::Exception & )
868 : {
869 : return;
870 : }
871 :
872 0 : OUString sName;
873 0 : if ( ! (anyTitle >>= sName) )
874 : {
875 : OSL_FAIL("Could not get file name for extension.");
876 : return;
877 : }
878 :
879 0 : rCmdEnv->setWarnUser( bWarnUser );
880 0 : uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
881 0 : uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
882 : OUString sTitle(
883 0 : m_sAddingPackages.replaceAll("%EXTENSION_NAME", sName));
884 0 : rCmdEnv->progressSection( sTitle, xAbortChannel );
885 :
886 : try
887 : {
888 0 : xExtMgr->addExtension(rPackageURL, uno::Sequence<beans::NamedValue>(),
889 0 : rRepository, xAbortChannel, rCmdEnv.get() );
890 : }
891 0 : catch ( const ucb::CommandFailedException & )
892 : {
893 : // When the extension is already installed we'll get a dialog asking if we want to overwrite. If we then press
894 : // cancel this exception is thrown.
895 : }
896 0 : catch ( const ucb::CommandAbortedException & )
897 : {
898 : // User clicked the cancel button
899 : // TODO: handle cancel
900 : }
901 0 : rCmdEnv->setWarnUser( false );
902 : }
903 :
904 : //------------------------------------------------------------------------------
905 0 : void ExtensionCmdQueue::Thread::_removeExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
906 : const uno::Reference< deployment::XPackage > &xPackage )
907 : {
908 0 : uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
909 0 : uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
910 : OUString sTitle(
911 : m_sRemovingPackages.replaceAll("%EXTENSION_NAME",
912 0 : xPackage->getDisplayName()));
913 0 : rCmdEnv->progressSection( sTitle, xAbortChannel );
914 :
915 0 : OUString id( dp_misc::getIdentifier( xPackage ) );
916 : try
917 : {
918 0 : xExtMgr->removeExtension( id, xPackage->getName(), xPackage->getRepositoryName(), xAbortChannel, rCmdEnv.get() );
919 : }
920 0 : catch ( const deployment::DeploymentException & )
921 : {}
922 0 : catch ( const ucb::CommandFailedException & )
923 : {}
924 0 : catch ( const ucb::CommandAbortedException & )
925 : {}
926 :
927 : // Check, if there are still updates to be notified via menu bar icon
928 0 : uno::Sequence< uno::Sequence< rtl::OUString > > aItemList;
929 0 : UpdateDialog::createNotifyJob( false, aItemList );
930 0 : }
931 :
932 : //------------------------------------------------------------------------------
933 0 : void ExtensionCmdQueue::Thread::_checkForUpdates(
934 : const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList )
935 : {
936 : UpdateDialog* pUpdateDialog;
937 0 : std::vector< UpdateData > vData;
938 :
939 0 : const SolarMutexGuard guard;
940 :
941 0 : pUpdateDialog = new UpdateDialog( m_xContext, m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, vExtensionList, &vData );
942 :
943 0 : pUpdateDialog->notifyMenubar( true, false ); // prepare the checking, if there updates to be notified via menu bar icon
944 :
945 0 : if ( ( pUpdateDialog->Execute() == RET_OK ) && !vData.empty() )
946 : {
947 : // If there is at least one directly downloadable extension then we
948 : // open the install dialog.
949 0 : ::std::vector< UpdateData > dataDownload;
950 0 : int countWebsiteDownload = 0;
951 : typedef std::vector< dp_gui::UpdateData >::const_iterator cit;
952 :
953 0 : for ( cit i = vData.begin(); i < vData.end(); ++i )
954 : {
955 0 : if ( !i->sWebsiteURL.isEmpty() )
956 0 : countWebsiteDownload ++;
957 : else
958 0 : dataDownload.push_back( *i );
959 : }
960 :
961 0 : short nDialogResult = RET_OK;
962 0 : if ( !dataDownload.empty() )
963 : {
964 0 : nDialogResult = UpdateInstallDialog( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, dataDownload, m_xContext ).Execute();
965 0 : pUpdateDialog->notifyMenubar( false, true ); // Check, if there are still pending updates to be notified via menu bar icon
966 : }
967 : else
968 0 : pUpdateDialog->notifyMenubar( false, false ); // Check, if there are pending updates to be notified via menu bar icon
969 :
970 : //Now start the webbrowser and navigate to the websites where we get the updates
971 0 : if ( RET_OK == nDialogResult )
972 : {
973 0 : for ( cit i = vData.begin(); i < vData.end(); ++i )
974 : {
975 0 : if ( m_pDialogHelper && ( !i->sWebsiteURL.isEmpty() ) )
976 0 : m_pDialogHelper->openWebBrowser( i->sWebsiteURL, m_pDialogHelper->getWindow()->GetText() );
977 : }
978 0 : }
979 : }
980 : else
981 0 : pUpdateDialog->notifyMenubar( false, false ); // check if there updates to be notified via menu bar icon
982 :
983 0 : delete pUpdateDialog;
984 0 : }
985 :
986 : //------------------------------------------------------------------------------
987 0 : void ExtensionCmdQueue::Thread::_enableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
988 : const uno::Reference< deployment::XPackage > &xPackage )
989 : {
990 0 : if ( !xPackage.is() )
991 0 : return;
992 :
993 0 : uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
994 0 : uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
995 : OUString sTitle(
996 : m_sEnablingPackages.replaceAll("%EXTENSION_NAME",
997 0 : xPackage->getDisplayName()));
998 0 : rCmdEnv->progressSection( sTitle, xAbortChannel );
999 :
1000 : try
1001 : {
1002 0 : xExtMgr->enableExtension( xPackage, xAbortChannel, rCmdEnv.get() );
1003 0 : if ( m_pDialogHelper )
1004 0 : m_pDialogHelper->updatePackageInfo( xPackage );
1005 : }
1006 0 : catch ( const ::ucb::CommandAbortedException & )
1007 0 : {}
1008 : }
1009 :
1010 : //------------------------------------------------------------------------------
1011 0 : void ExtensionCmdQueue::Thread::_disableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
1012 : const uno::Reference< deployment::XPackage > &xPackage )
1013 : {
1014 0 : if ( !xPackage.is() )
1015 0 : return;
1016 :
1017 0 : uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
1018 0 : uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
1019 : OUString sTitle(
1020 : m_sDisablingPackages.replaceAll("%EXTENSION_NAME",
1021 0 : xPackage->getDisplayName()));
1022 0 : rCmdEnv->progressSection( sTitle, xAbortChannel );
1023 :
1024 : try
1025 : {
1026 0 : xExtMgr->disableExtension( xPackage, xAbortChannel, rCmdEnv.get() );
1027 0 : if ( m_pDialogHelper )
1028 0 : m_pDialogHelper->updatePackageInfo( xPackage );
1029 : }
1030 0 : catch ( const ::ucb::CommandAbortedException & )
1031 0 : {}
1032 : }
1033 :
1034 : //------------------------------------------------------------------------------
1035 0 : void ExtensionCmdQueue::Thread::_acceptLicense( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
1036 : const uno::Reference< deployment::XPackage > &xPackage )
1037 : {
1038 0 : if ( !xPackage.is() )
1039 0 : return;
1040 :
1041 0 : uno::Reference< deployment::XExtensionManager > xExtMgr = m_pManager->getExtensionManager();
1042 0 : uno::Reference< task::XAbortChannel > xAbortChannel( xExtMgr->createAbortChannel() );
1043 : OUString sTitle(
1044 : m_sAcceptLicense.replaceAll("%EXTENSION_NAME",
1045 0 : xPackage->getDisplayName()));
1046 0 : rCmdEnv->progressSection( sTitle, xAbortChannel );
1047 :
1048 : try
1049 : {
1050 0 : xExtMgr->checkPrerequisitesAndEnable( xPackage, xAbortChannel, rCmdEnv.get() );
1051 0 : if ( m_pDialogHelper )
1052 0 : m_pDialogHelper->updatePackageInfo( xPackage );
1053 : }
1054 0 : catch ( const ::ucb::CommandAbortedException & )
1055 0 : {}
1056 : }
1057 :
1058 0 : void ExtensionCmdQueue::Thread::_insert(const TExtensionCmd& rExtCmd)
1059 : {
1060 0 : ::osl::MutexGuard aGuard( m_mutex );
1061 :
1062 : // If someone called stop then we do not process the command -> game over!
1063 0 : if ( m_bStopped )
1064 0 : return;
1065 :
1066 0 : m_queue.push( rExtCmd );
1067 0 : m_eInput = START;
1068 0 : m_wakeup.set();
1069 : }
1070 :
1071 : //------------------------------------------------------------------------------
1072 0 : ExtensionCmdQueue::ExtensionCmdQueue( DialogHelper * pDialogHelper,
1073 : TheExtensionManager *pManager,
1074 : const uno::Reference< uno::XComponentContext > &rContext )
1075 0 : : m_thread( new Thread( pDialogHelper, pManager, rContext ) )
1076 : {
1077 0 : m_thread->launch();
1078 0 : }
1079 :
1080 0 : ExtensionCmdQueue::~ExtensionCmdQueue() {
1081 0 : stop();
1082 0 : }
1083 :
1084 0 : void ExtensionCmdQueue::addExtension( const ::rtl::OUString & extensionURL,
1085 : const ::rtl::OUString & repository,
1086 : const bool bWarnUser )
1087 : {
1088 0 : m_thread->addExtension( extensionURL, repository, bWarnUser );
1089 0 : }
1090 :
1091 0 : void ExtensionCmdQueue::removeExtension( const uno::Reference< deployment::XPackage > &rPackage )
1092 : {
1093 0 : m_thread->removeExtension( rPackage );
1094 0 : }
1095 :
1096 0 : void ExtensionCmdQueue::enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
1097 : const bool bEnable )
1098 : {
1099 0 : m_thread->enableExtension( rPackage, bEnable );
1100 0 : }
1101 :
1102 0 : void ExtensionCmdQueue::checkForUpdates( const std::vector<uno::Reference<deployment::XPackage > > &vExtensionList )
1103 : {
1104 0 : m_thread->checkForUpdates( vExtensionList );
1105 0 : }
1106 :
1107 0 : void ExtensionCmdQueue::acceptLicense( const uno::Reference< deployment::XPackage > &rPackage )
1108 : {
1109 0 : m_thread->acceptLicense( rPackage );
1110 0 : }
1111 :
1112 0 : void ExtensionCmdQueue::syncRepositories( const uno::Reference< uno::XComponentContext > &xContext )
1113 : {
1114 0 : dp_misc::syncRepositories( false, new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) );
1115 0 : }
1116 :
1117 0 : void ExtensionCmdQueue::stop()
1118 : {
1119 0 : m_thread->stop();
1120 0 : }
1121 :
1122 0 : bool ExtensionCmdQueue::isBusy()
1123 : {
1124 0 : return m_thread->isBusy();
1125 : }
1126 :
1127 0 : void handleInteractionRequest( const uno::Reference< uno::XComponentContext > & xContext,
1128 : const uno::Reference< task::XInteractionRequest > & xRequest )
1129 : {
1130 0 : ::rtl::Reference< ProgressCmdEnv > xCmdEnv( new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) );
1131 0 : xCmdEnv->handle( xRequest );
1132 0 : }
1133 :
1134 : } //namespace dp_gui
1135 :
1136 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|