LCOV - code coverage report
Current view: top level - dbaccess/source/ui/dlg - sqlmessage.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1 336 0.3 %
Date: 2015-06-13 12:38:46 Functions: 2 52 3.8 %
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 != "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 = static_cast<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 = static_cast<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             : class OExceptionChainDialog : public ModalDialog
     294             : {
     295             :     VclPtr<SvTreeListBox>    m_pExceptionList;
     296             :     VclPtr<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           0 :     virtual ~OExceptionChainDialog() { disposeOnce(); }
     306           0 :     virtual void dispose() SAL_OVERRIDE
     307             :     {
     308           0 :         m_pExceptionList.clear();
     309           0 :         m_pExceptionText.clear();
     310           0 :         ModalDialog::dispose();
     311           0 :     }
     312             : 
     313             : protected:
     314             :     DECL_LINK(OnExceptionSelected, void*);
     315             : };
     316             : 
     317           0 : OExceptionChainDialog::OExceptionChainDialog(vcl::Window* pParent, const ExceptionDisplayChain& _rExceptions)
     318             :     : ModalDialog(pParent, "SQLExceptionDialog", "dbaccess/ui/sqlexception.ui")
     319           0 :     , m_aExceptions(_rExceptions)
     320             : {
     321           0 :     get(m_pExceptionList, "list");
     322           0 :     Size aListSize(LogicToPixel(Size(85, 93), MAP_APPFONT));
     323           0 :     m_pExceptionList->set_width_request(aListSize.Width());
     324           0 :     m_pExceptionList->set_height_request(aListSize.Height());
     325           0 :     get(m_pExceptionText, "description");
     326           0 :     Size aTextSize(LogicToPixel(Size(125 , 93), MAP_APPFONT));
     327           0 :     m_pExceptionText->set_width_request(aTextSize.Width());
     328           0 :     m_pExceptionText->set_height_request(aTextSize.Height());
     329             : 
     330           0 :     m_sStatusLabel = ModuleRes( STR_EXCEPTION_STATUS );
     331           0 :     m_sErrorCodeLabel = ModuleRes( STR_EXCEPTION_ERRORCODE );
     332             : 
     333           0 :     m_pExceptionList->SetSelectionMode(SINGLE_SELECTION);
     334           0 :     m_pExceptionList->SetDragDropMode(DragDropMode::NONE);
     335           0 :     m_pExceptionList->EnableInplaceEditing(false);
     336           0 :     m_pExceptionList->SetStyle(m_pExceptionList->GetStyle() | WB_HASLINES | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HSCROLL);
     337             : 
     338           0 :     m_pExceptionList->SetSelectHdl(LINK(this, OExceptionChainDialog, OnExceptionSelected));
     339           0 :     m_pExceptionList->SetNodeDefaultImages( );
     340             : 
     341           0 :     bool bHave22018 = false;
     342           0 :     size_t elementPos = 0;
     343             : 
     344           0 :     for (   ExceptionDisplayChain::const_iterator loop = m_aExceptions.begin();
     345           0 :             loop != m_aExceptions.end();
     346             :             ++loop, ++elementPos
     347             :         )
     348             :     {
     349           0 :         lcl_insertExceptionEntry( *m_pExceptionList, elementPos, *loop );
     350           0 :         bHave22018 = loop->sSQLState == "22018";
     351             :     }
     352             : 
     353             :     // if the error has the code 22018, then add an additional explanation
     354             :     // #i24021#
     355           0 :     if ( bHave22018 )
     356             :     {
     357           0 :         ProviderFactory aProviderFactory;
     358             : 
     359           0 :         ExceptionDisplayInfo aInfo22018;
     360           0 :         aInfo22018.sMessage = ModuleRes( STR_EXPLAN_STRINGCONVERSION_ERROR );
     361           0 :         aInfo22018.pLabelProvider = aProviderFactory.getLabelProvider( SQLExceptionInfo::SQL_CONTEXT, false );
     362           0 :         aInfo22018.pImageProvider = aProviderFactory.getImageProvider( SQLExceptionInfo::SQL_CONTEXT );
     363           0 :         m_aExceptions.push_back( aInfo22018 );
     364             : 
     365           0 :         lcl_insertExceptionEntry( *m_pExceptionList, m_aExceptions.size() - 1, aInfo22018 );
     366             :     }
     367           0 : }
     368             : 
     369           0 : IMPL_LINK_NOARG(OExceptionChainDialog, OnExceptionSelected)
     370             : {
     371           0 :     SvTreeListEntry* pSelected = m_pExceptionList->FirstSelected();
     372             :     OSL_ENSURE(!pSelected || !m_pExceptionList->NextSelected(pSelected), "OExceptionChainDialog::OnExceptionSelected : multi selection ?");
     373             : 
     374           0 :     OUString sText;
     375             : 
     376           0 :     if ( pSelected )
     377             :     {
     378           0 :         size_t pos = reinterpret_cast< size_t >( pSelected->GetUserData() );
     379           0 :         const ExceptionDisplayInfo& aExceptionInfo( m_aExceptions[ pos ] );
     380             : 
     381           0 :         if ( !aExceptionInfo.sSQLState.isEmpty() )
     382             :         {
     383           0 :             sText += m_sStatusLabel;
     384           0 :             sText += ": ";
     385           0 :             sText += aExceptionInfo.sSQLState;
     386           0 :             sText += "\n";
     387             :         }
     388             : 
     389           0 :         if ( !aExceptionInfo.sErrorCode.isEmpty() )
     390             :         {
     391           0 :             sText += m_sErrorCodeLabel;
     392           0 :             sText += ": ";
     393           0 :             sText += aExceptionInfo.sErrorCode;
     394           0 :             sText += "\n";
     395             :         }
     396             : 
     397           0 :         if ( !sText.isEmpty() )
     398           0 :             sText += "\n";
     399             : 
     400           0 :         sText += aExceptionInfo.sMessage;
     401             :     }
     402             : 
     403           0 :     m_pExceptionText->SetText(sText);
     404             : 
     405           0 :     return 0L;
     406             : }
     407             : 
     408             : // SQLMessageBox_Impl
     409           0 : struct SQLMessageBox_Impl
     410             : {
     411             :     ExceptionDisplayChain   aDisplayInfo;
     412             : 
     413           0 :     SQLMessageBox_Impl( const SQLExceptionInfo& _rExceptionInfo )
     414           0 :     {
     415             :         // transform the exception chain to a form more suitable for displaying it here
     416           0 :         ProviderFactory aProviderFactory;
     417           0 :         lcl_buildExceptionChain( _rExceptionInfo, aProviderFactory, aDisplayInfo );
     418           0 :     }
     419             : };
     420             : 
     421             : namespace
     422             : {
     423           0 :     void lcl_positionInAppFont( const vcl::Window& _rParent, vcl::Window& _rChild, long _nX, long _nY, long _Width, long _Height )
     424             :     {
     425           0 :         Point aPos = _rParent.LogicToPixel( Point( _nX, _nY ), MAP_APPFONT );
     426           0 :         Size aSize = _rParent.LogicToPixel( Size( _Width, _Height ), MAP_APPFONT );
     427           0 :         _rChild.SetPosSizePixel( aPos, aSize );
     428           0 :     }
     429             : 
     430           0 :     void lcl_addButton( ButtonDialog& _rDialog, StandardButtonType _eType, bool _bDefault )
     431             :     {
     432           0 :         sal_uInt16 nButtonID = 0;
     433           0 :         switch ( _eType )
     434             :         {
     435           0 :         case StandardButtonType::Yes:    nButtonID = RET_YES; break;
     436           0 :         case StandardButtonType::No:     nButtonID = RET_NO; break;
     437           0 :         case StandardButtonType::OK:     nButtonID = RET_OK; break;
     438           0 :         case StandardButtonType::Cancel: nButtonID = RET_CANCEL; break;
     439           0 :         case StandardButtonType::Retry:  nButtonID = RET_RETRY; break;
     440           0 :         case StandardButtonType::Help:   nButtonID = RET_HELP; break;
     441             :         default:
     442             :             OSL_FAIL( "lcl_addButton: invalid button id!" );
     443           0 :             break;
     444             :         }
     445           0 :         _rDialog.AddButton( _eType, nButtonID, _bDefault ? ButtonDialogFlags::Default | ButtonDialogFlags::Focus : ButtonDialogFlags::NONE );
     446           0 :     }
     447             : }
     448             : 
     449           0 : void OSQLMessageBox::impl_positionControls()
     450             : {
     451             :     OSL_PRECOND( !m_pImpl->aDisplayInfo.empty(), "OSQLMessageBox::impl_positionControls: nothing to display at all?" );
     452             : 
     453           0 :     if ( m_pImpl->aDisplayInfo.empty() )
     454           0 :         return;
     455           0 :     const ExceptionDisplayInfo* pSecondInfo = NULL;
     456             : 
     457           0 :     const ExceptionDisplayInfo& rFirstInfo = *m_pImpl->aDisplayInfo.begin();
     458           0 :     if ( m_pImpl->aDisplayInfo.size() > 1 )
     459           0 :         pSecondInfo = &m_pImpl->aDisplayInfo[1];
     460           0 :     OUString sPrimary, sSecondary;
     461           0 :     sPrimary = rFirstInfo.sMessage;
     462             :     // one or two texts to display?
     463           0 :     if ( pSecondInfo )
     464             :     {
     465             :         // we show two elements in the main dialog if and only if one of
     466             :         // - the first element in the chain is an SQLContext, and the second
     467             :         //   element denotes its sub entry
     468             :         // - the first and the second element are both independent (i.e. the second
     469             :         //   is no sub entry), and none of them is a context.
     470           0 :         bool bFirstElementIsContext = ( rFirstInfo.eType == SQLExceptionInfo::SQL_CONTEXT );
     471           0 :         bool bSecondElementIsContext = ( pSecondInfo->eType == SQLExceptionInfo::SQL_CONTEXT );
     472             : 
     473           0 :         if ( bFirstElementIsContext && pSecondInfo->bSubEntry )
     474           0 :             sSecondary = pSecondInfo->sMessage;
     475           0 :         if ( !bFirstElementIsContext && !bSecondElementIsContext )
     476           0 :             sSecondary = pSecondInfo->sMessage;
     477             :     }
     478             : 
     479             :     // image
     480           0 :     lcl_positionInAppFont( *this, *m_aInfoImage.get(), OUTER_MARGIN, OUTER_MARGIN, IMAGE_SIZE, IMAGE_SIZE );
     481           0 :     m_aInfoImage->Show();
     482             : 
     483             :     // primary text
     484           0 :     lcl_positionInAppFont( *this, *m_aTitle.get(), TEXT_POS_X, OUTER_MARGIN, DIALOG_WIDTH - TEXT_POS_X - 2 * OUTER_MARGIN, 16 );
     485           0 :     sPrimary = lcl_stripOOoBaseVendor( sPrimary );
     486           0 :     m_aTitle->SetText( sPrimary );
     487           0 :     m_aTitle->Show();
     488             : 
     489           0 :     Rectangle aPrimaryRect( m_aTitle->GetPosPixel(), m_aTitle->GetSizePixel() );
     490             : 
     491             :     // secondary text (if applicable)
     492           0 :     m_aMessage->SetStyle( m_aMessage->GetStyle() | WB_NOLABEL );
     493           0 :     sSecondary = lcl_stripOOoBaseVendor( sSecondary );
     494           0 :     m_aMessage->SetText( sSecondary );
     495             : 
     496           0 :     lcl_positionInAppFont( *this, *m_aMessage.get(), TEXT_POS_X, OUTER_MARGIN + 16 + 3, DIALOG_WIDTH - TEXT_POS_X - 2 * OUTER_MARGIN, 8 );
     497           0 :     Rectangle aSecondaryRect( m_aMessage->GetPosPixel(), m_aMessage->GetSizePixel() );
     498             : 
     499           0 :     bool bHaveSecondaryText = !sSecondary.isEmpty();
     500             : 
     501             :     // determine which space the secondary text would occupy
     502           0 :     if ( bHaveSecondaryText )
     503           0 :         aSecondaryRect = GetTextRect( aSecondaryRect, sSecondary, DrawTextFlags::WordBreak | DrawTextFlags::MultiLine | DrawTextFlags::Left );
     504             :     else
     505           0 :         aSecondaryRect.Bottom() = aSecondaryRect.Top() - 1;
     506             : 
     507             :     // adjust secondary control height accordingly
     508           0 :     m_aMessage->SetSizePixel( aSecondaryRect.GetSize() );
     509           0 :     m_aMessage->Show( aSecondaryRect.GetHeight() > 0 );
     510             : 
     511             :     // if there's no secondary text ...
     512           0 :     if ( !bHaveSecondaryText )
     513             :     {   // then give the primary text as much horizontal space as it needs
     514           0 :         Rectangle aSuggestedRect( GetTextRect( aPrimaryRect, sPrimary, DrawTextFlags::WordBreak | DrawTextFlags::MultiLine | DrawTextFlags::Center ) );
     515           0 :         aPrimaryRect.Right() = aPrimaryRect.Left() + aSuggestedRect.GetWidth();
     516           0 :         aPrimaryRect.Bottom() = aPrimaryRect.Top() + aSuggestedRect.GetHeight();
     517             :         // and center it horizontally
     518           0 :         m_aTitle->SetStyle( ( m_aTitle->GetStyle() & ~WB_LEFT ) | WB_CENTER );
     519             : 
     520           0 :         Rectangle aInfoRect( m_aInfoImage->GetPosPixel(), m_aInfoImage->GetSizePixel() );
     521             :         // also, if it's not as high as the image ...
     522           0 :         if ( aPrimaryRect.GetHeight() < m_aInfoImage->GetSizePixel().Height() )
     523             :         {   // ... make it fit the image height
     524           0 :             aPrimaryRect.Bottom() += aInfoRect.GetHeight() - aPrimaryRect.GetHeight();
     525             :             // and center it vertically
     526           0 :             m_aTitle->SetStyle( m_aTitle->GetStyle() | WB_VCENTER );
     527             :         }
     528             :         else
     529             :         {   // ... otherwise, center the image vertically, relative to the primary text
     530           0 :             aInfoRect.Move( 0, ( aPrimaryRect.GetHeight() - aInfoRect.GetHeight() ) / 2 );
     531           0 :             m_aInfoImage->SetPosSizePixel( aInfoRect.TopLeft(), aInfoRect.GetSize() );
     532             :         }
     533             : 
     534           0 :         m_aTitle->SetPosSizePixel( aPrimaryRect.TopLeft(), aPrimaryRect.GetSize() );
     535             :     }
     536             : 
     537             :     // adjust dialog size accordingly
     538           0 :     const Rectangle& rBottomTextRect( bHaveSecondaryText ? aSecondaryRect : aPrimaryRect );
     539           0 :     Size aBorderSize = LogicToPixel( Size( OUTER_MARGIN, OUTER_MARGIN ), MAP_APPFONT );
     540           0 :     Size aDialogSize( LogicToPixel( Size( DIALOG_WIDTH, 30 ), MAP_APPFONT ) );
     541           0 :     aDialogSize.Height() = rBottomTextRect.Bottom() + aBorderSize.Height();
     542           0 :     aDialogSize.Width() = aPrimaryRect.Right() + aBorderSize.Width();
     543             : 
     544           0 :     SetSizePixel( aDialogSize );
     545           0 :     SetPageSizePixel( aDialogSize );
     546             : }
     547             : 
     548           0 : void OSQLMessageBox::impl_initImage( MessageType _eImage )
     549             : {
     550           0 :     switch (_eImage)
     551             :     {
     552             :         default:
     553             :             OSL_FAIL( "OSQLMessageBox::impl_initImage: unsupported image type!" );
     554             :             /* Fall through */
     555             :         case Info:
     556           0 :             m_aInfoImage->SetImage(InfoBox::GetStandardImage());
     557           0 :             break;
     558             :         case Warning:
     559           0 :             m_aInfoImage->SetImage(WarningBox::GetStandardImage());
     560           0 :             break;
     561             :         case Error:
     562           0 :             m_aInfoImage->SetImage(ErrorBox::GetStandardImage());
     563           0 :             break;
     564             :         case Query:
     565           0 :             m_aInfoImage->SetImage(QueryBox::GetStandardImage());
     566           0 :             break;
     567             :     }
     568           0 : }
     569             : 
     570           0 : void OSQLMessageBox::impl_createStandardButtons( WinBits _nStyle )
     571             : {
     572           0 :     if ( _nStyle & WB_YES_NO_CANCEL )
     573             :     {
     574           0 :         lcl_addButton( *this, StandardButtonType::Yes,    ( _nStyle & WB_DEF_YES ) != 0 );
     575           0 :         lcl_addButton( *this, StandardButtonType::No,     ( _nStyle & WB_DEF_NO ) != 0 );
     576           0 :         lcl_addButton( *this, StandardButtonType::Cancel, ( _nStyle & WB_DEF_CANCEL ) != 0 );
     577             :     }
     578           0 :     else if ( _nStyle & WB_OK_CANCEL )
     579             :     {
     580           0 :         lcl_addButton( *this, StandardButtonType::OK,     ( _nStyle & WB_DEF_OK ) != 0 );
     581           0 :         lcl_addButton( *this, StandardButtonType::Cancel, ( _nStyle & WB_DEF_CANCEL ) != 0 );
     582             :     }
     583           0 :     else if ( _nStyle & WB_YES_NO )
     584             :     {
     585           0 :         lcl_addButton( *this, StandardButtonType::Yes,    ( _nStyle & WB_DEF_YES ) != 0 );
     586           0 :         lcl_addButton( *this, StandardButtonType::No,     ( _nStyle & WB_DEF_NO ) != 0 );
     587             :     }
     588           0 :     else if ( _nStyle & WB_RETRY_CANCEL )
     589             :     {
     590           0 :         lcl_addButton( *this, StandardButtonType::Retry,  ( _nStyle & WB_DEF_RETRY ) != 0 );
     591           0 :         lcl_addButton( *this, StandardButtonType::Cancel, ( _nStyle & WB_DEF_CANCEL ) != 0 );
     592             :     }
     593             :     else
     594             :     {
     595             :         OSL_ENSURE( WB_OK & _nStyle, "OSQLMessageBox::impl_createStandardButtons: unsupported dialog style requested!" );
     596           0 :         AddButton( StandardButtonType::OK, RET_OK, ButtonDialogFlags::Default | ButtonDialogFlags::Focus );
     597             :     }
     598             : 
     599           0 :     if ( !m_sHelpURL.isEmpty() )
     600             :     {
     601           0 :         lcl_addButton( *this, StandardButtonType::Help, false );
     602             : 
     603           0 :         OUString aTmp;
     604           0 :         INetURLObject aHID( m_sHelpURL );
     605           0 :         if ( aHID.GetProtocol() == INetProtocol::Hid )
     606           0 :               aTmp = aHID.GetURLPath();
     607             :         else
     608           0 :             aTmp = m_sHelpURL;
     609             : 
     610           0 :         SetHelpId( OUStringToOString( aTmp, RTL_TEXTENCODING_UTF8 ) );
     611             :     }
     612           0 : }
     613             : 
     614           0 : void OSQLMessageBox::impl_addDetailsButton()
     615             : {
     616           0 :     size_t nFirstPageVisible = m_aMessage->IsVisible() ? 2 : 1;
     617             : 
     618           0 :     bool bMoreDetailsAvailable = m_pImpl->aDisplayInfo.size() > nFirstPageVisible;
     619           0 :     if ( !bMoreDetailsAvailable )
     620             :     {
     621             :         // even if the text fits into what we can display, we might need to details button
     622             :         // if there is more non-trivial information in the errors than the mere messages
     623           0 :         for (   ExceptionDisplayChain::const_iterator error = m_pImpl->aDisplayInfo.begin();
     624           0 :                 error != m_pImpl->aDisplayInfo.end();
     625             :                 ++error
     626             :             )
     627             :         {
     628           0 :             if ( lcl_hasDetails( *error ) )
     629             :             {
     630           0 :                 bMoreDetailsAvailable = true;
     631           0 :                 break;
     632             :             }
     633             :         }
     634             :     }
     635             : 
     636           0 :     if ( bMoreDetailsAvailable )
     637             :     {
     638           0 :         AddButton( StandardButtonType::More, RET_MORE);
     639           0 :         PushButton* pButton = GetPushButton( RET_MORE );
     640             :         OSL_ENSURE( pButton, "OSQLMessageBox::impl_addDetailsButton: just added this button, why isn't it there?" );
     641           0 :         pButton->SetClickHdl( LINK( this, OSQLMessageBox, ButtonClickHdl ) );
     642           0 :         pButton->SetUniqueId( UID_SQLERROR_BUTTONMORE );
     643             :     }
     644           0 : }
     645             : 
     646           0 : void OSQLMessageBox::Construct( WinBits _nStyle, MessageType _eImage )
     647             : {
     648           0 :     SetText( utl::ConfigManager::getProductName() + " Base" );
     649             : 
     650             :     // position and size the controls and the dialog, depending on whether we have one or two texts to display
     651           0 :     impl_positionControls();
     652             : 
     653             :     // init the image
     654           0 :     MessageType eType( _eImage );
     655           0 :     if ( eType == AUTO )
     656             :     {
     657           0 :         switch ( m_pImpl->aDisplayInfo[0].eType )
     658             :         {
     659           0 :         case SQLExceptionInfo::SQL_EXCEPTION: eType = Error;    break;
     660           0 :         case SQLExceptionInfo::SQL_WARNING:   eType = Warning;  break;
     661           0 :         case SQLExceptionInfo::SQL_CONTEXT:   eType = Info;     break;
     662             :         default: OSL_FAIL( "OSQLMessageBox::Construct: invalid type!" );
     663             :         }
     664             :     }
     665           0 :     impl_initImage( eType );
     666             : 
     667             :     // create buttons
     668           0 :     impl_createStandardButtons( _nStyle );
     669           0 :     impl_addDetailsButton();
     670           0 : }
     671             : 
     672           0 : OSQLMessageBox::OSQLMessageBox(vcl::Window* _pParent, const SQLExceptionInfo& _rException, WinBits _nStyle, const OUString& _rHelpURL )
     673             :     :ButtonDialog( _pParent, WB_HORZ | WB_STDDIALOG )
     674             :     ,m_aInfoImage( VclPtr<FixedImage>::Create(this) )
     675             :     ,m_aTitle( VclPtr<FixedText>::Create(this, WB_WORDBREAK | WB_LEFT) )
     676             :     ,m_aMessage( VclPtr<FixedText>::Create(this, WB_WORDBREAK | WB_LEFT) )
     677             :     ,m_sHelpURL( _rHelpURL )
     678           0 :     ,m_pImpl( new SQLMessageBox_Impl( _rException ) )
     679             : {
     680           0 :     Construct( _nStyle, AUTO );
     681           0 : }
     682             : 
     683           0 : OSQLMessageBox::OSQLMessageBox( vcl::Window* _pParent, const OUString& _rTitle, const OUString& _rMessage, WinBits _nStyle, MessageType _eType, const ::dbtools::SQLExceptionInfo* _pAdditionalErrorInfo )
     684             :     :ButtonDialog( _pParent, WB_HORZ | WB_STDDIALOG )
     685             :     ,m_aInfoImage( VclPtr<FixedImage>::Create(this) )
     686             :     ,m_aTitle( VclPtr<FixedText>::Create(this, WB_WORDBREAK | WB_LEFT) )
     687           0 :     ,m_aMessage( VclPtr<FixedText>::Create(this, WB_WORDBREAK | WB_LEFT) )
     688             : {
     689           0 :     SQLContext aError;
     690           0 :     aError.Message = _rTitle;
     691           0 :     aError.Details = _rMessage;
     692           0 :     if ( _pAdditionalErrorInfo )
     693           0 :         aError.NextException = _pAdditionalErrorInfo->get();
     694             : 
     695           0 :     m_pImpl.reset( new SQLMessageBox_Impl( SQLExceptionInfo( aError ) ) );
     696             : 
     697           0 :     Construct( _nStyle, _eType );
     698           0 : }
     699             : 
     700           0 : OSQLMessageBox::~OSQLMessageBox()
     701             : {
     702           0 :     disposeOnce();
     703           0 : }
     704             : 
     705           0 : void OSQLMessageBox::dispose()
     706             : {
     707           0 :     m_aInfoImage.disposeAndClear();
     708           0 :     m_aTitle.disposeAndClear();
     709           0 :     m_aMessage.disposeAndClear();
     710           0 :     ButtonDialog::dispose();
     711           0 : }
     712             : 
     713           0 : IMPL_LINK( OSQLMessageBox, ButtonClickHdl, Button *, /*pButton*/ )
     714             : {
     715           0 :     ScopedVclPtrInstance< OExceptionChainDialog > aDlg( this, m_pImpl->aDisplayInfo );
     716           0 :     aDlg->Execute();
     717           0 :     return 0;
     718             : }
     719             : 
     720             : // OSQLWarningBox
     721           0 : OSQLWarningBox::OSQLWarningBox( vcl::Window* _pParent, const OUString& _rMessage, WinBits _nStyle,
     722             :     const ::dbtools::SQLExceptionInfo* _pAdditionalErrorInfo )
     723           0 :     :OSQLMessageBox( _pParent, ModuleRes( STR_EXCEPTION_WARNING ), _rMessage, _nStyle, OSQLMessageBox::Warning, _pAdditionalErrorInfo )
     724             : {
     725           0 : }
     726             : 
     727             : // OSQLErrorBox
     728           0 : OSQLErrorBox::OSQLErrorBox( vcl::Window* _pParent, const OUString& _rMessage, WinBits _nStyle,
     729             :     const ::dbtools::SQLExceptionInfo* _pAdditionalErrorInfo )
     730           0 :     :OSQLMessageBox( _pParent, ModuleRes( STR_EXCEPTION_ERROR ), _rMessage, _nStyle, OSQLMessageBox::Error, _pAdditionalErrorInfo )
     731             : {
     732           0 : }
     733             : 
     734          36 : }   // namespace dbaui
     735             : 
     736             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11