xref: /aoo41x/main/uui/source/iahndl.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include <memory>
29 
30 #include "com/sun/star/awt/XWindow.hpp"
31 #include "com/sun/star/beans/PropertyValue.hpp"
32 #include "com/sun/star/configuration/backend/MergeRecoveryRequest.hpp"
33 #include "com/sun/star/configuration/backend/StratumCreationException.hpp"
34 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
35 #include "com/sun/star/document/BrokenPackageRequest.hpp"
36 #include "com/sun/star/task/DocumentMacroConfirmationRequest.hpp"
37 #include "com/sun/star/java/WrongJavaVersionException.hpp"
38 #include "com/sun/star/lang/XInitialization.hpp"
39 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
40 #include "com/sun/star/script/ModuleSizeExceededRequest.hpp"
41 #include "com/sun/star/sync2/BadPartnershipException.hpp"
42 #include "com/sun/star/task/ErrorCodeIOException.hpp"
43 #include "com/sun/star/task/ErrorCodeRequest.hpp"
44 #include "com/sun/star/task/FutureDocumentVersionProductUpdateRequest.hpp"
45 #include "com/sun/star/task/XInteractionAbort.hpp"
46 #include "com/sun/star/task/XInteractionApprove.hpp"
47 #include "com/sun/star/task/XInteractionAskLater.hpp"
48 #include "com/sun/star/task/XInteractionDisapprove.hpp"
49 #include "com/sun/star/task/XInteractionHandler2.hpp"
50 #include "com/sun/star/task/XInteractionRequest.hpp"
51 #include "com/sun/star/task/XInteractionRetry.hpp"
52 #include "com/sun/star/ucb/InteractiveAppException.hpp"
53 #include "com/sun/star/ucb/InteractiveCHAOSException.hpp"
54 #include "com/sun/star/ucb/InteractiveLockingLockedException.hpp"
55 #include "com/sun/star/ucb/InteractiveLockingNotLockedException.hpp"
56 #include "com/sun/star/ucb/InteractiveLockingLockExpiredException.hpp"
57 #include "com/sun/star/ucb/InteractiveNetworkConnectException.hpp"
58 #include "com/sun/star/ucb/InteractiveNetworkOffLineException.hpp"
59 #include "com/sun/star/ucb/InteractiveNetworkReadException.hpp"
60 #include "com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp"
61 #include "com/sun/star/ucb/InteractiveNetworkWriteException.hpp"
62 #include "com/sun/star/ucb/InteractiveWrongMediumException.hpp"
63 #include "com/sun/star/ucb/NameClashException.hpp"
64 #include "com/sun/star/ucb/NameClashResolveRequest.hpp"
65 #include "com/sun/star/ucb/UnsupportedNameClashException.hpp"
66 #include "com/sun/star/ucb/XInteractionReplaceExistingData.hpp"
67 #include "com/sun/star/ucb/XInteractionSupplyName.hpp"
68 #include "com/sun/star/xforms/InvalidDataOnSubmitException.hpp"
69 
70 #include "osl/conditn.hxx"
71 #include "tools/rcid.h" // RSC_STRING
72 #include "tools/errinf.hxx" // ErrorHandler, ErrorContext, ...
73 #include "vos/mutex.hxx"
74 #include "tools/diagnose_ex.h"
75 #include "comphelper/documentconstants.hxx" // ODFVER_012_TEXT
76 #include "svtools/sfxecode.hxx" // ERRCODE_SFX_*
77 #include "vcl/msgbox.hxx"
78 #include "vcl/svapp.hxx"
79 #include "unotools/configmgr.hxx"
80 #include "toolkit/helper/vclunohelper.hxx"
81 #include "comphelper/namedvaluecollection.hxx"
82 #include "typelib/typedescription.hxx"
83 #include "unotools/confignode.hxx"
84 
85 #include "ids.hrc"
86 
87 #include "getcontinuations.hxx"
88 #include "secmacrowarnings.hxx"
89 #include "newerverwarn.hxx"
90 
91 #include "iahndl.hxx"
92 #include "nameclashdlg.hxx"
93 
94 /** === begin UNO using === **/
95 using ::com::sun::star::uno::Sequence;
96 using ::com::sun::star::uno::UNO_QUERY;
97 using ::com::sun::star::uno::Reference;
98 using ::com::sun::star::task::XInteractionContinuation;
99 using ::com::sun::star::task::XInteractionAbort;
100 using ::com::sun::star::task::XInteractionApprove;
101 using ::com::sun::star::task::XInteractionAskLater;
102 using ::com::sun::star::task::FutureDocumentVersionProductUpdateRequest;
103 using ::com::sun::star::uno::XInterface;
104 using ::com::sun::star::lang::XInitialization;
105 using ::com::sun::star::uno::UNO_QUERY_THROW;
106 using ::com::sun::star::task::XInteractionHandler2;
107 using ::com::sun::star::uno::Exception;
108 using ::com::sun::star::uno::Any;
109 using ::com::sun::star::task::XInteractionRequest;
110 using ::com::sun::star::lang::XMultiServiceFactory;
111 /** === end UNO using === **/
112 
113 using namespace ::com::sun::star;
114 
115 namespace {
116 
117 class HandleData : public osl::Condition
118 {
119 public:
120     HandleData(
121         uno::Reference< task::XInteractionRequest > const & rRequest)
122         : osl::Condition(),
123           m_rRequest(rRequest),
124           bHandled( false )
125     {
126     }
127     uno::Reference< task::XInteractionRequest > m_rRequest;
128     bool                                        bHandled;
129     beans::Optional< rtl::OUString >            m_aResult;
130 };
131 
132 } /* namespace */
133 
134 UUIInteractionHelper::UUIInteractionHelper(
135     uno::Reference< lang::XMultiServiceFactory > const & rServiceFactory,
136     uno::Sequence< uno::Any > const & rArguments)
137     SAL_THROW(()):
138         m_xServiceFactory(rServiceFactory),
139         m_aProperties(rArguments)
140 {
141 }
142 
143 UUIInteractionHelper::UUIInteractionHelper(
144     uno::Reference< lang::XMultiServiceFactory > const & rServiceFactory)
145     SAL_THROW(()):
146         m_xServiceFactory(rServiceFactory)
147 {
148 }
149 
150 UUIInteractionHelper::~UUIInteractionHelper()
151 {
152 }
153 
154 long
155 UUIInteractionHelper::handlerequest(
156     void* pHandleData, void* pInteractionHelper)
157 {
158     HandleData* pHND
159         = static_cast< HandleData * >(pHandleData);
160     UUIInteractionHelper* pUUI
161         = static_cast< UUIInteractionHelper * >(pInteractionHelper);
162     bool bDummy = false;
163     rtl::OUString aDummy;
164     pHND->bHandled
165         = pUUI->handleRequest_impl(pHND->m_rRequest, false, bDummy, aDummy);
166     pHND->set();
167     return 0;
168 }
169 
170 bool
171 UUIInteractionHelper::handleRequest(
172     uno::Reference< task::XInteractionRequest > const & rRequest)
173     SAL_THROW((uno::RuntimeException))
174 {
175     Application* pApp = 0;
176     if(
177         // be aware,it is the same type
178         static_cast< oslThreadIdentifier >(
179             Application::GetMainThreadIdentifier())
180         != osl_getThreadIdentifier(NULL)
181         &&
182         (pApp = GetpApp())
183         != 0
184     ) {
185         // we are not in the main thread, let it handle that stuff
186         HandleData aHD(rRequest);
187         Link aLink(&aHD,handlerequest);
188         pApp->PostUserEvent(aLink,this);
189         sal_uLong locks = Application::ReleaseSolarMutex();
190         aHD.wait();
191         Application::AcquireSolarMutex(locks);
192         return aHD.bHandled;
193     }
194     else
195     {
196         bool bDummy = false;
197         rtl::OUString aDummy;
198         return handleRequest_impl(rRequest, false, bDummy, aDummy);
199     }
200 }
201 
202 long
203 UUIInteractionHelper::getstringfromrequest(
204     void* pHandleData,void* pInteractionHelper)
205 {
206     HandleData* pHND = (HandleData*) pHandleData;
207     UUIInteractionHelper* pUUI = (UUIInteractionHelper*) pInteractionHelper;
208     pHND->m_aResult = pUUI->getStringFromRequest_impl(pHND->m_rRequest);
209     pHND->set();
210     return 0;
211 }
212 
213 beans::Optional< rtl::OUString >
214 UUIInteractionHelper::getStringFromRequest_impl(
215     uno::Reference< task::XInteractionRequest > const & rRequest)
216     SAL_THROW((uno::RuntimeException))
217 {
218     bool bSuccess = false;
219     rtl::OUString aMessage;
220     handleRequest_impl(rRequest, true, bSuccess, aMessage);
221 
222     OSL_ENSURE(bSuccess ||
223                !isInformationalErrorMessageRequest(
224                    rRequest->getContinuations()),
225                "Interaction request is a candidate for a string representation."
226                "Please implement!");
227 
228     return beans::Optional< rtl::OUString >(bSuccess, aMessage);
229 }
230 
231 beans::Optional< rtl::OUString >
232 UUIInteractionHelper::getStringFromRequest(
233     uno::Reference< task::XInteractionRequest > const & rRequest)
234     SAL_THROW((uno::RuntimeException))
235 {
236     Application* pApp = 0;
237     if(
238         // be aware,it is the same type
239         static_cast< oslThreadIdentifier >(
240             Application::GetMainThreadIdentifier())
241         != osl_getThreadIdentifier(NULL)
242         &&
243         (pApp = GetpApp())
244         != 0
245     ) {
246         // we are not in the main thread, let it handle that stuff
247         HandleData aHD(rRequest);
248         Link aLink(&aHD,getstringfromrequest);
249         pApp->PostUserEvent(aLink,this);
250         sal_uLong locks = Application::ReleaseSolarMutex();
251         aHD.wait();
252         Application::AcquireSolarMutex(locks);
253         return aHD.m_aResult;
254     }
255     else
256         return getStringFromRequest_impl(rRequest);
257 }
258 
259 ::rtl::OUString
260 UUIInteractionHelper::replaceMessageWithArguments(
261     ::rtl::OUString aMessage,
262     std::vector< rtl::OUString > const & rArguments )
263 {
264     for (sal_Int32 i = 0;;)
265     {
266         i = aMessage.
267         indexOf(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("$(ARG")), i);
268         if (i == -1)
269             break;
270         if (aMessage.getLength() - i >= RTL_CONSTASCII_LENGTH("$(ARGx)")
271             && aMessage.getStr()[i + RTL_CONSTASCII_LENGTH("$(ARGx")] == ')')
272         {
273             sal_Unicode c
274                 = aMessage.getStr()[i + RTL_CONSTASCII_LENGTH("$(ARG")];
275             if (c >= '1' && c <= '2')
276             {
277                 std::vector< rtl::OUString >::size_type nIndex
278                     = static_cast< std::vector< rtl::OUString >::size_type >(
279                         c - '1');
280                 if (nIndex < rArguments.size())
281                 {
282                     aMessage
283                         = aMessage.replaceAt(i,
284                                              RTL_CONSTASCII_LENGTH("$(ARGx)"),
285                                              rArguments[nIndex]);
286                     i += rArguments[nIndex].getLength();
287                     continue;
288                 }
289             }
290         }
291         ++i;
292     }
293 
294     return aMessage;
295 }
296 
297 bool
298 UUIInteractionHelper::isInformationalErrorMessageRequest(
299     uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
300         rContinuations)
301 {
302     // Only requests with a single continuation (user has no choice, request
303     // is just informational)
304     if (rContinuations.getLength() != 1 )
305         return false;
306 
307     // user can only abort or approve, all other continuations are not
308     // considered to be informational.
309     uno::Reference< task::XInteractionApprove > xApprove(
310         rContinuations[0], uno::UNO_QUERY);
311     if (xApprove.is())
312         return true;
313 
314     uno::Reference< task::XInteractionAbort > xAbort(
315         rContinuations[0], uno::UNO_QUERY);
316     if (xAbort.is())
317         return true;
318 
319     return false;
320 }
321 
322 bool
323 UUIInteractionHelper::tryOtherInteractionHandler(
324     uno::Reference< task::XInteractionRequest > const & rRequest)
325     SAL_THROW((uno::RuntimeException))
326 {
327     InteractionHandlerDataList dataList;
328     getInteractionHandlerList(dataList);
329 
330     InteractionHandlerDataList::const_iterator aEnd(dataList.end());
331     for (InteractionHandlerDataList::const_iterator aIt(dataList.begin());
332          aIt != aEnd;
333          ++aIt)
334     {
335 		if ( handleCustomRequest( rRequest, aIt->ServiceName ) )
336 			return true;
337     }
338     return false;
339 }
340 
341 namespace
342 {
343     // .................................................................................................................
344     static bool lcl_matchesRequest( const Any& i_rRequest, const ::rtl::OUString& i_rTypeName, const ::rtl::OUString& i_rPropagation )
345     {
346         const ::com::sun::star::uno::TypeDescription aTypeDesc( i_rTypeName );
347         const typelib_TypeDescription* pTypeDesc = aTypeDesc.get();
348         if ( !pTypeDesc || !pTypeDesc->pWeakRef )
349         {
350 #if OSL_DEBUG_LEVEL > 0
351             ::rtl::OStringBuffer aMessage;
352             aMessage.append( "no type found for '" );
353             aMessage.append( ::rtl::OUStringToOString( i_rTypeName, RTL_TEXTENCODING_UTF8 ) );
354             aMessage.append( "'" );
355             OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
356 #endif
357             return false;
358         }
359         const ::com::sun::star::uno::Type aType( pTypeDesc->pWeakRef );
360 
361         const bool bExactMatch = ( i_rPropagation.compareToAscii( "named-only" ) == 0 );
362         if ( bExactMatch )
363             return i_rRequest.getValueType().equals( aType );
364 
365         return i_rRequest.isExtractableTo( aType );
366     }
367 }
368 
369 // ---------------------------------------------------------------------------------------------------------------------
370 bool UUIInteractionHelper::handleCustomRequest( const Reference< XInteractionRequest >& i_rRequest, const ::rtl::OUString& i_rServiceName ) const
371 {
372     try
373     {
374         Reference< XInteractionHandler2 > xHandler( m_xServiceFactory->createInstance( i_rServiceName ), UNO_QUERY_THROW );
375 
376         Reference< XInitialization > xHandlerInit( xHandler, UNO_QUERY );
377         if ( xHandlerInit.is() )
378         {
379             ::comphelper::NamedValueCollection aInitArgs;
380             aInitArgs.put( "Parent", getParentXWindow() );
381             xHandlerInit->initialize( aInitArgs.getWrappedPropertyValues() );
382         }
383 
384         if ( xHandler->handleInteractionRequest( i_rRequest ) )
385             return true;
386     }
387     catch( const Exception& )
388     {
389     	DBG_UNHANDLED_EXCEPTION();
390     }
391     return false;
392 }
393 
394 // ---------------------------------------------------------------------------------------------------------------------
395 bool UUIInteractionHelper::handleTypedHandlerImplementations( Reference< XInteractionRequest > const & rRequest )
396 {
397     // the request
398     const Any aRequest( rRequest->getRequest() );
399 
400     const StringHashMap::const_iterator aCacheHitTest = m_aTypedCustomHandlers.find( aRequest.getValueTypeName() );
401     if ( aCacheHitTest != m_aTypedCustomHandlers.end() )
402         return handleCustomRequest( rRequest, aCacheHitTest->second );
403 
404     // the base registration node for "typed" interaction handlers
405     const ::utl::OConfigurationTreeRoot aConfigRoot( ::utl::OConfigurationTreeRoot::createWithServiceFactory(
406         m_xServiceFactory,
407         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Interaction/InteractionHandlers" ) ),
408         -1,
409         ::utl::OConfigurationTreeRoot::CM_READONLY
410     ) );
411 
412     // loop through all registered implementations
413     const Sequence< ::rtl::OUString > aRegisteredHandlers( aConfigRoot.getNodeNames() );
414     const ::rtl::OUString* pHandlerName = aRegisteredHandlers.getConstArray();
415     const ::rtl::OUString* pHandlersEnd = aRegisteredHandlers.getConstArray() + aRegisteredHandlers.getLength();
416     for ( ; pHandlerName != pHandlersEnd; ++pHandlerName )
417     {
418         const ::utl::OConfigurationNode aHandlerNode( aConfigRoot.openNode( *pHandlerName ) );
419         const ::utl::OConfigurationNode aTypesNode( aHandlerNode.openNode( "HandledRequestTypes" ) );
420 
421         // loop through all the types which the current handler is registered for
422         const Sequence< ::rtl::OUString > aHandledTypes( aTypesNode.getNodeNames() );
423         const ::rtl::OUString* pType = aHandledTypes.getConstArray();
424         const ::rtl::OUString* pTypesEnd = aHandledTypes.getConstArray() + aHandledTypes.getLength();
425         for ( ; pType != pTypesEnd; ++pType )
426         {
427             // the UNO type is the node name
428             ::utl::OConfigurationNode aType( aTypesNode.openNode( *pType ) );
429             // and there's a child denoting how the responsibility propagates
430             ::rtl::OUString sPropagation;
431             OSL_VERIFY( aType.getNodeValue( "Propagation" ) >>= sPropagation );
432             if ( lcl_matchesRequest( aRequest, *pType, sPropagation ) )
433             {
434                 // retrieve the service/implementation name of the handler
435                 ::rtl::OUString sServiceName;
436                 OSL_VERIFY( aHandlerNode.getNodeValue( "ServiceName" ) >>= sServiceName );
437                 // cache the information who feels responsible for requests of this type
438                 m_aTypedCustomHandlers[ aRequest.getValueTypeName() ] = sServiceName;
439                 // actually handle the request
440                 return handleCustomRequest( rRequest, sServiceName );
441             }
442         }
443     }
444 
445     return false;
446 }
447 
448 bool
449 UUIInteractionHelper::handleRequest_impl(
450     uno::Reference< task::XInteractionRequest > const & rRequest,
451     bool bObtainErrorStringOnly,
452     bool & bHasErrorString,
453     rtl::OUString & rErrorString)
454     SAL_THROW((uno::RuntimeException))
455 {
456     try
457     {
458         if (!rRequest.is())
459             return false;
460 
461         uno::Any aAnyRequest(rRequest->getRequest());
462 
463         script::ModuleSizeExceededRequest aModSizeException;
464         if (aAnyRequest >>= aModSizeException )
465         {
466             ErrCode nErrorCode = ERRCODE_UUI_IO_MODULESIZEEXCEEDED;
467             std::vector< rtl::OUString > aArguments;
468             uno::Sequence< rtl::OUString > sModules
469                 = aModSizeException.Names;
470             if ( sModules.getLength() )
471             {
472                 rtl::OUString aName;
473                 for ( sal_Int32 index=0; index< sModules.getLength(); ++index )
474                 {
475                     if ( index )
476                         aName = aName + rtl::OUString( ',' ) + sModules[index];
477                     else
478                         aName = sModules[index]; // 1st name
479                 }
480                 aArguments.push_back( aName );
481             }
482             handleErrorHandlerRequest( task::InteractionClassification_WARNING,
483                                        nErrorCode,
484                                        aArguments,
485                                        rRequest->getContinuations(),
486                                        bObtainErrorStringOnly,
487                                        bHasErrorString,
488                                        rErrorString);
489             return true;
490         }
491 
492         ucb::NameClashException aNCException;
493         if (aAnyRequest >>= aNCException)
494         {
495             ErrCode nErrorCode = ERRCODE_UUI_IO_TARGETALREADYEXISTS;
496             std::vector< rtl::OUString > aArguments;
497 
498             if( aNCException.Name.getLength() )
499             {
500                 nErrorCode = ERRCODE_UUI_IO_ALREADYEXISTS;
501                 aArguments.push_back( aNCException.Name );
502             }
503 
504             handleErrorHandlerRequest( aNCException.Classification,
505                                        nErrorCode,
506                                        aArguments,
507                                        rRequest->getContinuations(),
508                                        bObtainErrorStringOnly,
509                                        bHasErrorString,
510                                        rErrorString);
511             return true;
512         }
513 
514         ucb::UnsupportedNameClashException aUORequest;
515         if (aAnyRequest >>= aUORequest)
516         {
517             ErrCode nErrorCode = ERRCODE_UUI_IO_UNSUPPORTEDOVERWRITE;
518             std::vector< rtl::OUString > aArguments;
519 
520             uno::Reference< task::XInteractionApprove > xApprove;
521             uno::Reference< task::XInteractionDisapprove > xDisapprove;
522             getContinuations(
523                 rRequest->getContinuations(), &xApprove, &xDisapprove);
524 
525             if ( xApprove.is() && xDisapprove.is() )
526             {
527                 handleErrorHandlerRequest( task::InteractionClassification_QUERY,
528                                            nErrorCode,
529                                            aArguments,
530                                            rRequest->getContinuations(),
531                                            bObtainErrorStringOnly,
532                                            bHasErrorString,
533                                            rErrorString);
534             }
535             return true;
536         }
537 
538         if ( handleInteractiveIOException( rRequest,
539                                            bObtainErrorStringOnly,
540                                            bHasErrorString,
541                                            rErrorString ) )
542             return true;
543 
544         ucb::InteractiveAppException aAppException;
545         if (aAnyRequest >>= aAppException)
546         {
547             std::vector< rtl::OUString > aArguments;
548             handleErrorHandlerRequest( aAppException.Classification,
549                                        aAppException.Code,
550                                        aArguments,
551                                        rRequest->getContinuations(),
552                                        bObtainErrorStringOnly,
553                                        bHasErrorString,
554                                        rErrorString);
555             return true;
556         }
557 
558         ucb::InteractiveNetworkException aNetworkException;
559         if (aAnyRequest >>= aNetworkException)
560         {
561             ErrCode nErrorCode;
562             std::vector< rtl::OUString > aArguments;
563             ucb::InteractiveNetworkOffLineException aOffLineException;
564             ucb::InteractiveNetworkResolveNameException aResolveNameException;
565             ucb::InteractiveNetworkConnectException aConnectException;
566             ucb::InteractiveNetworkReadException aReadException;
567             ucb::InteractiveNetworkWriteException aWriteException;
568             if (aAnyRequest >>= aOffLineException)
569                 nErrorCode = ERRCODE_INET_OFFLINE;
570             else if (aAnyRequest >>= aResolveNameException)
571             {
572                 nErrorCode = ERRCODE_INET_NAME_RESOLVE;
573                 aArguments.push_back(aResolveNameException.Server);
574             }
575             else if (aAnyRequest >>= aConnectException)
576             {
577                 nErrorCode = ERRCODE_INET_CONNECT;
578                 aArguments.push_back(aConnectException.Server);
579             }
580             else if (aAnyRequest >>= aReadException)
581             {
582                 nErrorCode = ERRCODE_INET_READ;
583                 aArguments.push_back(aReadException.Diagnostic);
584             }
585             else if (aAnyRequest >>= aWriteException)
586             {
587                 nErrorCode = ERRCODE_INET_WRITE;
588                 aArguments.push_back(aWriteException.Diagnostic);
589             }
590             else
591                 nErrorCode = ERRCODE_INET_GENERAL;
592 
593             handleErrorHandlerRequest(aNetworkException.Classification,
594                                       nErrorCode,
595                                       aArguments,
596                                       rRequest->getContinuations(),
597                                       bObtainErrorStringOnly,
598                                       bHasErrorString,
599                                       rErrorString);
600             return true;
601         }
602 
603 		ucb::InteractiveCHAOSException aChaosException;
604         if (aAnyRequest >>= aChaosException)
605         {
606             std::vector< rtl::OUString > aArguments;
607             sal_Int32 nCount
608                 = std::min< sal_Int32 >(aChaosException.Arguments.getLength(),
609                                         2);
610             aArguments.
611                 reserve(static_cast< std::vector< rtl::OUString >::size_type >(
612                     nCount));
613             for (sal_Int32 i = 0; i < nCount; ++i)
614                 aArguments.push_back(aChaosException.Arguments[i]);
615             handleErrorHandlerRequest(aChaosException.Classification,
616                                       aChaosException.ID,
617                                       aArguments,
618                                       rRequest->getContinuations(),
619                                       bObtainErrorStringOnly,
620                                       bHasErrorString,
621                                       rErrorString);
622             return true;
623         }
624 
625         ucb::InteractiveWrongMediumException aWrongMediumException;
626         if (aAnyRequest >>= aWrongMediumException)
627         {
628             sal_Int32 nMedium = 0;
629             aWrongMediumException.Medium >>= nMedium;
630             std::vector< rtl::OUString > aArguments;
631             aArguments.push_back(UniString::CreateFromInt32(nMedium + 1));
632             handleErrorHandlerRequest(aWrongMediumException.Classification,
633                                       ERRCODE_UUI_WRONGMEDIUM,
634                                       aArguments,
635                                       rRequest->getContinuations(),
636                                       bObtainErrorStringOnly,
637                                       bHasErrorString,
638                                       rErrorString);
639             return true;
640         }
641 
642         java::WrongJavaVersionException aWrongJavaVersionException;
643         if (aAnyRequest >>= aWrongJavaVersionException)
644         {
645             ErrCode nErrorCode;
646             std::vector< rtl::OUString > aArguments;
647             if (aWrongJavaVersionException.DetectedVersion.getLength() == 0)
648                 if (aWrongJavaVersionException.LowestSupportedVersion.
649                     getLength()
650                     == 0)
651                     nErrorCode = ERRCODE_UUI_WRONGJAVA;
652                 else
653                 {
654                     nErrorCode = ERRCODE_UUI_WRONGJAVA_MIN;
655                     aArguments.push_back(aWrongJavaVersionException.
656                                          LowestSupportedVersion);
657                 }
658             else if (aWrongJavaVersionException.LowestSupportedVersion.
659                      getLength()
660                      == 0)
661             {
662                 nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION;
663                 aArguments.push_back(aWrongJavaVersionException.
664                                      DetectedVersion);
665             }
666             else
667             {
668                 nErrorCode = ERRCODE_UUI_WRONGJAVA_VERSION_MIN;
669                 aArguments.reserve(2);
670                 aArguments.push_back(aWrongJavaVersionException.
671                                      DetectedVersion);
672                 aArguments.push_back(aWrongJavaVersionException.
673                                      LowestSupportedVersion);
674             }
675             handleErrorHandlerRequest(task::InteractionClassification_ERROR,
676                                       nErrorCode,
677                                       aArguments,
678                                       rRequest->getContinuations(),
679                                       bObtainErrorStringOnly,
680                                       bHasErrorString,
681                                       rErrorString);
682             return true;
683         }
684 
685         sync2::BadPartnershipException aBadPartnershipException;
686         if (aAnyRequest >>= aBadPartnershipException)
687         {
688             ErrCode nErrorCode;
689             std::vector< rtl::OUString > aArguments;
690             if (aBadPartnershipException.Partnership.getLength() == 0)
691                 nErrorCode = ERRCODE_UUI_BADPARTNERSHIP;
692             else
693             {
694                 nErrorCode = ERRCODE_UUI_BADPARTNERSHIP_NAME;
695                 aArguments.push_back(aBadPartnershipException.Partnership);
696             }
697             handleErrorHandlerRequest(task::InteractionClassification_ERROR,
698                                       nErrorCode,
699                                       aArguments,
700                                       rRequest->getContinuations(),
701                                       bObtainErrorStringOnly,
702                                       bHasErrorString,
703                                       rErrorString);
704             return true;
705         }
706 
707         configuration::backend::MergeRecoveryRequest aMergeRecoveryRequest;
708         if (aAnyRequest >>= aMergeRecoveryRequest)
709         {
710             ErrCode nErrorCode = aMergeRecoveryRequest.IsRemovalRequest
711                 ? ERRCODE_UUI_CONFIGURATION_BROKENDATA_WITHREMOVE
712                 : ERRCODE_UUI_CONFIGURATION_BROKENDATA_NOREMOVE;
713 
714             std::vector< rtl::OUString > aArguments;
715             aArguments.push_back(aMergeRecoveryRequest.ErrorLayerId);
716 
717             handleErrorHandlerRequest(task::InteractionClassification_ERROR,
718                                       nErrorCode,
719                                       aArguments,
720                                       rRequest->getContinuations(),
721                                       bObtainErrorStringOnly,
722                                       bHasErrorString,
723                                       rErrorString);
724             return true;
725         }
726 
727         configuration::backend::StratumCreationException
728             aStratumCreationException;
729 
730         if (aAnyRequest >>= aStratumCreationException)
731         {
732             const ErrCode nErrorCode = ERRCODE_UUI_CONFIGURATION_BACKENDMISSING;
733 
734             rtl::OUString aStratum = aStratumCreationException.StratumData;
735             if (aStratum.getLength() == 0)
736                 aStratum = aStratumCreationException.StratumService;
737 
738             std::vector< rtl::OUString > aArguments;
739             aArguments.push_back(aStratum);
740 
741             handleErrorHandlerRequest(task::InteractionClassification_ERROR,
742                                       nErrorCode,
743                                       aArguments,
744                                       rRequest->getContinuations(),
745                                       bObtainErrorStringOnly,
746                                       bHasErrorString,
747                                       rErrorString);
748             return true;
749         }
750 
751         xforms::InvalidDataOnSubmitException aInvalidDataOnSubmitException;
752         if (aAnyRequest >>= aInvalidDataOnSubmitException)
753         {
754             const ErrCode nErrorCode =
755                 ERRCODE_UUI_INVALID_XFORMS_SUBMISSION_DATA;
756 
757             std::vector< rtl::OUString > aArguments;
758 
759             handleErrorHandlerRequest(task::InteractionClassification_QUERY,
760                                       nErrorCode,
761                                       aArguments,
762                                       rRequest->getContinuations(),
763                                       bObtainErrorStringOnly,
764                                       bHasErrorString,
765                                       rErrorString);
766             return true;
767         }
768 
769         ucb::InteractiveLockingLockedException aLLException;
770         if (aAnyRequest >>= aLLException)
771         {
772             ErrCode nErrorCode = aLLException.SelfOwned
773                 ? ERRCODE_UUI_LOCKING_LOCKED_SELF : ERRCODE_UUI_LOCKING_LOCKED;
774             std::vector< rtl::OUString > aArguments;
775             aArguments.push_back( aLLException.Url );
776 
777             handleErrorHandlerRequest( aLLException.Classification,
778                                        nErrorCode,
779                                        aArguments,
780                                        rRequest->getContinuations(),
781                                        bObtainErrorStringOnly,
782                                        bHasErrorString,
783                                        rErrorString );
784             return true;
785         }
786 
787         ucb::InteractiveLockingNotLockedException aLNLException;
788         if (aAnyRequest >>= aLNLException)
789         {
790             ErrCode nErrorCode = ERRCODE_UUI_LOCKING_NOT_LOCKED;
791             std::vector< rtl::OUString > aArguments;
792             aArguments.push_back( aLNLException.Url );
793 
794             handleErrorHandlerRequest( aLNLException.Classification,
795                                        nErrorCode,
796                                        aArguments,
797                                        rRequest->getContinuations(),
798                                        bObtainErrorStringOnly,
799                                        bHasErrorString,
800                                        rErrorString );
801             return true;
802         }
803 
804         ucb::InteractiveLockingLockExpiredException aLLEException;
805         if (aAnyRequest >>= aLLEException)
806         {
807             ErrCode nErrorCode = ERRCODE_UUI_LOCKING_LOCK_EXPIRED;
808             std::vector< rtl::OUString > aArguments;
809             aArguments.push_back( aLLEException.Url );
810 
811             handleErrorHandlerRequest( aLLEException.Classification,
812                                        nErrorCode,
813                                        aArguments,
814                                        rRequest->getContinuations(),
815                                        bObtainErrorStringOnly,
816                                        bHasErrorString,
817                                        rErrorString );
818             return true;
819         }
820 
821         document::BrokenPackageRequest aBrokenPackageRequest;
822         if (aAnyRequest >>= aBrokenPackageRequest)
823         {
824             std::vector< rtl::OUString > aArguments;
825 
826             if( aBrokenPackageRequest.aName.getLength() )
827                 aArguments.push_back( aBrokenPackageRequest.aName );
828 
829             handleBrokenPackageRequest( aArguments,
830                                         rRequest->getContinuations(),
831                                         bObtainErrorStringOnly,
832                                         bHasErrorString,
833                                         rErrorString );
834             return true;
835         }
836 
837         task::ErrorCodeRequest aErrorCodeRequest;
838         if (aAnyRequest >>= aErrorCodeRequest)
839         {
840             handleGenericErrorRequest( aErrorCodeRequest.ErrCode,
841                                        rRequest->getContinuations(),
842                                        bObtainErrorStringOnly,
843                                        bHasErrorString,
844                                        rErrorString);
845             return true;
846         }
847 
848         task::ErrorCodeIOException aErrorCodeIOException;
849         if (aAnyRequest >>= aErrorCodeIOException)
850         {
851             handleGenericErrorRequest( aErrorCodeIOException.ErrCode,
852                                        rRequest->getContinuations(),
853                                        bObtainErrorStringOnly,
854                                        bHasErrorString,
855                                        rErrorString);
856             return true;
857         }
858 
859 
860         ///////////////////////////////////////////////////////////////////
861         // Handle requests which do not have a plain string representation.
862         ///////////////////////////////////////////////////////////////////
863         if (!bObtainErrorStringOnly)
864         {
865             if ( handleAuthenticationRequest( rRequest ) )
866                 return true;
867 
868             if ( handleCertificateValidationRequest( rRequest ) )
869                 return true;
870 
871             ucb::NameClashResolveRequest aNameClashResolveRequest;
872             if (aAnyRequest >>= aNameClashResolveRequest)
873             {
874                 handleNameClashResolveRequest(aNameClashResolveRequest,
875                                               rRequest->getContinuations());
876                 return true;
877             }
878 
879             if ( handleMasterPasswordRequest( rRequest ) )
880                 return true;
881 
882             if ( handlePasswordRequest( rRequest ) )
883                 return true;
884 
885             if ( handleCookiesRequest( rRequest ) )
886                 return true;
887 
888             if ( handleNoSuchFilterRequest( rRequest ) )
889                 return true;
890 
891             if ( handleAmbigousFilterRequest( rRequest ) )
892                 return true;
893 
894             if ( handleFilterOptionsRequest( rRequest ) )
895                 return true;
896 
897             if ( handleLockedDocumentRequest( rRequest ) )
898                 return true;
899 
900             if ( handleChangedByOthersRequest( rRequest ) )
901                 return true;
902 
903             if ( handleLockFileIgnoreRequest( rRequest ) )
904                 return true;
905 
906             task::DocumentMacroConfirmationRequest aMacroConfirmRequest;
907             if (aAnyRequest >>= aMacroConfirmRequest)
908             {
909                 handleMacroConfirmRequest(
910                     aMacroConfirmRequest.DocumentURL,
911                     aMacroConfirmRequest.DocumentStorage,
912                     aMacroConfirmRequest.DocumentVersion.getLength() ? aMacroConfirmRequest.DocumentVersion : ODFVER_012_TEXT,
913                     aMacroConfirmRequest.DocumentSignatureInformation,
914                     rRequest->getContinuations());
915                 return true;
916             }
917 
918             task::FutureDocumentVersionProductUpdateRequest
919                 aProductUpdateRequest;
920             if (aAnyRequest >>= aProductUpdateRequest)
921             {
922                 handleFutureDocumentVersionUpdateRequest(
923                     aProductUpdateRequest,
924                     rRequest->getContinuations());
925                 return true;
926             }
927 
928             ///////////////////////////////////////////////////////////////
929             // Last chance: interaction handlers registered in the configuration
930             ///////////////////////////////////////////////////////////////
931 
932 			// typed InteractionHandlers (ooo.Interactions)
933 			if ( handleTypedHandlerImplementations( rRequest ) )
934 				return true;
935 
936 			// legacy configuration (ooo.ucb.InteractionHandlers)
937             if (tryOtherInteractionHandler( rRequest ))
938                 return true;
939         }
940 
941         // Not handled.
942         return false;
943     }
944     catch (std::bad_alloc const &)
945     {
946         throw uno::RuntimeException(
947             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("out of memory")),
948             uno::Reference< uno::XInterface >());
949     }
950     catch( const uno::RuntimeException& )
951     {
952         throw;  // allowed to leave here
953     }
954     catch( const uno::Exception& )
955     {
956         DBG_UNHANDLED_EXCEPTION();
957     }
958     return false;
959 }
960 
961 void
962 UUIInteractionHelper::getInteractionHandlerList(
963     InteractionHandlerDataList &rdataList)
964     SAL_THROW((uno::RuntimeException))
965 {
966     try
967     {
968         uno::Reference< lang::XMultiServiceFactory > xConfigProv(
969             m_xServiceFactory->createInstance(
970                 rtl::OUString::createFromAscii(
971                     "com.sun.star.configuration.ConfigurationProvider" ) ),
972             uno::UNO_QUERY );
973 
974         if ( !xConfigProv.is() )
975             throw uno::RuntimeException(
976                 rtl::OUString(
977                     RTL_CONSTASCII_USTRINGPARAM(
978                         "unable to instanciate config provider service")),
979                 uno::Reference< uno::XInterface >());
980 
981         rtl::OUStringBuffer aFullPath;
982         aFullPath.appendAscii(
983             "/org.openoffice.ucb.InteractionHandler/InteractionHandlers" );
984 
985         uno::Sequence< uno::Any > aArguments( 1 );
986         beans::PropertyValue      aProperty;
987         aProperty.Name
988             = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
989         aProperty.Value <<= aFullPath.makeStringAndClear();
990         aArguments[ 0 ] <<= aProperty;
991 
992         uno::Reference< uno::XInterface > xInterface(
993                 xConfigProv->createInstanceWithArguments(
994                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
995                         "com.sun.star.configuration.ConfigurationAccess" ) ),
996                     aArguments ) );
997 
998         if ( !xInterface.is() )
999             throw uno::RuntimeException(
1000                 rtl::OUString(
1001                     RTL_CONSTASCII_USTRINGPARAM(
1002                         "unable to instanciate config access")),
1003                 uno::Reference< uno::XInterface >());
1004 
1005         uno::Reference< container::XNameAccess > xNameAccess(
1006             xInterface, uno::UNO_QUERY );
1007         if ( !xNameAccess.is() )
1008             throw uno::RuntimeException(
1009                 rtl::OUString(
1010                     RTL_CONSTASCII_USTRINGPARAM(
1011                         "config access does not implement XNameAccess")),
1012                 uno::Reference< uno::XInterface >());
1013 
1014         uno::Sequence< rtl::OUString > aElems = xNameAccess->getElementNames();
1015         const rtl::OUString* pElems = aElems.getConstArray();
1016         sal_Int32 nCount = aElems.getLength();
1017 
1018         if ( nCount > 0 )
1019         {
1020             uno::Reference< container::XHierarchicalNameAccess >
1021                                 xHierNameAccess( xInterface, uno::UNO_QUERY );
1022 
1023             if ( !xHierNameAccess.is() )
1024             throw uno::RuntimeException(
1025                 rtl::OUString(
1026                     RTL_CONSTASCII_USTRINGPARAM(
1027                         "config access does not implement XHierarchicalNameAccess")),
1028                 uno::Reference< uno::XInterface >());
1029 
1030             // Iterate over children.
1031             for ( sal_Int32 n = 0; n < nCount; ++n )
1032             {
1033                 rtl::OUStringBuffer aElemBuffer;
1034                 aElemBuffer.appendAscii( "['" );
1035                 aElemBuffer.append( pElems[ n ] );
1036 
1037                 try
1038                 {
1039                     InteractionHandlerData aInfo;
1040 
1041                     // Obtain service name.
1042                     rtl::OUStringBuffer aKeyBuffer = aElemBuffer;
1043                     aKeyBuffer.appendAscii( "']/ServiceName" );
1044 
1045                     rtl::OUString aValue;
1046                     if ( !( xHierNameAccess->getByHierarchicalName(
1047                                 aKeyBuffer.makeStringAndClear() ) >>= aValue ) )
1048                     {
1049                         OSL_ENSURE( false,
1050                                     "GetInteractionHandlerList - "
1051                                     "Error getting item value!" );
1052                         continue;
1053                     }
1054 
1055                     aInfo.ServiceName = aValue;
1056 
1057                     // Append info to list.
1058                     rdataList.push_back( aInfo );
1059                 }
1060                 catch ( container::NoSuchElementException& )
1061                 {
1062                     // getByHierarchicalName
1063 
1064                     OSL_ENSURE( false,
1065                                 "GetInteractionHandlerList - "
1066                                 "caught NoSuchElementException!" );
1067                 }
1068             }
1069         }
1070     }
1071     catch ( uno::RuntimeException const & )
1072     {
1073         throw;
1074     }
1075     catch ( uno::Exception const & )
1076     {
1077         OSL_ENSURE( false, "GetInteractionHandlerList - Caught Exception!" );
1078     }
1079 }
1080 
1081 Window *
1082 UUIInteractionHelper::getParentProperty()
1083     SAL_THROW(())
1084 {
1085     uno::Reference< awt::XWindow > xWindow = getParentXWindow();
1086     if ( xWindow.is() )
1087         return VCLUnoHelper::GetWindow(xWindow);
1088 
1089     return 0;
1090 }
1091 
1092 uno::Reference< awt::XWindow>
1093 UUIInteractionHelper::getParentXWindow() const
1094     SAL_THROW(())
1095 {
1096     osl::MutexGuard aGuard(m_aPropertyMutex);
1097     ::comphelper::NamedValueCollection aProperties( m_aProperties );
1098     if ( aProperties.has( "Parent" ) )
1099     {
1100         uno::Reference< awt::XWindow > xWindow;
1101         OSL_VERIFY( aProperties.get( "Parent" ) >>= xWindow );
1102 		return xWindow;
1103     }
1104     return 0;
1105 }
1106 
1107 rtl::OUString
1108 UUIInteractionHelper::getContextProperty()
1109     SAL_THROW(())
1110 {
1111     osl::MutexGuard aGuard(m_aPropertyMutex);
1112     for (sal_Int32 i = 0; i < m_aProperties.getLength(); ++i)
1113     {
1114         beans::PropertyValue aProperty;
1115         if ((m_aProperties[i] >>= aProperty)
1116             && aProperty.
1117                    Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Context")))
1118         {
1119             rtl::OUString aContext;
1120             aProperty.Value >>= aContext;
1121             return aContext;
1122         }
1123     }
1124     return rtl::OUString();
1125 }
1126 
1127 uno::Reference< task::XInteractionHandler >
1128 UUIInteractionHelper::getInteractionHandler()
1129     SAL_THROW((uno::RuntimeException))
1130 {
1131     uno::Reference< task::XInteractionHandler > xIH;
1132     try
1133     {
1134         xIH.set(m_xServiceFactory->createInstanceWithArguments(
1135                     rtl::OUString(
1136                         RTL_CONSTASCII_USTRINGPARAM(
1137                             "com.sun.star.task.InteractionHandler")),
1138                     m_aProperties),
1139                 uno::UNO_QUERY);
1140     }
1141     catch (uno::Exception const &)
1142     {}
1143 
1144     if (!xIH.is())
1145         throw uno::RuntimeException(
1146             rtl::OUString(
1147                 RTL_CONSTASCII_USTRINGPARAM(
1148                     "unable to instanciate Interaction Handler service")),
1149             uno::Reference< uno::XInterface >());
1150     return xIH;
1151 }
1152 
1153 namespace {
1154 
1155 sal_uInt16
1156 executeMessageBox(
1157     Window * pParent,
1158     rtl::OUString const & rTitle,
1159     rtl::OUString const & rMessage,
1160     WinBits nButtonMask )
1161     SAL_THROW((uno::RuntimeException))
1162 {
1163     vos::OGuard aGuard(Application::GetSolarMutex());
1164 
1165     MessBox xBox( pParent, nButtonMask, rTitle, rMessage );
1166 
1167     sal_uInt16 aResult = xBox.Execute();
1168     switch( aResult )
1169     {
1170     case BUTTONID_OK:
1171         aResult = ERRCODE_BUTTON_OK;
1172         break;
1173     case BUTTONID_CANCEL:
1174         aResult = ERRCODE_BUTTON_CANCEL;
1175         break;
1176     case BUTTONID_YES:
1177         aResult = ERRCODE_BUTTON_YES;
1178         break;
1179     case BUTTONID_NO:
1180         aResult = ERRCODE_BUTTON_NO;
1181         break;
1182     case BUTTONID_RETRY:
1183         aResult = ERRCODE_BUTTON_RETRY;
1184         break;
1185     }
1186 
1187     return aResult;
1188 }
1189 
1190 NameClashResolveDialogResult executeSimpleNameClashResolveDialog( Window *pParent,
1191                                                                   rtl::OUString const & rTargetFolderURL,
1192                                                                   rtl::OUString const & rClashingName,
1193                                                                   rtl::OUString & rProposedNewName,
1194                                                                   bool bAllowOverwrite )
1195 {
1196     std::auto_ptr< ResMgr > xManager( ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) );
1197     if ( !xManager.get() )
1198         return ABORT;
1199 
1200     NameClashDialog aDialog( pParent, xManager.get(), rTargetFolderURL,
1201                              rClashingName, rProposedNewName, bAllowOverwrite );
1202 
1203     NameClashResolveDialogResult eResult = (NameClashResolveDialogResult) aDialog.Execute();
1204     rProposedNewName = aDialog.getNewName();
1205     return eResult;
1206 }
1207 
1208 } // namespace
1209 
1210 void
1211 UUIInteractionHelper::handleNameClashResolveRequest(
1212     ucb::NameClashResolveRequest const & rRequest,
1213     uno::Sequence< uno::Reference<
1214         task::XInteractionContinuation > > const & rContinuations)
1215   SAL_THROW((uno::RuntimeException))
1216 {
1217     OSL_ENSURE(
1218         rRequest.TargetFolderURL.getLength() > 0,
1219         "NameClashResolveRequest must not contain empty TargetFolderURL" );
1220 
1221     OSL_ENSURE(
1222         rRequest.ClashingName.getLength() > 0,
1223         "NameClashResolveRequest must not contain empty ClashingName" );
1224 
1225     uno::Reference< task::XInteractionAbort > xAbort;
1226     uno::Reference< ucb::XInteractionSupplyName > xSupplyName;
1227     uno::Reference< ucb::XInteractionReplaceExistingData > xReplaceExistingData;
1228     getContinuations(
1229         rContinuations, &xAbort, &xSupplyName, &xReplaceExistingData);
1230 
1231     OSL_ENSURE( xAbort.is(),
1232         "NameClashResolveRequest must contain Abort continuation" );
1233 
1234     OSL_ENSURE( xSupplyName.is(),
1235         "NameClashResolveRequest must contain SupplyName continuation" );
1236 
1237     NameClashResolveDialogResult eResult = ABORT;
1238     rtl::OUString aProposedNewName( rRequest.ProposedNewName );
1239 
1240     eResult = executeSimpleNameClashResolveDialog( getParentProperty(),
1241                     rRequest.TargetFolderURL,
1242                     rRequest.ClashingName,
1243                     aProposedNewName,
1244                     xReplaceExistingData.is() );
1245 
1246     switch ( eResult )
1247     {
1248     case ABORT:
1249         xAbort->select();
1250         break;
1251 
1252     case RENAME:
1253         xSupplyName->setName( aProposedNewName );
1254         xSupplyName->select();
1255         break;
1256 
1257     case OVERWRITE:
1258         OSL_ENSURE(
1259             xReplaceExistingData.is(),
1260             "Invalid NameClashResolveDialogResult: OVERWRITE - "
1261             "No ReplaceExistingData continuation available!" );
1262         xReplaceExistingData->select();
1263         break;
1264     }
1265 }
1266 
1267 void
1268 UUIInteractionHelper::handleGenericErrorRequest(
1269     sal_Int32 nErrorCode,
1270     uno::Sequence< uno::Reference<
1271         task::XInteractionContinuation > > const & rContinuations,
1272     bool bObtainErrorStringOnly,
1273     bool & bHasErrorString,
1274     rtl::OUString & rErrorString)
1275     SAL_THROW((uno::RuntimeException))
1276 {
1277     if (bObtainErrorStringOnly)
1278     {
1279         bHasErrorString = isInformationalErrorMessageRequest(rContinuations);
1280         if (bHasErrorString)
1281         {
1282             String aErrorString;
1283             ErrorHandler::GetErrorString(nErrorCode, aErrorString);
1284             rErrorString = aErrorString;
1285         }
1286     }
1287     else
1288     {
1289         uno::Reference< task::XInteractionAbort > xAbort;
1290         uno::Reference< task::XInteractionApprove > xApprove;
1291         getContinuations(rContinuations, &xApprove, &xAbort);
1292 
1293         // Note: It's important to convert the transported long to the
1294         // required  unsigned long value. Otherwhise using as flag field
1295         // can fail ...
1296         ErrCode  nError   = static_cast< ErrCode >(nErrorCode);
1297         sal_Bool bWarning = !ERRCODE_TOERROR(nError);
1298 
1299         if ( nError == ERRCODE_SFX_BROKENSIGNATURE
1300              || nError == ERRCODE_SFX_INCOMPLETE_ENCRYPTION )
1301         {
1302             // the security warning box needs a special title
1303             String aErrorString;
1304             ErrorHandler::GetErrorString( nErrorCode, aErrorString );
1305 
1306             std::auto_ptr< ResMgr > xManager(
1307                 ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) );
1308             ::rtl::OUString aTitle;
1309 
1310             try
1311             {
1312                 uno::Any aProductNameAny =
1313                     ::utl::ConfigManager::GetConfigManager()
1314                         ->GetDirectConfigProperty(
1315                            ::utl::ConfigManager::PRODUCTNAME );
1316                 aProductNameAny >>= aTitle;
1317             }
1318             catch( uno::Exception& )
1319             {
1320             }
1321 
1322             ::rtl::OUString aErrTitle
1323                   = String( ResId( nError == ERRCODE_SFX_BROKENSIGNATURE
1324                                        ? STR_WARNING_BROKENSIGNATURE_TITLE
1325                                        : STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE,
1326                                    *xManager.get() ) );
1327 
1328             if ( aTitle.getLength() && aErrTitle.getLength() )
1329                 aTitle += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " - " ) );
1330             aTitle += aErrTitle;
1331 
1332             executeMessageBox(
1333                 getParentProperty(), aTitle, aErrorString, WB_OK );
1334         }
1335         else
1336             ErrorHandler::HandleError(nErrorCode);
1337 
1338         if (xApprove.is() && bWarning)
1339             xApprove->select();
1340         else if (xAbort.is())
1341             xAbort->select();
1342     }
1343 }
1344 
1345 void
1346 UUIInteractionHelper::handleMacroConfirmRequest(
1347     const ::rtl::OUString& aDocumentURL,
1348     const uno::Reference< embed::XStorage >& xZipStorage,
1349     const ::rtl::OUString& aDocumentVersion,
1350     const uno::Sequence< security::DocumentSignatureInformation > aSignInfo,
1351     uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
1352         rContinuations )
1353     SAL_THROW((uno::RuntimeException))
1354 {
1355     uno::Reference< task::XInteractionAbort > xAbort;
1356     uno::Reference< task::XInteractionApprove > xApprove;
1357     getContinuations( rContinuations, &xApprove, &xAbort );
1358 
1359     bool bApprove = false;
1360 
1361     std::auto_ptr< ResMgr > pResMgr(
1362         ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) );
1363     if ( pResMgr.get() )
1364     {
1365         bool bShowSignatures = aSignInfo.getLength() > 0;
1366         MacroWarning aWarning(
1367             getParentProperty(), bShowSignatures, *pResMgr.get() );
1368 
1369         aWarning.SetDocumentURL( aDocumentURL );
1370         if ( aSignInfo.getLength() > 1 )
1371         {
1372             aWarning.SetStorage( xZipStorage, aDocumentVersion, aSignInfo );
1373         }
1374         else if ( aSignInfo.getLength() == 1 )
1375         {
1376             aWarning.SetCertificate( aSignInfo[ 0 ].Signer );
1377         }
1378 
1379         bApprove = aWarning.Execute() == RET_OK;
1380     }
1381 
1382     if ( bApprove && xApprove.is() )
1383         xApprove->select();
1384     else if ( xAbort.is() )
1385         xAbort->select();
1386 }
1387 
1388 void
1389 UUIInteractionHelper::handleFutureDocumentVersionUpdateRequest(
1390     const task::FutureDocumentVersionProductUpdateRequest& _rRequest,
1391     uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
1392         rContinuations )
1393     SAL_THROW((uno::RuntimeException))
1394 {
1395     uno::Reference< task::XInteractionAbort > xAbort;
1396     uno::Reference< task::XInteractionApprove > xApprove;
1397     uno::Reference< task::XInteractionAskLater > xAskLater;
1398     getContinuations( rContinuations, &xApprove, &xAbort, &xAskLater );
1399 
1400     short nResult = RET_CANCEL;
1401 
1402     static bool s_bDeferredToNextSession = false;
1403     // TODO: this static variable is somewhat hacky. Formerly (before the dialog was moved from SFX2 to the
1404     // interaction handler implementation), this was stored in SFX_APP()'s impl structure, in member
1405     // bODFVersionWarningLater. Of course, we do not have access to it here.
1406     //
1407     // A proper solution which I would envision would be:
1408     // - There's a central implementation (this one here) of css.task.InteractionHandler
1409     // - There's a configuration which maps UNO names to service names
1410     // - If the handler is confronted with a request, it tries to find the name of the UNO structure describing
1411     //   the request in the said configuration.
1412     //   - If an entry is found, then
1413     //     - the respective service is instantiated
1414     //     - the component is queried for css.task.XInteractionHandler, and the request is delegated
1415     //   - if no entry is found, then the request is silenced (with calling the AbortContinuation, if possible)
1416     // This way, the FutureDocumentVersionProductUpdateRequest could be handled in SFX (or any other
1417     // suitable place), again, and we would only have one place where we remember the s_bDeferredToNextSession
1418     // flag.
1419     //
1420 	// Note: The above pattern has been implemented in CWS autorecovery. Now the remaining task is to move the
1421 	// handling of this interaction to SFX, again.
1422 
1423     if ( !s_bDeferredToNextSession )
1424     {
1425         std::auto_ptr< ResMgr > pResMgr(
1426             ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( uui ) ) );
1427         if ( pResMgr.get() )
1428         {
1429             ::uui::NewerVersionWarningDialog aDialog(
1430                 getParentProperty(),
1431                 _rRequest.DocumentODFVersion,
1432                 *pResMgr.get() );
1433             nResult = aDialog.Execute();
1434         }
1435     }
1436 
1437     switch ( nResult )
1438     {
1439     case RET_OK:
1440         if ( xApprove.is() )
1441             xApprove->select();
1442         break;
1443     case RET_CANCEL:
1444         if ( xAbort.is() )
1445             xAbort->select();
1446         break;
1447     case RET_ASK_LATER:
1448         if ( xAskLater.is() )
1449             xAskLater->select();
1450         s_bDeferredToNextSession = true;
1451         break;
1452     default:
1453         OSL_ENSURE( false,
1454             "UUIInteractionHelper::handleFutureDocumentVersionUpdateRequest: "
1455                     "unexpected dialog return value!" );
1456         break;
1457     }
1458 }
1459 
1460 void
1461 UUIInteractionHelper::handleBrokenPackageRequest(
1462     std::vector< rtl::OUString > const & rArguments,
1463     uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
1464         rContinuations,
1465     bool bObtainErrorStringOnly,
1466     bool & bHasErrorString,
1467     rtl::OUString & rErrorString)
1468     SAL_THROW((uno::RuntimeException))
1469 {
1470     if (bObtainErrorStringOnly)
1471     {
1472         bHasErrorString = isInformationalErrorMessageRequest(rContinuations);
1473         if (!bHasErrorString)
1474             return;
1475     }
1476 
1477     uno::Reference< task::XInteractionApprove > xApprove;
1478     uno::Reference< task::XInteractionDisapprove > xDisapprove;
1479     uno::Reference< task::XInteractionAbort > xAbort;
1480     getContinuations(rContinuations, &xApprove, &xDisapprove, &xAbort);
1481 
1482     ErrCode nErrorCode;
1483     if( xApprove.is() && xDisapprove.is() )
1484     {
1485         nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE;
1486     }
1487     else if ( xAbort.is() )
1488     {
1489         nErrorCode = ERRCODE_UUI_IO_BROKENPACKAGE_CANTREPAIR;
1490     }
1491     else
1492         return;
1493 
1494     ::rtl::OUString aMessage;
1495     {
1496         vos::OGuard aGuard(Application::GetSolarMutex());
1497         std::auto_ptr< ResMgr > xManager(
1498             ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(uui)));
1499         if (!xManager.get())
1500             return;
1501 
1502         ResId aResId( RID_UUI_ERRHDL, *xManager.get() );
1503         if ( !ErrorResource(aResId).getString(nErrorCode, &aMessage) )
1504             return;
1505     }
1506 
1507     aMessage = replaceMessageWithArguments( aMessage, rArguments );
1508 
1509     if (bObtainErrorStringOnly)
1510     {
1511         rErrorString = aMessage;
1512         return;
1513     }
1514 
1515     WinBits nButtonMask;
1516     if( xApprove.is() && xDisapprove.is() )
1517     {
1518         nButtonMask = WB_YES_NO | WB_DEF_YES;
1519     }
1520     else if ( xAbort.is() )
1521     {
1522         nButtonMask = WB_OK;
1523     }
1524     else
1525         return;
1526 
1527     uno::Any aProductNameAny =
1528         ::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty(
1529             ::utl::ConfigManager::PRODUCTNAME );
1530     uno::Any aProductVersionAny =
1531         ::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty(
1532             ::utl::ConfigManager::PRODUCTVERSION );
1533     ::rtl::OUString aProductName, aProductVersion;
1534     if ( !( aProductNameAny >>= aProductName ) )
1535         aProductName
1536             = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("StarOffice") );
1537 
1538     ::rtl::OUString aTitle( aProductName );
1539     if( aProductVersionAny >>= aProductVersion )
1540     {
1541         aTitle += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" ") );
1542         aTitle += aProductVersion;
1543     }
1544 
1545     switch ( executeMessageBox( getParentProperty(),
1546                                 aTitle,
1547                                 aMessage,
1548                                 nButtonMask ))
1549     {
1550     case ERRCODE_BUTTON_OK:
1551         OSL_ENSURE( xAbort.is(), "unexpected situation" );
1552         if (xAbort.is())
1553             xAbort->select();
1554         break;
1555 
1556     case ERRCODE_BUTTON_NO:
1557         OSL_ENSURE(xDisapprove.is(), "unexpected situation");
1558         if (xDisapprove.is())
1559             xDisapprove->select();
1560         break;
1561 
1562     case ERRCODE_BUTTON_YES:
1563         OSL_ENSURE(xApprove.is(), "unexpected situation");
1564         if (xApprove.is())
1565             xApprove->select();
1566         break;
1567     }
1568 }
1569 
1570 //=========================================================================
1571 // ErrorResource Implementation
1572 //=========================================================================
1573 
1574 bool
1575 ErrorResource::getString(ErrCode nErrorCode, rtl::OUString * pString)
1576     const SAL_THROW(())
1577 {
1578     OSL_ENSURE(pString, "specification violation");
1579     ResId aResId(static_cast< sal_uInt16 >(nErrorCode & ERRCODE_RES_MASK),
1580                  *m_pResMgr);
1581     aResId.SetRT(RSC_STRING);
1582     if (!IsAvailableRes(aResId))
1583         return false;
1584     aResId.SetAutoRelease(false);
1585     *pString = UniString(aResId);
1586     m_pResMgr->PopContext();
1587     return true;
1588 }
1589