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