summaryrefslogtreecommitdiff
path: root/tools/source/ref/errinf.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tools/source/ref/errinf.cxx')
-rw-r--r--tools/source/ref/errinf.cxx464
1 files changed, 464 insertions, 0 deletions
diff --git a/tools/source/ref/errinf.cxx b/tools/source/ref/errinf.cxx
new file mode 100644
index 000000000000..9ad9b71dcba3
--- /dev/null
+++ b/tools/source/ref/errinf.cxx
@@ -0,0 +1,464 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_tools.hxx"
+
+#include <limits.h>
+#include <tools/shl.hxx>
+#include <tools/debug.hxx>
+#include <tools/errinf.hxx>
+#include <tools/string.hxx>
+
+class ErrorHandler;
+
+namespace {
+
+typedef void (* DisplayFnPtr)();
+
+}
+
+struct EDcrData
+{
+ public:
+
+ ErrorHandler *pFirstHdl;
+ ErrorContext *pFirstCtx;
+ DisplayFnPtr pDsp;
+ sal_Bool bIsWindowDsp;
+
+
+ DynamicErrorInfo *ppDcr[ERRCODE_DYNAMIC_COUNT];
+ sal_uInt16 nNextDcr;
+ EDcrData();
+
+static EDcrData *GetData();
+
+};
+
+class EDcr_Impl
+{
+ sal_uIntPtr lErrId;
+ sal_uInt16 nMask;
+
+ void RegisterEDcr(DynamicErrorInfo *);
+ void UnRegisterEDcr(DynamicErrorInfo *);
+ static ErrorInfo *GetDynamicErrorInfo(sal_uIntPtr lId);
+
+friend class DynamicErrorInfo;
+friend class ErrorInfo;
+};
+
+
+EDcrData::EDcrData()
+{
+ for(sal_uInt16 n=0;n<ERRCODE_DYNAMIC_COUNT;n++)
+ ppDcr[n]=0;
+ nNextDcr=0;
+ pFirstHdl=0;
+ pDsp=0;
+ pFirstCtx=0;
+}
+
+
+EDcrData *EDcrData::GetData()
+{
+#ifdef BOOTSTRAP
+ return 0x0;
+#else
+ EDcrData **ppDat=(EDcrData **)GetAppData(SHL_ERR);
+ if(!*ppDat)
+ {
+ return (*ppDat=new EDcrData);
+ }
+ else
+ return *ppDat;
+#endif
+}
+
+void EDcr_Impl::RegisterEDcr(DynamicErrorInfo *pDcr)
+{
+ //Vergibt eine dynamische Id
+
+ EDcrData* pData=EDcrData::GetData();
+ lErrId= (((sal_uIntPtr)pData->nNextDcr + 1) << ERRCODE_DYNAMIC_SHIFT) +
+ pDcr->GetErrorCode();
+ DynamicErrorInfo **ppDcr=pData->ppDcr;
+ sal_uInt16 nNext=pData->nNextDcr;
+
+ // bei einem Ringbuffer koennen wir uns das ASSERT wohl sparen!
+ // DBG_ASSERT(ppDcr[nNext]==0,"ErrHdl: Alle Errors belegt");
+ if(ppDcr[nNext])
+ {
+ delete ppDcr[nNext];
+ }
+ ppDcr[nNext]=pDcr;
+ if(++pData->nNextDcr>=ERRCODE_DYNAMIC_COUNT)
+ pData->nNextDcr=0;
+}
+
+
+void EDcr_Impl::UnRegisterEDcr(DynamicErrorInfo *pDcr)
+{
+
+ EDcrData* pData=EDcrData::GetData();
+ DynamicErrorInfo **ppDcr=pData->ppDcr;
+ sal_uIntPtr lIdx=(
+ ((sal_uIntPtr)(*pDcr) & ERRCODE_DYNAMIC_MASK)>>ERRCODE_DYNAMIC_SHIFT)-1;
+ DBG_ASSERT(ppDcr[lIdx]==pDcr,"ErrHdl: Error nicht gefunden");
+ if(ppDcr[lIdx]==pDcr)
+ ppDcr[lIdx]=0;
+}
+
+TYPEINIT0(ErrorInfo);
+TYPEINIT1(DynamicErrorInfo, ErrorInfo);
+TYPEINIT1(StandardErrorInfo, DynamicErrorInfo);
+TYPEINIT1(StringErrorInfo, DynamicErrorInfo);
+TYPEINIT1(TwoStringErrorInfo, DynamicErrorInfo);
+TYPEINIT1(MessageInfo, DynamicErrorInfo);
+
+
+ErrorInfo *ErrorInfo::GetErrorInfo(sal_uIntPtr lId)
+{
+ if(lId & ERRCODE_DYNAMIC_MASK)
+ return EDcr_Impl::GetDynamicErrorInfo(lId);
+ else
+ return new ErrorInfo(lId);
+}
+
+DynamicErrorInfo::operator sal_uIntPtr() const
+{
+ return pImpl->lErrId;
+}
+
+DynamicErrorInfo::DynamicErrorInfo(sal_uIntPtr lArgUserId, sal_uInt16 nMask)
+: ErrorInfo(lArgUserId)
+{
+ pImpl=new EDcr_Impl;
+ pImpl->RegisterEDcr(this);
+ pImpl->nMask=nMask;
+}
+
+DynamicErrorInfo::~DynamicErrorInfo()
+{
+ pImpl->UnRegisterEDcr(this);
+ delete pImpl;
+}
+
+ErrorInfo* EDcr_Impl::GetDynamicErrorInfo(sal_uIntPtr lId)
+{
+ sal_uIntPtr lIdx=((lId & ERRCODE_DYNAMIC_MASK)>>ERRCODE_DYNAMIC_SHIFT)-1;
+ DynamicErrorInfo* pDcr=EDcrData::GetData()->ppDcr[lIdx];
+ if(pDcr && (sal_uIntPtr)(*pDcr)==lId)
+ return pDcr;
+ else
+ return new ErrorInfo(lId & ~ERRCODE_DYNAMIC_MASK);
+}
+
+
+sal_uInt16 DynamicErrorInfo::GetDialogMask() const
+{
+ return pImpl->nMask;
+}
+
+
+StandardErrorInfo::StandardErrorInfo(
+ sal_uIntPtr UserId, sal_uIntPtr lArgExtId, sal_uInt16 nFlags)
+: DynamicErrorInfo(UserId, nFlags), lExtId(lArgExtId)
+{
+}
+
+
+StringErrorInfo::StringErrorInfo(
+ sal_uIntPtr UserId, const String& aStringP, sal_uInt16 nFlags)
+: DynamicErrorInfo(UserId, nFlags), aString(aStringP)
+{
+}
+
+
+class ErrHdl_Impl
+{
+ public:
+
+ ErrorHandler *pNext;
+ static sal_Bool CreateString(const ErrorHandler *pStart,
+ const ErrorInfo*, String&, sal_uInt16&);
+};
+
+
+static void aDspFunc(const String &rErr, const String &rAction)
+{
+ ByteString aErr("Aktion: ");
+ aErr+= ByteString( rAction, RTL_TEXTENCODING_ASCII_US );
+ aErr+=" Fehler: ";
+ aErr+= ByteString( rErr, RTL_TEXTENCODING_ASCII_US );
+ OSL_FAIL(aErr.GetBuffer());
+}
+
+
+ErrorContext::ErrorContext(Window *pWinP)
+{
+ EDcrData *pData=EDcrData::GetData();
+ ErrorContext *&pHdl=pData->pFirstCtx;
+ pWin=pWinP;
+ pNext=pHdl;
+ pHdl=this;
+}
+
+ErrorContext::~ErrorContext()
+{
+ ErrorContext **ppCtx=&(EDcrData::GetData()->pFirstCtx);
+ while(*ppCtx && *ppCtx!=this)
+ ppCtx=&((*ppCtx)->pNext);
+ if(*ppCtx)
+ *ppCtx=(*ppCtx)->pNext;
+}
+
+ErrorContext *ErrorContext::GetContext()
+{
+ return EDcrData::GetData()->pFirstCtx;
+}
+
+ErrorHandler::ErrorHandler()
+{
+ pImpl=new ErrHdl_Impl;
+ EDcrData *pData=EDcrData::GetData();
+ ErrorHandler *&pHdl=pData->pFirstHdl;
+ pImpl->pNext=pHdl;
+ pHdl=this;
+ if(!pData->pDsp)
+ RegisterDisplay(&aDspFunc);
+}
+
+ErrorHandler::~ErrorHandler()
+{
+ ErrorHandler **ppHdl=&(EDcrData::GetData()->pFirstHdl);
+ while(*ppHdl && *ppHdl!=this)
+ ppHdl=&((*ppHdl)->pImpl->pNext);
+ if(*ppHdl)
+ *ppHdl=(*ppHdl)->pImpl->pNext;
+ delete pImpl;
+}
+
+void ErrorHandler::RegisterDisplay(WindowDisplayErrorFunc *aDsp)
+{
+ EDcrData *pData=EDcrData::GetData();
+ pData->bIsWindowDsp=sal_True;
+ pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
+}
+
+void ErrorHandler::RegisterDisplay(BasicDisplayErrorFunc *aDsp)
+{
+ EDcrData *pData=EDcrData::GetData();
+ pData->bIsWindowDsp=sal_False;
+ pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
+}
+
+sal_uInt16 ErrorHandler::HandleError_Impl(
+ sal_uIntPtr lId, sal_uInt16 nFlags, sal_Bool bJustCreateString, String & rError)
+{
+
+/* [Beschreibung]
+ Handelt einen Fehler ab. lId ist die FehlerId, nFlags sind die
+ ErrorFlags. Werden nFlags nicht abgegeben, so werden die in
+ der DynamicErrorInfo angegebenen Flags bzw. die aus der Resource
+ verwendet.
+
+ Also:
+
+ 1. nFlags,
+ 2. Resource Flags
+ 3. Dynamic Flags
+ 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
+
+
+ */
+
+ String aErr;
+ String aAction;
+ if(!lId || lId == ERRCODE_ABORT)
+ return 0;
+ EDcrData *pData=EDcrData::GetData();
+ ErrorInfo *pInfo=ErrorInfo::GetErrorInfo(lId);
+ ErrorContext *pCtx=ErrorContext::GetContext();
+ if(pCtx)
+ pCtx->GetString(pInfo->GetErrorCode(), aAction);
+ Window *pParent=0;
+ //Nimm den Parent aus dem Konext
+ for(;pCtx;pCtx=pCtx->pNext)
+ if(pCtx->GetParent())
+ {
+ pParent=pCtx->GetParent();
+ break;
+ }
+
+ sal_Bool bWarning = ((lId & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
+ sal_uInt16 nErrFlags = ERRCODE_BUTTON_DEF_OK | ERRCODE_BUTTON_OK;
+ if (bWarning)
+ nErrFlags |= ERRCODE_MSG_WARNING;
+ else
+ nErrFlags |= ERRCODE_MSG_ERROR;
+
+ DynamicErrorInfo* pDynPtr=PTR_CAST(DynamicErrorInfo,pInfo);
+ if(pDynPtr)
+ {
+ sal_uInt16 nDynFlags = pDynPtr->GetDialogMask();
+ if( nDynFlags )
+ nErrFlags = nDynFlags;
+ }
+
+ if(ErrHdl_Impl::CreateString(pData->pFirstHdl,pInfo,aErr,nErrFlags))
+ {
+ if (bJustCreateString)
+ {
+ rError = aErr;
+ return 1;
+ }
+ else
+ {
+ if(!pData->pDsp)
+ {
+ ByteString aStr("Action: ");
+ aStr += ByteString( aAction, RTL_TEXTENCODING_ASCII_US );
+ aStr += ByteString("\nFehler: ");
+ aStr += ByteString( aErr, RTL_TEXTENCODING_ASCII_US );
+ OSL_FAIL( aStr.GetBuffer() );
+ }
+ else
+ {
+ delete pInfo;
+ if(!pData->bIsWindowDsp)
+ {
+ (*(BasicDisplayErrorFunc*)pData->pDsp)(aErr,aAction);
+ return 0;
+ }
+ else
+ {
+ if( nFlags != USHRT_MAX )
+ nErrFlags = nFlags;
+ return (*(WindowDisplayErrorFunc*)pData->pDsp)(
+ pParent, nErrFlags, aErr, aAction);
+ }
+ }
+ }
+ }
+ OSL_FAIL("Error nicht behandelt");
+ // Error 1 ist General Error im Sfx
+ if(pInfo->GetErrorCode()!=1) {
+ HandleError_Impl(1, USHRT_MAX, bJustCreateString, rError);
+ }
+ else {
+ OSL_FAIL("Error 1 nicht gehandeled");
+ }
+ delete pInfo;
+ return 0;
+}
+
+// static
+sal_Bool ErrorHandler::GetErrorString(sal_uIntPtr lId, String& rStr)
+{
+ return (sal_Bool)HandleError_Impl( lId, USHRT_MAX, sal_True, rStr );
+}
+
+sal_uInt16 ErrorHandler::HandleError(sal_uIntPtr lId, sal_uInt16 nFlags)
+{
+
+/* [Beschreibung]
+ Handelt einen Fehler ab. lId ist die FehlerId, nFlags sind die
+ ErrorFlags. Werden nFlags nicht abgegeben, so werden die in
+ der DynamicErrorInfo angegebenen Flags bzw. die aus der Resource
+ verwendet.
+
+ Also:
+
+ 1. nFlags,
+ 2. Resource Flags
+ 3. Dynamic Flags
+ 4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
+
+
+ */
+
+ String aDummy;
+ return HandleError_Impl( lId, nFlags, sal_False, aDummy );
+}
+
+sal_Bool ErrorHandler::ForwCreateString(const ErrorInfo* pInfo, String& rStr, sal_uInt16 &rFlags) const
+{
+ return ErrHdl_Impl::CreateString(this->pImpl->pNext, pInfo, rStr, rFlags);
+}
+
+sal_Bool ErrHdl_Impl::CreateString( const ErrorHandler *pStart,
+ const ErrorInfo* pInfo, String& pStr,
+ sal_uInt16 &rFlags)
+{
+ for(const ErrorHandler *pHdl=pStart;pHdl;pHdl=pHdl->pImpl->pNext)
+ {
+ if(pHdl->CreateString( pInfo, pStr, rFlags))
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Bool SimpleErrorHandler::CreateString(
+ const ErrorInfo *pInfo, String &rStr, sal_uInt16 &) const
+{
+ sal_uIntPtr nId = pInfo->GetErrorCode();
+ ByteString aStr;
+ aStr="Id ";
+ aStr+=ByteString::CreateFromInt32(nId);
+ aStr+=" only handled by SimpleErrorHandler";
+ aStr+="\nErrorCode: ";
+ aStr+=ByteString::CreateFromInt32(nId & ((1L << ERRCODE_CLASS_SHIFT) - 1 ));
+ aStr+="\nErrorClass: ";
+ aStr+=ByteString::CreateFromInt32((nId & ERRCODE_CLASS_MASK) >> ERRCODE_CLASS_SHIFT);
+ aStr+="\nErrorArea: ";
+ aStr+=ByteString::CreateFromInt32((nId & ERRCODE_ERROR_MASK &
+ ~((1 << ERRCODE_AREA_SHIFT ) -1 ) ) >> ERRCODE_AREA_SHIFT);
+ DynamicErrorInfo *pDyn=PTR_CAST(DynamicErrorInfo,pInfo);
+ if(pDyn)
+ {
+ aStr+="\nDId ";
+ aStr+=ByteString::CreateFromInt32((sal_uIntPtr)*pDyn);
+ }
+ StandardErrorInfo *pStd=PTR_CAST(StandardErrorInfo,pInfo);
+ if(pStd)
+ {
+ aStr+="\nXId ";
+ aStr+=ByteString::CreateFromInt32(pStd->GetExtendedErrorCode());
+ }
+ rStr = String( aStr, RTL_TEXTENCODING_ASCII_US );
+ return sal_True;
+}
+
+SimpleErrorHandler::SimpleErrorHandler()
+ : ErrorHandler()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */