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 .
21 #include <tools/shl.hxx>
22 #include <tools/debug.hxx>
23 #include <tools/errinf.hxx>
24 #include <tools/string.hxx>
25 #include <rtl/strbuf.hxx>
30 typedef void (* DisplayFnPtr
)();
36 ErrorHandler
*pFirstHdl
;
37 ErrorContext
*pFirstCtx
;
39 sal_Bool bIsWindowDsp
;
41 DynamicErrorInfo
*ppDcr
[ERRCODE_DYNAMIC_COUNT
];
45 static EDcrData
*GetData();
53 void RegisterEDcr(DynamicErrorInfo
*);
54 void UnRegisterEDcr(DynamicErrorInfo
*);
55 static ErrorInfo
*GetDynamicErrorInfo(sal_uIntPtr lId
);
57 friend class DynamicErrorInfo
;
58 friend class ErrorInfo
;
63 for(sal_uInt16 n
=0;n
<ERRCODE_DYNAMIC_COUNT
;n
++)
71 EDcrData
*EDcrData::GetData()
76 EDcrData
**ppDat
=(EDcrData
**)GetAppData(SHL_ERR
);
79 return (*ppDat
=new EDcrData
);
86 void EDcr_Impl::RegisterEDcr(DynamicErrorInfo
*pDcr
)
88 // Register dynamic identifier
89 EDcrData
* pData
=EDcrData::GetData();
90 lErrId
= (((sal_uIntPtr
)pData
->nNextDcr
+ 1) << ERRCODE_DYNAMIC_SHIFT
) +
92 DynamicErrorInfo
**ppDcr
=pData
->ppDcr
;
93 sal_uInt16 nNext
=pData
->nNextDcr
;
100 if(++pData
->nNextDcr
>=ERRCODE_DYNAMIC_COUNT
)
104 void EDcr_Impl::UnRegisterEDcr(DynamicErrorInfo
*pDcr
)
107 EDcrData
* pData
=EDcrData::GetData();
108 DynamicErrorInfo
**ppDcr
=pData
->ppDcr
;
110 ((sal_uIntPtr
)(*pDcr
) & ERRCODE_DYNAMIC_MASK
)>>ERRCODE_DYNAMIC_SHIFT
)-1;
111 DBG_ASSERT(ppDcr
[lIdx
]==pDcr
,"ErrHdl: Error nicht gefunden");
112 if(ppDcr
[lIdx
]==pDcr
)
116 TYPEINIT0(ErrorInfo
);
117 TYPEINIT1(DynamicErrorInfo
, ErrorInfo
);
118 TYPEINIT1(StringErrorInfo
, DynamicErrorInfo
);
119 TYPEINIT1(TwoStringErrorInfo
, DynamicErrorInfo
);
120 TYPEINIT1(MessageInfo
, DynamicErrorInfo
);
122 ErrorInfo
*ErrorInfo::GetErrorInfo(sal_uIntPtr lId
)
124 if(lId
& ERRCODE_DYNAMIC_MASK
)
125 return EDcr_Impl::GetDynamicErrorInfo(lId
);
127 return new ErrorInfo(lId
);
130 DynamicErrorInfo::operator sal_uIntPtr() const
132 return pImpl
->lErrId
;
135 DynamicErrorInfo::DynamicErrorInfo(sal_uIntPtr lArgUserId
, sal_uInt16 nMask
)
136 : ErrorInfo(lArgUserId
)
139 pImpl
->RegisterEDcr(this);
143 DynamicErrorInfo::~DynamicErrorInfo()
145 pImpl
->UnRegisterEDcr(this);
149 ErrorInfo
* EDcr_Impl::GetDynamicErrorInfo(sal_uIntPtr lId
)
151 sal_uIntPtr lIdx
=((lId
& ERRCODE_DYNAMIC_MASK
)>>ERRCODE_DYNAMIC_SHIFT
)-1;
152 DynamicErrorInfo
* pDcr
=EDcrData::GetData()->ppDcr
[lIdx
];
153 if(pDcr
&& (sal_uIntPtr
)(*pDcr
)==lId
)
156 return new ErrorInfo(lId
& ~ERRCODE_DYNAMIC_MASK
);
159 sal_uInt16
DynamicErrorInfo::GetDialogMask() const
164 StringErrorInfo::StringErrorInfo(
165 sal_uIntPtr UserId
, const OUString
& aStringP
, sal_uInt16 nFlags
)
166 : DynamicErrorInfo(UserId
, nFlags
), aString(aStringP
)
174 static sal_Bool
CreateString(const ErrorHandler
*pStart
,
175 const ErrorInfo
*, OUString
&, sal_uInt16
&);
178 static void aDspFunc(const OUString
&rErr
, const OUString
&rAction
)
180 OStringBuffer
aErr("Aktion: ");
181 aErr
.append(OUStringToOString(rAction
, RTL_TEXTENCODING_ASCII_US
));
182 aErr
.append(" Fehler: ");
183 aErr
.append(OUStringToOString(rErr
, RTL_TEXTENCODING_ASCII_US
));
184 OSL_FAIL(aErr
.getStr());
187 ErrorContext::ErrorContext(Window
*pWinP
)
189 EDcrData
*pData
=EDcrData::GetData();
190 ErrorContext
*&pHdl
=pData
->pFirstCtx
;
196 ErrorContext::~ErrorContext()
198 ErrorContext
**ppCtx
=&(EDcrData::GetData()->pFirstCtx
);
199 while(*ppCtx
&& *ppCtx
!=this)
200 ppCtx
=&((*ppCtx
)->pNext
);
202 *ppCtx
=(*ppCtx
)->pNext
;
205 ErrorContext
*ErrorContext::GetContext()
207 return EDcrData::GetData()->pFirstCtx
;
210 ErrorHandler::ErrorHandler()
212 pImpl
=new ErrHdl_Impl
;
213 EDcrData
*pData
=EDcrData::GetData();
214 ErrorHandler
*&pHdl
=pData
->pFirstHdl
;
218 RegisterDisplay(&aDspFunc
);
221 ErrorHandler::~ErrorHandler()
223 ErrorHandler
**ppHdl
=&(EDcrData::GetData()->pFirstHdl
);
224 while(*ppHdl
&& *ppHdl
!=this)
225 ppHdl
=&((*ppHdl
)->pImpl
->pNext
);
227 *ppHdl
=(*ppHdl
)->pImpl
->pNext
;
231 void ErrorHandler::RegisterDisplay(WindowDisplayErrorFunc
*aDsp
)
233 EDcrData
*pData
=EDcrData::GetData();
234 pData
->bIsWindowDsp
=sal_True
;
235 pData
->pDsp
= reinterpret_cast< DisplayFnPtr
>(aDsp
);
238 void ErrorHandler::RegisterDisplay(BasicDisplayErrorFunc
*aDsp
)
240 EDcrData
*pData
=EDcrData::GetData();
241 pData
->bIsWindowDsp
=sal_False
;
242 pData
->pDsp
= reinterpret_cast< DisplayFnPtr
>(aDsp
);
245 /** Handles an error.
247 If nFlags is not set, the DynamicErrorInfo flags or the
248 resource flags will be used.
254 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
257 @param nFlags error flags.
258 @param bJustCreateString ???
263 sal_uInt16
ErrorHandler::HandleError_Impl(
264 sal_uIntPtr lId
, sal_uInt16 nFlags
, sal_Bool bJustCreateString
, OUString
& rError
)
268 if(!lId
|| lId
== ERRCODE_ABORT
)
270 EDcrData
*pData
=EDcrData::GetData();
271 ErrorInfo
*pInfo
=ErrorInfo::GetErrorInfo(lId
);
272 ErrorContext
*pCtx
=ErrorContext::GetContext();
274 pCtx
->GetString(pInfo
->GetErrorCode(), aAction
);
276 // Remove parent from context
277 for(;pCtx
;pCtx
=pCtx
->pNext
)
278 if(pCtx
->GetParent())
280 pParent
=pCtx
->GetParent();
284 sal_Bool bWarning
= ((lId
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
);
285 sal_uInt16 nErrFlags
= ERRCODE_BUTTON_DEF_OK
| ERRCODE_BUTTON_OK
;
287 nErrFlags
|= ERRCODE_MSG_WARNING
;
289 nErrFlags
|= ERRCODE_MSG_ERROR
;
291 DynamicErrorInfo
* pDynPtr
=PTR_CAST(DynamicErrorInfo
,pInfo
);
294 sal_uInt16 nDynFlags
= pDynPtr
->GetDialogMask();
296 nErrFlags
= nDynFlags
;
299 if(ErrHdl_Impl::CreateString(pData
->pFirstHdl
,pInfo
,aErr
,nErrFlags
))
301 if (bJustCreateString
)
310 OStringBuffer
aStr("Action: ");
311 aStr
.append(OUStringToOString(aAction
, RTL_TEXTENCODING_ASCII_US
));
312 aStr
.append("\nFehler: ");
313 aStr
.append(OUStringToOString(aErr
, RTL_TEXTENCODING_ASCII_US
));
314 OSL_FAIL(aStr
.getStr());
319 if(!pData
->bIsWindowDsp
)
321 (*(BasicDisplayErrorFunc
*)pData
->pDsp
)(aErr
,aAction
);
326 if (nFlags
!= USHRT_MAX
)
328 return (*(WindowDisplayErrorFunc
*)pData
->pDsp
)(
329 pParent
, nErrFlags
, aErr
, aAction
);
334 OSL_FAIL("Error nicht behandelt");
335 // Error 1 is General Error in the Sfx
336 if(pInfo
->GetErrorCode()!=1)
338 HandleError_Impl(1, USHRT_MAX
, bJustCreateString
, rError
);
342 OSL_FAIL("Error 1 nicht gehandeled");
349 sal_Bool
ErrorHandler::GetErrorString(sal_uIntPtr lId
, OUString
& rStr
)
351 return (sal_Bool
)HandleError_Impl( lId
, USHRT_MAX
, sal_True
, rStr
);
354 /** Handles an error.
356 @see ErrorHandler::HandleError_Impl
358 sal_uInt16
ErrorHandler::HandleError(sal_uIntPtr lId
, sal_uInt16 nFlags
)
361 return HandleError_Impl( lId
, nFlags
, sal_False
, aDummy
);
364 sal_Bool
ErrHdl_Impl::CreateString( const ErrorHandler
*pStart
,
365 const ErrorInfo
* pInfo
, OUString
& pStr
,
368 for(const ErrorHandler
*pHdl
=pStart
;pHdl
;pHdl
=pHdl
->pImpl
->pNext
)
370 if(pHdl
->CreateString( pInfo
, pStr
, rFlags
))
376 sal_Bool
SimpleErrorHandler::CreateString(
377 const ErrorInfo
*pInfo
, OUString
&rStr
, sal_uInt16
&) const
379 sal_uIntPtr nId
= pInfo
->GetErrorCode();
380 OStringBuffer
aStr("Id ");
381 aStr
.append(static_cast<sal_Int32
>(nId
));
382 aStr
.append(" only handled by SimpleErrorHandler");
383 aStr
.append("\nErrorCode: ");
384 aStr
.append(static_cast<sal_Int32
>(
385 nId
& ((1L << ERRCODE_CLASS_SHIFT
) - 1 )));
386 aStr
.append("\nErrorClass: ");
387 aStr
.append(static_cast<sal_Int32
>(
388 (nId
& ERRCODE_CLASS_MASK
) >> ERRCODE_CLASS_SHIFT
));
389 aStr
.append("\nErrorArea: ");
390 aStr
.append(static_cast<sal_Int32
>((nId
& ERRCODE_ERROR_MASK
&
391 ~((1 << ERRCODE_AREA_SHIFT
) -1 ) ) >> ERRCODE_AREA_SHIFT
));
392 DynamicErrorInfo
*pDyn
=PTR_CAST(DynamicErrorInfo
,pInfo
);
395 aStr
.append("\nDId ");
396 aStr
.append(static_cast<sal_Int32
>(*pDyn
));
398 rStr
= OStringToOUString(aStr
.makeStringAndClear(),
399 RTL_TEXTENCODING_ASCII_US
);
403 SimpleErrorHandler::SimpleErrorHandler()
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */