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