Linux x86 build fix
[LibreOffice.git] / desktop / source / lib / lokinteractionhandler.cxx
bloba1e55687e1880bca7f820440d456fdb9eb53f087
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "lokinteractionhandler.hxx"
22 #include <boost/property_tree/json_parser.hpp>
24 #include <rtl/ref.hxx>
25 #include <cppuhelper/supportsservice.hxx>
27 #include <com/sun/star/task/XInteractionAbort.hpp>
28 #include <com/sun/star/task/XInteractionApprove.hpp>
29 #include <com/sun/star/task/XInteractionPassword2.hpp>
30 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
31 #include <com/sun/star/ucb/InteractiveNetworkOffLineException.hpp>
33 #include <com/sun/star/ucb/InteractiveIOException.hpp>
34 #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
35 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
36 #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
38 #define LOK_USE_UNSTABLE_API
39 #include <../../inc/lib/init.hxx>
41 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
43 using namespace com::sun::star;
45 LOKInteractionHandler::LOKInteractionHandler(
46 uno::Reference<uno::XComponentContext> const & /*rxContext*/,
47 const OString& rCommand,
48 desktop::LibLibreOffice_Impl *const pLOKit,
49 desktop::LibLODocument_Impl *const pLOKDocument)
50 : m_pLOKit(pLOKit)
51 , m_pLOKDocument(pLOKDocument)
52 , m_command(rCommand)
53 , m_usePassword(false)
55 assert(m_pLOKit);
58 LOKInteractionHandler::~LOKInteractionHandler()
62 OUString SAL_CALL LOKInteractionHandler::getImplementationName() throw (uno::RuntimeException, std::exception)
64 return OUString("com.sun.star.comp.uui.LOKInteractionHandler");
67 sal_Bool SAL_CALL LOKInteractionHandler::supportsService(OUString const & rServiceName) throw (uno::RuntimeException, std::exception)
69 return cppu::supportsService(this, rServiceName);
72 uno::Sequence< OUString > SAL_CALL LOKInteractionHandler::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
74 uno::Sequence< OUString > aNames(3);
75 aNames[0] = "com.sun.star.task.InteractionHandler";
76 // added to indicate support for configuration.backend.MergeRecoveryRequest
77 aNames[1] = "com.sun.star.configuration.backend.InteractionHandler";
78 aNames[2] = "com.sun.star.uui.InteractionHandler";
79 // for backwards compatibility
80 return aNames;
83 void SAL_CALL LOKInteractionHandler::initialize(uno::Sequence<uno::Any> const & /*rArguments*/) throw (uno::Exception, std::exception)
87 void SAL_CALL LOKInteractionHandler::handle(
88 uno::Reference<task::XInteractionRequest> const & xRequest)
89 throw (uno::RuntimeException, std::exception)
91 // just do the same thing in both cases
92 handleInteractionRequest(xRequest);
95 void LOKInteractionHandler::postError(css::task::InteractionClassification classif, const char* kind, ErrCode code, const OUString &message)
97 const char *classification = "error";
98 switch (classif)
100 case task::InteractionClassification_ERROR: break;
101 case task::InteractionClassification_WARNING: classification = "warning"; break;
102 case task::InteractionClassification_INFO: classification = "info"; break;
103 case task::InteractionClassification_QUERY: classification = "query"; break;
104 default: assert(false); break;
107 // create the JSON representation
108 boost::property_tree::ptree aTree;
109 aTree.put("classification", classification);
110 aTree.put("cmd", m_command.getStr());
111 aTree.put("kind", kind);
112 aTree.put("code", code);
113 aTree.put("message", message.toUtf8());
115 std::stringstream aStream;
116 boost::property_tree::write_json(aStream, aTree);
118 if (m_pLOKDocument && m_pLOKDocument->mpCallbackFlushHandler)
119 m_pLOKDocument->mpCallbackFlushHandler->queue(LOK_CALLBACK_ERROR, aStream.str().c_str());
120 else if (m_pLOKit->mpCallback)
121 m_pLOKit->mpCallback(LOK_CALLBACK_ERROR, aStream.str().c_str(), m_pLOKit->mpCallbackData);
124 namespace {
126 /// Just approve the interaction.
127 void selectApproved(uno::Sequence<uno::Reference<task::XInteractionContinuation>> const &rContinuations)
129 for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i)
131 uno::Reference<task::XInteractionApprove> xApprove(rContinuations[i], uno::UNO_QUERY);
132 if (xApprove.is())
133 xApprove->select();
139 bool LOKInteractionHandler::handleIOException(const css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> &rContinuations, const css::uno::Any& rRequest)
141 ucb::InteractiveIOException aIoException;
142 if (!(rRequest >>= aIoException))
143 return false;
145 static ErrCode const aErrorCode[ucb::IOErrorCode_WRONG_VERSION + 1] =
147 ERRCODE_IO_ABORT,
148 ERRCODE_IO_ACCESSDENIED,
149 ERRCODE_IO_ALREADYEXISTS,
150 ERRCODE_IO_BADCRC,
151 ERRCODE_IO_CANTCREATE,
152 ERRCODE_IO_CANTREAD,
153 ERRCODE_IO_CANTSEEK,
154 ERRCODE_IO_CANTTELL,
155 ERRCODE_IO_CANTWRITE,
156 ERRCODE_IO_CURRENTDIR,
157 ERRCODE_IO_DEVICENOTREADY,
158 ERRCODE_IO_NOTSAMEDEVICE,
159 ERRCODE_IO_GENERAL,
160 ERRCODE_IO_INVALIDACCESS,
161 ERRCODE_IO_INVALIDCHAR,
162 ERRCODE_IO_INVALIDDEVICE,
163 ERRCODE_IO_INVALIDLENGTH,
164 ERRCODE_IO_INVALIDPARAMETER,
165 ERRCODE_IO_ISWILDCARD,
166 ERRCODE_IO_LOCKVIOLATION,
167 ERRCODE_IO_MISPLACEDCHAR,
168 ERRCODE_IO_NAMETOOLONG,
169 ERRCODE_IO_NOTEXISTS,
170 ERRCODE_IO_NOTEXISTSPATH,
171 ERRCODE_IO_NOTSUPPORTED,
172 ERRCODE_IO_NOTADIRECTORY,
173 ERRCODE_IO_NOTAFILE,
174 ERRCODE_IO_OUTOFSPACE,
175 ERRCODE_IO_TOOMANYOPENFILES,
176 ERRCODE_IO_OUTOFMEMORY,
177 ERRCODE_IO_PENDING,
178 ERRCODE_IO_RECURSIVE,
179 ERRCODE_IO_UNKNOWN,
180 ERRCODE_IO_WRITEPROTECTED,
181 ERRCODE_IO_WRONGFORMAT,
182 ERRCODE_IO_WRONGVERSION,
185 postError(aIoException.Classification, "io", aErrorCode[aIoException.Code], "");
186 selectApproved(rContinuations);
188 return true;
191 bool LOKInteractionHandler::handleNetworkException(const uno::Sequence<uno::Reference<task::XInteractionContinuation>> &rContinuations, const uno::Any &rRequest)
193 ucb::InteractiveNetworkException aNetworkException;
194 if (!(rRequest >>= aNetworkException))
195 return false;
197 ErrCode nErrorCode;
198 OUString aMessage;
200 ucb::InteractiveNetworkOffLineException aOffLineException;
201 ucb::InteractiveNetworkResolveNameException aResolveNameException;
202 ucb::InteractiveNetworkConnectException aConnectException;
203 ucb::InteractiveNetworkReadException aReadException;
204 ucb::InteractiveNetworkWriteException aWriteException;
205 if (rRequest >>= aOffLineException)
207 nErrorCode = ERRCODE_INET_OFFLINE;
209 else if (rRequest >>= aResolveNameException)
211 nErrorCode = ERRCODE_INET_NAME_RESOLVE;
212 aMessage = aResolveNameException.Server;
214 else if (rRequest >>= aConnectException)
216 nErrorCode = ERRCODE_INET_CONNECT;
217 aMessage = aConnectException.Server;
219 else if (rRequest >>= aReadException)
221 nErrorCode = ERRCODE_INET_READ;
222 aMessage = aReadException.Diagnostic;
224 else if (rRequest >>= aWriteException)
226 nErrorCode = ERRCODE_INET_WRITE;
227 aMessage = aWriteException.Diagnostic;
229 else
231 nErrorCode = ERRCODE_INET_GENERAL;
234 postError(aNetworkException.Classification, "network", nErrorCode, aMessage);
235 selectApproved(rContinuations);
237 return true;
240 bool LOKInteractionHandler::handlePasswordRequest(const uno::Sequence<uno::Reference<task::XInteractionContinuation>> &rContinuations, const uno::Any &rRequest)
242 task::DocumentPasswordRequest2 passwordRequest;
243 if (!(rRequest >>= passwordRequest))
244 return false;
246 if (m_pLOKit->mpCallback &&
247 m_pLOKit->hasOptionalFeature((passwordRequest.IsRequestPasswordToModify)
248 ? LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY
249 : LOK_FEATURE_DOCUMENT_PASSWORD))
251 OString const url(passwordRequest.Name.toUtf8());
252 m_pLOKit->mpCallback(passwordRequest.IsRequestPasswordToModify
253 ? LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY
254 : LOK_CALLBACK_DOCUMENT_PASSWORD,
255 url.getStr(),
256 m_pLOKit->mpCallbackData);
258 // block until SetPassword is called
259 m_havePassword.wait();
260 m_havePassword.reset();
263 for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i)
265 if (m_usePassword)
267 if (passwordRequest.IsRequestPasswordToModify)
269 uno::Reference<task::XInteractionPassword2> const xIPW2(rContinuations[i], uno::UNO_QUERY);
270 xIPW2->setPasswordToModify(m_Password);
271 xIPW2->select();
273 else
275 uno::Reference<task::XInteractionPassword> const xIPW(rContinuations[i], uno::UNO_QUERY);
276 if (xIPW.is())
278 xIPW->setPassword(m_Password);
279 xIPW->select();
283 else
285 if (passwordRequest.IsRequestPasswordToModify)
287 uno::Reference<task::XInteractionPassword2> const xIPW2(rContinuations[i], uno::UNO_QUERY);
288 xIPW2->setRecommendReadOnly(true);
289 xIPW2->select();
291 else
293 uno::Reference<task::XInteractionAbort> const xAbort(rContinuations[i], uno::UNO_QUERY);
294 if (xAbort.is())
296 xAbort->select();
301 return true;
304 sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(
305 const uno::Reference<task::XInteractionRequest>& xRequest) throw (uno::RuntimeException, std::exception)
307 uno::Sequence<uno::Reference<task::XInteractionContinuation>> const &rContinuations = xRequest->getContinuations();
308 uno::Any const request(xRequest->getRequest());
310 if (handleIOException(rContinuations, request))
311 return true;
313 if (handleNetworkException(rContinuations, request))
314 return true;
316 if (handlePasswordRequest(rContinuations, request))
317 return true;
319 // TODO: perform more interactions 'for real' like the above
320 selectApproved(rContinuations);
322 return sal_True;
325 void LOKInteractionHandler::SetPassword(char const*const pPassword)
327 if (pPassword)
329 m_Password = OUString(pPassword, strlen(pPassword), RTL_TEXTENCODING_UTF8);
330 m_usePassword = true;
332 else
334 m_usePassword = false;
336 m_havePassword.set();
339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */