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