bump product version to 4.1.6.2
[LibreOffice.git] / dbaccess / source / ui / dlg / sqlmessage.cxx
blobc35fba5f4568529fc171476586eff3534fe723ed
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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
46 #define IMAGE_SIZE 20
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 //.........................................................................
56 namespace dbaui
58 //.........................................................................
60 namespace
62 //------------------------------------------------------------------------------
63 class IImageProvider
65 public:
66 virtual Image getImage() const = 0;
68 virtual ~IImageProvider() { }
71 //------------------------------------------------------------------------------
72 class ILabelProvider
74 public:
75 virtual String getLabel() const = 0;
77 virtual ~ILabelProvider() { };
80 //------------------------------------------------------------------------------
81 class ImageProvider : public IImageProvider
83 private:
84 sal_uInt16 m_defaultImageID;
86 mutable Image m_defaultImage;
88 public:
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
105 private:
106 String m_label;
107 public:
108 LabelProvider( sal_uInt16 _labelResourceID )
109 :m_label( ModuleRes( _labelResourceID ) )
113 virtual String getLabel() const
115 return m_label;
119 //------------------------------------------------------------------------------
120 class ProviderFactory
122 private:
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;
130 public:
131 ProviderFactory()
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 );
140 switch ( _eType )
142 case SQLExceptionInfo::SQL_WARNING:
143 ppProvider = &m_pWarningsImage;
144 nNormalImageID = BMP_EXCEPTION_WARNING;
145 break;
147 case SQLExceptionInfo::SQL_CONTEXT:
148 ppProvider = &m_pInfoImage;
149 nNormalImageID = BMP_EXCEPTION_INFO;
150 break;
152 default:
153 break;
156 if ( !ppProvider->get() )
157 ppProvider->reset( new ImageProvider( nNormalImageID ) );
158 return *ppProvider;
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 );
166 switch ( _eType )
168 case SQLExceptionInfo::SQL_WARNING:
169 ppProvider = &m_pWarningsLabel;
170 nLabelID = STR_EXCEPTION_WARNING;
171 break;
173 case SQLExceptionInfo::SQL_CONTEXT:
174 ppProvider = &m_pInfoLabel;
175 nLabelID = _bSubLabel ? STR_EXCEPTION_DETAILS : STR_EXCEPTION_INFO;
176 break;
177 default:
178 break;
181 if ( !ppProvider->get() )
182 ppProvider->reset( new LabelProvider( nLabelID ) );
183 return *ppProvider;
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;
197 bool bSubEntry;
199 String sMessage;
200 String sSQLState;
201 String sErrorCode;
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] == ' ' )
232 ++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!" );
270 continue;
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
309 FixedLine m_aFrame;
310 FixedText m_aListLabel;
311 SvTreeListBox m_aExceptionList;
312 FixedText m_aDescLabel;
313 MultiLineEdit m_aExceptionText;
314 OKButton m_aOK;
316 String m_sStatusLabel;
317 String m_sErrorCodeLabel;
319 ExceptionDisplayChain m_aExceptions;
321 public:
322 OExceptionChainDialog( Window* pParent, const ExceptionDisplayChain& _rExceptions );
323 ~OExceptionChainDialog();
325 protected:
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 ) );
346 FreeResource();
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();
362 ++loop, ++elementPos
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
370 // #i24021#
371 if ( bHave22018 )
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 ?");
397 OUString sText;
399 if ( pSelected )
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;
407 sText += ": ";
408 sText += aExceptionInfo.sSQLState;
409 sText += "\n";
412 if ( aExceptionInfo.sErrorCode.Len() )
414 sText += m_sErrorCodeLabel;
415 sText += ": ";
416 sText += aExceptionInfo.sErrorCode;
417 sText += "\n";
420 if ( !sText.isEmpty() )
421 sText += "\n";
423 sText += aExceptionInfo.sMessage;
426 m_aExceptionText.SetText(sText);
428 return 0L;
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 //------------------------------------------------------------------------------
447 namespace
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;
459 switch ( _eType )
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;
467 default:
468 OSL_FAIL( "lcl_addButton: invalid button id!" );
469 break;
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() )
482 return;
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?
491 if ( pSecondInfo )
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;
507 // image
508 lcl_positionInAppFont( *this, m_aInfoImage, OUTER_MARGIN, OUTER_MARGIN, IMAGE_SIZE, IMAGE_SIZE );
509 m_aInfoImage.Show();
511 // primary text
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 );
515 m_aTitle.Show();
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 );
532 else
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 );
556 else
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 )
579 switch (_eImage)
581 default:
582 OSL_FAIL( "OSQLMessageBox::impl_initImage: unsupported image type!" );
584 case Info:
585 m_aInfoImage.SetImage(InfoBox::GetStandardImage());
586 break;
587 case Warning:
588 m_aInfoImage.SetImage(WarningBox::GetStandardImage());
589 break;
590 case Error:
591 m_aInfoImage.SetImage(ErrorBox::GetStandardImage());
592 break;
593 case Query:
594 m_aInfoImage.SetImage(QueryBox::GetStandardImage());
595 break;
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 );
623 else
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 );
633 OUString aTmp;
634 INetURLObject aHID( m_sHelpURL );
635 if ( aHID.GetProtocol() == INET_PROT_HID )
636 aTmp = aHID.GetURLPath();
637 else
638 aTmp = m_sHelpURL;
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();
656 ++error
659 if ( lcl_hasDetails( *error ) )
661 bMoreDetailsAvailable = true;
662 break;
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 )
680 SetText(
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();
687 // init the image
688 MessageType eType( _eImage );
689 if ( eType == AUTO )
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 );
701 // create buttons
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 )
725 SQLContext aError;
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 );
745 aDlg.Execute();
746 return 0;
749 //==================================================================
750 // OSQLWarningBox
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 //==================================================================
759 // OSQLErrorBox
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 //.........................................................................
768 } // namespace dbaui
769 //.........................................................................
771 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */