summaryrefslogtreecommitdiffstats
path: root/dbaccess/source/ui/dlg/sqlmessage.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dbaccess/source/ui/dlg/sqlmessage.cxx607
1 files changed, 607 insertions, 0 deletions
diff --git a/dbaccess/source/ui/dlg/sqlmessage.cxx b/dbaccess/source/ui/dlg/sqlmessage.cxx
new file mode 100644
index 000000000..39ba6dc8e
--- /dev/null
+++ b/dbaccess/source/ui/dlg/sqlmessage.cxx
@@ -0,0 +1,607 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <core_resource.hxx>
+#include <sqlmessage.hxx>
+#include <strings.hrc>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdb/SQLContext.hpp>
+#include <vcl/stdtext.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <osl/diagnose.h>
+#include <connectivity/dbexception.hxx>
+#include <connectivity/sqlerror.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <tools/urlobj.hxx>
+
+#define RET_MORE RET_RETRY + 1
+
+using namespace dbtools;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::sdb;
+using namespace com::sun::star::sdbc;
+
+namespace dbaui
+{
+
+namespace
+{
+ class ImageProvider
+ {
+ private:
+ OUString m_defaultImageID;
+
+ public:
+ explicit ImageProvider(const OUString& defaultImageID)
+ : m_defaultImageID(defaultImageID)
+ {
+ }
+
+ const OUString& getImage() const
+ {
+ return m_defaultImageID;
+ }
+ };
+
+ class LabelProvider
+ {
+ private:
+ OUString m_label;
+ public:
+ explicit LabelProvider(const char* labelResourceID)
+ : m_label(DBA_RES(labelResourceID))
+ {
+ }
+
+ const OUString& getLabel() const
+ {
+ return m_label;
+ }
+ };
+
+ class ProviderFactory
+ {
+ private:
+ mutable std::shared_ptr< ImageProvider > m_pErrorImage;
+ mutable std::shared_ptr< ImageProvider > m_pWarningsImage;
+ mutable std::shared_ptr< ImageProvider > m_pInfoImage;
+ mutable std::shared_ptr< LabelProvider > m_pErrorLabel;
+ mutable std::shared_ptr< LabelProvider > m_pWarningsLabel;
+ mutable std::shared_ptr< LabelProvider > m_pInfoLabel;
+
+ public:
+ ProviderFactory()
+ {
+ }
+
+ std::shared_ptr< ImageProvider > const & getImageProvider( SQLExceptionInfo::TYPE _eType ) const
+ {
+ std::shared_ptr< ImageProvider >* ppProvider( &m_pErrorImage );
+ OUString sNormalImageID("dialog-error");
+
+ switch ( _eType )
+ {
+ case SQLExceptionInfo::TYPE::SQLWarning:
+ ppProvider = &m_pWarningsImage;
+ sNormalImageID = "dialog-warning";
+ break;
+
+ case SQLExceptionInfo::TYPE::SQLContext:
+ ppProvider = &m_pInfoImage;
+ sNormalImageID = "dialog-information";
+ break;
+
+ default:
+ break;
+ }
+
+ if ( !ppProvider->get() )
+ (*ppProvider) = std::make_shared<ImageProvider>(sNormalImageID);
+ return *ppProvider;
+ }
+
+ std::shared_ptr< LabelProvider > const & getLabelProvider( SQLExceptionInfo::TYPE _eType, bool _bSubLabel ) const
+ {
+ std::shared_ptr< LabelProvider >* ppProvider( &m_pErrorLabel );
+ const char* pLabelID( STR_EXCEPTION_ERROR );
+
+ switch ( _eType )
+ {
+ case SQLExceptionInfo::TYPE::SQLWarning:
+ ppProvider = &m_pWarningsLabel;
+ pLabelID = STR_EXCEPTION_WARNING;
+ break;
+
+ case SQLExceptionInfo::TYPE::SQLContext:
+ ppProvider = &m_pInfoLabel;
+ pLabelID = _bSubLabel ? STR_EXCEPTION_DETAILS : STR_EXCEPTION_INFO;
+ break;
+ default:
+ break;
+ }
+
+ if ( !ppProvider->get() )
+ (*ppProvider) = std::make_shared<LabelProvider>( pLabelID );
+ return *ppProvider;
+ }
+
+ };
+
+ /// a stripped version of the SQLException, packed for displaying
+ struct ExceptionDisplayInfo
+ {
+ SQLExceptionInfo::TYPE eType;
+
+ std::shared_ptr< ImageProvider > pImageProvider;
+ std::shared_ptr< LabelProvider > pLabelProvider;
+
+ bool bSubEntry;
+
+ OUString sMessage;
+ OUString sSQLState;
+ OUString sErrorCode;
+
+ ExceptionDisplayInfo() : eType( SQLExceptionInfo::TYPE::Undefined ), bSubEntry( false ) { }
+ explicit ExceptionDisplayInfo( SQLExceptionInfo::TYPE _eType ) : eType( _eType ), bSubEntry( false ) { }
+ };
+
+ bool lcl_hasDetails( const ExceptionDisplayInfo& _displayInfo )
+ {
+ return ( !_displayInfo.sErrorCode.isEmpty() )
+ || ( !_displayInfo.sSQLState.isEmpty()
+ && _displayInfo.sSQLState != "S1000"
+ );
+ }
+
+ typedef std::vector< ExceptionDisplayInfo > ExceptionDisplayChain;
+
+ /// strips the [OOoBase] vendor identifier from the given error message, if applicable
+ OUString lcl_stripOOoBaseVendor( const OUString& _rErrorMessage )
+ {
+ OUString sErrorMessage( _rErrorMessage );
+
+ const OUString sVendorIdentifier( ::connectivity::SQLError::getMessagePrefix() );
+ if ( sErrorMessage.startsWith( sVendorIdentifier ) )
+ {
+ // characters to strip
+ sal_Int32 nStripLen( sVendorIdentifier.getLength() );
+ // usually, there should be a whitespace between the vendor and the real message
+ while ( ( sErrorMessage.getLength() > nStripLen )
+ && ( sErrorMessage[nStripLen] == ' ' )
+ )
+ ++nStripLen;
+ sErrorMessage = sErrorMessage.copy( nStripLen );
+ }
+
+ return sErrorMessage;
+ }
+
+ void lcl_buildExceptionChain( const SQLExceptionInfo& _rErrorInfo, const ProviderFactory& _rFactory, ExceptionDisplayChain& _out_rChain )
+ {
+ {
+ ExceptionDisplayChain empty;
+ _out_rChain.swap( empty );
+ }
+
+ SQLExceptionIteratorHelper iter( _rErrorInfo );
+ while ( iter.hasMoreElements() )
+ {
+ // current chain element
+ SQLExceptionInfo aCurrentElement;
+ iter.next( aCurrentElement );
+
+ const SQLException* pCurrentError = aCurrentElement;
+ OSL_ENSURE( pCurrentError, "lcl_buildExceptionChain: iterator failure!" );
+ // hasMoreElements should not have returned <TRUE/> in this case
+
+ ExceptionDisplayInfo aDisplayInfo( aCurrentElement.getType() );
+
+ aDisplayInfo.sMessage = pCurrentError->Message.trim();
+ aDisplayInfo.sSQLState = pCurrentError->SQLState;
+ if ( pCurrentError->ErrorCode )
+ aDisplayInfo.sErrorCode = OUString::number( pCurrentError->ErrorCode );
+
+ if ( aDisplayInfo.sMessage.isEmpty()
+ && !lcl_hasDetails( aDisplayInfo )
+ )
+ {
+ OSL_FAIL( "lcl_buildExceptionChain: useless exception: no state, no error code, no message!" );
+ continue;
+ }
+
+ aDisplayInfo.pImageProvider = _rFactory.getImageProvider( aCurrentElement.getType() );
+ aDisplayInfo.pLabelProvider = _rFactory.getLabelProvider( aCurrentElement.getType(), false );
+
+ _out_rChain.push_back( aDisplayInfo );
+
+ if ( aCurrentElement.getType() == SQLExceptionInfo::TYPE::SQLContext )
+ {
+ const SQLContext* pContext = aCurrentElement;
+ if ( !pContext->Details.isEmpty() )
+ {
+ ExceptionDisplayInfo aSubInfo( aCurrentElement.getType() );
+
+ aSubInfo.sMessage = pContext->Details;
+ aSubInfo.pImageProvider = _rFactory.getImageProvider( aCurrentElement.getType() );
+ aSubInfo.pLabelProvider = _rFactory.getLabelProvider( aCurrentElement.getType(), true );
+ aSubInfo.bSubEntry = true;
+
+ _out_rChain.push_back( aSubInfo );
+ }
+ }
+ }
+ }
+
+ void lcl_insertExceptionEntry(weld::TreeView& rList, size_t nElementPos, const ExceptionDisplayInfo& rEntry)
+ {
+ rList.append(OUString::number(nElementPos), rEntry.pLabelProvider->getLabel(), rEntry.pImageProvider->getImage());
+ }
+}
+
+namespace {
+
+class OExceptionChainDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::TreeView> m_xExceptionList;
+ std::unique_ptr<weld::TextView> m_xExceptionText;
+
+ OUString m_sStatusLabel;
+ OUString m_sErrorCodeLabel;
+
+ ExceptionDisplayChain m_aExceptions;
+
+public:
+ OExceptionChainDialog(weld::Window* pParent, const ExceptionDisplayChain& rExceptions);
+
+protected:
+ DECL_LINK(OnExceptionSelected, weld::TreeView&, void);
+};
+
+}
+
+OExceptionChainDialog::OExceptionChainDialog(weld::Window* pParent, const ExceptionDisplayChain& rExceptions)
+ : GenericDialogController(pParent, "dbaccess/ui/sqlexception.ui", "SQLExceptionDialog")
+ , m_xExceptionList(m_xBuilder->weld_tree_view("list"))
+ , m_xExceptionText(m_xBuilder->weld_text_view("description"))
+ , m_aExceptions(rExceptions)
+{
+ int nListWidth = m_xExceptionText->get_approximate_digit_width() * 28;
+ int nTextWidth = m_xExceptionText->get_approximate_digit_width() * 42;
+ int nHeight = m_xExceptionList->get_height_rows(6);
+ m_xExceptionList->set_size_request(nListWidth, nHeight);
+ m_xExceptionText->set_size_request(nTextWidth, nHeight);
+
+ m_sStatusLabel = DBA_RES( STR_EXCEPTION_STATUS );
+ m_sErrorCodeLabel = DBA_RES( STR_EXCEPTION_ERRORCODE );
+
+ m_xExceptionList->connect_changed(LINK(this, OExceptionChainDialog, OnExceptionSelected));
+
+ bool bHave22018 = false;
+ size_t elementPos = 0;
+
+ for (auto const& elem : m_aExceptions)
+ {
+ lcl_insertExceptionEntry(*m_xExceptionList, elementPos, elem);
+ bHave22018 = elem.sSQLState == "22018";
+ ++elementPos;
+ }
+
+ // if the error has the code 22018, then add an additional explanation
+ // #i24021#
+ if ( bHave22018 )
+ {
+ ProviderFactory aProviderFactory;
+
+ ExceptionDisplayInfo aInfo22018;
+ aInfo22018.sMessage = DBA_RES( STR_EXPLAN_STRINGCONVERSION_ERROR );
+ aInfo22018.pLabelProvider = aProviderFactory.getLabelProvider( SQLExceptionInfo::TYPE::SQLContext, false );
+ aInfo22018.pImageProvider = aProviderFactory.getImageProvider( SQLExceptionInfo::TYPE::SQLContext );
+ m_aExceptions.push_back( aInfo22018 );
+
+ lcl_insertExceptionEntry(*m_xExceptionList, m_aExceptions.size() - 1, aInfo22018);
+ }
+
+ if (m_xExceptionList->n_children())
+ {
+ m_xExceptionList->select(0);
+ OnExceptionSelected(*m_xExceptionList);
+ }
+}
+
+IMPL_LINK_NOARG(OExceptionChainDialog, OnExceptionSelected, weld::TreeView&, void)
+{
+ OUString sText;
+
+ OUString sId(m_xExceptionList->get_selected_id());
+ if (!sId.isEmpty())
+ {
+ const ExceptionDisplayInfo& aExceptionInfo(m_aExceptions[sId.toUInt32()]);
+
+ if ( !aExceptionInfo.sSQLState.isEmpty() )
+ {
+ sText += m_sStatusLabel + ": " + aExceptionInfo.sSQLState + "\n";
+ }
+
+ if ( !aExceptionInfo.sErrorCode.isEmpty() )
+ {
+ sText += m_sErrorCodeLabel + ": " + aExceptionInfo.sErrorCode + "\n";
+ }
+
+ if ( !sText.isEmpty() )
+ sText += "\n";
+
+ sText += aExceptionInfo.sMessage;
+ }
+
+ m_xExceptionText->set_text(sText);
+}
+
+// SQLMessageBox_Impl
+struct SQLMessageBox_Impl
+{
+ ExceptionDisplayChain aDisplayInfo;
+
+ explicit SQLMessageBox_Impl( const SQLExceptionInfo& _rExceptionInfo )
+ {
+ // transform the exception chain to a form more suitable for displaying it here
+ ProviderFactory aProviderFactory;
+ lcl_buildExceptionChain( _rExceptionInfo, aProviderFactory, aDisplayInfo );
+ }
+};
+
+namespace
+{
+ void lcl_addButton(weld::MessageDialog* pDialog, StandardButtonType eType, bool bDefault)
+ {
+ sal_uInt16 nButtonID = 0;
+ switch (eType)
+ {
+ case StandardButtonType::Yes:
+ nButtonID = RET_YES;
+ pDialog->add_button(GetStandardText(StandardButtonType::Yes), nButtonID);
+ break;
+ case StandardButtonType::No:
+ nButtonID = RET_NO;
+ pDialog->add_button(GetStandardText(StandardButtonType::No), nButtonID);
+ break;
+ case StandardButtonType::OK:
+ nButtonID = RET_OK;
+ pDialog->add_button(GetStandardText(StandardButtonType::OK), nButtonID);
+ break;
+ case StandardButtonType::Cancel:
+ nButtonID = RET_CANCEL;
+ pDialog->add_button(GetStandardText(StandardButtonType::Cancel), nButtonID);
+ break;
+ case StandardButtonType::Retry:
+ nButtonID = RET_RETRY;
+ pDialog->add_button(GetStandardText(StandardButtonType::Retry), nButtonID);
+ break;
+ case StandardButtonType::Help:
+ nButtonID = RET_HELP;
+ pDialog->add_button(GetStandardText(StandardButtonType::Help), nButtonID);
+ break;
+ default:
+ OSL_FAIL( "lcl_addButton: invalid button id!" );
+ break;
+ }
+ if (bDefault)
+ pDialog->set_default_response(nButtonID);
+ }
+}
+
+void OSQLMessageBox::impl_fillMessages()
+{
+ OSL_PRECOND( !m_pImpl->aDisplayInfo.empty(), "OSQLMessageBox::impl_fillMessages: nothing to display at all?" );
+
+ if ( m_pImpl->aDisplayInfo.empty() )
+ return;
+ const ExceptionDisplayInfo* pSecondInfo = nullptr;
+
+ const ExceptionDisplayInfo& rFirstInfo = *m_pImpl->aDisplayInfo.begin();
+ if ( m_pImpl->aDisplayInfo.size() > 1 )
+ pSecondInfo = &m_pImpl->aDisplayInfo[1];
+ OUString sPrimary, sSecondary;
+ sPrimary = rFirstInfo.sMessage;
+ // one or two texts to display?
+ if ( pSecondInfo )
+ {
+ // we show two elements in the main dialog if and only if one of
+ // - the first element in the chain is an SQLContext, and the second
+ // element denotes its sub entry
+ // - the first and the second element are both independent (i.e. the second
+ // is no sub entry), and none of them is a context.
+ bool bFirstElementIsContext = ( rFirstInfo.eType == SQLExceptionInfo::TYPE::SQLContext );
+ bool bSecondElementIsContext = ( pSecondInfo->eType == SQLExceptionInfo::TYPE::SQLContext );
+
+ if ( bFirstElementIsContext && pSecondInfo->bSubEntry )
+ sSecondary = pSecondInfo->sMessage;
+ if ( !bFirstElementIsContext && !bSecondElementIsContext )
+ sSecondary = pSecondInfo->sMessage;
+ }
+
+ // primary text
+ m_xDialog->set_primary_text(lcl_stripOOoBaseVendor(sPrimary));
+
+ // secondary text (if applicable)
+ m_xDialog->set_secondary_text(lcl_stripOOoBaseVendor(sSecondary));
+}
+
+void OSQLMessageBox::impl_createStandardButtons( MessBoxStyle _nStyle )
+{
+ if ( _nStyle & MessBoxStyle::YesNoCancel )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Yes, bool(_nStyle & MessBoxStyle::DefaultYes));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::No, bool(_nStyle & MessBoxStyle::DefaultNo));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Cancel, bool(_nStyle & MessBoxStyle::DefaultCancel));
+ }
+ else if ( _nStyle & MessBoxStyle::OkCancel )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::OK, bool(_nStyle & MessBoxStyle::DefaultOk));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Cancel, bool(_nStyle & MessBoxStyle::DefaultCancel));
+ }
+ else if ( _nStyle & MessBoxStyle::YesNo )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Yes, bool(_nStyle & MessBoxStyle::DefaultYes));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::No, bool(_nStyle & MessBoxStyle::DefaultNo));
+ }
+ else if ( _nStyle & MessBoxStyle::RetryCancel )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Retry, bool(_nStyle & MessBoxStyle::DefaultRetry));
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Cancel, bool(_nStyle & MessBoxStyle::DefaultCancel));
+ }
+ else if ( _nStyle & MessBoxStyle::Ok )
+ {
+ lcl_addButton(m_xDialog.get(), StandardButtonType::OK, true);
+ }
+
+ if ( m_sHelpURL.isEmpty() )
+ return;
+
+ lcl_addButton(m_xDialog.get(), StandardButtonType::Help, false);
+
+ OUString aTmp;
+ INetURLObject aHID( m_sHelpURL );
+ if ( aHID.GetProtocol() == INetProtocol::Hid )
+ aTmp = aHID.GetURLPath();
+ else
+ aTmp = m_sHelpURL;
+
+ m_xDialog->set_help_id(OUStringToOString(aTmp, RTL_TEXTENCODING_UTF8));
+}
+
+void OSQLMessageBox::impl_addDetailsButton()
+{
+ size_t nFirstPageVisible = m_xDialog->get_secondary_text().isEmpty() ? 1 : 2;
+
+ bool bMoreDetailsAvailable = m_pImpl->aDisplayInfo.size() > nFirstPageVisible;
+ if ( !bMoreDetailsAvailable )
+ {
+ // even if the text fits into what we can display, we might need to details button
+ // if there is more non-trivial information in the errors than the mere messages
+ for (auto const& error : m_pImpl->aDisplayInfo)
+ {
+ if ( lcl_hasDetails(error) )
+ {
+ bMoreDetailsAvailable = true;
+ break;
+ }
+ }
+ }
+
+ if ( bMoreDetailsAvailable )
+ {
+ m_xDialog->add_button(GetStandardText(StandardButtonType::More), RET_MORE);
+ m_xMoreButton.reset(m_xDialog->weld_widget_for_response(RET_MORE));
+ m_xMoreButton->connect_clicked(LINK(this, OSQLMessageBox, ButtonClickHdl));
+ }
+}
+
+void OSQLMessageBox::Construct(weld::Window* pParent, MessBoxStyle _nStyle, MessageType _eImage)
+{
+ // init the image
+ MessageType eType( _eImage );
+ if ( eType == AUTO )
+ {
+ switch ( m_pImpl->aDisplayInfo[0].eType )
+ {
+ case SQLExceptionInfo::TYPE::SQLException: eType = Error; break;
+ case SQLExceptionInfo::TYPE::SQLWarning: eType = Warning; break;
+ case SQLExceptionInfo::TYPE::SQLContext: eType = Info; break;
+ default: OSL_FAIL( "OSQLMessageBox::Construct: invalid type!" );
+ }
+ }
+ VclMessageType eMessageType;
+ switch (eType)
+ {
+ default:
+ OSL_FAIL( "OSQLMessageBox::impl_initImage: unsupported image type!" );
+ [[fallthrough]];
+ case Info:
+ eMessageType = VclMessageType::Info;
+ break;
+ case Warning:
+ eMessageType = VclMessageType::Warning;
+ break;
+ case Error:
+ eMessageType = VclMessageType::Error;
+ break;
+ case Query:
+ eMessageType = VclMessageType::Question;
+ break;
+ }
+
+ m_xDialog.reset(Application::CreateMessageDialog(pParent, eMessageType, VclButtonsType::NONE, ""));
+ m_xDialog->set_title(utl::ConfigManager::getProductName() + " Base");
+
+ impl_fillMessages();
+
+ // create buttons
+ impl_createStandardButtons( _nStyle );
+ impl_addDetailsButton();
+}
+
+OSQLMessageBox::OSQLMessageBox(weld::Window* pParent, const SQLExceptionInfo& rException, MessBoxStyle nStyle, const OUString& rHelpURL)
+ : m_pImpl(new SQLMessageBox_Impl(rException))
+ , m_sHelpURL(rHelpURL)
+{
+ Construct(pParent, nStyle, AUTO);
+}
+
+OSQLMessageBox::OSQLMessageBox(weld::Window* pParent, const OUString& rTitle, const OUString& rMessage, MessBoxStyle nStyle, MessageType eType, const ::dbtools::SQLExceptionInfo* pAdditionalErrorInfo )
+{
+ SQLContext aError;
+ aError.Message = rTitle;
+ aError.Details = rMessage;
+ if (pAdditionalErrorInfo)
+ aError.NextException = pAdditionalErrorInfo->get();
+
+ m_pImpl.reset(new SQLMessageBox_Impl(SQLExceptionInfo(aError)));
+
+ Construct(pParent, nStyle, eType);
+}
+
+OSQLMessageBox::~OSQLMessageBox()
+{
+}
+
+IMPL_LINK_NOARG(OSQLMessageBox, ButtonClickHdl, weld::Button&, void)
+{
+ OExceptionChainDialog aDlg(m_xDialog.get(), m_pImpl->aDisplayInfo);
+ aDlg.run();
+}
+
+// OSQLWarningBox
+OSQLWarningBox::OSQLWarningBox(weld::Window* pParent, const OUString& rMessage, MessBoxStyle nStyle,
+ const ::dbtools::SQLExceptionInfo* pAdditionalErrorInfo )
+ : OSQLMessageBox(pParent, DBA_RES(STR_EXCEPTION_WARNING), rMessage, nStyle, MessageType::Warning, pAdditionalErrorInfo)
+{
+}
+
+// OSQLErrorBox
+OSQLErrorBox::OSQLErrorBox(weld::Window* pParent, const OUString& rMessage)
+ : OSQLMessageBox(pParent, DBA_RES(STR_EXCEPTION_ERROR), rMessage, MessBoxStyle::Ok | MessBoxStyle::DefaultOk,
+ MessageType::Error, nullptr)
+{
+}
+
+} // namespace dbaui
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */