LCOV - code coverage report
Current view: top level - dbaccess/source/ui/dlg - sqlmessage.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 325 0.3 %
Date: 2014-11-03 Functions: 2 48 4.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include "sqlmessage.hxx"
      21             : #include "dbu_dlg.hrc"
      22             : #include <com/sun/star/sdbc/SQLException.hpp>
      23             : #include <com/sun/star/sdb/SQLContext.hpp>
      24             : #include <vcl/fixed.hxx>
      25             : #include <osl/diagnose.h>
      26             : #include <svtools/treelistbox.hxx>
      27             : #include "svtools/treelistentry.hxx"
      28             : #include <svtools/svmedit.hxx>
      29             : #include <connectivity/dbexception.hxx>
      30             : #include <connectivity/sqlerror.hxx>
      31             : #include <vcl/msgbox.hxx>
      32             : #include <unotools/configmgr.hxx>
      33             : #include <sfx2/sfxuno.hxx>
      34             : #include "dbaccess_helpid.hrc"
      35             : #include "UITools.hxx"
      36             : #include "moduledbu.hxx"
      37             : 
      38             : #include <tools/urlobj.hxx>
      39             : 
      40             : #define RET_MORE   RET_RETRY + 1
      41             : 
      42             : #define DIALOG_WIDTH    220
      43             : #define OUTER_MARGIN    6
      44             : #define IMAGE_SIZE      20
      45             : #define INNER_PADDING   3
      46             : #define TEXT_POS_X      ( OUTER_MARGIN + IMAGE_SIZE + INNER_PADDING )
      47             : 
      48             : using namespace dbtools;
      49             : using namespace com::sun::star::uno;
      50             : using namespace com::sun::star::sdb;
      51             : using namespace com::sun::star::sdbc;
      52             : 
      53             : namespace dbaui
      54             : {
      55             : 
      56             : namespace
      57             : {
      58           0 :     class IImageProvider
      59             :     {
      60             :     public:
      61             :         virtual Image   getImage() const = 0;
      62             : 
      63           0 :         virtual ~IImageProvider() { }
      64             :     };
      65             : 
      66           0 :     class ILabelProvider
      67             :     {
      68             :     public:
      69             :         virtual OUString  getLabel() const = 0;
      70             : 
      71           0 :         virtual ~ILabelProvider() { };
      72             :     };
      73             : 
      74           0 :     class ImageProvider : public IImageProvider
      75             :     {
      76             :     private:
      77             :         sal_uInt16  m_defaultImageID;
      78             : 
      79             :         mutable Image   m_defaultImage;
      80             : 
      81             :     public:
      82           0 :         ImageProvider( sal_uInt16 _defaultImageID )
      83           0 :             :m_defaultImageID( _defaultImageID )
      84             :         {
      85           0 :         }
      86             : 
      87           0 :         virtual Image getImage() const SAL_OVERRIDE
      88             :         {
      89           0 :             if ( !m_defaultImage )
      90           0 :                 m_defaultImage = Image( ModuleRes( m_defaultImageID ) );
      91           0 :             return m_defaultImage;
      92             :         }
      93             :     };
      94             : 
      95           0 :     class LabelProvider : public ILabelProvider
      96             :     {
      97             :     private:
      98             :         OUString  m_label;
      99             :     public:
     100           0 :         LabelProvider( sal_uInt16 _labelResourceID )
     101           0 :             :m_label( ModuleRes( _labelResourceID ) )
     102             :         {
     103           0 :         }
     104             : 
     105           0 :         virtual OUString  getLabel() const SAL_OVERRIDE
     106             :         {
     107           0 :             return m_label;
     108             :         }
     109             :     };
     110             : 
     111           0 :     class ProviderFactory
     112             :     {
     113             :     private:
     114             :         mutable ::boost::shared_ptr< IImageProvider >   m_pErrorImage;
     115             :         mutable ::boost::shared_ptr< IImageProvider >   m_pWarningsImage;
     116             :         mutable ::boost::shared_ptr< IImageProvider >   m_pInfoImage;
     117             :         mutable ::boost::shared_ptr< ILabelProvider >   m_pErrorLabel;
     118             :         mutable ::boost::shared_ptr< ILabelProvider >   m_pWarningsLabel;
     119             :         mutable ::boost::shared_ptr< ILabelProvider >   m_pInfoLabel;
     120             : 
     121             :     public:
     122           0 :         ProviderFactory()
     123           0 :         {
     124           0 :         }
     125             : 
     126           0 :         ::boost::shared_ptr< IImageProvider >   getImageProvider( SQLExceptionInfo::TYPE _eType ) const
     127             :         {
     128           0 :             ::boost::shared_ptr< IImageProvider >* ppProvider( &m_pErrorImage );
     129           0 :             sal_uInt16 nNormalImageID( BMP_EXCEPTION_ERROR );
     130             : 
     131           0 :             switch ( _eType )
     132             :             {
     133             :             case SQLExceptionInfo::SQL_WARNING:
     134           0 :                 ppProvider = &m_pWarningsImage;
     135           0 :                 nNormalImageID = BMP_EXCEPTION_WARNING;
     136           0 :                 break;
     137             : 
     138             :             case SQLExceptionInfo::SQL_CONTEXT:
     139           0 :                 ppProvider = &m_pInfoImage;
     140           0 :                 nNormalImageID = BMP_EXCEPTION_INFO;
     141           0 :                 break;
     142             : 
     143             :             default:
     144           0 :                 break;
     145             :             }
     146             : 
     147           0 :             if ( !ppProvider->get() )
     148           0 :                 ppProvider->reset( new ImageProvider( nNormalImageID ) );
     149           0 :             return *ppProvider;
     150             :         }
     151             : 
     152           0 :         ::boost::shared_ptr< ILabelProvider >   getLabelProvider( SQLExceptionInfo::TYPE _eType, bool _bSubLabel ) const
     153             :         {
     154           0 :             ::boost::shared_ptr< ILabelProvider >* ppProvider( &m_pErrorLabel );
     155           0 :             sal_uInt16 nLabelID( STR_EXCEPTION_ERROR );
     156             : 
     157           0 :             switch ( _eType )
     158             :             {
     159             :             case SQLExceptionInfo::SQL_WARNING:
     160           0 :                 ppProvider = &m_pWarningsLabel;
     161           0 :                 nLabelID = STR_EXCEPTION_WARNING;
     162           0 :                 break;
     163             : 
     164             :             case SQLExceptionInfo::SQL_CONTEXT:
     165           0 :                 ppProvider = &m_pInfoLabel;
     166           0 :                 nLabelID = _bSubLabel ? STR_EXCEPTION_DETAILS : STR_EXCEPTION_INFO;
     167           0 :                 break;
     168             :             default:
     169           0 :                 break;
     170             :             }
     171             : 
     172           0 :             if ( !ppProvider->get() )
     173           0 :                 ppProvider->reset( new LabelProvider( nLabelID ) );
     174           0 :             return *ppProvider;
     175             :         }
     176             : 
     177             :     };
     178             : 
     179             :     /// a stripped version of the SQLException, packed for displaying
     180           0 :     struct ExceptionDisplayInfo
     181             :     {
     182             :         SQLExceptionInfo::TYPE                  eType;
     183             : 
     184             :         ::boost::shared_ptr< IImageProvider >   pImageProvider;
     185             :         ::boost::shared_ptr< ILabelProvider >   pLabelProvider;
     186             : 
     187             :         bool                                    bSubEntry;
     188             : 
     189             :         OUString                                sMessage;
     190             :         OUString                                sSQLState;
     191             :         OUString                                sErrorCode;
     192             : 
     193           0 :         ExceptionDisplayInfo() : eType( SQLExceptionInfo::UNDEFINED ), bSubEntry( false ) { }
     194           0 :         ExceptionDisplayInfo( SQLExceptionInfo::TYPE _eType ) : eType( _eType ), bSubEntry( false ) { }
     195             :     };
     196             : 
     197           0 :     static bool lcl_hasDetails( const ExceptionDisplayInfo& _displayInfo )
     198             :     {
     199           0 :         return  ( !_displayInfo.sErrorCode.isEmpty() )
     200           0 :                 ||  (   !_displayInfo.sSQLState.isEmpty()
     201           0 :                     &&  !_displayInfo.sSQLState.equalsAscii( "S1000" )
     202           0 :                     );
     203             :     }
     204             : 
     205             :     typedef ::std::vector< ExceptionDisplayInfo >   ExceptionDisplayChain;
     206             : 
     207             :     /// strips the [OOoBase] vendor identifier from the given error message, if applicable
     208           0 :     OUString lcl_stripOOoBaseVendor( const OUString& _rErrorMessage )
     209             :     {
     210           0 :         OUString sErrorMessage( _rErrorMessage );
     211             : 
     212           0 :         const OUString sVendorIdentifier( ::connectivity::SQLError::getMessagePrefix() );
     213           0 :         if ( sErrorMessage.startsWith( sVendorIdentifier ) )
     214             :         {
     215             :             // characters to strip
     216           0 :             sal_Int32 nStripLen( sVendorIdentifier.getLength() );
     217             :             // usually, there should be a whitespace between the vendor and the real message
     218           0 :             while   (   ( sErrorMessage.getLength() > nStripLen )
     219           0 :                     &&  ( sErrorMessage[nStripLen] == ' ' )
     220             :                     )
     221           0 :                     ++nStripLen;
     222           0 :             sErrorMessage = sErrorMessage.copy( nStripLen );
     223             :         }
     224             : 
     225           0 :         return sErrorMessage;
     226             :     }
     227             : 
     228           0 :     void lcl_buildExceptionChain( const SQLExceptionInfo& _rErrorInfo, const ProviderFactory& _rFactory, ExceptionDisplayChain& _out_rChain )
     229             :     {
     230             :         {
     231           0 :             ExceptionDisplayChain empty;
     232           0 :             _out_rChain.swap( empty );
     233             :         }
     234             : 
     235           0 :         SQLExceptionIteratorHelper iter( _rErrorInfo );
     236           0 :         while ( iter.hasMoreElements() )
     237             :         {
     238             :             // current chain element
     239           0 :             SQLExceptionInfo aCurrentElement;
     240           0 :             iter.next( aCurrentElement );
     241             : 
     242           0 :             const SQLException* pCurrentError = (const SQLException*)aCurrentElement;
     243             :             OSL_ENSURE( pCurrentError, "lcl_buildExceptionChain: iterator failure!" );
     244             :                 // hasMoreElements should not have returned <TRUE/> in this case
     245             : 
     246           0 :             ExceptionDisplayInfo aDisplayInfo( aCurrentElement.getType() );
     247             : 
     248           0 :             aDisplayInfo.sMessage = pCurrentError->Message.trim();
     249           0 :             aDisplayInfo.sSQLState = pCurrentError->SQLState;
     250           0 :             if ( pCurrentError->ErrorCode )
     251           0 :                 aDisplayInfo.sErrorCode = OUString::number( pCurrentError->ErrorCode );
     252             : 
     253           0 :             if  (   aDisplayInfo.sMessage.isEmpty()
     254           0 :                 &&  !lcl_hasDetails( aDisplayInfo )
     255             :                 )
     256             :             {
     257             :                 OSL_FAIL( "lcl_buildExceptionChain: useless exception: no state, no error code, no message!" );
     258           0 :                 continue;
     259             :             }
     260             : 
     261           0 :             aDisplayInfo.pImageProvider = _rFactory.getImageProvider( aCurrentElement.getType() );
     262           0 :             aDisplayInfo.pLabelProvider = _rFactory.getLabelProvider( aCurrentElement.getType(), false );
     263             : 
     264           0 :             _out_rChain.push_back( aDisplayInfo );
     265             : 
     266           0 :             if ( aCurrentElement.getType() == SQLExceptionInfo::SQL_CONTEXT )
     267             :             {
     268           0 :                 const SQLContext* pContext = (const SQLContext*)aCurrentElement;
     269           0 :                 if ( !pContext->Details.isEmpty() )
     270             :                 {
     271           0 :                     ExceptionDisplayInfo aSubInfo( aCurrentElement.getType() );
     272             : 
     273           0 :                     aSubInfo.sMessage = pContext->Details;
     274           0 :                     aSubInfo.pImageProvider = _rFactory.getImageProvider( aCurrentElement.getType() );
     275           0 :                     aSubInfo.pLabelProvider = _rFactory.getLabelProvider( aCurrentElement.getType(), true );
     276           0 :                     aSubInfo.bSubEntry = true;
     277             : 
     278           0 :                     _out_rChain.push_back( aSubInfo );
     279             :                 }
     280             :             }
     281           0 :         }
     282           0 :     }
     283             : 
     284           0 :     void lcl_insertExceptionEntry( SvTreeListBox& _rList, size_t _nElementPos, const ExceptionDisplayInfo& _rEntry )
     285             :     {
     286           0 :         Image aEntryImage( _rEntry.pImageProvider->getImage() );
     287             :         SvTreeListEntry* pListEntry =
     288           0 :             _rList.InsertEntry( _rEntry.pLabelProvider->getLabel(), aEntryImage, aEntryImage );
     289           0 :         pListEntry->SetUserData( reinterpret_cast< void* >( _nElementPos ) );
     290           0 :     }
     291             : }
     292             : 
     293           0 : class OExceptionChainDialog : public ModalDialog
     294             : {
     295             :     SvTreeListBox*    m_pExceptionList;
     296             :     VclMultiLineEdit* m_pExceptionText;
     297             : 
     298             :     OUString        m_sStatusLabel;
     299             :     OUString        m_sErrorCodeLabel;
     300             : 
     301             :     ExceptionDisplayChain   m_aExceptions;
     302             : 
     303             : public:
     304             :     OExceptionChainDialog( vcl::Window* pParent, const ExceptionDisplayChain& _rExceptions );
     305             : 
     306             : protected:
     307             :     DECL_LINK(OnExceptionSelected, void*);
     308             : };
     309             : 
     310           0 : OExceptionChainDialog::OExceptionChainDialog(vcl::Window* pParent, const ExceptionDisplayChain& _rExceptions)
     311             :     : ModalDialog(pParent, "SQLExceptionDialog", "dbaccess/ui/sqlexception.ui")
     312           0 :     , m_aExceptions(_rExceptions)
     313             : {
     314           0 :     get(m_pExceptionList, "list");
     315           0 :     Size aListSize(LogicToPixel(Size(85, 93), MAP_APPFONT));
     316           0 :     m_pExceptionList->set_width_request(aListSize.Width());
     317           0 :     m_pExceptionList->set_height_request(aListSize.Height());
     318           0 :     get(m_pExceptionText, "description");
     319           0 :     Size aTextSize(LogicToPixel(Size(125 , 93), MAP_APPFONT));
     320           0 :     m_pExceptionText->set_width_request(aTextSize.Width());
     321           0 :     m_pExceptionText->set_height_request(aTextSize.Height());
     322             : 
     323           0 :     m_sStatusLabel = ModuleRes( STR_EXCEPTION_STATUS );
     324           0 :     m_sErrorCodeLabel = ModuleRes( STR_EXCEPTION_ERRORCODE );
     325             : 
     326           0 :     m_pExceptionList->SetSelectionMode(SINGLE_SELECTION);
     327           0 :     m_pExceptionList->SetDragDropMode(0);
     328           0 :     m_pExceptionList->EnableInplaceEditing(false);
     329           0 :     m_pExceptionList->SetStyle(m_pExceptionList->GetStyle() | WB_HASLINES | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HSCROLL);
     330             : 
     331           0 :     m_pExceptionList->SetSelectHdl(LINK(this, OExceptionChainDialog, OnExceptionSelected));
     332           0 :     m_pExceptionList->SetNodeDefaultImages( );
     333             : 
     334           0 :     bool bHave22018 = false;
     335           0 :     size_t elementPos = 0;
     336             : 
     337           0 :     for (   ExceptionDisplayChain::const_iterator loop = m_aExceptions.begin();
     338           0 :             loop != m_aExceptions.end();
     339             :             ++loop, ++elementPos
     340             :         )
     341             :     {
     342           0 :         lcl_insertExceptionEntry( *m_pExceptionList, elementPos, *loop );
     343           0 :         bHave22018 = loop->sSQLState.equalsAscii( "22018" );
     344             :     }
     345             : 
     346             :     // if the error has the code 22018, then add an additional explanation
     347             :     // #i24021#
     348           0 :     if ( bHave22018 )
     349             :     {
     350           0 :         ProviderFactory aProviderFactory;
     351             : 
     352           0 :         ExceptionDisplayInfo aInfo22018;
     353           0 :         aInfo22018.sMessage = ModuleRes( STR_EXPLAN_STRINGCONVERSION_ERROR );
     354           0 :         aInfo22018.pLabelProvider = aProviderFactory.getLabelProvider( SQLExceptionInfo::SQL_CONTEXT, false );
     355           0 :         aInfo22018.pImageProvider = aProviderFactory.getImageProvider( SQLExceptionInfo::SQL_CONTEXT );
     356           0 :         m_aExceptions.push_back( aInfo22018 );
     357             : 
     358           0 :         lcl_insertExceptionEntry( *m_pExceptionList, m_aExceptions.size() - 1, aInfo22018 );
     359             :     }
     360           0 : }
     361             : 
     362           0 : IMPL_LINK_NOARG(OExceptionChainDialog, OnExceptionSelected)
     363             : {
     364           0 :     SvTreeListEntry* pSelected = m_pExceptionList->FirstSelected();
     365             :     OSL_ENSURE(!pSelected || !m_pExceptionList->NextSelected(pSelected), "OExceptionChainDialog::OnExceptionSelected : multi selection ?");
     366             : 
     367           0 :     OUString sText;
     368             : 
     369           0 :     if ( pSelected )
     370             :     {
     371           0 :         size_t pos = reinterpret_cast< size_t >( pSelected->GetUserData() );
     372           0 :         const ExceptionDisplayInfo& aExceptionInfo( m_aExceptions[ pos ] );
     373             : 
     374           0 :         if ( !aExceptionInfo.sSQLState.isEmpty() )
     375             :         {
     376           0 :             sText += m_sStatusLabel;
     377           0 :             sText += ": ";
     378           0 :             sText += aExceptionInfo.sSQLState;
     379           0 :             sText += "\n";
     380             :         }
     381             : 
     382           0 :         if ( !aExceptionInfo.sErrorCode.isEmpty() )
     383             :         {
     384           0 :             sText += m_sErrorCodeLabel;
     385           0 :             sText += ": ";
     386           0 :             sText += aExceptionInfo.sErrorCode;
     387           0 :             sText += "\n";
     388             :         }
     389             : 
     390           0 :         if ( !sText.isEmpty() )
     391           0 :             sText += "\n";
     392             : 
     393           0 :         sText += aExceptionInfo.sMessage;
     394             :     }
     395             : 
     396           0 :     m_pExceptionText->SetText(sText);
     397             : 
     398           0 :     return 0L;
     399             : }
     400             : 
     401             : // SQLMessageBox_Impl
     402           0 : struct SQLMessageBox_Impl
     403             : {
     404             :     ExceptionDisplayChain   aDisplayInfo;
     405             : 
     406           0 :     SQLMessageBox_Impl( const SQLExceptionInfo& _rExceptionInfo )
     407           0 :     {
     408             :         // transform the exception chain to a form more suitable for displaying it here
     409           0 :         ProviderFactory aProviderFactory;
     410           0 :         lcl_buildExceptionChain( _rExceptionInfo, aProviderFactory, aDisplayInfo );
     411           0 :     }
     412             : };
     413             : 
     414             : namespace
     415             : {
     416           0 :     void lcl_positionInAppFont( const vcl::Window& _rParent, vcl::Window& _rChild, long _nX, long _nY, long _Width, long _Height )
     417             :     {
     418           0 :         Point aPos = _rParent.LogicToPixel( Point( _nX, _nY ), MAP_APPFONT );
     419           0 :         Size aSize = _rParent.LogicToPixel( Size( _Width, _Height ), MAP_APPFONT );
     420           0 :         _rChild.SetPosSizePixel( aPos, aSize );
     421           0 :     }
     422             : 
     423           0 :     void lcl_addButton( ButtonDialog& _rDialog, StandardButtonType _eType, bool _bDefault )
     424             :     {
     425           0 :         sal_uInt16 nButtonID = 0;
     426           0 :         switch ( _eType )
     427             :         {
     428           0 :         case BUTTON_YES:    nButtonID = RET_YES; break;
     429           0 :         case BUTTON_NO:     nButtonID = RET_NO; break;
     430           0 :         case BUTTON_OK:     nButtonID = RET_OK; break;
     431           0 :         case BUTTON_CANCEL: nButtonID = RET_CANCEL; break;
     432           0 :         case BUTTON_RETRY:  nButtonID = RET_RETRY; break;
     433           0 :         case BUTTON_HELP:   nButtonID = RET_HELP; break;
     434             :         default:
     435             :             OSL_FAIL( "lcl_addButton: invalid button id!" );
     436           0 :             break;
     437             :         }
     438           0 :         _rDialog.AddButton( _eType, nButtonID, _bDefault ? BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON : 0 );
     439           0 :     }
     440             : }
     441             : 
     442           0 : void OSQLMessageBox::impl_positionControls()
     443             : {
     444             :     OSL_PRECOND( !m_pImpl->aDisplayInfo.empty(), "OSQLMessageBox::impl_positionControls: nothing to display at all?" );
     445             : 
     446           0 :     if ( m_pImpl->aDisplayInfo.empty() )
     447           0 :         return;
     448           0 :     const ExceptionDisplayInfo* pSecondInfo = NULL;
     449             : 
     450           0 :     const ExceptionDisplayInfo& rFirstInfo = *m_pImpl->aDisplayInfo.begin();
     451           0 :     if ( m_pImpl->aDisplayInfo.size() > 1 )
     452           0 :         pSecondInfo = &m_pImpl->aDisplayInfo[1];
     453           0 :     OUString sPrimary, sSecondary;
     454           0 :     sPrimary = rFirstInfo.sMessage;
     455             :     // one or two texts to display?
     456           0 :     if ( pSecondInfo )
     457             :     {
     458             :         // we show two elements in the main dialog if and only if one of
     459             :         // - the first element in the chain is an SQLContext, and the second
     460             :         //   element denotes its sub entry
     461             :         // - the first and the second element are both independent (i.e. the second
     462             :         //   is no sub entry), and none of them is a context.
     463           0 :         bool bFirstElementIsContext = ( rFirstInfo.eType == SQLExceptionInfo::SQL_CONTEXT );
     464           0 :         bool bSecondElementIsContext = ( pSecondInfo->eType == SQLExceptionInfo::SQL_CONTEXT );
     465             : 
     466           0 :         if ( bFirstElementIsContext && pSecondInfo->bSubEntry )
     467           0 :             sSecondary = pSecondInfo->sMessage;
     468           0 :         if ( !bFirstElementIsContext && !bSecondElementIsContext )
     469           0 :             sSecondary = pSecondInfo->sMessage;
     470             :     }
     471             : 
     472             :     // image
     473           0 :     lcl_positionInAppFont( *this, m_aInfoImage, OUTER_MARGIN, OUTER_MARGIN, IMAGE_SIZE, IMAGE_SIZE );
     474           0 :     m_aInfoImage.Show();
     475             : 
     476             :     // primary text
     477           0 :     lcl_positionInAppFont( *this, m_aTitle, TEXT_POS_X, OUTER_MARGIN, DIALOG_WIDTH - TEXT_POS_X - 2 * OUTER_MARGIN, 16 );
     478           0 :     sPrimary = lcl_stripOOoBaseVendor( sPrimary );
     479           0 :     m_aTitle.SetText( sPrimary );
     480           0 :     m_aTitle.Show();
     481             : 
     482           0 :     Rectangle aPrimaryRect( m_aTitle.GetPosPixel(), m_aTitle.GetSizePixel() );
     483             : 
     484             :     // secondary text (if applicable)
     485           0 :     m_aMessage.SetStyle( m_aMessage.GetStyle() | WB_NOLABEL );
     486           0 :     sSecondary = lcl_stripOOoBaseVendor( sSecondary );
     487           0 :     m_aMessage.SetText( sSecondary );
     488             : 
     489           0 :     lcl_positionInAppFont( *this, m_aMessage, TEXT_POS_X, OUTER_MARGIN + 16 + 3, DIALOG_WIDTH - TEXT_POS_X - 2 * OUTER_MARGIN, 8 );
     490           0 :     Rectangle aSecondaryRect( m_aMessage.GetPosPixel(), m_aMessage.GetSizePixel() );
     491             : 
     492           0 :     bool bHaveSecondaryText = !sSecondary.isEmpty();
     493             : 
     494             :     // determine which space the secondary text would occupy
     495           0 :     if ( bHaveSecondaryText )
     496           0 :         aSecondaryRect = GetTextRect( aSecondaryRect, sSecondary, TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE | TEXT_DRAW_LEFT );
     497             :     else
     498           0 :         aSecondaryRect.Bottom() = aSecondaryRect.Top() - 1;
     499             : 
     500             :     // adjust secondary control height accordingly
     501           0 :     m_aMessage.SetSizePixel( aSecondaryRect.GetSize() );
     502           0 :     m_aMessage.Show( aSecondaryRect.GetHeight() > 0 );
     503             : 
     504             :     // if there's no secondary text ...
     505           0 :     if ( !bHaveSecondaryText )
     506             :     {   // then give the primary text as much horizontal space as it needs
     507           0 :         Rectangle aSuggestedRect( GetTextRect( aPrimaryRect, sPrimary, TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE | TEXT_DRAW_CENTER ) );
     508           0 :         aPrimaryRect.Right() = aPrimaryRect.Left() + aSuggestedRect.GetWidth();
     509           0 :         aPrimaryRect.Bottom() = aPrimaryRect.Top() + aSuggestedRect.GetHeight();
     510             :         // and center it horizontally
     511           0 :         m_aTitle.SetStyle( ( m_aTitle.GetStyle() & ~WB_LEFT ) | WB_CENTER );
     512             : 
     513           0 :         Rectangle aInfoRect( m_aInfoImage.GetPosPixel(), m_aInfoImage.GetSizePixel() );
     514             :         // also, if it's not as high as the image ...
     515           0 :         if ( aPrimaryRect.GetHeight() < m_aInfoImage.GetSizePixel().Height() )
     516             :         {   // ... make it fit the image height
     517           0 :             aPrimaryRect.Bottom() += aInfoRect.GetHeight() - aPrimaryRect.GetHeight();
     518             :             // and center it vertically
     519           0 :             m_aTitle.SetStyle( m_aTitle.GetStyle() | WB_VCENTER );
     520             :         }
     521             :         else
     522             :         {   // ... otherwise, center the image vertically, relative to the primary text
     523           0 :             aInfoRect.Move( 0, ( aPrimaryRect.GetHeight() - aInfoRect.GetHeight() ) / 2 );
     524           0 :             m_aInfoImage.SetPosSizePixel( aInfoRect.TopLeft(), aInfoRect.GetSize() );
     525             :         }
     526             : 
     527           0 :         m_aTitle.SetPosSizePixel( aPrimaryRect.TopLeft(), aPrimaryRect.GetSize() );
     528             :     }
     529             : 
     530             :     // adjust dialog size accordingly
     531           0 :     const Rectangle& rBottomTextRect( bHaveSecondaryText ? aSecondaryRect : aPrimaryRect );
     532           0 :     Size aBorderSize = LogicToPixel( Size( OUTER_MARGIN, OUTER_MARGIN ), MAP_APPFONT );
     533           0 :     Size aDialogSize( LogicToPixel( Size( DIALOG_WIDTH, 30 ), MAP_APPFONT ) );
     534           0 :     aDialogSize.Height() = rBottomTextRect.Bottom() + aBorderSize.Height();
     535           0 :     aDialogSize.Width() = aPrimaryRect.Right() + aBorderSize.Width();
     536             : 
     537           0 :     SetSizePixel( aDialogSize );
     538           0 :     SetPageSizePixel( aDialogSize );
     539             : }
     540             : 
     541           0 : void OSQLMessageBox::impl_initImage( MessageType _eImage )
     542             : {
     543           0 :     switch (_eImage)
     544             :     {
     545             :         default:
     546             :             OSL_FAIL( "OSQLMessageBox::impl_initImage: unsupported image type!" );
     547             :             /* Fall through */
     548             :         case Info:
     549           0 :             m_aInfoImage.SetImage(InfoBox::GetStandardImage());
     550           0 :             break;
     551             :         case Warning:
     552           0 :             m_aInfoImage.SetImage(WarningBox::GetStandardImage());
     553           0 :             break;
     554             :         case Error:
     555           0 :             m_aInfoImage.SetImage(ErrorBox::GetStandardImage());
     556           0 :             break;
     557             :         case Query:
     558           0 :             m_aInfoImage.SetImage(QueryBox::GetStandardImage());
     559           0 :             break;
     560             :     }
     561           0 : }
     562             : 
     563           0 : void OSQLMessageBox::impl_createStandardButtons( WinBits _nStyle )
     564             : {
     565           0 :     if ( _nStyle & WB_YES_NO_CANCEL )
     566             :     {
     567           0 :         lcl_addButton( *this, BUTTON_YES,    ( _nStyle & WB_DEF_YES ) != 0 );
     568           0 :         lcl_addButton( *this, BUTTON_NO,     ( _nStyle & WB_DEF_NO ) != 0 );
     569           0 :         lcl_addButton( *this, BUTTON_CANCEL, ( _nStyle & WB_DEF_CANCEL ) != 0 );
     570             :     }
     571           0 :     else if ( _nStyle & WB_OK_CANCEL )
     572             :     {
     573           0 :         lcl_addButton( *this, BUTTON_OK,     ( _nStyle & WB_DEF_OK ) != 0 );
     574           0 :         lcl_addButton( *this, BUTTON_CANCEL, ( _nStyle & WB_DEF_CANCEL ) != 0 );
     575             :     }
     576           0 :     else if ( _nStyle & WB_YES_NO )
     577             :     {
     578           0 :         lcl_addButton( *this, BUTTON_YES,    ( _nStyle & WB_DEF_YES ) != 0 );
     579           0 :         lcl_addButton( *this, BUTTON_NO,     ( _nStyle & WB_DEF_NO ) != 0 );
     580             :     }
     581           0 :     else if ( _nStyle & WB_RETRY_CANCEL )
     582             :     {
     583           0 :         lcl_addButton( *this, BUTTON_RETRY,  ( _nStyle & WB_DEF_RETRY ) != 0 );
     584           0 :         lcl_addButton( *this, BUTTON_CANCEL, ( _nStyle & WB_DEF_CANCEL ) != 0 );
     585             :     }
     586             :     else
     587             :     {
     588             :         OSL_ENSURE( WB_OK & _nStyle, "OSQLMessageBox::impl_createStandardButtons: unsupported dialog style requested!" );
     589           0 :         AddButton( BUTTON_OK, RET_OK, BUTTONDIALOG_DEFBUTTON | BUTTONDIALOG_FOCUSBUTTON );
     590             :     }
     591             : 
     592           0 :     if ( !m_sHelpURL.isEmpty() )
     593             :     {
     594           0 :         lcl_addButton( *this, BUTTON_HELP, false );
     595             : 
     596           0 :         OUString aTmp;
     597           0 :         INetURLObject aHID( m_sHelpURL );
     598           0 :         if ( aHID.GetProtocol() == INET_PROT_HID )
     599           0 :               aTmp = aHID.GetURLPath();
     600             :         else
     601           0 :             aTmp = m_sHelpURL;
     602             : 
     603           0 :         SetHelpId( OUStringToOString( aTmp, RTL_TEXTENCODING_UTF8 ) );
     604             :     }
     605           0 : }
     606             : 
     607           0 : void OSQLMessageBox::impl_addDetailsButton()
     608             : {
     609           0 :     size_t nFirstPageVisible = m_aMessage.IsVisible() ? 2 : 1;
     610             : 
     611           0 :     bool bMoreDetailsAvailable = m_pImpl->aDisplayInfo.size() > nFirstPageVisible;
     612           0 :     if ( !bMoreDetailsAvailable )
     613             :     {
     614             :         // even if the text fits into what we can display, we might need to details button
     615             :         // if there is more non-trivial information in the errors than the mere messages
     616           0 :         for (   ExceptionDisplayChain::const_iterator error = m_pImpl->aDisplayInfo.begin();
     617           0 :                 error != m_pImpl->aDisplayInfo.end();
     618             :                 ++error
     619             :             )
     620             :         {
     621           0 :             if ( lcl_hasDetails( *error ) )
     622             :             {
     623           0 :                 bMoreDetailsAvailable = true;
     624           0 :                 break;
     625             :             }
     626             :         }
     627             :     }
     628             : 
     629           0 :     if ( bMoreDetailsAvailable )
     630             :     {
     631           0 :         AddButton( BUTTON_MORE, RET_MORE, 0 );
     632           0 :         PushButton* pButton = GetPushButton( RET_MORE );
     633             :         OSL_ENSURE( pButton, "OSQLMessageBox::impl_addDetailsButton: just added this button, why isn't it there?" );
     634           0 :         pButton->SetClickHdl( LINK( this, OSQLMessageBox, ButtonClickHdl ) );
     635           0 :         pButton->SetUniqueId( UID_SQLERROR_BUTTONMORE );
     636             :     }
     637           0 : }
     638             : 
     639           0 : void OSQLMessageBox::Construct( WinBits _nStyle, MessageType _eImage )
     640             : {
     641             :     SetText(
     642           0 :         utl::ConfigManager::getProductName() +
     643           0 :         OUString( " Base" ) );
     644             : 
     645             :     // position and size the controls and the dialog, depending on whether we have one or two texts to display
     646           0 :     impl_positionControls();
     647             : 
     648             :     // init the image
     649           0 :     MessageType eType( _eImage );
     650           0 :     if ( eType == AUTO )
     651             :     {
     652           0 :         switch ( m_pImpl->aDisplayInfo[0].eType )
     653             :         {
     654           0 :         case SQLExceptionInfo::SQL_EXCEPTION: eType = Error;    break;
     655           0 :         case SQLExceptionInfo::SQL_WARNING:   eType = Warning;  break;
     656           0 :         case SQLExceptionInfo::SQL_CONTEXT:   eType = Info;     break;
     657             :         default: OSL_FAIL( "OSQLMessageBox::Construct: invalid type!" );
     658             :         }
     659             :     }
     660           0 :     impl_initImage( eType );
     661             : 
     662             :     // create buttons
     663           0 :     impl_createStandardButtons( _nStyle );
     664           0 :     impl_addDetailsButton();
     665           0 : }
     666             : 
     667           0 : OSQLMessageBox::OSQLMessageBox(vcl::Window* _pParent, const SQLExceptionInfo& _rException, WinBits _nStyle, const OUString& _rHelpURL )
     668             :     :ButtonDialog( _pParent, WB_HORZ | WB_STDDIALOG )
     669             :     ,m_aInfoImage( this )
     670             :     ,m_aTitle( this, WB_WORDBREAK | WB_LEFT )
     671             :     ,m_aMessage( this, WB_WORDBREAK | WB_LEFT )
     672             :     ,m_sHelpURL( _rHelpURL )
     673           0 :     ,m_pImpl( new SQLMessageBox_Impl( _rException ) )
     674             : {
     675           0 :     Construct( _nStyle, AUTO );
     676           0 : }
     677             : 
     678           0 : OSQLMessageBox::OSQLMessageBox( vcl::Window* _pParent, const OUString& _rTitle, const OUString& _rMessage, WinBits _nStyle, MessageType _eType, const ::dbtools::SQLExceptionInfo* _pAdditionalErrorInfo )
     679             :     :ButtonDialog( _pParent, WB_HORZ | WB_STDDIALOG )
     680             :     ,m_aInfoImage( this )
     681             :     ,m_aTitle( this, WB_WORDBREAK | WB_LEFT )
     682           0 :     ,m_aMessage( this, WB_WORDBREAK | WB_LEFT )
     683             : {
     684           0 :     SQLContext aError;
     685           0 :     aError.Message = _rTitle;
     686           0 :     aError.Details = _rMessage;
     687           0 :     if ( _pAdditionalErrorInfo )
     688           0 :         aError.NextException = _pAdditionalErrorInfo->get();
     689             : 
     690           0 :     m_pImpl.reset( new SQLMessageBox_Impl( SQLExceptionInfo( aError ) ) );
     691             : 
     692           0 :     Construct( _nStyle, _eType );
     693           0 : }
     694             : 
     695           0 : OSQLMessageBox::~OSQLMessageBox()
     696             : {
     697           0 : }
     698             : 
     699           0 : IMPL_LINK( OSQLMessageBox, ButtonClickHdl, Button *, /*pButton*/ )
     700             : {
     701           0 :     OExceptionChainDialog aDlg( this, m_pImpl->aDisplayInfo );
     702           0 :     aDlg.Execute();
     703           0 :     return 0;
     704             : }
     705             : 
     706             : // OSQLWarningBox
     707           0 : OSQLWarningBox::OSQLWarningBox( vcl::Window* _pParent, const OUString& _rMessage, WinBits _nStyle,
     708             :     const ::dbtools::SQLExceptionInfo* _pAdditionalErrorInfo )
     709           0 :     :OSQLMessageBox( _pParent, ModuleRes( STR_EXCEPTION_WARNING ), _rMessage, _nStyle, OSQLMessageBox::Warning, _pAdditionalErrorInfo )
     710             : {
     711           0 : }
     712             : 
     713             : // OSQLErrorBox
     714           0 : OSQLErrorBox::OSQLErrorBox( vcl::Window* _pParent, const OUString& _rMessage, WinBits _nStyle,
     715             :     const ::dbtools::SQLExceptionInfo* _pAdditionalErrorInfo )
     716           0 :     :OSQLMessageBox( _pParent, ModuleRes( STR_EXCEPTION_ERROR ), _rMessage, _nStyle, OSQLMessageBox::Error, _pAdditionalErrorInfo )
     717             : {
     718           0 : }
     719             : 
     720          72 : }   // namespace dbaui
     721             : 
     722             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10