xref: /trunk/main/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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