VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/globals/UIErrorString.cpp@ 96430

Last change on this file since 96430 was 96430, checked in by vboxsync, 20 months ago

FE/Qt: A bunch of NLS fixes across the GUI #3; Preparing for BETA NLS update.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 KB
Line 
1/* $Id: UIErrorString.cpp 96430 2022-08-23 08:37:08Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIErrorString class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QApplication>
30#include <QObject>
31#include <QPalette>
32
33/* GUI includes: */
34#include "UICommon.h"
35#include "UIErrorString.h"
36#include "UITranslator.h"
37
38/* COM includes: */
39#include "COMDefs.h"
40#include "CProgress.h"
41#include "CVirtualBoxErrorInfo.h"
42
43
44/* static */
45QString UIErrorString::formatRC(HRESULT rc)
46{
47 /** @todo r=bird: Not sure why we set the sign bit 31 bit for warnings.
48 * Maybe to try get the error variant? It won't really work for S_FALSE and
49 * probably a bunch of others too. I've modified it on windows to try get
50 * the exact one, the one with the top bit set, or just the value. */
51#ifdef RT_OS_WINDOWS
52 char szDefine[80];
53 if ( !SUCCEEDED_WARNING(rc)
54 || ( RTErrWinQueryDefine(rc, szDefine, sizeof(szDefine), true /*fFailIfUnknown*/) == VERR_NOT_FOUND
55 && RTErrWinQueryDefine(rc | 0x80000000, szDefine, sizeof(szDefine), true /*fFailIfUnknown*/) == VERR_NOT_FOUND))
56 RTErrWinQueryDefine(rc, szDefine, sizeof(szDefine), false /*fFailIfUnknown*/);
57
58 QString str;
59 str.sprintf("%s", szDefine);
60 return str;
61#else
62 const char *pszDefine = RTErrCOMGet(SUCCEEDED_WARNING(rc) ? rc | 0x80000000 : rc)->pszDefine;
63 Assert(pszDefine);
64
65 return QString(pszDefine);
66#endif
67}
68
69/* static */
70QString UIErrorString::formatRCFull(HRESULT rc)
71{
72 /** @todo r=bird: See UIErrorString::formatRC for 31th bit discussion. */
73 char szHex[32];
74 RTStrPrintf(szHex, sizeof(szHex), "%#010X", rc);
75
76#ifdef RT_OS_WINDOWS
77 char szDefine[80];
78 ssize_t cchRet = RTErrWinQueryDefine(rc, szDefine, sizeof(szDefine), true /*fFailIfUnknown*/);
79 if (cchRet == VERR_NOT_FOUND && SUCCEEDED_WARNING(rc))
80 cchRet = RTErrWinQueryDefine(rc | 0x80000000, szDefine, sizeof(szDefine), true /*fFailIfUnknown*/);
81
82 if (cchRet != VERR_NOT_FOUND)
83 return QString(szDefine).append(" (").append(szHex).append(")");
84#else
85 const char *pszDefine = RTErrCOMGet(SUCCEEDED_WARNING(rc) ? rc | 0x80000000 : rc)->pszDefine;
86 Assert(pszDefine);
87
88 if (strncmp(pszDefine, RT_STR_TUPLE("Unknown ")))
89 return QString(pszDefine).append(" (").append(szHex).append(")");
90#endif
91 return QString(szHex);
92}
93
94/* static */
95QString UIErrorString::formatErrorInfo(const CProgress &comProgress)
96{
97 /* Check for API errors first: */
98 if (!comProgress.isOk())
99 return formatErrorInfo(static_cast<COMBaseWithEI>(comProgress));
100
101 /* For progress errors otherwise: */
102 CVirtualBoxErrorInfo comErrorInfo = comProgress.GetErrorInfo();
103 /* Handle valid error-info first: */
104 if (!comErrorInfo.isNull())
105 return formatErrorInfo(comErrorInfo);
106 /* Handle NULL error-info otherwise: */
107 return QString("<table bgcolor=%1 border=0 cellspacing=5 cellpadding=0 width=100%>"
108 "<tr><td>%2</td><td><tt>%3</tt></td></tr></table>")
109 .arg(QApplication::palette().color(QPalette::Active, QPalette::Window).name(QColor::HexRgb))
110 .arg(QApplication::translate("UIErrorString", "Result&nbsp;Code:", "error info"))
111 .arg(formatRCFull(comProgress.GetResultCode()))
112 .prepend("<!--EOM-->") /* move to details */;
113}
114
115/* static */
116QString UIErrorString::formatErrorInfo(const COMErrorInfo &comInfo, HRESULT wrapperRC /* = S_OK */)
117{
118 return QString("<qt>%1</qt>").arg(UIErrorString::errorInfoToString(comInfo, wrapperRC));
119}
120
121/* static */
122QString UIErrorString::formatErrorInfo(const CVirtualBoxErrorInfo &comInfo)
123{
124 return formatErrorInfo(COMErrorInfo(comInfo));
125}
126
127/* static */
128QString UIErrorString::formatErrorInfo(const COMBaseWithEI &comWrapper)
129{
130 Assert(comWrapper.lastRC() != S_OK);
131 return formatErrorInfo(comWrapper.errorInfo(), comWrapper.lastRC());
132}
133
134/* static */
135QString UIErrorString::formatErrorInfo(const COMResult &comRc)
136{
137 Assert(comRc.rc() != S_OK);
138 return formatErrorInfo(comRc.errorInfo(), comRc.rc());
139}
140
141/* static */
142QString UIErrorString::simplifiedErrorInfo(const COMErrorInfo &comInfo, HRESULT wrapperRC /* = S_OK */)
143{
144 return UIErrorString::errorInfoToSimpleString(comInfo, wrapperRC);
145}
146
147/* static */
148QString UIErrorString::simplifiedErrorInfo(const COMBaseWithEI &comWrapper)
149{
150 Assert(comWrapper.lastRC() != S_OK);
151 return simplifiedErrorInfo(comWrapper.errorInfo(), comWrapper.lastRC());
152}
153
154/* static */
155QString UIErrorString::errorInfoToString(const COMErrorInfo &comInfo, HRESULT wrapperRC)
156{
157 /* Compose complex details string with internal <!--EOM--> delimiter to
158 * make it possible to split string into info & details parts which will
159 * be used separately in QIMessageBox. */
160 QString strFormatted;
161
162 /* Check if details text is NOT empty: */
163 const QString strDetailsInfo = comInfo.text();
164 if (!strDetailsInfo.isEmpty())
165 {
166 /* Check if details text written in English (latin1) and translated: */
167 if ( strDetailsInfo == QString::fromLatin1(strDetailsInfo.toLatin1())
168 && strDetailsInfo != QObject::tr(strDetailsInfo.toLatin1().constData()))
169 strFormatted += QString("<p>%1.</p>").arg(UITranslator::emphasize(QObject::tr(strDetailsInfo.toLatin1().constData())));
170 else
171 strFormatted += QString("<p>%1.</p>").arg(UITranslator::emphasize(strDetailsInfo));
172 }
173
174 strFormatted += QString("<!--EOM--><table bgcolor=%1 border=0 cellspacing=5 cellpadding=0 width=100%>")
175 .arg(QApplication::palette().color(QPalette::Active, QPalette::Window).name(QColor::HexRgb));
176
177 bool fHaveResultCode = false;
178
179 if (comInfo.isBasicAvailable())
180 {
181#ifdef VBOX_WS_WIN
182 fHaveResultCode = comInfo.isFullAvailable();
183 bool fHaveComponent = true;
184 bool fHaveInterfaceID = true;
185#else /* !VBOX_WS_WIN */
186 fHaveResultCode = true;
187 bool fHaveComponent = comInfo.isFullAvailable();
188 bool fHaveInterfaceID = comInfo.isFullAvailable();
189#endif
190
191 if (fHaveResultCode)
192 {
193 strFormatted += QString("<tr><td>%1</td><td><tt>%2</tt></td></tr>")
194 .arg(QApplication::translate("UIErrorString", "Result&nbsp;Code:", "error info"))
195 .arg(formatRCFull(comInfo.resultCode()));
196 }
197
198 if (fHaveComponent)
199 strFormatted += QString("<tr><td>%1</td><td>%2</td></tr>")
200 .arg(QApplication::translate("UIErrorString", "Component:", "error info"), comInfo.component());
201
202 if (fHaveInterfaceID)
203 {
204 QString s = comInfo.interfaceID().toString();
205 if (!comInfo.interfaceName().isEmpty())
206 s = comInfo.interfaceName() + ' ' + s;
207 strFormatted += QString("<tr><td>%1</td><td>%2</td></tr>")
208 .arg(QApplication::translate("UIErrorString", "Interface:", "error info"), s);
209 }
210
211 if (!comInfo.calleeIID().isNull() && comInfo.calleeIID() != comInfo.interfaceID())
212 {
213 QString s = comInfo.calleeIID().toString();
214 if (!comInfo.calleeName().isEmpty())
215 s = comInfo.calleeName() + ' ' + s;
216 strFormatted += QString("<tr><td>%1</td><td>%2</td></tr>")
217 .arg(QApplication::translate("UIErrorString", "Callee:", "error info"), s);
218 }
219 }
220
221 if ( FAILED(wrapperRC)
222 && (!fHaveResultCode || wrapperRC != comInfo.resultCode()))
223 {
224 strFormatted += QString("<tr><td>%1</td><td><tt>%2</tt></td></tr>")
225 .arg(QApplication::translate("UIErrorString", "Callee&nbsp;RC:", "error info"))
226 .arg(formatRCFull(wrapperRC));
227 }
228
229 strFormatted += "</table>";
230
231 if (comInfo.next())
232 strFormatted = strFormatted + "<!--EOP-->" + errorInfoToString(*comInfo.next());
233
234 return strFormatted;
235}
236
237/* static */
238QString UIErrorString::errorInfoToSimpleString(const COMErrorInfo &comInfo, HRESULT wrapperRC /* = S_OK */)
239{
240 /* Compose complex details string with text and status code: */
241 QString strFormatted;
242
243 /* Check if details text is NOT empty: */
244 const QString strDetailsInfo = comInfo.text();
245 if (!strDetailsInfo.isEmpty())
246 strFormatted += strDetailsInfo;
247
248 /* Check if we have result code: */
249 bool fHaveResultCode = false;
250
251 if (comInfo.isBasicAvailable())
252 {
253#ifdef VBOX_WS_WIN
254 fHaveResultCode = comInfo.isFullAvailable();
255#else
256 fHaveResultCode = true;
257#endif
258
259 if (fHaveResultCode)
260 strFormatted += "; " + QString("Result Code: ") + formatRCFull(comInfo.resultCode());
261 }
262
263 if ( FAILED(wrapperRC)
264 && (!fHaveResultCode || wrapperRC != comInfo.resultCode()))
265 strFormatted += "; " + QString("Callee RC: ") + formatRCFull(wrapperRC);
266
267 /* Check if we have next error queued: */
268 if (comInfo.next())
269 strFormatted += "; " + errorInfoToSimpleString(*comInfo.next());
270
271 return strFormatted;
272}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use