tdf#154285 Check upper bound of arguments in SbRtl_Minute function
[LibreOffice.git] / svtools / source / misc / ehdl.cxx
blobe740055a65dff1a04438ea11e84cac2e420fc5e3
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 <unotools/resmgr.hxx>
21 #include <utility>
22 #include <vcl/stdtext.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/weld.hxx>
25 #include <sal/log.hxx>
27 #include <svtools/ehdl.hxx>
28 #include <svtools/svtresid.hxx>
29 #include <svtools/sfxecode.hxx>
30 #include <memory>
31 #include <errtxt.hrc>
33 static DialogMask aWndFunc(
34 weld::Window *pWin, // Parent of the dialog
35 DialogMask nFlags,
36 const OUString &rErr, // error text
37 const OUString &rAction) // action text
39 /* [Description]
41 Draw an errorbox on the screen. Depending on nFlags
42 Error/Info etc. boxes with the requested buttons are shown.
44 Returnvalue is the button pressed
50 SolarMutexGuard aGuard;
52 // determine necessary WinBits from the flags
53 VclButtonsType eButtonsType = VclButtonsType::NONE;
54 bool bAddRetry = false;
55 if ( (nFlags & (DialogMask::ButtonsCancel | DialogMask::ButtonsRetry)) == (DialogMask::ButtonsCancel | DialogMask::ButtonsRetry))
57 bAddRetry = true;
58 eButtonsType = VclButtonsType::Cancel;
60 else if ( (nFlags & DialogMask::ButtonsOk) == DialogMask::ButtonsOk )
61 eButtonsType = VclButtonsType::Ok;
62 else if ( (nFlags & DialogMask::ButtonsYesNo) == DialogMask::ButtonsYesNo )
63 eButtonsType = VclButtonsType::YesNo;
65 OUString aErr(u"$(ACTION)$(ERROR)"_ustr);
66 OUString aAction(rAction);
67 if ( !aAction.isEmpty() )
68 aAction += ":\n";
69 aErr = aErr.replaceAll("$(ACTION)", aAction);
70 aErr = aErr.replaceAll("$(ERROR)", rErr);
72 VclMessageType eMessageType;
73 switch (nFlags & DialogMask(0xf000))
75 case DialogMask::MessageError:
76 eMessageType = VclMessageType::Error;
77 break;
79 case DialogMask::MessageWarning:
80 eMessageType = VclMessageType::Warning;
81 break;
83 case DialogMask::MessageInfo:
84 eMessageType = VclMessageType::Info;
85 break;
87 default:
89 SAL_WARN( "svtools.misc", "no MessBox type");
90 return DialogMask::ButtonsOk;
94 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pWin,
95 eMessageType, eButtonsType, aErr));
97 if (bAddRetry)
98 xBox->add_button(GetStandardText(StandardButtonType::Retry), RET_RETRY);
100 switch(nFlags & DialogMask(0x0f00))
102 case DialogMask::ButtonDefaultsOk:
103 xBox->set_default_response(RET_OK);
104 break;
105 case DialogMask::ButtonDefaultsCancel:
106 xBox->set_default_response(RET_CANCEL);
107 break;
108 case DialogMask::ButtonDefaultsYes:
109 xBox->set_default_response(RET_YES);
110 break;
111 case DialogMask::ButtonDefaultsNo:
112 xBox->set_default_response(RET_NO);
113 break;
114 default:
115 break;
118 DialogMask nRet = DialogMask::NONE;
119 switch (xBox->run())
121 case RET_OK:
122 nRet = DialogMask::ButtonsOk;
123 break;
124 case RET_CANCEL:
125 nRet = DialogMask::ButtonsCancel;
126 break;
127 case RET_RETRY:
128 nRet = DialogMask::ButtonsRetry;
129 break;
130 case RET_YES:
131 nRet = DialogMask::ButtonsYes;
132 break;
133 case RET_NO:
134 nRet = DialogMask::ButtonsNo;
135 break;
136 default:
137 SAL_WARN( "svtools.misc", "Unknown MessBox return value" );
138 break;
141 return nRet;
144 SfxErrorHandler::SfxErrorHandler(const ErrMsgCode* pIdPs, ErrCodeArea lStartP, ErrCodeArea lEndP, const std::locale& rLocale)
145 : lStart(lStartP), lEnd(lEndP), pIds(pIdPs), aResLocale(rLocale)
147 ErrorRegistry::RegisterDisplay(&aWndFunc);
150 SfxErrorHandler::~SfxErrorHandler()
154 bool SfxErrorHandler::CreateString(const ErrCodeMsg& nErr, OUString &rStr) const
156 /* [Description]
158 Assemble error string for the ErrorInfo pErr.
163 ErrCode nErrCode(sal_uInt32(nErr.GetCode()) & ERRCODE_ERROR_MASK);
164 if (nErr.GetCode().GetArea() < lStart || lEnd < nErr.GetCode().GetArea())
165 return false;
166 if(GetErrorString(nErrCode, rStr))
168 if(!nErr.GetArg1().isEmpty())
169 rStr = rStr.replaceAll("$(ARG1)", nErr.GetArg1());
170 if(!nErr.GetArg2().isEmpty())
171 rStr = rStr.replaceAll("$(ARG2)", nErr.GetArg2());
172 return true;
174 return false;
177 void SfxErrorHandler::GetClassString(ErrCodeClass lClassId, OUString &rStr)
179 /* [Description]
181 Creates the string for the class of the error. Will always
182 be read from the resource of the Sfx.
187 for (const std::pair<TranslateId, ErrCodeClass>* pItem = RID_ERRHDL_CLASS; pItem->first; ++pItem)
189 if (pItem->second == lClassId)
191 rStr = SvtResId(pItem->first);
192 break;
197 bool SfxErrorHandler::GetErrorString(ErrCode lErrId, OUString &rStr) const
199 /* [Description]
201 Creates the error string for the actual error
202 without its class
207 bool bRet = false;
208 rStr = "$(CLASS)$(ERROR)";
210 for (const ErrMsgCode* pItem = pIds; pItem->second; ++pItem)
212 if (pItem->second.StripWarning() == lErrId.StripWarning())
214 rStr = rStr.replaceAll("$(ERROR)", Translate::get(pItem->first, aResLocale));
215 bRet = true;
216 break;
220 if( bRet )
222 OUString aErrStr;
223 GetClassString(lErrId.GetClass(), aErrStr);
224 if(!aErrStr.isEmpty())
225 aErrStr += ".\n";
226 rStr = rStr.replaceAll("$(CLASS)",aErrStr);
229 return bRet;
232 SfxErrorContext::SfxErrorContext(
233 sal_uInt16 nCtxIdP, weld::Window *pWindow, const ErrMsgCode* pIdsP, const std::locale& rResLocaleP)
234 : ErrorContext(pWindow), nCtxId(nCtxIdP), pIds(pIdsP), aResLocale(rResLocaleP)
236 if (!pIds)
237 pIds = RID_ERRCTX;
241 SfxErrorContext::SfxErrorContext(
242 sal_uInt16 nCtxIdP, OUString aArg1P, weld::Window *pWindow,
243 const ErrMsgCode* pIdsP, const std::locale& rResLocaleP)
244 : ErrorContext(pWindow), nCtxId(nCtxIdP), pIds(pIdsP), aResLocale(rResLocaleP),
245 aArg1(std::move(aArg1P))
247 if (!pIds)
248 pIds = RID_ERRCTX;
251 bool SfxErrorContext::GetString(const ErrCodeMsg& nErr, OUString &rStr)
253 /* [Description]
255 Constructs the description of an error context
259 bool bRet = false;
260 for (const ErrMsgCode* pItem = pIds; pItem->second; ++pItem)
262 if (sal_uInt32(pItem->second) == nCtxId)
264 rStr = Translate::get(pItem->first, aResLocale);
265 rStr = rStr.replaceAll("$(ARG1)", aArg1);
266 bRet = true;
267 break;
271 SAL_WARN_IF(!bRet, "svtools.misc", "ErrorContext cannot find the resource");
273 if ( bRet )
275 sal_uInt16 nId = nErr.IsWarning() ? ERRCTX_WARNING : ERRCTX_ERROR;
276 for (const ErrMsgCode* pItem = RID_ERRCTX; pItem->second; ++pItem)
278 if (sal_uInt32(pItem->second) == nId)
280 rStr = rStr.replaceAll("$(ERR)", Translate::get(pItem->first, aResLocale));
281 break;
286 // SfxInPlaceClient::DoVerb adds some extra info to report
287 if (bRet && nErr.GetCode() == ERRCODE_SO_GENERALERROR && !nErr.GetArg1().isEmpty())
288 rStr += "\n" + nErr.GetArg1();
290 return bRet;
293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */