1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "sqlmessage.hxx"
31 #include "dbu_dlg.hrc"
32 #include "sqlmessage.hrc"
33 #include <com/sun/star/sdbc/SQLException.hpp>
34 #include <com/sun/star/sdb/SQLContext.hpp>
35 #include <vcl/fixed.hxx>
36 #include <osl/diagnose.h>
37 #include <svtools/svtreebx.hxx>
38 #include <svtools/svmedit.hxx>
39 #include <connectivity/dbexception.hxx>
40 #include <connectivity/sqlerror.hxx>
41 #include <vcl/msgbox.hxx>
42 #include <unotools/configmgr.hxx>
43 #include <sfx2/sfxuno.hxx>
44 #include "dbaccess_helpid.hrc"
45 #include "UITools.hxx"
46 #include "moduledbu.hxx"
48 #include <tools/urlobj.hxx>
50 #define BUTTONID_MORE BUTTONID_RETRY + 1
52 #define DIALOG_WIDTH 220
53 #define OUTER_MARGIN 6
55 #define INNER_PADDING 3
56 #define TEXT_POS_X ( OUTER_MARGIN + IMAGE_SIZE + INNER_PADDING )
58 using namespace dbtools
;
59 using namespace com::sun::star::uno
;
60 using namespace com::sun::star::sdb
;
61 using namespace com::sun::star::sdbc
;
63 //.........................................................................
66 //.........................................................................
70 //------------------------------------------------------------------------------
74 virtual Image
getImage() const = 0;
76 virtual ~IImageProvider() { }
79 //------------------------------------------------------------------------------
83 virtual String
getLabel() const = 0;
85 virtual ~ILabelProvider() { };
88 //------------------------------------------------------------------------------
89 class ImageProvider
: public IImageProvider
92 sal_uInt16 m_defaultImageID
;
94 mutable Image m_defaultImage
;
97 ImageProvider( sal_uInt16 _defaultImageID
)
98 :m_defaultImageID( _defaultImageID
)
102 virtual Image
getImage() const
104 if ( !m_defaultImage
)
105 m_defaultImage
= Image( ModuleRes( m_defaultImageID
) );
106 return m_defaultImage
;
110 //------------------------------------------------------------------------------
111 class LabelProvider
: public ILabelProvider
116 LabelProvider( sal_uInt16 _labelResourceID
)
117 :m_label( ModuleRes( _labelResourceID
) )
121 virtual String
getLabel() const
127 //------------------------------------------------------------------------------
128 class ProviderFactory
131 mutable ::boost::shared_ptr
< IImageProvider
> m_pErrorImage
;
132 mutable ::boost::shared_ptr
< IImageProvider
> m_pWarningsImage
;
133 mutable ::boost::shared_ptr
< IImageProvider
> m_pInfoImage
;
134 mutable ::boost::shared_ptr
< ILabelProvider
> m_pErrorLabel
;
135 mutable ::boost::shared_ptr
< ILabelProvider
> m_pWarningsLabel
;
136 mutable ::boost::shared_ptr
< ILabelProvider
> m_pInfoLabel
;
143 ::boost::shared_ptr
< IImageProvider
> getImageProvider( SQLExceptionInfo::TYPE _eType
) const
145 ::boost::shared_ptr
< IImageProvider
>* ppProvider( &m_pErrorImage
);
146 sal_uInt16
nNormalImageID( BMP_EXCEPTION_ERROR
);
150 case SQLExceptionInfo::SQL_WARNING
:
151 ppProvider
= &m_pWarningsImage
;
152 nNormalImageID
= BMP_EXCEPTION_WARNING
;
155 case SQLExceptionInfo::SQL_CONTEXT
:
156 ppProvider
= &m_pInfoImage
;
157 nNormalImageID
= BMP_EXCEPTION_INFO
;
164 if ( !ppProvider
->get() )
165 ppProvider
->reset( new ImageProvider( nNormalImageID
) );
169 ::boost::shared_ptr
< ILabelProvider
> getLabelProvider( SQLExceptionInfo::TYPE _eType
, bool _bSubLabel
) const
171 ::boost::shared_ptr
< ILabelProvider
>* ppProvider( &m_pErrorLabel
);
172 sal_uInt16
nLabelID( STR_EXCEPTION_ERROR
);
176 case SQLExceptionInfo::SQL_WARNING
:
177 ppProvider
= &m_pWarningsLabel
;
178 nLabelID
= STR_EXCEPTION_WARNING
;
181 case SQLExceptionInfo::SQL_CONTEXT
:
182 ppProvider
= &m_pInfoLabel
;
183 nLabelID
= _bSubLabel
? STR_EXCEPTION_DETAILS
: STR_EXCEPTION_INFO
;
189 if ( !ppProvider
->get() )
190 ppProvider
->reset( new LabelProvider( nLabelID
) );
196 //------------------------------------------------------------------------------
197 /// a stripped version of the SQLException, packed for displaying
198 struct ExceptionDisplayInfo
200 SQLExceptionInfo::TYPE eType
;
202 ::boost::shared_ptr
< IImageProvider
> pImageProvider
;
203 ::boost::shared_ptr
< ILabelProvider
> pLabelProvider
;
211 ExceptionDisplayInfo() : eType( SQLExceptionInfo::UNDEFINED
), bSubEntry( false ) { }
212 ExceptionDisplayInfo( SQLExceptionInfo::TYPE _eType
) : eType( _eType
), bSubEntry( false ) { }
215 static bool lcl_hasDetails( const ExceptionDisplayInfo
& _displayInfo
)
217 return ( _displayInfo
.sErrorCode
.Len() )
218 || ( _displayInfo
.sSQLState
.Len()
219 && !_displayInfo
.sSQLState
.EqualsAscii( "S1000" )
223 typedef ::std::vector
< ExceptionDisplayInfo
> ExceptionDisplayChain
;
225 //------------------------------------------------------------------------------
226 /// strips the [OOoBase] vendor identifier from the given error message, if applicable
227 ::rtl::OUString
lcl_stripOOoBaseVendor( const ::rtl::OUString
& _rErrorMessage
)
229 ::rtl::OUString
sErrorMessage( _rErrorMessage
);
231 const ::rtl::OUString
sVendorIdentifier( ::connectivity::SQLError::getMessagePrefix() );
232 if ( sErrorMessage
.indexOf( sVendorIdentifier
) == 0 )
234 // characters to strip
235 sal_Int32
nStripLen( sVendorIdentifier
.getLength() );
236 // usually, there should be a whitespace between the vendor and the real message
237 while ( ( sErrorMessage
.getLength() > nStripLen
)
238 && ( sErrorMessage
[nStripLen
] == ' ' )
241 sErrorMessage
= sErrorMessage
.copy( nStripLen
);
244 return sErrorMessage
;
247 //------------------------------------------------------------------------------
248 void lcl_buildExceptionChain( const SQLExceptionInfo
& _rErrorInfo
, const ProviderFactory
& _rFactory
, ExceptionDisplayChain
& _out_rChain
)
251 ExceptionDisplayChain empty
;
252 _out_rChain
.swap( empty
);
255 SQLExceptionIteratorHelper
iter( _rErrorInfo
);
256 while ( iter
.hasMoreElements() )
258 // current chain element
259 SQLExceptionInfo aCurrentElement
;
260 iter
.next( aCurrentElement
);
262 const SQLException
* pCurrentError
= (const SQLException
*)aCurrentElement
;
263 OSL_ENSURE( pCurrentError
, "lcl_buildExceptionChain: iterator failure!" );
264 // hasMoreElements should not have returned <TRUE/> in this case
266 ExceptionDisplayInfo
aDisplayInfo( aCurrentElement
.getType() );
268 aDisplayInfo
.sMessage
= pCurrentError
->Message
.trim();
269 aDisplayInfo
.sSQLState
= pCurrentError
->SQLState
;
270 if ( pCurrentError
->ErrorCode
)
271 aDisplayInfo
.sErrorCode
= String::CreateFromInt32( pCurrentError
->ErrorCode
);
273 if ( !aDisplayInfo
.sMessage
.Len()
274 && !lcl_hasDetails( aDisplayInfo
)
277 OSL_FAIL( "lcl_buildExceptionChain: useles exception: no state, no error code, no message!" );
281 aDisplayInfo
.pImageProvider
= _rFactory
.getImageProvider( aCurrentElement
.getType() );
282 aDisplayInfo
.pLabelProvider
= _rFactory
.getLabelProvider( aCurrentElement
.getType(), false );
284 _out_rChain
.push_back( aDisplayInfo
);
286 if ( aCurrentElement
.getType() == SQLExceptionInfo::SQL_CONTEXT
)
288 const SQLContext
* pContext
= (const SQLContext
*)aCurrentElement
;
289 if ( !pContext
->Details
.isEmpty() )
291 ExceptionDisplayInfo
aSubInfo( aCurrentElement
.getType() );
293 aSubInfo
.sMessage
= pContext
->Details
;
294 aSubInfo
.pImageProvider
= _rFactory
.getImageProvider( aCurrentElement
.getType() );
295 aSubInfo
.pLabelProvider
= _rFactory
.getLabelProvider( aCurrentElement
.getType(), true );
296 aSubInfo
.bSubEntry
= true;
298 _out_rChain
.push_back( aSubInfo
);
304 //------------------------------------------------------------------------------
305 void lcl_insertExceptionEntry( SvTreeListBox
& _rList
, size_t _nElementPos
, const ExceptionDisplayInfo
& _rEntry
)
307 Image
aEntryImage( _rEntry
.pImageProvider
->getImage() );
308 SvLBoxEntry
* pListEntry
=
309 _rList
.InsertEntry( _rEntry
.pLabelProvider
->getLabel(), aEntryImage
, aEntryImage
);
310 pListEntry
->SetUserData( reinterpret_cast< void* >( _nElementPos
) );
314 //==============================================================================
315 class OExceptionChainDialog
: public ModalDialog
318 FixedText m_aListLabel
;
319 SvTreeListBox m_aExceptionList
;
320 FixedText m_aDescLabel
;
321 MultiLineEdit m_aExceptionText
;
324 String m_sStatusLabel
;
325 String m_sErrorCodeLabel
;
327 ExceptionDisplayChain m_aExceptions
;
330 OExceptionChainDialog( Window
* pParent
, const ExceptionDisplayChain
& _rExceptions
);
331 ~OExceptionChainDialog();
334 DECL_LINK(OnExceptionSelected
, void*);
337 DBG_NAME(OExceptionChainDialog
)
338 //------------------------------------------------------------------------------
339 OExceptionChainDialog::OExceptionChainDialog( Window
* pParent
, const ExceptionDisplayChain
& _rExceptions
)
340 :ModalDialog(pParent
, ModuleRes(DLG_SQLEXCEPTIONCHAIN
))
341 ,m_aFrame (this, ModuleRes(FL_DETAILS
))
342 ,m_aListLabel (this, ModuleRes(FT_ERRORLIST
))
343 ,m_aExceptionList (this, ModuleRes(CTL_ERRORLIST
))
344 ,m_aDescLabel (this, ModuleRes(FT_DESCRIPTION
))
345 ,m_aExceptionText (this, ModuleRes(ME_DESCRIPTION
))
346 ,m_aOK (this, ModuleRes(PB_OK
))
347 ,m_aExceptions( _rExceptions
)
349 DBG_CTOR(OExceptionChainDialog
,NULL
);
351 m_sStatusLabel
= String( ModuleRes( STR_EXCEPTION_STATUS
) );
352 m_sErrorCodeLabel
= String( ModuleRes( STR_EXCEPTION_ERRORCODE
) );
356 m_aExceptionList
.SetSelectionMode(SINGLE_SELECTION
);
357 m_aExceptionList
.SetDragDropMode(0);
358 m_aExceptionList
.EnableInplaceEditing(sal_False
);
359 m_aExceptionList
.SetStyle(m_aExceptionList
.GetStyle() | WB_HASLINES
| WB_HASBUTTONS
| WB_HASBUTTONSATROOT
| WB_HSCROLL
);
361 m_aExceptionList
.SetSelectHdl(LINK(this, OExceptionChainDialog
, OnExceptionSelected
));
362 m_aExceptionList
.SetNodeDefaultImages( );
363 m_aExceptionText
.SetReadOnly(sal_True
);
365 bool bHave22018
= false;
366 size_t elementPos
= 0;
368 for ( ExceptionDisplayChain::const_iterator loop
= m_aExceptions
.begin();
369 loop
!= m_aExceptions
.end();
373 lcl_insertExceptionEntry( m_aExceptionList
, elementPos
, *loop
);
374 bHave22018
= loop
->sSQLState
.EqualsAscii( "22018" );
377 // if the error has the code 22018, then add an additional explanation
381 ProviderFactory aProviderFactory
;
383 ExceptionDisplayInfo aInfo22018
;
384 aInfo22018
.sMessage
= String( ModuleRes( STR_EXPLAN_STRINGCONVERSION_ERROR
) );
385 aInfo22018
.pLabelProvider
= aProviderFactory
.getLabelProvider( SQLExceptionInfo::SQL_CONTEXT
, false );
386 aInfo22018
.pImageProvider
= aProviderFactory
.getImageProvider( SQLExceptionInfo::SQL_CONTEXT
);
387 m_aExceptions
.push_back( aInfo22018
);
389 lcl_insertExceptionEntry( m_aExceptionList
, m_aExceptions
.size() - 1, aInfo22018
);
393 //------------------------------------------------------------------------------
394 OExceptionChainDialog::~OExceptionChainDialog()
396 DBG_DTOR(OExceptionChainDialog
,NULL
);
399 //------------------------------------------------------------------------------
400 IMPL_LINK_NOARG(OExceptionChainDialog
, OnExceptionSelected
)
402 SvLBoxEntry
* pSelected
= m_aExceptionList
.FirstSelected();
403 OSL_ENSURE(!pSelected
|| !m_aExceptionList
.NextSelected(pSelected
), "OExceptionChainDialog::OnExceptionSelected : multi selection ?");
409 size_t pos
= reinterpret_cast< size_t >( pSelected
->GetUserData() );
410 const ExceptionDisplayInfo
& aExceptionInfo( m_aExceptions
[ pos
] );
412 if ( aExceptionInfo
.sSQLState
.Len() )
414 sText
+= m_sStatusLabel
;
415 sText
.AppendAscii(": ");
416 sText
+= aExceptionInfo
.sSQLState
;
417 sText
.AppendAscii("\n");
420 if ( aExceptionInfo
.sErrorCode
.Len() )
422 sText
+= m_sErrorCodeLabel
;
423 sText
.AppendAscii(": ");
424 sText
+= aExceptionInfo
.sErrorCode
;
425 sText
.AppendAscii("\n");
429 sText
.AppendAscii( "\n" );
431 sText
+= aExceptionInfo
.sMessage
;
434 m_aExceptionText
.SetText(sText
);
439 //==============================================================================
440 //= SQLMessageBox_Impl
441 //==============================================================================
442 struct SQLMessageBox_Impl
444 ExceptionDisplayChain aDisplayInfo
;
446 SQLMessageBox_Impl( const SQLExceptionInfo
& _rExceptionInfo
)
448 // transform the exception chain to a form more suitable for displaying it here
449 ProviderFactory aProviderFactory
;
450 lcl_buildExceptionChain( _rExceptionInfo
, aProviderFactory
, aDisplayInfo
);
454 //------------------------------------------------------------------------------
457 void lcl_positionInAppFont( const Window
& _rParent
, Window
& _rChild
, long _nX
, long _nY
, long _Width
, long _Height
)
459 Point aPos
= _rParent
.LogicToPixel( Point( _nX
, _nY
), MAP_APPFONT
);
460 Size aSize
= _rParent
.LogicToPixel( Size( _Width
, _Height
), MAP_APPFONT
);
461 _rChild
.SetPosSizePixel( aPos
, aSize
);
464 void lcl_addButton( ButtonDialog
& _rDialog
, StandardButtonType _eType
, bool _bDefault
)
466 sal_uInt16 nButtonID
= 0;
469 case BUTTON_YES
: nButtonID
= BUTTONID_YES
; break;
470 case BUTTON_NO
: nButtonID
= BUTTONID_NO
; break;
471 case BUTTON_OK
: nButtonID
= BUTTONID_OK
; break;
472 case BUTTON_CANCEL
: nButtonID
= BUTTONID_CANCEL
; break;
473 case BUTTON_RETRY
: nButtonID
= BUTTONID_RETRY
; break;
474 case BUTTON_HELP
: nButtonID
= BUTTONID_HELP
; break;
476 OSL_FAIL( "lcl_addButton: invalid button id!" );
479 _rDialog
.AddButton( _eType
, nButtonID
, _bDefault
? BUTTONDIALOG_DEFBUTTON
| BUTTONDIALOG_FOCUSBUTTON
: 0 );
483 //------------------------------------------------------------------------------
484 void OSQLMessageBox::impl_positionControls()
486 OSL_PRECOND( !m_pImpl
->aDisplayInfo
.empty(), "OSQLMessageBox::impl_positionControls: nothing to display at all?" );
489 if ( m_pImpl
->aDisplayInfo
.empty() )
491 const ExceptionDisplayInfo
* pSecondInfo
= NULL
;
493 const ExceptionDisplayInfo
& rFirstInfo
= *m_pImpl
->aDisplayInfo
.begin();
494 if ( m_pImpl
->aDisplayInfo
.size() > 1 )
495 pSecondInfo
= &m_pImpl
->aDisplayInfo
[1];
496 String sPrimary
, sSecondary
;
497 sPrimary
= rFirstInfo
.sMessage
;
498 // one or two texts to display?
501 // we show two elements in the main dialog if and only if one of
502 // - the first element in the chain is an SQLContext, and the second
503 // element denotes its sub entry
504 // - the first and the second element are both independent (i.e. the second
505 // is no sub entry), and none of them is a context.
506 bool bFirstElementIsContext
= ( rFirstInfo
.eType
== SQLExceptionInfo::SQL_CONTEXT
);
507 bool bSecondElementIsContext
= ( pSecondInfo
->eType
== SQLExceptionInfo::SQL_CONTEXT
);
509 if ( bFirstElementIsContext
&& pSecondInfo
->bSubEntry
)
510 sSecondary
= pSecondInfo
->sMessage
;
511 if ( !bFirstElementIsContext
&& !bSecondElementIsContext
)
512 sSecondary
= pSecondInfo
->sMessage
;
516 lcl_positionInAppFont( *this, m_aInfoImage
, OUTER_MARGIN
, OUTER_MARGIN
, IMAGE_SIZE
, IMAGE_SIZE
);
520 lcl_positionInAppFont( *this, m_aTitle
, TEXT_POS_X
, OUTER_MARGIN
, DIALOG_WIDTH
- TEXT_POS_X
- 2 * OUTER_MARGIN
, 16 );
521 sPrimary
= lcl_stripOOoBaseVendor( sPrimary
);
522 m_aTitle
.SetText( sPrimary
);
525 Rectangle
aPrimaryRect( m_aTitle
.GetPosPixel(), m_aTitle
.GetSizePixel() );
527 // secondary text (if applicable)
528 m_aMessage
.SetStyle( m_aMessage
.GetStyle() | WB_NOLABEL
);
529 sSecondary
= lcl_stripOOoBaseVendor( sSecondary
);
530 m_aMessage
.SetText( sSecondary
);
532 lcl_positionInAppFont( *this, m_aMessage
, TEXT_POS_X
, OUTER_MARGIN
+ 16 + 3, DIALOG_WIDTH
- TEXT_POS_X
- 2 * OUTER_MARGIN
, 8 );
533 Rectangle
aSecondaryRect( m_aMessage
.GetPosPixel(), m_aMessage
.GetSizePixel() );
535 bool bHaveSecondaryText
= sSecondary
.Len() != 0;
537 // determine which space the secondary text would occupy
538 if ( bHaveSecondaryText
)
539 aSecondaryRect
= GetTextRect( aSecondaryRect
, sSecondary
, TEXT_DRAW_WORDBREAK
| TEXT_DRAW_MULTILINE
| TEXT_DRAW_LEFT
);
541 aSecondaryRect
.Bottom() = aSecondaryRect
.Top() - 1;
543 // adjust secondary control height accordingly
544 m_aMessage
.SetSizePixel( aSecondaryRect
.GetSize() );
545 m_aMessage
.Show( aSecondaryRect
.GetHeight() > 0 );
547 // if there's no secondary text ...
548 if ( !bHaveSecondaryText
)
549 { // then give the primary text as much horizontal space as it needs
550 Rectangle
aSuggestedRect( GetTextRect( aPrimaryRect
, sPrimary
, TEXT_DRAW_WORDBREAK
| TEXT_DRAW_MULTILINE
| TEXT_DRAW_CENTER
) );
551 aPrimaryRect
.Right() = aPrimaryRect
.Left() + aSuggestedRect
.GetWidth();
552 aPrimaryRect
.Bottom() = aPrimaryRect
.Top() + aSuggestedRect
.GetHeight();
553 // and center it horizontally
554 m_aTitle
.SetStyle( ( m_aTitle
.GetStyle() & ~WB_LEFT
) | WB_CENTER
);
556 Rectangle
aInfoRect( m_aInfoImage
.GetPosPixel(), m_aInfoImage
.GetSizePixel() );
557 // also, if it's not as high as the image ...
558 if ( aPrimaryRect
.GetHeight() < m_aInfoImage
.GetSizePixel().Height() )
559 { // ... make it fit the image height
560 aPrimaryRect
.Bottom() += aInfoRect
.GetHeight() - aPrimaryRect
.GetHeight();
561 // and center it vertically
562 m_aTitle
.SetStyle( m_aTitle
.GetStyle() | WB_VCENTER
);
565 { // ... otherwise, center the image vertically, relative to the primary text
566 aInfoRect
.Move( 0, ( aPrimaryRect
.GetHeight() - aInfoRect
.GetHeight() ) / 2 );
567 m_aInfoImage
.SetPosSizePixel( aInfoRect
.TopLeft(), aInfoRect
.GetSize() );
570 m_aTitle
.SetPosSizePixel( aPrimaryRect
.TopLeft(), aPrimaryRect
.GetSize() );
573 // adjust dialog size accordingly
574 const Rectangle
& rBottomTextRect( bHaveSecondaryText
? aSecondaryRect
: aPrimaryRect
);
575 Size aBorderSize
= LogicToPixel( Size( OUTER_MARGIN
, OUTER_MARGIN
), MAP_APPFONT
);
576 Size
aDialogSize( LogicToPixel( Size( DIALOG_WIDTH
, 30 ), MAP_APPFONT
) );
577 aDialogSize
.Height() = rBottomTextRect
.Bottom() + aBorderSize
.Height();
578 aDialogSize
.Width() = aPrimaryRect
.Right() + aBorderSize
.Width();
580 SetSizePixel( aDialogSize
);
581 SetPageSizePixel( aDialogSize
);
584 //------------------------------------------------------------------------------
585 void OSQLMessageBox::impl_initImage( MessageType _eImage
)
590 OSL_FAIL( "OSQLMessageBox::impl_initImage: unsupported image type!" );
593 m_aInfoImage
.SetImage(InfoBox::GetStandardImage());
596 m_aInfoImage
.SetImage(WarningBox::GetStandardImage());
599 m_aInfoImage
.SetImage(ErrorBox::GetStandardImage());
602 m_aInfoImage
.SetImage(QueryBox::GetStandardImage());
607 //------------------------------------------------------------------------------
608 void OSQLMessageBox::impl_createStandardButtons( WinBits _nStyle
)
610 if ( _nStyle
& WB_YES_NO_CANCEL
)
612 lcl_addButton( *this, BUTTON_YES
, ( _nStyle
& WB_DEF_YES
) != 0 );
613 lcl_addButton( *this, BUTTON_NO
, ( _nStyle
& WB_DEF_NO
) != 0 );
614 lcl_addButton( *this, BUTTON_CANCEL
, ( _nStyle
& WB_DEF_CANCEL
) != 0 );
616 else if ( _nStyle
& WB_OK_CANCEL
)
618 lcl_addButton( *this, BUTTON_OK
, ( _nStyle
& WB_DEF_OK
) != 0 );
619 lcl_addButton( *this, BUTTON_CANCEL
, ( _nStyle
& WB_DEF_CANCEL
) != 0 );
621 else if ( _nStyle
& WB_YES_NO
)
623 lcl_addButton( *this, BUTTON_YES
, ( _nStyle
& WB_DEF_YES
) != 0 );
624 lcl_addButton( *this, BUTTON_NO
, ( _nStyle
& WB_DEF_NO
) != 0 );
626 else if ( _nStyle
& WB_RETRY_CANCEL
)
628 lcl_addButton( *this, BUTTON_RETRY
, ( _nStyle
& WB_DEF_RETRY
) != 0 );
629 lcl_addButton( *this, BUTTON_CANCEL
, ( _nStyle
& WB_DEF_CANCEL
) != 0 );
633 OSL_ENSURE( WB_OK
& _nStyle
, "OSQLMessageBox::impl_createStandardButtons: unsupported dialog style requested!" );
634 AddButton( BUTTON_OK
, BUTTONID_OK
, BUTTONDIALOG_DEFBUTTON
| BUTTONDIALOG_FOCUSBUTTON
);
637 if ( !m_sHelpURL
.isEmpty() )
639 lcl_addButton( *this, BUTTON_HELP
, false );
642 INetURLObject
aHID( m_sHelpURL
);
643 if ( aHID
.GetProtocol() == INET_PROT_HID
)
644 aTmp
= aHID
.GetURLPath();
648 SetHelpId( rtl::OUStringToOString( aTmp
, RTL_TEXTENCODING_UTF8
) );
652 //------------------------------------------------------------------------------
653 void OSQLMessageBox::impl_addDetailsButton()
655 size_t nFirstPageVisible
= m_aMessage
.IsVisible() ? 2 : 1;
657 bool bMoreDetailsAvailable
= m_pImpl
->aDisplayInfo
.size() > nFirstPageVisible
;
658 if ( !bMoreDetailsAvailable
)
660 // even if the text fits into what we can display, we might need to details button
661 // if there is more non-trivial information in the errors than the mere messages
662 for ( ExceptionDisplayChain::const_iterator error
= m_pImpl
->aDisplayInfo
.begin();
663 error
!= m_pImpl
->aDisplayInfo
.end();
667 if ( lcl_hasDetails( *error
) )
669 bMoreDetailsAvailable
= true;
675 if ( bMoreDetailsAvailable
)
677 AddButton( BUTTON_MORE
, BUTTONID_MORE
, 0 );
678 PushButton
* pButton
= GetPushButton( BUTTONID_MORE
);
679 OSL_ENSURE( pButton
, "OSQLMessageBox::impl_addDetailsButton: just added this button, why isn't it there?" );
680 pButton
->SetClickHdl( LINK( this, OSQLMessageBox
, ButtonClickHdl
) );
681 pButton
->SetUniqueId( UID_SQLERROR_BUTTONMORE
);
685 //------------------------------------------------------------------------------
686 void OSQLMessageBox::Construct( WinBits _nStyle
, MessageType _eImage
)
689 utl::ConfigManager::getProductName() +
690 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " Base" ) ) );
692 // position and size the controls and the dialog, depending on whether we have one or two texts to display
693 impl_positionControls();
696 MessageType
eType( _eImage
);
699 switch ( m_pImpl
->aDisplayInfo
[0].eType
)
701 case SQLExceptionInfo::SQL_EXCEPTION
: eType
= Error
; break;
702 case SQLExceptionInfo::SQL_WARNING
: eType
= Warning
; break;
703 case SQLExceptionInfo::SQL_CONTEXT
: eType
= Info
; break;
704 default: OSL_FAIL( "OSQLMessageBox::Construct: invalid type!" );
707 impl_initImage( eType
);
710 impl_createStandardButtons( _nStyle
);
711 impl_addDetailsButton();
714 //------------------------------------------------------------------------------
715 OSQLMessageBox::OSQLMessageBox(Window
* _pParent
, const SQLExceptionInfo
& _rException
, WinBits _nStyle
, const ::rtl::OUString
& _rHelpURL
)
716 :ButtonDialog( _pParent
, WB_HORZ
| WB_STDDIALOG
)
717 ,m_aInfoImage( this )
718 ,m_aTitle( this, WB_WORDBREAK
| WB_LEFT
)
719 ,m_aMessage( this, WB_WORDBREAK
| WB_LEFT
)
720 ,m_sHelpURL( _rHelpURL
)
721 ,m_pImpl( new SQLMessageBox_Impl( _rException
) )
723 Construct( _nStyle
, AUTO
);
726 //------------------------------------------------------------------------------
727 OSQLMessageBox::OSQLMessageBox( Window
* _pParent
, const UniString
& _rTitle
, const UniString
& _rMessage
, WinBits _nStyle
, MessageType _eType
, const ::dbtools::SQLExceptionInfo
* _pAdditionalErrorInfo
)
728 :ButtonDialog( _pParent
, WB_HORZ
| WB_STDDIALOG
)
729 ,m_aInfoImage( this )
730 ,m_aTitle( this, WB_WORDBREAK
| WB_LEFT
)
731 ,m_aMessage( this, WB_WORDBREAK
| WB_LEFT
)
734 aError
.Message
= _rTitle
;
735 aError
.Details
= _rMessage
;
736 if ( _pAdditionalErrorInfo
)
737 aError
.NextException
= _pAdditionalErrorInfo
->get();
739 m_pImpl
.reset( new SQLMessageBox_Impl( SQLExceptionInfo( aError
) ) );
741 Construct( _nStyle
, _eType
);
744 //--------------------------------------------------------------------------
745 OSQLMessageBox::~OSQLMessageBox()
749 //--------------------------------------------------------------------------
750 IMPL_LINK( OSQLMessageBox
, ButtonClickHdl
, Button
*, /*pButton*/ )
752 OExceptionChainDialog
aDlg( this, m_pImpl
->aDisplayInfo
);
757 //==================================================================
759 //==================================================================
760 OSQLWarningBox::OSQLWarningBox( Window
* _pParent
, const UniString
& _rMessage
, WinBits _nStyle
,
761 const ::dbtools::SQLExceptionInfo
* _pAdditionalErrorInfo
)
762 :OSQLMessageBox( _pParent
, String( ModuleRes( STR_STAT_WARNING
) ), _rMessage
, _nStyle
, OSQLMessageBox::Warning
, _pAdditionalErrorInfo
)
766 //.........................................................................
768 //.........................................................................
770 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */