LibreOffice Module vcl (master) 1
errinf.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <osl/diagnose.h>
21#include <sal/log.hxx>
22
23#include <tools/debug.hxx>
24#include <utility>
25#include <vcl/errinf.hxx>
26
27#include <algorithm>
28#include <vector>
29
30class ErrorHandler;
31
32namespace {
33
34 ErrorRegistry& GetErrorRegistry()
35 {
36 static ErrorRegistry gErrorRegistry;
37 return gErrorRegistry;
38 }
39
40}
41
42bool ErrorStringFactory::CreateString(const ErrorInfo* pInfo, OUString& rStr)
43{
44 for(const ErrorHandler *pHdlr : GetErrorRegistry().errorHandlers)
45 {
46 if(pHdlr->CreateString(pInfo, rStr))
47 return true;
48 }
49 return false;
50}
51
53 : pDsp(nullptr)
54 , bIsWindowDsp(false)
55 , m_bLock(false)
56 , nNextError(0)
57{
59 rp = nullptr;
60}
61
63{
64 ErrorRegistry &rData = GetErrorRegistry();
65 rData.bIsWindowDsp = false;
66 rData.pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
67}
68
70{
71 ErrorRegistry &rData = GetErrorRegistry();
72 rData.bIsWindowDsp = true;
73 rData.pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
74}
75
76void ErrorRegistry::SetLock(bool bLock)
77{
78 ErrorRegistry& rData = GetErrorRegistry();
79 rData.m_bLock = bLock;
80}
81
83{
84 ErrorRegistry& rData = GetErrorRegistry();
85 return rData.m_bLock;
86}
87
89{
90 ErrorRegistry &rData = GetErrorRegistry();
91 rData = ErrorRegistry();
92}
93
94static void aDspFunc(const OUString &rErr, const OUString &rAction)
95{
96 SAL_WARN("vcl", "Action: " << rAction << " Error: " << rErr);
97}
98
100{
101 ErrorRegistry &rData = GetErrorRegistry();
102 rData.errorHandlers.insert(rData.errorHandlers.begin(), this);
103
104 if(!rData.pDsp)
106}
107
109{
110 auto &rErrorHandlers = GetErrorRegistry().errorHandlers;
111 rErrorHandlers.erase( ::std::remove(rErrorHandlers.begin(), rErrorHandlers.end(), this),
112 rErrorHandlers.end());
113}
114
115bool ErrorHandler::GetErrorString(ErrCode nErrCodeId, OUString& rErrStr)
116{
117 OUString aErr;
118
119 if(!nErrCodeId || nErrCodeId == ERRCODE_ABORT)
120 return false;
121
122 std::unique_ptr<ErrorInfo> pInfo = ErrorInfo::GetErrorInfo(nErrCodeId);
123
124 if (ErrorStringFactory::CreateString(pInfo.get(),aErr))
125 {
126 rErrStr = aErr;
127 return true;
128 }
129
130 return false;
131}
132
134{
135 if (nErrCodeId == ERRCODE_NONE || nErrCodeId == ERRCODE_ABORT)
136 return DialogMask::NONE;
137
138 ErrorRegistry &rData = GetErrorRegistry();
139 std::unique_ptr<ErrorInfo> pInfo = ErrorInfo::GetErrorInfo(nErrCodeId);
140 OUString aAction;
141
142 if (!rData.contexts.empty())
143 {
144 rData.contexts.front()->GetString(pInfo->GetErrorCode(), aAction);
145
146 for(ErrorContext *pCtx : rData.contexts)
147 {
148 if(pCtx->GetParent())
149 {
150 pParent = pCtx->GetParent();
151 break;
152 }
153 }
154 }
155
156 bool bWarning = nErrCodeId.IsWarning();
158 if (bWarning)
159 nErrFlags |= DialogMask::MessageWarning;
160 else
161 nErrFlags |= DialogMask::MessageError;
162
163 DynamicErrorInfo* pDynPtr = dynamic_cast<DynamicErrorInfo*>(pInfo.get());
164 if(pDynPtr)
165 {
166 DialogMask nDynFlags = pDynPtr->GetDialogMask();
167 if( nDynFlags != DialogMask::NONE )
168 nErrFlags = nDynFlags;
169 }
170
171 OUString aErr;
172 if (ErrorStringFactory::CreateString(pInfo.get(), aErr))
173 {
174 if (!rData.pDsp || rData.m_bLock)
175 {
176 SAL_WARN( "vcl", "Action: " << aAction << "Error: " << aErr);
177 }
178 else
179 {
180 if(!rData.bIsWindowDsp)
181 {
182 (*reinterpret_cast<BasicDisplayErrorFunc*>(rData.pDsp))(aErr,aAction);
183 return DialogMask::NONE;
184 }
185 else
186 {
187 if (nFlags != DialogMask::MAX)
188 nErrFlags = nFlags;
189
190 return (*reinterpret_cast<WindowDisplayErrorFunc*>(rData.pDsp))(
191 pParent, nErrFlags, aErr, aAction);
192 }
193 }
194 }
195
196 SAL_WARN( "vcl", "Error not handled " << pInfo->GetErrorCode());
197 // Error 1 (ERRCODE_ABORT) is classified as a General Error in sfx
198 if (pInfo->GetErrorCode() != ERRCODE_ABORT)
200 else
201 OSL_FAIL("ERRCODE_ABORT not handled");
202
203 return DialogMask::NONE;
204}
205
207{
209};
210
212 : pImpl( new ImplErrorContext )
213{
214 pImpl->pWin = pWinP;
215 GetErrorRegistry().contexts.insert(GetErrorRegistry().contexts.begin(), this);
216}
217
219{
220 auto &rContexts = GetErrorRegistry().contexts;
221 rContexts.erase( ::std::remove(rContexts.begin(), rContexts.end(), this), rContexts.end());
222}
223
225{
226 return GetErrorRegistry().contexts.empty() ? nullptr : GetErrorRegistry().contexts.front();
227}
228
230{
231 return pImpl ? pImpl->pWin : nullptr;
232}
233
235{
236 friend class DynamicErrorInfo;
237 friend class ErrorInfo;
238
239private:
241 : nMask(nInMask)
242 {
243 }
245 static void UnRegisterError(DynamicErrorInfo const *);
246 static std::unique_ptr<ErrorInfo> GetDynamicErrorInfo(ErrCode nId);
247
250
251};
252
254{
255 // Register dynamic identifier
256 ErrorRegistry& rData = GetErrorRegistry();
257 nErrId = ErrCode(((sal_uInt32(rData.nNextError) + 1) << ERRCODE_DYNAMIC_SHIFT) +
258 sal_uInt32(pDynErrInfo->GetErrorCode()));
259
260 if(rData.ppDynErrInfo[rData.nNextError])
261 delete rData.ppDynErrInfo[rData.nNextError];
262
263 rData.ppDynErrInfo[rData.nNextError] = pDynErrInfo;
264
266 rData.nNextError=0;
267}
268
270{
271 DynamicErrorInfo **ppDynErrInfo = GetErrorRegistry().ppDynErrInfo;
272 sal_uInt32 nIdx = ErrCode(*pDynErrInfo).GetDynamic() - 1;
273 DBG_ASSERT(ppDynErrInfo[nIdx] == pDynErrInfo, "ErrHdl: Error not found");
274
275 if(ppDynErrInfo[nIdx]==pDynErrInfo)
276 ppDynErrInfo[nIdx]=nullptr;
277}
278
280{
281 sal_uInt32 nIdx = nId.GetDynamic() - 1;
282 DynamicErrorInfo* pDynErrInfo = GetErrorRegistry().ppDynErrInfo[nIdx];
283
284 if(pDynErrInfo && ErrCode(*pDynErrInfo)==nId)
285 return std::unique_ptr<ErrorInfo>(pDynErrInfo);
286 else
287 return std::make_unique<ErrorInfo>(nId.StripDynamic());
288}
289
290std::unique_ptr<ErrorInfo> ErrorInfo::GetErrorInfo(ErrCode nId)
291{
292 if(nId.IsDynamic())
294 else
295 return std::make_unique<ErrorInfo>(nId);
296}
297
299{
300}
301
303: ErrorInfo(nArgUserId),
304 pImpl(new ImplDynamicErrorInfo(nMask))
305{
306 pImpl->RegisterError(this);
307}
308
310{
312}
313
314DynamicErrorInfo::operator ErrCode() const
315{
316 return pImpl->nErrId;
317}
318
320{
321 return pImpl->nMask;
322}
323
325 ErrCode nArgUserId, OUString aStringP, DialogMask nMask)
326: DynamicErrorInfo(nArgUserId, nMask), aString(std::move(aStringP))
327{
328}
329
330/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< ImplDynamicErrorInfo > pImpl
Definition: errinf.hxx:174
DialogMask GetDialogMask() const
Definition: errinf.cxx:319
DynamicErrorInfo(ErrCode nUserId, DialogMask nMask)
Definition: errinf.cxx:302
virtual ~DynamicErrorInfo() override
Definition: errinf.cxx:309
bool IsWarning() const
sal_uInt32 GetDynamic() const
virtual ~ErrorContext()
Definition: errinf.cxx:218
ErrorContext(weld::Window *pWin)
Definition: errinf.cxx:211
static ErrorContext * GetContext()
Definition: errinf.cxx:224
std::unique_ptr< ImplErrorContext > pImpl
Definition: errinf.hxx:224
weld::Window * GetParent()
Definition: errinf.cxx:229
static bool GetErrorString(ErrCode nId, OUString &rStr)
Definition: errinf.cxx:115
static DialogMask HandleError(ErrCode nId, weld::Window *pParent=nullptr, DialogMask nMask=DialogMask::MAX)
Handles an error.
Definition: errinf.cxx:133
virtual ~ErrorHandler()
Definition: errinf.cxx:108
ErrorHandler()
Definition: errinf.cxx:99
virtual ~ErrorInfo()
Definition: errinf.cxx:298
ErrCode const & GetErrorCode() const
Definition: errinf.hxx:154
static std::unique_ptr< ErrorInfo > GetErrorInfo(ErrCode)
Definition: errinf.cxx:290
bool bIsWindowDsp
Definition: errinf.hxx:77
std::vector< ErrorHandler * > errorHandlers
Definition: errinf.hxx:83
static void Reset()
Definition: errinf.cxx:88
DynamicErrorInfo * ppDynErrInfo[ERRCODE_DYNAMIC_COUNT]
Definition: errinf.hxx:86
static void RegisterDisplay(BasicDisplayErrorFunc *)
Definition: errinf.cxx:62
static void SetLock(bool bLock)
Definition: errinf.cxx:76
bool m_bLock
Definition: errinf.hxx:79
DisplayFnPtr pDsp
Definition: errinf.hxx:76
sal_uInt16 nNextError
Definition: errinf.hxx:81
static bool GetLock()
Definition: errinf.cxx:82
std::vector< ErrorContext * > contexts
Definition: errinf.hxx:84
static bool CreateString(const ErrorInfo *, OUString &)
Definition: errinf.cxx:42
void RegisterError(DynamicErrorInfo *)
Definition: errinf.cxx:253
static void UnRegisterError(DynamicErrorInfo const *)
Definition: errinf.cxx:269
static std::unique_ptr< ErrorInfo > GetDynamicErrorInfo(ErrCode nId)
Definition: errinf.cxx:279
DialogMask nMask
Definition: errinf.cxx:249
ImplDynamicErrorInfo(DialogMask nInMask)
Definition: errinf.cxx:240
StringErrorInfo(ErrCode nUserId, OUString aStringP, DialogMask nMask=DialogMask::NONE)
Definition: errinf.cxx:324
#define DBG_ASSERT(sCon, aError)
#define ERRCODE_DYNAMIC_SHIFT
#define ERRCODE_DYNAMIC_COUNT
#define ERRCODE_ABORT
#define ERRCODE_NONE
static void aDspFunc(const OUString &rErr, const OUString &rAction)
Definition: errinf.cxx:94
DialogMask WindowDisplayErrorFunc(weld::Window *, DialogMask eMask, const OUString &rErr, const OUString &rAction)
Definition: errinf.hxx:51
void BasicDisplayErrorFunc(const OUString &rErr, const OUString &rAction)
Definition: errinf.hxx:54
DialogMask
Definition: errinf.hxx:90
void(* DisplayFnPtr)()
Definition: errinf.hxx:49
#define SAL_WARN(area, stream)
sal_Int16 nId
weld::Window * pWin
Definition: errinf.cxx:208