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