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 <unotools/resmgr.hxx>
32 #include <osl/diagnose.h>
33 #include <rtl/ustrbuf.hxx>
36 #include "getcontinuations.hxx"
41 using namespace com::sun::star
;
45 enum class MessageBoxStyle
{
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())
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()));
78 case task::InteractionClassification_WARNING
:
79 xBox
.reset(Application::CreateMessageDialog(pParent
,
80 VclMessageType::Warning
, VclButtonsType::NONE
, aText
.makeStringAndClear()));
82 case task::InteractionClassification_INFO
:
83 xBox
.reset(Application::CreateMessageDialog(pParent
,
84 VclMessageType::Info
, VclButtonsType::NONE
, aText
.makeStringAndClear()));
86 case task::InteractionClassification_QUERY
:
87 xBox
.reset(Application::CreateMessageDialog(pParent
,
88 VclMessageType::Question
, VclButtonsType::NONE
, aText
.makeStringAndClear()));
98 case MessageBoxStyle::NONE
:
100 case MessageBoxStyle::Ok
:
101 xBox
->add_button(GetStandardText(StandardButtonType::OK
), static_cast<int>(DialogMask::ButtonsOk
));
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
));
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
));
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
));
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
));
122 return static_cast<DialogMask
>(xBox
->run());
128 UUIInteractionHelper::handleErrorHandlerRequest(
129 task::InteractionClassification eClassification
,
131 std::vector
< OUString
> const & rArguments
,
132 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
134 bool bObtainErrorStringOnly
,
135 bool & bHasErrorString
,
136 OUString
& rErrorString
)
138 if (bObtainErrorStringOnly
)
140 bHasErrorString
= isInformationalErrorMessageRequest(rContinuations
);
141 if (!bHasErrorString
)
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]
153 ErrCodeArea nErrorArea
= nErrorCode
.GetArea();
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
))
164 aMessage
= replaceMessageWithArguments( aMessage
, rArguments
);
166 if (bObtainErrorStringOnly
)
168 rErrorString
= aMessage
;
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
;
185 rContinuations
, &xApprove
, &xDisapprove
, &xRetry
, &xAbort
);
187 // The following mapping uses the bit mask
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
)
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();
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
);
254 case DialogMask::ButtonsOk
:
255 OSL_ENSURE(xApprove
.is() || xAbort
.is(), "unexpected situation");
258 else if (xAbort
.is())
262 case DialogMask::ButtonsCancel
:
263 OSL_ENSURE(xAbort
.is(), "unexpected situation");
268 case DialogMask::ButtonsRetry
:
269 OSL_ENSURE(xRetry
.is(), "unexpected situation");
274 case DialogMask::ButtonsNo
:
275 OSL_ENSURE(xDisapprove
.is(), "unexpected situation");
276 if (xDisapprove
.is())
277 xDisapprove
->select();
280 case DialogMask::ButtonsYes
:
281 OSL_ENSURE(xApprove
.is(), "unexpected situation");
292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */