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 : #include <boost/scoped_ptr.hpp>
32 :
33 :
34 0 : static sal_uInt16 aWndFunc(
35 : vcl::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 0 : VclPtr<MessBox> pBox;
93 0 : switch ( nFlags & 0xf000 )
94 : {
95 : case ERRCODE_MSG_ERROR:
96 0 : pBox.reset(VclPtr<ErrorBox>::Create(pWin, eBits, aErr));
97 0 : break;
98 :
99 : case ERRCODE_MSG_WARNING:
100 0 : pBox.reset(VclPtr<WarningBox>::Create(pWin, eBits, aErr));
101 0 : break;
102 :
103 : case ERRCODE_MSG_INFO:
104 0 : pBox.reset(VclPtr<InfoBox>::Create(pWin, aErr));
105 0 : break;
106 :
107 : case ERRCODE_MSG_QUERY:
108 0 : pBox.reset(VclPtr<QueryBox>::Create(pWin, eBits, aErr));
109 0 : break;
110 :
111 : default:
112 : {
113 : SAL_WARN( "svtools.misc", "no MessBox type");
114 0 : return ERRCODE_BUTTON_OK;
115 : }
116 : }
117 :
118 0 : sal_uInt16 nRet = RET_CANCEL;
119 0 : switch ( pBox->Execute() )
120 : {
121 : case RET_OK:
122 0 : nRet = ERRCODE_BUTTON_OK;
123 0 : break;
124 : case RET_CANCEL:
125 0 : nRet = ERRCODE_BUTTON_CANCEL;
126 0 : break;
127 : case RET_RETRY:
128 0 : nRet = ERRCODE_BUTTON_RETRY;
129 0 : break;
130 : case RET_YES:
131 0 : nRet = ERRCODE_BUTTON_YES;
132 0 : break;
133 : case RET_NO:
134 0 : nRet = ERRCODE_BUTTON_NO;
135 0 : break;
136 : default:
137 : SAL_WARN( "svtools.misc", "Unknown MessBox return value" );
138 0 : break;
139 : }
140 0 : return nRet;
141 : }
142 :
143 :
144 :
145 870 : SfxErrorHandler::SfxErrorHandler(sal_uInt16 nIdP, sal_uLong lStartP, sal_uLong lEndP, ResMgr *pMgrP) :
146 :
147 870 : lStart(lStartP), lEnd(lEndP), nId(nIdP), pMgr(pMgrP), pFreeMgr( NULL )
148 :
149 : {
150 870 : RegisterDisplay(&aWndFunc);
151 870 : if( ! pMgr )
152 : {
153 208 : pFreeMgr = pMgr = ResMgr::CreateResMgr("ofa", Application::GetSettings().GetUILanguageTag() );
154 : }
155 870 : }
156 :
157 :
158 :
159 1458 : SfxErrorHandler::~SfxErrorHandler()
160 : {
161 524 : delete pFreeMgr;
162 934 : }
163 :
164 :
165 :
166 0 : bool SfxErrorHandler::CreateString(
167 : const ErrorInfo *pErr, OUString &rStr, sal_uInt16& nFlags) const
168 :
169 : /* [Description]
170 :
171 : Assemble error string for the ErrorInfo pErr.
172 :
173 : */
174 :
175 : {
176 0 : sal_uLong nErrCode = pErr->GetErrorCode() & ERRCODE_ERROR_MASK;
177 0 : if( nErrCode>=lEnd || nErrCode<=lStart )
178 0 : return false;
179 0 : const MessageInfo *pMsgInfo = PTR_CAST(MessageInfo,pErr);
180 0 : if(pMsgInfo)
181 : {
182 0 : if(GetMessageString(nErrCode, rStr, nFlags))
183 : {
184 0 : rStr = rStr.replaceAll("$(ARG1)", pMsgInfo->GetMessageArg());
185 0 : return true;
186 : }
187 : }
188 0 : else if(GetErrorString(nErrCode, rStr, nFlags))
189 : {
190 0 : const StringErrorInfo *pStringInfo = PTR_CAST(StringErrorInfo,pErr);
191 0 : if(pStringInfo)
192 : {
193 0 : rStr = rStr.replaceAll(OUString("$(ARG1)"),
194 0 : pStringInfo->GetErrorString());
195 : }
196 : else
197 : {
198 0 : const TwoStringErrorInfo * pTwoStringInfo = PTR_CAST(TwoStringErrorInfo,
199 : pErr);
200 0 : if (pTwoStringInfo)
201 : {
202 0 : rStr = rStr.replaceAll("$(ARG1)", pTwoStringInfo->GetArg1());
203 0 : rStr = rStr.replaceAll("$(ARG2)", pTwoStringInfo->GetArg2());
204 : }
205 : }
206 0 : return true;
207 : }
208 0 : return false;
209 : }
210 :
211 :
212 :
213 0 : class ResString: public OUString
214 :
215 : /* [Description]
216 :
217 : Helpclass to read a string and optional ExtraData from
218 : a string Resource.
219 :
220 : */
221 :
222 : {
223 : sal_uInt16 nFlags;
224 : public:
225 0 : sal_uInt16 GetFlags() const {return nFlags;}
226 0 : const OUString & GetString() const {return *this;}
227 : explicit ResString( ResId &rId);
228 : };
229 :
230 :
231 :
232 0 : ResString::ResString(ResId & rId):
233 0 : OUString(rId.SetAutoRelease(false).toString()),
234 0 : nFlags(0)
235 : {
236 0 : ResMgr * pResMgr = rId.GetResMgr();
237 : // String ctor temporarily sets global ResManager
238 0 : if (pResMgr->GetRemainSize())
239 0 : nFlags = sal_uInt16(pResMgr->ReadShort());
240 0 : rId.SetAutoRelease(true);
241 0 : pResMgr->PopContext();
242 0 : }
243 :
244 :
245 :
246 : struct ErrorResource_Impl : private Resource
247 :
248 : /* [Description]
249 :
250 : Helpclass for access to string sub-resources of a resource
251 : */
252 :
253 : {
254 :
255 : ResId aResId;
256 :
257 0 : ErrorResource_Impl(ResId& rErrIdP, sal_uInt16 nId)
258 0 : : Resource(rErrIdP),aResId(nId,*rErrIdP.GetResMgr()){}
259 :
260 0 : ~ErrorResource_Impl() { FreeResource(); }
261 :
262 0 : operator ResString() { return ResString( aResId ); }
263 0 : operator bool() { return IsAvailableRes(aResId.SetRT(RSC_STRING)); }
264 :
265 : };
266 :
267 :
268 0 : bool SfxErrorHandler::GetClassString(sal_uLong lClassId, OUString &rStr) const
269 :
270 : /* [Description]
271 :
272 : Creates the string for the class of the error. Will always
273 : be read from the resource of the Sfx.
274 :
275 : */
276 :
277 : {
278 0 : bool bRet = false;
279 0 : boost::scoped_ptr<ResMgr> pResMgr(ResMgr::CreateResMgr("ofa", Application::GetSettings().GetUILanguageTag() ));
280 0 : if( pResMgr )
281 : {
282 0 : ResId aId(RID_ERRHDL, *pResMgr );
283 0 : ErrorResource_Impl aEr(aId, (sal_uInt16)lClassId);
284 0 : if(aEr)
285 : {
286 0 : rStr = static_cast<ResString>(aEr).GetString();
287 0 : bRet = true;
288 0 : }
289 : }
290 0 : return bRet;
291 : }
292 :
293 :
294 :
295 0 : bool SfxErrorHandler::GetMessageString(
296 : sal_uLong lErrId, OUString &rStr, sal_uInt16 &nFlags) const
297 :
298 : /* [Description]
299 :
300 : Creates the string to output a message box
301 :
302 : */
303 :
304 : {
305 0 : bool bRet = false;
306 0 : boost::scoped_ptr<ResId> pResId(new ResId(nId, *pMgr));
307 :
308 0 : ErrorResource_Impl aEr(*pResId, (sal_uInt16)lErrId);
309 0 : if(aEr)
310 : {
311 0 : ResString aErrorString(aEr);
312 0 : sal_uInt16 nResFlags = aErrorString.GetFlags();
313 0 : if( nResFlags )
314 0 : nFlags=aErrorString.GetFlags();
315 0 : rStr = aErrorString.GetString();
316 0 : bRet = true;
317 : }
318 :
319 0 : return bRet;
320 : }
321 :
322 :
323 :
324 0 : bool SfxErrorHandler::GetErrorString(
325 : sal_uLong lErrId, OUString &rStr, sal_uInt16 &nFlags) const
326 :
327 : /* [Description]
328 :
329 : Creates the error string for the actual error
330 : without its class
331 :
332 : */
333 :
334 : {
335 0 : SolarMutexGuard aGuard;
336 :
337 0 : bool bRet = false;
338 0 : rStr = SvtResId(RID_ERRHDL_CLASS).toString();
339 0 : ResId aResId(nId, *pMgr);
340 :
341 : {
342 0 : ErrorResource_Impl aEr(aResId, (sal_uInt16)lErrId);
343 0 : if(aEr)
344 : {
345 0 : ResString aErrorString(aEr);
346 :
347 0 : sal_uInt16 nResFlags = aErrorString.GetFlags();
348 0 : if ( nResFlags )
349 0 : nFlags = nResFlags;
350 0 : rStr = rStr.replaceAll(OUString("$(ERROR)"), aErrorString.GetString());
351 0 : bRet = true;
352 : }
353 : else
354 0 : bRet = false;
355 : }
356 :
357 0 : if( bRet )
358 : {
359 0 : OUString aErrStr;
360 : GetClassString(lErrId & ERRCODE_CLASS_MASK,
361 0 : aErrStr);
362 0 : if(!aErrStr.isEmpty())
363 0 : aErrStr += ".\n";
364 0 : rStr = rStr.replaceAll("$(CLASS)",aErrStr);
365 : }
366 :
367 0 : return bRet;
368 : }
369 :
370 :
371 :
372 0 : SfxErrorContext::SfxErrorContext(
373 : sal_uInt16 nCtxIdP, vcl::Window *pWindow, sal_uInt16 nResIdP, ResMgr *pMgrP)
374 0 : : ErrorContext(pWindow), nCtxId(nCtxIdP), nResId(nResIdP), pMgr(pMgrP)
375 : {
376 0 : if( nResId==USHRT_MAX )
377 0 : nResId=RID_ERRCTX;
378 0 : }
379 :
380 :
381 :
382 2008 : SfxErrorContext::SfxErrorContext(
383 : sal_uInt16 nCtxIdP, const OUString &aArg1P, vcl::Window *pWindow,
384 : sal_uInt16 nResIdP, ResMgr *pMgrP)
385 : : ErrorContext(pWindow), nCtxId(nCtxIdP), nResId(nResIdP), pMgr(pMgrP),
386 2008 : aArg1(aArg1P)
387 : {
388 2008 : if( nResId==USHRT_MAX )
389 2008 : nResId=RID_ERRCTX;
390 2008 : }
391 :
392 :
393 :
394 0 : bool SfxErrorContext::GetString(sal_uLong nErrId, OUString &rStr)
395 :
396 : /* [Description]
397 :
398 : Constructs the description of a error context
399 : */
400 :
401 : {
402 0 : bool bRet = false;
403 0 : ResMgr* pFreeMgr = NULL;
404 0 : if( ! pMgr )
405 : {
406 0 : pFreeMgr = pMgr = ResMgr::CreateResMgr("ofa", Application::GetSettings().GetUILanguageTag() );
407 : }
408 0 : if( pMgr )
409 : {
410 0 : SolarMutexGuard aGuard;
411 :
412 0 : ResId aResId( nResId, *pMgr );
413 :
414 0 : ErrorResource_Impl aTestEr( aResId, nCtxId );
415 0 : if ( aTestEr )
416 : {
417 0 : rStr = static_cast<ResString>(aTestEr).GetString();
418 0 : rStr = rStr.replaceAll(OUString("$(ARG1)"), aArg1 );
419 0 : bRet = true;
420 : }
421 : else
422 : {
423 : SAL_WARN( "svtools.misc", "ErrorContext cannot find the resource" );
424 0 : bRet = false;
425 : }
426 :
427 0 : if ( bRet )
428 : {
429 0 : sal_uInt16 nId = ( nErrId & ERRCODE_WARNING_MASK ) ? ERRCTX_WARNING : ERRCTX_ERROR;
430 0 : ResId aSfxResId( RID_ERRCTX, *pMgr );
431 0 : ErrorResource_Impl aEr( aSfxResId, nId );
432 0 : rStr = rStr.replaceAll( OUString("$(ERR)"), static_cast<ResString>(aEr).GetString() );
433 0 : }
434 : }
435 :
436 0 : if( pFreeMgr )
437 : {
438 0 : delete pFreeMgr;
439 0 : pMgr = NULL;
440 : }
441 0 : return bRet;
442 : }
443 :
444 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|