1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <svx/dialogs.hrc>
32 #include <unotools/resmgr.hxx>
33 #include <osl/diagnose.h>
37 #include "getcontinuations.hxx"
42 using namespace com::sun::star
;
46 enum class MessageBoxStyle
{
57 weld::Window
* pParent
,
58 task::InteractionClassification eClassification
,
59 OUString
const & rContext
,
60 OUString
const & rMessage
,
61 MessageBoxStyle nButtonMask
)
63 SolarMutexGuard aGuard
;
65 OUStringBuffer
aText(rContext
);
66 if (!rContext
.isEmpty() && !rMessage
.isEmpty())
68 //TODO! must be internationalized
69 aText
.append(rMessage
);
71 std::unique_ptr
<weld::MessageDialog
> xBox
;
73 switch (eClassification
)
75 case task::InteractionClassification_ERROR
:
76 xBox
.reset(Application::CreateMessageDialog(pParent
,
77 VclMessageType::Error
, VclButtonsType::NONE
, aText
.makeStringAndClear()));
79 case task::InteractionClassification_WARNING
:
80 xBox
.reset(Application::CreateMessageDialog(pParent
,
81 VclMessageType::Warning
, VclButtonsType::NONE
, aText
.makeStringAndClear()));
83 case task::InteractionClassification_INFO
:
84 xBox
.reset(Application::CreateMessageDialog(pParent
,
85 VclMessageType::Info
, VclButtonsType::NONE
, aText
.makeStringAndClear()));
87 case task::InteractionClassification_QUERY
:
88 xBox
.reset(Application::CreateMessageDialog(pParent
,
89 VclMessageType::Question
, VclButtonsType::NONE
, aText
.makeStringAndClear()));
99 case MessageBoxStyle::NONE
:
101 case MessageBoxStyle::Ok
:
102 xBox
->add_button(GetStandardText(StandardButtonType::OK
), static_cast<int>(DialogMask::ButtonsOk
));
104 case MessageBoxStyle::OkCancel
:
105 xBox
->add_button(GetStandardText(StandardButtonType::OK
), static_cast<int>(DialogMask::ButtonsOk
));
106 xBox
->add_button(GetStandardText(StandardButtonType::Cancel
), static_cast<int>(DialogMask::ButtonsCancel
));
108 case MessageBoxStyle::YesNo
:
109 xBox
->add_button(GetStandardText(StandardButtonType::Yes
), static_cast<int>(DialogMask::ButtonsYes
));
110 xBox
->add_button(GetStandardText(StandardButtonType::No
), static_cast<int>(DialogMask::ButtonsNo
));
112 case MessageBoxStyle::YesNoCancel
:
113 xBox
->add_button(GetStandardText(StandardButtonType::Yes
), static_cast<int>(DialogMask::ButtonsYes
));
114 xBox
->add_button(GetStandardText(StandardButtonType::No
), static_cast<int>(DialogMask::ButtonsNo
));
115 xBox
->add_button(GetStandardText(StandardButtonType::Cancel
), static_cast<int>(DialogMask::ButtonsCancel
));
117 case MessageBoxStyle::RetryCancel
:
118 xBox
->add_button(GetStandardText(StandardButtonType::Retry
), static_cast<int>(DialogMask::ButtonsRetry
));
119 xBox
->add_button(GetStandardText(StandardButtonType::Cancel
), static_cast<int>(DialogMask::ButtonsCancel
));
123 return static_cast<DialogMask
>(xBox
->run());
129 UUIInteractionHelper::handleErrorHandlerRequest(
130 task::InteractionClassification eClassification
,
132 std::vector
< OUString
> const & rArguments
,
133 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
135 bool bObtainErrorStringOnly
,
136 bool & bHasErrorString
,
137 OUString
& rErrorString
)
139 if (bObtainErrorStringOnly
)
141 bHasErrorString
= isInformationalErrorMessageRequest(rContinuations
);
142 if (!bHasErrorString
)
148 enum Source
{ SOURCE_DEFAULT
, SOURCE_SVX
, SOURCE_UUI
};
149 static char const * const aManager
[3] = { "svt", "svx", "uui" };
150 static const ErrMsgCode
* const aId
[3]
154 ErrCodeArea nErrorArea
= nErrorCode
.GetArea();
156 nErrorArea
< ErrCodeArea::Svx
? SOURCE_DEFAULT
157 : nErrorArea
== ErrCodeArea::Svx
? SOURCE_SVX
: SOURCE_UUI
;
159 std::locale aResLocale
= Translate::Create(aManager
[eSource
]);
160 ErrorResource
aErrorResource(aId
[eSource
], aResLocale
);
161 if (!aErrorResource
.getString(nErrorCode
, aMessage
))
165 aMessage
= replaceMessageWithArguments( aMessage
, rArguments
);
167 if (bObtainErrorStringOnly
)
169 rErrorString
= aMessage
;
174 //TODO! It can happen that the buttons calculated below do not match
175 // the error text from the resource (e.g., some text that is not a
176 // question, but YES and NO buttons). Some error texts have
177 // ExtraData that specifies a set of buttons, but that data is not
178 // really useful, because a single error text may well make sense
179 // both with only an OK button and with RETRY and CANCEL buttons.
181 uno::Reference
< task::XInteractionApprove
> xApprove
;
182 uno::Reference
< task::XInteractionDisapprove
> xDisapprove
;
183 uno::Reference
< task::XInteractionRetry
> xRetry
;
184 uno::Reference
< task::XInteractionAbort
> xAbort
;
186 rContinuations
, &xApprove
, &xDisapprove
, &xRetry
, &xAbort
);
188 // The following mapping uses the bit mask
194 // The mapping has five properties on which the code to select the
195 // correct continuation relies:
196 // 1 The OK button is mapped to Approve if that is available,
197 // otherwise to Abort if that is available, otherwise to none.
198 // 2 The CANCEL button is always mapped to Abort.
199 // 3 The RETRY button is always mapped to Retry.
200 // 4 The NO button is always mapped to Disapprove.
201 // 5 The YES button is always mapped to Approve.
203 // Because the WinBits button combinations are quite restricted, not
204 // every request can be served here.
206 // Finally, it seems to be better to leave default button
207 // determination to VCL (the favouring of CANCEL as default button
208 // seems to not always be what the user wants)...
209 MessageBoxStyle
const aButtonMask
[16]
210 = { MessageBoxStyle::NONE
,
211 MessageBoxStyle::Ok
/*| MessBoxStyle::DefaultOk*/, // Abort
212 MessageBoxStyle::NONE
,
213 MessageBoxStyle::RetryCancel
/*| MessBoxStyle::DefaultCancel*/, // Retry, Abort
214 MessageBoxStyle::NONE
,
215 MessageBoxStyle::NONE
,
216 MessageBoxStyle::NONE
,
217 MessageBoxStyle::NONE
,
218 MessageBoxStyle::Ok
/*| MessBoxStyle::DefaultOk*/, // Approve
219 MessageBoxStyle::OkCancel
/*| MessBoxStyle::DefaultCancel*/, // Approve, Abort
220 MessageBoxStyle::NONE
,
221 MessageBoxStyle::NONE
,
222 MessageBoxStyle::YesNo
/*| MessBoxStyle::DefaultNo*/, // Approve, Disapprove
223 MessageBoxStyle::YesNoCancel
/*| MessBoxStyle::DefaultCancel*/,
224 // Approve, Disapprove, Abort
225 MessageBoxStyle::NONE
,
226 MessageBoxStyle::NONE
};
228 MessageBoxStyle nButtonMask
= aButtonMask
[(xApprove
.is() ? 8 : 0)
229 | (xDisapprove
.is() ? 4 : 0)
230 | (xRetry
.is() ? 2 : 0)
231 | (xAbort
.is() ? 1 : 0)];
232 if (nButtonMask
== MessageBoxStyle::NONE
)
235 //TODO! remove this backwards compatibility?
236 OUString
aContext(m_aContextParam
);
237 if (aContext
.isEmpty() && nErrorCode
!= ERRCODE_NONE
)
239 SolarMutexGuard aGuard
;
240 ErrorContext
* pContext
= ErrorContext::GetContext();
243 OUString aContextString
;
244 if (pContext
->GetString(nErrorCode
, aContextString
))
245 aContext
= aContextString
;
249 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
250 DialogMask nResult
= executeErrorDialog(Application::GetFrameWeld(xParent
),
251 eClassification
, aContext
, aMessage
, nButtonMask
);
255 case DialogMask::ButtonsOk
:
256 OSL_ENSURE(xApprove
.is() || xAbort
.is(), "unexpected situation");
259 else if (xAbort
.is())
263 case DialogMask::ButtonsCancel
:
264 OSL_ENSURE(xAbort
.is(), "unexpected situation");
269 case DialogMask::ButtonsRetry
:
270 OSL_ENSURE(xRetry
.is(), "unexpected situation");
275 case DialogMask::ButtonsNo
:
276 OSL_ENSURE(xDisapprove
.is(), "unexpected situation");
277 if (xDisapprove
.is())
278 xDisapprove
->select();
281 case DialogMask::ButtonsYes
:
282 OSL_ENSURE(xApprove
.is(), "unexpected situation");
293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */