1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: errinf.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
35 #include <tools/shl.hxx>
36 #include <tools/debug.hxx>
37 #include <tools/errinf.hxx>
38 #include <tools/string.hxx>
44 typedef void (* DisplayFnPtr
)();
52 ErrorHandler
*pFirstHdl
;
53 ErrorContext
*pFirstCtx
;
58 DynamicErrorInfo
*ppDcr
[ERRCODE_DYNAMIC_COUNT
];
62 static EDcrData
*GetData();
71 void RegisterEDcr(DynamicErrorInfo
*);
72 void UnRegisterEDcr(DynamicErrorInfo
*);
73 static ErrorInfo
*GetDynamicErrorInfo(ULONG lId
);
75 friend class DynamicErrorInfo
;
76 friend class ErrorInfo
;
82 for(USHORT n
=0;n
<ERRCODE_DYNAMIC_COUNT
;n
++)
91 EDcrData
*EDcrData::GetData()
96 EDcrData
**ppDat
=(EDcrData
**)GetAppData(SHL_ERR
);
99 return (*ppDat
=new EDcrData
);
106 void EDcr_Impl::RegisterEDcr(DynamicErrorInfo
*pDcr
)
108 //Vergibt eine dynamische Id
110 EDcrData
* pData
=EDcrData::GetData();
111 lErrId
= (((ULONG
)pData
->nNextDcr
+ 1) << ERRCODE_DYNAMIC_SHIFT
) +
112 pDcr
->GetErrorCode();
113 DynamicErrorInfo
**ppDcr
=pData
->ppDcr
;
114 USHORT nNext
=pData
->nNextDcr
;
116 // bei einem Ringbuffer koennen wir uns das ASSERT wohl sparen!
117 // DBG_ASSERT(ppDcr[nNext]==0,"ErrHdl: Alle Errors belegt");
123 if(++pData
->nNextDcr
>=ERRCODE_DYNAMIC_COUNT
)
128 void EDcr_Impl::UnRegisterEDcr(DynamicErrorInfo
*pDcr
)
131 EDcrData
* pData
=EDcrData::GetData();
132 DynamicErrorInfo
**ppDcr
=pData
->ppDcr
;
134 ((ULONG
)(*pDcr
) & ERRCODE_DYNAMIC_MASK
)>>ERRCODE_DYNAMIC_SHIFT
)-1;
135 DBG_ASSERT(ppDcr
[lIdx
]==pDcr
,"ErrHdl: Error nicht gefunden");
136 if(ppDcr
[lIdx
]==pDcr
)
140 TYPEINIT0(ErrorInfo
);
141 TYPEINIT1(DynamicErrorInfo
, ErrorInfo
);
142 TYPEINIT1(StandardErrorInfo
, DynamicErrorInfo
);
143 TYPEINIT1(StringErrorInfo
, DynamicErrorInfo
);
144 TYPEINIT1(TwoStringErrorInfo
, DynamicErrorInfo
);
145 TYPEINIT1(MessageInfo
, DynamicErrorInfo
);
148 ErrorInfo
*ErrorInfo::GetErrorInfo(ULONG lId
)
150 if(lId
& ERRCODE_DYNAMIC_MASK
)
151 return EDcr_Impl::GetDynamicErrorInfo(lId
);
153 return new ErrorInfo(lId
);
156 DynamicErrorInfo::operator ULONG() const
158 return pImpl
->lErrId
;
161 DynamicErrorInfo::DynamicErrorInfo(ULONG lArgUserId
, USHORT nMask
)
162 : ErrorInfo(lArgUserId
)
165 pImpl
->RegisterEDcr(this);
169 DynamicErrorInfo::~DynamicErrorInfo()
171 pImpl
->UnRegisterEDcr(this);
175 ErrorInfo
* EDcr_Impl::GetDynamicErrorInfo(ULONG lId
)
177 ULONG lIdx
=((lId
& ERRCODE_DYNAMIC_MASK
)>>ERRCODE_DYNAMIC_SHIFT
)-1;
178 DynamicErrorInfo
* pDcr
=EDcrData::GetData()->ppDcr
[lIdx
];
179 if(pDcr
&& (ULONG
)(*pDcr
)==lId
)
182 return new ErrorInfo(lId
& ~ERRCODE_DYNAMIC_MASK
);
186 USHORT
DynamicErrorInfo::GetDialogMask() const
192 StandardErrorInfo::StandardErrorInfo(
193 ULONG UserId
, ULONG lArgExtId
, USHORT nFlags
)
194 : DynamicErrorInfo(UserId
, nFlags
), lExtId(lArgExtId
)
199 StringErrorInfo::StringErrorInfo(
200 ULONG UserId
, const String
& aStringP
, USHORT nFlags
)
201 : DynamicErrorInfo(UserId
, nFlags
), aString(aStringP
)
211 static BOOL
CreateString(const ErrorHandler
*pStart
,
212 const ErrorInfo
*, String
&, USHORT
&);
216 static void aDspFunc(const String
&rErr
, const String
&rAction
)
218 ByteString
aErr("Aktion: ");
219 aErr
+= ByteString( rAction
, RTL_TEXTENCODING_ASCII_US
);
221 aErr
+= ByteString( rErr
, RTL_TEXTENCODING_ASCII_US
);
222 DBG_ERROR(aErr
.GetBuffer());
226 ErrorContext::ErrorContext(Window
*pWinP
)
228 EDcrData
*pData
=EDcrData::GetData();
229 ErrorContext
*&pHdl
=pData
->pFirstCtx
;
235 ErrorContext::~ErrorContext()
237 ErrorContext
**ppCtx
=&(EDcrData::GetData()->pFirstCtx
);
238 while(*ppCtx
&& *ppCtx
!=this)
239 ppCtx
=&((*ppCtx
)->pNext
);
241 *ppCtx
=(*ppCtx
)->pNext
;
244 ErrorContext
*ErrorContext::GetContext()
246 return EDcrData::GetData()->pFirstCtx
;
249 ErrorHandler::ErrorHandler()
251 pImpl
=new ErrHdl_Impl
;
252 EDcrData
*pData
=EDcrData::GetData();
253 ErrorHandler
*&pHdl
=pData
->pFirstHdl
;
257 RegisterDisplay(&aDspFunc
);
260 ErrorHandler::~ErrorHandler()
262 ErrorHandler
**ppHdl
=&(EDcrData::GetData()->pFirstHdl
);
263 while(*ppHdl
&& *ppHdl
!=this)
264 ppHdl
=&((*ppHdl
)->pImpl
->pNext
);
266 *ppHdl
=(*ppHdl
)->pImpl
->pNext
;
270 void ErrorHandler::RegisterDisplay(WindowDisplayErrorFunc
*aDsp
)
272 EDcrData
*pData
=EDcrData::GetData();
273 pData
->bIsWindowDsp
=TRUE
;
274 pData
->pDsp
= reinterpret_cast< DisplayFnPtr
>(aDsp
);
277 void ErrorHandler::RegisterDisplay(BasicDisplayErrorFunc
*aDsp
)
279 EDcrData
*pData
=EDcrData::GetData();
280 pData
->bIsWindowDsp
=FALSE
;
281 pData
->pDsp
= reinterpret_cast< DisplayFnPtr
>(aDsp
);
284 USHORT
ErrorHandler::HandleError_Impl(
285 ULONG lId
, USHORT nFlags
, BOOL bJustCreateString
, String
& rError
)
289 Handelt einen Fehler ab. lId ist die FehlerId, nFlags sind die
290 ErrorFlags. Werden nFlags nicht abgegeben, so werden die in
291 der DynamicErrorInfo angegebenen Flags bzw. die aus der Resource
299 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
306 if(!lId
|| lId
== ERRCODE_ABORT
)
308 EDcrData
*pData
=EDcrData::GetData();
309 ErrorInfo
*pInfo
=ErrorInfo::GetErrorInfo(lId
);
310 ErrorContext
*pCtx
=ErrorContext::GetContext();
312 pCtx
->GetString(pInfo
->GetErrorCode(), aAction
);
314 //Nimm den Parent aus dem Konext
315 for(;pCtx
;pCtx
=pCtx
->pNext
)
316 if(pCtx
->GetParent())
318 pParent
=pCtx
->GetParent();
322 BOOL bWarning
= ((lId
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
);
323 USHORT nErrFlags
= ERRCODE_BUTTON_DEF_OK
| ERRCODE_BUTTON_OK
;
325 nErrFlags
|= ERRCODE_MSG_WARNING
;
327 nErrFlags
|= ERRCODE_MSG_ERROR
;
329 DynamicErrorInfo
* pDynPtr
=PTR_CAST(DynamicErrorInfo
,pInfo
);
332 USHORT nDynFlags
= pDynPtr
->GetDialogMask();
334 nErrFlags
= nDynFlags
;
337 if(ErrHdl_Impl::CreateString(pData
->pFirstHdl
,pInfo
,aErr
,nErrFlags
))
339 if (bJustCreateString
)
348 ByteString
aStr("Action: ");
349 aStr
+= ByteString( aAction
, RTL_TEXTENCODING_ASCII_US
);
350 aStr
+= ByteString("\nFehler: ");
351 aStr
+= ByteString( aErr
, RTL_TEXTENCODING_ASCII_US
);
352 DBG_ERROR( aStr
.GetBuffer() );
357 if(!pData
->bIsWindowDsp
)
359 (*(BasicDisplayErrorFunc
*)pData
->pDsp
)(aErr
,aAction
);
364 if( nFlags
!= USHRT_MAX
)
366 return (*(WindowDisplayErrorFunc
*)pData
->pDsp
)(
367 pParent
, nErrFlags
, aErr
, aAction
);
372 DBG_ERROR("Error nicht behandelt");
373 // Error 1 ist General Error im Sfx
374 if(pInfo
->GetErrorCode()!=1) {
375 HandleError_Impl(1, USHRT_MAX
, bJustCreateString
, rError
);
378 DBG_ERROR("Error 1 nicht gehandeled");
385 BOOL
ErrorHandler::GetErrorString(ULONG lId
, String
& rStr
)
387 return (BOOL
)HandleError_Impl( lId
, USHRT_MAX
, TRUE
, rStr
);
390 USHORT
ErrorHandler::HandleError(ULONG lId
, USHORT nFlags
)
394 Handelt einen Fehler ab. lId ist die FehlerId, nFlags sind die
395 ErrorFlags. Werden nFlags nicht abgegeben, so werden die in
396 der DynamicErrorInfo angegebenen Flags bzw. die aus der Resource
404 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
410 return HandleError_Impl( lId
, nFlags
, FALSE
, aDummy
);
413 BOOL
ErrorHandler::ForwCreateString(const ErrorInfo
* pInfo
, String
& rStr
, USHORT
&rFlags
) const
415 return ErrHdl_Impl::CreateString(this->pImpl
->pNext
, pInfo
, rStr
, rFlags
);
418 BOOL
ErrHdl_Impl::CreateString( const ErrorHandler
*pStart
,
419 const ErrorInfo
* pInfo
, String
& pStr
,
422 for(const ErrorHandler
*pHdl
=pStart
;pHdl
;pHdl
=pHdl
->pImpl
->pNext
)
424 if(pHdl
->CreateString( pInfo
, pStr
, rFlags
))
430 BOOL
SimpleErrorHandler::CreateString(
431 const ErrorInfo
*pInfo
, String
&rStr
, USHORT
&) const
433 ULONG nId
= pInfo
->GetErrorCode();
436 aStr
+=ByteString::CreateFromInt32(nId
);
437 aStr
+=" only handled by SimpleErrorHandler";
438 aStr
+="\nErrorCode: ";
439 aStr
+=ByteString::CreateFromInt32(nId
& ((1L << ERRCODE_CLASS_SHIFT
) - 1 ));
440 aStr
+="\nErrorClass: ";
441 aStr
+=ByteString::CreateFromInt32((nId
& ERRCODE_CLASS_MASK
) >> ERRCODE_CLASS_SHIFT
);
442 aStr
+="\nErrorArea: ";
443 aStr
+=ByteString::CreateFromInt32((nId
& ERRCODE_ERROR_MASK
&
444 ~((1 << ERRCODE_AREA_SHIFT
) -1 ) ) >> ERRCODE_AREA_SHIFT
);
445 DynamicErrorInfo
*pDyn
=PTR_CAST(DynamicErrorInfo
,pInfo
);
449 aStr
+=ByteString::CreateFromInt32((ULONG
)*pDyn
);
451 StandardErrorInfo
*pStd
=PTR_CAST(StandardErrorInfo
,pInfo
);
455 aStr
+=ByteString::CreateFromInt32(pStd
->GetExtendedErrorCode());
457 rStr
= String( aStr
, RTL_TEXTENCODING_ASCII_US
);
461 SimpleErrorHandler::SimpleErrorHandler()