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

Generated by: LCOV version 1.10