1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "sqlmessage.hxx"
22 #include "dbu_dlg.hrc"
23 #include "sqlmessage.hrc"
24 #include <com/sun/star/sdbc/SQLException.hpp>
25 #include <com/sun/star/sdb/SQLContext.hpp>
26 #include <vcl/fixed.hxx>
27 #include <osl/diagnose.h>
28 #include <svtools/treelistbox.hxx>
29 #include "svtools/treelistentry.hxx"
30 #include <svtools/svmedit.hxx>
31 #include <connectivity/dbexception.hxx>
32 #include <connectivity/sqlerror.hxx>
33 #include <vcl/msgbox.hxx>
34 #include <unotools/configmgr.hxx>
35 #include <sfx2/sfxuno.hxx>
36 #include "dbaccess_helpid.hrc"
37 #include "UITools.hxx"
38 #include "moduledbu.hxx"
40 #include <tools/urlobj.hxx>
42 #define RET_MORE RET_RETRY + 1
44 #define DIALOG_WIDTH 220
45 #define OUTER_MARGIN 6
47 #define INNER_PADDING 3
48 #define TEXT_POS_X ( OUTER_MARGIN + IMAGE_SIZE + INNER_PADDING )
50 using namespace dbtools
;
51 using namespace com::sun::star::uno
;
52 using namespace com::sun::star::sdb
;
53 using namespace com::sun::star::sdbc
;
55 //.........................................................................
58 //.........................................................................
62 //------------------------------------------------------------------------------
66 virtual Image
getImage() const = 0;
68 virtual ~IImageProvider() { }
71 //------------------------------------------------------------------------------
75 virtual String
getLabel() const = 0;
77 virtual ~ILabelProvider() { };
80 //------------------------------------------------------------------------------
81 class ImageProvider
: public IImageProvider
84 sal_uInt16 m_defaultImageID
;
86 mutable Image m_defaultImage
;
89 ImageProvider( sal_uInt16 _defaultImageID
)
90 :m_defaultImageID( _defaultImageID
)
94 virtual Image
getImage() const
96 if ( !m_defaultImage
)
97 m_defaultImage
= Image( ModuleRes( m_defaultImageID
) );
98 return m_defaultImage
;
102 //------------------------------------------------------------------------------
103 class LabelProvider
: public ILabelProvider
108 LabelProvider( sal_uInt16 _labelResourceID
)
109 :m_label( ModuleRes( _labelResourceID
) )
113 virtual String
getLabel() const
119 //------------------------------------------------------------------------------
120 class ProviderFactory
123 mutable ::boost::shared_ptr
< IImageProvider
> m_pErrorImage
;
124 mutable ::boost::shared_ptr
< IImageProvider
> m_pWarningsImage
;
125 mutable ::boost::shared_ptr
< IImageProvider
> m_pInfoImage
;
126 mutable ::boost::shared_ptr
< ILabelProvider
> m_pErrorLabel
;
127 mutable ::boost::shared_ptr
< ILabelProvider
> m_pWarningsLabel
;
128 mutable ::boost::shared_ptr
< ILabelProvider
> m_pInfoLabel
;
135 ::boost::shared_ptr
< IImageProvider
> getImageProvider( SQLExceptionInfo::TYPE _eType
) const
137 ::boost::shared_ptr
< IImageProvider
>* ppProvider( &m_pErrorImage
);
138 sal_uInt16
nNormalImageID( BMP_EXCEPTION_ERROR
);
142 case SQLExceptionInfo::SQL_WARNING
:
143 ppProvider
= &m_pWarningsImage
;
144 nNormalImageID
= BMP_EXCEPTION_WARNING
;
147 case SQLExceptionInfo::SQL_CONTEXT
:
148 ppProvider
= &m_pInfoImage
;
149 nNormalImageID
= BMP_EXCEPTION_INFO
;
156 if ( !ppProvider
->get() )
157 ppProvider
->reset( new ImageProvider( nNormalImageID
) );
161 ::boost::shared_ptr
< ILabelProvider
> getLabelProvider( SQLExceptionInfo::TYPE _eType
, bool _bSubLabel
) const
163 ::boost::shared_ptr
< ILabelProvider
>* ppProvider( &m_pErrorLabel
);
164 sal_uInt16
nLabelID( STR_EXCEPTION_ERROR
);
168 case SQLExceptionInfo::SQL_WARNING
:
169 ppProvider
= &m_pWarningsLabel
;
170 nLabelID
= STR_EXCEPTION_WARNING
;
173 case SQLExceptionInfo::SQL_CONTEXT
:
174 ppProvider
= &m_pInfoLabel
;
175 nLabelID
= _bSubLabel
? STR_EXCEPTION_DETAILS
: STR_EXCEPTION_INFO
;
181 if ( !ppProvider
->get() )
182 ppProvider
->reset( new LabelProvider( nLabelID
) );
188 //------------------------------------------------------------------------------
189 /// a stripped version of the SQLException, packed for displaying
190 struct ExceptionDisplayInfo
192 SQLExceptionInfo::TYPE eType
;
194 ::boost::shared_ptr
< IImageProvider
> pImageProvider
;
195 ::boost::shared_ptr
< ILabelProvider
> pLabelProvider
;
203 ExceptionDisplayInfo() : eType( SQLExceptionInfo::UNDEFINED
), bSubEntry( false ) { }
204 ExceptionDisplayInfo( SQLExceptionInfo::TYPE _eType
) : eType( _eType
), bSubEntry( false ) { }
207 static bool lcl_hasDetails( const ExceptionDisplayInfo
& _displayInfo
)
209 return ( _displayInfo
.sErrorCode
.Len() )
210 || ( _displayInfo
.sSQLState
.Len()
211 && !_displayInfo
.sSQLState
.EqualsAscii( "S1000" )
215 typedef ::std::vector
< ExceptionDisplayInfo
> ExceptionDisplayChain
;
217 //------------------------------------------------------------------------------
218 /// strips the [OOoBase] vendor identifier from the given error message, if applicable
219 OUString
lcl_stripOOoBaseVendor( const OUString
& _rErrorMessage
)
221 OUString
sErrorMessage( _rErrorMessage
);
223 const OUString
sVendorIdentifier( ::connectivity::SQLError::getMessagePrefix() );
224 if ( sErrorMessage
.indexOf( sVendorIdentifier
) == 0 )
226 // characters to strip
227 sal_Int32
nStripLen( sVendorIdentifier
.getLength() );
228 // usually, there should be a whitespace between the vendor and the real message
229 while ( ( sErrorMessage
.getLength() > nStripLen
)
230 && ( sErrorMessage
[nStripLen
] == ' ' )
233 sErrorMessage
= sErrorMessage
.copy( nStripLen
);
236 return sErrorMessage
;
239 //------------------------------------------------------------------------------
240 void lcl_buildExceptionChain( const SQLExceptionInfo
& _rErrorInfo
, const ProviderFactory
& _rFactory
, ExceptionDisplayChain
& _out_rChain
)
243 ExceptionDisplayChain empty
;
244 _out_rChain
.swap( empty
);
247 SQLExceptionIteratorHelper
iter( _rErrorInfo
);
248 while ( iter
.hasMoreElements() )
250 // current chain element
251 SQLExceptionInfo aCurrentElement
;
252 iter
.next( aCurrentElement
);
254 const SQLException
* pCurrentError
= (const SQLException
*)aCurrentElement
;
255 OSL_ENSURE( pCurrentError
, "lcl_buildExceptionChain: iterator failure!" );
256 // hasMoreElements should not have returned <TRUE/> in this case
258 ExceptionDisplayInfo
aDisplayInfo( aCurrentElement
.getType() );
260 aDisplayInfo
.sMessage
= pCurrentError
->Message
.trim();
261 aDisplayInfo
.sSQLState
= pCurrentError
->SQLState
;
262 if ( pCurrentError
->ErrorCode
)
263 aDisplayInfo
.sErrorCode
= OUString::number( pCurrentError
->ErrorCode
);
265 if ( !aDisplayInfo
.sMessage
.Len()
266 && !lcl_hasDetails( aDisplayInfo
)
269 OSL_FAIL( "lcl_buildExceptionChain: useles exception: no state, no error code, no message!" );
273 aDisplayInfo
.pImageProvider
= _rFactory
.getImageProvider( aCurrentElement
.getType() );
274 aDisplayInfo
.pLabelProvider
= _rFactory
.getLabelProvider( aCurrentElement
.getType(), false );
276 _out_rChain
.push_back( aDisplayInfo
);
278 if ( aCurrentElement
.getType() == SQLExceptionInfo::SQL_CONTEXT
)
280 const SQLContext
* pContext
= (const SQLContext
*)aCurrentElement
;
281 if ( !pContext
->Details
.isEmpty() )
283 ExceptionDisplayInfo
aSubInfo( aCurrentElement
.getType() );
285 aSubInfo
.sMessage
= pContext
->Details
;
286 aSubInfo
.pImageProvider
= _rFactory
.getImageProvider( aCurrentElement
.getType() );
287 aSubInfo
.pLabelProvider
= _rFactory
.getLabelProvider( aCurrentElement
.getType(), true );
288 aSubInfo
.bSubEntry
= true;
290 _out_rChain
.push_back( aSubInfo
);
296 //------------------------------------------------------------------------------
297 void lcl_insertExceptionEntry( SvTreeListBox
& _rList
, size_t _nElementPos
, const ExceptionDisplayInfo
& _rEntry
)
299 Image
aEntryImage( _rEntry
.pImageProvider
->getImage() );
300 SvTreeListEntry
* pListEntry
=
301 _rList
.InsertEntry( _rEntry
.pLabelProvider
->getLabel(), aEntryImage
, aEntryImage
);
302 pListEntry
->SetUserData( reinterpret_cast< void* >( _nElementPos
) );
306 //==============================================================================
307 class OExceptionChainDialog
: public ModalDialog
310 FixedText m_aListLabel
;
311 SvTreeListBox m_aExceptionList
;
312 FixedText m_aDescLabel
;
313 MultiLineEdit m_aExceptionText
;
316 String m_sStatusLabel
;
317 String m_sErrorCodeLabel
;
319 ExceptionDisplayChain m_aExceptions
;
322 OExceptionChainDialog( Window
* pParent
, const ExceptionDisplayChain
& _rExceptions
);
323 ~OExceptionChainDialog();
326 DECL_LINK(OnExceptionSelected
, void*);
329 DBG_NAME(OExceptionChainDialog
)
330 //------------------------------------------------------------------------------
331 OExceptionChainDialog::OExceptionChainDialog( Window
* pParent
, const ExceptionDisplayChain
& _rExceptions
)
332 :ModalDialog(pParent
, ModuleRes(DLG_SQLEXCEPTIONCHAIN
))
333 ,m_aFrame (this, ModuleRes(FL_DETAILS
))
334 ,m_aListLabel (this, ModuleRes(FT_ERRORLIST
))
335 ,m_aExceptionList (this, ModuleRes(CTL_ERRORLIST
))
336 ,m_aDescLabel (this, ModuleRes(FT_DESCRIPTION
))
337 ,m_aExceptionText (this, ModuleRes(ME_DESCRIPTION
))
338 ,m_aOK (this, ModuleRes(PB_OK
))
339 ,m_aExceptions( _rExceptions
)
341 DBG_CTOR(OExceptionChainDialog
,NULL
);
343 m_sStatusLabel
= String( ModuleRes( STR_EXCEPTION_STATUS
) );
344 m_sErrorCodeLabel
= String( ModuleRes( STR_EXCEPTION_ERRORCODE
) );
348 m_aExceptionList
.SetSelectionMode(SINGLE_SELECTION
);
349 m_aExceptionList
.SetDragDropMode(0);
350 m_aExceptionList
.EnableInplaceEditing(sal_False
);
351 m_aExceptionList
.SetStyle(m_aExceptionList
.GetStyle() | WB_HASLINES
| WB_HASBUTTONS
| WB_HASBUTTONSATROOT
| WB_HSCROLL
);
353 m_aExceptionList
.SetSelectHdl(LINK(this, OExceptionChainDialog
, OnExceptionSelected
));
354 m_aExceptionList
.SetNodeDefaultImages( );
355 m_aExceptionText
.SetReadOnly(sal_True
);
357 bool bHave22018
= false;
358 size_t elementPos
= 0;
360 for ( ExceptionDisplayChain::const_iterator loop
= m_aExceptions
.begin();
361 loop
!= m_aExceptions
.end();
365 lcl_insertExceptionEntry( m_aExceptionList
, elementPos
, *loop
);
366 bHave22018
= loop
->sSQLState
.EqualsAscii( "22018" );
369 // if the error has the code 22018, then add an additional explanation
373 ProviderFactory aProviderFactory
;
375 ExceptionDisplayInfo aInfo22018
;
376 aInfo22018
.sMessage
= String( ModuleRes( STR_EXPLAN_STRINGCONVERSION_ERROR
) );
377 aInfo22018
.pLabelProvider
= aProviderFactory
.getLabelProvider( SQLExceptionInfo::SQL_CONTEXT
, false );
378 aInfo22018
.pImageProvider
= aProviderFactory
.getImageProvider( SQLExceptionInfo::SQL_CONTEXT
);
379 m_aExceptions
.push_back( aInfo22018
);
381 lcl_insertExceptionEntry( m_aExceptionList
, m_aExceptions
.size() - 1, aInfo22018
);
385 //------------------------------------------------------------------------------
386 OExceptionChainDialog::~OExceptionChainDialog()
388 DBG_DTOR(OExceptionChainDialog
,NULL
);
391 //------------------------------------------------------------------------------
392 IMPL_LINK_NOARG(OExceptionChainDialog
, OnExceptionSelected
)
394 SvTreeListEntry
* pSelected
= m_aExceptionList
.FirstSelected();
395 OSL_ENSURE(!pSelected
|| !m_aExceptionList
.NextSelected(pSelected
), "OExceptionChainDialog::OnExceptionSelected : multi selection ?");
401 size_t pos
= reinterpret_cast< size_t >( pSelected
->GetUserData() );
402 const ExceptionDisplayInfo
& aExceptionInfo( m_aExceptions
[ pos
] );
404 if ( aExceptionInfo
.sSQLState
.Len() )
406 sText
+= m_sStatusLabel
;
408 sText
+= aExceptionInfo
.sSQLState
;
412 if ( aExceptionInfo
.sErrorCode
.Len() )
414 sText
+= m_sErrorCodeLabel
;
416 sText
+= aExceptionInfo
.sErrorCode
;
420 if ( !sText
.isEmpty() )
423 sText
+= aExceptionInfo
.sMessage
;
426 m_aExceptionText
.SetText(sText
);
431 //==============================================================================
432 //= SQLMessageBox_Impl
433 //==============================================================================
434 struct SQLMessageBox_Impl
436 ExceptionDisplayChain aDisplayInfo
;
438 SQLMessageBox_Impl( const SQLExceptionInfo
& _rExceptionInfo
)
440 // transform the exception chain to a form more suitable for displaying it here
441 ProviderFactory aProviderFactory
;
442 lcl_buildExceptionChain( _rExceptionInfo
, aProviderFactory
, aDisplayInfo
);
446 //------------------------------------------------------------------------------
449 void lcl_positionInAppFont( const Window
& _rParent
, Window
& _rChild
, long _nX
, long _nY
, long _Width
, long _Height
)
451 Point aPos
= _rParent
.LogicToPixel( Point( _nX
, _nY
), MAP_APPFONT
);
452 Size aSize
= _rParent
.LogicToPixel( Size( _Width
, _Height
), MAP_APPFONT
);
453 _rChild
.SetPosSizePixel( aPos
, aSize
);
456 void lcl_addButton( ButtonDialog
& _rDialog
, StandardButtonType _eType
, bool _bDefault
)
458 sal_uInt16 nButtonID
= 0;
461 case BUTTON_YES
: nButtonID
= RET_YES
; break;
462 case BUTTON_NO
: nButtonID
= RET_NO
; break;
463 case BUTTON_OK
: nButtonID
= RET_OK
; break;
464 case BUTTON_CANCEL
: nButtonID
= RET_CANCEL
; break;
465 case BUTTON_RETRY
: nButtonID
= RET_RETRY
; break;
466 case BUTTON_HELP
: nButtonID
= RET_HELP
; break;
468 OSL_FAIL( "lcl_addButton: invalid button id!" );
471 _rDialog
.AddButton( _eType
, nButtonID
, _bDefault
? BUTTONDIALOG_DEFBUTTON
| BUTTONDIALOG_FOCUSBUTTON
: 0 );
475 //------------------------------------------------------------------------------
476 void OSQLMessageBox::impl_positionControls()
478 OSL_PRECOND( !m_pImpl
->aDisplayInfo
.empty(), "OSQLMessageBox::impl_positionControls: nothing to display at all?" );
481 if ( m_pImpl
->aDisplayInfo
.empty() )
483 const ExceptionDisplayInfo
* pSecondInfo
= NULL
;
485 const ExceptionDisplayInfo
& rFirstInfo
= *m_pImpl
->aDisplayInfo
.begin();
486 if ( m_pImpl
->aDisplayInfo
.size() > 1 )
487 pSecondInfo
= &m_pImpl
->aDisplayInfo
[1];
488 String sPrimary
, sSecondary
;
489 sPrimary
= rFirstInfo
.sMessage
;
490 // one or two texts to display?
493 // we show two elements in the main dialog if and only if one of
494 // - the first element in the chain is an SQLContext, and the second
495 // element denotes its sub entry
496 // - the first and the second element are both independent (i.e. the second
497 // is no sub entry), and none of them is a context.
498 bool bFirstElementIsContext
= ( rFirstInfo
.eType
== SQLExceptionInfo::SQL_CONTEXT
);
499 bool bSecondElementIsContext
= ( pSecondInfo
->eType
== SQLExceptionInfo::SQL_CONTEXT
);
501 if ( bFirstElementIsContext
&& pSecondInfo
->bSubEntry
)
502 sSecondary
= pSecondInfo
->sMessage
;
503 if ( !bFirstElementIsContext
&& !bSecondElementIsContext
)
504 sSecondary
= pSecondInfo
->sMessage
;
508 lcl_positionInAppFont( *this, m_aInfoImage
, OUTER_MARGIN
, OUTER_MARGIN
, IMAGE_SIZE
, IMAGE_SIZE
);
512 lcl_positionInAppFont( *this, m_aTitle
, TEXT_POS_X
, OUTER_MARGIN
, DIALOG_WIDTH
- TEXT_POS_X
- 2 * OUTER_MARGIN
, 16 );
513 sPrimary
= lcl_stripOOoBaseVendor( sPrimary
);
514 m_aTitle
.SetText( sPrimary
);
517 Rectangle
aPrimaryRect( m_aTitle
.GetPosPixel(), m_aTitle
.GetSizePixel() );
519 // secondary text (if applicable)
520 m_aMessage
.SetStyle( m_aMessage
.GetStyle() | WB_NOLABEL
);
521 sSecondary
= lcl_stripOOoBaseVendor( sSecondary
);
522 m_aMessage
.SetText( sSecondary
);
524 lcl_positionInAppFont( *this, m_aMessage
, TEXT_POS_X
, OUTER_MARGIN
+ 16 + 3, DIALOG_WIDTH
- TEXT_POS_X
- 2 * OUTER_MARGIN
, 8 );
525 Rectangle
aSecondaryRect( m_aMessage
.GetPosPixel(), m_aMessage
.GetSizePixel() );
527 bool bHaveSecondaryText
= sSecondary
.Len() != 0;
529 // determine which space the secondary text would occupy
530 if ( bHaveSecondaryText
)
531 aSecondaryRect
= GetTextRect( aSecondaryRect
, sSecondary
, TEXT_DRAW_WORDBREAK
| TEXT_DRAW_MULTILINE
| TEXT_DRAW_LEFT
);
533 aSecondaryRect
.Bottom() = aSecondaryRect
.Top() - 1;
535 // adjust secondary control height accordingly
536 m_aMessage
.SetSizePixel( aSecondaryRect
.GetSize() );
537 m_aMessage
.Show( aSecondaryRect
.GetHeight() > 0 );
539 // if there's no secondary text ...
540 if ( !bHaveSecondaryText
)
541 { // then give the primary text as much horizontal space as it needs
542 Rectangle
aSuggestedRect( GetTextRect( aPrimaryRect
, sPrimary
, TEXT_DRAW_WORDBREAK
| TEXT_DRAW_MULTILINE
| TEXT_DRAW_CENTER
) );
543 aPrimaryRect
.Right() = aPrimaryRect
.Left() + aSuggestedRect
.GetWidth();
544 aPrimaryRect
.Bottom() = aPrimaryRect
.Top() + aSuggestedRect
.GetHeight();
545 // and center it horizontally
546 m_aTitle
.SetStyle( ( m_aTitle
.GetStyle() & ~WB_LEFT
) | WB_CENTER
);
548 Rectangle
aInfoRect( m_aInfoImage
.GetPosPixel(), m_aInfoImage
.GetSizePixel() );
549 // also, if it's not as high as the image ...
550 if ( aPrimaryRect
.GetHeight() < m_aInfoImage
.GetSizePixel().Height() )
551 { // ... make it fit the image height
552 aPrimaryRect
.Bottom() += aInfoRect
.GetHeight() - aPrimaryRect
.GetHeight();
553 // and center it vertically
554 m_aTitle
.SetStyle( m_aTitle
.GetStyle() | WB_VCENTER
);
557 { // ... otherwise, center the image vertically, relative to the primary text
558 aInfoRect
.Move( 0, ( aPrimaryRect
.GetHeight() - aInfoRect
.GetHeight() ) / 2 );
559 m_aInfoImage
.SetPosSizePixel( aInfoRect
.TopLeft(), aInfoRect
.GetSize() );
562 m_aTitle
.SetPosSizePixel( aPrimaryRect
.TopLeft(), aPrimaryRect
.GetSize() );
565 // adjust dialog size accordingly
566 const Rectangle
& rBottomTextRect( bHaveSecondaryText
? aSecondaryRect
: aPrimaryRect
);
567 Size aBorderSize
= LogicToPixel( Size( OUTER_MARGIN
, OUTER_MARGIN
), MAP_APPFONT
);
568 Size
aDialogSize( LogicToPixel( Size( DIALOG_WIDTH
, 30 ), MAP_APPFONT
) );
569 aDialogSize
.Height() = rBottomTextRect
.Bottom() + aBorderSize
.Height();
570 aDialogSize
.Width() = aPrimaryRect
.Right() + aBorderSize
.Width();
572 SetSizePixel( aDialogSize
);
573 SetPageSizePixel( aDialogSize
);
576 //------------------------------------------------------------------------------
577 void OSQLMessageBox::impl_initImage( MessageType _eImage
)
582 OSL_FAIL( "OSQLMessageBox::impl_initImage: unsupported image type!" );
585 m_aInfoImage
.SetImage(InfoBox::GetStandardImage());
588 m_aInfoImage
.SetImage(WarningBox::GetStandardImage());
591 m_aInfoImage
.SetImage(ErrorBox::GetStandardImage());
594 m_aInfoImage
.SetImage(QueryBox::GetStandardImage());
599 //------------------------------------------------------------------------------
600 void OSQLMessageBox::impl_createStandardButtons( WinBits _nStyle
)
602 if ( _nStyle
& WB_YES_NO_CANCEL
)
604 lcl_addButton( *this, BUTTON_YES
, ( _nStyle
& WB_DEF_YES
) != 0 );
605 lcl_addButton( *this, BUTTON_NO
, ( _nStyle
& WB_DEF_NO
) != 0 );
606 lcl_addButton( *this, BUTTON_CANCEL
, ( _nStyle
& WB_DEF_CANCEL
) != 0 );
608 else if ( _nStyle
& WB_OK_CANCEL
)
610 lcl_addButton( *this, BUTTON_OK
, ( _nStyle
& WB_DEF_OK
) != 0 );
611 lcl_addButton( *this, BUTTON_CANCEL
, ( _nStyle
& WB_DEF_CANCEL
) != 0 );
613 else if ( _nStyle
& WB_YES_NO
)
615 lcl_addButton( *this, BUTTON_YES
, ( _nStyle
& WB_DEF_YES
) != 0 );
616 lcl_addButton( *this, BUTTON_NO
, ( _nStyle
& WB_DEF_NO
) != 0 );
618 else if ( _nStyle
& WB_RETRY_CANCEL
)
620 lcl_addButton( *this, BUTTON_RETRY
, ( _nStyle
& WB_DEF_RETRY
) != 0 );
621 lcl_addButton( *this, BUTTON_CANCEL
, ( _nStyle
& WB_DEF_CANCEL
) != 0 );
625 OSL_ENSURE( WB_OK
& _nStyle
, "OSQLMessageBox::impl_createStandardButtons: unsupported dialog style requested!" );
626 AddButton( BUTTON_OK
, RET_OK
, BUTTONDIALOG_DEFBUTTON
| BUTTONDIALOG_FOCUSBUTTON
);
629 if ( !m_sHelpURL
.isEmpty() )
631 lcl_addButton( *this, BUTTON_HELP
, false );
634 INetURLObject
aHID( m_sHelpURL
);
635 if ( aHID
.GetProtocol() == INET_PROT_HID
)
636 aTmp
= aHID
.GetURLPath();
640 SetHelpId( OUStringToOString( aTmp
, RTL_TEXTENCODING_UTF8
) );
644 //------------------------------------------------------------------------------
645 void OSQLMessageBox::impl_addDetailsButton()
647 size_t nFirstPageVisible
= m_aMessage
.IsVisible() ? 2 : 1;
649 bool bMoreDetailsAvailable
= m_pImpl
->aDisplayInfo
.size() > nFirstPageVisible
;
650 if ( !bMoreDetailsAvailable
)
652 // even if the text fits into what we can display, we might need to details button
653 // if there is more non-trivial information in the errors than the mere messages
654 for ( ExceptionDisplayChain::const_iterator error
= m_pImpl
->aDisplayInfo
.begin();
655 error
!= m_pImpl
->aDisplayInfo
.end();
659 if ( lcl_hasDetails( *error
) )
661 bMoreDetailsAvailable
= true;
667 if ( bMoreDetailsAvailable
)
669 AddButton( BUTTON_MORE
, RET_MORE
, 0 );
670 PushButton
* pButton
= GetPushButton( RET_MORE
);
671 OSL_ENSURE( pButton
, "OSQLMessageBox::impl_addDetailsButton: just added this button, why isn't it there?" );
672 pButton
->SetClickHdl( LINK( this, OSQLMessageBox
, ButtonClickHdl
) );
673 pButton
->SetUniqueId( UID_SQLERROR_BUTTONMORE
);
677 //------------------------------------------------------------------------------
678 void OSQLMessageBox::Construct( WinBits _nStyle
, MessageType _eImage
)
681 utl::ConfigManager::getProductName() +
682 OUString( " Base" ) );
684 // position and size the controls and the dialog, depending on whether we have one or two texts to display
685 impl_positionControls();
688 MessageType
eType( _eImage
);
691 switch ( m_pImpl
->aDisplayInfo
[0].eType
)
693 case SQLExceptionInfo::SQL_EXCEPTION
: eType
= Error
; break;
694 case SQLExceptionInfo::SQL_WARNING
: eType
= Warning
; break;
695 case SQLExceptionInfo::SQL_CONTEXT
: eType
= Info
; break;
696 default: OSL_FAIL( "OSQLMessageBox::Construct: invalid type!" );
699 impl_initImage( eType
);
702 impl_createStandardButtons( _nStyle
);
703 impl_addDetailsButton();
706 //------------------------------------------------------------------------------
707 OSQLMessageBox::OSQLMessageBox(Window
* _pParent
, const SQLExceptionInfo
& _rException
, WinBits _nStyle
, const OUString
& _rHelpURL
)
708 :ButtonDialog( _pParent
, WB_HORZ
| WB_STDDIALOG
)
709 ,m_aInfoImage( this )
710 ,m_aTitle( this, WB_WORDBREAK
| WB_LEFT
)
711 ,m_aMessage( this, WB_WORDBREAK
| WB_LEFT
)
712 ,m_sHelpURL( _rHelpURL
)
713 ,m_pImpl( new SQLMessageBox_Impl( _rException
) )
715 Construct( _nStyle
, AUTO
);
718 //------------------------------------------------------------------------------
719 OSQLMessageBox::OSQLMessageBox( Window
* _pParent
, const OUString
& _rTitle
, const OUString
& _rMessage
, WinBits _nStyle
, MessageType _eType
, const ::dbtools::SQLExceptionInfo
* _pAdditionalErrorInfo
)
720 :ButtonDialog( _pParent
, WB_HORZ
| WB_STDDIALOG
)
721 ,m_aInfoImage( this )
722 ,m_aTitle( this, WB_WORDBREAK
| WB_LEFT
)
723 ,m_aMessage( this, WB_WORDBREAK
| WB_LEFT
)
726 aError
.Message
= _rTitle
;
727 aError
.Details
= _rMessage
;
728 if ( _pAdditionalErrorInfo
)
729 aError
.NextException
= _pAdditionalErrorInfo
->get();
731 m_pImpl
.reset( new SQLMessageBox_Impl( SQLExceptionInfo( aError
) ) );
733 Construct( _nStyle
, _eType
);
736 //--------------------------------------------------------------------------
737 OSQLMessageBox::~OSQLMessageBox()
741 //--------------------------------------------------------------------------
742 IMPL_LINK( OSQLMessageBox
, ButtonClickHdl
, Button
*, /*pButton*/ )
744 OExceptionChainDialog
aDlg( this, m_pImpl
->aDisplayInfo
);
749 //==================================================================
751 //==================================================================
752 OSQLWarningBox::OSQLWarningBox( Window
* _pParent
, const OUString
& _rMessage
, WinBits _nStyle
,
753 const ::dbtools::SQLExceptionInfo
* _pAdditionalErrorInfo
)
754 :OSQLMessageBox( _pParent
, String( ModuleRes( STR_EXCEPTION_WARNING
) ), _rMessage
, _nStyle
, OSQLMessageBox::Warning
, _pAdditionalErrorInfo
)
758 //==================================================================
760 //==================================================================
761 OSQLErrorBox::OSQLErrorBox( Window
* _pParent
, const OUString
& _rMessage
, WinBits _nStyle
,
762 const ::dbtools::SQLExceptionInfo
* _pAdditionalErrorInfo
)
763 :OSQLMessageBox( _pParent
, String( ModuleRes( STR_EXCEPTION_ERROR
) ), _rMessage
, _nStyle
, OSQLMessageBox::Error
, _pAdditionalErrorInfo
)
767 //.........................................................................
769 //.........................................................................
771 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */