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