1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sqlmessage.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #ifndef _DBAUI_SQLMESSAGE_HXX_
35 #include "sqlmessage.hxx"
38 #include "dbu_dlg.hrc"
40 #ifndef _DBAUI_SQLMESSAGE_HRC_
41 #include "sqlmessage.hrc"
43 #ifndef _COM_SUN_STAR_SDBC_SQLEXCEPTION_HPP_
44 #include <com/sun/star/sdbc/SQLException.hpp>
46 #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
47 #include <com/sun/star/sdb/SQLContext.hpp>
49 #ifndef _SV_GROUP_HXX //autogen
50 #include <vcl/fixed.hxx>
52 #ifndef _SVTREEBOX_HXX
53 #include <svtools/svtreebx.hxx>
55 #ifndef _SVEDIT_HXX //autogen
56 #include <svtools/svmedit.hxx>
58 #ifndef _DBHELPER_DBEXCEPTION_HXX_
59 #include <connectivity/dbexception.hxx>
61 #ifndef CONNECTIVITY_SQLERROR_HXX
62 #include <connectivity/sqlerror.hxx>
64 #ifndef _SV_MSGBOX_HXX //autogen
65 #include <vcl/msgbox.hxx>
67 #ifndef _UTL_CONFIGMGR_HXX_
68 #include <unotools/configmgr.hxx>
70 #ifndef _SFX_SFXUNO_HXX
71 #include <sfx2/sfxuno.hxx>
73 #ifndef _DBA_DBACCESS_HELPID_HRC_
74 #include "dbaccess_helpid.hrc"
76 #ifndef DBAUI_TOOLS_HXX
77 #include "UITools.hxx"
79 #ifndef _DBAUI_MODULE_DBU_HXX_
80 #include "moduledbu.hxx"
83 #define BUTTONID_MORE BUTTONID_RETRY + 1
85 #define DIALOG_WIDTH 220
86 #define OUTER_MARGIN 6
88 #define INNER_PADDING 3
89 #define TEXT_POS_X ( OUTER_MARGIN + IMAGE_SIZE + INNER_PADDING )
91 using namespace dbtools
;
92 using namespace com::sun::star::uno
;
93 using namespace com::sun::star::sdb
;
94 using namespace com::sun::star::sdbc
;
96 //.........................................................................
99 //.........................................................................
103 //------------------------------------------------------------------------------
107 virtual Image
getImage( bool _highContrast
) const = 0;
109 virtual ~IImageProvider() { }
112 //------------------------------------------------------------------------------
116 virtual String
getLabel() const = 0;
118 virtual ~ILabelProvider() { };
121 //------------------------------------------------------------------------------
122 class ImageProvider
: public IImageProvider
125 USHORT m_defaultImageID
;
126 USHORT m_highContrastImageID
;
128 mutable Image m_defaultImage
;
129 mutable Image m_highContrastImage
;
132 ImageProvider( USHORT _defaultImageID
, USHORT _highContrastImageID
)
133 :m_defaultImageID( _defaultImageID
)
134 ,m_highContrastImageID( _highContrastImageID
)
138 virtual Image
getImage( bool _highContrast
) const
142 if ( !m_highContrastImage
)
143 m_highContrastImage
= Image( ModuleRes( m_highContrastImageID
) );
144 return m_highContrastImage
;
147 if ( !m_defaultImage
)
148 m_defaultImage
= Image( ModuleRes( m_defaultImageID
) );
149 return m_defaultImage
;
153 //------------------------------------------------------------------------------
154 class LabelProvider
: public ILabelProvider
159 LabelProvider( USHORT _labelResourceID
)
160 :m_label( ModuleRes( _labelResourceID
) )
164 virtual String
getLabel() const
170 //------------------------------------------------------------------------------
171 class ProviderFactory
174 mutable ::boost::shared_ptr
< IImageProvider
> m_pErrorImage
;
175 mutable ::boost::shared_ptr
< IImageProvider
> m_pWarningsImage
;
176 mutable ::boost::shared_ptr
< IImageProvider
> m_pInfoImage
;
177 mutable ::boost::shared_ptr
< ILabelProvider
> m_pErrorLabel
;
178 mutable ::boost::shared_ptr
< ILabelProvider
> m_pWarningsLabel
;
179 mutable ::boost::shared_ptr
< ILabelProvider
> m_pInfoLabel
;
186 ::boost::shared_ptr
< IImageProvider
> getImageProvider( SQLExceptionInfo::TYPE _eType
) const
188 ::boost::shared_ptr
< IImageProvider
>* ppProvider( &m_pErrorImage
);
189 USHORT
nNormalImageID( BMP_EXCEPTION_ERROR
);
190 USHORT
nHCImageID( BMP_EXCEPTION_ERROR_SCH
);
194 case SQLExceptionInfo::SQL_WARNING
:
195 ppProvider
= &m_pWarningsImage
;
196 nNormalImageID
= BMP_EXCEPTION_WARNING
;
197 nHCImageID
= BMP_EXCEPTION_WARNING_SCH
;
200 case SQLExceptionInfo::SQL_CONTEXT
:
201 ppProvider
= &m_pInfoImage
;
202 nNormalImageID
= BMP_EXCEPTION_INFO
;
203 nHCImageID
= BMP_EXCEPTION_INFO_SCH
;
210 if ( !ppProvider
->get() )
211 ppProvider
->reset( new ImageProvider( nNormalImageID
, nHCImageID
) );
215 ::boost::shared_ptr
< ILabelProvider
> getLabelProvider( SQLExceptionInfo::TYPE _eType
, bool _bSubLabel
) const
217 ::boost::shared_ptr
< ILabelProvider
>* ppProvider( &m_pErrorLabel
);
218 USHORT
nLabelID( STR_EXCEPTION_ERROR
);
222 case SQLExceptionInfo::SQL_WARNING
:
223 ppProvider
= &m_pWarningsLabel
;
224 nLabelID
= STR_EXCEPTION_WARNING
;
227 case SQLExceptionInfo::SQL_CONTEXT
:
228 ppProvider
= &m_pInfoLabel
;
229 nLabelID
= _bSubLabel
? STR_EXCEPTION_DETAILS
: STR_EXCEPTION_INFO
;
235 if ( !ppProvider
->get() )
236 ppProvider
->reset( new LabelProvider( nLabelID
) );
242 //------------------------------------------------------------------------------
243 /// a stripped version of the SQLException, packed for displaying
244 struct ExceptionDisplayInfo
246 SQLExceptionInfo::TYPE eType
;
248 ::boost::shared_ptr
< IImageProvider
> pImageProvider
;
249 ::boost::shared_ptr
< ILabelProvider
> pLabelProvider
;
257 ExceptionDisplayInfo() : eType( SQLExceptionInfo::UNDEFINED
), bSubEntry( false ) { }
258 ExceptionDisplayInfo( SQLExceptionInfo::TYPE _eType
) : eType( _eType
), bSubEntry( false ) { }
261 static bool lcl_hasDetails( const ExceptionDisplayInfo
& _displayInfo
)
263 return ( _displayInfo
.sErrorCode
.Len() )
264 || ( _displayInfo
.sSQLState
.Len()
265 && !_displayInfo
.sSQLState
.EqualsAscii( "S1000" )
269 typedef ::std::vector
< ExceptionDisplayInfo
> ExceptionDisplayChain
;
271 //------------------------------------------------------------------------------
272 /// strips the [OOoBase] vendor identifier from the given error message, if applicable
273 ::rtl::OUString
lcl_stripOOoBaseVendor( const ::rtl::OUString
& _rErrorMessage
)
275 ::rtl::OUString
sErrorMessage( _rErrorMessage
);
277 const ::rtl::OUString
sVendorIdentifier( ::connectivity::SQLError::getMessagePrefix() );
278 if ( sErrorMessage
.indexOf( sVendorIdentifier
) == 0 )
280 // characters to strip
281 sal_Int32
nStripLen( sVendorIdentifier
.getLength() );
282 // usually, there should be a whitespace between the vendor and the real message
283 while ( ( sErrorMessage
.getLength() > nStripLen
)
284 && ( sErrorMessage
[nStripLen
] == ' ' )
287 sErrorMessage
= sErrorMessage
.copy( nStripLen
);
290 return sErrorMessage
;
293 //------------------------------------------------------------------------------
294 void lcl_buildExceptionChain( const SQLExceptionInfo
& _rErrorInfo
, const ProviderFactory
& _rFactory
, ExceptionDisplayChain
& _out_rChain
)
297 ExceptionDisplayChain empty
;
298 _out_rChain
.swap( empty
);
301 SQLExceptionIteratorHelper
iter( _rErrorInfo
);
302 while ( iter
.hasMoreElements() )
304 // current chain element
305 SQLExceptionInfo aCurrentElement
;
306 iter
.next( aCurrentElement
);
308 const SQLException
* pCurrentError
= (const SQLException
*)aCurrentElement
;
309 DBG_ASSERT( pCurrentError
, "lcl_buildExceptionChain: iterator failure!" );
310 // hasMoreElements should not have returned <TRUE/> in this case
312 ExceptionDisplayInfo
aDisplayInfo( aCurrentElement
.getType() );
314 aDisplayInfo
.sMessage
= pCurrentError
->Message
.trim();
315 aDisplayInfo
.sSQLState
= pCurrentError
->SQLState
;
316 if ( pCurrentError
->ErrorCode
)
317 aDisplayInfo
.sErrorCode
= String::CreateFromInt32( pCurrentError
->ErrorCode
);
319 if ( !aDisplayInfo
.sMessage
.Len()
320 && !lcl_hasDetails( aDisplayInfo
)
323 OSL_ENSURE( false, "lcl_buildExceptionChain: useles exception: no state, no error code, no message!" );
327 aDisplayInfo
.pImageProvider
= _rFactory
.getImageProvider( aCurrentElement
.getType() );
328 aDisplayInfo
.pLabelProvider
= _rFactory
.getLabelProvider( aCurrentElement
.getType(), false );
330 _out_rChain
.push_back( aDisplayInfo
);
332 if ( aCurrentElement
.getType() == SQLExceptionInfo::SQL_CONTEXT
)
334 const SQLContext
* pContext
= (const SQLContext
*)aCurrentElement
;
335 if ( pContext
->Details
.getLength() )
337 ExceptionDisplayInfo
aSubInfo( aCurrentElement
.getType() );
339 aSubInfo
.sMessage
= pContext
->Details
;
340 aSubInfo
.pImageProvider
= _rFactory
.getImageProvider( aCurrentElement
.getType() );
341 aSubInfo
.pLabelProvider
= _rFactory
.getLabelProvider( aCurrentElement
.getType(), true );
342 aSubInfo
.bSubEntry
= true;
344 _out_rChain
.push_back( aSubInfo
);
350 //------------------------------------------------------------------------------
351 void lcl_insertExceptionEntry( SvTreeListBox
& _rList
, bool _bHiContrast
, size_t _nElementPos
, const ExceptionDisplayInfo
& _rEntry
)
353 Image
aEntryImage( _rEntry
.pImageProvider
->getImage( _bHiContrast
) );
354 SvLBoxEntry
* pListEntry
=
355 _rList
.InsertEntry( _rEntry
.pLabelProvider
->getLabel(), aEntryImage
, aEntryImage
);
356 pListEntry
->SetUserData( reinterpret_cast< void* >( _nElementPos
) );
360 //==============================================================================
361 class OExceptionChainDialog
: public ModalDialog
364 FixedText m_aListLabel
;
365 SvTreeListBox m_aExceptionList
;
366 FixedText m_aDescLabel
;
367 MultiLineEdit m_aExceptionText
;
370 String m_sStatusLabel
;
371 String m_sErrorCodeLabel
;
373 ExceptionDisplayChain m_aExceptions
;
376 OExceptionChainDialog( Window
* pParent
, const ExceptionDisplayChain
& _rExceptions
);
377 ~OExceptionChainDialog();
380 DECL_LINK(OnExceptionSelected
, void*);
383 DBG_NAME(OExceptionChainDialog
)
384 //------------------------------------------------------------------------------
385 OExceptionChainDialog::OExceptionChainDialog( Window
* pParent
, const ExceptionDisplayChain
& _rExceptions
)
386 :ModalDialog(pParent
, ModuleRes(DLG_SQLEXCEPTIONCHAIN
))
387 ,m_aFrame (this, ModuleRes(FL_DETAILS
))
388 ,m_aListLabel (this, ModuleRes(FT_ERRORLIST
))
389 ,m_aExceptionList (this, ModuleRes(CTL_ERRORLIST
))
390 ,m_aDescLabel (this, ModuleRes(FT_DESCRIPTION
))
391 ,m_aExceptionText (this, ModuleRes(ME_DESCRIPTION
))
392 ,m_aOK (this, ModuleRes(PB_OK
))
393 ,m_aExceptions( _rExceptions
)
395 DBG_CTOR(OExceptionChainDialog
,NULL
);
397 m_sStatusLabel
= String( ModuleRes( STR_EXCEPTION_STATUS
) );
398 m_sErrorCodeLabel
= String( ModuleRes( STR_EXCEPTION_ERRORCODE
) );
402 m_aExceptionList
.SetSelectionMode(SINGLE_SELECTION
);
403 m_aExceptionList
.SetDragDropMode(0);
404 m_aExceptionList
.EnableInplaceEditing(sal_False
);
405 m_aExceptionList
.SetWindowBits(WB_HASLINES
| WB_HASBUTTONS
| WB_HASBUTTONSATROOT
| WB_HSCROLL
);
407 m_aExceptionList
.SetSelectHdl(LINK(this, OExceptionChainDialog
, OnExceptionSelected
));
408 m_aExceptionList
.SetNodeDefaultImages( );
409 m_aExceptionText
.SetReadOnly(sal_True
);
411 bool bHave22018
= false;
412 bool bHiContrast
= isHiContrast( this );
413 size_t elementPos
= 0;
415 for ( ExceptionDisplayChain::const_iterator loop
= m_aExceptions
.begin();
416 loop
!= m_aExceptions
.end();
420 lcl_insertExceptionEntry( m_aExceptionList
, bHiContrast
, elementPos
, *loop
);
421 bHave22018
= loop
->sSQLState
.EqualsAscii( "22018" );
424 // if the error has the code 22018, then add an additional explanation
425 // #i24021# / 2004-10-14 / frank.schoenheit@sun.com
428 ProviderFactory aProviderFactory
;
430 ExceptionDisplayInfo aInfo22018
;
431 aInfo22018
.sMessage
= String( ModuleRes( STR_EXPLAN_STRINGCONVERSION_ERROR
) );
432 aInfo22018
.pLabelProvider
= aProviderFactory
.getLabelProvider( SQLExceptionInfo::SQL_CONTEXT
, false );
433 aInfo22018
.pImageProvider
= aProviderFactory
.getImageProvider( SQLExceptionInfo::SQL_CONTEXT
);
434 m_aExceptions
.push_back( aInfo22018
);
436 lcl_insertExceptionEntry( m_aExceptionList
, bHiContrast
, m_aExceptions
.size() - 1, aInfo22018
);
440 //------------------------------------------------------------------------------
441 OExceptionChainDialog::~OExceptionChainDialog()
443 DBG_DTOR(OExceptionChainDialog
,NULL
);
446 //------------------------------------------------------------------------------
447 IMPL_LINK(OExceptionChainDialog
, OnExceptionSelected
, void*, EMPTYARG
)
449 SvLBoxEntry
* pSelected
= m_aExceptionList
.FirstSelected();
450 DBG_ASSERT(!pSelected
|| !m_aExceptionList
.NextSelected(pSelected
), "OExceptionChainDialog::OnExceptionSelected : multi selection ?");
456 size_t pos
= reinterpret_cast< size_t >( pSelected
->GetUserData() );
457 const ExceptionDisplayInfo
& aExceptionInfo( m_aExceptions
[ pos
] );
459 if ( aExceptionInfo
.sSQLState
.Len() )
461 sText
+= m_sStatusLabel
;
462 sText
.AppendAscii(": ");
463 sText
+= aExceptionInfo
.sSQLState
;
464 sText
.AppendAscii("\n");
467 if ( aExceptionInfo
.sErrorCode
.Len() )
469 sText
+= m_sErrorCodeLabel
;
470 sText
.AppendAscii(": ");
471 sText
+= aExceptionInfo
.sErrorCode
;
472 sText
.AppendAscii("\n");
476 sText
.AppendAscii( "\n" );
478 sText
+= aExceptionInfo
.sMessage
;
481 m_aExceptionText
.SetText(sText
);
486 //==============================================================================
487 //= SQLMessageBox_Impl
488 //==============================================================================
489 struct SQLMessageBox_Impl
491 ExceptionDisplayChain aDisplayInfo
;
493 SQLMessageBox_Impl( const SQLExceptionInfo
& _rExceptionInfo
)
495 // transform the exception chain to a form more suitable for displaying it here
496 ProviderFactory aProviderFactory
;
497 lcl_buildExceptionChain( _rExceptionInfo
, aProviderFactory
, aDisplayInfo
);
501 //------------------------------------------------------------------------------
504 ::rtl::OUString
lcl_getProductName()
506 ::rtl::OUString sProductName
;
507 OSL_VERIFY( ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME
) >>= sProductName
);
511 void lcl_positionInAppFont( const Window
& _rParent
, Window
& _rChild
, long _nX
, long _nY
, long _Width
, long _Height
)
513 Point aPos
= _rParent
.LogicToPixel( Point( _nX
, _nY
), MAP_APPFONT
);
514 Size aSize
= _rParent
.LogicToPixel( Size( _Width
, _Height
), MAP_APPFONT
);
515 _rChild
.SetPosSizePixel( aPos
, aSize
);
518 void lcl_addButton( ButtonDialog
& _rDialog
, StandardButtonType _eType
, bool _bDefault
)
520 USHORT nButtonID
= 0;
523 case BUTTON_YES
: nButtonID
= BUTTONID_YES
; break;
524 case BUTTON_NO
: nButtonID
= BUTTONID_NO
; break;
525 case BUTTON_OK
: nButtonID
= BUTTONID_OK
; break;
526 case BUTTON_CANCEL
: nButtonID
= BUTTONID_CANCEL
; break;
527 case BUTTON_RETRY
: nButtonID
= BUTTONID_RETRY
; break;
528 case BUTTON_HELP
: nButtonID
= BUTTONID_HELP
; break;
530 OSL_ENSURE( false, "lcl_addButton: invalid button id!" );
533 _rDialog
.AddButton( _eType
, nButtonID
, _bDefault
? BUTTONDIALOG_DEFBUTTON
| BUTTONDIALOG_FOCUSBUTTON
: 0 );
537 //------------------------------------------------------------------------------
538 void OSQLMessageBox::impl_positionControls()
540 OSL_PRECOND( !m_pImpl
->aDisplayInfo
.empty(), "OSQLMessageBox::impl_positionControls: nothing to display at all?" );
543 if ( m_pImpl
->aDisplayInfo
.empty() )
545 const ExceptionDisplayInfo
* pSecondInfo
= NULL
;
547 const ExceptionDisplayInfo
& rFirstInfo
= *m_pImpl
->aDisplayInfo
.begin();
548 if ( m_pImpl
->aDisplayInfo
.size() > 1 )
549 pSecondInfo
= &m_pImpl
->aDisplayInfo
[1];
550 String sPrimary
, sSecondary
;
551 sPrimary
= rFirstInfo
.sMessage
;
552 // one or two texts to display?
555 // we show two elements in the main dialog if and only if one of
556 // - the first element in the chain is an SQLContext, and the second
557 // element denotes its sub entry
558 // - the first and the second element are both independent (i.e. the second
559 // is no sub entry), and none of them is a context.
560 bool bFirstElementIsContext
= ( rFirstInfo
.eType
== SQLExceptionInfo::SQL_CONTEXT
);
561 bool bSecondElementIsContext
= ( pSecondInfo
->eType
== SQLExceptionInfo::SQL_CONTEXT
);
563 if ( bFirstElementIsContext
&& pSecondInfo
->bSubEntry
)
564 sSecondary
= pSecondInfo
->sMessage
;
565 if ( !bFirstElementIsContext
&& !bSecondElementIsContext
)
566 sSecondary
= pSecondInfo
->sMessage
;
570 lcl_positionInAppFont( *this, m_aInfoImage
, OUTER_MARGIN
, OUTER_MARGIN
, IMAGE_SIZE
, IMAGE_SIZE
);
574 lcl_positionInAppFont( *this, m_aTitle
, TEXT_POS_X
, OUTER_MARGIN
, DIALOG_WIDTH
- TEXT_POS_X
- 2 * OUTER_MARGIN
, 16 );
575 sPrimary
= lcl_stripOOoBaseVendor( sPrimary
);
576 m_aTitle
.SetText( sPrimary
);
579 Rectangle
aPrimaryRect( m_aTitle
.GetPosPixel(), m_aTitle
.GetSizePixel() );
581 // secondary text (if applicable)
582 m_aMessage
.SetStyle( m_aMessage
.GetStyle() | WB_NOLABEL
);
583 sSecondary
= lcl_stripOOoBaseVendor( sSecondary
);
584 m_aMessage
.SetText( sSecondary
);
586 lcl_positionInAppFont( *this, m_aMessage
, TEXT_POS_X
, OUTER_MARGIN
+ 16 + 3, DIALOG_WIDTH
- TEXT_POS_X
- 2 * OUTER_MARGIN
, 8 );
587 Rectangle
aSecondaryRect( m_aMessage
.GetPosPixel(), m_aMessage
.GetSizePixel() );
589 bool bHaveSecondaryText
= sSecondary
.Len() != 0;
591 // determine which space the secondary text would occupy
592 if ( bHaveSecondaryText
)
593 aSecondaryRect
= GetTextRect( aSecondaryRect
, sSecondary
, TEXT_DRAW_WORDBREAK
| TEXT_DRAW_MULTILINE
| TEXT_DRAW_LEFT
);
595 aSecondaryRect
.Bottom() = aSecondaryRect
.Top() - 1;
597 // adjust secondary control height accordingly
598 m_aMessage
.SetSizePixel( aSecondaryRect
.GetSize() );
599 m_aMessage
.Show( aSecondaryRect
.GetHeight() > 0 );
601 // if there's no secondary text ...
602 if ( !bHaveSecondaryText
)
603 { // then give the primary text as much horizontal space as it needs
604 Rectangle
aSuggestedRect( GetTextRect( aPrimaryRect
, sPrimary
, TEXT_DRAW_WORDBREAK
| TEXT_DRAW_MULTILINE
| TEXT_DRAW_CENTER
) );
605 aPrimaryRect
.Right() = aPrimaryRect
.Left() + aSuggestedRect
.GetWidth();
606 aPrimaryRect
.Bottom() = aPrimaryRect
.Top() + aSuggestedRect
.GetHeight();
607 // and center it horizontally
608 m_aTitle
.SetStyle( ( m_aTitle
.GetStyle() & ~WB_LEFT
) | WB_CENTER
);
610 Rectangle
aInfoRect( m_aInfoImage
.GetPosPixel(), m_aInfoImage
.GetSizePixel() );
611 // also, if it's not as high as the image ...
612 if ( aPrimaryRect
.GetHeight() < m_aInfoImage
.GetSizePixel().Height() )
613 { // ... make it fit the image height
614 aPrimaryRect
.Bottom() += aInfoRect
.GetHeight() - aPrimaryRect
.GetHeight();
615 // and center it vertically
616 m_aTitle
.SetStyle( m_aTitle
.GetStyle() | WB_VCENTER
);
619 { // ... otherwise, center the image vertically, relative to the primary text
620 aInfoRect
.Move( 0, ( aPrimaryRect
.GetHeight() - aInfoRect
.GetHeight() ) / 2 );
621 m_aInfoImage
.SetPosSizePixel( aInfoRect
.TopLeft(), aInfoRect
.GetSize() );
624 m_aTitle
.SetPosSizePixel( aPrimaryRect
.TopLeft(), aPrimaryRect
.GetSize() );
627 // adjust dialog size accordingly
628 const Rectangle
& rBottomTextRect( bHaveSecondaryText
? aSecondaryRect
: aPrimaryRect
);
629 Size aBorderSize
= LogicToPixel( Size( OUTER_MARGIN
, OUTER_MARGIN
), MAP_APPFONT
);
630 Size
aDialogSize( LogicToPixel( Size( DIALOG_WIDTH
, 30 ), MAP_APPFONT
) );
631 aDialogSize
.Height() = rBottomTextRect
.Bottom() + aBorderSize
.Height();
632 aDialogSize
.Width() = aPrimaryRect
.Right() + aBorderSize
.Width();
634 SetSizePixel( aDialogSize
);
635 SetPageSizePixel( aDialogSize
);
638 //------------------------------------------------------------------------------
639 void OSQLMessageBox::impl_initImage( MessageType _eImage
)
644 DBG_ERROR( "OSQLMessageBox::impl_initImage: unsupported image type!" );
647 m_aInfoImage
.SetImage(InfoBox::GetStandardImage());
650 m_aInfoImage
.SetImage(WarningBox::GetStandardImage());
653 m_aInfoImage
.SetImage(ErrorBox::GetStandardImage());
656 m_aInfoImage
.SetImage(QueryBox::GetStandardImage());
661 //------------------------------------------------------------------------------
662 void OSQLMessageBox::impl_createStandardButtons( WinBits _nStyle
)
664 if ( _nStyle
& WB_YES_NO_CANCEL
)
666 lcl_addButton( *this, BUTTON_YES
, ( _nStyle
& WB_DEF_YES
) != 0 );
667 lcl_addButton( *this, BUTTON_NO
, ( _nStyle
& WB_DEF_NO
) != 0 );
668 lcl_addButton( *this, BUTTON_CANCEL
, ( _nStyle
& WB_DEF_CANCEL
) != 0 );
670 else if ( _nStyle
& WB_OK_CANCEL
)
672 lcl_addButton( *this, BUTTON_OK
, ( _nStyle
& WB_DEF_OK
) != 0 );
673 lcl_addButton( *this, BUTTON_CANCEL
, ( _nStyle
& WB_DEF_CANCEL
) != 0 );
675 else if ( _nStyle
& WB_YES_NO
)
677 lcl_addButton( *this, BUTTON_YES
, ( _nStyle
& WB_DEF_YES
) != 0 );
678 lcl_addButton( *this, BUTTON_NO
, ( _nStyle
& WB_DEF_NO
) != 0 );
680 else if ( _nStyle
& WB_RETRY_CANCEL
)
682 lcl_addButton( *this, BUTTON_RETRY
, ( _nStyle
& WB_DEF_RETRY
) != 0 );
683 lcl_addButton( *this, BUTTON_CANCEL
, ( _nStyle
& WB_DEF_CANCEL
) != 0 );
687 OSL_ENSURE( WB_OK
& _nStyle
, "OSQLMessageBox::impl_createStandardButtons: unsupported dialog style requested!" );
688 AddButton( BUTTON_OK
, BUTTONID_OK
, BUTTONDIALOG_DEFBUTTON
| BUTTONDIALOG_FOCUSBUTTON
);
691 if ( m_sHelpURL
.getLength() )
693 lcl_addButton( *this, BUTTON_HELP
, false );
695 SmartId
aHelpId( m_sHelpURL
);
696 if ( m_sHelpURL
.indexOfAsciiL( "HID:", 4 ) == 0 )
697 aHelpId
= SmartId( m_sHelpURL
.copy( 4 ).toInt32() );
699 SetSmartHelpId( aHelpId
);
703 //------------------------------------------------------------------------------
704 void OSQLMessageBox::impl_addDetailsButton()
706 size_t nFirstPageVisible
= m_aMessage
.IsVisible() ? 2 : 1;
708 bool bMoreDetailsAvailable
= m_pImpl
->aDisplayInfo
.size() > nFirstPageVisible
;
709 if ( !bMoreDetailsAvailable
)
711 // even if the text fits into what we can display, we might need to details button
712 // if there is more non-trivial information in the errors than the mere messages
713 for ( ExceptionDisplayChain::const_iterator error
= m_pImpl
->aDisplayInfo
.begin();
714 error
!= m_pImpl
->aDisplayInfo
.end();
718 if ( lcl_hasDetails( *error
) )
720 bMoreDetailsAvailable
= true;
726 if ( bMoreDetailsAvailable
)
728 AddButton( BUTTON_MORE
, BUTTONID_MORE
, 0 );
729 PushButton
* pButton
= GetPushButton( BUTTONID_MORE
);
730 OSL_ENSURE( pButton
, "OSQLMessageBox::impl_addDetailsButton: just added this button, why isn't it there?" );
731 pButton
->SetClickHdl( LINK( this, OSQLMessageBox
, ButtonClickHdl
) );
732 pButton
->SetUniqueId( UID_SQLERROR_BUTTONMORE
);
736 //------------------------------------------------------------------------------
737 void OSQLMessageBox::Construct( WinBits _nStyle
, MessageType _eImage
)
739 // Changed as per BugID 79541 Branding/Configuration
740 String
sDialogTitle( lcl_getProductName() );
741 SetText( sDialogTitle
.AppendAscii( " Base" ) );
743 // position and size the controls and the dialog, depending on whether we have one or two texts to display
744 impl_positionControls();
747 MessageType
eType( _eImage
);
750 switch ( m_pImpl
->aDisplayInfo
[0].eType
)
752 case SQLExceptionInfo::SQL_EXCEPTION
: eType
= Error
; break;
753 case SQLExceptionInfo::SQL_WARNING
: eType
= Warning
; break;
754 case SQLExceptionInfo::SQL_CONTEXT
: eType
= Info
; break;
755 default: OSL_ENSURE( false, "OSQLMessageBox::Construct: invalid type!" );
758 impl_initImage( eType
);
761 impl_createStandardButtons( _nStyle
);
762 impl_addDetailsButton();
765 //------------------------------------------------------------------------------
766 OSQLMessageBox::OSQLMessageBox(Window
* _pParent
, const SQLExceptionInfo
& _rException
, WinBits _nStyle
, const ::rtl::OUString
& _rHelpURL
)
767 :ButtonDialog( _pParent
, WB_HORZ
| WB_STDDIALOG
)
768 ,m_aInfoImage( this )
769 ,m_aTitle( this, WB_WORDBREAK
| WB_LEFT
)
770 ,m_aMessage( this, WB_WORDBREAK
| WB_LEFT
)
771 ,m_sHelpURL( _rHelpURL
)
772 ,m_pImpl( new SQLMessageBox_Impl( _rException
) )
774 Construct( _nStyle
, AUTO
);
777 //------------------------------------------------------------------------------
778 OSQLMessageBox::OSQLMessageBox( Window
* _pParent
, const UniString
& _rTitle
, const UniString
& _rMessage
, WinBits _nStyle
, MessageType _eType
, const ::dbtools::SQLExceptionInfo
* _pAdditionalErrorInfo
)
779 :ButtonDialog( _pParent
, WB_HORZ
| WB_STDDIALOG
)
780 ,m_aInfoImage( this )
781 ,m_aTitle( this, WB_WORDBREAK
| WB_LEFT
)
782 ,m_aMessage( this, WB_WORDBREAK
| WB_LEFT
)
785 aError
.Message
= _rTitle
;
786 aError
.Details
= _rMessage
;
787 if ( _pAdditionalErrorInfo
)
788 aError
.NextException
= _pAdditionalErrorInfo
->get();
790 m_pImpl
.reset( new SQLMessageBox_Impl( SQLExceptionInfo( aError
) ) );
792 Construct( _nStyle
, _eType
);
795 //--------------------------------------------------------------------------
796 OSQLMessageBox::~OSQLMessageBox()
800 //--------------------------------------------------------------------------
801 IMPL_LINK( OSQLMessageBox
, ButtonClickHdl
, Button
*, /*pButton*/ )
803 OExceptionChainDialog
aDlg( this, m_pImpl
->aDisplayInfo
);
808 //==================================================================
810 //==================================================================
811 OSQLWarningBox::OSQLWarningBox( Window
* _pParent
, const UniString
& _rMessage
, WinBits _nStyle
,
812 const ::dbtools::SQLExceptionInfo
* _pAdditionalErrorInfo
)
813 :OSQLMessageBox( _pParent
, String( ModuleRes( STR_STAT_WARNING
) ), _rMessage
, _nStyle
, OSQLMessageBox::Warning
, _pAdditionalErrorInfo
)
817 //.........................................................................
819 //.........................................................................