fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / dbaccess / source / ui / browser / unodatbr.cxx
blob369fb06fdfddd984ec064514cd96a6c1227484b2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "browserids.hxx"
21 #include "dbaccess_helpid.hrc"
22 #include "dbexchange.hxx"
23 #include "dbtreelistbox.hxx"
24 #include "dbtreemodel.hxx"
25 #include "dbtreeview.hxx"
26 #include "dbu_brw.hrc"
27 #include "dbu_reghelper.hxx"
28 #include "dbustrings.hrc"
29 #include "dlgsave.hxx"
30 #include "uiservices.hxx"
31 #include "HtmlReader.hxx"
32 #include "imageprovider.hxx"
33 #include "listviewitems.hxx"
34 #include "QEnumTypes.hxx"
35 #include "RtfReader.hxx"
36 #include "sbagrid.hrc"
37 #include "sbagrid.hxx"
38 #include "sqlmessage.hxx"
39 #include "TokenWriter.hxx"
40 #include "UITools.hxx"
41 #include "unodatbr.hxx"
42 #include "WColumnSelect.hxx"
43 #include "WCopyTable.hxx"
44 #include "WCPage.hxx"
45 #include "WExtendPages.hxx"
46 #include "WNameMatch.hxx"
48 #include <com/sun/star/awt/LineEndFormat.hpp>
49 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
50 #include <com/sun/star/awt/TextAlign.hpp>
51 #include <com/sun/star/awt/VisualEffect.hpp>
52 #include <com/sun/star/beans/NamedValue.hpp>
53 #include <com/sun/star/beans/PropertyValue.hpp>
54 #include <com/sun/star/container/XNameContainer.hpp>
55 #include <com/sun/star/form/XForm.hpp>
56 #include <com/sun/star/form/XGridColumnFactory.hpp>
57 #include <com/sun/star/form/XLoadable.hpp>
58 #include <com/sun/star/form/XReset.hpp>
59 #include <com/sun/star/frame/Desktop.hpp>
60 #include <com/sun/star/frame/FrameSearchFlag.hpp>
61 #include <com/sun/star/frame/XLayoutManager.hpp>
62 #include <com/sun/star/lang/DisposedException.hpp>
63 #include <com/sun/star/i18n/Collator.hpp>
64 #include <com/sun/star/sdb/CommandType.hpp>
65 #include <com/sun/star/sdb/SQLContext.hpp>
66 #include <com/sun/star/sdb/XBookmarksSupplier.hpp>
67 #include <com/sun/star/sdb/XCompletedConnection.hpp>
68 #include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
69 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
70 #include <com/sun/star/sdb/XParametersSupplier.hpp>
71 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
72 #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
73 #include <com/sun/star/sdb/XResultSetAccess.hpp>
74 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
75 #include <com/sun/star/sdb/application/NamedDatabaseObject.hpp>
76 #include <com/sun/star/sdbc/ColumnValue.hpp>
77 #include <com/sun/star/sdbc/DataType.hpp>
78 #include <com/sun/star/sdbc/FetchDirection.hpp>
79 #include <com/sun/star/sdbc/SQLWarning.hpp>
80 #include <com/sun/star/sdbc/XDataSource.hpp>
81 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
82 #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
83 #include <com/sun/star/sdbcx/Privilege.hpp>
84 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
85 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
86 #include <com/sun/star/sdbcx/XDrop.hpp>
87 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
88 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
89 #include <com/sun/star/task/InteractionHandler.hpp>
90 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
91 #include <com/sun/star/util/XFlushable.hpp>
92 #include <com/sun/star/document/MacroExecMode.hpp>
93 #include <com/sun/star/frame/XComponentLoader.hpp>
94 #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
96 #include <comphelper/processfactory.hxx>
97 #include <comphelper/extract.hxx>
98 #include <comphelper/sequence.hxx>
99 #include <comphelper/types.hxx>
100 #include <connectivity/dbexception.hxx>
101 #include <cppuhelper/exc_hlp.hxx>
102 #include <cppuhelper/implbase2.hxx>
103 #include <cppuhelper/typeprovider.hxx>
104 #include <sfx2/app.hxx>
105 #include <sfx2/dispatch.hxx>
106 #include <sot/storage.hxx>
107 #include <svl/filenotation.hxx>
108 #include <svl/intitem.hxx>
109 #include <unotools/moduleoptions.hxx>
110 #include <svtools/svlbitm.hxx>
111 #include <svtools/treelistbox.hxx>
112 #include "svtools/treelistentry.hxx"
113 #include <svx/algitem.hxx>
114 #include <svx/dataaccessdescriptor.hxx>
115 #include <svx/databaseregistrationui.hxx>
116 #include <toolkit/helper/vclunohelper.hxx>
117 #include <tools/diagnose_ex.h>
118 #include <osl/diagnose.h>
119 #include <tools/multisel.hxx>
120 #include <tools/urlobj.hxx>
121 #include <unotools/confignode.hxx>
122 #include <vcl/msgbox.hxx>
123 #include <vcl/split.hxx>
124 #include <vcl/stdtext.hxx>
125 #include <vcl/svapp.hxx>
126 #include <vcl/toolbox.hxx>
127 #include <vcl/waitobj.hxx>
128 #include <vcl/wrkwin.hxx>
129 #include <vcl/settings.hxx>
131 #include <memory>
133 using namespace ::com::sun::star::uno;
134 using namespace ::com::sun::star::awt;
135 using namespace ::com::sun::star::sdb;
136 using namespace ::com::sun::star::sdb::application;
137 using namespace ::com::sun::star::sdbc;
138 using namespace ::com::sun::star::sdbcx;
139 using namespace ::com::sun::star::beans;
140 using namespace ::com::sun::star::util;
141 using namespace ::com::sun::star::frame;
142 using namespace ::com::sun::star::container;
143 using namespace ::com::sun::star::lang;
144 using namespace ::com::sun::star::ui::dialogs;
145 using namespace ::com::sun::star::task;
146 using namespace ::com::sun::star::form;
147 using namespace ::com::sun::star::io;
148 using namespace ::com::sun::star::i18n;
149 using namespace ::com::sun::star::view;
150 using namespace ::com::sun::star::datatransfer;
151 using namespace ::com::sun::star::document;
152 using namespace ::com::sun::star::ui;
153 using namespace ::dbtools;
154 using namespace ::comphelper;
155 using namespace ::svx;
157 // SbaTableQueryBrowser
158 extern "C" void SAL_CALL createRegistryInfo_OBrowser()
160 static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::SbaTableQueryBrowser > aAutoRegistration;
163 namespace dbaui
166 namespace DatabaseObject = css::sdb::application::DatabaseObject;
167 namespace DatabaseObjectContainer = css::sdb::application::DatabaseObjectContainer;
169 void SafeAddPropertyListener(const Reference< XPropertySet > & xSet, const OUString& rPropName, XPropertyChangeListener* pListener)
171 Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
172 if (xInfo->hasPropertyByName(rPropName))
173 xSet->addPropertyChangeListener(rPropName, pListener);
176 void SafeRemovePropertyListener(const Reference< XPropertySet > & xSet, const OUString& rPropName, XPropertyChangeListener* pListener)
178 Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
179 if (xInfo->hasPropertyByName(rPropName))
180 xSet->removePropertyChangeListener(rPropName, pListener);
183 OUString SAL_CALL SbaTableQueryBrowser::getImplementationName() throw(RuntimeException, std::exception)
185 return getImplementationName_Static();
188 ::comphelper::StringSequence SAL_CALL SbaTableQueryBrowser::getSupportedServiceNames() throw(RuntimeException, std::exception)
190 return getSupportedServiceNames_Static();
193 OUString SbaTableQueryBrowser::getImplementationName_Static() throw(RuntimeException)
195 return OUString("org.openoffice.comp.dbu.ODatasourceBrowser");
198 ::comphelper::StringSequence SbaTableQueryBrowser::getSupportedServiceNames_Static() throw(RuntimeException)
200 ::comphelper::StringSequence aSupported(1);
201 aSupported[0] = "com.sun.star.sdb.DataSourceBrowser";
202 return aSupported;
205 Reference< XInterface > SAL_CALL SbaTableQueryBrowser::Create(const Reference<XMultiServiceFactory >& _rxFactory)
207 SolarMutexGuard aGuard;
208 return *(new SbaTableQueryBrowser(comphelper::getComponentContext(_rxFactory)));
211 SbaTableQueryBrowser::SbaTableQueryBrowser(const Reference< XComponentContext >& _rM)
212 :SbaXDataBrowserController(_rM)
213 ,m_aSelectionListeners( getMutex() )
214 ,m_aContextMenuInterceptors( getMutex() )
215 ,m_aTableCopyHelper(this)
216 ,m_pTreeView(NULL)
217 ,m_pSplitter(NULL)
218 ,m_pTreeModel(NULL)
219 ,m_pCurrentlyDisplayed(NULL)
220 ,m_nAsyncDrop(0)
221 ,m_nBorder(1)
222 ,m_bQueryEscapeProcessing( false )
223 ,m_bShowMenu(false)
224 ,m_bInSuspend(false)
225 ,m_bEnableBrowser(true)
229 SbaTableQueryBrowser::~SbaTableQueryBrowser()
231 if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
233 SAL_WARN("dbaccess.ui", "Please check who doesn't dispose this component!");
234 // increment ref count to prevent double call of Dtor
235 osl_atomic_increment( &m_refCount );
236 dispose();
238 SolarMutexGuard g;
239 m_pTreeView.reset();
240 m_pSplitter.reset();
243 Any SAL_CALL SbaTableQueryBrowser::queryInterface(const Type& _rType) throw (RuntimeException, std::exception)
245 if ( _rType.equals( cppu::UnoType<XScriptInvocationContext>::get() ) )
247 OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::queryInterface: did not initialize this, yet!" );
248 if ( !!m_aDocScriptSupport && *m_aDocScriptSupport )
249 return makeAny( Reference< XScriptInvocationContext >( this ) );
250 return Any();
253 Any aReturn = SbaXDataBrowserController::queryInterface(_rType);
254 if (!aReturn.hasValue())
255 aReturn = SbaTableQueryBrowser_Base::queryInterface(_rType);
256 return aReturn;
259 Sequence< Type > SAL_CALL SbaTableQueryBrowser::getTypes( ) throw (RuntimeException, std::exception)
261 Sequence< Type > aTypes( ::comphelper::concatSequences(
262 SbaXDataBrowserController::getTypes(),
263 SbaTableQueryBrowser_Base::getTypes()
264 ) );
266 OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::getTypes: did not initialize this, yet!" );
267 if ( !m_aDocScriptSupport || !*m_aDocScriptSupport )
269 Sequence< Type > aStrippedTypes( aTypes.getLength() - 1 );
270 ::std::remove_copy_if(
271 aTypes.getConstArray(),
272 aTypes.getConstArray() + aTypes.getLength(),
273 aStrippedTypes.getArray(),
274 ::std::bind2nd( ::std::equal_to< Type >(), cppu::UnoType<XScriptInvocationContext>::get() )
276 aTypes = aStrippedTypes;
278 return aTypes;
281 Sequence< sal_Int8 > SAL_CALL SbaTableQueryBrowser::getImplementationId( ) throw (RuntimeException, std::exception)
283 return css::uno::Sequence<sal_Int8>();
286 void SAL_CALL SbaTableQueryBrowser::disposing()
288 SolarMutexGuard aGuard;
289 // doin' a lot of VCL stuff here -> lock the SolarMutex
291 // kiss our listeners goodbye
292 com::sun::star::lang::EventObject aEvt(*this);
293 m_aSelectionListeners.disposeAndClear(aEvt);
294 m_aContextMenuInterceptors.disposeAndClear(aEvt);
296 // reset the content's tree view: it holds a reference to our model which is to be deleted immediately,
297 // and it will live longer than we do.
298 if (getBrowserView())
299 getBrowserView()->setTreeView(NULL);
301 clearTreeModel();
302 // clear the tree model
304 ::std::unique_ptr<SvTreeList> aTemp(m_pTreeModel);
305 m_pTreeModel = NULL;
308 // remove ourself as status listener
309 implRemoveStatusListeners();
311 // remove the container listener from the database context
314 Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
315 xDatabaseRegistrations->removeDatabaseRegistrationsListener( this );
317 catch( const Exception& )
319 DBG_UNHANDLED_EXCEPTION();
322 // check out from all the objects we are listening
323 // the frame
324 if (m_xCurrentFrameParent.is())
325 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
326 SbaXDataBrowserController::disposing();
329 bool SbaTableQueryBrowser::Construct(vcl::Window* pParent)
331 if ( !SbaXDataBrowserController::Construct( pParent ) )
332 return false;
336 Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
337 xDatabaseRegistrations->addDatabaseRegistrationsListener( this );
339 // the collator for the string compares
340 m_xCollator = Collator::create( getORB() );
341 m_xCollator->loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0 );
343 catch(const Exception&)
345 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::Construct: could not create (or start listening at) the database context!");
347 // some help ids
348 if (getBrowserView() && getBrowserView()->getVclControl())
351 // create controls and set sizes
352 const long nFrameWidth = getBrowserView()->LogicToPixel( ::Size( 3, 0 ), MAP_APPFONT ).Width();
354 m_pSplitter = VclPtr<Splitter>::Create(getBrowserView(),WB_HSCROLL);
355 m_pSplitter->SetPosSizePixel( ::Point(0,0), ::Size(nFrameWidth,0) );
356 m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) );
358 m_pTreeView = VclPtr<DBTreeView>::Create(getBrowserView(), WB_TABSTOP | WB_BORDER);
359 m_pTreeView->SetPreExpandHandler(LINK(this, SbaTableQueryBrowser, OnExpandEntry));
361 m_pTreeView->setCopyHandler(LINK(this, SbaTableQueryBrowser, OnCopyEntry));
363 m_pTreeView->getListBox().setContextMenuProvider( this );
364 m_pTreeView->getListBox().setControlActionListener( this );
365 m_pTreeView->SetHelpId(HID_CTL_TREEVIEW);
367 // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide
368 m_pSplitter->SetSplitPosPixel( getBrowserView()->LogicToPixel( ::Size( 80, 0 ), MAP_APPFONT ).Width() );
370 getBrowserView()->setSplitter(m_pSplitter);
371 getBrowserView()->setTreeView(m_pTreeView);
373 // fill view with data
374 m_pTreeModel = new SvTreeList;
375 m_pTreeModel->SetSortMode(SortAscending);
376 m_pTreeModel->SetCompareHdl(LINK(this, SbaTableQueryBrowser, OnTreeEntryCompare));
377 m_pTreeView->setModel(m_pTreeModel);
378 m_pTreeView->setSelChangeHdl( LINK( this, SbaTableQueryBrowser, OnSelectionChange ) );
380 // TODO
381 getBrowserView()->getVclControl()->GetDataWindow().SetUniqueId(UID_DATABROWSE_DATAWINDOW);
382 getBrowserView()->getVclControl()->SetHelpId(HID_CTL_TABBROWSER);
383 getBrowserView()->SetUniqueId(UID_CTL_CONTENT);
384 if (getBrowserView()->getVclControl()->GetHeaderBar())
385 getBrowserView()->getVclControl()->GetHeaderBar()->SetHelpId(HID_DATABROWSE_HEADER);
386 InvalidateFeature(ID_BROWSER_EXPLORER);
389 return true;
392 namespace
394 struct SelectValueByName : public ::std::unary_function< OUString, Any >
396 const Any& operator()( OUString const& i_name ) const
398 return m_rCollection.get( i_name );
401 SelectValueByName( ::comphelper::NamedValueCollection const& i_collection )
402 :m_rCollection( i_collection )
406 ::comphelper::NamedValueCollection const& m_rCollection;
410 void SbaTableQueryBrowser::impl_sanitizeRowSetClauses_nothrow()
414 Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
415 bool bEscapeProcessing = false;
416 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
417 if ( !bEscapeProcessing )
418 // don't touch or interpret anything if escape processing is disabled
419 return;
421 Reference< XSingleSelectQueryComposer > xComposer( createParser_nothrow() );
422 if ( !xComposer.is() )
423 // can't do anything. Already reported via assertion in createParser_nothrow.
424 return;
426 // the tables participating in the statement
427 const Reference< XTablesSupplier > xSuppTables( xComposer, UNO_QUERY_THROW );
428 const Reference< XNameAccess > xTableNames( xSuppTables->getTables(), UNO_QUERY_THROW );
430 // the columns participating in the statement
431 const Reference< XColumnsSupplier > xSuppColumns( xComposer, UNO_QUERY_THROW );
432 const Reference< XNameAccess > xColumnNames( xSuppColumns->getColumns(), UNO_QUERY_THROW );
434 // check if the order columns apply to tables which really exist in the statement
435 const Reference< XIndexAccess > xOrderColumns( xComposer->getOrderColumns(), UNO_SET_THROW );
436 const sal_Int32 nOrderColumns( xOrderColumns->getCount() );
437 bool invalidColumn = nOrderColumns == 0;
438 for ( sal_Int32 c=0; ( c < nOrderColumns ) && !invalidColumn; ++c )
440 const Reference< XPropertySet > xOrderColumn( xOrderColumns->getByIndex(c), UNO_QUERY_THROW );
441 OUString sTableName;
442 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName );
443 OUString sColumnName;
444 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName );
446 if ( sTableName.isEmpty() )
448 if ( !xColumnNames->hasByName( sColumnName ) )
450 invalidColumn = true;
451 break;
454 else
456 if ( !xTableNames->hasByName( sTableName ) )
458 invalidColumn = true;
459 break;
462 const Reference< XColumnsSupplier > xSuppTableColumns( xTableNames->getByName( sTableName ), UNO_QUERY_THROW );
463 const Reference< XNameAccess > xTableColumnNames( xSuppTableColumns->getColumns(), UNO_QUERY_THROW );
464 if ( !xTableColumnNames->hasByName( sColumnName ) )
466 invalidColumn = true;
467 break;
472 if ( invalidColumn )
474 // reset the complete order statement at both the row set and the parser
475 const OUString sEmptyOrder;
476 xRowSetProps->setPropertyValue( PROPERTY_ORDER, makeAny( sEmptyOrder ) );
477 xComposer->setOrder( sEmptyOrder );
480 // check if the columns participating in the filter refer to existing tables
481 // TODO: there's no API at all for this. The method which comes nearest to what we need is
482 // "getStructuredFilter", but it returns pure column names only. That is, for a statement like
483 // "SELECT * FROM <table> WHERE <other_table>.<column> = <value>", it will return "<column>". But
484 // there's no API at all to retrieve the information about "<other_table>" - which is what would
485 // be needed here.
486 // That'd be a chance to replace getStructuredFilter with something more reasonable. This method
487 // has at least one other problem: For a clause like "<column> != <value>", it will return "<column>"
488 // as column name, "NOT_EQUAL" as operator, and "!= <value>" as value, effectively duplicating the
489 // information about the operator, and beding all clients to manually remove the "!=" from the value
490 // string.
491 // So, what really would be handy, is some
492 // XNormalizedFilter getNormalizedFilter();
493 // with
494 // interface XDisjunctiveFilterExpression
495 // {
496 // XConjunctiveFilterTerm getTerm( int index );
497 // }
498 // interface XConjunctiveFilterTerm
499 // {
500 // ComparisonPredicate getPredicate( int index );
501 // }
502 // struct ComparisonPredicate
503 // {
504 // XComparisonOperand Lhs;
505 // SQLFilterOperator Operator;
506 // XComparisonOperand Rhs;
507 // }
508 // interface XComparisonOperand
509 // {
510 // SQLFilterOperand Type;
511 // XPropertySet getColumn();
512 // string getLiteral();
513 // ...
514 // }
515 // enum SQLFilterOperand { Column, Literal, ... }
516 // ... or something like this ....
518 catch( const Exception& )
520 DBG_UNHANDLED_EXCEPTION();
524 bool SbaTableQueryBrowser::InitializeForm( const Reference< XPropertySet > & i_formProperties )
526 if(!m_pCurrentlyDisplayed)
527 return true;
529 // this method set all format settings from the orignal table or query
532 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
533 ENSURE_OR_RETURN_FALSE( pData, "SbaTableQueryBrowser::InitializeForm: No user data set at the currently displayed entry!" );
534 ENSURE_OR_RETURN_FALSE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeForm: No table available!" );
536 Reference< XPropertySetInfo > xPSI( pData->xObjectProperties->getPropertySetInfo(), UNO_SET_THROW );
538 ::comphelper::NamedValueCollection aPropertyValues;
540 const OUString aTransferProperties[] =
542 OUString(PROPERTY_APPLYFILTER),
543 OUString(PROPERTY_FILTER),
544 OUString(PROPERTY_HAVING_CLAUSE),
545 OUString(PROPERTY_ORDER)
547 for (size_t i = 0; i < SAL_N_ELEMENTS(aTransferProperties); ++i)
549 if ( !xPSI->hasPropertyByName( aTransferProperties[i] ) )
550 continue;
551 aPropertyValues.put( aTransferProperties[i], pData->xObjectProperties->getPropertyValue( aTransferProperties[i] ) );
554 ::std::vector< OUString > aNames( aPropertyValues.getNames() );
555 ::std::sort(aNames.begin(), aNames.end());
556 Sequence< OUString > aPropNames( aNames.size() );
557 ::std::copy( aNames.begin(), aNames.end(), aPropNames.getArray() );
559 Sequence< Any > aPropValues( aNames.size() );
560 ::std::transform( aNames.begin(), aNames.end(), aPropValues.getArray(), SelectValueByName( aPropertyValues ) );
562 Reference< XMultiPropertySet > xFormMultiSet( i_formProperties, UNO_QUERY_THROW );
563 xFormMultiSet->setPropertyValues( aPropNames, aPropValues );
565 impl_sanitizeRowSetClauses_nothrow();
567 catch ( const Exception& )
569 DBG_UNHANDLED_EXCEPTION();
570 return false;
573 return true;
576 void SbaTableQueryBrowser::initializePreviewMode()
578 if ( getBrowserView() && getBrowserView()->getVclControl() )
580 getBrowserView()->getVclControl()->AlwaysEnableInput( false );
581 getBrowserView()->getVclControl()->EnableInput( false );
582 getBrowserView()->getVclControl()->ForceHideScrollbars( true );
584 Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY);
585 if ( xDataSourceSet.is() )
587 xDataSourceSet->setPropertyValue("AllowInserts",makeAny(sal_False));
588 xDataSourceSet->setPropertyValue("AllowUpdates",makeAny(sal_False));
589 xDataSourceSet->setPropertyValue("AllowDeletes",makeAny(sal_False));
593 bool SbaTableQueryBrowser::InitializeGridModel(const Reference< ::com::sun::star::form::XFormComponent > & xGrid)
597 Reference< ::com::sun::star::form::XGridColumnFactory > xColFactory(xGrid, UNO_QUERY);
598 Reference< XNameContainer > xColContainer(xGrid, UNO_QUERY);
599 clearGridColumns( xColContainer );
601 Reference< XChild > xGridAsChild(xGrid, UNO_QUERY);
602 Reference< XLoadable > xFormAsLoadable;
603 if (xGridAsChild.is())
604 xFormAsLoadable.set(xGridAsChild->getParent(), css::uno::UNO_QUERY);
605 if (xFormAsLoadable.is() && xFormAsLoadable->isLoaded())
607 // set the formats from the table
608 if(m_pCurrentlyDisplayed)
610 Sequence< OUString> aProperties(6 + ( m_bPreview ? 5 : 0 ));
611 Sequence< Any> aValues(7 + ( m_bPreview ? 5 : 0 ));
613 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
614 OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeGridModel: No table available!" );
615 if ( !pData->xObjectProperties.is() )
616 return false;
618 OUString* pStringIter = aProperties.getArray();
619 Any* pValueIter = aValues.getArray();
620 if ( m_bPreview )
622 *pStringIter++ = "AlwaysShowCursor";
623 *pValueIter++ <<= sal_False;
624 *pStringIter++ = PROPERTY_BORDER;
625 *pValueIter++ <<= sal_Int16(0);
628 *pStringIter++ = PROPERTY_FONT;
629 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_FONT);
630 *pStringIter++ = PROPERTY_TEXTEMPHASIS;
631 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTEMPHASIS);
632 *pStringIter++ = PROPERTY_TEXTRELIEF;
633 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTRELIEF);
634 if ( m_bPreview )
636 *pStringIter++ = "HasNavigationBar";
637 *pValueIter++ <<= sal_False;
638 *pStringIter++ = "HasRecordMarker";
639 *pValueIter++ <<= sal_False;
641 *pStringIter++ = PROPERTY_ROW_HEIGHT;
642 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_ROW_HEIGHT);
643 if ( m_bPreview )
645 *pStringIter++ = "Tabstop";
646 *pValueIter++ <<= sal_False;
648 *pStringIter++ = PROPERTY_TEXTCOLOR;
649 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTCOLOR);
650 *pStringIter++ = PROPERTY_TEXTLINECOLOR;
651 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTLINECOLOR);
653 Reference< XMultiPropertySet > xFormMultiSet(xGrid, UNO_QUERY);
654 xFormMultiSet->setPropertyValues(aProperties, aValues);
657 // get the formats supplier of the database we're working with
658 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier = getNumberFormatter()->getNumberFormatsSupplier();
660 Reference<XConnection> xConnection;
661 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
662 xRowSetProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
663 OSL_ENSURE(xConnection.is(),"A ActiveConnection should normally exists!");
665 Reference<XChild> xChild(xConnection,UNO_QUERY);
666 Reference<XPropertySet> xDataSourceProp(xChild->getParent(),UNO_QUERY);
667 bool bSuppressVersionCol = false;
668 OSL_VERIFY( xDataSourceProp->getPropertyValue( PROPERTY_SUPPRESSVERSIONCL ) >>= bSuppressVersionCol );
670 // insert the column into the gridcontrol so that we see something :-)
671 OUString aCurrentModelType;
672 Reference<XColumnsSupplier> xSupCols(getRowSet(),UNO_QUERY);
673 Reference<XNameAccess> xColumns = xSupCols->getColumns();
674 Sequence< OUString> aNames = xColumns->getElementNames();
675 const OUString* pIter = aNames.getConstArray();
676 const OUString* pEnd = pIter + aNames.getLength();
678 OUString sDefaultProperty;
679 Reference< XPropertySet > xColumn;
680 Reference< XPropertySetInfo > xColPSI;
681 for (sal_uInt16 i=0; pIter != pEnd; ++i,++pIter)
683 xColumn.set( xColumns->getByName( *pIter ), UNO_QUERY_THROW );
684 xColPSI.set( xColumn->getPropertySetInfo(), UNO_SET_THROW );
686 // ignore the column when it is a rowversion one
687 if ( bSuppressVersionCol
688 && xColPSI->hasPropertyByName( PROPERTY_ISROWVERSION )
689 && ::cppu::any2bool( xColumn->getPropertyValue( PROPERTY_ISROWVERSION ) )
691 continue;
693 // use the result set column's type to determine the type of grid column to create
694 bool bFormattedIsNumeric = true;
695 sal_Int32 nType = ::comphelper::getINT32( xColumn->getPropertyValue( PROPERTY_TYPE ) );
697 ::std::vector< NamedValue > aInitialValues;
698 ::std::vector< OUString > aCopyProperties;
699 Any aDefault;
701 switch(nType)
703 case DataType::BIT:
704 case DataType::BOOLEAN:
706 aCurrentModelType = "CheckBox";
707 aInitialValues.push_back( NamedValue( OUString( "VisualEffect" ), makeAny( VisualEffect::FLAT ) ) );
708 sDefaultProperty = PROPERTY_DEFAULTSTATE;
710 sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
711 OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable );
712 aInitialValues.push_back( NamedValue(
713 OUString( "TriState" ),
714 makeAny( ColumnValue::NO_NULLS != nNullable )
715 ) );
716 if ( ColumnValue::NO_NULLS == nNullable )
717 aDefault <<= (sal_Int16)TRISTATE_FALSE;
719 break;
721 case DataType::LONGVARCHAR:
722 case DataType::CLOB:
723 aInitialValues.push_back( NamedValue( OUString( "MultiLine" ), makeAny( true ) ) );
724 // NO break!
725 case DataType::BINARY:
726 case DataType::VARBINARY:
727 case DataType::LONGVARBINARY:
728 aCurrentModelType = "TextField";
729 sDefaultProperty = PROPERTY_DEFAULTTEXT;
730 break;
732 case DataType::VARCHAR:
733 case DataType::CHAR:
734 bFormattedIsNumeric = false;
735 // NO break!
736 default:
737 aCurrentModelType = "FormattedField";
738 sDefaultProperty = PROPERTY_EFFECTIVEDEFAULT;
740 if ( xSupplier.is() )
741 aInitialValues.push_back( NamedValue( OUString("FormatsSupplier"), makeAny( xSupplier ) ) );
742 aInitialValues.push_back( NamedValue( OUString("TreatAsNumber"), makeAny( bFormattedIsNumeric ) ) );
743 aCopyProperties.push_back( static_cast<const OUString&>(PROPERTY_FORMATKEY) );
744 break;
747 aInitialValues.push_back( NamedValue( PROPERTY_CONTROLSOURCE, makeAny( *pIter ) ) );
748 OUString sLabel;
749 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
750 if ( !sLabel.isEmpty() )
751 aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( sLabel ) ) );
752 else
753 aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( *pIter ) ) );
755 Reference< XPropertySet > xGridCol( xColFactory->createColumn( aCurrentModelType ), UNO_SET_THROW );
756 Reference< XPropertySetInfo > xGridColPSI( xGridCol->getPropertySetInfo(), UNO_SET_THROW );
758 // calculate the default
759 if ( xGridColPSI->hasPropertyByName( PROPERTY_CONTROLDEFAULT ) )
761 aDefault = xColumn->getPropertyValue( PROPERTY_CONTROLDEFAULT );
762 // default value
763 if ( nType == DataType::BIT || nType == DataType::BOOLEAN )
765 if ( aDefault.hasValue() )
766 aDefault <<= (comphelper::getString(aDefault).toInt32() == 0) ? (sal_Int16)TRISTATE_FALSE : (sal_Int16)TRISTATE_TRUE;
767 else
768 aDefault <<= ((sal_Int16)TRISTATE_INDET);
772 if ( aDefault.hasValue() )
773 aInitialValues.push_back( NamedValue( sDefaultProperty, aDefault ) );
775 // transfer properties from the definition to the UNO-model :
776 aCopyProperties.push_back( static_cast<const OUString&>(PROPERTY_HIDDEN) );
777 aCopyProperties.push_back( static_cast<const OUString&>(PROPERTY_WIDTH) );
779 // help text to display for the column
780 Any aDescription;
781 if ( xColPSI->hasPropertyByName( PROPERTY_HELPTEXT ) )
782 aDescription = xColumn->getPropertyValue( PROPERTY_HELPTEXT );
783 OUString sTemp;
784 aDescription >>= sTemp;
785 if ( sTemp.isEmpty() )
786 xColumn->getPropertyValue( PROPERTY_DESCRIPTION ) >>= sTemp;
788 aDescription <<= sTemp;
789 aInitialValues.push_back( NamedValue( PROPERTY_HELPTEXT, aDescription ) );
791 // ... horizontal justify
792 Any aAlign; aAlign <<= sal_Int16( 0 );
793 Any aColAlign( xColumn->getPropertyValue( PROPERTY_ALIGN ) );
794 if ( aColAlign.hasValue() )
795 aAlign <<= sal_Int16( ::comphelper::getINT32( aColAlign ) );
796 aInitialValues.push_back( NamedValue( PROPERTY_ALIGN, aAlign ) );
798 // don't allow the mouse to scroll in the cells
799 if ( xGridColPSI->hasPropertyByName( PROPERTY_MOUSE_WHEEL_BEHAVIOR ) )
800 aInitialValues.push_back( NamedValue( PROPERTY_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) ) );
802 // now set all those values
803 for ( ::std::vector< NamedValue >::const_iterator property = aInitialValues.begin();
804 property != aInitialValues.end();
805 ++property
808 xGridCol->setPropertyValue( property->Name, property->Value );
810 for ( ::std::vector< OUString >::const_iterator copyPropertyName = aCopyProperties.begin();
811 copyPropertyName != aCopyProperties.end();
812 ++copyPropertyName
814 xGridCol->setPropertyValue( *copyPropertyName, xColumn->getPropertyValue( *copyPropertyName ) );
816 xColContainer->insertByName(*pIter, makeAny(xGridCol));
820 catch(const Exception&)
822 DBG_UNHANDLED_EXCEPTION();
823 return false;
826 return true;
829 Reference<XPropertySet> getColumnHelper(SvTreeListEntry* _pCurrentlyDisplayed,const Reference<XPropertySet>& _rxSource)
831 Reference<XPropertySet> xRet;
832 if(_pCurrentlyDisplayed)
834 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pCurrentlyDisplayed->GetUserData());
835 Reference<XColumnsSupplier> xColumnsSup(pData->xObjectProperties,UNO_QUERY);
836 Reference<XNameAccess> xNames = xColumnsSup->getColumns();
837 OUString aName;
838 _rxSource->getPropertyValue(PROPERTY_NAME) >>= aName;
839 if(xNames.is() && xNames->hasByName(aName))
840 xRet.set(xNames->getByName(aName),UNO_QUERY);
842 return xRet;
845 void SbaTableQueryBrowser::transferChangedControlProperty(const OUString& _rProperty, const Any& _rNewValue)
847 if(m_pCurrentlyDisplayed)
849 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
850 Reference< XPropertySet > xObjectProps(pData->xObjectProperties, UNO_QUERY);
851 OSL_ENSURE(xObjectProps.is(),"SbaTableQueryBrowser::transferChangedControlProperty: no table/query object!");
852 if (xObjectProps.is())
853 xObjectProps->setPropertyValue(_rProperty, _rNewValue);
857 void SbaTableQueryBrowser::propertyChange(const PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException, std::exception)
859 SbaXDataBrowserController::propertyChange(evt);
863 Reference< XPropertySet > xSource(evt.Source, UNO_QUERY);
864 if (!xSource.is())
865 return;
867 // one of the many properties which require us to update the definition ?
868 // a column's width ?
869 else if (evt.PropertyName == PROPERTY_WIDTH)
870 { // a column width has changed -> update the model
871 // (the update of the view is done elsewhere)
872 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
873 if(xProp.is())
875 if(!evt.NewValue.hasValue())
876 xProp->setPropertyValue(PROPERTY_WIDTH,makeAny((sal_Int32)227));
877 else
878 xProp->setPropertyValue(PROPERTY_WIDTH,evt.NewValue);
882 // a column's 'visible' state ?
883 else if (evt.PropertyName == PROPERTY_HIDDEN)
885 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
886 if(xProp.is())
887 xProp->setPropertyValue(PROPERTY_HIDDEN,evt.NewValue);
890 // a columns alignment ?
891 else if (evt.PropertyName == PROPERTY_ALIGN)
893 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
896 if(xProp.is())
898 if(evt.NewValue.hasValue())
900 sal_Int16 nAlign = 0;
901 if(evt.NewValue >>= nAlign)
902 xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(sal_Int32(nAlign)));
903 else
904 xProp->setPropertyValue(PROPERTY_ALIGN,evt.NewValue);
906 else
907 xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(::com::sun::star::awt::TextAlign::LEFT));
910 catch( const Exception& )
912 DBG_UNHANDLED_EXCEPTION();
916 // a column's format ?
917 else if ( evt.PropertyName == PROPERTY_FORMATKEY
918 && (TypeClass_LONG == evt.NewValue.getValueTypeClass())
921 // update the model (means the definition object)
922 Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource);
923 if(xProp.is())
924 xProp->setPropertyValue(PROPERTY_FORMATKEY,evt.NewValue);
927 // some table definition properties ?
928 // the height of the rows in the grid ?
929 else if (evt.PropertyName == PROPERTY_ROW_HEIGHT)
931 if(m_pCurrentlyDisplayed)
933 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData());
934 OSL_ENSURE( pData->xObjectProperties.is(), "No table available!" );
936 bool bDefault = !evt.NewValue.hasValue();
937 if (bDefault)
938 pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,makeAny((sal_Int32)45));
939 else
940 pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,evt.NewValue);
944 else if ( evt.PropertyName == PROPERTY_FONT // the font ?
945 || evt.PropertyName == PROPERTY_TEXTCOLOR // the text color ?
946 || evt.PropertyName == PROPERTY_FILTER // the filter ?
947 || evt.PropertyName == PROPERTY_HAVING_CLAUSE // the having clause ?
948 || evt.PropertyName == PROPERTY_ORDER // the sort ?
949 || evt.PropertyName == PROPERTY_APPLYFILTER // the appliance of the filter ?
950 || evt.PropertyName == PROPERTY_TEXTLINECOLOR // the text line color ?
951 || evt.PropertyName == PROPERTY_TEXTEMPHASIS // the text emphasis ?
952 || evt.PropertyName == PROPERTY_TEXTRELIEF // the text relief ?
955 transferChangedControlProperty(evt.PropertyName, evt.NewValue);
958 catch( const Exception& )
960 DBG_UNHANDLED_EXCEPTION();
964 sal_Bool SbaTableQueryBrowser::suspend(sal_Bool bSuspend) throw( RuntimeException, std::exception )
966 SolarMutexGuard aSolarGuard;
967 ::osl::MutexGuard aGuard( getMutex() );
968 if ( getView() && getView()->IsInModalMode() )
969 return sal_False;
970 bool bRet = false;
971 if ( !m_bInSuspend )
973 m_bInSuspend = true;
974 if ( rBHelper.bDisposed )
975 throw DisposedException( OUString(), *this );
977 bRet = SbaXDataBrowserController::suspend(bSuspend);
978 if ( bRet && getView() )
979 getView()->Hide();
981 m_bInSuspend = false;
984 return bRet;
987 void SAL_CALL SbaTableQueryBrowser::statusChanged( const FeatureStateEvent& _rEvent ) throw(RuntimeException, std::exception)
989 // search the external dispatcher causing this call
990 Reference< XDispatch > xSource(_rEvent.Source, UNO_QUERY);
991 ExternalFeaturesMap::iterator aLoop;
992 for ( aLoop = m_aExternalFeatures.begin();
993 aLoop != m_aExternalFeatures.end();
994 ++aLoop
997 if ( _rEvent.FeatureURL.Complete == aLoop->second.aURL.Complete)
999 OSL_ENSURE( xSource.get() == aLoop->second.xDispatcher.get(), "SbaTableQueryBrowser::statusChanged: inconsistent!" );
1000 // update the enabled state
1001 aLoop->second.bEnabled = _rEvent.IsEnabled;
1003 switch ( aLoop->first )
1005 case ID_BROWSER_DOCUMENT_DATASOURCE:
1007 // if it's the slot for the document data source, remember the state
1008 Sequence< PropertyValue > aDescriptor;
1009 #if OSL_DEBUG_LEVEL > 0
1010 bool bProperFormat =
1011 #endif
1012 _rEvent.State >>= aDescriptor;
1013 OSL_ENSURE(bProperFormat, "SbaTableQueryBrowser::statusChanged: need a data access descriptor here!");
1014 m_aDocumentDataSource.initializeFrom(aDescriptor);
1016 OSL_ENSURE( ( m_aDocumentDataSource.has(daDataSource)
1017 || m_aDocumentDataSource.has(daDatabaseLocation)
1019 && m_aDocumentDataSource.has(daCommand)
1020 && m_aDocumentDataSource.has(daCommandType),
1021 "SbaTableQueryBrowser::statusChanged: incomplete descriptor!");
1023 // check if we know the object which is set as document data source
1024 checkDocumentDataSource();
1026 break;
1028 default:
1029 // update the toolbox
1030 implCheckExternalSlot( aLoop->first );
1031 break;
1033 break;
1037 OSL_ENSURE(aLoop != m_aExternalFeatures.end(), "SbaTableQueryBrowser::statusChanged: don't know who sent this!");
1040 void SbaTableQueryBrowser::checkDocumentDataSource()
1042 SvTreeListEntry* pDataSourceEntry = NULL;
1043 SvTreeListEntry* pContainerEntry = NULL;
1044 SvTreeListEntry* pObjectEntry = getObjectEntry( m_aDocumentDataSource, &pDataSourceEntry, &pContainerEntry, false );
1045 bool bKnownDocDataSource = (NULL != pObjectEntry);
1046 if (!bKnownDocDataSource)
1048 if (NULL != pDataSourceEntry)
1049 { // at least the data source is known
1050 if (NULL != pContainerEntry)
1051 bKnownDocDataSource = true; // assume we know it.
1052 // TODO: should we expand the object container? This may be too expensive just for checking ....
1053 else
1055 if ((NULL == pObjectEntry) && m_aDocumentDataSource.has(daCommandType) && m_aDocumentDataSource.has(daCommand))
1056 { // maybe we have a command to be displayed ?
1057 sal_Int32 nCommandType = CommandType::TABLE;
1058 m_aDocumentDataSource[daCommandType] >>= nCommandType;
1060 OUString sCommand;
1061 m_aDocumentDataSource[daCommand] >>= sCommand;
1063 bKnownDocDataSource = (CommandType::COMMAND == nCommandType) && (!sCommand.isEmpty());
1069 if ( !bKnownDocDataSource )
1070 m_aExternalFeatures[ ID_BROWSER_DOCUMENT_DATASOURCE ].bEnabled = false;
1072 // update the toolbox
1073 implCheckExternalSlot(ID_BROWSER_DOCUMENT_DATASOURCE);
1076 void SbaTableQueryBrowser::extractDescriptorProps(const svx::ODataAccessDescriptor& _rDescriptor, OUString& _rDataSource, OUString& _rCommand, sal_Int32& _rCommandType, bool& _rEscapeProcessing)
1078 _rDataSource = _rDescriptor.getDataSource();
1079 if ( _rDescriptor.has(daCommand) )
1080 _rDescriptor[daCommand] >>= _rCommand;
1081 if ( _rDescriptor.has(daCommandType) )
1082 _rDescriptor[daCommandType] >>= _rCommandType;
1084 // escape processing is the only one allowed not to be present
1085 _rEscapeProcessing = true;
1086 if (_rDescriptor.has(daEscapeProcessing))
1087 _rEscapeProcessing = ::cppu::any2bool(_rDescriptor[daEscapeProcessing]);
1090 namespace
1092 bool getDataSourceDisplayName_isURL( const OUString& _rDS, OUString& _rDisplayName, OUString& _rUniqueId )
1094 INetURLObject aURL( _rDS );
1095 if ( aURL.GetProtocol() != INetProtocol::NotValid )
1097 _rDisplayName = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET);
1098 _rUniqueId = aURL.GetMainURL( INetURLObject::NO_DECODE );
1099 return true;
1101 _rDisplayName = _rDS;
1102 _rUniqueId.clear();
1103 return false;
1106 struct FilterByEntryDataId : public IEntryFilter
1108 OUString sId;
1109 FilterByEntryDataId( const OUString& _rId ) : sId( _rId ) { }
1111 virtual ~FilterByEntryDataId() {}
1113 virtual bool includeEntry( SvTreeListEntry* _pEntry ) const SAL_OVERRIDE;
1116 bool FilterByEntryDataId::includeEntry( SvTreeListEntry* _pEntry ) const
1118 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() );
1119 return ( !pData || ( pData->sAccessor == sId ) );
1123 OUString SbaTableQueryBrowser::getDataSourceAcessor( SvTreeListEntry* _pDataSourceEntry ) const
1125 OSL_ENSURE( _pDataSourceEntry, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry!" );
1127 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pDataSourceEntry->GetUserData() );
1128 OSL_ENSURE( pData, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry data!" );
1129 OSL_ENSURE( pData->eType == etDatasource, "SbaTableQueryBrowser::getDataSourceAcessor: entry does not denote a data source!" );
1130 return !pData->sAccessor.isEmpty() ? OUString(pData->sAccessor) : GetEntryText( _pDataSourceEntry );
1133 SvTreeListEntry* SbaTableQueryBrowser::getObjectEntry(const OUString& _rDataSource, const OUString& _rCommand, sal_Int32 _nCommandType,
1134 SvTreeListEntry** _ppDataSourceEntry, SvTreeListEntry** _ppContainerEntry, bool _bExpandAncestors,
1135 const SharedConnection& _rxConnection )
1137 if (_ppDataSourceEntry)
1138 *_ppDataSourceEntry = NULL;
1139 if (_ppContainerEntry)
1140 *_ppContainerEntry = NULL;
1142 SvTreeListEntry* pObject = NULL;
1143 if ( m_pTreeView )
1145 // look for the data source entry
1146 OUString sDisplayName, sDataSourceId;
1147 bool bIsDataSourceURL = getDataSourceDisplayName_isURL( _rDataSource, sDisplayName, sDataSourceId );
1148 // the display name may differ from the URL for readability reasons
1149 // #i33699#
1151 FilterByEntryDataId aFilter( sDataSourceId );
1152 SvTreeListEntry* pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter );
1153 if ( !pDataSource ) // check if the data source name is a file location
1155 if ( bIsDataSourceURL )
1157 // special case, the data source is a URL
1158 // add new entries to the list box model
1159 implAddDatasource( _rDataSource, _rxConnection );
1160 pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter );
1161 OSL_ENSURE( pDataSource, "SbaTableQueryBrowser::getObjectEntry: hmm - did not find it again!" );
1164 if (_ppDataSourceEntry)
1165 // (caller wants to have it ...)
1166 *_ppDataSourceEntry = pDataSource;
1168 if (pDataSource)
1170 // expand if required so
1171 if (_bExpandAncestors)
1172 m_pTreeView->getListBox().Expand(pDataSource);
1174 // look for the object container
1175 SvTreeListEntry* pCommandType = NULL;
1176 switch (_nCommandType)
1178 case CommandType::TABLE:
1179 pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_TABLES);
1180 break;
1182 case CommandType::QUERY:
1183 pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_QUERIES);
1184 break;
1187 if (_ppContainerEntry)
1188 *_ppContainerEntry = pCommandType;
1190 if (pCommandType)
1192 // expand if required so
1193 if (_bExpandAncestors)
1195 m_pTreeView->getListBox().Expand(pCommandType);
1198 // look for the object
1199 OUString sCommand = _rCommand;
1200 sal_Int32 nIndex = 0;
1203 OUString sPath;
1204 switch (_nCommandType)
1206 case CommandType::TABLE:
1207 sPath = sCommand;
1208 nIndex = -1;
1209 break;
1211 default:
1212 assert(false);
1213 // in non-debug builds, fall through.
1214 case CommandType::QUERY:
1215 sPath = sCommand.getToken( 0, '/', nIndex );
1216 break;
1218 pObject = m_pTreeView->getListBox().GetEntryPosByName(sPath, pCommandType);
1219 pCommandType = pObject;
1220 if ( nIndex >= 0 )
1222 if (ensureEntryObject(pObject))
1224 DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( pObject->GetUserData() );
1225 Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
1226 sal_Int32 nIndex2 = nIndex;
1227 sPath = sCommand.getToken( 0, '/', nIndex2 );
1230 if ( xCollection->hasByName(sPath) )
1232 if(!m_pTreeView->getListBox().GetEntryPosByName(sPath,pObject))
1234 Reference<XNameAccess> xChild(xCollection->getByName(sPath),UNO_QUERY);
1235 DBTreeListUserData* pEntryData = new DBTreeListUserData;
1236 pEntryData->eType = etQuery;
1237 if ( xChild.is() )
1239 pEntryData->eType = etQueryContainer;
1241 implAppendEntry( pObject, sPath, pEntryData, pEntryData->eType );
1245 catch(const Exception&)
1247 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::populateTree: could not fill the tree");
1252 while ( nIndex >= 0 );
1256 return pObject;
1259 SvTreeListEntry* SbaTableQueryBrowser::getObjectEntry(const svx::ODataAccessDescriptor& _rDescriptor,
1260 SvTreeListEntry** _ppDataSourceEntry, SvTreeListEntry** _ppContainerEntry,
1261 bool _bExpandAncestors)
1263 // extract the props from the descriptor
1264 OUString sDataSource;
1265 OUString sCommand;
1266 sal_Int32 nCommandType = CommandType::COMMAND;
1267 bool bEscapeProcessing = true;
1268 extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
1270 return getObjectEntry( sDataSource, sCommand, nCommandType, _ppDataSourceEntry, _ppContainerEntry, _bExpandAncestors, SharedConnection() );
1273 void SbaTableQueryBrowser::connectExternalDispatches()
1275 Reference< XDispatchProvider > xProvider( getFrame(), UNO_QUERY );
1276 OSL_ENSURE(xProvider.is(), "SbaTableQueryBrowser::connectExternalDispatches: no DispatchProvider !");
1277 if (xProvider.is())
1279 if ( m_aExternalFeatures.empty() )
1281 const sal_Char* pURLs[] = {
1282 ".uno:DataSourceBrowser/DocumentDataSource",
1283 ".uno:DataSourceBrowser/FormLetter",
1284 ".uno:DataSourceBrowser/InsertColumns",
1285 ".uno:DataSourceBrowser/InsertContent",
1287 const sal_uInt16 nIds[] = {
1288 ID_BROWSER_DOCUMENT_DATASOURCE,
1289 ID_BROWSER_FORMLETTER,
1290 ID_BROWSER_INSERTCOLUMNS,
1291 ID_BROWSER_INSERTCONTENT
1294 for ( size_t i=0; i < sizeof( pURLs ) / sizeof( pURLs[0] ); ++i )
1296 URL aURL;
1297 aURL.Complete = OUString::createFromAscii( pURLs[i] );
1298 if ( m_xUrlTransformer.is() )
1299 m_xUrlTransformer->parseStrict( aURL );
1300 m_aExternalFeatures[ nIds[ i ] ] = ExternalFeature( aURL );
1304 for ( ExternalFeaturesMap::iterator feature = m_aExternalFeatures.begin();
1305 feature != m_aExternalFeatures.end();
1306 ++feature
1309 feature->second.xDispatcher = xProvider->queryDispatch(
1310 feature->second.aURL, OUString("_parent"), FrameSearchFlag::PARENT
1313 if ( feature->second.xDispatcher.get() == static_cast< XDispatch* >( this ) )
1315 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::connectExternalDispatches: this should not happen anymore!" );
1316 // (nowadays, the URLs aren't in our SupportedFeatures list anymore, so we should
1317 // not supply a dispatcher for this)
1318 feature->second.xDispatcher.clear();
1321 if ( feature->second.xDispatcher.is() )
1325 feature->second.xDispatcher->addStatusListener( this, feature->second.aURL );
1327 catch( const Exception& )
1329 DBG_UNHANDLED_EXCEPTION();
1333 implCheckExternalSlot( feature->first );
1338 void SbaTableQueryBrowser::implCheckExternalSlot( sal_uInt16 _nId )
1340 if ( !m_xMainToolbar.is() )
1341 return;
1343 vcl::Window* pToolboxWindow = VCLUnoHelper::GetWindow( m_xMainToolbar );
1344 ToolBox* pToolbox = dynamic_cast< ToolBox* >( pToolboxWindow );
1345 OSL_ENSURE( pToolbox, "SbaTableQueryBrowser::implCheckExternalSlot: cannot obtain the toolbox window!" );
1347 // check if we have to hide this item from the toolbox
1348 if ( pToolbox )
1350 bool bHaveDispatcher = m_aExternalFeatures[ _nId ].xDispatcher.is();
1351 if ( bHaveDispatcher != pToolbox->IsItemVisible( _nId ) )
1352 bHaveDispatcher ? pToolbox->ShowItem( _nId ) : pToolbox->HideItem( _nId );
1355 // and invalidate this feature in general
1356 InvalidateFeature( _nId );
1359 void SAL_CALL SbaTableQueryBrowser::disposing( const com::sun::star::lang::EventObject& _rSource ) throw(RuntimeException, std::exception)
1361 // our frame ?
1362 Reference< ::com::sun::star::frame::XFrame > xSourceFrame(_rSource.Source, UNO_QUERY);
1363 if (m_xCurrentFrameParent.is() && (xSourceFrame == m_xCurrentFrameParent))
1364 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
1365 else
1367 // search the external dispatcher causing this call in our map
1368 Reference< XDispatch > xSource(_rSource.Source, UNO_QUERY);
1369 if(xSource.is())
1371 ExternalFeaturesMap::iterator aLoop = m_aExternalFeatures.begin();
1372 ExternalFeaturesMap::iterator aEnd = m_aExternalFeatures.end();
1373 while (aLoop != aEnd)
1375 ExternalFeaturesMap::iterator aI = aLoop++;
1376 if ( aI->second.xDispatcher.get() == xSource.get() )
1378 sal_uInt16 nSlot = aI->first;
1380 // remove it
1381 m_aExternalFeatures.erase(aI);
1383 // maybe update the UI
1384 implCheckExternalSlot(nSlot);
1386 // continue, the same XDispatch may be resposible for more than one URL
1390 else
1392 Reference<XConnection> xCon(_rSource.Source, UNO_QUERY);
1393 if ( xCon.is() && m_pTreeView )
1394 { // our connection is in dispose so we have to find the entry equal with this connection
1395 // and close it what means to collapse the entry
1396 // get the top-level representing the removed data source
1397 SvTreeListEntry* pDSLoop = m_pTreeView->getListBox().FirstChild(NULL);
1398 while (pDSLoop)
1400 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pDSLoop->GetUserData());
1401 if ( pData && pData->xConnection == xCon )
1403 // we set the connection to null to avoid a second disposing of the connection
1404 pData->xConnection.clear();
1405 closeConnection(pDSLoop,false);
1406 break;
1409 pDSLoop = SvTreeList::NextSibling(pDSLoop);
1412 else
1413 SbaXDataBrowserController::disposing(_rSource);
1418 void SbaTableQueryBrowser::implRemoveStatusListeners()
1420 // clear all old dispatches
1421 for ( ExternalFeaturesMap::const_iterator aLoop = m_aExternalFeatures.begin();
1422 aLoop != m_aExternalFeatures.end();
1423 ++aLoop
1426 if ( aLoop->second.xDispatcher.is() )
1430 aLoop->second.xDispatcher->removeStatusListener( this, aLoop->second.aURL );
1432 catch (Exception&)
1434 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::implRemoveStatusListeners: could not remove a status listener!");
1438 m_aExternalFeatures.clear();
1441 sal_Bool SAL_CALL SbaTableQueryBrowser::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException, std::exception)
1443 SolarMutexGuard aGuard;
1444 // doin' a lot of VCL stuff here -> lock the SolarMutex
1446 Sequence< PropertyValue > aDescriptorSequence;
1447 if (!(_rSelection >>= aDescriptorSequence))
1448 throw IllegalArgumentException(OUString(), *this, 1);
1449 // TODO: error message
1451 ODataAccessDescriptor aDescriptor;
1454 aDescriptor = ODataAccessDescriptor(aDescriptorSequence);
1456 catch(const Exception&)
1458 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::select: could not extract the descriptor!");
1461 // check the precense of the props we need
1462 if ( !(aDescriptor.has(daDataSource) || aDescriptor.has(daDatabaseLocation)) || !aDescriptor.has(daCommand) || !aDescriptor.has(daCommandType))
1463 throw IllegalArgumentException(OUString(), *this, 1);
1464 // TODO: error message
1466 return implSelect(aDescriptor,true);
1469 Any SAL_CALL SbaTableQueryBrowser::getSelection( ) throw (RuntimeException, std::exception)
1471 Any aReturn;
1475 Reference< XLoadable > xLoadable(getRowSet(), UNO_QUERY);
1476 if (xLoadable.is() && xLoadable->isLoaded())
1478 Reference< XPropertySet > aFormProps(getRowSet(), UNO_QUERY);
1479 ODataAccessDescriptor aDescriptor(aFormProps);
1480 // remove properties which are not part of our "selection"
1481 aDescriptor.erase(daConnection);
1482 aDescriptor.erase(daCursor);
1484 aReturn <<= aDescriptor.createPropertyValueSequence();
1487 catch( const Exception& )
1489 DBG_UNHANDLED_EXCEPTION();
1492 return aReturn;
1495 void SAL_CALL SbaTableQueryBrowser::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException, std::exception)
1497 m_aSelectionListeners.addInterface(_rxListener);
1500 void SAL_CALL SbaTableQueryBrowser::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException, std::exception)
1502 m_aSelectionListeners.removeInterface(_rxListener);
1505 void SbaTableQueryBrowser::attachFrame(const Reference< ::com::sun::star::frame::XFrame > & _xFrame) throw( RuntimeException, std::exception )
1507 implRemoveStatusListeners();
1509 if (m_xCurrentFrameParent.is())
1510 m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
1512 SbaXDataBrowserController::attachFrame(_xFrame);
1514 Reference< XFrame > xCurrentFrame( getFrame() );
1515 if ( xCurrentFrame.is() )
1517 m_xCurrentFrameParent = xCurrentFrame->findFrame(OUString("_parent"),FrameSearchFlag::PARENT);
1518 if ( m_xCurrentFrameParent.is() )
1519 m_xCurrentFrameParent->addFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this);
1521 // obtain our toolbox
1524 Reference< XPropertySet > xFrameProps( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW );
1525 Reference< XLayoutManager > xLayouter(
1526 xFrameProps->getPropertyValue("LayoutManager"),
1527 UNO_QUERY );
1529 if ( xLayouter.is() )
1531 Reference< XUIElement > xUI(
1532 xLayouter->getElement( OUString( "private:resource/toolbar/toolbar" ) ),
1533 UNO_SET_THROW );
1534 m_xMainToolbar.set(xUI->getRealInterface(), css::uno::UNO_QUERY);
1535 OSL_ENSURE( m_xMainToolbar.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" );
1538 catch( const Exception& )
1540 DBG_UNHANDLED_EXCEPTION();
1544 // get the dispatchers for the external slots
1545 connectExternalDispatches();
1548 void SbaTableQueryBrowser::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
1550 SbaXDataBrowserController::addModelListeners(_xGridControlModel);
1551 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1552 if (xSourceSet.is())
1554 xSourceSet->addPropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1555 xSourceSet->addPropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1556 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1557 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1558 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1559 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1564 void SbaTableQueryBrowser::removeModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel)
1566 SbaXDataBrowserController::removeModelListeners(_xGridControlModel);
1567 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1568 if (xSourceSet.is())
1570 xSourceSet->removePropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1571 xSourceSet->removePropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1572 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1573 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1574 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1575 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1579 void SbaTableQueryBrowser::RowChanged()
1581 if(getBrowserView())
1583 SbaGridControl* pControl = getBrowserView()->getVclControl();
1584 if (!pControl->IsEditing())
1585 InvalidateFeature(ID_BROWSER_COPY);
1587 SbaXDataBrowserController::RowChanged();
1590 void SbaTableQueryBrowser::ColumnChanged()
1592 if(getBrowserView())
1594 SbaGridControl* pControl = getBrowserView()->getVclControl();
1595 if (!pControl->IsEditing())
1596 InvalidateFeature(ID_BROWSER_COPY);
1598 SbaXDataBrowserController::ColumnChanged();
1601 void SbaTableQueryBrowser::AddColumnListener(const Reference< XPropertySet > & xCol)
1603 SbaXDataBrowserController::AddColumnListener(xCol);
1604 SafeAddPropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1605 SafeAddPropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1606 SafeAddPropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1607 SafeAddPropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1610 void SbaTableQueryBrowser::RemoveColumnListener(const Reference< XPropertySet > & xCol)
1612 SbaXDataBrowserController::RemoveColumnListener(xCol);
1613 SafeRemovePropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1614 SafeRemovePropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1615 SafeRemovePropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1616 SafeRemovePropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1619 void SbaTableQueryBrowser::criticalFail()
1621 SbaXDataBrowserController::criticalFail();
1622 unloadAndCleanup( false );
1625 void SbaTableQueryBrowser::LoadFinished(bool _bWasSynch)
1627 SbaXDataBrowserController::LoadFinished(_bWasSynch);
1629 m_sQueryCommand.clear();
1630 m_bQueryEscapeProcessing = false;
1632 if (isValid() && !loadingCancelled())
1634 // did we load a query?
1635 bool bTemporary; // needed because we m_bQueryEscapeProcessing is only one bit wide (and we want to pass it by reference)
1636 if ( implGetQuerySignature( m_sQueryCommand, bTemporary ) )
1637 m_bQueryEscapeProcessing = bTemporary;
1640 // if the form has been loaded, this means that our "selection" has changed
1641 com::sun::star::lang::EventObject aEvent( *this );
1642 m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent );
1645 bool SbaTableQueryBrowser::getExternalSlotState( sal_uInt16 _nId ) const
1647 bool bEnabled = false;
1648 ExternalFeaturesMap::const_iterator aPos = m_aExternalFeatures.find( _nId );
1649 if ( ( m_aExternalFeatures.end() != aPos ) && aPos->second.xDispatcher.is() )
1650 bEnabled = aPos->second.bEnabled;
1651 return bEnabled;
1654 FeatureState SbaTableQueryBrowser::GetState(sal_uInt16 nId) const
1656 FeatureState aReturn;
1657 // (disabled automatically)
1659 // no chance without a view
1660 if (!getBrowserView() || !getBrowserView()->getVclControl())
1661 return aReturn;
1663 switch ( nId )
1665 case ID_TREE_ADMINISTRATE:
1666 aReturn.bEnabled = true;
1667 return aReturn;
1669 case ID_BROWSER_CLOSE:
1670 // the close button should always be enabled
1671 aReturn.bEnabled = !m_bEnableBrowser;
1672 return aReturn;
1674 // "toggle explorer" is always enabled (if we have a explorer)
1675 case ID_BROWSER_EXPLORER:
1676 aReturn.bEnabled = m_bEnableBrowser;
1677 aReturn.bChecked = haveExplorer();
1678 return aReturn;
1680 case ID_BROWSER_REMOVEFILTER:
1681 return SbaXDataBrowserController::GetState( nId );
1683 case ID_BROWSER_COPY:
1684 if ( !m_pTreeView->HasChildPathFocus() )
1685 // handled below
1686 break;
1687 // NO break!
1688 case ID_TREE_CLOSE_CONN:
1689 case ID_TREE_EDIT_DATABASE:
1691 SvTreeListEntry* pCurrentEntry( m_pTreeView->getListBox().GetCurEntry() );
1692 EntryType eType = getEntryType( pCurrentEntry );
1693 if ( eType == etUnknown )
1694 return aReturn;
1696 SvTreeListEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent( pCurrentEntry );
1697 DBTreeListUserData* pDSData
1698 = pDataSourceEntry
1699 ? static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() )
1700 : NULL;
1702 if ( nId == ID_TREE_CLOSE_CONN )
1704 aReturn.bEnabled = ( pDSData != NULL ) && pDSData->xConnection.is();
1706 else if ( nId == ID_TREE_EDIT_DATABASE )
1708 ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithComponentContext( getORB(),
1709 OUString( "/org.openoffice.Office.DataAccess/Policies/Features/Common" ) ) );
1710 bool bHaveEditDatabase( true );
1711 OSL_VERIFY( aConfig.getNodeValue( "EditDatabaseFromDataSourceView" ) >>= bHaveEditDatabase );
1712 aReturn.bEnabled = getORB().is() && ( pDataSourceEntry != NULL ) && bHaveEditDatabase;
1714 else if ( nId == ID_BROWSER_COPY )
1716 aReturn.bEnabled = isEntryCopyAllowed( pCurrentEntry );
1719 return aReturn;
1723 // all slots not handled above are not available if no form is loaded
1724 if (!isLoaded())
1725 return aReturn;
1729 bool bHandled = false;
1730 switch (nId)
1732 case ID_BROWSER_DOCUMENT_DATASOURCE:
1733 // the slot is enabled if we have an external dispatcher able to handle it,
1734 // and the dispatcher must have enabled the slot in general
1735 aReturn.bEnabled = getExternalSlotState( ID_BROWSER_DOCUMENT_DATASOURCE );
1736 bHandled = true;
1737 break;
1738 case ID_BROWSER_REFRESH:
1739 aReturn.bEnabled = true;
1740 bHandled = true;
1741 break;
1744 if (bHandled)
1745 return aReturn;
1747 // no chance without valid models
1748 if (isValid() && !isValidCursor() && nId != ID_BROWSER_CLOSE)
1749 return aReturn;
1751 switch (nId)
1753 case ID_BROWSER_INSERTCOLUMNS:
1754 case ID_BROWSER_INSERTCONTENT:
1755 case ID_BROWSER_FORMLETTER:
1757 // the slot is enabled if we have an external dispatcher able to handle it,
1758 // and the dispatcher must have enabled the slot in general
1759 aReturn.bEnabled = getExternalSlotState( nId );
1761 // for the Insert* slots, we need at least one selected row
1762 if (ID_BROWSER_FORMLETTER != nId)
1763 aReturn.bEnabled = aReturn.bEnabled && getBrowserView()->getVclControl()->GetSelectRowCount();
1765 // disabled for native queries which are not saved within the database
1766 Reference< XPropertySet > xDataSource(getRowSet(), UNO_QUERY);
1769 aReturn.bEnabled = aReturn.bEnabled && xDataSource.is();
1771 if (xDataSource.is())
1773 sal_Int32 nType = ::comphelper::getINT32(xDataSource->getPropertyValue(PROPERTY_COMMAND_TYPE));
1774 aReturn.bEnabled = aReturn.bEnabled && ((::comphelper::getBOOL(xDataSource->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || (nType == ::com::sun::star::sdb::CommandType::QUERY)));
1777 catch(DisposedException&)
1779 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::GetState: object already disposed!");
1781 catch( const Exception& )
1783 DBG_UNHANDLED_EXCEPTION();
1786 break;
1788 case ID_BROWSER_TITLE:
1790 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1791 sal_Int32 nCommandType = CommandType::TABLE;
1792 xProp->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nCommandType;
1793 OUString sTitle;
1794 switch (nCommandType)
1796 case CommandType::TABLE:
1797 sTitle = OUString(ModuleRes(STR_TBL_TITLE)); break;
1798 case CommandType::QUERY:
1799 case CommandType::COMMAND:
1800 sTitle = OUString(ModuleRes(STR_QRY_TITLE)); break;
1801 default:
1802 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::GetState: unknown command type!");
1804 OUString aName;
1805 xProp->getPropertyValue(PROPERTY_COMMAND) >>= aName;
1806 OUString sObject(aName);
1808 aReturn.sTitle = sTitle.replaceFirst(OUString('#'), sObject);
1809 aReturn.bEnabled = true;
1811 break;
1812 case ID_BROWSER_TABLEATTR:
1813 case ID_BROWSER_ROWHEIGHT:
1814 case ID_BROWSER_COLATTRSET:
1815 case ID_BROWSER_COLWIDTH:
1816 aReturn.bEnabled = getBrowserView() && getBrowserView()->getVclControl() && isValid() && isValidCursor();
1817 // aReturn.bEnabled &= getDefinition() && !getDefinition()->GetDatabase()->IsReadOnly();
1818 break;
1820 case ID_BROWSER_COPY:
1821 OSL_ENSURE( !m_pTreeView->HasChildPathFocus(), "SbaTableQueryBrowser::GetState( ID_BROWSER_COPY ): this should have been handled above!" );
1822 if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing())
1824 SbaGridControl* pControl = getBrowserView()->getVclControl();
1825 if ( pControl->GetSelectRowCount() )
1827 aReturn.bEnabled = m_aCurrentFrame.isActive();
1828 break;
1830 else
1831 aReturn.bEnabled = pControl->canCopyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
1832 break;
1834 // NO break here
1835 default:
1836 return SbaXDataBrowserController::GetState(nId);
1839 catch(const Exception&)
1841 DBG_UNHANDLED_EXCEPTION();
1844 return aReturn;
1848 void SbaTableQueryBrowser::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& aArgs)
1850 switch (nId)
1852 default:
1853 SbaXDataBrowserController::Execute(nId,aArgs);
1854 break;
1856 case ID_TREE_EDIT_DATABASE:
1857 implAdministrate( m_pTreeView->getListBox().GetCurEntry() );
1858 break;
1860 case ID_TREE_CLOSE_CONN:
1861 openHelpAgent( OString( HID_DSBROWSER_DISCONNECTING ));
1862 closeConnection( m_pTreeView->getListBox().GetRootLevelParent( m_pTreeView->getListBox().GetCurEntry() ) );
1863 break;
1865 case ID_TREE_ADMINISTRATE:
1866 svx::administrateDatabaseRegistration( getView() );
1867 break;
1869 case ID_BROWSER_REFRESH:
1871 if ( !SaveModified( ) )
1872 // nothing to do
1873 break;
1875 bool bFullReinit = false;
1876 // check if the query signature (if the form is based on a query) has changed
1877 if ( !m_sQueryCommand.isEmpty() )
1879 OUString sNewQueryCommand;
1880 bool bNewQueryEP;
1882 #if OSL_DEBUG_LEVEL > 0
1883 bool bIsQuery =
1884 #endif
1885 implGetQuerySignature( sNewQueryCommand, bNewQueryEP );
1886 OSL_ENSURE( bIsQuery, "SbaTableQueryBrowser::Execute: was a query before, but is not anymore?" );
1888 bFullReinit = ( sNewQueryCommand != m_sQueryCommand ) || ( m_bQueryEscapeProcessing != bNewQueryEP );
1890 if ( !bFullReinit )
1892 // let the base class do a simple reload
1893 SbaXDataBrowserController::Execute(nId,aArgs);
1894 break;
1896 // NO break here!
1899 case ID_BROWSER_REFRESH_REBUILD:
1901 if ( !SaveModified() )
1902 // nothing to do
1903 break;
1905 SvTreeListEntry* pSelected = m_pCurrentlyDisplayed;
1906 // unload
1907 unloadAndCleanup( false );
1909 // reselect the entry
1910 if ( pSelected )
1912 implSelect( pSelected );
1914 else
1916 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1917 implSelect(svx::ODataAccessDescriptor(xProp));
1920 break;
1922 case ID_BROWSER_EXPLORER:
1923 toggleExplorer();
1924 break;
1926 case ID_BROWSER_DOCUMENT_DATASOURCE:
1927 implSelect(m_aDocumentDataSource);
1928 break;
1930 case ID_BROWSER_INSERTCOLUMNS:
1931 case ID_BROWSER_INSERTCONTENT:
1932 case ID_BROWSER_FORMLETTER:
1933 if (getBrowserView() && isValidCursor())
1935 // the URL the slot id is assigned to
1936 OSL_ENSURE( m_aExternalFeatures.find( nId ) != m_aExternalFeatures.end(),
1937 "SbaTableQueryBrowser::Execute( ID_BROWSER_?): how could this ever be enabled?" );
1938 URL aParentUrl = m_aExternalFeatures[ nId ].aURL;
1940 // let the dispatcher execute the slot
1941 Reference< XDispatch > xDispatch( m_aExternalFeatures[ nId ].xDispatcher );
1942 if (xDispatch.is())
1944 // set the properties for the dispatch
1946 // first fill the selection
1947 SbaGridControl* pGrid = getBrowserView()->getVclControl();
1948 MultiSelection* pSelection = const_cast<MultiSelection*>(pGrid->GetSelection());
1949 Sequence< Any > aSelection;
1950 if ( !pGrid->IsAllSelected() )
1951 { // transfer the selected rows only if not all rows are selected
1952 // (all rows means the whole table)
1953 // #i3832#
1954 if (pSelection != NULL)
1956 aSelection.realloc(pSelection->GetSelectCount());
1957 long nIdx = pSelection->FirstSelected();
1958 Any* pSelectionNos = aSelection.getArray();
1959 while (nIdx >= 0)
1961 *pSelectionNos++ <<= (sal_Int32)(nIdx + 1);
1962 nIdx = pSelection->NextSelected();
1967 Reference< XResultSet > xCursorClone;
1970 Reference< XResultSetAccess > xResultSetAccess(getRowSet(),UNO_QUERY);
1971 if (xResultSetAccess.is())
1972 xCursorClone = xResultSetAccess->createResultSet();
1974 catch(DisposedException&)
1976 SAL_WARN("dbaccess.ui", "Object already disposed!");
1978 catch(const Exception&)
1980 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not clone the cursor!");
1983 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1987 ODataAccessDescriptor aDescriptor;
1988 OUString sDataSourceName;
1989 xProp->getPropertyValue(PROPERTY_DATASOURCENAME) >>= sDataSourceName;
1991 aDescriptor.setDataSource(sDataSourceName);
1992 aDescriptor[daCommand] = xProp->getPropertyValue(PROPERTY_COMMAND);
1993 aDescriptor[daCommandType] = xProp->getPropertyValue(PROPERTY_COMMAND_TYPE);
1994 aDescriptor[daConnection] = xProp->getPropertyValue(PROPERTY_ACTIVE_CONNECTION);
1995 aDescriptor[daCursor] <<= xCursorClone;
1996 if ( aSelection.getLength() )
1998 aDescriptor[daSelection] <<= aSelection;
1999 aDescriptor[daBookmarkSelection] <<= sal_False;
2000 // these are selection indices
2001 // before we change this, all clients have to be adjusted
2002 // so that they recognize the new BookmarkSelection property!
2005 xDispatch->dispatch(aParentUrl, aDescriptor.createPropertyValueSequence());
2007 catch( const Exception& )
2009 DBG_UNHANDLED_EXCEPTION();
2013 break;
2015 case ID_BROWSER_CLOSE:
2016 closeTask();
2017 // if it's not 0, such a async close is already pending
2018 break;
2020 case ID_BROWSER_COPY:
2021 if(m_pTreeView->HasChildPathFocus())
2023 copyEntry(m_pTreeView->getListBox().GetCurEntry());
2025 else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing() && getBrowserView()->getVclControl()->GetSelectRowCount() < 1)
2027 SbaGridControl* pControl = getBrowserView()->getVclControl();
2028 pControl->copyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
2030 else
2031 SbaXDataBrowserController::Execute(nId,aArgs);
2032 break;
2036 void SbaTableQueryBrowser::implAddDatasource( const OUString& _rDataSourceName, const SharedConnection& _rxConnection )
2038 Image a, b, c;
2039 OUString d, e;
2040 implAddDatasource( _rDataSourceName, a, d, b, e, c, _rxConnection );
2043 void SbaTableQueryBrowser::implAddDatasource(const OUString& _rDbName, Image& _rDbImage,
2044 OUString& _rQueryName, Image& _rQueryImage, OUString& _rTableName, Image& _rTableImage,
2045 const SharedConnection& _rxConnection)
2047 SolarMutexGuard aGuard;
2048 // initialize the names/images if necessary
2049 if (_rQueryName.isEmpty())
2050 _rQueryName = OUString(ModuleRes(RID_STR_QUERIES_CONTAINER));
2051 if (_rTableName.isEmpty())
2052 _rTableName = OUString(ModuleRes(RID_STR_TABLES_CONTAINER));
2054 ImageProvider aImageProvider;
2055 if (!_rQueryImage)
2056 _rQueryImage = ImageProvider::getFolderImage( DatabaseObject::QUERY );
2057 if (!_rTableImage)
2058 _rTableImage = ImageProvider::getFolderImage( DatabaseObject::TABLE );
2060 if (!_rDbImage)
2061 _rDbImage = ImageProvider::getDatabaseImage();
2063 // add the entry for the data source
2064 // special handling for data sources denoted by URLs - we do not want to display this ugly URL, do we?
2065 // #i33699#
2066 OUString sDSDisplayName, sDataSourceId;
2067 getDataSourceDisplayName_isURL( _rDbName, sDSDisplayName, sDataSourceId );
2069 SvTreeListEntry* pDatasourceEntry = m_pTreeView->getListBox().InsertEntry( sDSDisplayName, _rDbImage, _rDbImage, NULL, false );
2070 DBTreeListUserData* pDSData = new DBTreeListUserData;
2071 pDSData->eType = etDatasource;
2072 pDSData->sAccessor = sDataSourceId;
2073 pDSData->xConnection = _rxConnection;
2074 pDatasourceEntry->SetUserData(pDSData);
2076 // the child for the queries container
2078 DBTreeListUserData* pQueriesData = new DBTreeListUserData;
2079 pQueriesData->eType = etQueryContainer;
2081 m_pTreeView->getListBox().InsertEntry(
2082 _rQueryName, _rQueryImage, _rQueryImage, pDatasourceEntry,
2083 true /*ChildrenOnDemand*/, TREELIST_APPEND, pQueriesData );
2086 // the child for the tables container
2088 DBTreeListUserData* pTablesData = new DBTreeListUserData;
2089 pTablesData->eType = etTableContainer;
2091 m_pTreeView->getListBox().InsertEntry(
2092 _rTableName, _rTableImage, _rTableImage, pDatasourceEntry,
2093 true /*ChildrenOnDemand*/, TREELIST_APPEND, pTablesData );
2098 void SbaTableQueryBrowser::initializeTreeModel()
2100 if (m_xDatabaseContext.is())
2102 Image aDBImage, aQueriesImage, aTablesImage;
2103 OUString sQueriesName, sTablesName;
2105 // fill the model with the names of the registered datasources
2106 Sequence< OUString > aDatasources = m_xDatabaseContext->getElementNames();
2107 const OUString* pIter = aDatasources.getConstArray();
2108 const OUString* pEnd = pIter + aDatasources.getLength();
2109 for (; pIter != pEnd; ++pIter)
2110 implAddDatasource( *pIter, aDBImage, sQueriesName, aQueriesImage, sTablesName, aTablesImage, SharedConnection() );
2114 void SbaTableQueryBrowser::populateTree(const Reference<XNameAccess>& _xNameAccess,
2115 SvTreeListEntry* _pParent,
2116 EntryType _eEntryType)
2118 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pParent->GetUserData());
2119 if(pData) // don't ask if the nameaccess is already set see OnExpandEntry views and tables
2120 pData->xContainer = _xNameAccess;
2124 Sequence< OUString > aNames = _xNameAccess->getElementNames();
2125 const OUString* pIter = aNames.getConstArray();
2126 const OUString* pEnd = pIter + aNames.getLength();
2127 for (; pIter != pEnd; ++pIter)
2129 if( !m_pTreeView->getListBox().GetEntryPosByName(*pIter,_pParent))
2131 DBTreeListUserData* pEntryData = new DBTreeListUserData;
2132 pEntryData->eType = _eEntryType;
2133 if ( _eEntryType == etQuery )
2135 Reference<XNameAccess> xChild(_xNameAccess->getByName(*pIter),UNO_QUERY);
2136 if ( xChild.is() )
2137 pEntryData->eType = etQueryContainer;
2139 implAppendEntry( _pParent, *pIter, pEntryData, pEntryData->eType );
2143 catch(const Exception&)
2145 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::populateTree: could not fill the tree");
2149 SvTreeListEntry* SbaTableQueryBrowser::implAppendEntry( SvTreeListEntry* _pParent, const OUString& _rName, void* _pUserData, EntryType _eEntryType )
2151 ::std::unique_ptr< ImageProvider > pImageProvider( getImageProviderFor( _pParent ) );
2153 Image aImage;
2154 pImageProvider->getImages( _rName, getDatabaseObjectType( _eEntryType ), aImage );
2156 SvTreeListEntry* pNewEntry = m_pTreeView->getListBox().InsertEntry( _rName, _pParent, _eEntryType == etQueryContainer , TREELIST_APPEND, _pUserData );
2158 m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImage );
2159 m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImage );
2161 return pNewEntry;
2164 IMPL_LINK(SbaTableQueryBrowser, OnExpandEntry, SvTreeListEntry*, _pParent)
2166 if (_pParent->HasChildren())
2167 // nothing to do...
2168 return 1L;
2170 SvTreeListEntry* pFirstParent = m_pTreeView->getListBox().GetRootLevelParent(_pParent);
2171 OSL_ENSURE(pFirstParent,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!");
2173 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >(_pParent->GetUserData());
2174 assert(pData && "SbaTableQueryBrowser::OnExpandEntry: No user data!");
2175 #if OSL_DEBUG_LEVEL > 0
2176 SvLBoxString* pString = static_cast<SvLBoxString*>(pFirstParent->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2177 OSL_ENSURE(pString,"SbaTableQueryBrowser::OnExpandEntry: No string item!");
2178 #endif
2180 if (etTableContainer == pData->eType)
2182 WaitObject aWaitCursor(getBrowserView());
2184 // it could be that we already have a connection
2185 SharedConnection xConnection;
2186 ensureConnection( pFirstParent, xConnection );
2188 if ( xConnection.is() )
2190 SQLExceptionInfo aInfo;
2193 Reference< XWarningsSupplier > xWarnings(xConnection, UNO_QUERY);
2194 if (xWarnings.is())
2195 xWarnings->clearWarnings();
2197 // first insert the views because the tables can also include
2198 // views but that time the bitmap is the wrong one
2199 // the nameaccess will be overwritten in populateTree
2200 Reference<XViewsSupplier> xViewSup(xConnection,UNO_QUERY);
2201 if(xViewSup.is())
2202 populateTree( xViewSup->getViews(), _pParent, etTableOrView );
2204 Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY);
2205 if(xTabSup.is())
2207 populateTree( xTabSup->getTables(), _pParent, etTableOrView );
2208 Reference<XContainer> xCont(xTabSup->getTables(),UNO_QUERY);
2209 if(xCont.is())
2210 // add as listener to know when elements are inserted or removed
2211 xCont->addContainerListener(this);
2214 if (xWarnings.is())
2216 SQLExceptionInfo aWarnings(xWarnings->getWarnings());
2217 #if 0
2218 // Obviously this if test is always false. So to avoid a Clang warning
2219 // "use of logical '&&' with constant operand" I put this in #if
2220 // 0. Yeah, I know it is fairly likely nobody will ever read this
2221 // comment and make a decision what to do here, so I could as well
2222 // have just binned this...
2223 if (aWarnings.isValid() && sal_False)
2225 SQLContext aContext;
2226 aContext.Message = String(ModuleRes(STR_OPENTABLES_WARNINGS));
2227 aContext.Details = String(ModuleRes(STR_OPENTABLES_WARNINGS_DETAILS));
2228 aContext.NextException = aWarnings.get();
2229 aWarnings = aContext;
2230 showError(aWarnings);
2232 #endif
2233 // TODO: we need a better concept for these warnings:
2234 // something like "don't show any warnings for this datasource, again" would be nice
2235 // But this requires an extension of the InteractionHandler and an additional property on the data source
2238 catch(const SQLContext& e) { aInfo = e; }
2239 catch(const SQLWarning& e) { aInfo = e; }
2240 catch(const SQLException& e) { aInfo = e; }
2241 catch(const WrappedTargetException& e)
2243 SQLException aSql;
2244 if(e.TargetException >>= aSql)
2245 aInfo = aSql;
2246 else
2247 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnExpandEntry: something strange happened!");
2249 catch( const Exception& )
2251 DBG_UNHANDLED_EXCEPTION();
2253 if (aInfo.isValid())
2254 showError(aInfo);
2256 else
2257 return 0L;
2258 // 0 indicates that an error occurred
2260 else
2261 { // we have to expand the queries or bookmarks
2262 if (ensureEntryObject(_pParent))
2264 DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( _pParent->GetUserData() );
2265 Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
2266 populateTree( xCollection, _pParent, etQuery );
2269 return 1L;
2272 bool SbaTableQueryBrowser::ensureEntryObject( SvTreeListEntry* _pEntry )
2274 OSL_ENSURE(_pEntry, "SbaTableQueryBrowser::ensureEntryObject: invalid argument!");
2275 if (!_pEntry)
2276 return false;
2278 EntryType eType = getEntryType( _pEntry );
2280 // the user data of the entry
2281 DBTreeListUserData* pEntryData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData());
2282 OSL_ENSURE(pEntryData,"ensureEntryObject: user data should already be set!");
2284 SvTreeListEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(_pEntry);
2286 bool bSuccess = false;
2287 switch (eType)
2289 case etQueryContainer:
2290 if ( pEntryData->xContainer.is() )
2292 // nothing to do
2293 bSuccess = true;
2294 break;
2298 SvTreeListEntry* pParent = m_pTreeView->getListBox().GetParent(_pEntry);
2299 if ( pParent != pDataSourceEntry )
2301 SvLBoxString* pString = static_cast<SvLBoxString*>(_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2302 OSL_ENSURE(pString,"There must be a string item!");
2303 OUString aName(pString->GetText());
2304 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pParent->GetUserData());
2307 Reference< XNameAccess > xNameAccess(pData->xContainer,UNO_QUERY);
2308 if ( xNameAccess.is() )
2309 pEntryData->xContainer.set(xNameAccess->getByName(aName),UNO_QUERY);
2311 catch(const Exception& )
2313 DBG_UNHANDLED_EXCEPTION();
2316 bSuccess = pEntryData->xContainer.is();
2318 else
2322 Reference< XQueryDefinitionsSupplier > xQuerySup;
2323 m_xDatabaseContext->getByName( getDataSourceAcessor( pDataSourceEntry ) ) >>= xQuerySup;
2324 if (xQuerySup.is())
2326 Reference< XNameAccess > xQueryDefs = xQuerySup->getQueryDefinitions();
2327 Reference< XContainer > xCont(xQueryDefs, UNO_QUERY);
2328 if (xCont.is())
2329 // add as listener to get notified if elements are inserted or removed
2330 xCont->addContainerListener(this);
2332 pEntryData->xContainer = xQueryDefs;
2333 bSuccess = pEntryData->xContainer.is();
2335 else {
2336 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::ensureEntryObject: no XQueryDefinitionsSupplier interface!");
2339 catch( const Exception& )
2341 DBG_UNHANDLED_EXCEPTION();
2345 break;
2347 default:
2348 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::ensureEntryObject: ooops ... missing some implementation here!");
2349 // TODO ...
2350 break;
2353 return bSuccess;
2356 bool SbaTableQueryBrowser::implSelect(const svx::ODataAccessDescriptor& _rDescriptor, bool _bSelectDirect)
2358 // extract the props
2359 OUString sDataSource;
2360 OUString sCommand;
2361 sal_Int32 nCommandType = CommandType::COMMAND;
2362 bool bEscapeProcessing = true;
2363 extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
2365 // select it
2366 return implSelect( sDataSource, sCommand, nCommandType, bEscapeProcessing, SharedConnection(), _bSelectDirect );
2369 bool SbaTableQueryBrowser::implLoadAnything(const OUString& _rDataSourceName, const OUString& _rCommand,
2370 const sal_Int32 _nCommandType, const bool _bEscapeProcessing, const SharedConnection& _rxConnection)
2374 Reference<XPropertySet> xProp( getRowSet(), UNO_QUERY_THROW );
2375 Reference< XLoadable > xLoadable( xProp, UNO_QUERY_THROW );
2376 // the values allowing the RowSet to re-execute
2377 xProp->setPropertyValue(PROPERTY_DATASOURCENAME, makeAny(_rDataSourceName));
2378 if(_rxConnection.is())
2379 xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( _rxConnection.getTyped() ) );
2381 // set this _before_ setting the connection, else the rowset would rebuild it ...
2382 xProp->setPropertyValue(PROPERTY_COMMAND_TYPE, makeAny(_nCommandType));
2383 xProp->setPropertyValue(PROPERTY_COMMAND, makeAny(_rCommand));
2384 xProp->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, css::uno::makeAny(_bEscapeProcessing));
2385 if ( m_bPreview )
2387 xProp->setPropertyValue(PROPERTY_FETCHDIRECTION, makeAny(FetchDirection::FORWARD));
2390 // the formatter depends on the data source we're working on, so rebuild it here ...
2391 initFormatter();
2393 // switch the grid to design mode while loading
2394 getBrowserView()->getGridControl()->setDesignMode(sal_True);
2395 InitializeForm( xProp );
2397 bool bSuccess = true;
2401 Reference< XNameContainer > xColContainer(getFormComponent(), UNO_QUERY);
2402 // first we have to clear the grid
2403 clearGridColumns(xColContainer);
2405 FormErrorHelper aHelper(this);
2406 // load the form
2407 bSuccess = reloadForm(xLoadable);
2409 // initialize the model
2410 InitializeGridModel(getFormComponent());
2412 Any aVal = xProp->getPropertyValue(PROPERTY_ISNEW);
2413 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2415 // then set the default values and the parameters given from the parent
2416 Reference< XReset> xReset(xProp, UNO_QUERY);
2417 xReset->reset();
2420 if ( m_bPreview )
2421 initializePreviewMode();
2423 LoadFinished(true);
2426 InvalidateAll();
2427 return bSuccess;
2429 catch( const SQLException& )
2431 Any aException( ::cppu::getCaughtException() );
2432 showError( SQLExceptionInfo( aException ) );
2434 catch( const WrappedTargetException& e )
2436 SQLException aSql;
2437 if ( e.TargetException.isExtractableTo( ::cppu::UnoType< SQLException >::get() ) )
2438 showError( SQLExceptionInfo( e.TargetException ) );
2439 else
2441 DBG_UNHANDLED_EXCEPTION();
2444 catch(const Exception&)
2446 DBG_UNHANDLED_EXCEPTION();
2449 InvalidateAll();
2450 return false;
2453 bool SbaTableQueryBrowser::implSelect(const OUString& _rDataSourceName, const OUString& _rCommand,
2454 const sal_Int32 _nCommandType, const bool _bEscapeProcessing,
2455 const SharedConnection& _rxConnection,
2456 bool _bSelectDirect)
2458 if (_rDataSourceName.getLength() && _rCommand.getLength() && (-1 != _nCommandType))
2460 SvTreeListEntry* pDataSource = NULL;
2461 SvTreeListEntry* pCommandType = NULL;
2462 SvTreeListEntry* pCommand = getObjectEntry( _rDataSourceName, _rCommand, _nCommandType, &pDataSource, &pCommandType, true, _rxConnection );
2464 if (pCommand)
2466 bool bSuccess = true;
2467 if ( _bSelectDirect )
2469 bSuccess = implSelect( pCommand );
2471 else
2473 m_pTreeView->getListBox().Select( pCommand );
2476 if ( bSuccess )
2478 m_pTreeView->getListBox().MakeVisible(pCommand);
2479 m_pTreeView->getListBox().SetCursor(pCommand);
2482 else if (!pCommandType)
2484 if ( m_pCurrentlyDisplayed )
2485 { // tell the old entry (if any) it has been deselected
2486 selectPath(m_pCurrentlyDisplayed, false);
2487 m_pCurrentlyDisplayed = NULL;
2490 // we have a command and need to display this in the rowset
2491 return implLoadAnything(_rDataSourceName, _rCommand, _nCommandType, _bEscapeProcessing, _rxConnection);
2494 return false;
2497 IMPL_LINK_NOARG(SbaTableQueryBrowser, OnSelectionChange)
2499 return implSelect( m_pTreeView->getListBox().FirstSelected() ) ? 1L : 0L;
2502 SvTreeListEntry* SbaTableQueryBrowser::implGetConnectionEntry(SvTreeListEntry* _pEntry) const
2504 SvTreeListEntry* pCurrentEntry = _pEntry;
2505 DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() );
2506 while(pEntryData->eType != etDatasource )
2508 pCurrentEntry = m_pTreeModel->GetParent(pCurrentEntry);
2509 pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() );
2511 return pCurrentEntry;
2514 bool SbaTableQueryBrowser::implSelect( SvTreeListEntry* _pEntry )
2516 if ( !_pEntry )
2517 return false;
2519 DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() );
2520 switch (pEntryData->eType)
2522 case etTableOrView:
2523 case etQuery:
2524 break;
2525 default:
2526 // nothing to do
2527 return false;
2530 OSL_ENSURE(m_pTreeModel->HasParent(_pEntry), "SbaTableQueryBrowser::implSelect: invalid entry (1)!");
2531 OSL_ENSURE(m_pTreeModel->HasParent(m_pTreeModel->GetParent(_pEntry)), "SbaTableQueryBrowser::implSelect: invalid entry (2)!");
2533 // get the entry for the tables or queries
2534 SvTreeListEntry* pContainer = m_pTreeModel->GetParent(_pEntry);
2535 DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2537 // get the entry for the datasource
2538 SvTreeListEntry* pConnection = implGetConnectionEntry(pContainer);
2539 DBTreeListUserData* pConData = static_cast<DBTreeListUserData*>(pConnection->GetUserData());
2541 // reinitialize the rowset
2542 // but first check if it is necessary
2543 // get all old properties
2544 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
2545 OUString aOldName;
2546 xRowSetProps->getPropertyValue(PROPERTY_COMMAND) >>= aOldName;
2547 sal_Int32 nOldType = 0;
2548 xRowSetProps->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nOldType;
2549 Reference<XConnection> xOldConnection(xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
2551 // the name of the table or query
2552 SvLBoxString* pString = static_cast<SvLBoxString*>(_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2553 OSL_ENSURE(pString,"There must be a string item!");
2554 const OUString sSimpleName = pString->GetText();
2555 OUStringBuffer sNameBuffer(sSimpleName);
2556 if ( etQueryContainer == pContainerData->eType )
2558 SvTreeListEntry* pTemp = pContainer;
2559 while( m_pTreeModel->GetParent(pTemp) != pConnection )
2561 sNameBuffer.insert(0,'/');
2562 pString = static_cast<SvLBoxString*>(pTemp->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING));
2563 OSL_ENSURE(pString,"There must be a string item!");
2564 sNameBuffer.insert(0,pString->GetText());
2565 pTemp = m_pTreeModel->GetParent(pTemp);
2568 OUString aName = sNameBuffer.makeStringAndClear();
2570 sal_Int32 nCommandType = ( etTableContainer == pContainerData->eType)
2571 ? CommandType::TABLE
2572 : CommandType::QUERY;
2574 // check if need to rebuild the rowset
2575 bool bRebuild = ( xOldConnection != pConData->xConnection )
2576 || ( nOldType != nCommandType )
2577 || ( aName != aOldName );
2579 Reference< ::com::sun::star::form::XLoadable > xLoadable = getLoadable();
2580 bRebuild |= !xLoadable->isLoaded();
2581 bool bSuccess = true;
2582 if ( bRebuild )
2586 WaitObject aWaitCursor(getBrowserView());
2588 // tell the old entry it has been deselected
2589 selectPath(m_pCurrentlyDisplayed, false);
2590 m_pCurrentlyDisplayed = NULL;
2592 // not really loaded
2593 m_pCurrentlyDisplayed = _pEntry;
2594 // tell the new entry it has been selected
2595 selectPath(m_pCurrentlyDisplayed, true);
2597 // get the name of the data source currently selected
2598 ensureConnection( m_pCurrentlyDisplayed, pConData->xConnection );
2600 if ( !pConData->xConnection.is() )
2602 unloadAndCleanup( false );
2603 return false;
2606 Reference<XNameAccess> xNameAccess;
2607 switch(nCommandType)
2609 case CommandType::TABLE:
2611 // only for tables
2612 if ( !pContainerData->xContainer.is() )
2614 Reference<XTablesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2615 if(xSup.is())
2616 xNameAccess = xSup->getTables();
2618 pContainerData->xContainer = xNameAccess;
2620 else
2621 xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2623 break;
2624 case CommandType::QUERY:
2626 if ( pContainerData->xContainer.is() )
2627 xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2628 else
2630 Reference<XQueriesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2631 if(xSup.is())
2632 xNameAccess = xSup->getQueries();
2635 break;
2637 OUString sStatus(ModuleRes( CommandType::TABLE == nCommandType ? STR_LOADING_TABLE : STR_LOADING_QUERY ));
2638 sStatus = sStatus.replaceFirst("$name$", aName);
2639 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sStatus);
2641 bool bEscapeProcessing = true;
2642 if(xNameAccess.is() && xNameAccess->hasByName(sSimpleName))
2644 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData());
2645 if ( !pData->xObjectProperties.is() )
2647 Reference<XInterface> xObject;
2648 if(xNameAccess->getByName(sSimpleName) >>= xObject) // remember the table or query object
2650 pData->xObjectProperties.set(xObject, css::uno::UNO_QUERY);
2651 // if the query contains a parameterized statement and preview is enabled we won't get any data.
2652 if ( nCommandType == CommandType::QUERY && xObject.is() )
2654 Reference<XPropertySet> xObjectProps(xObject,UNO_QUERY);
2655 xObjectProps->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bEscapeProcessing;
2656 if ( m_bPreview )
2658 OUString sSql;
2659 xObjectProps->getPropertyValue(PROPERTY_COMMAND) >>= sSql;
2660 Reference< XMultiServiceFactory > xFactory( pConData->xConnection, UNO_QUERY );
2661 if (xFactory.is())
2665 Reference<XSingleSelectQueryAnalyzer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY);
2666 if ( xAnalyzer.is() )
2668 xAnalyzer->setQuery(sSql);
2669 Reference<XParametersSupplier> xParSup(xAnalyzer,UNO_QUERY);
2670 if ( xParSup->getParameters()->getCount() > 0 )
2672 OUString sFilter = " WHERE ";
2673 sFilter = sFilter + xAnalyzer->getFilter();
2674 OUString sReplace(sSql);
2675 sReplace = sReplace.replaceFirst(sFilter,OUString());
2676 xAnalyzer->setQuery(sReplace);
2677 Reference<XSingleSelectQueryComposer> xComposer(xAnalyzer,UNO_QUERY);
2678 xComposer->setFilter(OUString("0=1"));
2679 aName = xAnalyzer->getQuery();
2680 nCommandType = CommandType::COMMAND;
2684 catch (Exception&)
2686 DBG_UNHANDLED_EXCEPTION();
2695 OUString sDataSourceName( getDataSourceAcessor( pConnection ) );
2696 bSuccess = implLoadAnything( sDataSourceName, aName, nCommandType, bEscapeProcessing, pConData->xConnection );
2697 if ( !bSuccess )
2698 { // clean up
2699 criticalFail();
2702 catch(const SQLException& e)
2704 showError(SQLExceptionInfo(e));
2705 // reset the values
2706 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2707 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2709 catch(WrappedTargetException& e)
2711 SQLException aSql;
2712 if(e.TargetException >>= aSql)
2713 showError(SQLExceptionInfo(aSql));
2714 else
2715 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::implSelect: something strange happened!");
2716 // reset the values
2717 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2718 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2720 catch(const Exception&)
2722 // reset the values
2723 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2724 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2727 return bSuccess;
2730 SvTreeListEntry* SbaTableQueryBrowser::getEntryFromContainer(const Reference<XNameAccess>& _rxNameAccess)
2732 DBTreeListBox& rListBox = m_pTreeView->getListBox();
2733 SvTreeListEntry* pContainer = NULL;
2734 SvTreeListEntry* pDSLoop = rListBox.FirstChild(NULL);
2735 while (pDSLoop)
2737 pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_QUERIES);
2738 DBTreeListUserData* pQueriesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2739 if ( pQueriesData && pQueriesData->xContainer == _rxNameAccess )
2740 break;
2742 pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_TABLES);
2743 DBTreeListUserData* pTablesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData());
2744 if ( pTablesData && pTablesData->xContainer == _rxNameAccess )
2745 break;
2747 pDSLoop = SvTreeList::NextSibling(pDSLoop);
2748 pContainer = NULL;
2750 return pContainer;
2753 void SAL_CALL SbaTableQueryBrowser::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException, std::exception)
2755 SolarMutexGuard aSolarGuard;
2757 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2758 // first search for a definition container where we can insert this element
2760 SvTreeListEntry* pEntry = getEntryFromContainer(xNames);
2761 if(pEntry) // found one
2763 // insert the new entry into the tree
2764 DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pEntry->GetUserData());
2765 OSL_ENSURE(pContainerData, "elementInserted: There must be user data for this type!");
2767 DBTreeListUserData* pNewData = new DBTreeListUserData;
2768 bool bIsTable = etTableContainer == pContainerData->eType;
2769 if ( bIsTable )
2771 _rEvent.Element >>= pNewData->xObjectProperties;// remember the new element
2772 pNewData->eType = etTableOrView;
2774 else
2776 if ((sal_Int32)m_pTreeView->getListBox().GetChildCount(pEntry) < ( xNames->getElementNames().getLength() - 1 ) )
2778 // the item inserts its children on demand, but it has not been expanded yet. So ensure here and
2779 // now that it has all items
2780 populateTree(xNames, pEntry, etQuery );
2782 pNewData->eType = etQuery;
2784 implAppendEntry( pEntry, ::comphelper::getString( _rEvent.Accessor ), pNewData, pNewData->eType );
2786 else
2787 SbaXDataBrowserController::elementInserted(_rEvent);
2790 bool SbaTableQueryBrowser::isCurrentlyDisplayedChanged(const OUString& _sName,SvTreeListEntry* _pContainer)
2792 return m_pCurrentlyDisplayed
2793 && getEntryType(m_pCurrentlyDisplayed) == getChildType(_pContainer)
2794 && m_pTreeView->getListBox().GetParent(m_pCurrentlyDisplayed) == _pContainer
2795 && m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed) == _sName;
2798 void SAL_CALL SbaTableQueryBrowser::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException, std::exception)
2800 SolarMutexGuard aSolarGuard;
2802 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2803 // get the top-level representing the removed data source
2804 // and search for the queries and tables
2805 SvTreeListEntry* pContainer = getEntryFromContainer(xNames);
2806 if ( pContainer )
2807 { // a query or table has been removed
2808 OUString aName = ::comphelper::getString(_rEvent.Accessor);
2810 if ( isCurrentlyDisplayedChanged( aName, pContainer) )
2811 { // the element displayed currently has been replaced
2813 // we need to remember the old value
2814 SvTreeListEntry* pTemp = m_pCurrentlyDisplayed;
2816 // unload
2817 unloadAndCleanup( false ); // don't dispose the connection
2819 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData());
2820 pTemp->SetUserData(NULL);
2821 delete pData;
2822 // the data could be null because we have a table which isn't correct
2823 m_pTreeModel->Remove(pTemp);
2825 else
2827 // remove the entry from the model
2828 SvTreeListEntry* pChild = m_pTreeModel->FirstChild(pContainer);
2829 while(pChild)
2831 if (m_pTreeView->getListBox().GetEntryText(pChild) == aName)
2833 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData());
2834 pChild->SetUserData(NULL);
2835 delete pData;
2836 m_pTreeModel->Remove(pChild);
2837 break;
2839 pChild = SvTreeList::NextSibling(pChild);
2843 // maybe the object which is part of the document data source has been removed
2844 checkDocumentDataSource();
2846 else
2847 SbaXDataBrowserController::elementRemoved(_rEvent);
2850 void SAL_CALL SbaTableQueryBrowser::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException, std::exception)
2852 SolarMutexGuard aSolarGuard;
2854 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2855 SvTreeListEntry* pContainer = getEntryFromContainer(xNames);
2856 if ( pContainer )
2857 { // a table or query as been replaced
2858 OUString aName = ::comphelper::getString(_rEvent.Accessor);
2860 if ( isCurrentlyDisplayedChanged( aName, pContainer) )
2861 { // the element displayed currently has been replaced
2863 // we need to remember the old value
2864 SvTreeListEntry* pTemp = m_pCurrentlyDisplayed;
2865 unloadAndCleanup( false ); // don't dispose the connection
2867 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData());
2868 if (pData)
2870 if ( etTableOrView == pData->eType )
2871 { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2872 _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2874 else
2876 pTemp->SetUserData(NULL);
2877 delete pData;
2881 else
2883 // find the entry for this name
2884 SvTreeListEntry* pChild = m_pTreeModel->FirstChild(pContainer);
2885 while(pChild)
2887 if (m_pTreeView->getListBox().GetEntryText(pChild) == aName)
2889 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData());
2890 if (pData)
2892 if ( etTableOrView == pData->eType )
2893 { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2894 _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2896 else
2898 pChild->SetUserData(NULL);
2899 delete pData;
2902 break;
2904 pChild = SvTreeList::NextSibling(pChild);
2908 // maybe the object which is part of the document data source has been removed
2909 checkDocumentDataSource();
2911 else if (xNames.get() == m_xDatabaseContext.get())
2912 { // a datasource has been replaced in the context
2913 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::elementReplaced: no support for replaced data sources!");
2914 // very suspicious: the database context should not allow to replace data source, only to register
2915 // and revoke them
2917 else
2918 SbaXDataBrowserController::elementReplaced(_rEvent);
2921 void SbaTableQueryBrowser::impl_releaseConnection( SharedConnection& _rxConnection )
2923 // remove as event listener
2924 Reference< XComponent > xComponent( _rxConnection, UNO_QUERY );
2925 if ( xComponent.is() )
2927 Reference< XEventListener > xListener( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY );
2928 xComponent->removeEventListener( xListener );
2933 // temporary (hopefully!) hack for #i55274#
2934 Reference< XFlushable > xFlush( _rxConnection, UNO_QUERY );
2935 if ( xFlush.is() )
2936 xFlush->flush();
2938 catch( const Exception& )
2940 DBG_UNHANDLED_EXCEPTION();
2943 // clear
2944 _rxConnection.clear();
2945 // will implicitly dispose if we have the ownership, since xConnection is a SharedConnection
2948 void SbaTableQueryBrowser::disposeConnection( SvTreeListEntry* _pDSEntry )
2950 OSL_ENSURE( _pDSEntry, "SbaTableQueryBrowser::disposeConnection: invalid entry (NULL)!" );
2951 OSL_ENSURE( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::disposeConnection: invalid entry (not top-level)!" );
2953 if ( _pDSEntry )
2955 DBTreeListUserData* pTreeListData = static_cast< DBTreeListUserData* >( _pDSEntry->GetUserData() );
2956 if ( pTreeListData )
2957 impl_releaseConnection( pTreeListData->xConnection );
2961 void SbaTableQueryBrowser::closeConnection(SvTreeListEntry* _pDSEntry, bool _bDisposeConnection)
2963 OSL_ENSURE(_pDSEntry, "SbaTableQueryBrowser::closeConnection: invalid entry (NULL)!");
2964 OSL_ENSURE( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::closeConnection: invalid entry (not top-level)!");
2966 // if one of the entries of the given DS is displayed currently, unload the form
2967 if (m_pCurrentlyDisplayed && (m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed) == _pDSEntry))
2968 unloadAndCleanup(_bDisposeConnection);
2970 // collapse the query/table container
2971 for (SvTreeListEntry* pContainers = m_pTreeModel->FirstChild(_pDSEntry); pContainers; pContainers = SvTreeList::NextSibling(pContainers))
2973 SvTreeListEntry* pElements = m_pTreeModel->FirstChild(pContainers);
2974 if ( pElements )
2975 m_pTreeView->getListBox().Collapse(pContainers);
2976 m_pTreeView->getListBox().EnableExpandHandler(pContainers);
2977 // and delete their children (they are connection-relative)
2978 for (; pElements; )
2980 SvTreeListEntry* pRemove = pElements;
2981 pElements = SvTreeList::NextSibling(pElements);
2982 DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pRemove->GetUserData());
2983 pRemove->SetUserData(NULL);
2984 delete pData;
2985 m_pTreeModel->Remove(pRemove);
2988 // collapse the entry itself
2989 m_pTreeView->getListBox().Collapse(_pDSEntry);
2991 // dispose/reset the connection
2992 if ( _bDisposeConnection )
2993 disposeConnection( _pDSEntry );
2996 void SbaTableQueryBrowser::unloadAndCleanup( bool _bDisposeConnection )
2998 if (!m_pCurrentlyDisplayed)
2999 // nothing to do
3000 return;
3002 SvTreeListEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed);
3004 // de-select the path for the currently displayed table/query
3005 if (m_pCurrentlyDisplayed)
3007 selectPath(m_pCurrentlyDisplayed, false);
3009 m_pCurrentlyDisplayed = NULL;
3013 // get the active connection. We need to dispose it.
3014 Reference< XPropertySet > xRowSetProps(getRowSet(),UNO_QUERY);
3015 Reference< XConnection > xConn;
3016 xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION) >>= xConn;
3017 #if OSL_DEBUG_LEVEL > 1
3019 Reference< XComponent > xComp(
3020 xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),
3021 css::uno::UNO_QUERY);
3023 #endif
3025 // unload the form
3026 Reference< XLoadable > xLoadable = getLoadable();
3027 if (xLoadable->isLoaded())
3028 xLoadable->unload();
3030 // clear the grid control
3031 Reference< XNameContainer > xConta(getControlModel(),UNO_QUERY);
3032 clearGridColumns(xConta);
3034 // dispose the connection
3035 if(_bDisposeConnection)
3036 disposeConnection( pDSEntry );
3038 catch(SQLException& e)
3040 showError(SQLExceptionInfo(e));
3042 catch(WrappedTargetException& e)
3044 SQLException aSql;
3045 if(e.TargetException >>= aSql)
3046 showError(SQLExceptionInfo(aSql));
3047 else
3048 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::unloadAndCleanup: something strange happened!");
3050 catch(const Exception&)
3052 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::unloadAndCleanup: could not reset the form");
3056 namespace
3058 Reference< XInterface > lcl_getDataSource( const Reference< XDatabaseContext >& _rxDatabaseContext,
3059 const OUString& _rDataSourceName, const Reference< XConnection >& _rxConnection )
3061 Reference< XDataSource > xDataSource;
3064 if ( !_rDataSourceName.isEmpty() && _rxDatabaseContext->hasByName( _rDataSourceName ) )
3065 xDataSource.set( _rxDatabaseContext->getByName( _rDataSourceName ), UNO_QUERY_THROW );
3067 if ( !xDataSource.is() )
3069 Reference< XChild > xConnAsChild( _rxConnection, UNO_QUERY );
3070 if ( xConnAsChild.is() )
3071 xDataSource.set( xConnAsChild->getParent(), UNO_QUERY_THROW );
3074 catch( const Exception& )
3076 DBG_UNHANDLED_EXCEPTION();
3078 return xDataSource.get();
3082 void SbaTableQueryBrowser::impl_initialize()
3084 SolarMutexGuard aGuard;
3085 // doin' a lot of VCL stuff here -> lock the SolarMutex
3087 // first initialize the parent
3088 SbaXDataBrowserController::impl_initialize();
3090 Reference<XConnection> xForeignConnection;
3091 Reference< XFrame > xFrame;
3093 OUString aTableName, aCatalogName, aSchemaName;
3095 bool bEscapeProcessing = true;
3096 sal_Int32 nInitialDisplayCommandType = CommandType::COMMAND;
3097 OUString sInitialDataSourceName;
3098 OUString sInitialCommand;
3100 const NamedValueCollection& rArguments( getInitParams() );
3102 rArguments.get_ensureType( OUString(PROPERTY_DATASOURCENAME), sInitialDataSourceName );
3103 rArguments.get_ensureType( OUString(PROPERTY_COMMAND_TYPE), nInitialDisplayCommandType );
3104 rArguments.get_ensureType( OUString(PROPERTY_COMMAND), sInitialCommand );
3105 rArguments.get_ensureType( OUString(PROPERTY_ACTIVE_CONNECTION), xForeignConnection );
3106 rArguments.get_ensureType( OUString(PROPERTY_UPDATE_CATALOGNAME), aCatalogName );
3107 rArguments.get_ensureType( OUString(PROPERTY_UPDATE_SCHEMANAME), aSchemaName );
3108 rArguments.get_ensureType( OUString(PROPERTY_UPDATE_TABLENAME), aTableName );
3109 rArguments.get_ensureType( OUString(PROPERTY_ESCAPE_PROCESSING), bEscapeProcessing );
3110 rArguments.get_ensureType( "Frame", xFrame );
3111 rArguments.get_ensureType( OUString(PROPERTY_SHOWMENU), m_bShowMenu );
3113 // disable the browser if either of ShowTreeViewButton (compatibility name) or EnableBrowser
3114 // is present and set to FALSE
3115 bool bDisableBrowser = !rArguments.getOrDefault( "ShowTreeViewButton", sal_True ) // compatibility name
3116 || !rArguments.getOrDefault( OUString(PROPERTY_ENABLE_BROWSER), sal_True );
3117 OSL_ENSURE( !rArguments.has( "ShowTreeViewButton" ),
3118 "SbaTableQueryBrowser::impl_initialize: ShowTreeViewButton is superseded by EnableBrowser!" );
3119 m_bEnableBrowser = !bDisableBrowser;
3121 // hide the tree view it is disabled in general, or if the settings tell to hide it initially
3122 bool bHideTreeView = ( !m_bEnableBrowser )
3123 || !rArguments.getOrDefault( "ShowTreeView", sal_True ) // compatibility name
3124 || !rArguments.getOrDefault( OUString(PROPERTY_SHOW_BROWSER), sal_True );
3125 OSL_ENSURE( !rArguments.has( "ShowTreeView" ),
3126 "SbaTableQueryBrowser::impl_initialize: ShowTreeView is superseded by ShowBrowser!" );
3128 if ( bHideTreeView )
3129 hideExplorer();
3130 else
3131 showExplorer();
3133 if ( m_bPreview )
3137 Sequence< OUString> aProperties(5);
3138 Sequence< Any> aValues(5);
3140 OUString* pStringIter = aProperties.getArray();
3141 Any* pValueIter = aValues.getArray();
3142 *pStringIter++ = "AlwaysShowCursor";
3143 *pValueIter++ <<= sal_False;
3144 *pStringIter++ = PROPERTY_BORDER;
3145 *pValueIter++ <<= sal_Int16(0);
3147 *pStringIter++ = "HasNavigationBar";
3148 *pValueIter++ <<= sal_False;
3149 *pStringIter++ = "HasRecordMarker";
3150 *pValueIter++ <<= sal_False;
3152 *pStringIter++ = "Tabstop";
3153 *pValueIter++ <<= sal_False;
3155 Reference< XMultiPropertySet > xFormMultiSet(getFormComponent(), UNO_QUERY);
3156 if ( xFormMultiSet.is() )
3157 xFormMultiSet->setPropertyValues(aProperties, aValues);
3159 catch(const Exception&)
3161 DBG_UNHANDLED_EXCEPTION();
3165 // are we loaded into a (sub)frame of an embedded document (i.e. a form belonging to a database
3166 // document)?
3167 bool bSubFrameOfEmbeddedDocument = false;
3168 if ( xFrame.is() )
3170 Reference<XFramesSupplier> xSup = xFrame->getCreator();
3171 Reference<XController> xCont = xSup.is() ? xSup->getController() : Reference<XController>();
3173 bSubFrameOfEmbeddedDocument = xCont.is() && ::dbtools::isEmbeddedInDatabase( xCont->getModel(), xForeignConnection );
3176 // if we have a connection at this point, it was either passed from outside, our
3177 // determined from a outer DB document. In both cases, do not dispose it later on.
3178 SharedConnection xConnection( xForeignConnection, SharedConnection::NoTakeOwnership );
3180 // should we display all registered databases in the left hand side tree?
3181 // or only *one* special?
3182 bool bLimitedTreeEntries = false;
3183 // if we're part of a frame which is a secondary frame of a database document, then only
3184 // display the database for this document, not all registered ones
3185 bLimitedTreeEntries |= bSubFrameOfEmbeddedDocument;
3186 // if the tree view is not to be displayed at all, then only display the data source
3187 // which was given as initial selection
3188 bLimitedTreeEntries |= !m_bEnableBrowser;
3190 if ( bLimitedTreeEntries )
3192 if ( xConnection.is() )
3194 startConnectionListening( xConnection );
3196 // if no initial name was given, try to obtain one from the data source
3197 if ( sInitialDataSourceName.isEmpty() )
3199 Reference< XChild > xChild( xConnection, UNO_QUERY );
3200 Reference< XPropertySet > xDataSourceProperties;
3201 if ( xChild.is() )
3202 xDataSourceProperties.set(xChild->getParent(), css::uno::UNO_QUERY);
3203 if ( xDataSourceProperties.is() )
3207 OSL_VERIFY( xDataSourceProperties->getPropertyValue( PROPERTY_NAME ) >>= sInitialDataSourceName );
3209 catch( const Exception& )
3211 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::impl_initialize: a connection parent which does not have a 'Name'!??" );
3217 implAddDatasource( sInitialDataSourceName, xConnection );
3218 m_pTreeView->getListBox().Expand( m_pTreeView->getListBox().First() );
3220 else
3221 initializeTreeModel();
3223 if ( m_bEnableBrowser )
3225 m_aDocScriptSupport = ::boost::optional< bool >( false );
3227 else
3229 // we are not used as "browser", but as mere view for a single table/query/command. In particular,
3230 // there is a specific database document which we belong to.
3231 Reference< XOfficeDatabaseDocument > xDocument( getDataSourceOrModel(
3232 lcl_getDataSource( m_xDatabaseContext, sInitialDataSourceName, xConnection ) ), UNO_QUERY );
3233 m_aDocScriptSupport = ::boost::optional< bool >( Reference< XEmbeddedScripts >( xDocument, UNO_QUERY ).is() );
3236 if ( implSelect( sInitialDataSourceName, sInitialCommand, nInitialDisplayCommandType, bEscapeProcessing, xConnection, true ) )
3240 Reference< XPropertySet > xRowSetProps(getRowSet(), UNO_QUERY);
3241 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_CATALOGNAME,makeAny(aCatalogName));
3242 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_SCHEMANAME,makeAny(aSchemaName));
3243 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_TABLENAME,makeAny(aTableName));
3246 catch(const Exception&)
3248 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::impl_initialize: could not set the update related names!");
3252 InvalidateAll();
3255 bool SbaTableQueryBrowser::haveExplorer() const
3257 return m_pTreeView && m_pTreeView->IsVisible();
3260 void SbaTableQueryBrowser::hideExplorer()
3262 if (!haveExplorer())
3263 return;
3264 if (!getBrowserView())
3265 return;
3267 m_pTreeView->Hide();
3268 m_pSplitter->Hide();
3269 getBrowserView()->Resize();
3271 InvalidateFeature(ID_BROWSER_EXPLORER);
3274 void SbaTableQueryBrowser::showExplorer()
3276 if (haveExplorer())
3277 return;
3279 if (!getBrowserView())
3280 return;
3282 m_pTreeView->Show();
3283 m_pSplitter->Show();
3284 getBrowserView()->Resize();
3286 InvalidateFeature(ID_BROWSER_EXPLORER);
3289 bool SbaTableQueryBrowser::ensureConnection(SvTreeListEntry* _pAnyEntry, SharedConnection& _rConnection)
3291 SvTreeListEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(_pAnyEntry);
3292 DBTreeListUserData* pDSData =
3293 pDSEntry
3294 ? static_cast<DBTreeListUserData*>(pDSEntry->GetUserData())
3295 : NULL;
3297 return ensureConnection( pDSEntry, pDSData, _rConnection );
3300 ::std::unique_ptr< ImageProvider > SbaTableQueryBrowser::getImageProviderFor( SvTreeListEntry* _pAnyEntry )
3302 ::std::unique_ptr< ImageProvider > pImageProvider( new ImageProvider );
3303 SharedConnection xConnection;
3304 if ( getExistentConnectionFor( _pAnyEntry, xConnection ) )
3305 pImageProvider.reset( new ImageProvider( xConnection ) );
3306 return pImageProvider;
3309 bool SbaTableQueryBrowser::getExistentConnectionFor( SvTreeListEntry* _pAnyEntry, SharedConnection& _rConnection )
3311 SvTreeListEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent( _pAnyEntry );
3312 DBTreeListUserData* pDSData =
3313 pDSEntry
3314 ? static_cast< DBTreeListUserData* >( pDSEntry->GetUserData() )
3315 : NULL;
3316 if ( pDSData )
3317 _rConnection = pDSData->xConnection;
3318 return _rConnection.is();
3321 #if OSL_DEBUG_LEVEL > 0
3322 bool SbaTableQueryBrowser::impl_isDataSourceEntry( SvTreeListEntry* _pEntry ) const
3324 return m_pTreeModel->GetRootLevelParent( _pEntry ) == _pEntry;
3327 #endif
3329 bool SbaTableQueryBrowser::ensureConnection( SvTreeListEntry* _pDSEntry, void* pDSData, SharedConnection& _rConnection )
3331 OSL_ENSURE( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::ensureConnection: this entry does not denote a data source!" );
3332 if(_pDSEntry)
3334 DBTreeListUserData* pTreeListData = static_cast<DBTreeListUserData*>(pDSData);
3335 OUString aDSName = GetEntryText(_pDSEntry);
3337 if ( pTreeListData )
3338 _rConnection = pTreeListData->xConnection;
3340 if ( !_rConnection.is() && pTreeListData )
3342 // show the "connecting to ..." status
3343 OUString sConnecting(ModuleRes(STR_CONNECTING_DATASOURCE));
3344 sConnecting = sConnecting.replaceFirst("$name$", aDSName);
3345 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sConnecting);
3347 // build a string showing context information in case of error
3348 OUString sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) );
3349 sConnectingContext = sConnectingContext.replaceFirst("$name$", aDSName);
3351 // connect
3352 _rConnection.reset(
3353 connect( getDataSourceAcessor( _pDSEntry ), sConnectingContext, NULL ),
3354 SharedConnection::TakeOwnership
3357 // remember the connection
3358 pTreeListData->xConnection = _rConnection;
3362 return _rConnection.is();
3365 IMPL_LINK( SbaTableQueryBrowser, OnTreeEntryCompare, const SvSortData*, _pSortData )
3367 const SvTreeListEntry* pLHS = static_cast<const SvTreeListEntry*>(_pSortData->pLeft);
3368 const SvTreeListEntry* pRHS = static_cast<const SvTreeListEntry*>(_pSortData->pRight);
3369 OSL_ENSURE(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!");
3370 // we want the table entry and the end so we have to do a check
3372 if (isContainer(pRHS))
3374 // don't use getEntryType (directly or indirecly) for the LHS:
3375 // LHS is currently being inserted, so it is not "completely valid" at the moment
3377 const EntryType eRight = getEntryType(pRHS);
3378 if (etTableContainer == eRight)
3379 // every other container should be placed _before_ the bookmark container
3380 return -1;
3382 const OUString sLeft = m_pTreeView->getListBox().GetEntryText(const_cast<SvTreeListEntry*>(pLHS));
3384 EntryType eLeft = etTableContainer;
3385 if (OUString(ModuleRes(RID_STR_TABLES_CONTAINER)) == sLeft)
3386 eLeft = etTableContainer;
3387 else if (OUString(ModuleRes(RID_STR_QUERIES_CONTAINER)) == sLeft)
3388 eLeft = etQueryContainer;
3390 if ( eLeft == eRight )
3391 return 0;
3393 if ( ( eLeft == etTableContainer ) && ( eRight == etQueryContainer ) )
3394 return 1;
3396 if ( ( eLeft == etQueryContainer ) && ( eRight == etTableContainer ) )
3397 return -1;
3399 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnTreeEntryCompare: unexpected case!" );
3400 return 0;
3403 const SvLBoxString* pLeftTextItem = static_cast<const SvLBoxString*>(pLHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
3404 const SvLBoxString* pRightTextItem = static_cast<const SvLBoxString*>(pRHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
3405 OSL_ENSURE(pLeftTextItem && pRightTextItem, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid text items!");
3407 OUString sLeftText = pLeftTextItem->GetText();
3408 OUString sRightText = pRightTextItem->GetText();
3410 sal_Int32 nCompareResult = 0; // equal by default
3412 if (m_xCollator.is())
3416 nCompareResult = m_xCollator->compareString(sLeftText, sRightText);
3418 catch(const Exception&)
3422 else
3423 // default behaviour if we do not have a collator -> do the simple string compare
3424 nCompareResult = sLeftText.compareTo(sRightText);
3426 return nCompareResult;
3429 void SbaTableQueryBrowser::implAdministrate( SvTreeListEntry* _pApplyTo )
3431 OSL_PRECOND( _pApplyTo, "SbaTableQueryBrowser::implAdministrate: illegal entry!" );
3432 if ( !_pApplyTo )
3433 return;
3437 // get the desktop object
3438 sal_Int32 nFrameSearchFlag = FrameSearchFlag::ALL | FrameSearchFlag::GLOBAL ;
3439 Reference< XDesktop2 > xFrameLoader = Desktop::create( getORB() );
3441 // the initial selection
3442 SvTreeListEntry* pTopLevelSelected = _pApplyTo;
3443 while (pTopLevelSelected && m_pTreeView->getListBox().GetParent(pTopLevelSelected))
3444 pTopLevelSelected = m_pTreeView->getListBox().GetParent(pTopLevelSelected);
3445 OUString sInitialSelection;
3446 if (pTopLevelSelected)
3447 sInitialSelection = getDataSourceAcessor( pTopLevelSelected );
3449 Reference< XDataSource > xDataSource( getDataSourceByName( sInitialSelection, getView(), getORB(), NULL ) );
3450 Reference< XModel > xDocumentModel( getDataSourceOrModel( xDataSource ), UNO_QUERY );
3452 if ( xDocumentModel.is() )
3454 Reference< XInteractionHandler2 > xInteractionHandler(
3455 InteractionHandler::createWithParent(getORB(), 0) );
3457 ::comphelper::NamedValueCollection aLoadArgs;
3458 aLoadArgs.put( "Model", xDocumentModel );
3459 aLoadArgs.put( "InteractionHandler", xInteractionHandler );
3460 aLoadArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
3462 Sequence< PropertyValue > aLoadArgPV;
3463 aLoadArgs >>= aLoadArgPV;
3465 xFrameLoader->loadComponentFromURL(
3466 xDocumentModel->getURL(),
3467 OUString("_default"),
3468 nFrameSearchFlag,
3469 aLoadArgPV
3473 catch( const Exception& )
3475 DBG_UNHANDLED_EXCEPTION();
3479 bool SbaTableQueryBrowser::requestQuickHelp( const SvTreeListEntry* _pEntry, OUString& _rText ) const
3481 const DBTreeListUserData* pData = static_cast< const DBTreeListUserData* >( _pEntry->GetUserData() );
3482 if ( ( pData->eType == etDatasource ) && !pData->sAccessor.isEmpty() )
3484 _rText = ::svt::OFileNotation( pData->sAccessor ).get( ::svt::OFileNotation::N_SYSTEM );
3485 return true;
3487 return false;
3490 PopupMenu* SbaTableQueryBrowser::getContextMenu( Control& _rControl ) const
3492 OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl,
3493 "SbaTableQueryBrowser::getContextMenu: where does this come from?" );
3494 if ( &m_pTreeView->getListBox() != &_rControl )
3495 return NULL;
3497 return new PopupMenu( ModuleRes( MENU_BROWSER_DEFAULTCONTEXT ) );
3500 IController& SbaTableQueryBrowser::getCommandController()
3502 return *this;
3505 ::cppu::OInterfaceContainerHelper* SbaTableQueryBrowser::getContextMenuInterceptors()
3507 return &m_aContextMenuInterceptors;
3510 Any SbaTableQueryBrowser::getCurrentSelection( Control& _rControl ) const
3512 OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl,
3513 "SbaTableQueryBrowser::getCurrentSelection: where does this come from?" );
3515 if ( &m_pTreeView->getListBox() != &_rControl )
3516 return Any();
3518 SvTreeListEntry* pSelected = m_pTreeView->getListBox().FirstSelected();
3519 if ( !pSelected )
3520 return Any();
3522 OSL_ENSURE( m_pTreeView->getListBox().NextSelected( pSelected ) == NULL,
3523 "SbaTableQueryBrowser::getCurrentSelection: single-selection is expected here!" );
3525 NamedDatabaseObject aSelectedObject;
3526 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pSelected->GetUserData() );
3527 aSelectedObject.Type = static_cast< sal_Int32 >( pData->eType );
3529 switch ( aSelectedObject.Type )
3531 case DatabaseObject::QUERY:
3532 case DatabaseObject::TABLE:
3533 aSelectedObject.Name = m_pTreeView->getListBox().GetEntryText( pSelected );
3534 break;
3536 case DatabaseObjectContainer::DATA_SOURCE:
3537 case DatabaseObjectContainer::QUERIES:
3538 case DatabaseObjectContainer::TABLES:
3539 aSelectedObject.Name = getDataSourceAcessor( pSelected );
3540 break;
3542 default:
3543 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::getCurrentSelection: invalid (unexpected) object type!" );
3544 break;
3547 return makeAny( aSelectedObject );
3550 bool SbaTableQueryBrowser::implGetQuerySignature( OUString& _rCommand, bool& _bEscapeProcessing )
3552 _rCommand.clear();
3553 _bEscapeProcessing = false;
3557 // contain the dss (data source signature) of the form
3558 OUString sDataSourceName;
3559 OUString sCommand;
3560 sal_Int32 nCommandType = CommandType::COMMAND;
3561 Reference< XPropertySet > xRowsetProps( getRowSet(), UNO_QUERY );
3562 ODataAccessDescriptor aDesc( xRowsetProps );
3563 sDataSourceName = aDesc.getDataSource();
3564 aDesc[ daCommand ] >>= sCommand;
3565 aDesc[ daCommandType ] >>= nCommandType;
3567 // do we need to do anything?
3568 if ( CommandType::QUERY != nCommandType )
3569 return false;
3571 // get the query object
3572 Reference< XQueryDefinitionsSupplier > xSuppQueries;
3573 Reference< XNameAccess > xQueries;
3574 Reference< XPropertySet > xQuery;
3575 m_xDatabaseContext->getByName( sDataSourceName ) >>= xSuppQueries;
3576 if ( xSuppQueries.is() )
3577 xQueries = xSuppQueries->getQueryDefinitions();
3578 if ( xQueries.is() )
3579 xQueries->getByName( sCommand ) >>= xQuery;
3580 OSL_ENSURE( xQuery.is(), "SbaTableQueryBrowser::implGetQuerySignature: could not retrieve the query object!" );
3582 // get the two properties we need
3583 if ( xQuery.is() )
3585 xQuery->getPropertyValue( PROPERTY_COMMAND ) >>= _rCommand;
3586 _bEscapeProcessing = ::cppu::any2bool( xQuery->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) );
3587 return true;
3590 catch( const Exception& )
3592 DBG_UNHANDLED_EXCEPTION();
3595 return false;
3598 void SbaTableQueryBrowser::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException, std::exception )
3600 if (aEvent.Frame == m_xCurrentFrameParent)
3602 if(aEvent.Action == FrameAction_COMPONENT_DETACHING)
3603 implRemoveStatusListeners();
3604 else if (aEvent.Action == FrameAction_COMPONENT_REATTACHED)
3605 connectExternalDispatches();
3607 else
3608 SbaXDataBrowserController::frameAction(aEvent);
3612 void SbaTableQueryBrowser::clearGridColumns(const Reference< XNameContainer >& _xColContainer)
3614 // first we have to clear the grid
3615 Sequence< OUString > aNames = _xColContainer->getElementNames();
3616 const OUString* pIter = aNames.getConstArray();
3617 const OUString* pEnd = pIter + aNames.getLength();
3618 Reference< XInterface > xColumn;
3619 for (; pIter != pEnd;++pIter)
3621 _xColContainer->getByName(*pIter) >>= xColumn;
3622 _xColContainer->removeByName(*pIter);
3623 ::comphelper::disposeComponent(xColumn);
3627 void SbaTableQueryBrowser::loadMenu(const Reference< XFrame >& _xFrame)
3629 if ( m_bShowMenu )
3631 OGenericUnoController::loadMenu(_xFrame);
3633 else if ( !m_bPreview )
3635 Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager = getLayoutManager(_xFrame);
3637 if ( xLayoutManager.is() )
3639 xLayoutManager->lock();
3640 xLayoutManager->createElement( OUString( "private:resource/toolbar/toolbar" ));
3641 xLayoutManager->unlock();
3642 xLayoutManager->doLayout();
3644 onLoadedMenu( xLayoutManager );
3648 OUString SbaTableQueryBrowser::getPrivateTitle() const
3650 OUString sTitle;
3651 if ( m_pCurrentlyDisplayed )
3653 SvTreeListEntry* pContainer = m_pTreeModel->GetParent(m_pCurrentlyDisplayed);
3654 // get the entry for the datasource
3655 SvTreeListEntry* pConnection = implGetConnectionEntry(pContainer);
3656 OUString sName = m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed);
3657 sTitle = GetEntryText( pConnection );
3658 INetURLObject aURL(sTitle);
3659 if ( aURL.GetProtocol() != INetProtocol::NotValid )
3660 sTitle = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET);
3661 if ( !sName.isEmpty() )
3663 sName += " - ";
3664 sName += sTitle;
3665 sTitle = sName;
3669 return sTitle;
3672 bool SbaTableQueryBrowser::preReloadForm()
3674 bool bIni = false;
3675 if ( !m_pCurrentlyDisplayed )
3677 // switch the grid to design mode while loading
3678 getBrowserView()->getGridControl()->setDesignMode(sal_True);
3679 // we had an invalid statement so we need to connect the column models
3680 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
3681 svx::ODataAccessDescriptor aDesc(xRowSetProps);
3682 // extract the props
3683 OUString sDataSource;
3684 OUString sCommand;
3685 sal_Int32 nCommandType = CommandType::COMMAND;
3686 bool bEscapeProcessing = true;
3687 extractDescriptorProps(aDesc, sDataSource, sCommand, nCommandType, bEscapeProcessing);
3688 if ( !sDataSource.isEmpty() && !sCommand.isEmpty() && (-1 != nCommandType) )
3690 SvTreeListEntry* pDataSource = NULL;
3691 SvTreeListEntry* pCommandType = NULL;
3692 m_pCurrentlyDisplayed = getObjectEntry( sDataSource, sCommand, nCommandType, &pDataSource, &pCommandType, true, SharedConnection() );
3693 bIni = true;
3696 return bIni;
3699 void SbaTableQueryBrowser::postReloadForm()
3701 InitializeGridModel(getFormComponent());
3702 LoadFinished(true);
3705 Reference< XEmbeddedScripts > SAL_CALL SbaTableQueryBrowser::getScriptContainer() throw (RuntimeException, std::exception)
3707 // update our database document
3708 Reference< XModel > xDocument;
3711 Reference< XPropertySet > xCursorProps( getRowSet(), UNO_QUERY_THROW );
3712 Reference< XConnection > xConnection( xCursorProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY );
3713 if ( xConnection.is() )
3715 Reference< XChild > xChild( xConnection, UNO_QUERY_THROW );
3716 Reference< XDocumentDataSource > xDataSource( xChild->getParent(), UNO_QUERY_THROW );
3717 xDocument.set( xDataSource->getDatabaseDocument(), UNO_QUERY_THROW );
3720 catch( const Exception& )
3722 DBG_UNHANDLED_EXCEPTION();
3724 Reference< XEmbeddedScripts > xScripts( xDocument, UNO_QUERY );
3725 OSL_ENSURE( xScripts.is() || !xDocument.is(),
3726 "SbaTableQueryBrowser::getScriptContainer: invalid database document!" );
3727 return xScripts;
3730 void SAL_CALL SbaTableQueryBrowser::registerContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException, std::exception)
3732 if ( _Interceptor.is() )
3733 m_aContextMenuInterceptors.addInterface( _Interceptor );
3736 void SAL_CALL SbaTableQueryBrowser::releaseContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException, std::exception)
3738 if ( _Interceptor.is() )
3739 m_aContextMenuInterceptors.removeInterface( _Interceptor );
3742 void SAL_CALL SbaTableQueryBrowser::registeredDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException, std::exception)
3744 SolarMutexGuard aGuard;
3745 implAddDatasource( _Event.Name, SharedConnection() );
3748 void SbaTableQueryBrowser::impl_cleanupDataSourceEntry( const OUString& _rDataSourceName )
3750 // get the top-level representing the removed data source
3751 SvTreeListEntry* pDataSourceEntry = m_pTreeView->getListBox().FirstChild( NULL );
3752 while ( pDataSourceEntry )
3754 if ( m_pTreeView->getListBox().GetEntryText( pDataSourceEntry ) == _rDataSourceName )
3755 break;
3757 pDataSourceEntry = SvTreeList::NextSibling( pDataSourceEntry );
3760 OSL_ENSURE( pDataSourceEntry, "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: do not know this data source!" );
3761 if ( !pDataSourceEntry )
3762 return;
3764 if ( isSelected( pDataSourceEntry ) )
3765 { // a table or query belonging to the deleted data source is currently being displayed.
3766 OSL_ENSURE( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) == pDataSourceEntry,
3767 "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (1)!" );
3768 unloadAndCleanup( true );
3770 else
3771 OSL_ENSURE(
3772 ( NULL == m_pCurrentlyDisplayed )
3773 || ( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) != pDataSourceEntry ),
3774 "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (2)!");
3776 // delete any user data of the child entries of the to-be-removed entry
3777 std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> aIters =
3778 m_pTreeModel->GetChildIterators(pDataSourceEntry);
3780 SvTreeListEntries::iterator it = aIters.first, itEnd = aIters.second;
3782 for (; it != itEnd; ++it)
3784 SvTreeListEntry* pEntry = &(*it);
3785 const DBTreeListUserData* pData = static_cast<const DBTreeListUserData*>(pEntry->GetUserData());
3786 pEntry->SetUserData(NULL);
3787 delete pData;
3790 // remove the entry
3791 DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() );
3792 pDataSourceEntry->SetUserData( NULL );
3793 delete pData;
3794 m_pTreeModel->Remove( pDataSourceEntry );
3797 void SAL_CALL SbaTableQueryBrowser::revokedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException, std::exception)
3799 SolarMutexGuard aGuard;
3801 impl_cleanupDataSourceEntry( _Event.Name );
3803 // maybe the object which is part of the document data source has been removed
3804 checkDocumentDataSource();
3807 void SAL_CALL SbaTableQueryBrowser::changedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException, std::exception)
3809 SolarMutexGuard aGuard;
3811 // in case the data source was expanded, and connected, we need to clean it up
3812 // for simplicity, just do as if the data source were completely removed and re-added
3813 impl_cleanupDataSourceEntry( _Event.Name );
3814 implAddDatasource( _Event.Name, SharedConnection() );
3817 } // namespace dbaui
3819 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */