xref: /aoo41x/main/svtools/source/misc/ehdl.cxx (revision cdf0e10c)
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