xref: /trunk/main/svtools/source/misc/ehdl.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 #include <vos/mutex.hxx>
31 #include <tools/debug.hxx>
32 #include <tools/rcid.h>
33 #include <tools/wintypes.hxx>
34 #include <vcl/msgbox.hxx>
35 #include <vcl/svapp.hxx>
36 #if defined(OS2)
37 #include <vcl/sound.hxx>
38 #endif
39 
40 #ifndef GCC
41 #endif
42 
43 #include <svtools/ehdl.hxx>
44 #include <svtools/svtdata.hxx>
45 #include <svtools/svtools.hrc>
46 #include <svtools/sfxecode.hxx>
47 
48 //=========================================================================
49 
50 static sal_uInt16 aWndFunc(
51     Window *pWin,            // Parent des Dialoges
52     sal_uInt16 nFlags,
53     const String &rErr,      // Fehlertext
54     const String &rAction)   // Actiontext
55 
56 /*  [Beschreibung]
57 
58     Bringt eine Fehlerbox auf den Schirm. Je nach nFlags werden
59     Error/ Info usw. Boxen mit den gewuenschten Buttons angezeigt
60 
61     Rueckgabewert ist der gedrueckte Button
62 
63     */
64 
65 
66 {
67     vos:: OGuard  aGuard( Application::GetSolarMutex() );
68 
69     // aus den Flags die benoetigten WinBits ermitteln
70     WinBits eBits=0;
71     if ( (ERRCODE_BUTTON_CANCEL|ERRCODE_BUTTON_RETRY) == (nFlags & (ERRCODE_BUTTON_CANCEL|ERRCODE_BUTTON_RETRY)) )
72         eBits = WB_RETRY_CANCEL;
73     else if ( ERRCODE_BUTTON_OK_CANCEL == (nFlags & ERRCODE_BUTTON_OK_CANCEL) )
74         eBits = WB_OK_CANCEL;
75     else if ( ERRCODE_BUTTON_OK == (nFlags & ERRCODE_BUTTON_OK) )
76         eBits = WB_OK;
77     else if ( ERRCODE_BUTTON_YES_NO_CANCEL == (nFlags & ERRCODE_BUTTON_YES_NO_CANCEL) )
78         eBits = WB_YES_NO_CANCEL;
79     else if ( ERRCODE_BUTTON_YES_NO == (nFlags & ERRCODE_BUTTON_YES_NO) )
80         eBits = WB_YES_NO;
81 
82     switch(nFlags & 0x0f00)
83     {
84       case ERRCODE_BUTTON_DEF_OK:
85             eBits |= WB_DEF_OK;
86             break;
87 
88       case ERRCODE_BUTTON_DEF_CANCEL:
89             eBits |= WB_DEF_CANCEL;
90             break;
91 
92       case ERRCODE_BUTTON_DEF_YES:
93             eBits |= WB_DEF_YES;
94             break;
95 
96       case ERRCODE_BUTTON_DEF_NO:
97             eBits |= WB_DEF_NO;
98             break;
99     }
100 
101     String aErr(SvtResId(STR_ERR_HDLMESS));
102     String aAction(rAction);
103     if ( aAction.Len() )
104         aAction += String::CreateFromAscii( ":\n" );
105     aErr.SearchAndReplace(String::CreateFromAscii( "$(ACTION)" ), aAction);
106     aErr.SearchAndReplace(String::CreateFromAscii( "$(ERROR)" ), rErr);
107 
108     MessBox* pBox;
109     switch ( nFlags & 0xf000 )
110     {
111         case ERRCODE_MSG_ERROR:
112             pBox = new ErrorBox(pWin, eBits, aErr);
113             break;
114 
115         case ERRCODE_MSG_WARNING:
116             pBox = new WarningBox(pWin, eBits, aErr);
117             break;
118 
119         case ERRCODE_MSG_INFO:
120             pBox = new InfoBox(pWin, aErr);
121             break;
122 
123         case ERRCODE_MSG_QUERY:
124             pBox = new QueryBox(pWin, eBits, aErr);
125             break;
126 
127         default:
128         {
129             DBG_ERRORFILE( "no MessBox type");
130             pBox = NULL;
131             return ERRCODE_BUTTON_OK;
132         }
133     }
134 
135     sal_uInt16 nRet = RET_CANCEL;
136     switch ( pBox->Execute() )
137     {
138         case RET_OK:
139             nRet = ERRCODE_BUTTON_OK;
140             break;
141         case RET_CANCEL:
142             nRet = ERRCODE_BUTTON_CANCEL;
143             break;
144         case RET_RETRY:
145             nRet = ERRCODE_BUTTON_RETRY;
146             break;
147         case RET_YES:
148             nRet = ERRCODE_BUTTON_YES;
149             break;
150         case RET_NO:
151             nRet = ERRCODE_BUTTON_NO;
152             break;
153         default:
154             DBG_ERRORFILE( "Unknown MessBox return value" );
155             break;
156     }
157     delete pBox;
158     return nRet;
159 }
160 
161 //-------------------------------------------------------------------------
162 
163 SfxErrorHandler::SfxErrorHandler(sal_uInt16 nIdP, sal_uLong lStartP, sal_uLong lEndP, ResMgr *pMgrP) :
164 
165     lStart(lStartP), lEnd(lEndP), nId(nIdP), pMgr(pMgrP), pFreeMgr( NULL )
166 
167 {
168     RegisterDisplay(&aWndFunc);
169     if( ! pMgr )
170     {
171         com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
172         pFreeMgr = pMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(ofa), aLocale );
173     }
174 }
175 
176 //-------------------------------------------------------------------------
177 
178 SfxErrorHandler::~SfxErrorHandler()
179 {
180     if( pFreeMgr )
181         delete pFreeMgr;
182 }
183 
184 //-------------------------------------------------------------------------
185 
186 sal_Bool SfxErrorHandler::CreateString(
187     const ErrorInfo *pErr, String &rStr, sal_uInt16& nFlags) const
188 
189 /*  [Beschreibung]
190 
191     Der Fehlerstring fuer die ErrorInfo pErr wird zusammengesetzt.
192 
193     */
194 
195 {
196     sal_uLong nErrCode = pErr->GetErrorCode() & ERRCODE_ERROR_MASK;
197     if( nErrCode>=lEnd || nErrCode<=lStart )
198         return sal_False;
199     MessageInfo *pMsgInfo=PTR_CAST(MessageInfo,pErr);
200     if(pMsgInfo)
201     {
202         if(GetMessageString(nErrCode, rStr, nFlags))
203         {
204             for (xub_StrLen i = 0; i < rStr.Len();)
205             {
206                 i = rStr.SearchAndReplace(String::CreateFromAscii( "$(ARG1)" ),
207                                           pMsgInfo->GetMessageArg(), i);
208                 if (i == STRING_NOTFOUND)
209                     break;
210                 i = i + pMsgInfo->GetMessageArg().Len();
211             }
212             return sal_True;
213         }
214     }
215     else if(GetErrorString(nErrCode, rStr, nFlags))
216     {
217         StringErrorInfo *pStringInfo=PTR_CAST(StringErrorInfo,pErr);
218         if(pStringInfo)
219             for (xub_StrLen i = 0; i < rStr.Len();)
220             {
221                 i = rStr.SearchAndReplace(String::CreateFromAscii( "$(ARG1)" ),
222                                           pStringInfo->GetErrorString(), i);
223                 if (i == STRING_NOTFOUND)
224                     break;
225                 i = i + pStringInfo->GetErrorString().Len();
226             }
227         else
228         {
229             TwoStringErrorInfo * pTwoStringInfo = PTR_CAST(TwoStringErrorInfo,
230                                                            pErr);
231             if (pTwoStringInfo)
232                 for (sal_uInt16 i = 0; i < rStr.Len();)
233                 {
234                     sal_uInt16 nArg1Pos = rStr.Search(String::CreateFromAscii( "$(ARG1)" ), i);
235                     sal_uInt16 nArg2Pos = rStr.Search(String::CreateFromAscii( "$(ARG2)" ), i);
236                     if (nArg1Pos < nArg2Pos)
237                     {
238                         rStr.Replace(nArg1Pos, 7, pTwoStringInfo->GetArg1());
239                         i = nArg1Pos + pTwoStringInfo->GetArg1().Len();
240                     }
241                     else if (nArg2Pos < nArg1Pos)
242                     {
243                         rStr.Replace(nArg2Pos, 7, pTwoStringInfo->GetArg2());
244                         i = nArg2Pos + pTwoStringInfo->GetArg2().Len();
245                     }
246                     else break;
247                 }
248         }
249         return sal_True;
250     }
251     return sal_False;
252 }
253 
254 //-------------------------------------------------------------------------
255 
256 class ResString: public String
257 
258 /*  [Beschreibung]
259 
260     Hilfsklasse zum Auslesen eines Strings und optionaler ExtraData aus
261     einer String Resource.
262 
263     */
264 
265 {
266     sal_uInt16 nFlags;
267   public:
268     sal_uInt16 GetFlags() const {return nFlags;}
269     const String & GetString() const {return *this;}
270     ResString( ResId &rId);
271 };
272 
273 //-------------------------------------------------------------------------
274 
275 ResString::ResString(ResId & rId):
276     String(rId.SetAutoRelease(sal_False)),
277     nFlags(0)
278 {
279     ResMgr * pResMgr = rId.GetResMgr();
280      // String ctor temporarily sets global ResManager
281     if (pResMgr->GetRemainSize())
282         nFlags = sal_uInt16(pResMgr->ReadShort());
283     rId.SetAutoRelease(sal_True);
284     pResMgr->PopContext();
285 }
286 
287 //-------------------------------------------------------------------------
288 
289 struct ErrorResource_Impl : private Resource
290 
291 /*  [Beschreibung]
292 
293     Hilfsklasse zum Zugriff auf String SubResourcen einer Resource
294     */
295 
296 {
297 
298     ResId aResId;
299 
300     ErrorResource_Impl(ResId& rErrIdP, sal_uInt16 nId)
301         : Resource(rErrIdP),aResId(nId,*rErrIdP.GetResMgr()){}
302 
303     ~ErrorResource_Impl() { FreeResource(); }
304 
305     operator ResString(){ return ResString( aResId ); }
306     operator sal_Bool(){return IsAvailableRes(aResId.SetRT(RSC_STRING));}
307 
308 };
309 
310 
311 sal_Bool SfxErrorHandler::GetClassString(sal_uLong lClassId, String &rStr) const
312 
313 /*  [Beschreibung]
314 
315     Erzeugt den String fuer die Klasse des Fehlers. Wird immer aus der
316     Resource des Sfx gelesen
317 
318     */
319 
320 {
321     sal_Bool bRet = sal_False;
322     com::sun::star::lang::Locale aLocale( Application::GetSettings().GetUILocale() );
323     ResMgr* pResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(ofa), aLocale );
324     if( pResMgr )
325     {
326         ResId aId(RID_ERRHDL, *pResMgr );
327         ErrorResource_Impl aEr(aId, (sal_uInt16)lClassId);
328         if(aEr)
329         {
330             rStr=((ResString)aEr).GetString();
331             bRet = sal_True;
332         }
333     }
334     delete pResMgr;
335     return bRet;
336 }
337 
338 //-------------------------------------------------------------------------
339 
340 sal_Bool SfxErrorHandler::GetMessageString(
341     sal_uLong lErrId, String &rStr, sal_uInt16 &nFlags) const
342 
343 /*  [Beschreibung]
344 
345     Erzeugt den String fuer die Ausgabe in einer MessageBox
346 
347     */
348 
349 {
350     sal_Bool bRet = sal_False;
351     ResId *pResId= new ResId(nId, *pMgr);
352 
353     ErrorResource_Impl aEr(*pResId, (sal_uInt16)lErrId);
354     if(aEr)
355     {
356         ResString aErrorString(aEr);
357         sal_uInt16 nResFlags = aErrorString.GetFlags();
358         if( nResFlags )
359             nFlags=aErrorString.GetFlags();
360         rStr = aErrorString.GetString();
361         bRet = sal_True;
362     }
363 
364     delete pResId;
365     return bRet;
366 }
367 
368 //-------------------------------------------------------------------------
369 
370 sal_Bool SfxErrorHandler::GetErrorString(
371     sal_uLong lErrId, String &rStr, sal_uInt16 &nFlags) const
372 
373 /*  [Beschreibung]
374     Erzeugt den Fehlerstring fuer den eigentlichen Fehler ohne
375     dessen Klasse
376 
377     */
378 
379 {
380     vos:: OGuard  aGuard( Application::GetSolarMutex() );
381 
382     sal_Bool bRet = sal_False;
383     rStr=String(SvtResId(RID_ERRHDL_CLASS));
384     ResId aResId(nId, *pMgr);
385 
386     {
387         ErrorResource_Impl aEr(aResId, (sal_uInt16)lErrId);
388         if(aEr)
389         {
390             ResString aErrorString(aEr);
391 
392             sal_uInt16 nResFlags = aErrorString.GetFlags();
393             if ( nResFlags )
394                 nFlags = nResFlags;
395             rStr.SearchAndReplace(
396                 String::CreateFromAscii("$(ERROR)"), aErrorString.GetString());
397             bRet = sal_True;
398         }
399         else
400             bRet = sal_False;
401     }
402 
403     if( bRet )
404     {
405         String aErrStr;
406         GetClassString(lErrId & ERRCODE_CLASS_MASK,
407                        aErrStr);
408         if(aErrStr.Len())
409             aErrStr+=String::CreateFromAscii( ".\n" );
410         rStr.SearchAndReplace(String::CreateFromAscii( "$(CLASS)" ),aErrStr);
411     }
412 
413     return bRet;
414 }
415 
416 //-------------------------------------------------------------------------
417 
418 SfxErrorContext::SfxErrorContext(
419     sal_uInt16 nCtxIdP, Window *pWindow, sal_uInt16 nResIdP, ResMgr *pMgrP)
420 :   ErrorContext(pWindow), nCtxId(nCtxIdP), nResId(nResIdP), pMgr(pMgrP)
421 {
422     if( nResId==USHRT_MAX )
423         nResId=RID_ERRCTX;
424 }
425 
426 //-------------------------------------------------------------------------
427 
428 SfxErrorContext::SfxErrorContext(
429     sal_uInt16 nCtxIdP, const String &aArg1P, Window *pWindow,
430     sal_uInt16 nResIdP, ResMgr *pMgrP)
431 :   ErrorContext(pWindow), nCtxId(nCtxIdP), nResId(nResIdP), pMgr(pMgrP),
432     aArg1(aArg1P)
433 {
434     if( nResId==USHRT_MAX )
435         nResId=RID_ERRCTX;
436 }
437 
438 //-------------------------------------------------------------------------
439 
440 sal_Bool SfxErrorContext::GetString(sal_uLong nErrId, String &rStr)
441 
442 /*  [Beschreibung]
443 
444     Baut die Beschreibung eines ErrorContextes auf
445     */
446 
447 {
448     bool bRet = false;
449     ResMgr* pFreeMgr = NULL;
450     if( ! pMgr )
451     {
452         com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
453         pFreeMgr = pMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(ofa), aLocale );
454     }
455     if( pMgr )
456     {
457         vos:: OGuard  aGuard( Application::GetSolarMutex() );
458 
459         ResId aResId( nResId, *pMgr );
460 
461         ErrorResource_Impl aTestEr( aResId, nCtxId );
462         if ( aTestEr )
463         {
464             rStr = ( (ResString)aTestEr ).GetString();
465             rStr.SearchAndReplace( String::CreateFromAscii( "$(ARG1)" ), aArg1 );
466             bRet = true;
467         }
468         else
469         {
470             DBG_ERRORFILE( "ErrorContext cannot find the resource" );
471             bRet = false;
472         }
473 
474         if ( bRet )
475         {
476             sal_uInt16 nId = ( nErrId & ERRCODE_WARNING_MASK ) ? ERRCTX_WARNING : ERRCTX_ERROR;
477             ResId aSfxResId( RID_ERRCTX, *pMgr );
478             ErrorResource_Impl aEr( aSfxResId, nId );
479             rStr.SearchAndReplace( String::CreateFromAscii( "$(ERR)" ), ( (ResString)aEr ).GetString() );
480         }
481     }
482 
483     if( pFreeMgr )
484     {
485         delete pFreeMgr;
486         pMgr = NULL;
487     }
488     return bRet;
489 }
490