Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <osl/mutex.hxx>
21 : #include <tools/rcid.h>
22 : #include <tools/wintypes.hxx>
23 : #include <vcl/msgbox.hxx>
24 : #include <vcl/svapp.hxx>
25 : #include <vcl/settings.hxx>
26 :
27 : #include <svtools/ehdl.hxx>
28 : #include <svtools/svtresid.hxx>
29 : #include <svtools/svtools.hrc>
30 : #include <svtools/sfxecode.hxx>
31 :
32 :
33 :
34 0 : static sal_uInt16 aWndFunc(
35 : Window *pWin, // Parent of the dialog
36 : sal_uInt16 nFlags,
37 : const OUString &rErr, // error text
38 : const OUString &rAction) // action text
39 :
40 : /* [Description]
41 :
42 : Draw an errorbox on the screen. Depending on nFlags
43 : Error/Info etc. boxes with the requested buttosn are shown.
44 :
45 : Returnvalue is the button pressed
46 :
47 : */
48 :
49 :
50 : {
51 0 : SolarMutexGuard aGuard;
52 :
53 : // determine necessary WinBits from the flags
54 0 : WinBits eBits=0;
55 0 : if ( (ERRCODE_BUTTON_CANCEL|ERRCODE_BUTTON_RETRY) == (nFlags & (ERRCODE_BUTTON_CANCEL|ERRCODE_BUTTON_RETRY)) )
56 0 : eBits = WB_RETRY_CANCEL;
57 0 : else if ( ERRCODE_BUTTON_OK_CANCEL == (nFlags & ERRCODE_BUTTON_OK_CANCEL) )
58 0 : eBits = WB_OK_CANCEL;
59 0 : else if ( ERRCODE_BUTTON_OK == (nFlags & ERRCODE_BUTTON_OK) )
60 0 : eBits = WB_OK;
61 0 : else if ( ERRCODE_BUTTON_YES_NO_CANCEL == (nFlags & ERRCODE_BUTTON_YES_NO_CANCEL) )
62 0 : eBits = WB_YES_NO_CANCEL;
63 0 : else if ( ERRCODE_BUTTON_YES_NO == (nFlags & ERRCODE_BUTTON_YES_NO) )
64 0 : eBits = WB_YES_NO;
65 :
66 0 : switch(nFlags & 0x0f00)
67 : {
68 : case ERRCODE_BUTTON_DEF_OK:
69 0 : eBits |= WB_DEF_OK;
70 0 : break;
71 :
72 : case ERRCODE_BUTTON_DEF_CANCEL:
73 0 : eBits |= WB_DEF_CANCEL;
74 0 : break;
75 :
76 : case ERRCODE_BUTTON_DEF_YES:
77 0 : eBits |= WB_DEF_YES;
78 0 : break;
79 :
80 : case ERRCODE_BUTTON_DEF_NO:
81 0 : eBits |= WB_DEF_NO;
82 0 : break;
83 : }
84 :
85 0 : OUString aErr(SvtResId(STR_ERR_HDLMESS).toString());
86 0 : OUString aAction(rAction);
87 0 : if ( !aAction.isEmpty() )
88 0 : aAction += ":\n";
89 0 : aErr = aErr.replaceAll("$(ACTION)", aAction);
90 0 : aErr = aErr.replaceAll("$(ERROR)", rErr);
91 :
92 : MessBox* pBox;
93 0 : switch ( nFlags & 0xf000 )
94 : {
95 : case ERRCODE_MSG_ERROR:
96 0 : pBox = new ErrorBox(pWin, eBits, aErr);
97 0 : break;
98 :
99 : case ERRCODE_MSG_WARNING:
100 0 : pBox = new WarningBox(pWin, eBits, aErr);
101 0 : break;
102 :
103 : case ERRCODE_MSG_INFO:
104 0 : pBox = new InfoBox(pWin, aErr);
105 0 : break;
106 :
107 : case ERRCODE_MSG_QUERY:
108 0 : pBox = new QueryBox(pWin, eBits, aErr);
109 0 : break;
110 :
111 : default:
112 : {
113 : SAL_WARN( "svtools.misc", "no MessBox type");
114 0 : pBox = NULL;
115 0 : return ERRCODE_BUTTON_OK;
116 : }
117 : }
118 :
119 0 : sal_uInt16 nRet = RET_CANCEL;
120 0 : switch ( pBox->Execute() )
121 : {
122 : case RET_OK:
123 0 : nRet = ERRCODE_BUTTON_OK;
124 0 : break;
125 : case RET_CANCEL:
126 0 : nRet = ERRCODE_BUTTON_CANCEL;
127 0 : break;
128 : case RET_RETRY:
129 0 : nRet = ERRCODE_BUTTON_RETRY;
130 0 : break;
131 : case RET_YES:
132 0 : nRet = ERRCODE_BUTTON_YES;
133 0 : break;
134 : case RET_NO:
135 0 : nRet = ERRCODE_BUTTON_NO;
136 0 : break;
137 : default:
138 : SAL_WARN( "svtools.misc", "Unknown MessBox return value" );
139 0 : break;
140 : }
141 0 : delete pBox;
142 0 : return nRet;
143 : }
144 :
145 :
146 :
147 0 : SfxErrorHandler::SfxErrorHandler(sal_uInt16 nIdP, sal_uLong lStartP, sal_uLong lEndP, ResMgr *pMgrP) :
148 :
149 0 : lStart(lStartP), lEnd(lEndP), nId(nIdP), pMgr(pMgrP), pFreeMgr( NULL )
150 :
151 : {
152 0 : RegisterDisplay(&aWndFunc);
153 0 : if( ! pMgr )
154 : {
155 0 : pFreeMgr = pMgr = ResMgr::CreateResMgr("ofa", Application::GetSettings().GetUILanguageTag() );
156 : }
157 0 : }
158 :
159 :
160 :
161 0 : SfxErrorHandler::~SfxErrorHandler()
162 : {
163 0 : delete pFreeMgr;
164 0 : }
165 :
166 :
167 :
168 0 : bool SfxErrorHandler::CreateString(
169 : const ErrorInfo *pErr, OUString &rStr, sal_uInt16& nFlags) const
170 :
171 : /* [Description]
172 :
173 : Assemble error string for the ErrorInfo pErr.
174 :
175 : */
176 :
177 : {
178 0 : sal_uLong nErrCode = pErr->GetErrorCode() & ERRCODE_ERROR_MASK;
179 0 : if( nErrCode>=lEnd || nErrCode<=lStart )
180 0 : return false;
181 0 : MessageInfo *pMsgInfo=PTR_CAST(MessageInfo,pErr);
182 0 : if(pMsgInfo)
183 : {
184 0 : if(GetMessageString(nErrCode, rStr, nFlags))
185 : {
186 0 : rStr = rStr.replaceAll("$(ARG1)", pMsgInfo->GetMessageArg());
187 0 : return true;
188 : }
189 : }
190 0 : else if(GetErrorString(nErrCode, rStr, nFlags))
191 : {
192 0 : StringErrorInfo *pStringInfo=PTR_CAST(StringErrorInfo,pErr);
193 0 : if(pStringInfo)
194 : {
195 0 : rStr = rStr.replaceAll(OUString("$(ARG1)"),
196 0 : pStringInfo->GetErrorString());
197 : }
198 : else
199 : {
200 0 : TwoStringErrorInfo * pTwoStringInfo = PTR_CAST(TwoStringErrorInfo,
201 : pErr);
202 0 : if (pTwoStringInfo)
203 : {
204 0 : rStr = rStr.replaceAll("$(ARG1)", pTwoStringInfo->GetArg1());
205 0 : rStr = rStr.replaceAll("$(ARG2)", pTwoStringInfo->GetArg2());
206 : }
207 : }
208 0 : return true;
209 : }
210 0 : return false;
211 : }
212 :
213 :
214 :
215 0 : class ResString: public OUString
216 :
217 : /* [Description]
218 :
219 : Helpclass to read a string and optional ExtraData from
220 : a string Resource.
221 :
222 : */
223 :
224 : {
225 : sal_uInt16 nFlags;
226 : public:
227 0 : sal_uInt16 GetFlags() const {return nFlags;}
228 0 : const OUString & GetString() const {return *this;}
229 : ResString( ResId &rId);
230 : };
231 :
232 :
233 :
234 0 : ResString::ResString(ResId & rId):
235 0 : OUString(rId.SetAutoRelease(false).toString()),
236 0 : nFlags(0)
237 : {
238 0 : ResMgr * pResMgr = rId.GetResMgr();
239 : // String ctor temporarily sets global ResManager
240 0 : if (pResMgr->GetRemainSize())
241 0 : nFlags = sal_uInt16(pResMgr->ReadShort());
242 0 : rId.SetAutoRelease(true);
243 0 : pResMgr->PopContext();
244 0 : }
245 :
246 :
247 :
248 : struct ErrorResource_Impl : private Resource
249 :
250 : /* [Description]
251 :
252 : Helpclass for access to string sub-resources of a resource
253 : */
254 :
255 : {
256 :
257 : ResId aResId;
258 :
259 0 : ErrorResource_Impl(ResId& rErrIdP, sal_uInt16 nId)
260 0 : : Resource(rErrIdP),aResId(nId,*rErrIdP.GetResMgr()){}
261 :
262 0 : ~ErrorResource_Impl() { FreeResource(); }
263 :
264 0 : operator ResString(){ return ResString( aResId ); }
265 0 : operator sal_Bool(){return IsAvailableRes(aResId.SetRT(RSC_STRING));}
266 :
267 : };
268 :
269 :
270 0 : bool SfxErrorHandler::GetClassString(sal_uLong lClassId, OUString &rStr) const
271 :
272 : /* [Description]
273 :
274 : Creates the string for the class of the error. Will always
275 : be read from the resource of the Sfx.
276 :
277 : */
278 :
279 : {
280 0 : bool bRet = false;
281 0 : ResMgr* pResMgr = ResMgr::CreateResMgr("ofa", Application::GetSettings().GetUILanguageTag() );
282 0 : if( pResMgr )
283 : {
284 0 : ResId aId(RID_ERRHDL, *pResMgr );
285 0 : ErrorResource_Impl aEr(aId, (sal_uInt16)lClassId);
286 0 : if(aEr)
287 : {
288 0 : rStr=((ResString)aEr).GetString();
289 0 : bRet = true;
290 0 : }
291 : }
292 0 : delete pResMgr;
293 0 : return bRet;
294 : }
295 :
296 :
297 :
298 0 : bool SfxErrorHandler::GetMessageString(
299 : sal_uLong lErrId, OUString &rStr, sal_uInt16 &nFlags) const
300 :
301 : /* [Description]
302 :
303 : Creates the string to output a message box
304 :
305 : */
306 :
307 : {
308 0 : bool bRet = false;
309 0 : ResId *pResId= new ResId(nId, *pMgr);
310 :
311 0 : ErrorResource_Impl aEr(*pResId, (sal_uInt16)lErrId);
312 0 : if(aEr)
313 : {
314 0 : ResString aErrorString(aEr);
315 0 : sal_uInt16 nResFlags = aErrorString.GetFlags();
316 0 : if( nResFlags )
317 0 : nFlags=aErrorString.GetFlags();
318 0 : rStr = aErrorString.GetString();
319 0 : bRet = true;
320 : }
321 :
322 0 : delete pResId;
323 0 : return bRet;
324 : }
325 :
326 :
327 :
328 0 : bool SfxErrorHandler::GetErrorString(
329 : sal_uLong lErrId, OUString &rStr, sal_uInt16 &nFlags) const
330 :
331 : /* [Description]
332 :
333 : Creates the error string for the actual error
334 : without its class
335 :
336 : */
337 :
338 : {
339 0 : SolarMutexGuard aGuard;
340 :
341 0 : bool bRet = false;
342 0 : rStr = SvtResId(RID_ERRHDL_CLASS).toString();
343 0 : ResId aResId(nId, *pMgr);
344 :
345 : {
346 0 : ErrorResource_Impl aEr(aResId, (sal_uInt16)lErrId);
347 0 : if(aEr)
348 : {
349 0 : ResString aErrorString(aEr);
350 :
351 0 : sal_uInt16 nResFlags = aErrorString.GetFlags();
352 0 : if ( nResFlags )
353 0 : nFlags = nResFlags;
354 0 : rStr = rStr.replaceAll(OUString("$(ERROR)"), aErrorString.GetString());
355 0 : bRet = true;
356 : }
357 : else
358 0 : bRet = false;
359 : }
360 :
361 0 : if( bRet )
362 : {
363 0 : OUString aErrStr;
364 : GetClassString(lErrId & ERRCODE_CLASS_MASK,
365 0 : aErrStr);
366 0 : if(!aErrStr.isEmpty())
367 0 : aErrStr += ".\n";
368 0 : rStr = rStr.replaceAll("$(CLASS)",aErrStr);
369 : }
370 :
371 0 : return bRet;
372 : }
373 :
374 :
375 :
376 0 : SfxErrorContext::SfxErrorContext(
377 : sal_uInt16 nCtxIdP, Window *pWindow, sal_uInt16 nResIdP, ResMgr *pMgrP)
378 0 : : ErrorContext(pWindow), nCtxId(nCtxIdP), nResId(nResIdP), pMgr(pMgrP)
379 : {
380 0 : if( nResId==USHRT_MAX )
381 0 : nResId=RID_ERRCTX;
382 0 : }
383 :
384 :
385 :
386 0 : SfxErrorContext::SfxErrorContext(
387 : sal_uInt16 nCtxIdP, const OUString &aArg1P, Window *pWindow,
388 : sal_uInt16 nResIdP, ResMgr *pMgrP)
389 : : ErrorContext(pWindow), nCtxId(nCtxIdP), nResId(nResIdP), pMgr(pMgrP),
390 0 : aArg1(aArg1P)
391 : {
392 0 : if( nResId==USHRT_MAX )
393 0 : nResId=RID_ERRCTX;
394 0 : }
395 :
396 :
397 :
398 0 : bool SfxErrorContext::GetString(sal_uLong nErrId, OUString &rStr)
399 :
400 : /* [Description]
401 :
402 : Constructs the description of a error context
403 : */
404 :
405 : {
406 0 : bool bRet = false;
407 0 : ResMgr* pFreeMgr = NULL;
408 0 : if( ! pMgr )
409 : {
410 0 : pFreeMgr = pMgr = ResMgr::CreateResMgr("ofa", Application::GetSettings().GetUILanguageTag() );
411 : }
412 0 : if( pMgr )
413 : {
414 0 : SolarMutexGuard aGuard;
415 :
416 0 : ResId aResId( nResId, *pMgr );
417 :
418 0 : ErrorResource_Impl aTestEr( aResId, nCtxId );
419 0 : if ( aTestEr )
420 : {
421 0 : rStr = ( (ResString)aTestEr ).GetString();
422 0 : rStr = rStr.replaceAll(OUString("$(ARG1)"), aArg1 );
423 0 : bRet = true;
424 : }
425 : else
426 : {
427 : SAL_WARN( "svtools.misc", "ErrorContext cannot find the resource" );
428 0 : bRet = false;
429 : }
430 :
431 0 : if ( bRet )
432 : {
433 0 : sal_uInt16 nId = ( nErrId & ERRCODE_WARNING_MASK ) ? ERRCTX_WARNING : ERRCTX_ERROR;
434 0 : ResId aSfxResId( RID_ERRCTX, *pMgr );
435 0 : ErrorResource_Impl aEr( aSfxResId, nId );
436 0 : rStr = rStr.replaceAll( OUString("$(ERR)"), ( (ResString)aEr ).GetString() );
437 0 : }
438 : }
439 :
440 0 : if( pFreeMgr )
441 : {
442 0 : delete pFreeMgr;
443 0 : pMgr = NULL;
444 : }
445 0 : return bRet;
446 : }
447 :
448 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|