Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / dbaccess / source / ui / browser / unodatbr.cxx
blob9db7af8bbba6571379ca9624ae516406fbe642c2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "browserids.hxx"
31 #include "dbaccess_helpid.hrc"
32 #include "dbexchange.hxx"
33 #include "dbtreelistbox.hxx"
34 #include "dbtreemodel.hxx"
35 #include "dbtreeview.hxx"
36 #include "dbu_brw.hrc"
37 #include "dbu_reghelper.hxx"
38 #include "dbustrings.hrc"
39 #include "dlgsave.hxx"
40 #include "HtmlReader.hxx"
41 #include "imageprovider.hxx"
42 #include "listviewitems.hxx"
43 #include "QEnumTypes.hxx"
44 #include "RtfReader.hxx"
45 #include "sbagrid.hrc"
46 #include "sbagrid.hxx"
47 #include "sqlmessage.hxx"
48 #include "TokenWriter.hxx"
49 #include "UITools.hxx"
50 #include "unodatbr.hxx"
51 #include "WColumnSelect.hxx"
52 #include "WCopyTable.hxx"
53 #include "WCPage.hxx"
54 #include "WExtendPages.hxx"
55 #include "WNameMatch.hxx"
57 /** === begin UNO includes === **/
58 #include <com/sun/star/awt/LineEndFormat.hpp>
59 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
60 #include <com/sun/star/awt/TextAlign.hpp>
61 #include <com/sun/star/awt/VisualEffect.hpp>
62 #include <com/sun/star/beans/NamedValue.hpp>
63 #include <com/sun/star/beans/PropertyValue.hpp>
64 #include <com/sun/star/container/XNameContainer.hpp>
65 #include <com/sun/star/form/XForm.hpp>
66 #include <com/sun/star/form/XGridColumnFactory.hpp>
67 #include <com/sun/star/form/XLoadable.hpp>
68 #include <com/sun/star/form/XReset.hpp>
69 #include <com/sun/star/frame/FrameSearchFlag.hpp>
70 #include <com/sun/star/frame/XLayoutManager.hpp>
71 #include <com/sun/star/lang/DisposedException.hpp>
72 #include <com/sun/star/sdb/CommandType.hpp>
73 #include <com/sun/star/sdb/SQLContext.hpp>
74 #include <com/sun/star/sdb/XBookmarksSupplier.hpp>
75 #include <com/sun/star/sdb/XCompletedConnection.hpp>
76 #include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
77 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
78 #include <com/sun/star/sdb/XParametersSupplier.hpp>
79 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
80 #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
81 #include <com/sun/star/sdb/XResultSetAccess.hpp>
82 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
83 #include <com/sun/star/sdb/application/NamedDatabaseObject.hpp>
84 #include <com/sun/star/sdbc/ColumnValue.hpp>
85 #include <com/sun/star/sdbc/DataType.hpp>
86 #include <com/sun/star/sdbc/FetchDirection.hpp>
87 #include <com/sun/star/sdbc/SQLWarning.hpp>
88 #include <com/sun/star/sdbc/XDataSource.hpp>
89 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
90 #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
91 #include <com/sun/star/sdbcx/Privilege.hpp>
92 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
93 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
94 #include <com/sun/star/sdbcx/XDrop.hpp>
95 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
96 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
97 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
98 #include <com/sun/star/util/XFlushable.hpp>
99 #include <com/sun/star/document/MacroExecMode.hpp>
100 #include <com/sun/star/frame/XComponentLoader.hpp>
101 #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
102 /** === end UNO includes === **/
104 #include <comphelper/extract.hxx>
105 #include <comphelper/sequence.hxx>
106 #include <comphelper/types.hxx>
107 #include <connectivity/dbexception.hxx>
108 #include <cppuhelper/exc_hlp.hxx>
109 #include <cppuhelper/implbase2.hxx>
110 #include <cppuhelper/typeprovider.hxx>
111 #include <sfx2/app.hxx>
112 #include <sfx2/dispatch.hxx>
113 #include <sot/storage.hxx>
114 #include <svl/filenotation.hxx>
115 #include <svl/intitem.hxx>
116 #include <unotools/moduleoptions.hxx>
117 #include <svtools/svlbitm.hxx>
118 #include <svtools/svtreebx.hxx>
119 #include <svx/algitem.hxx>
120 #include <svx/dataaccessdescriptor.hxx>
121 #include <svx/databaseregistrationui.hxx>
122 #include <toolkit/unohlp.hxx>
123 #include <tools/diagnose_ex.h>
124 #include <osl/diagnose.h>
125 #include <tools/multisel.hxx>
126 #include <tools/urlobj.hxx>
127 #include <unotools/confignode.hxx>
128 #include <vcl/msgbox.hxx>
129 #include <vcl/split.hxx>
130 #include <vcl/stdtext.hxx>
131 #include <vcl/svapp.hxx>
132 #include <vcl/toolbox.hxx>
133 #include <vcl/waitobj.hxx>
134 #include <vcl/wrkwin.hxx>
135 #include <rtl/logfile.hxx>
137 #include <memory>
139 using namespace ::com::sun::star::uno;
140 using namespace ::com::sun::star::awt;
141 using namespace ::com::sun::star::sdb;
142 using namespace ::com::sun::star::sdb::application;
143 using namespace ::com::sun::star::sdbc;
144 using namespace ::com::sun::star::sdbcx;
145 using namespace ::com::sun::star::beans;
146 using namespace ::com::sun::star::util;
147 using namespace ::com::sun::star::frame;
148 using namespace ::com::sun::star::container;
149 using namespace ::com::sun::star::lang;
150 using namespace ::com::sun::star::ui::dialogs;
151 using namespace ::com::sun::star::task;
152 using namespace ::com::sun::star::form;
153 using namespace ::com::sun::star::io;
154 using namespace ::com::sun::star::i18n;
155 using namespace ::com::sun::star::view;
156 using namespace ::com::sun::star::datatransfer;
157 using namespace ::com::sun::star::document;
158 using namespace ::com::sun::star::ui;
159 using namespace ::dbtools;
160 using namespace ::comphelper;
161 using namespace ::svx;
163 // .........................................................................
164 namespace dbaui
166 // .........................................................................
168 namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
169 namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer;
171 //==================================================================
172 //= SbaTableQueryBrowser
173 //==================================================================
174 // -------------------------------------------------------------------------
175 extern "C" void SAL_CALL createRegistryInfo_OBrowser()
177 static OMultiInstanceAutoRegistration< SbaTableQueryBrowser > aAutoRegistration;
179 // -------------------------------------------------------------------------
180 void SafeAddPropertyListener(const Reference< XPropertySet > & xSet, const ::rtl::OUString& rPropName, XPropertyChangeListener* pListener)
182 Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
183 if (xInfo->hasPropertyByName(rPropName))
184 xSet->addPropertyChangeListener(rPropName, pListener);
187 // -------------------------------------------------------------------------
188 void SafeRemovePropertyListener(const Reference< XPropertySet > & xSet, const ::rtl::OUString& rPropName, XPropertyChangeListener* pListener)
190 Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
191 if (xInfo->hasPropertyByName(rPropName))
192 xSet->removePropertyChangeListener(rPropName, pListener);
194 //-------------------------------------------------------------------------
195 ::rtl::OUString SAL_CALL SbaTableQueryBrowser::getImplementationName() throw(RuntimeException)
197 return getImplementationName_Static();
199 //-------------------------------------------------------------------------
200 ::comphelper::StringSequence SAL_CALL SbaTableQueryBrowser::getSupportedServiceNames() throw(RuntimeException)
202 return getSupportedServiceNames_Static();
204 // -------------------------------------------------------------------------
205 ::rtl::OUString SbaTableQueryBrowser::getImplementationName_Static() throw(RuntimeException)
207 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.ODatasourceBrowser"));
209 //-------------------------------------------------------------------------
210 ::comphelper::StringSequence SbaTableQueryBrowser::getSupportedServiceNames_Static() throw(RuntimeException)
212 ::comphelper::StringSequence aSupported(1);
213 aSupported.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.DataSourceBrowser"));
214 return aSupported;
216 //-------------------------------------------------------------------------
217 Reference< XInterface > SAL_CALL SbaTableQueryBrowser::Create(const Reference<XMultiServiceFactory >& _rxFactory)
219 SolarMutexGuard aGuard;
220 return *(new SbaTableQueryBrowser(_rxFactory));
223 DBG_NAME(SbaTableQueryBrowser);
224 //------------------------------------------------------------------------------
225 SbaTableQueryBrowser::SbaTableQueryBrowser(const Reference< XMultiServiceFactory >& _rM)
226 :SbaXDataBrowserController(_rM)
227 ,m_aSelectionListeners( getMutex() )
228 ,m_aContextMenuInterceptors( getMutex() )
229 ,m_aTableCopyHelper(this)
230 ,m_pTreeView(NULL)
231 ,m_pSplitter(NULL)
232 ,m_pTreeModel(NULL)
233 ,m_pCurrentlyDisplayed(NULL)
234 ,m_nAsyncDrop(0)
235 ,m_nBorder(1)
236 ,m_bQueryEscapeProcessing( sal_False )
237 ,m_bShowMenu(sal_False)
238 ,m_bInSuspend(sal_False)
239 ,m_bEnableBrowser(sal_True)
241 DBG_CTOR(SbaTableQueryBrowser,NULL);
244 //------------------------------------------------------------------------------
245 SbaTableQueryBrowser::~SbaTableQueryBrowser()
247 DBG_DTOR(SbaTableQueryBrowser,NULL);
248 if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
250 OSL_FAIL("Please check who doesn't dispose this component!");
251 // increment ref count to prevent double call of Dtor
252 osl_incrementInterlockedCount( &m_refCount );
253 dispose();
257 //------------------------------------------------------------------------------
258 Any SAL_CALL SbaTableQueryBrowser::queryInterface(const Type& _rType) throw (RuntimeException)
260 if ( _rType.equals( XScriptInvocationContext::static_type() ) )
262 OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::queryInterface: did not initialize this, yet!" );
263 if ( !!m_aDocScriptSupport && *m_aDocScriptSupport )
264 return makeAny( Reference< XScriptInvocationContext >( this ) );
265 return Any();
268 Any aReturn = SbaXDataBrowserController::queryInterface(_rType);
269 if (!aReturn.hasValue())
270 aReturn = SbaTableQueryBrowser_Base::queryInterface(_rType);
271 return aReturn;
274 //------------------------------------------------------------------------------
275 Sequence< Type > SAL_CALL SbaTableQueryBrowser::getTypes( ) throw (RuntimeException)
277 Sequence< Type > aTypes( ::comphelper::concatSequences(
278 SbaXDataBrowserController::getTypes(),
279 SbaTableQueryBrowser_Base::getTypes()
280 ) );
282 OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::getTypes: did not initialize this, yet!" );
283 if ( !m_aDocScriptSupport || !*m_aDocScriptSupport )
285 Sequence< Type > aStrippedTypes( aTypes.getLength() - 1 );
286 ::std::remove_copy_if(
287 aTypes.getConstArray(),
288 aTypes.getConstArray() + aTypes.getLength(),
289 aStrippedTypes.getArray(),
290 ::std::bind2nd( ::std::equal_to< Type >(), XScriptInvocationContext::static_type() )
292 aTypes = aStrippedTypes;
294 return aTypes;
297 //------------------------------------------------------------------------------
298 Sequence< sal_Int8 > SAL_CALL SbaTableQueryBrowser::getImplementationId( ) throw (RuntimeException)
300 static ::cppu::OImplementationId * pId = 0;
301 if (! pId)
303 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
304 if (! pId)
306 static ::cppu::OImplementationId aId;
307 pId = &aId;
310 return pId->getImplementationId();
313 //------------------------------------------------------------------------------
314 void SAL_CALL SbaTableQueryBrowser::disposing()
316 SolarMutexGuard aGuard;
317 // doin' a lot of VCL stuff here -> lock the SolarMutex
319 // kiss our listeners goodbye
320 EventObject aEvt(*this);
321 m_aSelectionListeners.disposeAndClear(aEvt);
322 m_aContextMenuInterceptors.disposeAndClear(aEvt);
324 // reset the content's tree view: it holds a reference to our model which is to be deleted immediately,
325 // and it will live longer than we do.
326 if (getBrowserView())
327 getBrowserView()->setTreeView(NULL);
329 clearTreeModel();
330 // clear the tree model
332 SAL_WNODEPRECATED_DECLARATIONS_PUSH
333 ::std::auto_ptr<SvLBoxTreeList> aTemp(m_pTreeModel);
334 SAL_WNODEPRECATED_DECLARATIONS_POP
335 m_pTreeModel = NULL;
338 // remove ourself as status listener
339 implRemoveStatusListeners();
341 // remove the container listener from the database context
344 Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
345 xDatabaseRegistrations->removeDatabaseRegistrationsListener( this );
347 catch( const Exception& )
349 DBG_UNHANDLED_EXCEPTION();
352 // check out from all the objects we are listening
353 // the frame
354 if (m_xCurrentFrameParent.is())
355 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
356 SbaXDataBrowserController::disposing();
359 //------------------------------------------------------------------------------
360 sal_Bool SbaTableQueryBrowser::Construct(Window* pParent)
362 if ( !SbaXDataBrowserController::Construct( pParent ) )
363 return sal_False;
367 Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
368 xDatabaseRegistrations->addDatabaseRegistrationsListener( this );
370 // the collator for the string compares
371 m_xCollator = Reference< XCollator >( getORB()->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.i18n.Collator")) ), UNO_QUERY_THROW );
372 m_xCollator->loadDefaultCollator( Application::GetSettings().GetLocale(), 0 );
374 catch(const Exception&)
376 OSL_FAIL("SbaTableQueryBrowser::Construct: could not create (or start listening at) the database context!");
378 // some help ids
379 if (getBrowserView() && getBrowserView()->getVclControl())
382 // create controls and set sizes
383 const long nFrameWidth = getBrowserView()->LogicToPixel( ::Size( 3, 0 ), MAP_APPFONT ).Width();
385 m_pSplitter = new Splitter(getBrowserView(),WB_HSCROLL);
386 m_pSplitter->SetPosSizePixel( ::Point(0,0), ::Size(nFrameWidth,0) );
387 m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) );
389 m_pTreeView = new DBTreeView(getBrowserView(),getORB(), WB_TABSTOP | WB_BORDER);
390 m_pTreeView->SetPreExpandHandler(LINK(this, SbaTableQueryBrowser, OnExpandEntry));
392 m_pTreeView->setCopyHandler(LINK(this, SbaTableQueryBrowser, OnCopyEntry));
394 m_pTreeView->getListBox().setContextMenuProvider( this );
395 m_pTreeView->getListBox().setControlActionListener( this );
396 m_pTreeView->SetHelpId(HID_CTL_TREEVIEW);
398 // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide
399 m_pSplitter->SetSplitPosPixel( getBrowserView()->LogicToPixel( ::Size( 80, 0 ), MAP_APPFONT ).Width() );
401 getBrowserView()->setSplitter(m_pSplitter);
402 getBrowserView()->setTreeView(m_pTreeView);
404 // fill view with data
405 m_pTreeModel = new SvLBoxTreeList;
406 m_pTreeModel->SetSortMode(SortAscending);
407 m_pTreeModel->SetCompareHdl(LINK(this, SbaTableQueryBrowser, OnTreeEntryCompare));
408 m_pTreeView->setModel(m_pTreeModel);
409 m_pTreeView->setSelChangeHdl( LINK( this, SbaTableQueryBrowser, OnSelectionChange ) );
411 // TODO
412 getBrowserView()->getVclControl()->GetDataWindow().SetUniqueId(UID_DATABROWSE_DATAWINDOW);
413 getBrowserView()->getVclControl()->SetHelpId(HID_CTL_TABBROWSER);
414 getBrowserView()->SetUniqueId(UID_CTL_CONTENT);
415 if (getBrowserView()->getVclControl()->GetHeaderBar())
416 getBrowserView()->getVclControl()->GetHeaderBar()->SetHelpId(HID_DATABROWSE_HEADER);
417 InvalidateFeature(ID_BROWSER_EXPLORER);
420 return sal_True;
422 // ---------------------------------------------------------------------------------------------------------------------
423 namespace
425 // -----------------------------------------------------------------------------------------------------------------
426 struct SelectValueByName : public ::std::unary_function< ::rtl::OUString, Any >
428 const Any& operator()( ::rtl::OUString const& i_name ) const
430 return m_rCollection.get( i_name );
433 SelectValueByName( ::comphelper::NamedValueCollection const& i_collection )
434 :m_rCollection( i_collection )
438 ::comphelper::NamedValueCollection const& m_rCollection;
442 // ---------------------------------------------------------------------------------------------------------------------
443 void SbaTableQueryBrowser::impl_sanitizeRowSetClauses_nothrow()
447 Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
448 sal_Bool bEscapeProcessing = sal_False;
449 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
450 if ( !bEscapeProcessing )
451 // don't touch or interpret anything if escape processing is disabled
452 return;
454 Reference< XSingleSelectQueryComposer > xComposer( createParser_nothrow() );
455 if ( !xComposer.is() )
456 // can't do anything. Already reported via assertion in createParser_nothrow.
457 return;
459 // the tables participating in the statement
460 const Reference< XTablesSupplier > xSuppTables( xComposer, UNO_QUERY_THROW );
461 const Reference< XNameAccess > xTableNames( xSuppTables->getTables(), UNO_QUERY_THROW );
463 // the columns participating in the statement
464 const Reference< XColumnsSupplier > xSuppColumns( xComposer, UNO_QUERY_THROW );
465 const Reference< XNameAccess > xColumnNames( xSuppColumns->getColumns(), UNO_QUERY_THROW );
467 // .............................................................................................................
468 // check if the order columns apply to tables which really exist in the statement
469 const Reference< XIndexAccess > xOrderColumns( xComposer->getOrderColumns(), UNO_SET_THROW );
470 const sal_Int32 nOrderColumns( xOrderColumns->getCount() );
471 bool invalidColumn = nOrderColumns == 0;
472 for ( sal_Int32 c=0; ( c < nOrderColumns ) && !invalidColumn; ++c )
474 const Reference< XPropertySet > xOrderColumn( xOrderColumns->getByIndex(c), UNO_QUERY_THROW );
475 ::rtl::OUString sTableName;
476 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName );
477 ::rtl::OUString sColumnName;
478 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName );
480 if ( sTableName.isEmpty() )
482 if ( !xColumnNames->hasByName( sColumnName ) )
484 invalidColumn = true;
485 break;
488 else
490 if ( !xTableNames->hasByName( sTableName ) )
492 invalidColumn = true;
493 break;
496 const Reference< XColumnsSupplier > xSuppTableColumns( xTableNames->getByName( sTableName ), UNO_QUERY_THROW );
497 const Reference< XNameAccess > xTableColumnNames( xSuppTableColumns->getColumns(), UNO_QUERY_THROW );
498 if ( !xTableColumnNames->hasByName( sColumnName ) )
500 invalidColumn = true;
501 break;
506 if ( invalidColumn )
508 // reset the complete order statement at both the row set and the parser
509 const ::rtl::OUString sEmptyOrder;
510 xRowSetProps->setPropertyValue( PROPERTY_ORDER, makeAny( sEmptyOrder ) );
511 xComposer->setOrder( sEmptyOrder );
514 // .............................................................................................................
515 // check if the columns participating in the filter refer to existing tables
516 // TODO: there's no API at all for this. The method which comes nearest to what we need is
517 // "getStructuredFilter", but it returns pure column names only. That is, for a statement like
518 // "SELECT * FROM <table> WHERE <other_table>.<column> = <value>", it will return "<column>". But
519 // there's no API at all to retrieve the information about "<other_table>" - which is what would
520 // be needed here.
521 // That'd be a chance to replace getStructuredFilter with something more reasonable. This method
522 // has at least one other problem: For a clause like "<column> != <value>", it will return "<column>"
523 // as column name, "NOT_EQUAL" as operator, and "!= <value>" as value, effectively duplicating the
524 // information about the operator, and beding all clients to manually remove the "!=" from the value
525 // string.
526 // So, what really would be handy, is some
527 // XNormalizedFilter getNormalizedFilter();
528 // with
529 // interface XDisjunctiveFilterExpression
530 // {
531 // XConjunctiveFilterTerm getTerm( int index );
532 // }
533 // interface XConjunctiveFilterTerm
534 // {
535 // ComparisonPredicate getPredicate( int index );
536 // }
537 // struct ComparisonPredicate
538 // {
539 // XComparisonOperand Lhs;
540 // SQLFilterOperator Operator;
541 // XComparisonOperand Rhs;
542 // }
543 // interface XComparisonOperand
544 // {
545 // SQLFilterOperand Type;
546 // XPropertySet getColumn();
547 // string getLiteral();
548 // ...
549 // }
550 // enum SQLFilterOperand { Column, Literal, ... }
552 // ... or something like this ....
554 catch( const Exception& )
556 DBG_UNHANDLED_EXCEPTION();
560 // ---------------------------------------------------------------------------------------------------------------------
561 sal_Bool SbaTableQueryBrowser::InitializeForm( const Reference< XPropertySet > & i_formProperties )
563 if(!m_pCurrentlyDisplayed)
564 return sal_True;
566 // this method set all format settings from the orignal table or query
569 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
570 ENSURE_OR_RETURN_FALSE( pData, "SbaTableQueryBrowser::InitializeForm: No user data set at the currently displayed entry!" );
571 ENSURE_OR_RETURN_FALSE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeForm: No table available!" );
573 Reference< XPropertySetInfo > xPSI( pData->xObjectProperties->getPropertySetInfo(), UNO_SET_THROW );
575 ::comphelper::NamedValueCollection aPropertyValues;
577 const ::rtl::OUString aTransferProperties[] =
579 PROPERTY_APPLYFILTER,
580 PROPERTY_FILTER,
581 PROPERTY_HAVING_CLAUSE,
582 PROPERTY_ORDER
584 for (size_t i = 0; i < SAL_N_ELEMENTS(aTransferProperties); ++i)
586 if ( !xPSI->hasPropertyByName( aTransferProperties[i] ) )
587 continue;
588 aPropertyValues.put( aTransferProperties[i], pData->xObjectProperties->getPropertyValue( aTransferProperties[i] ) );
591 ::std::vector< ::rtl::OUString > aNames( aPropertyValues.getNames() );
592 ::std::sort(aNames.begin(), aNames.end());
593 Sequence< ::rtl::OUString > aPropNames( aNames.size() );
594 ::std::copy( aNames.begin(), aNames.end(), aPropNames.getArray() );
596 Sequence< Any > aPropValues( aNames.size() );
597 ::std::transform( aNames.begin(), aNames.end(), aPropValues.getArray(), SelectValueByName( aPropertyValues ) );
599 Reference< XMultiPropertySet > xFormMultiSet( i_formProperties, UNO_QUERY_THROW );
600 xFormMultiSet->setPropertyValues( aPropNames, aPropValues );
602 impl_sanitizeRowSetClauses_nothrow();
604 catch ( const Exception& )
606 DBG_UNHANDLED_EXCEPTION();
607 return sal_False;
610 return sal_True;
613 //------------------------------------------------------------------------------
614 void SbaTableQueryBrowser::initializePreviewMode()
616 if ( getBrowserView() && getBrowserView()->getVclControl() )
618 getBrowserView()->getVclControl()->AlwaysEnableInput( sal_False );
619 getBrowserView()->getVclControl()->EnableInput( sal_False );
620 getBrowserView()->getVclControl()->ForceHideScrollbars( sal_True );
622 Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY);
623 if ( xDataSourceSet.is() )
625 xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowInserts")),makeAny(sal_False));
626 xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowUpdates")),makeAny(sal_False));
627 xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowDeletes")),makeAny(sal_False));
631 //------------------------------------------------------------------------------
632 sal_Bool SbaTableQueryBrowser::InitializeGridModel(const Reference< ::com::sun::star::form::XFormComponent > & xGrid)
636 Reference< ::com::sun::star::form::XGridColumnFactory > xColFactory(xGrid, UNO_QUERY);
637 Reference< XNameContainer > xColContainer(xGrid, UNO_QUERY);
638 clearGridColumns( xColContainer );
640 Reference< XChild > xGridAsChild(xGrid, UNO_QUERY);
641 Reference< XLoadable > xFormAsLoadable;
642 if (xGridAsChild.is())
643 xFormAsLoadable = xFormAsLoadable.query(xGridAsChild->getParent());
644 if (xFormAsLoadable.is() && xFormAsLoadable->isLoaded())
646 // set the formats from the table
647 if(m_pCurrentlyDisplayed)
649 Sequence< ::rtl::OUString> aProperties(6 + ( m_bPreview ? 5 : 0 ));
650 Sequence< Any> aValues(7 + ( m_bPreview ? 5 : 0 ));
652 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
653 OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeGridModel: No table available!" );
654 if ( !pData->xObjectProperties.is() )
655 return sal_False;
657 ::rtl::OUString* pStringIter = aProperties.getArray();
658 Any* pValueIter = aValues.getArray();
659 if ( m_bPreview )
661 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlwaysShowCursor"));
662 *pValueIter++ <<= sal_False;
663 *pStringIter++ = PROPERTY_BORDER;
664 *pValueIter++ <<= sal_Int16(0);
667 *pStringIter++ = PROPERTY_FONT;
668 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_FONT);
669 *pStringIter++ = PROPERTY_TEXTEMPHASIS;
670 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTEMPHASIS);
671 *pStringIter++ = PROPERTY_TEXTRELIEF;
672 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTRELIEF);
673 if ( m_bPreview )
675 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasNavigationBar"));
676 *pValueIter++ <<= sal_False;
677 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasRecordMarker"));
678 *pValueIter++ <<= sal_False;
680 *pStringIter++ = PROPERTY_ROW_HEIGHT;
681 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_ROW_HEIGHT);
682 if ( m_bPreview )
684 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tabstop"));
685 *pValueIter++ <<= sal_False;
687 *pStringIter++ = PROPERTY_TEXTCOLOR;
688 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTCOLOR);
689 *pStringIter++ = PROPERTY_TEXTLINECOLOR;
690 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTLINECOLOR);
692 Reference< XMultiPropertySet > xFormMultiSet(xGrid, UNO_QUERY);
693 xFormMultiSet->setPropertyValues(aProperties, aValues);
697 // get the formats supplier of the database we're working with
698 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier = getNumberFormatter()->getNumberFormatsSupplier();
700 Reference<XConnection> xConnection;
701 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
702 xRowSetProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
703 OSL_ENSURE(xConnection.is(),"A ActiveConnection should normaly exists!");
705 Reference<XChild> xChild(xConnection,UNO_QUERY);
706 Reference<XPropertySet> xDataSourceProp(xChild->getParent(),UNO_QUERY);
707 sal_Bool bSuppressVersionCol = sal_False;
708 OSL_VERIFY( xDataSourceProp->getPropertyValue( PROPERTY_SUPPRESSVERSIONCL ) >>= bSuppressVersionCol );
710 // insert the column into the gridcontrol so that we see something :-)
711 ::rtl::OUString aCurrentModelType;
712 Reference<XColumnsSupplier> xSupCols(getRowSet(),UNO_QUERY);
713 Reference<XNameAccess> xColumns = xSupCols->getColumns();
714 Sequence< ::rtl::OUString> aNames = xColumns->getElementNames();
715 const ::rtl::OUString* pIter = aNames.getConstArray();
716 const ::rtl::OUString* pEnd = pIter + aNames.getLength();
718 ::rtl::OUString sDefaultProperty;
719 Reference< XPropertySet > xColumn;
720 Reference< XPropertySetInfo > xColPSI;
721 for (sal_uInt16 i=0; pIter != pEnd; ++i,++pIter)
723 xColumn.set( xColumns->getByName( *pIter ), UNO_QUERY_THROW );
724 xColPSI.set( xColumn->getPropertySetInfo(), UNO_SET_THROW );
726 // ignore the column when it is a rowversion one
727 if ( bSuppressVersionCol
728 && xColPSI->hasPropertyByName( PROPERTY_ISROWVERSION )
729 && ::cppu::any2bool( xColumn->getPropertyValue( PROPERTY_ISROWVERSION ) )
731 continue;
733 // use the result set column's type to determine the type of grid column to create
734 sal_Bool bFormattedIsNumeric = sal_True;
735 sal_Int32 nType = ::comphelper::getINT32( xColumn->getPropertyValue( PROPERTY_TYPE ) );
737 ::std::vector< NamedValue > aInitialValues;
738 ::std::vector< ::rtl::OUString > aCopyProperties;
739 Any aDefault;
741 switch(nType)
743 case DataType::BIT:
744 case DataType::BOOLEAN:
746 aCurrentModelType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CheckBox"));
747 aInitialValues.push_back( NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualEffect" ) ), makeAny( VisualEffect::FLAT ) ) );
748 sDefaultProperty = PROPERTY_DEFAULTSTATE;
750 sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
751 OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable );
752 aInitialValues.push_back( NamedValue(
753 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TriState" ) ),
754 makeAny( sal_Bool( ColumnValue::NO_NULLS != nNullable ) )
755 ) );
756 if ( ColumnValue::NO_NULLS == nNullable )
757 aDefault <<= (sal_Int16)STATE_NOCHECK;
759 break;
761 case DataType::LONGVARCHAR:
762 case DataType::CLOB:
763 aInitialValues.push_back( NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiLine" ) ), makeAny( (sal_Bool)sal_True ) ) );
764 // NO break!
765 case DataType::BINARY:
766 case DataType::VARBINARY:
767 case DataType::LONGVARBINARY:
768 aCurrentModelType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TextField"));
769 sDefaultProperty = PROPERTY_DEFAULTTEXT;
770 break;
772 case DataType::VARCHAR:
773 case DataType::CHAR:
774 bFormattedIsNumeric = sal_False;
775 // NO break!
776 default:
777 aCurrentModelType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FormattedField"));
778 sDefaultProperty = PROPERTY_EFFECTIVEDEFAULT;
780 if ( xSupplier.is() )
781 aInitialValues.push_back( NamedValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FormatsSupplier")), makeAny( xSupplier ) ) );
782 aInitialValues.push_back( NamedValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TreatAsNumber")), makeAny( (sal_Bool)bFormattedIsNumeric ) ) );
783 aCopyProperties.push_back( static_cast<const rtl::OUString&>(PROPERTY_FORMATKEY) );
784 break;
787 aInitialValues.push_back( NamedValue( PROPERTY_CONTROLSOURCE, makeAny( *pIter ) ) );
788 ::rtl::OUString sLabel;
789 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
790 if ( !sLabel.isEmpty() )
791 aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( sLabel ) ) );
792 else
793 aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( *pIter ) ) );
795 Reference< XPropertySet > xGridCol( xColFactory->createColumn( aCurrentModelType ), UNO_SET_THROW );
796 Reference< XPropertySetInfo > xGridColPSI( xGridCol->getPropertySetInfo(), UNO_SET_THROW );
798 // calculate the default
799 if ( xGridColPSI->hasPropertyByName( PROPERTY_CONTROLDEFAULT ) )
801 aDefault = xColumn->getPropertyValue( PROPERTY_CONTROLDEFAULT );
802 // default value
803 if ( nType == DataType::BIT || nType == DataType::BOOLEAN )
805 if ( aDefault.hasValue() )
806 aDefault <<= (comphelper::getString(aDefault).toInt32() == 0) ? (sal_Int16)STATE_NOCHECK : (sal_Int16)STATE_CHECK;
807 else
808 aDefault <<= ((sal_Int16)STATE_DONTKNOW);
812 if ( aDefault.hasValue() )
813 aInitialValues.push_back( NamedValue( sDefaultProperty, aDefault ) );
815 // transfer properties from the definition to the UNO-model :
816 aCopyProperties.push_back( static_cast<const rtl::OUString&>(PROPERTY_HIDDEN) );
817 aCopyProperties.push_back( static_cast<const rtl::OUString&>(PROPERTY_WIDTH) );
819 // help text to display for the column
820 Any aDescription;
821 if ( xColPSI->hasPropertyByName( PROPERTY_HELPTEXT ) )
822 aDescription = xColumn->getPropertyValue( PROPERTY_HELPTEXT );
823 ::rtl::OUString sTemp;
824 aDescription >>= sTemp;
825 if ( sTemp.isEmpty() )
826 xColumn->getPropertyValue( PROPERTY_DESCRIPTION ) >>= sTemp;
828 aDescription <<= sTemp;
829 aInitialValues.push_back( NamedValue( PROPERTY_HELPTEXT, aDescription ) );
831 // ... horizontal justify
832 Any aAlign; aAlign <<= sal_Int16( 0 );
833 Any aColAlign( xColumn->getPropertyValue( PROPERTY_ALIGN ) );
834 if ( aColAlign.hasValue() )
835 aAlign <<= sal_Int16( ::comphelper::getINT32( aColAlign ) );
836 aInitialValues.push_back( NamedValue( PROPERTY_ALIGN, aAlign ) );
838 // don't allow the mouse to scroll in the cells
839 if ( xGridColPSI->hasPropertyByName( PROPERTY_MOUSE_WHEEL_BEHAVIOR ) )
840 aInitialValues.push_back( NamedValue( PROPERTY_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) ) );
842 // now set all those values
843 for ( ::std::vector< NamedValue >::const_iterator property = aInitialValues.begin();
844 property != aInitialValues.end();
845 ++property
848 xGridCol->setPropertyValue( property->Name, property->Value );
850 for ( ::std::vector< ::rtl::OUString >::const_iterator copyPropertyName = aCopyProperties.begin();
851 copyPropertyName != aCopyProperties.end();
852 ++copyPropertyName
854 xGridCol->setPropertyValue( *copyPropertyName, xColumn->getPropertyValue( *copyPropertyName ) );
856 xColContainer->insertByName(*pIter, makeAny(xGridCol));
860 catch(const Exception&)
862 DBG_UNHANDLED_EXCEPTION();
863 return sal_False;
866 return sal_True;
868 // -----------------------------------------------------------------------------
869 Reference<XPropertySet> getColumnHelper(SvLBoxEntry* _pCurrentlyDisplayed,const Reference<XPropertySet>& _rxSource)
871 Reference<XPropertySet> xRet;
872 if(_pCurrentlyDisplayed)
874 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pCurrentlyDisplayed->GetUserData());
875 Reference<XColumnsSupplier> xColumnsSup(pData->xObjectProperties,UNO_QUERY);
876 Reference<XNameAccess> xNames = xColumnsSup->getColumns();
877 ::rtl::OUString aName;
878 _rxSource->getPropertyValue(PROPERTY_NAME) >>= aName;
879 if(xNames.is() && xNames->hasByName(aName))
880 xRet.set(xNames->getByName(aName),UNO_QUERY);
882 return xRet;
885 // -----------------------------------------------------------------------
886 void SbaTableQueryBrowser::transferChangedControlProperty(const ::rtl::OUString& _rProperty, const Any& _rNewValue)
888 if(m_pCurrentlyDisplayed)
890 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
891 Reference< XPropertySet > xObjectProps(pData->xObjectProperties, UNO_QUERY);
892 OSL_ENSURE(xObjectProps.is(),"SbaTableQueryBrowser::transferChangedControlProperty: no table/query object!");
893 if (xObjectProps.is())
894 xObjectProps->setPropertyValue(_rProperty, _rNewValue);
898 // -----------------------------------------------------------------------
899 void SbaTableQueryBrowser::propertyChange(const PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException)
901 SbaXDataBrowserController::propertyChange(evt);
905 Reference< XPropertySet > xSource(evt.Source, UNO_QUERY);
906 if (!xSource.is())
907 return;
909 // one of the many properties which require us to update the definition ?
910 // a column's width ?
911 else if (evt.PropertyName.equals(PROPERTY_WIDTH))
912 { // a column width has changed -> update the model
913 // (the update of the view is done elsewhere)
914 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
915 if(xProp.is())
917 if(!evt.NewValue.hasValue())
918 xProp->setPropertyValue(PROPERTY_WIDTH,makeAny((sal_Int32)227));
919 else
920 xProp->setPropertyValue(PROPERTY_WIDTH,evt.NewValue);
924 // a column's 'visible' state ?
925 else if (evt.PropertyName.equals(PROPERTY_HIDDEN))
927 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
928 if(xProp.is())
929 xProp->setPropertyValue(PROPERTY_HIDDEN,evt.NewValue);
932 // a columns alignment ?
933 else if (evt.PropertyName.equals(PROPERTY_ALIGN))
935 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
938 if(xProp.is())
940 if(evt.NewValue.hasValue())
942 sal_Int16 nAlign = 0;
943 if(evt.NewValue >>= nAlign)
944 xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(sal_Int32(nAlign)));
945 else
946 xProp->setPropertyValue(PROPERTY_ALIGN,evt.NewValue);
948 else
949 xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(::com::sun::star::awt::TextAlign::LEFT));
952 catch( const Exception& )
954 DBG_UNHANDLED_EXCEPTION();
958 // a column's format ?
959 else if ( (evt.PropertyName.equals(PROPERTY_FORMATKEY))
960 && (TypeClass_LONG == evt.NewValue.getValueTypeClass())
963 // update the model (means the definition object)
964 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
965 if(xProp.is())
966 xProp->setPropertyValue(PROPERTY_FORMATKEY,evt.NewValue);
969 // some table definition properties ?
970 // the height of the rows in the grid ?
971 else if (evt.PropertyName.equals(PROPERTY_ROW_HEIGHT))
973 if(m_pCurrentlyDisplayed)
975 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
976 OSL_ENSURE( pData->xObjectProperties.is(), "No table available!" );
978 sal_Bool bDefault = !evt.NewValue.hasValue();
979 if (bDefault)
980 pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,makeAny((sal_Int32)45));
981 else
982 pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,evt.NewValue);
986 else if ( evt.PropertyName.equals(PROPERTY_FONT) // the font ?
987 || evt.PropertyName.equals(PROPERTY_TEXTCOLOR) // the text color ?
988 || evt.PropertyName.equals(PROPERTY_FILTER) // the filter ?
989 || evt.PropertyName.equals(PROPERTY_HAVING_CLAUSE) // the having clause ?
990 || evt.PropertyName.equals(PROPERTY_ORDER) // the sort ?
991 || evt.PropertyName.equals(PROPERTY_APPLYFILTER) // the appliance of the filter ?
992 || evt.PropertyName.equals(PROPERTY_TEXTLINECOLOR) // the text line color ?
993 || evt.PropertyName.equals(PROPERTY_TEXTEMPHASIS) // the text emphasis ?
994 || evt.PropertyName.equals(PROPERTY_TEXTRELIEF) // the text relief ?
997 transferChangedControlProperty(evt.PropertyName, evt.NewValue);
1000 catch( const Exception& )
1002 DBG_UNHANDLED_EXCEPTION();
1006 // -----------------------------------------------------------------------
1007 sal_Bool SbaTableQueryBrowser::suspend(sal_Bool bSuspend) throw( RuntimeException )
1009 SolarMutexGuard aSolarGuard;
1010 ::osl::MutexGuard aGuard( getMutex() );
1011 if ( getView() && getView()->IsInModalMode() )
1012 return sal_False;
1013 sal_Bool bRet = sal_False;
1014 if ( !m_bInSuspend )
1016 m_bInSuspend = sal_True;
1017 if ( rBHelper.bDisposed )
1018 throw DisposedException( ::rtl::OUString(), *this );
1020 bRet = SbaXDataBrowserController::suspend(bSuspend);
1021 if ( bRet && getView() )
1022 getView()->Hide();
1024 m_bInSuspend = sal_False;
1027 return bRet;
1030 // -------------------------------------------------------------------------
1031 void SAL_CALL SbaTableQueryBrowser::statusChanged( const FeatureStateEvent& _rEvent ) throw(RuntimeException)
1033 // search the external dispatcher causing this call
1034 Reference< XDispatch > xSource(_rEvent.Source, UNO_QUERY);
1035 ExternalFeaturesMap::iterator aLoop;
1036 for ( aLoop = m_aExternalFeatures.begin();
1037 aLoop != m_aExternalFeatures.end();
1038 ++aLoop
1041 if ( _rEvent.FeatureURL.Complete == aLoop->second.aURL.Complete)
1043 OSL_ENSURE( xSource.get() == aLoop->second.xDispatcher.get(), "SbaTableQueryBrowser::statusChanged: inconsistent!" );
1044 // update the enabled state
1045 aLoop->second.bEnabled = _rEvent.IsEnabled;
1047 switch ( aLoop->first )
1049 case ID_BROWSER_DOCUMENT_DATASOURCE:
1051 // if it's the slot for the document data source, remember the state
1052 Sequence< PropertyValue > aDescriptor;
1053 #if OSL_DEBUG_LEVEL > 0
1054 sal_Bool bProperFormat =
1055 #endif
1056 _rEvent.State >>= aDescriptor;
1057 OSL_ENSURE(bProperFormat, "SbaTableQueryBrowser::statusChanged: need a data access descriptor here!");
1058 m_aDocumentDataSource.initializeFrom(aDescriptor);
1060 OSL_ENSURE( ( m_aDocumentDataSource.has(daDataSource)
1061 || m_aDocumentDataSource.has(daDatabaseLocation)
1063 && m_aDocumentDataSource.has(daCommand)
1064 && m_aDocumentDataSource.has(daCommandType),
1065 "SbaTableQueryBrowser::statusChanged: incomplete descriptor!");
1067 // check if we know the object which is set as document data source
1068 checkDocumentDataSource();
1070 break;
1072 default:
1073 // update the toolbox
1074 implCheckExternalSlot( aLoop->first );
1075 break;
1077 break;
1081 OSL_ENSURE(aLoop != m_aExternalFeatures.end(), "SbaTableQueryBrowser::statusChanged: don't know who sent this!");
1084 // -------------------------------------------------------------------------
1085 void SbaTableQueryBrowser::checkDocumentDataSource()
1087 SvLBoxEntry* pDataSourceEntry = NULL;
1088 SvLBoxEntry* pContainerEntry = NULL;
1089 SvLBoxEntry* pObjectEntry = getObjectEntry( m_aDocumentDataSource, &pDataSourceEntry, &pContainerEntry, sal_False );
1090 sal_Bool bKnownDocDataSource = (NULL != pObjectEntry);
1091 if (!bKnownDocDataSource)
1093 if (NULL != pDataSourceEntry)
1094 { // at least the data source is known
1095 if (NULL != pContainerEntry)
1096 bKnownDocDataSource = sal_True; // assume we know it.
1097 // TODO: should we expand the object container? This may be too expensive just for checking ....
1098 else
1100 if ((NULL == pObjectEntry) && m_aDocumentDataSource.has(daCommandType) && m_aDocumentDataSource.has(daCommand))
1101 { // maybe we have a command to be displayed ?
1102 sal_Int32 nCommandType = CommandType::TABLE;
1103 m_aDocumentDataSource[daCommandType] >>= nCommandType;
1105 ::rtl::OUString sCommand;
1106 m_aDocumentDataSource[daCommand] >>= sCommand;
1108 bKnownDocDataSource = (CommandType::COMMAND == nCommandType) && (!sCommand.isEmpty());
1114 if ( !bKnownDocDataSource )
1115 m_aExternalFeatures[ ID_BROWSER_DOCUMENT_DATASOURCE ].bEnabled = sal_False;
1117 // update the toolbox
1118 implCheckExternalSlot(ID_BROWSER_DOCUMENT_DATASOURCE);
1121 // -------------------------------------------------------------------------
1122 void SbaTableQueryBrowser::extractDescriptorProps(const ::svx::ODataAccessDescriptor& _rDescriptor, ::rtl::OUString& _rDataSource, ::rtl::OUString& _rCommand, sal_Int32& _rCommandType, sal_Bool& _rEscapeProcessing)
1124 _rDataSource = _rDescriptor.getDataSource();
1125 if ( _rDescriptor.has(daCommand) )
1126 _rDescriptor[daCommand] >>= _rCommand;
1127 if ( _rDescriptor.has(daCommandType) )
1128 _rDescriptor[daCommandType] >>= _rCommandType;
1130 // escape processing is the only one allowed not to be present
1131 _rEscapeProcessing = sal_True;
1132 if (_rDescriptor.has(daEscapeProcessing))
1133 _rEscapeProcessing = ::cppu::any2bool(_rDescriptor[daEscapeProcessing]);
1136 // -------------------------------------------------------------------------
1137 namespace
1139 bool getDataSourceDisplayName_isURL( const String& _rDS, String& _rDisplayName, String& _rUniqueId )
1141 INetURLObject aURL( _rDS );
1142 if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )
1144 _rDisplayName = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET);
1145 _rUniqueId = aURL.GetMainURL( INetURLObject::NO_DECODE );
1146 return true;
1148 _rDisplayName = _rDS;
1149 _rUniqueId = String();
1150 return false;
1153 // .....................................................................
1154 struct FilterByEntryDataId : public IEntryFilter
1156 String sId;
1157 FilterByEntryDataId( const String& _rId ) : sId( _rId ) { }
1159 virtual ~FilterByEntryDataId() {}
1161 virtual bool includeEntry( SvLBoxEntry* _pEntry ) const;
1164 bool FilterByEntryDataId::includeEntry( SvLBoxEntry* _pEntry ) const
1166 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() );
1167 return ( !pData || ( pData->sAccessor == sId ) );
1171 // -------------------------------------------------------------------------
1172 String SbaTableQueryBrowser::getDataSourceAcessor( SvLBoxEntry* _pDataSourceEntry ) const
1174 OSL_ENSURE( _pDataSourceEntry, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry!" );
1176 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pDataSourceEntry->GetUserData() );
1177 OSL_ENSURE( pData, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry data!" );
1178 OSL_ENSURE( pData->eType == etDatasource, "SbaTableQueryBrowser::getDataSourceAcessor: entry does not denote a data source!" );
1179 return pData->sAccessor.Len() ? pData->sAccessor : GetEntryText( _pDataSourceEntry );
1182 // -------------------------------------------------------------------------
1183 SvLBoxEntry* SbaTableQueryBrowser::getObjectEntry(const ::rtl::OUString& _rDataSource, const ::rtl::OUString& _rCommand, sal_Int32 _nCommandType,
1184 SvLBoxEntry** _ppDataSourceEntry, SvLBoxEntry** _ppContainerEntry, sal_Bool _bExpandAncestors,
1185 const SharedConnection& _rxConnection )
1187 if (_ppDataSourceEntry)
1188 *_ppDataSourceEntry = NULL;
1189 if (_ppContainerEntry)
1190 *_ppContainerEntry = NULL;
1192 SvLBoxEntry* pObject = NULL;
1193 if ( m_pTreeView )
1195 // look for the data source entry
1196 String sDisplayName, sDataSourceId;
1197 bool bIsDataSourceURL = getDataSourceDisplayName_isURL( _rDataSource, sDisplayName, sDataSourceId );
1198 // the display name may differ from the URL for readability reasons
1199 // #i33699#
1201 FilterByEntryDataId aFilter( sDataSourceId );
1202 SvLBoxEntry* pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter );
1203 if ( !pDataSource ) // check if the data source name is a file location
1205 if ( bIsDataSourceURL )
1207 // special case, the data source is a URL
1208 // add new entries to the list box model
1209 implAddDatasource( _rDataSource, _rxConnection );
1210 pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter );
1211 OSL_ENSURE( pDataSource, "SbaTableQueryBrowser::getObjectEntry: hmm - did not find it again!" );
1214 if (_ppDataSourceEntry)
1215 // (caller wants to have it ...)
1216 *_ppDataSourceEntry = pDataSource;
1218 if (pDataSource)
1220 // expand if required so
1221 if (_bExpandAncestors)
1222 m_pTreeView->getListBox().Expand(pDataSource);
1224 // look for the object container
1225 SvLBoxEntry* pCommandType = NULL;
1226 switch (_nCommandType)
1228 case CommandType::TABLE:
1229 pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_TABLES);
1230 break;
1232 case CommandType::QUERY:
1233 pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_QUERIES);
1234 break;
1237 if (_ppContainerEntry)
1238 *_ppContainerEntry = pCommandType;
1240 if (pCommandType)
1242 // expand if required so
1243 if (_bExpandAncestors)
1245 m_pTreeView->getListBox().Expand(pCommandType);
1248 // look for the object
1249 ::rtl::OUString sCommand = _rCommand;
1250 sal_Int32 nIndex = 0;
1253 ::rtl::OUString sPath = sCommand.getToken( 0, '/', nIndex );
1254 pObject = m_pTreeView->getListBox().GetEntryPosByName(sPath, pCommandType);
1255 pCommandType = pObject;
1256 if ( nIndex >= 0 )
1258 if (ensureEntryObject(pObject))
1260 DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( pObject->GetUserData() );
1261 Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
1262 sal_Int32 nIndex2 = nIndex;
1263 sPath = sCommand.getToken( 0, '/', nIndex2 );
1266 if ( xCollection->hasByName(sPath) )
1268 if(!m_pTreeView->getListBox().GetEntryPosByName(sPath,pObject))
1270 Reference<XNameAccess> xChild(xCollection->getByName(sPath),UNO_QUERY);
1271 DBTreeListUserData* pEntryData = new DBTreeListUserData;
1272 pEntryData->eType = etQuery;
1273 if ( xChild.is() )
1275 pEntryData->eType = etQueryContainer;
1277 implAppendEntry( pObject, sPath, pEntryData, pEntryData->eType );
1281 catch(const Exception&)
1283 OSL_FAIL("SbaTableQueryBrowser::populateTree: could not fill the tree");
1288 while ( nIndex >= 0 );
1292 return pObject;
1295 // -------------------------------------------------------------------------
1296 SvLBoxEntry* SbaTableQueryBrowser::getObjectEntry(const ::svx::ODataAccessDescriptor& _rDescriptor,
1297 SvLBoxEntry** _ppDataSourceEntry, SvLBoxEntry** _ppContainerEntry,
1298 sal_Bool _bExpandAncestors)
1300 // extract the props from the descriptor
1301 ::rtl::OUString sDataSource;
1302 ::rtl::OUString sCommand;
1303 sal_Int32 nCommandType = CommandType::COMMAND;
1304 sal_Bool bEscapeProcessing = sal_True;
1305 extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
1307 return getObjectEntry( sDataSource, sCommand, nCommandType, _ppDataSourceEntry, _ppContainerEntry, _bExpandAncestors, SharedConnection() );
1310 // -------------------------------------------------------------------------
1311 void SbaTableQueryBrowser::connectExternalDispatches()
1313 Reference< XDispatchProvider > xProvider( getFrame(), UNO_QUERY );
1314 OSL_ENSURE(xProvider.is(), "SbaTableQueryBrowser::connectExternalDispatches: no DispatchProvider !");
1315 if (xProvider.is())
1317 if ( m_aExternalFeatures.empty() )
1319 const sal_Char* pURLs[] = {
1320 ".uno:DataSourceBrowser/DocumentDataSource",
1321 ".uno:DataSourceBrowser/FormLetter",
1322 ".uno:DataSourceBrowser/InsertColumns",
1323 ".uno:DataSourceBrowser/InsertContent",
1325 const sal_uInt16 nIds[] = {
1326 ID_BROWSER_DOCUMENT_DATASOURCE,
1327 ID_BROWSER_FORMLETTER,
1328 ID_BROWSER_INSERTCOLUMNS,
1329 ID_BROWSER_INSERTCONTENT
1332 for ( size_t i=0; i < sizeof( pURLs ) / sizeof( pURLs[0] ); ++i )
1334 URL aURL;
1335 aURL.Complete = ::rtl::OUString::createFromAscii( pURLs[i] );
1336 if ( m_xUrlTransformer.is() )
1337 m_xUrlTransformer->parseStrict( aURL );
1338 m_aExternalFeatures[ nIds[ i ] ] = ExternalFeature( aURL );
1342 for ( ExternalFeaturesMap::iterator feature = m_aExternalFeatures.begin();
1343 feature != m_aExternalFeatures.end();
1344 ++feature
1347 feature->second.xDispatcher = xProvider->queryDispatch(
1348 feature->second.aURL, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_parent")), FrameSearchFlag::PARENT
1351 if ( feature->second.xDispatcher.get() == static_cast< XDispatch* >( this ) )
1353 OSL_FAIL( "SbaTableQueryBrowser::connectExternalDispatches: this should not happen anymore!" );
1354 // (nowadays, the URLs aren't in our SupportedFeatures list anymore, so we should
1355 // not supply a dispatcher for this)
1356 feature->second.xDispatcher.clear();
1359 if ( feature->second.xDispatcher.is() )
1363 feature->second.xDispatcher->addStatusListener( this, feature->second.aURL );
1365 catch( const Exception& )
1367 DBG_UNHANDLED_EXCEPTION();
1371 implCheckExternalSlot( feature->first );
1376 // -------------------------------------------------------------------------
1377 void SbaTableQueryBrowser::implCheckExternalSlot( sal_uInt16 _nId )
1379 if ( !m_xMainToolbar.is() )
1380 return;
1382 Window* pToolboxWindow = VCLUnoHelper::GetWindow( m_xMainToolbar );
1383 ToolBox* pToolbox = dynamic_cast< ToolBox* >( pToolboxWindow );
1384 OSL_ENSURE( pToolbox, "SbaTableQueryBrowser::implCheckExternalSlot: cannot obtain the toolbox window!" );
1386 // check if we have to hide this item from the toolbox
1387 if ( pToolbox )
1389 sal_Bool bHaveDispatcher = m_aExternalFeatures[ _nId ].xDispatcher.is();
1390 if ( bHaveDispatcher != pToolbox->IsItemVisible( _nId ) )
1391 bHaveDispatcher ? pToolbox->ShowItem( _nId ) : pToolbox->HideItem( _nId );
1394 // and invalidate this feature in general
1395 InvalidateFeature( _nId );
1398 // -------------------------------------------------------------------------
1399 void SAL_CALL SbaTableQueryBrowser::disposing( const EventObject& _rSource ) throw(RuntimeException)
1401 // our frame ?
1402 Reference< ::com::sun::star::frame::XFrame > xSourceFrame(_rSource.Source, UNO_QUERY);
1403 if (m_xCurrentFrameParent.is() && (xSourceFrame == m_xCurrentFrameParent))
1404 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
1405 else
1407 // search the external dispatcher causing this call in our map
1408 Reference< XDispatch > xSource(_rSource.Source, UNO_QUERY);
1409 if(xSource.is())
1411 ExternalFeaturesMap::iterator aLoop = m_aExternalFeatures.begin();
1412 ExternalFeaturesMap::iterator aEnd = m_aExternalFeatures.end();
1413 while (aLoop != aEnd)
1415 ExternalFeaturesMap::iterator aI = aLoop++;
1416 if ( aI->second.xDispatcher.get() == xSource.get() )
1418 sal_uInt16 nSlot = aI->first;
1420 // remove it
1421 m_aExternalFeatures.erase(aI);
1423 // maybe update the UI
1424 implCheckExternalSlot(nSlot);
1426 // continue, the same XDispatch may be resposible for more than one URL
1430 else
1432 Reference<XConnection> xCon(_rSource.Source, UNO_QUERY);
1433 if ( xCon.is() && m_pTreeView )
1434 { // our connection is in dispose so we have to find the entry equal with this connection
1435 // and close it what means to collapse the entry
1436 // get the top-level representing the removed data source
1437 SvLBoxEntry* pDSLoop = m_pTreeView->getListBox().FirstChild(NULL);
1438 while (pDSLoop)
1440 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pDSLoop->GetUserData());
1441 if ( pData && pData->xConnection == xCon )
1443 // we set the connection to null to avoid a second disposing of the connection
1444 pData->xConnection.clear();
1445 closeConnection(pDSLoop,sal_False);
1446 break;
1449 pDSLoop = m_pTreeView->getListBox().NextSibling(pDSLoop);
1452 else
1453 SbaXDataBrowserController::disposing(_rSource);
1458 // -------------------------------------------------------------------------
1459 void SbaTableQueryBrowser::implRemoveStatusListeners()
1461 // clear all old dispatches
1462 for ( ExternalFeaturesMap::const_iterator aLoop = m_aExternalFeatures.begin();
1463 aLoop != m_aExternalFeatures.end();
1464 ++aLoop
1467 if ( aLoop->second.xDispatcher.is() )
1471 aLoop->second.xDispatcher->removeStatusListener( this, aLoop->second.aURL );
1473 catch (Exception&)
1475 OSL_FAIL("SbaTableQueryBrowser::implRemoveStatusListeners: could not remove a status listener!");
1479 m_aExternalFeatures.clear();
1482 // -------------------------------------------------------------------------
1483 sal_Bool SAL_CALL SbaTableQueryBrowser::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException)
1485 SolarMutexGuard aGuard;
1486 // doin' a lot of VCL stuff here -> lock the SolarMutex
1488 Sequence< PropertyValue > aDescriptorSequence;
1489 if (!(_rSelection >>= aDescriptorSequence))
1490 throw IllegalArgumentException(::rtl::OUString(), *this, 1);
1491 // TODO: error message
1493 ODataAccessDescriptor aDescriptor;
1496 aDescriptor = ODataAccessDescriptor(aDescriptorSequence);
1498 catch(const Exception&)
1500 OSL_FAIL("SbaTableQueryBrowser::select: could not extract the descriptor!");
1503 // check the precense of the props we need
1504 if ( !(aDescriptor.has(daDataSource) || aDescriptor.has(daDatabaseLocation)) || !aDescriptor.has(daCommand) || !aDescriptor.has(daCommandType))
1505 throw IllegalArgumentException(::rtl::OUString(), *this, 1);
1506 // TODO: error message
1508 return implSelect(aDescriptor,sal_True);
1511 // -------------------------------------------------------------------------
1512 Any SAL_CALL SbaTableQueryBrowser::getSelection( ) throw (RuntimeException)
1514 Any aReturn;
1518 Reference< XLoadable > xLoadable(getRowSet(), UNO_QUERY);
1519 if (xLoadable.is() && xLoadable->isLoaded())
1521 Reference< XPropertySet > aFormProps(getRowSet(), UNO_QUERY);
1522 ODataAccessDescriptor aDescriptor(aFormProps);
1523 // remove properties which are not part of our "selection"
1524 aDescriptor.erase(daConnection);
1525 aDescriptor.erase(daCursor);
1527 aReturn <<= aDescriptor.createPropertyValueSequence();
1530 catch( const Exception& )
1532 DBG_UNHANDLED_EXCEPTION();
1535 return aReturn;
1538 // -------------------------------------------------------------------------
1539 void SAL_CALL SbaTableQueryBrowser::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException)
1541 m_aSelectionListeners.addInterface(_rxListener);
1544 // -------------------------------------------------------------------------
1545 void SAL_CALL SbaTableQueryBrowser::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException)
1547 m_aSelectionListeners.removeInterface(_rxListener);
1550 // -------------------------------------------------------------------------
1551 void SbaTableQueryBrowser::attachFrame(const Reference< ::com::sun::star::frame::XFrame > & _xFrame) throw( RuntimeException )
1553 implRemoveStatusListeners();
1555 if (m_xCurrentFrameParent.is())
1556 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
1558 SbaXDataBrowserController::attachFrame(_xFrame);
1560 Reference< XFrame > xCurrentFrame( getFrame() );
1561 if ( xCurrentFrame.is() )
1563 m_xCurrentFrameParent = xCurrentFrame->findFrame(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_parent")),FrameSearchFlag::PARENT);
1564 if ( m_xCurrentFrameParent.is() )
1565 m_xCurrentFrameParent->addFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
1567 // obtain our toolbox
1570 Reference< XPropertySet > xFrameProps( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW );
1571 Reference< XLayoutManager > xLayouter(
1572 xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ),
1573 UNO_QUERY );
1575 if ( xLayouter.is() )
1577 Reference< XUIElement > xUI(
1578 xLayouter->getElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ) ) ),
1579 UNO_SET_THROW );
1580 m_xMainToolbar = m_xMainToolbar.query( xUI->getRealInterface() );
1581 OSL_ENSURE( m_xMainToolbar.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" );
1584 catch( const Exception& )
1586 DBG_UNHANDLED_EXCEPTION();
1590 // get the dispatchers for the external slots
1591 connectExternalDispatches();
1594 // -------------------------------------------------------------------------
1595 void SbaTableQueryBrowser::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
1597 SbaXDataBrowserController::addModelListeners(_xGridControlModel);
1598 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1599 if (xSourceSet.is())
1601 xSourceSet->addPropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1602 xSourceSet->addPropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1603 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1604 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1605 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1606 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1611 // -------------------------------------------------------------------------
1612 void SbaTableQueryBrowser::removeModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
1614 SbaXDataBrowserController::removeModelListeners(_xGridControlModel);
1615 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1616 if (xSourceSet.is())
1618 xSourceSet->removePropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1619 xSourceSet->removePropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1620 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1621 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1622 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1623 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1626 // -------------------------------------------------------------------------
1627 void SbaTableQueryBrowser::RowChanged()
1629 if(getBrowserView())
1631 SbaGridControl* pControl = getBrowserView()->getVclControl();
1632 if (!pControl->IsEditing())
1633 InvalidateFeature(ID_BROWSER_COPY);
1635 SbaXDataBrowserController::RowChanged();
1638 // -------------------------------------------------------------------------
1639 void SbaTableQueryBrowser::ColumnChanged()
1641 if(getBrowserView())
1643 SbaGridControl* pControl = getBrowserView()->getVclControl();
1644 if (!pControl->IsEditing())
1645 InvalidateFeature(ID_BROWSER_COPY);
1647 SbaXDataBrowserController::ColumnChanged();
1649 //------------------------------------------------------------------------------
1650 void SbaTableQueryBrowser::AddColumnListener(const Reference< XPropertySet > & xCol)
1652 SbaXDataBrowserController::AddColumnListener(xCol);
1653 SafeAddPropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1654 SafeAddPropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1655 SafeAddPropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1656 SafeAddPropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1659 //------------------------------------------------------------------------------
1660 void SbaTableQueryBrowser::RemoveColumnListener(const Reference< XPropertySet > & xCol)
1662 SbaXDataBrowserController::RemoveColumnListener(xCol);
1663 SafeRemovePropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1664 SafeRemovePropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1665 SafeRemovePropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1666 SafeRemovePropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1669 //------------------------------------------------------------------------------
1670 void SbaTableQueryBrowser::criticalFail()
1672 SbaXDataBrowserController::criticalFail();
1673 unloadAndCleanup( sal_False );
1676 //------------------------------------------------------------------------------
1677 void SbaTableQueryBrowser::LoadFinished(sal_Bool _bWasSynch)
1679 SbaXDataBrowserController::LoadFinished(_bWasSynch);
1681 m_sQueryCommand = ::rtl::OUString();
1682 m_bQueryEscapeProcessing = sal_False;
1684 if (isValid() && !loadingCancelled())
1686 // did we load a query?
1687 sal_Bool bTemporary; // needed because we m_bQueryEscapeProcessing is only one bit wide (and we want to pass it by reference)
1688 if ( implGetQuerySignature( m_sQueryCommand, bTemporary ) )
1689 m_bQueryEscapeProcessing = bTemporary;
1692 // if the form has been loaded, this means that our "selection" has changed
1693 EventObject aEvent( *this );
1694 m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent );
1697 //------------------------------------------------------------------------------
1698 sal_Bool SbaTableQueryBrowser::getExternalSlotState( sal_uInt16 _nId ) const
1700 sal_Bool bEnabled = sal_False;
1701 ExternalFeaturesMap::const_iterator aPos = m_aExternalFeatures.find( _nId );
1702 if ( ( m_aExternalFeatures.end() != aPos ) && aPos->second.xDispatcher.is() )
1703 bEnabled = aPos->second.bEnabled;
1704 return bEnabled;
1707 //------------------------------------------------------------------------------
1708 FeatureState SbaTableQueryBrowser::GetState(sal_uInt16 nId) const
1710 FeatureState aReturn;
1711 // (disabled automatically)
1713 // no chance without a view
1714 if (!getBrowserView() || !getBrowserView()->getVclControl())
1715 return aReturn;
1717 switch ( nId )
1719 case ID_TREE_ADMINISTRATE:
1720 aReturn.bEnabled = true;
1721 return aReturn;
1723 case ID_BROWSER_CLOSE:
1724 // the close button should always be enabled
1725 aReturn.bEnabled = !m_bEnableBrowser;
1726 return aReturn;
1728 // "toggle explorer" is always enabled (if we have a explorer)
1729 case ID_BROWSER_EXPLORER:
1730 aReturn.bEnabled = m_bEnableBrowser;
1731 aReturn.bChecked = haveExplorer();
1732 return aReturn;
1734 case ID_BROWSER_REMOVEFILTER:
1735 return SbaXDataBrowserController::GetState( nId );
1737 case ID_BROWSER_COPY:
1738 if ( !m_pTreeView->HasChildPathFocus() )
1739 // handled below
1740 break;
1741 // NO break!
1742 case ID_TREE_CLOSE_CONN:
1743 case ID_TREE_EDIT_DATABASE:
1745 SvLBoxEntry* pCurrentEntry( m_pTreeView->getListBox().GetCurEntry() );
1746 EntryType eType = getEntryType( pCurrentEntry );
1747 if ( eType == etUnknown )
1748 return aReturn;
1750 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent( pCurrentEntry );
1751 DBTreeListUserData* pDSData
1752 = pDataSourceEntry
1753 ? static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() )
1754 : NULL;
1756 if ( nId == ID_TREE_CLOSE_CONN )
1758 aReturn.bEnabled = ( pDSData != NULL ) && pDSData->xConnection.is();
1760 else if ( nId == ID_TREE_EDIT_DATABASE )
1762 ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithServiceFactory( getORB(),
1763 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.DataAccess/Policies/Features/Common" ) ) ) );
1764 sal_Bool bHaveEditDatabase( sal_True );
1765 OSL_VERIFY( aConfig.getNodeValue( "EditDatabaseFromDataSourceView" ) >>= bHaveEditDatabase );
1766 aReturn.bEnabled = getORB().is() && ( pDataSourceEntry != NULL ) && bHaveEditDatabase;
1768 else if ( nId == ID_BROWSER_COPY )
1770 aReturn.bEnabled = isEntryCopyAllowed( pCurrentEntry );
1773 return aReturn;
1777 // all slots not handled above are not available if no form is loaded
1778 if (!isLoaded())
1779 return aReturn;
1783 sal_Bool bHandled = sal_False;
1784 switch (nId)
1786 case ID_BROWSER_DOCUMENT_DATASOURCE:
1787 // the slot is enabled if we have an external dispatcher able to handle it,
1788 // and the dispatcher must have enabled the slot in general
1789 aReturn.bEnabled = getExternalSlotState( ID_BROWSER_DOCUMENT_DATASOURCE );
1790 bHandled = sal_True;
1791 break;
1792 case ID_BROWSER_REFRESH:
1793 aReturn.bEnabled = sal_True;
1794 bHandled = sal_True;
1795 break;
1798 if (bHandled)
1799 return aReturn;
1801 // no chance without valid models
1802 if (isValid() && !isValidCursor() && nId != ID_BROWSER_CLOSE)
1803 return aReturn;
1805 switch (nId)
1807 case ID_BROWSER_INSERTCOLUMNS:
1808 case ID_BROWSER_INSERTCONTENT:
1809 case ID_BROWSER_FORMLETTER:
1811 // the slot is enabled if we have an external dispatcher able to handle it,
1812 // and the dispatcher must have enabled the slot in general
1813 aReturn.bEnabled = getExternalSlotState( nId );
1815 // for the Insert* slots, we need at least one selected row
1816 if (ID_BROWSER_FORMLETTER != nId)
1817 aReturn.bEnabled = aReturn.bEnabled && getBrowserView()->getVclControl()->GetSelectRowCount();
1819 // disabled for native queries which are not saved within the database
1820 Reference< XPropertySet > xDataSource(getRowSet(), UNO_QUERY);
1823 aReturn.bEnabled = aReturn.bEnabled && xDataSource.is();
1825 if (xDataSource.is())
1827 sal_Int32 nType = ::comphelper::getINT32(xDataSource->getPropertyValue(PROPERTY_COMMAND_TYPE));
1828 aReturn.bEnabled = aReturn.bEnabled && ((::comphelper::getBOOL(xDataSource->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || (nType == ::com::sun::star::sdb::CommandType::QUERY)));
1831 catch(DisposedException&)
1833 OSL_FAIL("SbaTableQueryBrowser::GetState: object already disposed!");
1835 catch( const Exception& )
1837 DBG_UNHANDLED_EXCEPTION();
1840 break;
1842 case ID_BROWSER_TITLE:
1844 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1845 sal_Int32 nCommandType = CommandType::TABLE;
1846 xProp->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nCommandType;
1847 String sTitle;
1848 switch (nCommandType)
1850 case CommandType::TABLE:
1851 sTitle = String(ModuleRes(STR_TBL_TITLE)); break;
1852 case CommandType::QUERY:
1853 case CommandType::COMMAND:
1854 sTitle = String(ModuleRes(STR_QRY_TITLE)); break;
1855 default:
1856 OSL_FAIL("SbaTableQueryBrowser::GetState: unknown command type!");
1858 ::rtl::OUString aName;
1859 xProp->getPropertyValue(PROPERTY_COMMAND) >>= aName;
1860 String sObject(aName.getStr());
1862 sTitle.SearchAndReplace('#',sObject);
1863 aReturn.sTitle = sTitle;
1864 aReturn.bEnabled = sal_True;
1866 break;
1867 case ID_BROWSER_TABLEATTR:
1868 case ID_BROWSER_ROWHEIGHT:
1869 case ID_BROWSER_COLATTRSET:
1870 case ID_BROWSER_COLWIDTH:
1871 aReturn.bEnabled = getBrowserView() && getBrowserView()->getVclControl() && isValid() && isValidCursor();
1872 // aReturn.bEnabled &= getDefinition() && !getDefinition()->GetDatabase()->IsReadOnly();
1873 break;
1875 case ID_BROWSER_COPY:
1876 OSL_ENSURE( !m_pTreeView->HasChildPathFocus(), "SbaTableQueryBrowser::GetState( ID_BROWSER_COPY ): this should have been handled above!" );
1877 if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing())
1879 SbaGridControl* pControl = getBrowserView()->getVclControl();
1880 if ( pControl->GetSelectRowCount() )
1882 aReturn.bEnabled = m_aCurrentFrame.isActive();
1883 break;
1885 else
1886 aReturn.bEnabled = pControl->canCopyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
1887 break;
1889 // NO break here
1890 default:
1891 return SbaXDataBrowserController::GetState(nId);
1894 catch(const Exception&)
1896 DBG_UNHANDLED_EXCEPTION();
1899 return aReturn;
1903 //------------------------------------------------------------------------------
1904 void SbaTableQueryBrowser::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& aArgs)
1906 switch (nId)
1908 default:
1909 SbaXDataBrowserController::Execute(nId,aArgs);
1910 break;
1912 case ID_TREE_EDIT_DATABASE:
1913 implAdministrate( m_pTreeView->getListBox().GetCurEntry() );
1914 break;
1916 case ID_TREE_CLOSE_CONN:
1917 openHelpAgent( rtl::OString( HID_DSBROWSER_DISCONNECTING ));
1918 closeConnection( m_pTreeView->getListBox().GetRootLevelParent( m_pTreeView->getListBox().GetCurEntry() ) );
1919 break;
1921 case ID_TREE_ADMINISTRATE:
1922 ::svx::administrateDatabaseRegistration( getView() );
1923 break;
1925 case ID_BROWSER_REFRESH:
1927 if ( !SaveModified( ) )
1928 // nothing to do
1929 break;
1931 sal_Bool bFullReinit = sal_False;
1932 // check if the query signature (if the form is based on a query) has changed
1933 if ( !m_sQueryCommand.isEmpty() )
1935 ::rtl::OUString sNewQueryCommand;
1936 sal_Bool bNewQueryEP;
1938 #if OSL_DEBUG_LEVEL > 0
1939 sal_Bool bIsQuery =
1940 #endif
1941 implGetQuerySignature( sNewQueryCommand, bNewQueryEP );
1942 OSL_ENSURE( bIsQuery, "SbaTableQueryBrowser::Execute: was a query before, but is not anymore?" );
1944 bFullReinit = ( sNewQueryCommand != m_sQueryCommand ) || ( m_bQueryEscapeProcessing != bNewQueryEP );
1946 if ( !bFullReinit )
1948 // let the base class do a simple reload
1949 SbaXDataBrowserController::Execute(nId,aArgs);
1950 break;
1952 // NO break here!
1955 case ID_BROWSER_REFRESH_REBUILD:
1957 if ( !SaveModified() )
1958 // nothing to do
1959 break;
1961 SvLBoxEntry* pSelected = m_pCurrentlyDisplayed;
1962 // unload
1963 unloadAndCleanup( sal_False );
1965 // reselect the entry
1966 if ( pSelected )
1968 implSelect( pSelected );
1970 else
1972 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1973 implSelect(::svx::ODataAccessDescriptor(xProp));
1976 break;
1978 case ID_BROWSER_EXPLORER:
1979 toggleExplorer();
1980 break;
1982 case ID_BROWSER_DOCUMENT_DATASOURCE:
1983 implSelect(m_aDocumentDataSource);
1984 break;
1986 case ID_BROWSER_INSERTCOLUMNS:
1987 case ID_BROWSER_INSERTCONTENT:
1988 case ID_BROWSER_FORMLETTER:
1989 if (getBrowserView() && isValidCursor())
1991 // the URL the slot id is assigned to
1992 OSL_ENSURE( m_aExternalFeatures.find( nId ) != m_aExternalFeatures.end(),
1993 "SbaTableQueryBrowser::Execute( ID_BROWSER_?): how could this ever be enabled?" );
1994 URL aParentUrl = m_aExternalFeatures[ nId ].aURL;
1996 // let the dispatcher execute the slot
1997 Reference< XDispatch > xDispatch( m_aExternalFeatures[ nId ].xDispatcher );
1998 if (xDispatch.is())
2000 // set the properties for the dispatch
2002 // first fill the selection
2003 SbaGridControl* pGrid = getBrowserView()->getVclControl();
2004 MultiSelection* pSelection = (MultiSelection*)pGrid->GetSelection();
2005 Sequence< Any > aSelection;
2006 if ( !pGrid->IsAllSelected() )
2007 { // transfer the selected rows only if not all rows are selected
2008 // (all rows means the whole table)
2009 // #i3832#
2010 if (pSelection != NULL)
2012 aSelection.realloc(pSelection->GetSelectCount());
2013 long nIdx = pSelection->FirstSelected();
2014 Any* pSelectionNos = aSelection.getArray();
2015 while (nIdx >= 0)
2017 *pSelectionNos++ <<= (sal_Int32)(nIdx + 1);
2018 nIdx = pSelection->NextSelected();
2023 Reference< XResultSet > xCursorClone;
2026 Reference< XResultSetAccess > xResultSetAccess(getRowSet(),UNO_QUERY);
2027 if (xResultSetAccess.is())
2028 xCursorClone = xResultSetAccess->createResultSet();
2030 catch(DisposedException&)
2032 OSL_FAIL("Object already disposed!");
2034 catch(const Exception&)
2036 OSL_FAIL("SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not clone the cursor!");
2039 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
2043 ODataAccessDescriptor aDescriptor;
2044 ::rtl::OUString sDataSourceName;
2045 xProp->getPropertyValue(PROPERTY_DATASOURCENAME) >>= sDataSourceName;
2047 aDescriptor.setDataSource(sDataSourceName);
2048 aDescriptor[daCommand] = xProp->getPropertyValue(PROPERTY_COMMAND);
2049 aDescriptor[daCommandType] = xProp->getPropertyValue(PROPERTY_COMMAND_TYPE);
2050 aDescriptor[daConnection] = xProp->getPropertyValue(PROPERTY_ACTIVE_CONNECTION);
2051 aDescriptor[daCursor] <<= xCursorClone;
2052 if ( aSelection.getLength() )
2054 aDescriptor[daSelection] <<= aSelection;
2055 aDescriptor[daBookmarkSelection] <<= sal_False;
2056 // these are selection indicies
2057 // before we change this, all clients have to be adjusted
2058 // so that they recognize the new BookmarkSelection property!
2061 xDispatch->dispatch(aParentUrl, aDescriptor.createPropertyValueSequence());
2063 catch( const Exception& )
2065 DBG_UNHANDLED_EXCEPTION();
2069 break;
2071 case ID_BROWSER_CLOSE:
2072 closeTask();
2073 // if it's not 0, such a async close is already pending
2074 break;
2076 case ID_BROWSER_COPY:
2077 if(m_pTreeView->HasChildPathFocus())
2079 copyEntry(m_pTreeView->getListBox().GetCurEntry());
2081 else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing() && getBrowserView()->getVclControl()->GetSelectRowCount() < 1)
2083 SbaGridControl* pControl = getBrowserView()->getVclControl();
2084 pControl->copyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
2086 else
2087 SbaXDataBrowserController::Execute(nId,aArgs);
2088 break;
2092 // -------------------------------------------------------------------------
2093 void SbaTableQueryBrowser::implAddDatasource( const String& _rDataSourceName, const SharedConnection& _rxConnection )
2095 Image a, b, c;
2096 String d, e;
2097 implAddDatasource( _rDataSourceName, a, d, b, e, c, _rxConnection );
2100 // -------------------------------------------------------------------------
2101 void SbaTableQueryBrowser::implAddDatasource(const String& _rDbName, Image& _rDbImage,
2102 String& _rQueryName, Image& _rQueryImage, String& _rTableName, Image& _rTableImage,
2103 const SharedConnection& _rxConnection)
2105 SolarMutexGuard aGuard;
2106 // initialize the names/images if necessary
2107 if (!_rQueryName.Len())
2108 _rQueryName = String(ModuleRes(RID_STR_QUERIES_CONTAINER));
2109 if (!_rTableName.Len())
2110 _rTableName = String(ModuleRes(RID_STR_TABLES_CONTAINER));
2112 ImageProvider aImageProvider;
2113 if (!_rQueryImage)
2114 _rQueryImage = aImageProvider.getFolderImage( DatabaseObject::QUERY );
2115 if (!_rTableImage)
2116 _rTableImage = aImageProvider.getFolderImage( DatabaseObject::TABLE );
2118 if (!_rDbImage)
2119 _rDbImage = aImageProvider.getDatabaseImage();
2121 // add the entry for the data source
2122 // special handling for data sources denoted by URLs - we do not want to display this ugly URL, do we?
2123 // #i33699#
2124 String sDSDisplayName, sDataSourceId;
2125 getDataSourceDisplayName_isURL( _rDbName, sDSDisplayName, sDataSourceId );
2127 SvLBoxEntry* pDatasourceEntry = m_pTreeView->getListBox().InsertEntry( sDSDisplayName, _rDbImage, _rDbImage, NULL, sal_False );
2128 DBTreeListUserData* pDSData = new DBTreeListUserData;
2129 pDSData->eType = etDatasource;
2130 pDSData->sAccessor = sDataSourceId;
2131 pDSData->xConnection = _rxConnection;
2132 pDatasourceEntry->SetUserData(pDSData);
2134 // the child for the queries container
2136 DBTreeListUserData* pQueriesData = new DBTreeListUserData;
2137 pQueriesData->eType = etQueryContainer;
2139 m_pTreeView->getListBox().InsertEntry(
2140 _rQueryName, _rQueryImage, _rQueryImage, pDatasourceEntry,
2141 sal_True /*ChildrenOnDemand*/, LIST_APPEND, pQueriesData );
2144 // the child for the tables container
2146 DBTreeListUserData* pTablesData = new DBTreeListUserData;
2147 pTablesData->eType = etTableContainer;
2149 m_pTreeView->getListBox().InsertEntry(
2150 _rTableName, _rTableImage, _rTableImage, pDatasourceEntry,
2151 sal_True /*ChildrenOnDemand*/, LIST_APPEND, pTablesData );
2155 // -------------------------------------------------------------------------
2156 void SbaTableQueryBrowser::initializeTreeModel()
2158 if (m_xDatabaseContext.is())
2160 Image aDBImage, aQueriesImage, aTablesImage;
2161 String sQueriesName, sTablesName;
2163 // fill the model with the names of the registered datasources
2164 Sequence< ::rtl::OUString > aDatasources = m_xDatabaseContext->getElementNames();
2165 const ::rtl::OUString* pIter = aDatasources.getConstArray();
2166 const ::rtl::OUString* pEnd = pIter + aDatasources.getLength();
2167 for (; pIter != pEnd; ++pIter)
2168 implAddDatasource( *pIter, aDBImage, sQueriesName, aQueriesImage, sTablesName, aTablesImage, SharedConnection() );
2171 // -------------------------------------------------------------------------
2172 void SbaTableQueryBrowser::populateTree(const Reference<XNameAccess>& _xNameAccess,
2173 SvLBoxEntry* _pParent,
2174 EntryType _eEntryType)
2176 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pParent->GetUserData());
2177 if(pData) // don't ask if the nameaccess is already set see OnExpandEntry views and tables
2178 pData->xContainer = _xNameAccess;
2182 Sequence< ::rtl::OUString > aNames = _xNameAccess->getElementNames();
2183 const ::rtl::OUString* pIter = aNames.getConstArray();
2184 const ::rtl::OUString* pEnd = pIter + aNames.getLength();
2185 for (; pIter != pEnd; ++pIter)
2187 if( !m_pTreeView->getListBox().GetEntryPosByName(*pIter,_pParent))
2189 Reference<XNameAccess> xChild(_xNameAccess->getByName(*pIter),UNO_QUERY);
2190 DBTreeListUserData* pEntryData = new DBTreeListUserData;
2191 pEntryData->eType = _eEntryType;
2192 if ( _eEntryType == etQuery && xChild.is() )
2194 pEntryData->eType = etQueryContainer;
2196 implAppendEntry( _pParent, *pIter, pEntryData, pEntryData->eType );
2200 catch(const Exception&)
2202 OSL_FAIL("SbaTableQueryBrowser::populateTree: could not fill the tree");
2206 //------------------------------------------------------------------------------
2207 SvLBoxEntry* SbaTableQueryBrowser::implAppendEntry( SvLBoxEntry* _pParent, const String& _rName, void* _pUserData, EntryType _eEntryType )
2209 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2210 ::std::auto_ptr< ImageProvider > pImageProvider( getImageProviderFor( _pParent ) );
2211 SAL_WNODEPRECATED_DECLARATIONS_POP
2213 Image aImage;
2214 pImageProvider->getImages( _rName, getDatabaseObjectType( _eEntryType ), aImage );
2216 SvLBoxEntry* pNewEntry = m_pTreeView->getListBox().InsertEntry( _rName, _pParent, _eEntryType == etQueryContainer , LIST_APPEND, _pUserData );
2218 m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImage );
2219 m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImage );
2221 return pNewEntry;
2224 //------------------------------------------------------------------------------
2225 IMPL_LINK(SbaTableQueryBrowser, OnExpandEntry, SvLBoxEntry*, _pParent)
2227 if (_pParent->HasChildren())
2228 // nothing to to ...
2229 return 1L;
2231 SvLBoxEntry* pFirstParent = m_pTreeView->getListBox().GetRootLevelParent(_pParent);
2232 OSL_ENSURE(pFirstParent,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!");
2234 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >(_pParent->GetUserData());
2235 OSL_ENSURE(pData,"SbaTableQueryBrowser::OnExpandEntry: No user data!");
2236 #if OSL_DEBUG_LEVEL > 0
2237 SvLBoxString* pString = static_cast<SvLBoxString*>(pFirstParent->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2238 OSL_ENSURE(pString,"SbaTableQueryBrowser::OnExpandEntry: No string item!");
2239 #endif
2241 if (etTableContainer == pData->eType)
2243 WaitObject aWaitCursor(getBrowserView());
2245 // it could be that we already have a connection
2246 SharedConnection xConnection;
2247 ensureConnection( pFirstParent, xConnection );
2249 if ( xConnection.is() )
2251 SQLExceptionInfo aInfo;
2254 Reference< XWarningsSupplier > xWarnings(xConnection, UNO_QUERY);
2255 if (xWarnings.is())
2256 xWarnings->clearWarnings();
2258 // first insert the views because the tables can also include
2259 // views but that time the bitmap is the wrong one
2260 // the nameaccess will be overwriten in populateTree
2261 Reference<XViewsSupplier> xViewSup(xConnection,UNO_QUERY);
2262 if(xViewSup.is())
2263 populateTree( xViewSup->getViews(), _pParent, etTableOrView );
2265 Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY);
2266 if(xTabSup.is())
2268 populateTree( xTabSup->getTables(), _pParent, etTableOrView );
2269 Reference<XContainer> xCont(xTabSup->getTables(),UNO_QUERY);
2270 if(xCont.is())
2271 // add as listener to know when elements are inserted or removed
2272 xCont->addContainerListener(this);
2275 if (xWarnings.is())
2277 SQLExceptionInfo aWarnings(xWarnings->getWarnings());
2278 #if 0
2279 // Obviously this if test is always false. So to avoid a Clang warning
2280 // "use of logical '&&' with constant operand" I put this in #if
2281 // 0. Yeah, I know it is fairly likely nobody will ever read this
2282 // comment and make a decision what to do here, so I could as well
2283 // have just binned this...
2284 if (aWarnings.isValid() && sal_False)
2286 SQLContext aContext;
2287 aContext.Message = String(ModuleRes(STR_OPENTABLES_WARNINGS));
2288 aContext.Details = String(ModuleRes(STR_OPENTABLES_WARNINGS_DETAILS));
2289 aContext.NextException = aWarnings.get();
2290 aWarnings = aContext;
2291 showError(aWarnings);
2293 #endif
2294 // TODO: we need a better concept for these warnings:
2295 // something like "don't show any warnings for this datasource, again" would be nice
2296 // But this requires an extension of the InteractionHandler and an additional property on the data source
2299 catch(const SQLContext& e) { aInfo = e; }
2300 catch(const SQLWarning& e) { aInfo = e; }
2301 catch(const SQLException& e) { aInfo = e; }
2302 catch(const WrappedTargetException& e)
2304 SQLException aSql;
2305 if(e.TargetException >>= aSql)
2306 aInfo = aSql;
2307 else
2308 OSL_FAIL("SbaTableQueryBrowser::OnExpandEntry: something strange happended!");
2310 catch( const Exception& )
2312 DBG_UNHANDLED_EXCEPTION();
2314 if (aInfo.isValid())
2315 showError(aInfo);
2317 else
2318 return 0L;
2319 // 0 indicates that an error occurred
2321 else
2322 { // we have to expand the queries or bookmarks
2323 if (ensureEntryObject(_pParent))
2325 DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( _pParent->GetUserData() );
2326 Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
2327 populateTree( xCollection, _pParent, etQuery );
2330 return 1L;
2333 //------------------------------------------------------------------------------
2334 sal_Bool SbaTableQueryBrowser::ensureEntryObject( SvLBoxEntry* _pEntry )
2336 OSL_ENSURE(_pEntry, "SbaTableQueryBrowser::ensureEntryObject: invalid argument!");
2337 if (!_pEntry)
2338 return sal_False;
2340 EntryType eType = getEntryType( _pEntry );
2342 // the user data of the entry
2343 DBTreeListUserData* pEntryData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData());
2344 OSL_ENSURE(pEntryData,"ensureEntryObject: user data should already be set!");
2346 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(_pEntry);
2348 sal_Bool bSuccess = sal_False;
2349 switch (eType)
2351 case etQueryContainer:
2352 if ( pEntryData->xContainer.is() )
2354 // nothing to do
2355 bSuccess = sal_True;
2356 break;
2360 SvLBoxEntry* pParent = m_pTreeView->getListBox().GetParent(_pEntry);
2361 if ( pParent != pDataSourceEntry )
2363 SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING);
2364 OSL_ENSURE(pString,"There must be a string item!");
2365 ::rtl::OUString aName(pString->GetText());
2366 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pParent->GetUserData());
2369 Reference< XNameAccess > xNameAccess(pData->xContainer,UNO_QUERY);
2370 if ( xNameAccess.is() )
2371 pEntryData->xContainer.set(xNameAccess->getByName(aName),UNO_QUERY);
2373 catch(const Exception& )
2375 DBG_UNHANDLED_EXCEPTION();
2378 bSuccess = pEntryData->xContainer.is();
2380 else
2384 Reference< XQueryDefinitionsSupplier > xQuerySup;
2385 m_xDatabaseContext->getByName( getDataSourceAcessor( pDataSourceEntry ) ) >>= xQuerySup;
2386 if (xQuerySup.is())
2388 Reference< XNameAccess > xQueryDefs = xQuerySup->getQueryDefinitions();
2389 Reference< XContainer > xCont(xQueryDefs, UNO_QUERY);
2390 if (xCont.is())
2391 // add as listener to get notified if elements are inserted or removed
2392 xCont->addContainerListener(this);
2394 pEntryData->xContainer = xQueryDefs;
2395 bSuccess = pEntryData->xContainer.is();
2397 else {
2398 OSL_FAIL("SbaTableQueryBrowser::ensureEntryObject: no XQueryDefinitionsSupplier interface!");
2401 catch( const Exception& )
2403 DBG_UNHANDLED_EXCEPTION();
2407 break;
2409 default:
2410 OSL_FAIL("SbaTableQueryBrowser::ensureEntryObject: ooops ... missing some implementation here!");
2411 // TODO ...
2412 break;
2415 return bSuccess;
2417 //------------------------------------------------------------------------------
2418 sal_Bool SbaTableQueryBrowser::implSelect(const ::svx::ODataAccessDescriptor& _rDescriptor,sal_Bool _bSelectDirect)
2420 // extract the props
2421 ::rtl::OUString sDataSource;
2422 ::rtl::OUString sCommand;
2423 sal_Int32 nCommandType = CommandType::COMMAND;
2424 sal_Bool bEscapeProcessing = sal_True;
2425 extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
2427 // select it
2428 return implSelect( sDataSource, sCommand, nCommandType, bEscapeProcessing, SharedConnection(), _bSelectDirect );
2431 //------------------------------------------------------------------------------
2432 sal_Bool SbaTableQueryBrowser::implLoadAnything(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand,
2433 const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing, const SharedConnection& _rxConnection)
2437 Reference<XPropertySet> xProp( getRowSet(), UNO_QUERY_THROW );
2438 Reference< XLoadable > xLoadable( xProp, UNO_QUERY_THROW );
2439 // the values allowing the RowSet to re-execute
2440 xProp->setPropertyValue(PROPERTY_DATASOURCENAME, makeAny(_rDataSourceName));
2441 if(_rxConnection.is())
2442 xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( _rxConnection.getTyped() ) );
2444 // set this _before_ setting the connection, else the rowset would rebuild it ...
2445 xProp->setPropertyValue(PROPERTY_COMMAND_TYPE, makeAny(_nCommandType));
2446 xProp->setPropertyValue(PROPERTY_COMMAND, makeAny(_rCommand));
2447 xProp->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, ::cppu::bool2any(_bEscapeProcessing));
2448 if ( m_bPreview )
2450 xProp->setPropertyValue(PROPERTY_FETCHDIRECTION, makeAny(FetchDirection::FORWARD));
2453 // the formatter depends on the data source we're working on, so rebuild it here ...
2454 initFormatter();
2456 // switch the grid to design mode while loading
2457 getBrowserView()->getGridControl()->setDesignMode(sal_True);
2458 InitializeForm( xProp );
2460 sal_Bool bSuccess = sal_True;
2464 Reference< XNameContainer > xColContainer(getFormComponent(), UNO_QUERY);
2465 // first we have to clear the grid
2466 clearGridColumns(xColContainer);
2468 FormErrorHelper aHelper(this);
2469 // load the form
2470 bSuccess = reloadForm(xLoadable);
2472 // initialize the model
2473 InitializeGridModel(getFormComponent());
2475 Any aVal = xProp->getPropertyValue(PROPERTY_ISNEW);
2476 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2478 // then set the default values and the parameters given from the parent
2479 Reference< XReset> xReset(xProp, UNO_QUERY);
2480 xReset->reset();
2483 if ( m_bPreview )
2484 initializePreviewMode();
2486 LoadFinished(sal_True);
2489 InvalidateAll();
2490 return bSuccess;
2492 catch( const SQLException& )
2494 Any aException( ::cppu::getCaughtException() );
2495 showError( SQLExceptionInfo( aException ) );
2497 catch( const WrappedTargetException& e )
2499 SQLException aSql;
2500 if ( e.TargetException.isExtractableTo( ::cppu::UnoType< SQLException >::get() ) )
2501 showError( SQLExceptionInfo( e.TargetException ) );
2502 else
2504 DBG_UNHANDLED_EXCEPTION();
2507 catch(const Exception&)
2509 DBG_UNHANDLED_EXCEPTION();
2512 InvalidateAll();
2513 return sal_False;
2516 //------------------------------------------------------------------------------
2517 sal_Bool SbaTableQueryBrowser::implSelect(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand,
2518 const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing,
2519 const SharedConnection& _rxConnection
2520 ,sal_Bool _bSelectDirect)
2522 if (_rDataSourceName.getLength() && _rCommand.getLength() && (-1 != _nCommandType))
2524 SvLBoxEntry* pDataSource = NULL;
2525 SvLBoxEntry* pCommandType = NULL;
2526 SvLBoxEntry* pCommand = getObjectEntry( _rDataSourceName, _rCommand, _nCommandType, &pDataSource, &pCommandType, sal_True, _rxConnection );
2528 if (pCommand)
2530 bool bSuccess = true;
2531 if ( _bSelectDirect )
2533 bSuccess = implSelect( pCommand );
2535 else
2537 m_pTreeView->getListBox().Select( pCommand );
2540 if ( bSuccess )
2542 m_pTreeView->getListBox().MakeVisible(pCommand);
2543 m_pTreeView->getListBox().SetCursor(pCommand);
2546 else if (!pCommandType)
2548 if ( m_pCurrentlyDisplayed )
2549 { // tell the old entry (if any) it has been deselected
2550 selectPath(m_pCurrentlyDisplayed, sal_False);
2551 m_pCurrentlyDisplayed = NULL;
2554 // we have a command and need to display this in the rowset
2555 return implLoadAnything(_rDataSourceName, _rCommand, _nCommandType, _bEscapeProcessing, _rxConnection);
2558 return sal_False;
2561 //------------------------------------------------------------------------------
2562 IMPL_LINK(SbaTableQueryBrowser, OnSelectionChange, void*, /*NOINTERESTEDIN*/)
2564 return implSelect( m_pTreeView->getListBox().FirstSelected() ) ? 1L : 0L;
2566 //------------------------------------------------------------------------------
2567 SvLBoxEntry* SbaTableQueryBrowser::implGetConnectionEntry(SvLBoxEntry* _pEntry) const
2569 SvLBoxEntry* pCurrentEntry = _pEntry;
2570 DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() );
2571 while(pEntryData->eType != etDatasource )
2573 pCurrentEntry = m_pTreeModel->GetParent(pCurrentEntry);
2574 pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() );
2576 return pCurrentEntry;
2578 //------------------------------------------------------------------------------
2579 bool SbaTableQueryBrowser::implSelect( SvLBoxEntry* _pEntry )
2581 if ( !_pEntry )
2582 return false;
2584 DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() );
2585 switch (pEntryData->eType)
2587 case etTableOrView:
2588 case etQuery:
2589 break;
2590 default:
2591 // nothing to do
2592 return false;
2595 OSL_ENSURE(m_pTreeModel->HasParent(_pEntry), "SbaTableQueryBrowser::implSelect: invalid entry (1)!");
2596 OSL_ENSURE(m_pTreeModel->HasParent(m_pTreeModel->GetParent(_pEntry)), "SbaTableQueryBrowser::implSelect: invalid entry (2)!");
2598 // get the entry for the tables or queries
2599 SvLBoxEntry* pContainer = m_pTreeModel->GetParent(_pEntry);
2600 DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2602 // get the entry for the datasource
2603 SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer);
2604 DBTreeListUserData* pConData = static_cast<DBTreeListUserData*>(pConnection->GetUserData());
2606 // reinitialize the rowset
2607 // but first check if it is necessary
2608 // get all old properties
2609 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
2610 ::rtl::OUString aOldName;
2611 xRowSetProps->getPropertyValue(PROPERTY_COMMAND) >>= aOldName;
2612 sal_Int32 nOldType = 0;
2613 xRowSetProps->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nOldType;
2614 Reference<XConnection> xOldConnection(xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
2616 // the name of the table or query
2617 SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING);
2618 OSL_ENSURE(pString,"There must be a string item!");
2619 const ::rtl::OUString sSimpleName = pString->GetText();
2620 ::rtl::OUStringBuffer sNameBuffer(sSimpleName);
2621 if ( etQueryContainer == pContainerData->eType )
2623 SvLBoxEntry* pTemp = pContainer;
2624 while( m_pTreeModel->GetParent(pTemp) != pConnection )
2626 sNameBuffer.insert(0,sal_Unicode('/'));
2627 pString = (SvLBoxString*)pTemp->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING);
2628 OSL_ENSURE(pString,"There must be a string item!");
2629 sNameBuffer.insert(0,pString->GetText());
2630 pTemp = m_pTreeModel->GetParent(pTemp);
2633 ::rtl::OUString aName = sNameBuffer.makeStringAndClear();
2635 sal_Int32 nCommandType = ( etTableContainer == pContainerData->eType)
2636 ? CommandType::TABLE
2637 : CommandType::QUERY;
2639 // check if need to rebuild the rowset
2640 sal_Bool bRebuild = ( xOldConnection != pConData->xConnection )
2641 || ( nOldType != nCommandType )
2642 || ( aName != aOldName );
2644 Reference< ::com::sun::star::form::XLoadable > xLoadable = getLoadable();
2645 bRebuild |= !xLoadable->isLoaded();
2646 bool bSuccess = true;
2647 if ( bRebuild )
2651 WaitObject aWaitCursor(getBrowserView());
2653 // tell the old entry it has been deselected
2654 selectPath(m_pCurrentlyDisplayed, sal_False);
2655 m_pCurrentlyDisplayed = NULL;
2657 // not really loaded
2658 m_pCurrentlyDisplayed = _pEntry;
2659 // tell the new entry it has been selected
2660 selectPath(m_pCurrentlyDisplayed, sal_True);
2662 // get the name of the data source currently selected
2663 ensureConnection( m_pCurrentlyDisplayed, pConData->xConnection );
2665 if ( !pConData->xConnection.is() )
2667 unloadAndCleanup( sal_False );
2668 return false;
2671 Reference<XNameAccess> xNameAccess;
2672 switch(nCommandType)
2674 case CommandType::TABLE:
2676 // only for tables
2677 if ( !pContainerData->xContainer.is() )
2679 Reference<XTablesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2680 if(xSup.is())
2681 xNameAccess = xSup->getTables();
2683 pContainerData->xContainer = xNameAccess;
2685 else
2686 xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2688 break;
2689 case CommandType::QUERY:
2691 if ( pContainerData->xContainer.is() )
2692 xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2693 else
2695 Reference<XQueriesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2696 if(xSup.is())
2697 xNameAccess = xSup->getQueries();
2700 break;
2702 String sStatus(ModuleRes( CommandType::TABLE == nCommandType ? STR_LOADING_TABLE : STR_LOADING_QUERY ));
2703 sStatus.SearchAndReplaceAscii("$name$", aName);
2704 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sStatus);
2707 sal_Bool bEscapeProcessing = sal_True;
2708 if(xNameAccess.is() && xNameAccess->hasByName(sSimpleName))
2710 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData());
2711 if ( !pData->xObjectProperties.is() )
2713 Reference<XInterface> xObject;
2714 if(xNameAccess->getByName(sSimpleName) >>= xObject) // remember the table or query object
2716 pData->xObjectProperties = pData->xObjectProperties.query( xObject );
2717 // if the query contains a parameterized statement and preview is enabled we won't get any data.
2718 if ( nCommandType == CommandType::QUERY && xObject.is() )
2720 Reference<XPropertySet> xObjectProps(xObject,UNO_QUERY);
2721 xObjectProps->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bEscapeProcessing;
2722 if ( m_bPreview )
2724 ::rtl::OUString sSql;
2725 xObjectProps->getPropertyValue(PROPERTY_COMMAND) >>= sSql;
2726 Reference< XMultiServiceFactory > xFactory( pConData->xConnection, UNO_QUERY );
2727 if (xFactory.is())
2731 Reference<XSingleSelectQueryAnalyzer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
2732 if ( xAnalyzer.is() )
2734 xAnalyzer->setQuery(sSql);
2735 Reference<XParametersSupplier> xParSup(xAnalyzer,UNO_QUERY);
2736 if ( xParSup->getParameters()->getCount() > 0 )
2738 String sFilter = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE "));
2739 sFilter = sFilter + xAnalyzer->getFilter();
2740 String sReplace(sSql);
2741 sReplace.SearchAndReplace(sFilter,String());
2742 xAnalyzer->setQuery(sReplace);
2743 Reference<XSingleSelectQueryComposer> xComposer(xAnalyzer,UNO_QUERY);
2744 xComposer->setFilter(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0=1")));
2745 aName = xAnalyzer->getQuery();
2746 nCommandType = CommandType::COMMAND;
2750 catch (Exception&)
2752 DBG_UNHANDLED_EXCEPTION();
2761 String sDataSourceName( getDataSourceAcessor( pConnection ) );
2762 bSuccess = implLoadAnything( sDataSourceName, aName, nCommandType, bEscapeProcessing, pConData->xConnection );
2763 if ( !bSuccess )
2764 { // clean up
2765 criticalFail();
2768 catch(const SQLException& e)
2770 showError(SQLExceptionInfo(e));
2771 // reset the values
2772 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2773 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2775 catch(WrappedTargetException& e)
2777 SQLException aSql;
2778 if(e.TargetException >>= aSql)
2779 showError(SQLExceptionInfo(aSql));
2780 else
2781 OSL_FAIL("SbaTableQueryBrowser::implSelect: something strange happended!");
2782 // reset the values
2783 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2784 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2786 catch(const Exception&)
2788 // reset the values
2789 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2790 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2793 return bSuccess;
2796 // -----------------------------------------------------------------------------
2797 SvLBoxEntry* SbaTableQueryBrowser::getEntryFromContainer(const Reference<XNameAccess>& _rxNameAccess)
2799 DBTreeListBox& rListBox = m_pTreeView->getListBox();
2800 SvLBoxEntry* pContainer = NULL;
2801 SvLBoxEntry* pDSLoop = rListBox.FirstChild(NULL);
2802 while (pDSLoop)
2804 pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_QUERIES);
2805 DBTreeListUserData* pQueriesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2806 if ( pQueriesData && pQueriesData->xContainer == _rxNameAccess )
2807 break;
2809 pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_TABLES);
2810 DBTreeListUserData* pTablesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2811 if ( pTablesData && pTablesData->xContainer == _rxNameAccess )
2812 break;
2814 pDSLoop = rListBox.NextSibling(pDSLoop);
2815 pContainer = NULL;
2817 return pContainer;
2820 // -------------------------------------------------------------------------
2821 void SAL_CALL SbaTableQueryBrowser::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException)
2823 SolarMutexGuard aSolarGuard;
2825 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2826 // first search for a definition container where we can insert this element
2828 SvLBoxEntry* pEntry = getEntryFromContainer(xNames);
2829 if(pEntry) // found one
2831 // insert the new entry into the tree
2832 DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pEntry->GetUserData());
2833 OSL_ENSURE(pContainerData, "elementInserted: There must be user data for this type!");
2835 DBTreeListUserData* pNewData = new DBTreeListUserData;
2836 sal_Bool bIsTable = etTableContainer == pContainerData->eType;
2837 if ( bIsTable )
2839 _rEvent.Element >>= pNewData->xObjectProperties;// remember the new element
2840 pNewData->eType = etTableOrView;
2842 else
2844 if ((sal_Int32)m_pTreeView->getListBox().GetChildCount(pEntry) < ( xNames->getElementNames().getLength() - 1 ) )
2846 // the item inserts its children on demand, but it has not been expanded yet. So ensure here and
2847 // now that it has all items
2848 populateTree(xNames, pEntry, etQuery );
2850 pNewData->eType = etQuery;
2852 implAppendEntry( pEntry, ::comphelper::getString( _rEvent.Accessor ), pNewData, pNewData->eType );
2854 else
2855 SbaXDataBrowserController::elementInserted(_rEvent);
2857 // -------------------------------------------------------------------------
2858 sal_Bool SbaTableQueryBrowser::isCurrentlyDisplayedChanged(const String& _sName,SvLBoxEntry* _pContainer)
2860 return m_pCurrentlyDisplayed
2861 && getEntryType(m_pCurrentlyDisplayed) == getChildType(_pContainer)
2862 && m_pTreeView->getListBox().GetParent(m_pCurrentlyDisplayed) == _pContainer
2863 && m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed) == _sName;
2865 // -------------------------------------------------------------------------
2866 void SAL_CALL SbaTableQueryBrowser::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException)
2868 SolarMutexGuard aSolarGuard;
2870 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2871 // get the top-level representing the removed data source
2872 // and search for the queries and tables
2873 SvLBoxEntry* pContainer = getEntryFromContainer(xNames);
2874 if ( pContainer )
2875 { // a query or table has been removed
2876 String aName = ::comphelper::getString(_rEvent.Accessor).getStr();
2878 if ( isCurrentlyDisplayedChanged( aName, pContainer) )
2879 { // the element displayed currently has been replaced
2881 // we need to remember the old value
2882 SvLBoxEntry* pTemp = m_pCurrentlyDisplayed;
2884 // unload
2885 unloadAndCleanup( sal_False ); // don't dispose the connection
2887 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData());
2888 pTemp->SetUserData(NULL);
2889 delete pData;
2890 // the data could be null because we have a table which isn't correct
2891 m_pTreeModel->Remove(pTemp);
2893 else
2895 // remove the entry from the model
2896 SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer);
2897 while(pChild)
2899 if (m_pTreeView->getListBox().GetEntryText(pChild) == aName)
2901 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData());
2902 pChild->SetUserData(NULL);
2903 delete pData;
2904 m_pTreeModel->Remove(pChild);
2905 break;
2907 pChild = m_pTreeModel->NextSibling(pChild);
2911 // maybe the object which is part of the document data source has been removed
2912 checkDocumentDataSource();
2914 else
2915 SbaXDataBrowserController::elementRemoved(_rEvent);
2918 // -------------------------------------------------------------------------
2919 void SAL_CALL SbaTableQueryBrowser::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException)
2921 SolarMutexGuard aSolarGuard;
2923 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2924 SvLBoxEntry* pContainer = getEntryFromContainer(xNames);
2925 if ( pContainer )
2926 { // a table or query as been replaced
2927 String aName = ::comphelper::getString(_rEvent.Accessor).getStr();
2929 if ( isCurrentlyDisplayedChanged( aName, pContainer) )
2930 { // the element displayed currently has been replaced
2932 // we need to remember the old value
2933 SvLBoxEntry* pTemp = m_pCurrentlyDisplayed;
2934 unloadAndCleanup( sal_False ); // don't dispose the connection
2936 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData());
2937 if (pData)
2939 if ( etTableOrView == pData->eType )
2940 { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2941 _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2943 else
2945 pTemp->SetUserData(NULL);
2946 delete pData;
2950 else
2952 // find the entry for this name
2953 SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer);
2954 while(pChild)
2956 if (m_pTreeView->getListBox().GetEntryText(pChild) == aName)
2958 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData());
2959 if (pData)
2961 if ( etTableOrView == pData->eType )
2962 { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2963 _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2965 else
2967 pChild->SetUserData(NULL);
2968 delete pData;
2971 break;
2973 pChild = m_pTreeModel->NextSibling(pChild);
2977 // maybe the object which is part of the document data source has been removed
2978 checkDocumentDataSource();
2980 else if (xNames.get() == m_xDatabaseContext.get())
2981 { // a datasource has been replaced in the context
2982 OSL_FAIL("SbaTableQueryBrowser::elementReplaced: no support for replaced data sources!");
2983 // very suspicious: the database context should not allow to replace data source, only to register
2984 // and revoke them
2986 else
2987 SbaXDataBrowserController::elementReplaced(_rEvent);
2990 // -------------------------------------------------------------------------
2991 void SbaTableQueryBrowser::impl_releaseConnection( SharedConnection& _rxConnection )
2993 // remove as event listener
2994 Reference< XComponent > xComponent( _rxConnection, UNO_QUERY );
2995 if ( xComponent.is() )
2997 Reference< XEventListener > xListener( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY );
2998 xComponent->removeEventListener( xListener );
3003 // temporary (hopefully!) hack for #i55274#
3004 Reference< XFlushable > xFlush( _rxConnection, UNO_QUERY );
3005 if ( xFlush.is() )
3006 xFlush->flush();
3008 catch( const Exception& )
3010 DBG_UNHANDLED_EXCEPTION();
3013 // clear
3014 _rxConnection.clear();
3015 // will implicitly dispose if we have the ownership, since xConnection is a SharedConnection
3018 // -------------------------------------------------------------------------
3019 void SbaTableQueryBrowser::disposeConnection( SvLBoxEntry* _pDSEntry )
3021 OSL_ENSURE( _pDSEntry, "SbaTableQueryBrowser::disposeConnection: invalid entry (NULL)!" );
3022 OSL_ENSURE( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::disposeConnection: invalid entry (not top-level)!" );
3024 if ( _pDSEntry )
3026 DBTreeListUserData* pTreeListData = static_cast< DBTreeListUserData* >( _pDSEntry->GetUserData() );
3027 if ( pTreeListData )
3028 impl_releaseConnection( pTreeListData->xConnection );
3032 // -------------------------------------------------------------------------
3033 void SbaTableQueryBrowser::closeConnection(SvLBoxEntry* _pDSEntry,sal_Bool _bDisposeConnection)
3035 OSL_ENSURE(_pDSEntry, "SbaTableQueryBrowser::closeConnection: invalid entry (NULL)!");
3036 OSL_ENSURE( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::closeConnection: invalid entry (not top-level)!");
3038 // if one of the entries of the given DS is displayed currently, unload the form
3039 if (m_pCurrentlyDisplayed && (m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed) == _pDSEntry))
3040 unloadAndCleanup(_bDisposeConnection);
3042 // collapse the query/table container
3043 for (SvLBoxEntry* pContainers = m_pTreeModel->FirstChild(_pDSEntry); pContainers; pContainers= m_pTreeModel->NextSibling(pContainers))
3045 SvLBoxEntry* pElements = m_pTreeModel->FirstChild(pContainers);
3046 if ( pElements )
3047 m_pTreeView->getListBox().Collapse(pContainers);
3048 m_pTreeView->getListBox().EnableExpandHandler(pContainers);
3049 // and delete their children (they are connection-relative)
3050 for (; pElements; )
3052 SvLBoxEntry* pRemove = pElements;
3053 pElements= m_pTreeModel->NextSibling(pElements);
3054 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pRemove->GetUserData());
3055 pRemove->SetUserData(NULL);
3056 delete pData;
3057 m_pTreeModel->Remove(pRemove);
3060 // collapse the entry itself
3061 m_pTreeView->getListBox().Collapse(_pDSEntry);
3063 // dispose/reset the connection
3064 if ( _bDisposeConnection )
3065 disposeConnection( _pDSEntry );
3068 // -------------------------------------------------------------------------
3069 void SbaTableQueryBrowser::unloadAndCleanup( sal_Bool _bDisposeConnection )
3071 if (!m_pCurrentlyDisplayed)
3072 // nothing to do
3073 return;
3075 SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed);
3077 // de-select the path for the currently displayed table/query
3078 if (m_pCurrentlyDisplayed)
3080 selectPath(m_pCurrentlyDisplayed, sal_False);
3082 m_pCurrentlyDisplayed = NULL;
3086 // get the active connection. We need to dispose it.
3087 Reference< XPropertySet > xRowSetProps(getRowSet(),UNO_QUERY);
3088 Reference< XConnection > xConn;
3089 xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION) >>= xConn;
3090 #if OSL_DEBUG_LEVEL > 1
3092 Reference< XComponent > xComp;
3093 ::cppu::extractInterface(xComp, xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION));
3095 #endif
3097 // unload the form
3098 Reference< XLoadable > xLoadable = getLoadable();
3099 if (xLoadable->isLoaded())
3100 xLoadable->unload();
3102 // clear the grid control
3103 Reference< XNameContainer > xConta(getControlModel(),UNO_QUERY);
3104 clearGridColumns(xConta);
3106 // dispose the connection
3107 if(_bDisposeConnection)
3108 disposeConnection( pDSEntry );
3110 catch(SQLException& e)
3112 showError(SQLExceptionInfo(e));
3114 catch(WrappedTargetException& e)
3116 SQLException aSql;
3117 if(e.TargetException >>= aSql)
3118 showError(SQLExceptionInfo(aSql));
3119 else
3120 OSL_FAIL("SbaTableQueryBrowser::unloadAndCleanup: something strange happended!");
3122 catch(const Exception&)
3124 OSL_FAIL("SbaTableQueryBrowser::unloadAndCleanup: could not reset the form");
3128 // -------------------------------------------------------------------------
3129 namespace
3131 Reference< XInterface > lcl_getDataSource( const Reference< XNameAccess >& _rxDatabaseContext,
3132 const ::rtl::OUString& _rDataSourceName, const Reference< XConnection >& _rxConnection )
3134 Reference< XDataSource > xDataSource;
3137 if ( !_rDataSourceName.isEmpty() && _rxDatabaseContext->hasByName( _rDataSourceName ) )
3138 xDataSource.set( _rxDatabaseContext->getByName( _rDataSourceName ), UNO_QUERY_THROW );
3140 if ( !xDataSource.is() )
3142 Reference< XChild > xConnAsChild( _rxConnection, UNO_QUERY );
3143 if ( xConnAsChild.is() )
3144 xDataSource.set( xConnAsChild->getParent(), UNO_QUERY_THROW );
3147 catch( const Exception& )
3149 DBG_UNHANDLED_EXCEPTION();
3151 return xDataSource.get();
3155 // -------------------------------------------------------------------------
3156 void SbaTableQueryBrowser::impl_initialize()
3158 SolarMutexGuard aGuard;
3159 // doin' a lot of VCL stuff here -> lock the SolarMutex
3161 // first initialize the parent
3162 SbaXDataBrowserController::impl_initialize();
3164 Reference<XConnection> xForeignConnection;
3165 Reference< XFrame > xFrame;
3167 ::rtl::OUString aTableName, aCatalogName, aSchemaName;
3169 sal_Bool bEsacpeProcessing = sal_True;
3170 sal_Int32 nInitialDisplayCommandType = CommandType::COMMAND;
3171 ::rtl::OUString sInitialDataSourceName;
3172 ::rtl::OUString sInitialCommand;
3174 const NamedValueCollection& rArguments( getInitParams() );
3176 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_DATASOURCENAME, sInitialDataSourceName );
3177 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND_TYPE, nInitialDisplayCommandType );
3178 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND, sInitialCommand );
3179 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, xForeignConnection );
3180 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_CATALOGNAME, aCatalogName );
3181 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_SCHEMANAME, aSchemaName );
3182 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_TABLENAME, aTableName );
3183 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, bEsacpeProcessing );
3184 rArguments.get_ensureType( "Frame", xFrame );
3185 rArguments.get_ensureType( (::rtl::OUString)PROPERTY_SHOWMENU, m_bShowMenu );
3187 // disable the browser if either of ShowTreeViewButton (compatibility name) or EnableBrowser
3188 // is present and set to FALSE
3189 sal_Bool bDisableBrowser = ( sal_False == rArguments.getOrDefault( "ShowTreeViewButton", sal_True ) ) // compatibility name
3190 || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_True ) );
3191 OSL_ENSURE( !rArguments.has( "ShowTreeViewButton" ),
3192 "SbaTableQueryBrowser::impl_initialize: ShowTreeViewButton is superseded by EnableBrowser!" );
3193 m_bEnableBrowser = !bDisableBrowser;
3195 // hide the tree view it is disabled in general, or if the settings tell to hide it initially
3196 sal_Bool bHideTreeView = ( !m_bEnableBrowser )
3197 || ( sal_False == rArguments.getOrDefault( "ShowTreeView", sal_True ) ) // compatibility name
3198 || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_SHOW_BROWSER, sal_True ) );
3199 OSL_ENSURE( !rArguments.has( "ShowTreeView" ),
3200 "SbaTableQueryBrowser::impl_initialize: ShowTreeView is superseded by ShowBrowser!" );
3202 if ( bHideTreeView )
3203 hideExplorer();
3204 else
3205 showExplorer();
3207 if ( m_bPreview )
3211 Sequence< ::rtl::OUString> aProperties(5);
3212 Sequence< Any> aValues(5);
3214 ::rtl::OUString* pStringIter = aProperties.getArray();
3215 Any* pValueIter = aValues.getArray();
3216 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlwaysShowCursor"));
3217 *pValueIter++ <<= sal_False;
3218 *pStringIter++ = PROPERTY_BORDER;
3219 *pValueIter++ <<= sal_Int16(0);
3221 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasNavigationBar"));
3222 *pValueIter++ <<= sal_False;
3223 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasRecordMarker"));
3224 *pValueIter++ <<= sal_False;
3226 *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tabstop"));
3227 *pValueIter++ <<= sal_False;
3229 Reference< XMultiPropertySet > xFormMultiSet(getFormComponent(), UNO_QUERY);
3230 if ( xFormMultiSet.is() )
3231 xFormMultiSet->setPropertyValues(aProperties, aValues);
3233 catch(const Exception&)
3235 DBG_UNHANDLED_EXCEPTION();
3239 // are we loaded into a (sub)frame of an embedded document (i.e. a form belonging to a database
3240 // document)?
3241 sal_Bool bSubFrameOfEmbeddedDocument = sal_False;
3242 if ( xFrame.is() )
3244 Reference<XFramesSupplier> xSup = xFrame->getCreator();
3245 Reference<XController> xCont = xSup.is() ? xSup->getController() : Reference<XController>();
3247 bSubFrameOfEmbeddedDocument = xCont.is() && ::dbtools::isEmbeddedInDatabase( xCont->getModel(), xForeignConnection );
3250 // if we have a connection at this point, it was either passed from outside, our
3251 // determined from a outer DB document. In both cases, do not dispose it later on.
3252 SharedConnection xConnection( xForeignConnection, SharedConnection::NoTakeOwnership );
3254 // should we display all registered databases in the left hand side tree?
3255 // or only *one* special?
3256 sal_Bool bLimitedTreeEntries = sal_False;
3257 // if we're part of a frame which is a secondary frame of a database document, then only
3258 // display the database for this document, not all registered ones
3259 bLimitedTreeEntries |= bSubFrameOfEmbeddedDocument;
3260 // if the tree view is not to be displayed at all, then only display the data source
3261 // which was given as initial selection
3262 bLimitedTreeEntries |= ( m_bEnableBrowser != sal_True );
3264 if ( bLimitedTreeEntries )
3266 if ( xConnection.is() )
3268 startConnectionListening( xConnection );
3270 // if no initial name was given, try to obtain one from the data source
3271 if ( sInitialDataSourceName.isEmpty() )
3273 Reference< XChild > xChild( xConnection, UNO_QUERY );
3274 Reference< XPropertySet > xDataSourceProperties;
3275 if ( xChild.is() )
3276 xDataSourceProperties = xDataSourceProperties.query( xChild->getParent() );
3277 if ( xDataSourceProperties.is() )
3281 OSL_VERIFY( xDataSourceProperties->getPropertyValue( PROPERTY_NAME ) >>= sInitialDataSourceName );
3283 catch( const Exception& )
3285 OSL_FAIL( "SbaTableQueryBrowser::impl_initialize: a connection parent which does not have a 'Name'!??" );
3291 implAddDatasource( sInitialDataSourceName, xConnection );
3292 m_pTreeView->getListBox().Expand( m_pTreeView->getListBox().First() );
3294 else
3295 initializeTreeModel();
3297 if ( m_bEnableBrowser )
3299 m_aDocScriptSupport = ::boost::optional< bool >( false );
3301 else
3303 // we are not used as "browser", but as mere view for a single table/query/command. In particular,
3304 // there is a specific database document which we belong to.
3305 Reference< XOfficeDatabaseDocument > xDocument( getDataSourceOrModel(
3306 lcl_getDataSource( m_xDatabaseContext, sInitialDataSourceName, xConnection ) ), UNO_QUERY );
3307 m_aDocScriptSupport = ::boost::optional< bool >( Reference< XEmbeddedScripts >( xDocument, UNO_QUERY ).is() );
3310 if ( implSelect( sInitialDataSourceName, sInitialCommand, nInitialDisplayCommandType, bEsacpeProcessing, xConnection, sal_True ) )
3314 Reference< XPropertySet > xRowSetProps(getRowSet(), UNO_QUERY);
3315 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_CATALOGNAME,makeAny(aCatalogName));
3316 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_SCHEMANAME,makeAny(aSchemaName));
3317 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_TABLENAME,makeAny(aTableName));
3320 catch(const Exception&)
3322 OSL_FAIL("SbaTableQueryBrowser::impl_initialize: could not set the update related names!");
3326 InvalidateAll();
3329 // -------------------------------------------------------------------------
3330 sal_Bool SbaTableQueryBrowser::haveExplorer() const
3332 return m_pTreeView && m_pTreeView->IsVisible();
3335 // -------------------------------------------------------------------------
3336 void SbaTableQueryBrowser::hideExplorer()
3338 if (!haveExplorer())
3339 return;
3340 if (!getBrowserView())
3341 return;
3343 m_pTreeView->Hide();
3344 m_pSplitter->Hide();
3345 getBrowserView()->Resize();
3347 InvalidateFeature(ID_BROWSER_EXPLORER);
3350 // -------------------------------------------------------------------------
3351 void SbaTableQueryBrowser::showExplorer()
3353 if (haveExplorer())
3354 return;
3356 if (!getBrowserView())
3357 return;
3359 m_pTreeView->Show();
3360 m_pSplitter->Show();
3361 getBrowserView()->Resize();
3363 InvalidateFeature(ID_BROWSER_EXPLORER);
3366 // -----------------------------------------------------------------------------
3367 sal_Bool SbaTableQueryBrowser::ensureConnection(SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection)
3369 SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(_pAnyEntry);
3370 DBTreeListUserData* pDSData =
3371 pDSEntry
3372 ? static_cast<DBTreeListUserData*>(pDSEntry->GetUserData())
3373 : NULL;
3375 return ensureConnection( pDSEntry, pDSData, _rConnection );
3378 // -----------------------------------------------------------------------------
3379 SAL_WNODEPRECATED_DECLARATIONS_PUSH
3380 ::std::auto_ptr< ImageProvider > SbaTableQueryBrowser::getImageProviderFor( SvLBoxEntry* _pAnyEntry )
3382 ::std::auto_ptr< ImageProvider > pImageProvider( new ImageProvider );
3383 SharedConnection xConnection;
3384 if ( getExistentConnectionFor( _pAnyEntry, xConnection ) )
3385 pImageProvider.reset( new ImageProvider( xConnection ) );
3386 return pImageProvider;
3388 SAL_WNODEPRECATED_DECLARATIONS_POP
3390 // -----------------------------------------------------------------------------
3391 sal_Bool SbaTableQueryBrowser::getExistentConnectionFor( SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection )
3393 SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent( _pAnyEntry );
3394 DBTreeListUserData* pDSData =
3395 pDSEntry
3396 ? static_cast< DBTreeListUserData* >( pDSEntry->GetUserData() )
3397 : NULL;
3398 if ( pDSData )
3399 _rConnection = pDSData->xConnection;
3400 return _rConnection.is();
3403 #if OSL_DEBUG_LEVEL > 0
3404 // -----------------------------------------------------------------------------
3405 bool SbaTableQueryBrowser::impl_isDataSourceEntry( SvLBoxEntry* _pEntry ) const
3407 return m_pTreeModel->GetRootLevelParent( _pEntry ) == _pEntry;
3409 #endif
3411 // -----------------------------------------------------------------------------
3412 sal_Bool SbaTableQueryBrowser::ensureConnection( SvLBoxEntry* _pDSEntry, void* pDSData, SharedConnection& _rConnection )
3414 OSL_ENSURE( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::ensureConnection: this entry does not denote a data source!" );
3415 if(_pDSEntry)
3417 DBTreeListUserData* pTreeListData = static_cast<DBTreeListUserData*>(pDSData);
3418 ::rtl::OUString aDSName = GetEntryText(_pDSEntry);
3420 if ( pTreeListData )
3421 _rConnection = pTreeListData->xConnection;
3423 if ( !_rConnection.is() && pTreeListData )
3425 // show the "connecting to ..." status
3426 String sConnecting(ModuleRes(STR_CONNECTING_DATASOURCE));
3427 sConnecting.SearchAndReplaceAscii("$name$", aDSName);
3428 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sConnecting);
3430 // build a string showing context information in case of error
3431 String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) );
3432 sConnectingContext.SearchAndReplaceAscii("$name$", aDSName);
3434 // connect
3435 _rConnection.reset(
3436 connect( getDataSourceAcessor( _pDSEntry ), sConnectingContext, NULL ),
3437 SharedConnection::TakeOwnership
3440 // remember the connection
3441 pTreeListData->xConnection = _rConnection;
3445 return _rConnection.is();
3448 // -----------------------------------------------------------------------------
3449 IMPL_LINK( SbaTableQueryBrowser, OnTreeEntryCompare, const SvSortData*, _pSortData )
3451 SvLBoxEntry* pLHS = static_cast<SvLBoxEntry*>(_pSortData->pLeft);
3452 SvLBoxEntry* pRHS = static_cast<SvLBoxEntry*>(_pSortData->pRight);
3453 OSL_ENSURE(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!");
3454 // we want the table entry and the end so we have to do a check
3456 if (isContainer(pRHS))
3458 // don't use getEntryType (directly or indirecly) for the LHS:
3459 // LHS is currently beeing inserted, so it is not "completely valid" at the moment
3461 const EntryType eRight = getEntryType(pRHS);
3462 if (etTableContainer == eRight)
3463 // every other container should be placed _before_ the bookmark container
3464 return -1;
3466 const String sLeft = m_pTreeView->getListBox().GetEntryText(pLHS);
3468 EntryType eLeft = etTableContainer;
3469 if (String(ModuleRes(RID_STR_TABLES_CONTAINER)) == sLeft)
3470 eLeft = etTableContainer;
3471 else if (String(ModuleRes(RID_STR_QUERIES_CONTAINER)) == sLeft)
3472 eLeft = etQueryContainer;
3474 if ( eLeft == eRight )
3475 return COMPARE_EQUAL;
3477 if ( ( eLeft == etTableContainer ) && ( eRight == etQueryContainer ) )
3478 return COMPARE_GREATER;
3480 if ( ( eLeft == etQueryContainer ) && ( eRight == etTableContainer ) )
3481 return COMPARE_LESS;
3483 OSL_FAIL( "SbaTableQueryBrowser::OnTreeEntryCompare: unexpected case!" );
3484 return COMPARE_EQUAL;
3487 SvLBoxString* pLeftTextItem = static_cast<SvLBoxString*>(pLHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
3488 SvLBoxString* pRightTextItem = static_cast<SvLBoxString*>(pRHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
3489 OSL_ENSURE(pLeftTextItem && pRightTextItem, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid text items!");
3491 String sLeftText = pLeftTextItem->GetText();
3492 String sRightText = pRightTextItem->GetText();
3494 sal_Int32 nCompareResult = 0; // equal by default
3496 if (m_xCollator.is())
3500 nCompareResult = m_xCollator->compareString(sLeftText, sRightText);
3502 catch(const Exception&)
3506 else
3507 // default behaviour if we do not have a collator -> do the simple string compare
3508 nCompareResult = sLeftText.CompareTo(sRightText);
3510 return nCompareResult;
3513 // -----------------------------------------------------------------------------
3514 void SbaTableQueryBrowser::implAdministrate( SvLBoxEntry* _pApplyTo )
3516 OSL_PRECOND( _pApplyTo, "SbaTableQueryBrowser::implAdministrate: illegal entry!" );
3517 if ( !_pApplyTo )
3518 return;
3522 // get the desktop object
3523 sal_Int32 nFrameSearchFlag = FrameSearchFlag::ALL | FrameSearchFlag::GLOBAL ;
3524 Reference< XComponentLoader > xFrameLoader(getORB()->createInstance(SERVICE_FRAME_DESKTOP),UNO_QUERY);
3526 if ( xFrameLoader.is() )
3528 // the initial selection
3529 SvLBoxEntry* pTopLevelSelected = _pApplyTo;
3530 while (pTopLevelSelected && m_pTreeView->getListBox().GetParent(pTopLevelSelected))
3531 pTopLevelSelected = m_pTreeView->getListBox().GetParent(pTopLevelSelected);
3532 ::rtl::OUString sInitialSelection;
3533 if (pTopLevelSelected)
3534 sInitialSelection = getDataSourceAcessor( pTopLevelSelected );
3536 Reference< XDataSource > xDataSource( getDataSourceByName( sInitialSelection, getView(), getORB(), NULL ) );
3537 Reference< XModel > xDocumentModel( getDataSourceOrModel( xDataSource ), UNO_QUERY );
3539 if ( xDocumentModel.is() )
3541 Reference< XInteractionHandler > xInteractionHandler(
3542 getORB()->createInstance(
3543 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ),
3544 UNO_QUERY );
3545 OSL_ENSURE( xInteractionHandler.is(), "SbaTableQueryBrowser::implAdministrate: no interaction handler available!" );
3547 ::comphelper::NamedValueCollection aLoadArgs;
3548 aLoadArgs.put( "Model", xDocumentModel );
3549 aLoadArgs.put( "InteractionHandler", xInteractionHandler );
3550 aLoadArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
3552 Sequence< PropertyValue > aLoadArgPV;
3553 aLoadArgs >>= aLoadArgPV;
3555 xFrameLoader->loadComponentFromURL(
3556 xDocumentModel->getURL(),
3557 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_default")),
3558 nFrameSearchFlag,
3559 aLoadArgPV
3564 catch( const Exception& )
3566 DBG_UNHANDLED_EXCEPTION();
3570 // -----------------------------------------------------------------------------
3571 sal_Bool SbaTableQueryBrowser::requestQuickHelp( const SvLBoxEntry* _pEntry, String& _rText ) const
3573 const DBTreeListUserData* pData = static_cast< const DBTreeListUserData* >( _pEntry->GetUserData() );
3574 if ( ( pData->eType == etDatasource ) && pData->sAccessor.Len() )
3576 _rText = ::svt::OFileNotation( pData->sAccessor ).get( ::svt::OFileNotation::N_SYSTEM );
3577 return sal_True;
3579 return sal_False;
3582 // -----------------------------------------------------------------------------
3583 PopupMenu* SbaTableQueryBrowser::getContextMenu( Control& _rControl ) const
3585 OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl,
3586 "SbaTableQueryBrowser::getContextMenu: where does this come from?" );
3587 if ( &m_pTreeView->getListBox() != &_rControl )
3588 return NULL;
3590 return new PopupMenu( ModuleRes( MENU_BROWSER_DEFAULTCONTEXT ) );
3593 // -----------------------------------------------------------------------------
3594 IController& SbaTableQueryBrowser::getCommandController()
3596 return *this;
3599 // -----------------------------------------------------------------------------
3600 ::cppu::OInterfaceContainerHelper* SbaTableQueryBrowser::getContextMenuInterceptors()
3602 return &m_aContextMenuInterceptors;
3605 // -----------------------------------------------------------------------------
3606 Any SbaTableQueryBrowser::getCurrentSelection( Control& _rControl ) const
3608 OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl,
3609 "SbaTableQueryBrowser::getCurrentSelection: where does this come from?" );
3611 if ( &m_pTreeView->getListBox() != &_rControl )
3612 return Any();
3614 SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected();
3615 if ( !pSelected )
3616 return Any();
3618 OSL_ENSURE( m_pTreeView->getListBox().NextSelected( pSelected ) == NULL,
3619 "SbaTableQueryBrowser::getCurrentSelection: single-selection is expected here!" );
3621 NamedDatabaseObject aSelectedObject;
3622 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pSelected->GetUserData() );
3623 aSelectedObject.Type = static_cast< sal_Int32 >( pData->eType );
3625 switch ( aSelectedObject.Type )
3627 case DatabaseObject::QUERY:
3628 case DatabaseObject::TABLE:
3629 aSelectedObject.Name = m_pTreeView->getListBox().GetEntryText( pSelected );
3630 break;
3632 case DatabaseObjectContainer::DATA_SOURCE:
3633 case DatabaseObjectContainer::QUERIES:
3634 case DatabaseObjectContainer::TABLES:
3635 aSelectedObject.Name = getDataSourceAcessor( pSelected );
3636 break;
3638 default:
3639 OSL_FAIL( "SbaTableQueryBrowser::getCurrentSelection: invalid (unexpected) object type!" );
3640 break;
3643 return makeAny( aSelectedObject );
3646 // -----------------------------------------------------------------------------
3647 sal_Bool SbaTableQueryBrowser::implGetQuerySignature( ::rtl::OUString& _rCommand, sal_Bool& _bEscapeProcessing )
3649 _rCommand = ::rtl::OUString();
3650 _bEscapeProcessing = sal_False;
3654 // contain the dss (data source signature) of the form
3655 ::rtl::OUString sDataSourceName;
3656 ::rtl::OUString sCommand;
3657 sal_Int32 nCommandType = CommandType::COMMAND;
3658 Reference< XPropertySet > xRowsetProps( getRowSet(), UNO_QUERY );
3659 ODataAccessDescriptor aDesc( xRowsetProps );
3660 sDataSourceName = aDesc.getDataSource();
3661 aDesc[ daCommand ] >>= sCommand;
3662 aDesc[ daCommandType ] >>= nCommandType;
3664 // do we need to do anything?
3665 if ( CommandType::QUERY != nCommandType )
3666 return sal_False;
3668 // get the query object
3669 Reference< XQueryDefinitionsSupplier > xSuppQueries;
3670 Reference< XNameAccess > xQueries;
3671 Reference< XPropertySet > xQuery;
3672 m_xDatabaseContext->getByName( sDataSourceName ) >>= xSuppQueries;
3673 if ( xSuppQueries.is() )
3674 xQueries = xSuppQueries->getQueryDefinitions();
3675 if ( xQueries.is() )
3676 xQueries->getByName( sCommand ) >>= xQuery;
3677 OSL_ENSURE( xQuery.is(), "SbaTableQueryBrowser::implGetQuerySignature: could not retrieve the query object!" );
3679 // get the two properties we need
3680 if ( xQuery.is() )
3682 xQuery->getPropertyValue( PROPERTY_COMMAND ) >>= _rCommand;
3683 _bEscapeProcessing = ::cppu::any2bool( xQuery->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) );
3684 return sal_True;
3687 catch( const Exception& )
3689 DBG_UNHANDLED_EXCEPTION();
3692 return sal_False;
3694 //------------------------------------------------------------------------------
3695 void SbaTableQueryBrowser::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException )
3697 if (aEvent.Frame == m_xCurrentFrameParent)
3699 if(aEvent.Action == FrameAction_COMPONENT_DETACHING)
3700 implRemoveStatusListeners();
3701 else if (aEvent.Action == FrameAction_COMPONENT_REATTACHED)
3702 connectExternalDispatches();
3704 else
3705 SbaXDataBrowserController::frameAction(aEvent);
3708 // -----------------------------------------------------------------------------
3709 void SbaTableQueryBrowser::clearGridColumns(const Reference< XNameContainer >& _xColContainer)
3711 // first we have to clear the grid
3712 Sequence< ::rtl::OUString > aNames = _xColContainer->getElementNames();
3713 const ::rtl::OUString* pIter = aNames.getConstArray();
3714 const ::rtl::OUString* pEnd = pIter + aNames.getLength();
3715 Reference< XInterface > xColumn;
3716 for (; pIter != pEnd;++pIter)
3718 _xColContainer->getByName(*pIter) >>= xColumn;
3719 _xColContainer->removeByName(*pIter);
3720 ::comphelper::disposeComponent(xColumn);
3723 // -----------------------------------------------------------------------------
3724 void SbaTableQueryBrowser::loadMenu(const Reference< XFrame >& _xFrame)
3726 if ( m_bShowMenu )
3728 OGenericUnoController::loadMenu(_xFrame);
3730 else if ( !m_bPreview )
3732 Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager = getLayoutManager(_xFrame);
3734 if ( xLayoutManager.is() )
3736 xLayoutManager->lock();
3737 xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" )));
3738 xLayoutManager->unlock();
3739 xLayoutManager->doLayout();
3741 onLoadedMenu( xLayoutManager );
3744 // -----------------------------------------------------------------------------
3745 ::rtl::OUString SbaTableQueryBrowser::getPrivateTitle() const
3747 ::rtl::OUString sTitle;
3748 if ( m_pCurrentlyDisplayed )
3750 SvLBoxEntry* pContainer = m_pTreeModel->GetParent(m_pCurrentlyDisplayed);
3751 // get the entry for the datasource
3752 SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer);
3753 ::rtl::OUString sName = m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed);
3754 sTitle = GetEntryText( pConnection );
3755 INetURLObject aURL(sTitle);
3756 if ( aURL.GetProtocol() != INET_PROT_NOT_VALID )
3757 sTitle = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET);
3758 if ( !sName.isEmpty() )
3760 sName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" - "));
3761 sName += sTitle;
3762 sTitle = sName;
3766 return sTitle;
3768 // -----------------------------------------------------------------------------
3769 sal_Bool SbaTableQueryBrowser::preReloadForm()
3771 sal_Bool bIni = sal_False;
3772 if ( !m_pCurrentlyDisplayed )
3774 // switch the grid to design mode while loading
3775 getBrowserView()->getGridControl()->setDesignMode(sal_True);
3776 // we had an invalid statement so we need to connect the column models
3777 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
3778 ::svx::ODataAccessDescriptor aDesc(xRowSetProps);
3779 // extract the props
3780 ::rtl::OUString sDataSource;
3781 ::rtl::OUString sCommand;
3782 sal_Int32 nCommandType = CommandType::COMMAND;
3783 sal_Bool bEscapeProcessing = sal_True;
3784 extractDescriptorProps(aDesc, sDataSource, sCommand, nCommandType, bEscapeProcessing);
3785 if ( !sDataSource.isEmpty() && !sCommand.isEmpty() && (-1 != nCommandType) )
3787 SvLBoxEntry* pDataSource = NULL;
3788 SvLBoxEntry* pCommandType = NULL;
3789 m_pCurrentlyDisplayed = getObjectEntry( sDataSource, sCommand, nCommandType, &pDataSource, &pCommandType, sal_True, SharedConnection() );
3790 bIni = sal_True;
3793 return bIni;
3796 // -----------------------------------------------------------------------------
3797 void SbaTableQueryBrowser::postReloadForm()
3799 InitializeGridModel(getFormComponent());
3800 LoadFinished(sal_True);
3803 //------------------------------------------------------------------------------
3804 Reference< XEmbeddedScripts > SAL_CALL SbaTableQueryBrowser::getScriptContainer() throw (RuntimeException)
3806 // update our database document
3807 Reference< XModel > xDocument;
3810 Reference< XPropertySet > xCursorProps( getRowSet(), UNO_QUERY_THROW );
3811 Reference< XConnection > xConnection( xCursorProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY );
3812 if ( xConnection.is() )
3814 Reference< XChild > xChild( xConnection, UNO_QUERY_THROW );
3815 Reference< XDocumentDataSource > xDataSource( xChild->getParent(), UNO_QUERY_THROW );
3816 xDocument.set( xDataSource->getDatabaseDocument(), UNO_QUERY_THROW );
3819 catch( const Exception& )
3821 DBG_UNHANDLED_EXCEPTION();
3823 Reference< XEmbeddedScripts > xScripts( xDocument, UNO_QUERY );
3824 OSL_ENSURE( xScripts.is() || !xDocument.is(),
3825 "SbaTableQueryBrowser::getScriptContainer: invalid database document!" );
3826 return xScripts;
3829 //------------------------------------------------------------------------------
3830 void SAL_CALL SbaTableQueryBrowser::registerContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException)
3832 if ( _Interceptor.is() )
3833 m_aContextMenuInterceptors.addInterface( _Interceptor );
3836 //------------------------------------------------------------------------------
3837 void SAL_CALL SbaTableQueryBrowser::releaseContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException)
3839 if ( _Interceptor.is() )
3840 m_aContextMenuInterceptors.removeInterface( _Interceptor );
3843 //------------------------------------------------------------------------------
3844 void SAL_CALL SbaTableQueryBrowser::registeredDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException)
3846 SolarMutexGuard aGuard;
3847 implAddDatasource( _Event.Name, SharedConnection() );
3850 //------------------------------------------------------------------------------
3851 void SbaTableQueryBrowser::impl_cleanupDataSourceEntry( const String& _rDataSourceName )
3853 // get the top-level representing the removed data source
3854 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().FirstChild( NULL );
3855 while ( pDataSourceEntry )
3857 if ( m_pTreeView->getListBox().GetEntryText( pDataSourceEntry ) == _rDataSourceName )
3858 break;
3860 pDataSourceEntry = m_pTreeView->getListBox().NextSibling( pDataSourceEntry );
3863 OSL_ENSURE( pDataSourceEntry, "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: do not know this data source!" );
3864 if ( !pDataSourceEntry )
3865 return;
3867 if ( isSelected( pDataSourceEntry ) )
3868 { // a table or query belonging to the deleted data source is currently beeing displayed.
3869 OSL_ENSURE( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) == pDataSourceEntry,
3870 "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (1)!" );
3871 unloadAndCleanup( sal_True );
3873 else
3874 OSL_ENSURE(
3875 ( NULL == m_pCurrentlyDisplayed )
3876 || ( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) != pDataSourceEntry ),
3877 "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (2)!");
3879 // delete any user data of the child entries of the to-be-removed entry
3880 SvTreeEntryList* pList = m_pTreeModel->GetChildList( pDataSourceEntry );
3881 if ( pList )
3883 for ( size_t i = 0, n = pList->size(); i < n; ++i )
3885 SvLBoxEntry* pEntryLoop = static_cast<SvLBoxEntry*>((*pList)[ i ]);
3886 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pEntryLoop->GetUserData() );
3887 pEntryLoop->SetUserData( NULL );
3888 delete pData;
3892 // remove the entry
3893 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() );
3894 pDataSourceEntry->SetUserData( NULL );
3895 delete pData;
3896 m_pTreeModel->Remove( pDataSourceEntry );
3899 //------------------------------------------------------------------------------
3900 void SAL_CALL SbaTableQueryBrowser::revokedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException)
3902 SolarMutexGuard aGuard;
3904 impl_cleanupDataSourceEntry( _Event.Name );
3906 // maybe the object which is part of the document data source has been removed
3907 checkDocumentDataSource();
3910 //------------------------------------------------------------------------------
3911 void SAL_CALL SbaTableQueryBrowser::changedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException)
3913 SolarMutexGuard aGuard;
3915 // in case the data source was expanded, and connected, we need to clean it up
3916 // for simplicity, just do as if the data source were completely removed and re-added
3917 impl_cleanupDataSourceEntry( _Event.Name );
3918 implAddDatasource( _Event.Name, SharedConnection() );
3922 // .........................................................................
3923 } // namespace dbaui
3924 // .........................................................................
3927 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */