merge the formfield patch from ooo-build
[ooovba.git] / tools / source / ref / errinf.cxx
blob1eeb9c1bd1353160cd2be1db1cf0fba48d43ba2e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: errinf.cxx,v $
10 * $Revision: 1.9 $
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"
34 #include <limits.h>
35 #include <tools/shl.hxx>
36 #include <tools/debug.hxx>
37 #include <tools/errinf.hxx>
38 #include <tools/string.hxx>
40 class ErrorHandler;
42 namespace {
44 typedef void (* DisplayFnPtr)();
48 struct EDcrData
50 public:
52 ErrorHandler *pFirstHdl;
53 ErrorContext *pFirstCtx;
54 DisplayFnPtr pDsp;
55 BOOL bIsWindowDsp;
58 DynamicErrorInfo *ppDcr[ERRCODE_DYNAMIC_COUNT];
59 USHORT nNextDcr;
60 EDcrData();
62 static EDcrData *GetData();
66 class EDcr_Impl
68 ULONG lErrId;
69 USHORT nMask;
71 void RegisterEDcr(DynamicErrorInfo *);
72 void UnRegisterEDcr(DynamicErrorInfo *);
73 static ErrorInfo *GetDynamicErrorInfo(ULONG lId);
75 friend class DynamicErrorInfo;
76 friend class ErrorInfo;
80 EDcrData::EDcrData()
82 for(USHORT n=0;n<ERRCODE_DYNAMIC_COUNT;n++)
83 ppDcr[n]=0;
84 nNextDcr=0;
85 pFirstHdl=0;
86 pDsp=0;
87 pFirstCtx=0;
91 EDcrData *EDcrData::GetData()
93 #ifdef BOOTSTRAP
94 return 0x0;
95 #else
96 EDcrData **ppDat=(EDcrData **)GetAppData(SHL_ERR);
97 if(!*ppDat)
99 return (*ppDat=new EDcrData);
101 else
102 return *ppDat;
103 #endif
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");
118 if(ppDcr[nNext])
120 delete ppDcr[nNext];
122 ppDcr[nNext]=pDcr;
123 if(++pData->nNextDcr>=ERRCODE_DYNAMIC_COUNT)
124 pData->nNextDcr=0;
128 void EDcr_Impl::UnRegisterEDcr(DynamicErrorInfo *pDcr)
131 EDcrData* pData=EDcrData::GetData();
132 DynamicErrorInfo **ppDcr=pData->ppDcr;
133 ULONG lIdx=(
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)
137 ppDcr[lIdx]=0;
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);
152 else
153 return new ErrorInfo(lId);
156 DynamicErrorInfo::operator ULONG() const
158 return pImpl->lErrId;
161 DynamicErrorInfo::DynamicErrorInfo(ULONG lArgUserId, USHORT nMask)
162 : ErrorInfo(lArgUserId)
164 pImpl=new EDcr_Impl;
165 pImpl->RegisterEDcr(this);
166 pImpl->nMask=nMask;
169 DynamicErrorInfo::~DynamicErrorInfo()
171 pImpl->UnRegisterEDcr(this);
172 delete pImpl;
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)
180 return pDcr;
181 else
182 return new ErrorInfo(lId & ~ERRCODE_DYNAMIC_MASK);
186 USHORT DynamicErrorInfo::GetDialogMask() const
188 return pImpl->nMask;
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)
206 class ErrHdl_Impl
208 public:
210 ErrorHandler *pNext;
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 );
220 aErr+=" Fehler: ";
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;
230 pWin=pWinP;
231 pNext=pHdl;
232 pHdl=this;
235 ErrorContext::~ErrorContext()
237 ErrorContext **ppCtx=&(EDcrData::GetData()->pFirstCtx);
238 while(*ppCtx && *ppCtx!=this)
239 ppCtx=&((*ppCtx)->pNext);
240 if(*ppCtx)
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;
254 pImpl->pNext=pHdl;
255 pHdl=this;
256 if(!pData->pDsp)
257 RegisterDisplay(&aDspFunc);
260 ErrorHandler::~ErrorHandler()
262 ErrorHandler **ppHdl=&(EDcrData::GetData()->pFirstHdl);
263 while(*ppHdl && *ppHdl!=this)
264 ppHdl=&((*ppHdl)->pImpl->pNext);
265 if(*ppHdl)
266 *ppHdl=(*ppHdl)->pImpl->pNext;
267 delete pImpl;
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)
288 /* [Beschreibung]
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
292 verwendet.
294 Also:
296 1. nFlags,
297 2. Resource Flags
298 3. Dynamic Flags
299 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
304 String aErr;
305 String aAction;
306 if(!lId || lId == ERRCODE_ABORT)
307 return 0;
308 EDcrData *pData=EDcrData::GetData();
309 ErrorInfo *pInfo=ErrorInfo::GetErrorInfo(lId);
310 ErrorContext *pCtx=ErrorContext::GetContext();
311 if(pCtx)
312 pCtx->GetString(pInfo->GetErrorCode(), aAction);
313 Window *pParent=0;
314 //Nimm den Parent aus dem Konext
315 for(;pCtx;pCtx=pCtx->pNext)
316 if(pCtx->GetParent())
318 pParent=pCtx->GetParent();
319 break;
322 BOOL bWarning = ((lId & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
323 USHORT nErrFlags = ERRCODE_BUTTON_DEF_OK | ERRCODE_BUTTON_OK;
324 if (bWarning)
325 nErrFlags |= ERRCODE_MSG_WARNING;
326 else
327 nErrFlags |= ERRCODE_MSG_ERROR;
329 DynamicErrorInfo* pDynPtr=PTR_CAST(DynamicErrorInfo,pInfo);
330 if(pDynPtr)
332 USHORT nDynFlags = pDynPtr->GetDialogMask();
333 if( nDynFlags )
334 nErrFlags = nDynFlags;
337 if(ErrHdl_Impl::CreateString(pData->pFirstHdl,pInfo,aErr,nErrFlags))
339 if (bJustCreateString)
341 rError = aErr;
342 return 1;
344 else
346 if(!pData->pDsp)
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() );
354 else
356 delete pInfo;
357 if(!pData->bIsWindowDsp)
359 (*(BasicDisplayErrorFunc*)pData->pDsp)(aErr,aAction);
360 return 0;
362 else
364 if( nFlags != USHRT_MAX )
365 nErrFlags = nFlags;
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);
377 else {
378 DBG_ERROR("Error 1 nicht gehandeled");
380 delete pInfo;
381 return 0;
384 // static
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)
393 /* [Beschreibung]
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
397 verwendet.
399 Also:
401 1. nFlags,
402 2. Resource Flags
403 3. Dynamic Flags
404 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
409 String aDummy;
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,
420 USHORT &rFlags)
422 for(const ErrorHandler *pHdl=pStart;pHdl;pHdl=pHdl->pImpl->pNext)
424 if(pHdl->CreateString( pInfo, pStr, rFlags))
425 return TRUE;
427 return FALSE;
430 BOOL SimpleErrorHandler::CreateString(
431 const ErrorInfo *pInfo, String &rStr, USHORT &) const
433 ULONG nId = pInfo->GetErrorCode();
434 ByteString aStr;
435 aStr="Id ";
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);
446 if(pDyn)
448 aStr+="\nDId ";
449 aStr+=ByteString::CreateFromInt32((ULONG)*pDyn);
451 StandardErrorInfo *pStd=PTR_CAST(StandardErrorInfo,pInfo);
452 if(pStd)
454 aStr+="\nXId ";
455 aStr+=ByteString::CreateFromInt32(pStd->GetExtendedErrorCode());
457 rStr = String( aStr, RTL_TEXTENCODING_ASCII_US );
458 return TRUE;
461 SimpleErrorHandler::SimpleErrorHandler()
462 : ErrorHandler()