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