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