nss: upgrade to release 3.73
[LibreOffice.git] / uui / source / iahndl-errorhandler.cxx
blob56f54255d730d2f194b617089df47d3274c12768
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 <vcl/errinf.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/stdtext.hxx>
23 #include <vcl/weld.hxx>
25 #include <com/sun/star/task/XInteractionAbort.hpp>
26 #include <com/sun/star/task/XInteractionApprove.hpp>
27 #include <com/sun/star/task/XInteractionDisapprove.hpp>
28 #include <com/sun/star/task/XInteractionRetry.hpp>
30 #include <svx/svxerr.hxx>
31 #include <unotools/resmgr.hxx>
32 #include <osl/diagnose.h>
33 #include <rtl/ustrbuf.hxx>
35 #include <ids.hrc>
36 #include "getcontinuations.hxx"
38 #include "iahndl.hxx"
39 #include <memory>
41 using namespace com::sun::star;
43 namespace {
45 enum class MessageBoxStyle {
46 NONE = 0x0000,
47 Ok = 0x0001,
48 OkCancel = 0x0002,
49 YesNo = 0x0004,
50 YesNoCancel = 0x0008,
51 RetryCancel = 0x0010
54 DialogMask
55 executeErrorDialog(
56 weld::Window* pParent,
57 task::InteractionClassification eClassification,
58 OUString const & rContext,
59 OUString const & rMessage,
60 MessageBoxStyle nButtonMask)
62 SolarMutexGuard aGuard;
64 OUStringBuffer aText(rContext);
65 if (!rContext.isEmpty() && !rMessage.isEmpty())
66 aText.append(":\n");
67 //TODO! must be internationalized
68 aText.append(rMessage);
70 std::unique_ptr<weld::MessageDialog> xBox;
72 switch (eClassification)
74 case task::InteractionClassification_ERROR:
75 xBox.reset(Application::CreateMessageDialog(pParent,
76 VclMessageType::Error, VclButtonsType::NONE, aText.makeStringAndClear()));
77 break;
78 case task::InteractionClassification_WARNING:
79 xBox.reset(Application::CreateMessageDialog(pParent,
80 VclMessageType::Warning, VclButtonsType::NONE, aText.makeStringAndClear()));
81 break;
82 case task::InteractionClassification_INFO:
83 xBox.reset(Application::CreateMessageDialog(pParent,
84 VclMessageType::Info, VclButtonsType::NONE, aText.makeStringAndClear()));
85 break;
86 case task::InteractionClassification_QUERY:
87 xBox.reset(Application::CreateMessageDialog(pParent,
88 VclMessageType::Question, VclButtonsType::NONE, aText.makeStringAndClear()));
89 break;
90 default:
91 assert(false);
92 break;
96 switch (nButtonMask)
98 case MessageBoxStyle::NONE:
99 break;
100 case MessageBoxStyle::Ok:
101 xBox->add_button(GetStandardText(StandardButtonType::OK), static_cast<int>(DialogMask::ButtonsOk));
102 break;
103 case MessageBoxStyle::OkCancel:
104 xBox->add_button(GetStandardText(StandardButtonType::OK), static_cast<int>(DialogMask::ButtonsOk));
105 xBox->add_button(GetStandardText(StandardButtonType::Cancel), static_cast<int>(DialogMask::ButtonsCancel));
106 break;
107 case MessageBoxStyle::YesNo:
108 xBox->add_button(GetStandardText(StandardButtonType::Yes), static_cast<int>(DialogMask::ButtonsYes));
109 xBox->add_button(GetStandardText(StandardButtonType::No), static_cast<int>(DialogMask::ButtonsNo));
110 break;
111 case MessageBoxStyle::YesNoCancel:
112 xBox->add_button(GetStandardText(StandardButtonType::Yes), static_cast<int>(DialogMask::ButtonsYes));
113 xBox->add_button(GetStandardText(StandardButtonType::No), static_cast<int>(DialogMask::ButtonsNo));
114 xBox->add_button(GetStandardText(StandardButtonType::Cancel), static_cast<int>(DialogMask::ButtonsCancel));
115 break;
116 case MessageBoxStyle::RetryCancel:
117 xBox->add_button(GetStandardText(StandardButtonType::Retry), static_cast<int>(DialogMask::ButtonsRetry));
118 xBox->add_button(GetStandardText(StandardButtonType::Cancel), static_cast<int>(DialogMask::ButtonsCancel));
119 break;
122 return static_cast<DialogMask>(xBox->run());
127 void
128 UUIInteractionHelper::handleErrorHandlerRequest(
129 task::InteractionClassification eClassification,
130 ErrCode nErrorCode,
131 std::vector< OUString > const & rArguments,
132 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
133 rContinuations,
134 bool bObtainErrorStringOnly,
135 bool & bHasErrorString,
136 OUString & rErrorString)
138 if (bObtainErrorStringOnly)
140 bHasErrorString = isInformationalErrorMessageRequest(rContinuations);
141 if (!bHasErrorString)
142 return;
145 OUString aMessage;
147 enum Source { SOURCE_DEFAULT, SOURCE_SVX, SOURCE_UUI };
148 static char const * const aManager[3] = { "svt", "svx", "uui" };
149 static const ErrMsgCode* const aId[3]
150 = { RID_ERRHDL,
151 RID_SVXERRCODE,
152 RID_UUI_ERRHDL };
153 ErrCodeArea nErrorArea = nErrorCode.GetArea();
154 Source eSource =
155 nErrorArea < ErrCodeArea::Svx ? SOURCE_DEFAULT
156 : nErrorArea == ErrCodeArea::Svx ? SOURCE_SVX : SOURCE_UUI;
158 std::locale aResLocale = Translate::Create(aManager[eSource]);
159 ErrorResource aErrorResource(aId[eSource], aResLocale);
160 if (!aErrorResource.getString(nErrorCode, aMessage))
161 return;
164 aMessage = replaceMessageWithArguments( aMessage, rArguments );
166 if (bObtainErrorStringOnly)
168 rErrorString = aMessage;
169 return;
171 else
173 //TODO! It can happen that the buttons calculated below do not match
174 // the error text from the resource (e.g., some text that is not a
175 // question, but YES and NO buttons). Some error texts have
176 // ExtraData that specifies a set of buttons, but that data is not
177 // really useful, because a single error text may well make sense
178 // both with only an OK button and with RETRY and CANCEL buttons.
180 uno::Reference< task::XInteractionApprove > xApprove;
181 uno::Reference< task::XInteractionDisapprove > xDisapprove;
182 uno::Reference< task::XInteractionRetry > xRetry;
183 uno::Reference< task::XInteractionAbort > xAbort;
184 getContinuations(
185 rContinuations, &xApprove, &xDisapprove, &xRetry, &xAbort);
187 // The following mapping uses the bit mask
188 // Approve = 8,
189 // Disapprove = 4,
190 // Retry = 2,
191 // Abort = 1
193 // The mapping has five properties on which the code to select the
194 // correct continuation relies:
195 // 1 The OK button is mapped to Approve if that is available,
196 // otherwise to Abort if that is available, otherwise to none.
197 // 2 The CANCEL button is always mapped to Abort.
198 // 3 The RETRY button is always mapped to Retry.
199 // 4 The NO button is always mapped to Disapprove.
200 // 5 The YES button is always mapped to Approve.
202 // Because the WinBits button combinations are quite restricted, not
203 // every request can be served here.
205 // Finally, it seems to be better to leave default button
206 // determination to VCL (the favouring of CANCEL as default button
207 // seems to not always be what the user wants)...
208 MessageBoxStyle const aButtonMask[16]
209 = { MessageBoxStyle::NONE,
210 MessageBoxStyle::Ok /*| MessBoxStyle::DefaultOk*/, // Abort
211 MessageBoxStyle::NONE,
212 MessageBoxStyle::RetryCancel /*| MessBoxStyle::DefaultCancel*/, // Retry, Abort
213 MessageBoxStyle::NONE,
214 MessageBoxStyle::NONE,
215 MessageBoxStyle::NONE,
216 MessageBoxStyle::NONE,
217 MessageBoxStyle::Ok /*| MessBoxStyle::DefaultOk*/, // Approve
218 MessageBoxStyle::OkCancel /*| MessBoxStyle::DefaultCancel*/, // Approve, Abort
219 MessageBoxStyle::NONE,
220 MessageBoxStyle::NONE,
221 MessageBoxStyle::YesNo /*| MessBoxStyle::DefaultNo*/, // Approve, Disapprove
222 MessageBoxStyle::YesNoCancel /*| MessBoxStyle::DefaultCancel*/,
223 // Approve, Disapprove, Abort
224 MessageBoxStyle::NONE,
225 MessageBoxStyle::NONE };
227 MessageBoxStyle nButtonMask = aButtonMask[(xApprove.is() ? 8 : 0)
228 | (xDisapprove.is() ? 4 : 0)
229 | (xRetry.is() ? 2 : 0)
230 | (xAbort.is() ? 1 : 0)];
231 if (nButtonMask == MessageBoxStyle::NONE)
232 return;
234 //TODO! remove this backwards compatibility?
235 OUString aContext(m_aContextParam);
236 if (aContext.isEmpty() && nErrorCode != ERRCODE_NONE)
238 SolarMutexGuard aGuard;
239 ErrorContext * pContext = ErrorContext::GetContext();
240 if (pContext)
242 OUString aContextString;
243 if (pContext->GetString(nErrorCode, aContextString))
244 aContext = aContextString;
248 uno::Reference<awt::XWindow> xParent = getParentXWindow();
249 DialogMask nResult = executeErrorDialog(Application::GetFrameWeld(xParent),
250 eClassification, aContext, aMessage, nButtonMask );
252 switch (nResult)
254 case DialogMask::ButtonsOk:
255 OSL_ENSURE(xApprove.is() || xAbort.is(), "unexpected situation");
256 if (xApprove.is())
257 xApprove->select();
258 else if (xAbort.is())
259 xAbort->select();
260 break;
262 case DialogMask::ButtonsCancel:
263 OSL_ENSURE(xAbort.is(), "unexpected situation");
264 if (xAbort.is())
265 xAbort->select();
266 break;
268 case DialogMask::ButtonsRetry:
269 OSL_ENSURE(xRetry.is(), "unexpected situation");
270 if (xRetry.is())
271 xRetry->select();
272 break;
274 case DialogMask::ButtonsNo:
275 OSL_ENSURE(xDisapprove.is(), "unexpected situation");
276 if (xDisapprove.is())
277 xDisapprove->select();
278 break;
280 case DialogMask::ButtonsYes:
281 OSL_ENSURE(xApprove.is(), "unexpected situation");
282 if (xApprove.is())
283 xApprove->select();
284 break;
286 default: break;
292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */