1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <core_resource.hxx>
23 #include <dbtreelistbox.hxx>
24 #include "dbtreemodel.hxx"
25 #include <strings.hrc>
26 #include <imageprovider.hxx>
27 #include <sbagrid.hxx>
28 #include <strings.hxx>
29 #include <UITools.hxx>
30 #include <unodatbr.hxx>
32 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
33 #include <com/sun/star/awt/TextAlign.hpp>
34 #include <com/sun/star/awt/VisualEffect.hpp>
35 #include <com/sun/star/beans/NamedValue.hpp>
36 #include <com/sun/star/beans/PropertyValue.hpp>
37 #include <com/sun/star/beans/XMultiPropertySet.hpp>
38 #include <com/sun/star/container/XNameContainer.hpp>
39 #include <com/sun/star/form/XGridColumnFactory.hpp>
40 #include <com/sun/star/form/XLoadable.hpp>
41 #include <com/sun/star/form/XReset.hpp>
42 #include <com/sun/star/frame/Desktop.hpp>
43 #include <com/sun/star/frame/FrameSearchFlag.hpp>
44 #include <com/sun/star/frame/XLayoutManager.hpp>
45 #include <com/sun/star/lang/DisposedException.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/i18n/Collator.hpp>
48 #include <com/sun/star/sdb/CommandType.hpp>
49 #include <com/sun/star/sdb/SQLContext.hpp>
50 #include <com/sun/star/sdb/XDatabaseContext.hpp>
51 #include <com/sun/star/sdb/XDatabaseRegistrations.hpp>
52 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
53 #include <com/sun/star/sdb/XParametersSupplier.hpp>
54 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
55 #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
56 #include <com/sun/star/sdb/XResultSetAccess.hpp>
57 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
58 #include <com/sun/star/sdb/application/NamedDatabaseObject.hpp>
59 #include <com/sun/star/sdbc/ColumnValue.hpp>
60 #include <com/sun/star/sdbc/DataType.hpp>
61 #include <com/sun/star/sdbc/FetchDirection.hpp>
62 #include <com/sun/star/sdbc/SQLWarning.hpp>
63 #include <com/sun/star/sdbc/XDataSource.hpp>
64 #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
65 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
66 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
67 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
68 #include <com/sun/star/task/InteractionHandler.hpp>
69 #include <com/sun/star/util/XFlushable.hpp>
70 #include <com/sun/star/util/XNumberFormatter.hpp>
71 #include <com/sun/star/util/XURLTransformer.hpp>
72 #include <com/sun/star/document/MacroExecMode.hpp>
73 #include <com/sun/star/ui/XContextMenuInterceptor.hpp>
75 #include <comphelper/extract.hxx>
76 #include <comphelper/sequence.hxx>
77 #include <comphelper/types.hxx>
78 #include <connectivity/dbexception.hxx>
79 #include <cppuhelper/exc_hlp.hxx>
80 #include <i18nlangtag/languagetag.hxx>
81 #include <svl/filenotation.hxx>
82 #include <svx/dataaccessdescriptor.hxx>
83 #include <svx/databaseregistrationui.hxx>
84 #include <toolkit/helper/vclunohelper.hxx>
85 #include <tools/diagnose_ex.h>
86 #include <osl/diagnose.h>
87 #include <sal/log.hxx>
88 #include <tools/multisel.hxx>
89 #include <tools/urlobj.hxx>
90 #include <unotools/confignode.hxx>
91 #include <vcl/split.hxx>
92 #include <vcl/svapp.hxx>
93 #include <vcl/toolbox.hxx>
94 #include <vcl/settings.hxx>
95 #include <vcl/weld.hxx>
99 using namespace ::com::sun::star::uno
;
100 using namespace ::com::sun::star::awt
;
101 using namespace ::com::sun::star::sdb
;
102 using namespace ::com::sun::star::sdb::application
;
103 using namespace ::com::sun::star::sdbc
;
104 using namespace ::com::sun::star::sdbcx
;
105 using namespace ::com::sun::star::beans
;
106 using namespace ::com::sun::star::util
;
107 using namespace ::com::sun::star::frame
;
108 using namespace ::com::sun::star::container
;
109 using namespace ::com::sun::star::lang
;
110 using namespace ::com::sun::star::ui::dialogs
;
111 using namespace ::com::sun::star::task
;
112 using namespace ::com::sun::star::form
;
113 using namespace ::com::sun::star::io
;
114 using namespace ::com::sun::star::i18n
;
115 using namespace ::com::sun::star::view
;
116 using namespace ::com::sun::star::datatransfer
;
117 using namespace ::com::sun::star::document
;
118 using namespace ::com::sun::star::ui
;
119 using namespace ::dbtools
;
120 using namespace ::comphelper
;
121 using namespace ::svx
;
123 // SbaTableQueryBrowser
124 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
125 org_openoffice_comp_dbu_ODatasourceBrowser_get_implementation(
126 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
128 SolarMutexGuard aGuard
;
129 return cppu::acquire(new ::dbaui::SbaTableQueryBrowser(context
));
135 namespace DatabaseObject
= css::sdb::application::DatabaseObject
;
136 namespace DatabaseObjectContainer
= css::sdb::application::DatabaseObjectContainer
;
138 static void SafeAddPropertyListener(const Reference
< XPropertySet
> & xSet
, const OUString
& rPropName
, XPropertyChangeListener
* pListener
)
140 Reference
< XPropertySetInfo
> xInfo
= xSet
->getPropertySetInfo();
141 if (xInfo
->hasPropertyByName(rPropName
))
142 xSet
->addPropertyChangeListener(rPropName
, pListener
);
145 static void SafeRemovePropertyListener(const Reference
< XPropertySet
> & xSet
, const OUString
& rPropName
, XPropertyChangeListener
* pListener
)
147 Reference
< XPropertySetInfo
> xInfo
= xSet
->getPropertySetInfo();
148 if (xInfo
->hasPropertyByName(rPropName
))
149 xSet
->removePropertyChangeListener(rPropName
, pListener
);
152 OUString SAL_CALL
SbaTableQueryBrowser::getImplementationName()
154 return "org.openoffice.comp.dbu.ODatasourceBrowser";
157 css::uno::Sequence
<OUString
> SAL_CALL
SbaTableQueryBrowser::getSupportedServiceNames()
159 return { "com.sun.star.sdb.DataSourceBrowser" };
162 SbaTableQueryBrowser::SbaTableQueryBrowser(const Reference
< XComponentContext
>& _rM
)
163 :SbaXDataBrowserController(_rM
)
164 ,m_aSelectionListeners( getMutex() )
165 ,m_aContextMenuInterceptors( getMutex() )
166 ,m_aTableCopyHelper(this)
167 ,m_pTreeView(nullptr)
168 ,m_pSplitter(nullptr)
169 ,m_nAsyncDrop(nullptr)
170 ,m_bQueryEscapeProcessing( false )
173 ,m_bEnableBrowser(true)
177 SbaTableQueryBrowser::~SbaTableQueryBrowser()
179 if ( !rBHelper
.bDisposed
&& !rBHelper
.bInDispose
)
181 SAL_WARN("dbaccess.ui", "Please check who doesn't dispose this component!");
182 // increment ref count to prevent double call of Dtor
183 osl_atomic_increment( &m_refCount
);
191 Any SAL_CALL
SbaTableQueryBrowser::queryInterface(const Type
& _rType
)
193 if ( _rType
.equals( cppu::UnoType
<XScriptInvocationContext
>::get() ) )
195 OSL_PRECOND( !!m_aDocScriptSupport
, "SbaTableQueryBrowser::queryInterface: did not initialize this, yet!" );
196 if ( !!m_aDocScriptSupport
&& *m_aDocScriptSupport
)
197 return makeAny( Reference
< XScriptInvocationContext
>( this ) );
201 Any aReturn
= SbaXDataBrowserController::queryInterface(_rType
);
202 if (!aReturn
.hasValue())
203 aReturn
= SbaTableQueryBrowser_Base::queryInterface(_rType
);
207 Sequence
< Type
> SAL_CALL
SbaTableQueryBrowser::getTypes( )
209 Sequence
< Type
> aTypes( ::comphelper::concatSequences(
210 SbaXDataBrowserController::getTypes(),
211 SbaTableQueryBrowser_Base::getTypes()
214 OSL_PRECOND( !!m_aDocScriptSupport
, "SbaTableQueryBrowser::getTypes: did not initialize this, yet!" );
215 if ( !m_aDocScriptSupport
|| !*m_aDocScriptSupport
)
217 auto newEnd
= std::remove_if( aTypes
.begin(), aTypes
.end(),
219 { return type
== cppu::UnoType
<XScriptInvocationContext
>::get(); } );
220 aTypes
.realloc( std::distance(aTypes
.begin(), newEnd
) );
225 Sequence
< sal_Int8
> SAL_CALL
SbaTableQueryBrowser::getImplementationId( )
227 return css::uno::Sequence
<sal_Int8
>();
230 void SAL_CALL
SbaTableQueryBrowser::disposing()
232 SolarMutexGuard aGuard
;
233 // doin' a lot of VCL stuff here -> lock the SolarMutex
235 // kiss our listeners goodbye
236 css::lang::EventObject
aEvt(*this);
237 m_aSelectionListeners
.disposeAndClear(aEvt
);
238 m_aContextMenuInterceptors
.disposeAndClear(aEvt
);
240 if (getBrowserView())
242 // Need to do some cleanup of the data pointed to the tree view entries before we remove the treeview
244 m_pTreeView
= nullptr;
245 getBrowserView()->setTreeView(nullptr);
248 // remove ourself as status listener
249 implRemoveStatusListeners();
251 // remove the container listener from the database context
254 Reference
< XDatabaseRegistrations
> xDatabaseRegistrations( m_xDatabaseContext
, UNO_QUERY_THROW
);
255 xDatabaseRegistrations
->removeDatabaseRegistrationsListener( this );
257 catch( const Exception
& )
259 DBG_UNHANDLED_EXCEPTION("dbaccess");
262 // check out from all the objects we are listening
264 if (m_xCurrentFrameParent
.is())
265 m_xCurrentFrameParent
->removeFrameActionListener(static_cast<css::frame::XFrameActionListener
*>(this));
266 SbaXDataBrowserController::disposing();
269 bool SbaTableQueryBrowser::Construct(vcl::Window
* pParent
)
271 if ( !SbaXDataBrowserController::Construct( pParent
) )
276 Reference
< XDatabaseRegistrations
> xDatabaseRegistrations( m_xDatabaseContext
, UNO_QUERY_THROW
);
277 xDatabaseRegistrations
->addDatabaseRegistrationsListener( this );
279 // the collator for the string compares
280 m_xCollator
= Collator::create( getORB() );
281 m_xCollator
->loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0 );
283 catch(const Exception
&)
285 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::Construct: could not create (or start listening at) the database context!");
288 if (getBrowserView() && getBrowserView()->getVclControl())
291 // create controls and set sizes
292 const tools::Long nFrameWidth
= getBrowserView()->LogicToPixel(::Size(3, 0), MapMode(MapUnit::MapAppFont
)).Width();
294 m_pSplitter
= VclPtr
<Splitter
>::Create(getBrowserView(),WB_HSCROLL
);
295 m_pSplitter
->SetPosSizePixel( ::Point(0,0), ::Size(nFrameWidth
,0) );
296 m_pSplitter
->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) );
298 m_pTreeView
= VclPtr
<InterimDBTreeListBox
>::Create(getBrowserView());
300 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
301 rTreeView
.connect_expanding(LINK(this, SbaTableQueryBrowser
, OnExpandEntry
));
303 m_pTreeView
->setCopyHandler(LINK(this, SbaTableQueryBrowser
, OnCopyEntry
));
305 m_pTreeView
->setContextMenuProvider( this );
306 m_pTreeView
->setControlActionListener( this );
307 m_pTreeView
->SetHelpId(HID_CTL_TREEVIEW
);
309 // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide
310 m_pSplitter
->SetSplitPosPixel(getBrowserView()->LogicToPixel(::Size(80, 0), MapMode(MapUnit::MapAppFont
)).Width());
312 getBrowserView()->setSplitter(m_pSplitter
);
313 getBrowserView()->setTreeView(m_pTreeView
);
315 // fill view with data
316 rTreeView
.set_sort_order(true);
317 rTreeView
.set_sort_func([this](const weld::TreeIter
& rLeft
, const weld::TreeIter
& rRight
){
318 return OnTreeEntryCompare(rLeft
, rRight
);
320 rTreeView
.make_sorted();
321 m_pTreeView
->SetSelChangeHdl(LINK(this, SbaTableQueryBrowser
, OnSelectionChange
));
322 m_pTreeView
->show_container();
325 getBrowserView()->getVclControl()->SetHelpId(HID_CTL_TABBROWSER
);
326 if (getBrowserView()->getVclControl()->GetHeaderBar())
327 getBrowserView()->getVclControl()->GetHeaderBar()->SetHelpId(HID_DATABROWSE_HEADER
);
328 InvalidateFeature(ID_BROWSER_EXPLORER
);
336 struct SelectValueByName
338 const Any
& operator()( OUString
const& i_name
) const
340 return m_rCollection
.get( i_name
);
343 explicit SelectValueByName( ::comphelper::NamedValueCollection
const& i_collection
)
344 :m_rCollection( i_collection
)
348 ::comphelper::NamedValueCollection
const& m_rCollection
;
352 void SbaTableQueryBrowser::impl_sanitizeRowSetClauses_nothrow()
356 Reference
< XPropertySet
> xRowSetProps( getRowSet(), UNO_QUERY_THROW
);
357 bool bEscapeProcessing
= false;
358 OSL_VERIFY( xRowSetProps
->getPropertyValue( PROPERTY_ESCAPE_PROCESSING
) >>= bEscapeProcessing
);
359 if ( !bEscapeProcessing
)
360 // don't touch or interpret anything if escape processing is disabled
363 Reference
< XSingleSelectQueryComposer
> xComposer( createParser_nothrow() );
364 if ( !xComposer
.is() )
365 // can't do anything. Already reported via assertion in createParser_nothrow.
368 // the tables participating in the statement
369 const Reference
< XTablesSupplier
> xSuppTables( xComposer
, UNO_QUERY_THROW
);
370 const Reference
< XNameAccess
> xTableNames( xSuppTables
->getTables(), UNO_SET_THROW
);
372 // the columns participating in the statement
373 const Reference
< XColumnsSupplier
> xSuppColumns( xComposer
, UNO_QUERY_THROW
);
374 const Reference
< XNameAccess
> xColumnNames( xSuppColumns
->getColumns(), UNO_SET_THROW
);
376 // check if the order columns apply to tables which really exist in the statement
377 const Reference
< XIndexAccess
> xOrderColumns( xComposer
->getOrderColumns(), UNO_SET_THROW
);
378 const sal_Int32
nOrderColumns( xOrderColumns
->getCount() );
379 bool invalidColumn
= nOrderColumns
== 0;
380 for ( sal_Int32 c
=0; ( c
< nOrderColumns
) && !invalidColumn
; ++c
)
382 const Reference
< XPropertySet
> xOrderColumn( xOrderColumns
->getByIndex(c
), UNO_QUERY_THROW
);
384 OSL_VERIFY( xOrderColumn
->getPropertyValue( PROPERTY_TABLENAME
) >>= sTableName
);
385 OUString sColumnName
;
386 OSL_VERIFY( xOrderColumn
->getPropertyValue( PROPERTY_NAME
) >>= sColumnName
);
388 if ( sTableName
.isEmpty() )
390 if ( !xColumnNames
->hasByName( sColumnName
) )
392 invalidColumn
= true;
398 if ( !xTableNames
->hasByName( sTableName
) )
400 invalidColumn
= true;
404 const Reference
< XColumnsSupplier
> xSuppTableColumns( xTableNames
->getByName( sTableName
), UNO_QUERY_THROW
);
405 const Reference
< XNameAccess
> xTableColumnNames( xSuppTableColumns
->getColumns(), UNO_SET_THROW
);
406 if ( !xTableColumnNames
->hasByName( sColumnName
) )
408 invalidColumn
= true;
416 // reset the complete order statement at both the row set and the parser
417 xRowSetProps
->setPropertyValue( PROPERTY_ORDER
, makeAny( OUString() ) );
418 xComposer
->setOrder( "" );
421 // check if the columns participating in the filter refer to existing tables
422 // TODO: there's no API at all for this. The method which comes nearest to what we need is
423 // "getStructuredFilter", but it returns pure column names only. That is, for a statement like
424 // "SELECT * FROM <table> WHERE <other_table>.<column> = <value>", it will return "<column>". But
425 // there's no API at all to retrieve the information about "<other_table>" - which is what would
427 // That'd be a chance to replace getStructuredFilter with something more reasonable.
428 // So, what really would be handy, is some
429 // XNormalizedFilter getNormalizedFilter();
431 // interface XDisjunctiveFilterExpression
433 // XConjunctiveFilterTerm getTerm( int index );
435 // interface XConjunctiveFilterTerm
437 // ComparisonPredicate getPredicate( int index );
439 // struct ComparisonPredicate
441 // XComparisonOperand Lhs;
442 // SQLFilterOperator Operator;
443 // XComparisonOperand Rhs;
445 // interface XComparisonOperand
447 // SQLFilterOperand Type;
448 // XPropertySet getColumn();
449 // string getLiteral();
452 // enum SQLFilterOperand { Column, Literal, ... }
453 // ... or something like this...
455 catch( const Exception
& )
457 DBG_UNHANDLED_EXCEPTION("dbaccess");
461 bool SbaTableQueryBrowser::InitializeForm( const Reference
< XPropertySet
> & i_formProperties
)
463 if (!m_xCurrentlyDisplayed
)
466 // this method set all format settings from the original table or query
469 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
470 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*m_xCurrentlyDisplayed
).toUInt64());
471 ENSURE_OR_RETURN_FALSE( pData
, "SbaTableQueryBrowser::InitializeForm: No user data set at the currently displayed entry!" );
472 ENSURE_OR_RETURN_FALSE( pData
->xObjectProperties
.is(), "SbaTableQueryBrowser::InitializeForm: No table available!" );
474 Reference
< XPropertySetInfo
> xPSI( pData
->xObjectProperties
->getPropertySetInfo(), UNO_SET_THROW
);
476 ::comphelper::NamedValueCollection aPropertyValues
;
478 const OUString aTransferProperties
[] =
480 OUString(PROPERTY_APPLYFILTER
),
481 OUString(PROPERTY_FILTER
),
482 OUString(PROPERTY_HAVING_CLAUSE
),
483 OUString(PROPERTY_ORDER
)
485 for (const auto & aTransferPropertie
: aTransferProperties
)
487 if ( !xPSI
->hasPropertyByName( aTransferPropertie
) )
489 aPropertyValues
.put( aTransferPropertie
, pData
->xObjectProperties
->getPropertyValue( aTransferPropertie
) );
492 std::vector
< OUString
> aNames( aPropertyValues
.getNames() );
493 std::sort(aNames
.begin(), aNames
.end());
494 Sequence
< OUString
> aPropNames( comphelper::containerToSequence(aNames
) );
496 Sequence
< Any
> aPropValues( aNames
.size() );
497 std::transform( aNames
.begin(), aNames
.end(), aPropValues
.getArray(), SelectValueByName( aPropertyValues
) );
499 Reference
< XMultiPropertySet
> xFormMultiSet( i_formProperties
, UNO_QUERY_THROW
);
500 xFormMultiSet
->setPropertyValues( aPropNames
, aPropValues
);
502 impl_sanitizeRowSetClauses_nothrow();
504 catch ( const Exception
& )
506 DBG_UNHANDLED_EXCEPTION("dbaccess");
513 void SbaTableQueryBrowser::initializePreviewMode()
515 if ( getBrowserView() && getBrowserView()->getVclControl() )
517 getBrowserView()->getVclControl()->AlwaysEnableInput( false );
518 getBrowserView()->getVclControl()->EnableInput( false );
519 getBrowserView()->getVclControl()->ForceHideScrollbars();
521 Reference
< XPropertySet
> xDataSourceSet(getRowSet(), UNO_QUERY
);
522 if ( xDataSourceSet
.is() )
524 xDataSourceSet
->setPropertyValue("AllowInserts",makeAny(false));
525 xDataSourceSet
->setPropertyValue("AllowUpdates",makeAny(false));
526 xDataSourceSet
->setPropertyValue("AllowDeletes",makeAny(false));
530 void SbaTableQueryBrowser::InitializeGridModel(const Reference
< css::form::XFormComponent
> & xGrid
)
534 Reference
< css::form::XGridColumnFactory
> xColFactory(xGrid
, UNO_QUERY
);
535 Reference
< XNameContainer
> xColContainer(xGrid
, UNO_QUERY
);
536 clearGridColumns( xColContainer
);
538 Reference
< XLoadable
> xFormAsLoadable
;
540 xFormAsLoadable
.set(xGrid
->getParent(), css::uno::UNO_QUERY
);
541 if (xFormAsLoadable
.is() && xFormAsLoadable
->isLoaded())
543 // set the formats from the table
544 if (m_xCurrentlyDisplayed
)
546 Sequence
< OUString
> aProperties(6 + ( m_bPreview
? 5 : 0 ));
547 Sequence
< Any
> aValues(7 + ( m_bPreview
? 5 : 0 ));
549 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
550 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*m_xCurrentlyDisplayed
).toUInt64());
551 OSL_ENSURE( pData
->xObjectProperties
.is(), "SbaTableQueryBrowser::InitializeGridModel: No table available!" );
552 if ( !pData
->xObjectProperties
.is() )
555 OUString
* pStringIter
= aProperties
.getArray();
556 Any
* pValueIter
= aValues
.getArray();
559 *pStringIter
++ = "AlwaysShowCursor";
560 *pValueIter
++ <<= false;
561 *pStringIter
++ = PROPERTY_BORDER
;
562 *pValueIter
++ <<= sal_Int16(0);
565 *pStringIter
++ = PROPERTY_FONT
;
566 *pValueIter
++ = pData
->xObjectProperties
->getPropertyValue(PROPERTY_FONT
);
567 *pStringIter
++ = PROPERTY_TEXTEMPHASIS
;
568 *pValueIter
++ = pData
->xObjectProperties
->getPropertyValue(PROPERTY_TEXTEMPHASIS
);
569 *pStringIter
++ = PROPERTY_TEXTRELIEF
;
570 *pValueIter
++ = pData
->xObjectProperties
->getPropertyValue(PROPERTY_TEXTRELIEF
);
573 *pStringIter
++ = "HasNavigationBar";
574 *pValueIter
++ <<= false;
575 *pStringIter
++ = "HasRecordMarker";
576 *pValueIter
++ <<= false;
578 *pStringIter
++ = PROPERTY_ROW_HEIGHT
;
579 *pValueIter
++ = pData
->xObjectProperties
->getPropertyValue(PROPERTY_ROW_HEIGHT
);
582 *pStringIter
++ = "Tabstop";
583 *pValueIter
++ <<= false;
585 *pStringIter
++ = PROPERTY_TEXTCOLOR
;
586 *pValueIter
++ = pData
->xObjectProperties
->getPropertyValue(PROPERTY_TEXTCOLOR
);
587 *pStringIter
++ = PROPERTY_TEXTLINECOLOR
;
588 *pValueIter
++ = pData
->xObjectProperties
->getPropertyValue(PROPERTY_TEXTLINECOLOR
);
590 Reference
< XMultiPropertySet
> xFormMultiSet(xGrid
, UNO_QUERY
);
591 xFormMultiSet
->setPropertyValues(aProperties
, aValues
);
594 // get the formats supplier of the database we're working with
595 Reference
< css::util::XNumberFormatsSupplier
> xSupplier
= getNumberFormatter()->getNumberFormatsSupplier();
597 Reference
<XConnection
> xConnection
;
598 Reference
<XPropertySet
> xRowSetProps(getRowSet(),UNO_QUERY
);
599 xRowSetProps
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xConnection
;
600 OSL_ENSURE(xConnection
.is(),"A ActiveConnection should normally exists!");
602 Reference
<XChild
> xChild(xConnection
,UNO_QUERY
);
603 Reference
<XPropertySet
> xDataSourceProp(xChild
->getParent(),UNO_QUERY
);
604 bool bSuppressVersionCol
= false;
605 OSL_VERIFY( xDataSourceProp
->getPropertyValue( PROPERTY_SUPPRESSVERSIONCL
) >>= bSuppressVersionCol
);
607 // insert the column into the gridcontrol so that we see something :-)
608 OUString aCurrentModelType
;
609 Reference
<XColumnsSupplier
> xSupCols(getRowSet(),UNO_QUERY
);
610 Reference
<XNameAccess
> xColumns
= xSupCols
->getColumns();
612 OUString sDefaultProperty
;
613 Reference
< XPropertySet
> xColumn
;
614 Reference
< XPropertySetInfo
> xColPSI
;
615 const Sequence
<OUString
> aColNames
= xColumns
->getElementNames();
616 for (const OUString
& rName
: aColNames
)
618 xColumn
.set( xColumns
->getByName( rName
), UNO_QUERY_THROW
);
619 xColPSI
.set( xColumn
->getPropertySetInfo(), UNO_SET_THROW
);
621 // ignore the column when it is a rowversion one
622 if ( bSuppressVersionCol
623 && xColPSI
->hasPropertyByName( PROPERTY_ISROWVERSION
)
624 && ::cppu::any2bool( xColumn
->getPropertyValue( PROPERTY_ISROWVERSION
) )
628 // use the result set column's type to determine the type of grid column to create
629 bool bFormattedIsNumeric
= true;
630 sal_Int32 nType
= ::comphelper::getINT32( xColumn
->getPropertyValue( PROPERTY_TYPE
) );
632 std::vector
< NamedValue
> aInitialValues
;
633 std::vector
< OUString
> aCopyProperties
;
639 case DataType::BOOLEAN
:
641 aCurrentModelType
= "CheckBox";
642 aInitialValues
.emplace_back( "VisualEffect", makeAny( VisualEffect::FLAT
) );
643 sDefaultProperty
= PROPERTY_DEFAULTSTATE
;
645 sal_Int32 nNullable
= ColumnValue::NULLABLE_UNKNOWN
;
646 OSL_VERIFY( xColumn
->getPropertyValue( PROPERTY_ISNULLABLE
) >>= nNullable
);
647 aInitialValues
.emplace_back(
649 makeAny( ColumnValue::NO_NULLS
!= nNullable
)
651 if ( ColumnValue::NO_NULLS
== nNullable
)
652 aDefault
<<= sal_Int16(TRISTATE_FALSE
);
656 case DataType::LONGVARCHAR
:
658 aInitialValues
.emplace_back( "MultiLine", makeAny( true ) );
660 case DataType::BINARY
:
661 case DataType::VARBINARY
:
662 case DataType::LONGVARBINARY
:
663 aCurrentModelType
= "TextField";
664 sDefaultProperty
= PROPERTY_DEFAULTTEXT
;
667 case DataType::VARCHAR
:
669 bFormattedIsNumeric
= false;
672 aCurrentModelType
= "FormattedField";
673 sDefaultProperty
= PROPERTY_EFFECTIVEDEFAULT
;
675 if ( xSupplier
.is() )
676 aInitialValues
.emplace_back( "FormatsSupplier", makeAny( xSupplier
) );
677 aInitialValues
.emplace_back( "TreatAsNumber", makeAny( bFormattedIsNumeric
) );
678 aCopyProperties
.emplace_back(PROPERTY_FORMATKEY
);
682 aInitialValues
.emplace_back( PROPERTY_CONTROLSOURCE
, makeAny( rName
) );
684 xColumn
->getPropertyValue(PROPERTY_LABEL
) >>= sLabel
;
685 if ( !sLabel
.isEmpty() )
686 aInitialValues
.emplace_back( PROPERTY_LABEL
, makeAny( sLabel
) );
688 aInitialValues
.emplace_back( PROPERTY_LABEL
, makeAny( rName
) );
690 Reference
< XPropertySet
> xGridCol( xColFactory
->createColumn( aCurrentModelType
), UNO_SET_THROW
);
691 Reference
< XPropertySetInfo
> xGridColPSI( xGridCol
->getPropertySetInfo(), UNO_SET_THROW
);
693 // calculate the default
694 if ( xGridColPSI
->hasPropertyByName( PROPERTY_CONTROLDEFAULT
) )
696 aDefault
= xColumn
->getPropertyValue( PROPERTY_CONTROLDEFAULT
);
698 if ( nType
== DataType::BIT
|| nType
== DataType::BOOLEAN
)
700 if ( aDefault
.hasValue() )
701 aDefault
<<= (comphelper::getString(aDefault
).toInt32() == 0) ? sal_Int16(TRISTATE_FALSE
) : sal_Int16(TRISTATE_TRUE
);
703 aDefault
<<= sal_Int16(TRISTATE_INDET
);
707 if ( aDefault
.hasValue() )
708 aInitialValues
.emplace_back( sDefaultProperty
, aDefault
);
710 // transfer properties from the definition to the UNO-model :
711 aCopyProperties
.emplace_back(PROPERTY_HIDDEN
);
712 aCopyProperties
.emplace_back(PROPERTY_WIDTH
);
714 // help text to display for the column
716 if ( xColPSI
->hasPropertyByName( PROPERTY_HELPTEXT
) )
717 aDescription
= xColumn
->getPropertyValue( PROPERTY_HELPTEXT
);
719 aDescription
>>= sTemp
;
720 if ( sTemp
.isEmpty() )
721 xColumn
->getPropertyValue( PROPERTY_DESCRIPTION
) >>= sTemp
;
723 aDescription
<<= sTemp
;
724 aInitialValues
.emplace_back( PROPERTY_HELPTEXT
, aDescription
);
726 // ... horizontal justify
727 Any aAlign
; aAlign
<<= sal_Int16( 0 );
728 Any
aColAlign( xColumn
->getPropertyValue( PROPERTY_ALIGN
) );
729 if ( aColAlign
.hasValue() )
730 aAlign
<<= sal_Int16( ::comphelper::getINT32( aColAlign
) );
731 aInitialValues
.emplace_back( PROPERTY_ALIGN
, aAlign
);
733 // don't allow the mouse to scroll in the cells
734 if ( xGridColPSI
->hasPropertyByName( PROPERTY_MOUSE_WHEEL_BEHAVIOR
) )
735 aInitialValues
.emplace_back( PROPERTY_MOUSE_WHEEL_BEHAVIOR
, makeAny( MouseWheelBehavior::SCROLL_DISABLED
) );
737 // now set all those values
738 for (auto const& property
: aInitialValues
)
740 xGridCol
->setPropertyValue( property
.Name
, property
.Value
);
742 for (auto const& copyPropertyName
: aCopyProperties
)
743 xGridCol
->setPropertyValue( copyPropertyName
, xColumn
->getPropertyValue(copyPropertyName
) );
745 xColContainer
->insertByName(rName
, makeAny(xGridCol
));
749 catch(const Exception
&)
751 DBG_UNHANDLED_EXCEPTION("dbaccess");
755 static Reference
<XPropertySet
> getColumnHelper(const weld::TreeView
& rTreeView
,
756 const weld::TreeIter
* pCurrentlyDisplayed
,
757 const Reference
<XPropertySet
>& rxSource
)
759 Reference
<XPropertySet
> xRet
;
760 if (pCurrentlyDisplayed
)
762 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*pCurrentlyDisplayed
).toUInt64());
763 Reference
<XColumnsSupplier
> xColumnsSup(pData
->xObjectProperties
,UNO_QUERY
);
764 Reference
<XNameAccess
> xNames
= xColumnsSup
->getColumns();
766 rxSource
->getPropertyValue(PROPERTY_NAME
) >>= aName
;
767 if(xNames
.is() && xNames
->hasByName(aName
))
768 xRet
.set(xNames
->getByName(aName
),UNO_QUERY
);
773 void SbaTableQueryBrowser::transferChangedControlProperty(const OUString
& _rProperty
, const Any
& _rNewValue
)
775 if (m_xCurrentlyDisplayed
)
777 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
778 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*m_xCurrentlyDisplayed
).toUInt64());
779 Reference
< XPropertySet
> xObjectProps
= pData
->xObjectProperties
;
780 OSL_ENSURE(xObjectProps
.is(),"SbaTableQueryBrowser::transferChangedControlProperty: no table/query object!");
781 if (xObjectProps
.is())
782 xObjectProps
->setPropertyValue(_rProperty
, _rNewValue
);
786 void SbaTableQueryBrowser::propertyChange(const PropertyChangeEvent
& evt
)
788 SbaXDataBrowserController::propertyChange(evt
);
790 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
794 Reference
< XPropertySet
> xSource(evt
.Source
, UNO_QUERY
);
797 // one of the many properties which require us to update the definition ?
798 // a column's width ?
799 else if (evt
.PropertyName
== PROPERTY_WIDTH
)
800 { // a column width has changed -> update the model
801 // (the update of the view is done elsewhere)
802 Reference
<XPropertySet
> xProp
= getColumnHelper(rTreeView
, m_xCurrentlyDisplayed
.get(), xSource
);
805 if(!evt
.NewValue
.hasValue())
806 xProp
->setPropertyValue(PROPERTY_WIDTH
,makeAny(sal_Int32(227)));
808 xProp
->setPropertyValue(PROPERTY_WIDTH
,evt
.NewValue
);
812 // a column's 'visible' state ?
813 else if (evt
.PropertyName
== PROPERTY_HIDDEN
)
815 Reference
<XPropertySet
> xProp
= getColumnHelper(rTreeView
, m_xCurrentlyDisplayed
.get(), xSource
);
817 xProp
->setPropertyValue(PROPERTY_HIDDEN
,evt
.NewValue
);
820 // a columns alignment ?
821 else if (evt
.PropertyName
== PROPERTY_ALIGN
)
823 Reference
<XPropertySet
> xProp
= getColumnHelper(rTreeView
, m_xCurrentlyDisplayed
.get(), xSource
);
828 if(evt
.NewValue
.hasValue())
830 sal_Int16 nAlign
= 0;
831 if(evt
.NewValue
>>= nAlign
)
832 xProp
->setPropertyValue(PROPERTY_ALIGN
,makeAny(sal_Int32(nAlign
)));
834 xProp
->setPropertyValue(PROPERTY_ALIGN
,evt
.NewValue
);
837 xProp
->setPropertyValue(PROPERTY_ALIGN
,makeAny(css::awt::TextAlign::LEFT
));
840 catch( const Exception
& )
842 DBG_UNHANDLED_EXCEPTION("dbaccess");
846 // a column's format ?
847 else if ( evt
.PropertyName
== PROPERTY_FORMATKEY
848 && (TypeClass_LONG
== evt
.NewValue
.getValueTypeClass())
851 // update the model (means the definition object)
852 Reference
<XPropertySet
> xProp
= getColumnHelper(rTreeView
, m_xCurrentlyDisplayed
.get(), xSource
);
854 xProp
->setPropertyValue(PROPERTY_FORMATKEY
,evt
.NewValue
);
857 // some table definition properties ?
858 // the height of the rows in the grid ?
859 else if (evt
.PropertyName
== PROPERTY_ROW_HEIGHT
)
861 if (m_xCurrentlyDisplayed
)
863 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*m_xCurrentlyDisplayed
).toUInt64());
864 OSL_ENSURE( pData
->xObjectProperties
.is(), "No table available!" );
866 bool bDefault
= !evt
.NewValue
.hasValue();
868 pData
->xObjectProperties
->setPropertyValue(PROPERTY_ROW_HEIGHT
,makeAny(sal_Int32(45)));
870 pData
->xObjectProperties
->setPropertyValue(PROPERTY_ROW_HEIGHT
,evt
.NewValue
);
874 else if ( evt
.PropertyName
== PROPERTY_FONT
// the font ?
875 || evt
.PropertyName
== PROPERTY_TEXTCOLOR
// the text color ?
876 || evt
.PropertyName
== PROPERTY_FILTER
// the filter ?
877 || evt
.PropertyName
== PROPERTY_HAVING_CLAUSE
// the having clause ?
878 || evt
.PropertyName
== PROPERTY_ORDER
// the sort ?
879 || evt
.PropertyName
== PROPERTY_APPLYFILTER
// the appliance of the filter ?
880 || evt
.PropertyName
== PROPERTY_TEXTLINECOLOR
// the text line color ?
881 || evt
.PropertyName
== PROPERTY_TEXTEMPHASIS
// the text emphasis ?
882 || evt
.PropertyName
== PROPERTY_TEXTRELIEF
// the text relief ?
885 transferChangedControlProperty(evt
.PropertyName
, evt
.NewValue
);
888 catch( const Exception
& )
890 DBG_UNHANDLED_EXCEPTION("dbaccess");
894 sal_Bool
SbaTableQueryBrowser::suspend(sal_Bool bSuspend
)
896 SolarMutexGuard aSolarGuard
;
897 ::osl::MutexGuard
aGuard( getMutex() );
898 if ( getView() && getView()->IsInModalMode() )
904 if ( rBHelper
.bDisposed
)
905 throw DisposedException( OUString(), *this );
907 bRet
= SbaXDataBrowserController::suspend(bSuspend
);
908 if ( bRet
&& getView() )
911 m_bInSuspend
= false;
917 void SAL_CALL
SbaTableQueryBrowser::statusChanged( const FeatureStateEvent
& _rEvent
)
919 // search the external dispatcher causing this call
920 Reference
< XDispatch
> xSource(_rEvent
.Source
, UNO_QUERY
);
922 for (auto & externalFeature
: m_aExternalFeatures
)
924 if ( _rEvent
.FeatureURL
.Complete
== externalFeature
.second
.aURL
.Complete
)
927 OSL_ENSURE( xSource
.get() == externalFeature
.second
.xDispatcher
.get(), "SbaTableQueryBrowser::statusChanged: inconsistent!" );
928 // update the enabled state
929 externalFeature
.second
.bEnabled
= _rEvent
.IsEnabled
;
931 switch ( externalFeature
.first
)
933 case ID_BROWSER_DOCUMENT_DATASOURCE
:
935 // if it's the slot for the document data source, remember the state
936 Sequence
< PropertyValue
> aDescriptor
;
937 bool bProperFormat
= _rEvent
.State
>>= aDescriptor
;
938 OSL_ENSURE(bProperFormat
, "SbaTableQueryBrowser::statusChanged: need a data access descriptor here!");
939 m_aDocumentDataSource
.initializeFrom(aDescriptor
);
941 OSL_ENSURE( ( m_aDocumentDataSource
.has(DataAccessDescriptorProperty::DataSource
)
942 || m_aDocumentDataSource
.has(DataAccessDescriptorProperty::DatabaseLocation
)
944 && m_aDocumentDataSource
.has(DataAccessDescriptorProperty::Command
)
945 && m_aDocumentDataSource
.has(DataAccessDescriptorProperty::CommandType
),
946 "SbaTableQueryBrowser::statusChanged: incomplete descriptor!");
948 // check if we know the object which is set as document data source
949 checkDocumentDataSource();
954 // update the toolbox
955 implCheckExternalSlot( externalFeature
.first
);
962 OSL_ENSURE(bFound
, "SbaTableQueryBrowser::statusChanged: don't know who sent this!");
965 void SbaTableQueryBrowser::checkDocumentDataSource()
967 std::unique_ptr
<weld::TreeIter
> xDataSourceEntry
;
968 std::unique_ptr
<weld::TreeIter
> xContainerEntry
;
969 std::unique_ptr
<weld::TreeIter
> xObjectEntry
= getObjectEntry(m_aDocumentDataSource
, &xDataSourceEntry
, &xContainerEntry
);
970 bool bKnownDocDataSource
= static_cast<bool>(xObjectEntry
);
971 if (!bKnownDocDataSource
)
973 if (xDataSourceEntry
)
975 // at least the data source is known
978 bKnownDocDataSource
= true; // assume we know it.
979 // TODO: should we expand the object container? This may be too expensive just for checking...
983 if (m_aDocumentDataSource
.has(DataAccessDescriptorProperty::CommandType
)
984 && m_aDocumentDataSource
.has(DataAccessDescriptorProperty::Command
))
985 { // maybe we have a command to be displayed ?
986 sal_Int32 nCommandType
= CommandType::TABLE
;
987 m_aDocumentDataSource
[DataAccessDescriptorProperty::CommandType
] >>= nCommandType
;
990 m_aDocumentDataSource
[DataAccessDescriptorProperty::Command
] >>= sCommand
;
992 bKnownDocDataSource
= (CommandType::COMMAND
== nCommandType
) && (!sCommand
.isEmpty());
998 if ( !bKnownDocDataSource
)
999 m_aExternalFeatures
[ ID_BROWSER_DOCUMENT_DATASOURCE
].bEnabled
= false;
1001 // update the toolbox
1002 implCheckExternalSlot(ID_BROWSER_DOCUMENT_DATASOURCE
);
1005 void SbaTableQueryBrowser::extractDescriptorProps(const svx::ODataAccessDescriptor
& _rDescriptor
, OUString
& _rDataSource
, OUString
& _rCommand
, sal_Int32
& _rCommandType
, bool& _rEscapeProcessing
)
1007 _rDataSource
= _rDescriptor
.getDataSource();
1008 if ( _rDescriptor
.has(DataAccessDescriptorProperty::Command
) )
1009 _rDescriptor
[DataAccessDescriptorProperty::Command
] >>= _rCommand
;
1010 if ( _rDescriptor
.has(DataAccessDescriptorProperty::CommandType
) )
1011 _rDescriptor
[DataAccessDescriptorProperty::CommandType
] >>= _rCommandType
;
1013 // escape processing is the only one allowed not to be present
1014 _rEscapeProcessing
= true;
1015 if (_rDescriptor
.has(DataAccessDescriptorProperty::EscapeProcessing
))
1016 _rEscapeProcessing
= ::cppu::any2bool(_rDescriptor
[DataAccessDescriptorProperty::EscapeProcessing
]);
1021 bool getDataSourceDisplayName_isURL( const OUString
& _rDS
, OUString
& _rDisplayName
, OUString
& _rUniqueId
)
1023 INetURLObject
aURL( _rDS
);
1024 if ( aURL
.GetProtocol() != INetProtocol::NotValid
)
1026 _rDisplayName
= aURL
.getBase(INetURLObject::LAST_SEGMENT
,true,INetURLObject::DecodeMechanism::WithCharset
);
1027 _rUniqueId
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
1030 _rDisplayName
= _rDS
;
1035 struct FilterByEntryDataId
: public IEntryFilter
1038 explicit FilterByEntryDataId( const OUString
& _rId
) : sId( _rId
) { }
1040 virtual ~FilterByEntryDataId() {}
1042 virtual bool includeEntry(const void* pEntry
) const override
;
1045 bool FilterByEntryDataId::includeEntry(const void* pUserData
) const
1047 const DBTreeListUserData
* pData
= static_cast<const DBTreeListUserData
*>(pUserData
);
1048 return ( !pData
|| ( pData
->sAccessor
== sId
) );
1052 OUString
SbaTableQueryBrowser::getDataSourceAccessor(const weld::TreeIter
& rDataSourceEntry
) const
1054 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
1055 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(rDataSourceEntry
).toUInt64());
1056 OSL_ENSURE( pData
, "SbaTableQueryBrowser::getDataSourceAccessor: invalid entry data!" );
1057 OSL_ENSURE( pData
->eType
== etDatasource
, "SbaTableQueryBrowser::getDataSourceAccessor: entry does not denote a data source!" );
1058 return !pData
->sAccessor
.isEmpty() ? pData
->sAccessor
: GetEntryText(rDataSourceEntry
);
1061 std::unique_ptr
<weld::TreeIter
> SbaTableQueryBrowser::getObjectEntry(const OUString
& _rDataSource
, const OUString
& _rCommand
, sal_Int32 nCommandType
,
1062 std::unique_ptr
<weld::TreeIter
>* ppDataSourceEntry
, std::unique_ptr
<weld::TreeIter
>* ppContainerEntry
, bool bExpandAncestors
,
1063 const SharedConnection
& _rxConnection
)
1065 if (ppDataSourceEntry
)
1066 ppDataSourceEntry
->reset();
1067 if (ppContainerEntry
)
1068 ppContainerEntry
->reset();
1070 std::unique_ptr
<weld::TreeIter
> xObject
;
1073 // look for the data source entry
1074 OUString sDisplayName
, sDataSourceId
;
1075 bool bIsDataSourceURL
= getDataSourceDisplayName_isURL( _rDataSource
, sDisplayName
, sDataSourceId
);
1076 // the display name may differ from the URL for readability reasons
1079 FilterByEntryDataId
aFilter( sDataSourceId
);
1080 std::unique_ptr
<weld::TreeIter
> xDataSource
= m_pTreeView
->GetEntryPosByName( sDisplayName
, nullptr, &aFilter
);
1081 if (!xDataSource
) // check if the data source name is a file location
1083 if ( bIsDataSourceURL
)
1085 // special case, the data source is a URL
1086 // add new entries to the list box model
1087 implAddDatasource( _rDataSource
, _rxConnection
);
1088 xDataSource
= m_pTreeView
->GetEntryPosByName( sDisplayName
, nullptr, &aFilter
);
1089 OSL_ENSURE( xDataSource
, "SbaTableQueryBrowser::getObjectEntry: hmm - did not find it again!" );
1093 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
1097 if (ppDataSourceEntry
)
1099 // (caller wants to have it...)
1100 *ppDataSourceEntry
= rTreeView
.make_iterator(xDataSource
.get());
1103 // expand if required so
1104 if (bExpandAncestors
)
1105 rTreeView
.expand_row(*xDataSource
);
1107 // look for the object container
1108 std::unique_ptr
<weld::TreeIter
> xCommandType
;
1109 if (nCommandType
== CommandType::QUERY
|| nCommandType
== CommandType::TABLE
)
1111 xCommandType
= rTreeView
.make_iterator(xDataSource
.get());
1112 if (!rTreeView
.iter_children(*xCommandType
))
1113 xCommandType
.reset();
1116 // 1st child is queries, so we're already done if looking for CommandType::QUERY
1118 // 2nd child is tables
1119 if (nCommandType
== CommandType::TABLE
&& !rTreeView
.iter_next_sibling(*xCommandType
))
1120 xCommandType
.reset();
1126 if (ppContainerEntry
)
1128 // (caller wants to have it...)
1129 *ppContainerEntry
= rTreeView
.make_iterator(xCommandType
.get());
1132 rTreeView
.make_unsorted();
1134 // expand if required so
1135 if (bExpandAncestors
)
1137 rTreeView
.expand_row(*xCommandType
);
1140 // look for the object
1141 sal_Int32 nIndex
= 0;
1145 switch (nCommandType
)
1147 case CommandType::TABLE
:
1152 case CommandType::QUERY
:
1153 sPath
= _rCommand
.getToken( 0, '/', nIndex
);
1159 xObject
= m_pTreeView
->GetEntryPosByName(sPath
, xCommandType
.get());
1161 rTreeView
.copy_iterator(*xObject
, *xCommandType
);
1163 xCommandType
.reset();
1166 if (ensureEntryObject(*xObject
))
1168 DBTreeListUserData
* pParentData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xObject
).toUInt64());
1169 Reference
< XNameAccess
> xCollection( pParentData
->xContainer
, UNO_QUERY
);
1170 sal_Int32 nIndex2
= nIndex
;
1171 sPath
= _rCommand
.getToken( 0, '/', nIndex2
);
1174 if ( xCollection
->hasByName(sPath
) )
1176 if(!m_pTreeView
->GetEntryPosByName(sPath
, xObject
.get()))
1178 Reference
<XNameAccess
> xChild(xCollection
->getByName(sPath
),UNO_QUERY
);
1179 DBTreeListUserData
* pEntryData
= new DBTreeListUserData
;
1180 pEntryData
->eType
= etQuery
;
1183 pEntryData
->eType
= etQueryContainer
;
1185 implAppendEntry(xObject
.get(), sPath
, pEntryData
);
1189 catch(const Exception
&)
1191 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::populateTree: could not fill the tree");
1196 while ( nIndex
>= 0 );
1198 rTreeView
.make_sorted();
1205 std::unique_ptr
<weld::TreeIter
> SbaTableQueryBrowser::getObjectEntry(const svx::ODataAccessDescriptor
& rDescriptor
,
1206 std::unique_ptr
<weld::TreeIter
>* ppDataSourceEntry
, std::unique_ptr
<weld::TreeIter
>* ppContainerEntry
)
1208 // extract the props from the descriptor
1209 OUString sDataSource
;
1211 sal_Int32 nCommandType
= CommandType::COMMAND
;
1212 bool bEscapeProcessing
= true;
1213 extractDescriptorProps(rDescriptor
, sDataSource
, sCommand
, nCommandType
, bEscapeProcessing
);
1215 return getObjectEntry(sDataSource
, sCommand
, nCommandType
, ppDataSourceEntry
, ppContainerEntry
, false /*bExpandAncestors*/);
1218 void SbaTableQueryBrowser::connectExternalDispatches()
1220 Reference
< XDispatchProvider
> xProvider( getFrame(), UNO_QUERY
);
1221 OSL_ENSURE(xProvider
.is(), "SbaTableQueryBrowser::connectExternalDispatches: no DispatchProvider !");
1222 if (!xProvider
.is())
1225 if ( m_aExternalFeatures
.empty() )
1227 const char* pURLs
[] = {
1228 ".uno:DataSourceBrowser/DocumentDataSource",
1229 ".uno:DataSourceBrowser/FormLetter",
1230 ".uno:DataSourceBrowser/InsertColumns",
1231 ".uno:DataSourceBrowser/InsertContent",
1233 const sal_uInt16 nIds
[] = {
1234 ID_BROWSER_DOCUMENT_DATASOURCE
,
1235 ID_BROWSER_FORMLETTER
,
1236 ID_BROWSER_INSERTCOLUMNS
,
1237 ID_BROWSER_INSERTCONTENT
1240 for ( size_t i
=0; i
< SAL_N_ELEMENTS( pURLs
); ++i
)
1243 aURL
.Complete
= OUString::createFromAscii( pURLs
[i
] );
1244 if ( m_xUrlTransformer
.is() )
1245 m_xUrlTransformer
->parseStrict( aURL
);
1246 m_aExternalFeatures
[ nIds
[ i
] ] = ExternalFeature( aURL
);
1250 for (auto & externalFeature
: m_aExternalFeatures
)
1252 externalFeature
.second
.xDispatcher
= xProvider
->queryDispatch(
1253 externalFeature
.second
.aURL
, "_parent", FrameSearchFlag::PARENT
1256 if ( externalFeature
.second
.xDispatcher
.get() == static_cast< XDispatch
* >( this ) )
1258 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::connectExternalDispatches: this should not happen anymore!" );
1259 // (nowadays, the URLs aren't in our SupportedFeatures list anymore, so we should
1260 // not supply a dispatcher for this)
1261 externalFeature
.second
.xDispatcher
.clear();
1264 if ( externalFeature
.second
.xDispatcher
.is() )
1268 externalFeature
.second
.xDispatcher
->addStatusListener( this, externalFeature
.second
.aURL
);
1270 catch( const Exception
& )
1272 DBG_UNHANDLED_EXCEPTION("dbaccess");
1276 implCheckExternalSlot( externalFeature
.first
);
1280 void SbaTableQueryBrowser::implCheckExternalSlot( sal_uInt16 _nId
)
1282 if ( !m_xMainToolbar
.is() )
1285 VclPtr
<vcl::Window
> pToolboxWindow
= VCLUnoHelper::GetWindow( m_xMainToolbar
);
1286 ToolBox
* pToolbox
= dynamic_cast< ToolBox
* >( pToolboxWindow
.get() );
1287 OSL_ENSURE( pToolbox
, "SbaTableQueryBrowser::implCheckExternalSlot: cannot obtain the toolbox window!" );
1289 // check if we have to hide this item from the toolbox
1292 bool bHaveDispatcher
= m_aExternalFeatures
[ _nId
].xDispatcher
.is();
1293 if ( bHaveDispatcher
!= pToolbox
->IsItemVisible( _nId
) )
1294 bHaveDispatcher
? pToolbox
->ShowItem( _nId
) : pToolbox
->HideItem( _nId
);
1297 // and invalidate this feature in general
1298 InvalidateFeature( _nId
);
1301 void SAL_CALL
SbaTableQueryBrowser::disposing( const css::lang::EventObject
& _rSource
)
1304 Reference
< css::frame::XFrame
> xSourceFrame(_rSource
.Source
, UNO_QUERY
);
1305 if (m_xCurrentFrameParent
.is() && (xSourceFrame
== m_xCurrentFrameParent
))
1306 m_xCurrentFrameParent
->removeFrameActionListener(static_cast<css::frame::XFrameActionListener
*>(this));
1309 // search the external dispatcher causing this call in our map
1310 Reference
< XDispatch
> xSource(_rSource
.Source
, UNO_QUERY
);
1313 ExternalFeaturesMap::const_iterator aLoop
= m_aExternalFeatures
.begin();
1314 ExternalFeaturesMap::const_iterator aEnd
= m_aExternalFeatures
.end();
1315 while (aLoop
!= aEnd
)
1317 if ( aLoop
->second
.xDispatcher
.get() == xSource
.get() )
1319 sal_uInt16 nSlot
= aLoop
->first
;
1322 aLoop
= m_aExternalFeatures
.erase(aLoop
);
1324 // maybe update the UI
1325 implCheckExternalSlot(nSlot
);
1327 // continue, the same XDispatch may be responsible for more than one URL
1334 Reference
<XConnection
> xCon(_rSource
.Source
, UNO_QUERY
);
1335 if ( xCon
.is() && m_pTreeView
)
1337 // our connection is in dispose so we have to find the entry equal with this connection
1338 // and close it what means to collapse the entry
1339 // get the top-level representing the removed data source
1340 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
1341 std::unique_ptr
<weld::TreeIter
> xDSLoop(rTreeView
.make_iterator());
1342 if (rTreeView
.get_iter_first(*xDSLoop
))
1346 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xDSLoop
).toUInt64());
1347 if ( pData
&& pData
->xConnection
== xCon
)
1349 // we set the connection to null to avoid a second disposing of the connection
1350 pData
->xConnection
.clear();
1351 closeConnection(*xDSLoop
, false);
1355 while (rTreeView
.iter_next_sibling(*xDSLoop
));
1359 SbaXDataBrowserController::disposing(_rSource
);
1364 void SbaTableQueryBrowser::implRemoveStatusListeners()
1366 // clear all old dispatches
1367 for (auto const& externalFeature
: m_aExternalFeatures
)
1369 if ( externalFeature
.second
.xDispatcher
.is() )
1373 externalFeature
.second
.xDispatcher
->removeStatusListener( this, externalFeature
.second
.aURL
);
1377 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::implRemoveStatusListeners: could not remove a status listener!");
1381 m_aExternalFeatures
.clear();
1384 sal_Bool SAL_CALL
SbaTableQueryBrowser::select( const Any
& _rSelection
)
1386 SolarMutexGuard aGuard
;
1387 // doin' a lot of VCL stuff here -> lock the SolarMutex
1389 Sequence
< PropertyValue
> aDescriptorSequence
;
1390 if (!(_rSelection
>>= aDescriptorSequence
))
1391 throw IllegalArgumentException(OUString(), *this, 1);
1392 // TODO: error message
1394 ODataAccessDescriptor aDescriptor
;
1397 aDescriptor
= ODataAccessDescriptor(aDescriptorSequence
);
1399 catch(const Exception
&)
1401 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::select: could not extract the descriptor!");
1404 // check the presence of the props we need
1405 if ( !(aDescriptor
.has(DataAccessDescriptorProperty::DataSource
) || aDescriptor
.has(DataAccessDescriptorProperty::DatabaseLocation
)) || !aDescriptor
.has(DataAccessDescriptorProperty::Command
) || !aDescriptor
.has(DataAccessDescriptorProperty::CommandType
))
1406 throw IllegalArgumentException(OUString(), *this, 1);
1407 // TODO: error message
1409 return implSelect(aDescriptor
,true);
1412 Any SAL_CALL
SbaTableQueryBrowser::getSelection( )
1418 Reference
< XLoadable
> xLoadable(getRowSet(), UNO_QUERY
);
1419 if (xLoadable
.is() && xLoadable
->isLoaded())
1421 Reference
< XPropertySet
> aFormProps(getRowSet(), UNO_QUERY
);
1422 ODataAccessDescriptor
aDescriptor(aFormProps
);
1423 // remove properties which are not part of our "selection"
1424 aDescriptor
.erase(DataAccessDescriptorProperty::Connection
);
1425 aDescriptor
.erase(DataAccessDescriptorProperty::Cursor
);
1427 aReturn
<<= aDescriptor
.createPropertyValueSequence();
1430 catch( const Exception
& )
1432 DBG_UNHANDLED_EXCEPTION("dbaccess");
1438 void SAL_CALL
SbaTableQueryBrowser::addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
)
1440 m_aSelectionListeners
.addInterface(_rxListener
);
1443 void SAL_CALL
SbaTableQueryBrowser::removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
)
1445 m_aSelectionListeners
.removeInterface(_rxListener
);
1448 void SbaTableQueryBrowser::attachFrame(const Reference
< css::frame::XFrame
> & _xFrame
)
1450 implRemoveStatusListeners();
1452 if (m_xCurrentFrameParent
.is())
1453 m_xCurrentFrameParent
->removeFrameActionListener(static_cast<css::frame::XFrameActionListener
*>(this));
1455 SbaXDataBrowserController::attachFrame(_xFrame
);
1457 Reference
< XFrame
> xCurrentFrame( getFrame() );
1458 if ( xCurrentFrame
.is() )
1460 m_xCurrentFrameParent
= xCurrentFrame
->findFrame("_parent",FrameSearchFlag::PARENT
);
1461 if ( m_xCurrentFrameParent
.is() )
1462 m_xCurrentFrameParent
->addFrameActionListener(static_cast<css::frame::XFrameActionListener
*>(this));
1464 // obtain our toolbox
1467 Reference
< XPropertySet
> xFrameProps( m_aCurrentFrame
.getFrame(), UNO_QUERY_THROW
);
1468 Reference
< XLayoutManager
> xLayouter(
1469 xFrameProps
->getPropertyValue("LayoutManager"),
1472 if ( xLayouter
.is() )
1474 Reference
< XUIElement
> xUI(
1475 xLayouter
->getElement( "private:resource/toolbar/toolbar" ),
1477 m_xMainToolbar
.set(xUI
->getRealInterface(), css::uno::UNO_QUERY
);
1478 OSL_ENSURE( m_xMainToolbar
.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" );
1481 catch( const Exception
& )
1483 DBG_UNHANDLED_EXCEPTION("dbaccess");
1487 // get the dispatchers for the external slots
1488 connectExternalDispatches();
1491 void SbaTableQueryBrowser::addModelListeners(const Reference
< css::awt::XControlModel
> & _xGridControlModel
)
1493 SbaXDataBrowserController::addModelListeners(_xGridControlModel
);
1494 Reference
< XPropertySet
> xSourceSet(_xGridControlModel
, UNO_QUERY
);
1495 if (xSourceSet
.is())
1497 xSourceSet
->addPropertyChangeListener(PROPERTY_ROW_HEIGHT
, static_cast<XPropertyChangeListener
*>(this));
1498 xSourceSet
->addPropertyChangeListener(PROPERTY_FONT
, static_cast<XPropertyChangeListener
*>(this));
1499 xSourceSet
->addPropertyChangeListener(PROPERTY_TEXTCOLOR
, static_cast<XPropertyChangeListener
*>(this));
1500 xSourceSet
->addPropertyChangeListener(PROPERTY_TEXTLINECOLOR
, static_cast<XPropertyChangeListener
*>(this));
1501 xSourceSet
->addPropertyChangeListener(PROPERTY_TEXTEMPHASIS
, static_cast<XPropertyChangeListener
*>(this));
1502 xSourceSet
->addPropertyChangeListener(PROPERTY_TEXTRELIEF
, static_cast<XPropertyChangeListener
*>(this));
1507 void SbaTableQueryBrowser::removeModelListeners(const Reference
< css::awt::XControlModel
> & _xGridControlModel
)
1509 SbaXDataBrowserController::removeModelListeners(_xGridControlModel
);
1510 Reference
< XPropertySet
> xSourceSet(_xGridControlModel
, UNO_QUERY
);
1511 if (xSourceSet
.is())
1513 xSourceSet
->removePropertyChangeListener(PROPERTY_ROW_HEIGHT
, static_cast<XPropertyChangeListener
*>(this));
1514 xSourceSet
->removePropertyChangeListener(PROPERTY_FONT
, static_cast<XPropertyChangeListener
*>(this));
1515 xSourceSet
->removePropertyChangeListener(PROPERTY_TEXTCOLOR
, static_cast<XPropertyChangeListener
*>(this));
1516 xSourceSet
->removePropertyChangeListener(PROPERTY_TEXTLINECOLOR
, static_cast<XPropertyChangeListener
*>(this));
1517 xSourceSet
->removePropertyChangeListener(PROPERTY_TEXTEMPHASIS
, static_cast<XPropertyChangeListener
*>(this));
1518 xSourceSet
->removePropertyChangeListener(PROPERTY_TEXTRELIEF
, static_cast<XPropertyChangeListener
*>(this));
1522 void SbaTableQueryBrowser::RowChanged()
1524 if(getBrowserView())
1526 SbaGridControl
* pControl
= getBrowserView()->getVclControl();
1527 if (!pControl
->IsEditing())
1528 InvalidateFeature(ID_BROWSER_COPY
);
1530 SbaXDataBrowserController::RowChanged();
1533 void SbaTableQueryBrowser::ColumnChanged()
1535 if(getBrowserView())
1537 SbaGridControl
* pControl
= getBrowserView()->getVclControl();
1538 if (!pControl
->IsEditing())
1539 InvalidateFeature(ID_BROWSER_COPY
);
1541 SbaXDataBrowserController::ColumnChanged();
1544 void SbaTableQueryBrowser::AddColumnListener(const Reference
< XPropertySet
> & xCol
)
1546 SbaXDataBrowserController::AddColumnListener(xCol
);
1547 SafeAddPropertyListener(xCol
, PROPERTY_WIDTH
, static_cast<XPropertyChangeListener
*>(this));
1548 SafeAddPropertyListener(xCol
, PROPERTY_HIDDEN
, static_cast<XPropertyChangeListener
*>(this));
1549 SafeAddPropertyListener(xCol
, PROPERTY_ALIGN
, static_cast<XPropertyChangeListener
*>(this));
1550 SafeAddPropertyListener(xCol
, PROPERTY_FORMATKEY
, static_cast<XPropertyChangeListener
*>(this));
1553 void SbaTableQueryBrowser::RemoveColumnListener(const Reference
< XPropertySet
> & xCol
)
1555 SbaXDataBrowserController::RemoveColumnListener(xCol
);
1556 SafeRemovePropertyListener(xCol
, PROPERTY_WIDTH
, static_cast<XPropertyChangeListener
*>(this));
1557 SafeRemovePropertyListener(xCol
, PROPERTY_HIDDEN
, static_cast<XPropertyChangeListener
*>(this));
1558 SafeRemovePropertyListener(xCol
, PROPERTY_ALIGN
, static_cast<XPropertyChangeListener
*>(this));
1559 SafeRemovePropertyListener(xCol
, PROPERTY_FORMATKEY
, static_cast<XPropertyChangeListener
*>(this));
1562 void SbaTableQueryBrowser::criticalFail()
1564 SbaXDataBrowserController::criticalFail();
1565 unloadAndCleanup( false );
1568 void SbaTableQueryBrowser::LoadFinished(bool _bWasSynch
)
1570 SbaXDataBrowserController::LoadFinished(_bWasSynch
);
1572 m_sQueryCommand
.clear();
1573 m_bQueryEscapeProcessing
= false;
1575 if (isValid() && !loadingCancelled())
1577 // did we load a query?
1578 bool bTemporary
; // needed because we m_bQueryEscapeProcessing is only one bit wide (and we want to pass it by reference)
1579 if ( implGetQuerySignature( m_sQueryCommand
, bTemporary
) )
1580 m_bQueryEscapeProcessing
= bTemporary
;
1583 // if the form has been loaded, this means that our "selection" has changed
1584 css::lang::EventObject
aEvent( *this );
1585 m_aSelectionListeners
.notifyEach( &XSelectionChangeListener::selectionChanged
, aEvent
);
1588 bool SbaTableQueryBrowser::getExternalSlotState( sal_uInt16 _nId
) const
1590 bool bEnabled
= false;
1591 ExternalFeaturesMap::const_iterator aPos
= m_aExternalFeatures
.find( _nId
);
1592 if ( ( m_aExternalFeatures
.end() != aPos
) && aPos
->second
.xDispatcher
.is() )
1593 bEnabled
= aPos
->second
.bEnabled
;
1597 FeatureState
SbaTableQueryBrowser::GetState(sal_uInt16 nId
) const
1599 FeatureState aReturn
;
1600 // (disabled automatically)
1602 // no chance without a view
1603 if (!getBrowserView() || !getBrowserView()->getVclControl())
1608 case ID_TREE_ADMINISTRATE
:
1609 aReturn
.bEnabled
= true;
1612 case ID_BROWSER_CLOSE
:
1613 // the close button should always be enabled
1614 aReturn
.bEnabled
= !m_bEnableBrowser
;
1617 // "toggle explorer" is always enabled (if we have an explorer)
1618 case ID_BROWSER_EXPLORER
:
1619 aReturn
.bEnabled
= m_bEnableBrowser
;
1620 aReturn
.bChecked
= haveExplorer();
1623 case ID_BROWSER_REMOVEFILTER
:
1624 return SbaXDataBrowserController::GetState( nId
);
1626 case ID_BROWSER_COPY
:
1627 if ( !m_pTreeView
->HasChildPathFocus() )
1631 case ID_TREE_CLOSE_CONN
:
1632 case ID_TREE_EDIT_DATABASE
:
1634 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
1635 std::unique_ptr
<weld::TreeIter
> xCurrentEntry(rTreeView
.make_iterator());
1636 if (!rTreeView
.get_cursor(xCurrentEntry
.get()))
1639 EntryType eType
= getEntryType(*xCurrentEntry
);
1640 if ( eType
== etUnknown
)
1643 std::unique_ptr
<weld::TreeIter
> xDataSourceEntry
= m_pTreeView
->GetRootLevelParent(xCurrentEntry
.get());
1644 DBTreeListUserData
* pDSData
1646 ? reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xDataSourceEntry
).toUInt64())
1649 if ( nId
== ID_TREE_CLOSE_CONN
)
1651 aReturn
.bEnabled
= ( pDSData
!= nullptr ) && pDSData
->xConnection
.is();
1653 else if ( nId
== ID_TREE_EDIT_DATABASE
)
1655 ::utl::OConfigurationTreeRoot
aConfig( ::utl::OConfigurationTreeRoot::createWithComponentContext( getORB(),
1656 "/org.openoffice.Office.DataAccess/Policies/Features/Common" ) );
1657 bool bHaveEditDatabase( true );
1658 OSL_VERIFY( aConfig
.getNodeValue( "EditDatabaseFromDataSourceView" ) >>= bHaveEditDatabase
);
1659 aReturn
.bEnabled
= getORB().is() && xDataSourceEntry
&& bHaveEditDatabase
;
1661 else if ( nId
== ID_BROWSER_COPY
)
1663 aReturn
.bEnabled
= isEntryCopyAllowed(*xCurrentEntry
);
1670 // all slots not handled above are not available if no form is loaded
1676 bool bHandled
= false;
1679 case ID_BROWSER_DOCUMENT_DATASOURCE
:
1680 // the slot is enabled if we have an external dispatcher able to handle it,
1681 // and the dispatcher must have enabled the slot in general
1682 aReturn
.bEnabled
= getExternalSlotState( ID_BROWSER_DOCUMENT_DATASOURCE
);
1685 case ID_BROWSER_REFRESH
:
1686 aReturn
.bEnabled
= true;
1694 // no chance without valid models
1695 if (isValid() && !isValidCursor() && nId
!= ID_BROWSER_CLOSE
)
1700 case ID_BROWSER_INSERTCOLUMNS
:
1701 case ID_BROWSER_INSERTCONTENT
:
1702 case ID_BROWSER_FORMLETTER
:
1704 // the slot is enabled if we have an external dispatcher able to handle it,
1705 // and the dispatcher must have enabled the slot in general
1706 aReturn
.bEnabled
= getExternalSlotState( nId
);
1708 // for the Insert* slots, we need at least one selected row
1709 if (ID_BROWSER_FORMLETTER
!= nId
)
1710 aReturn
.bEnabled
= aReturn
.bEnabled
&& getBrowserView()->getVclControl()->GetSelectRowCount();
1712 // disabled for native queries which are not saved within the database
1713 Reference
< XPropertySet
> xDataSource(getRowSet(), UNO_QUERY
);
1716 aReturn
.bEnabled
= aReturn
.bEnabled
&& xDataSource
.is();
1718 if (xDataSource
.is())
1720 sal_Int32 nType
= ::comphelper::getINT32(xDataSource
->getPropertyValue(PROPERTY_COMMAND_TYPE
));
1721 aReturn
.bEnabled
= aReturn
.bEnabled
&&
1722 ( ::comphelper::getBOOL(xDataSource
->getPropertyValue(PROPERTY_ESCAPE_PROCESSING
)) ||
1723 (nType
== css::sdb::CommandType::QUERY
) );
1726 catch(DisposedException
&)
1728 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::GetState: object already disposed!");
1730 catch( const Exception
& )
1732 DBG_UNHANDLED_EXCEPTION("dbaccess");
1737 case ID_BROWSER_TITLE
:
1739 Reference
<XPropertySet
> xProp(getRowSet(),UNO_QUERY
);
1740 sal_Int32 nCommandType
= CommandType::TABLE
;
1741 xProp
->getPropertyValue(PROPERTY_COMMAND_TYPE
) >>= nCommandType
;
1743 switch (nCommandType
)
1745 case CommandType::TABLE
:
1746 sTitle
= DBA_RES(STR_TBL_TITLE
); break;
1747 case CommandType::QUERY
:
1748 case CommandType::COMMAND
:
1749 sTitle
= DBA_RES(STR_QRY_TITLE
); break;
1751 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::GetState: unknown command type!");
1754 xProp
->getPropertyValue(PROPERTY_COMMAND
) >>= aName
;
1755 OUString
sObject(aName
);
1757 aReturn
.sTitle
= sTitle
.replaceFirst("#", sObject
);
1758 aReturn
.bEnabled
= true;
1761 case ID_BROWSER_TABLEATTR
:
1762 case ID_BROWSER_ROWHEIGHT
:
1763 case ID_BROWSER_COLATTRSET
:
1764 case ID_BROWSER_COLWIDTH
:
1765 aReturn
.bEnabled
= getBrowserView()->getVclControl() && isValid() && isValidCursor();
1766 // aReturn.bEnabled &= getDefinition() && !getDefinition()->GetDatabase()->IsReadOnly();
1769 case ID_BROWSER_COPY
:
1770 OSL_ENSURE( !m_pTreeView
->HasChildPathFocus(), "SbaTableQueryBrowser::GetState( ID_BROWSER_COPY ): this should have been handled above!" );
1771 if (getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing())
1773 SbaGridControl
* pControl
= getBrowserView()->getVclControl();
1774 if ( pControl
->GetSelectRowCount() )
1776 aReturn
.bEnabled
= m_aCurrentFrame
.isActive();
1780 aReturn
.bEnabled
= pControl
->canCopyCellText(pControl
->GetCurRow(), pControl
->GetCurColumnId());
1785 return SbaXDataBrowserController::GetState(nId
);
1788 catch(const Exception
&)
1790 DBG_UNHANDLED_EXCEPTION("dbaccess");
1797 void SbaTableQueryBrowser::Execute(sal_uInt16 nId
, const Sequence
< PropertyValue
>& aArgs
)
1802 SbaXDataBrowserController::Execute(nId
,aArgs
);
1805 case ID_TREE_EDIT_DATABASE
:
1807 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
1808 std::unique_ptr
<weld::TreeIter
> xIter(rTreeView
.make_iterator());
1809 if (rTreeView
.get_cursor(xIter
.get()))
1810 implAdministrate(*xIter
);
1813 case ID_TREE_CLOSE_CONN
:
1815 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
1816 std::unique_ptr
<weld::TreeIter
> xIter(rTreeView
.make_iterator());
1817 if (rTreeView
.get_cursor(xIter
.get()))
1819 xIter
= m_pTreeView
->GetRootLevelParent(xIter
.get());
1820 closeConnection(*xIter
);
1824 case ID_TREE_ADMINISTRATE
:
1825 svx::administrateDatabaseRegistration( getFrameWeld() );
1828 case ID_BROWSER_REFRESH
:
1830 if ( !SaveModified( ) )
1834 bool bFullReinit
= false;
1835 // check if the query signature (if the form is based on a query) has changed
1836 if ( !m_sQueryCommand
.isEmpty() )
1838 OUString sNewQueryCommand
;
1842 implGetQuerySignature( sNewQueryCommand
, bNewQueryEP
);
1843 OSL_ENSURE( bIsQuery
, "SbaTableQueryBrowser::Execute: was a query before, but is not anymore?" );
1845 bFullReinit
= ( sNewQueryCommand
!= m_sQueryCommand
) || ( m_bQueryEscapeProcessing
!= bNewQueryEP
);
1849 // let the base class do a simple reload
1850 SbaXDataBrowserController::Execute(nId
,aArgs
);
1856 case ID_BROWSER_REFRESH_REBUILD
:
1858 if ( !SaveModified() )
1862 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
1863 std::unique_ptr
<weld::TreeIter
> xSelected
= m_xCurrentlyDisplayed
?
1864 rTreeView
.make_iterator(m_xCurrentlyDisplayed
.get()) : nullptr;
1867 unloadAndCleanup( false );
1869 // reselect the entry
1872 implSelect(xSelected
.get());
1876 Reference
<XPropertySet
> xProp(getRowSet(),UNO_QUERY
);
1877 implSelect(svx::ODataAccessDescriptor(xProp
));
1882 case ID_BROWSER_EXPLORER
:
1886 case ID_BROWSER_DOCUMENT_DATASOURCE
:
1887 implSelect(m_aDocumentDataSource
);
1890 case ID_BROWSER_INSERTCOLUMNS
:
1891 case ID_BROWSER_INSERTCONTENT
:
1892 case ID_BROWSER_FORMLETTER
:
1893 if (getBrowserView() && isValidCursor())
1895 // the URL the slot id is assigned to
1896 OSL_ENSURE( m_aExternalFeatures
.find( nId
) != m_aExternalFeatures
.end(),
1897 "SbaTableQueryBrowser::Execute( ID_BROWSER_?): how could this ever be enabled?" );
1898 URL aParentUrl
= m_aExternalFeatures
[ nId
].aURL
;
1900 // let the dispatcher execute the slot
1901 Reference
< XDispatch
> xDispatch( m_aExternalFeatures
[ nId
].xDispatcher
);
1904 // set the properties for the dispatch
1906 // first fill the selection
1907 SbaGridControl
* pGrid
= getBrowserView()->getVclControl();
1908 MultiSelection
* pSelection
= const_cast<MultiSelection
*>(pGrid
->GetSelection());
1909 Sequence
< Any
> aSelection
;
1910 if ( !pGrid
->IsAllSelected() )
1911 { // transfer the selected rows only if not all rows are selected
1912 // (all rows means the whole table)
1914 if (pSelection
!= nullptr)
1916 aSelection
.realloc(pSelection
->GetSelectCount());
1917 tools::Long nIdx
= pSelection
->FirstSelected();
1918 Any
* pSelectionNos
= aSelection
.getArray();
1919 while (nIdx
!= SFX_ENDOFSELECTION
)
1921 *pSelectionNos
++ <<= static_cast<sal_Int32
>(nIdx
+ 1);
1922 nIdx
= pSelection
->NextSelected();
1927 Reference
< XResultSet
> xCursorClone
;
1930 Reference
< XResultSetAccess
> xResultSetAccess(getRowSet(),UNO_QUERY
);
1931 if (xResultSetAccess
.is())
1932 xCursorClone
= xResultSetAccess
->createResultSet();
1934 catch(DisposedException
&)
1936 SAL_WARN("dbaccess.ui", "Object already disposed!");
1938 catch(const Exception
&)
1940 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not clone the cursor!");
1943 Reference
<XPropertySet
> xProp(getRowSet(),UNO_QUERY
);
1947 ODataAccessDescriptor aDescriptor
;
1948 OUString sDataSourceName
;
1949 xProp
->getPropertyValue(PROPERTY_DATASOURCENAME
) >>= sDataSourceName
;
1951 aDescriptor
.setDataSource(sDataSourceName
);
1952 aDescriptor
[DataAccessDescriptorProperty::Command
] = xProp
->getPropertyValue(PROPERTY_COMMAND
);
1953 aDescriptor
[DataAccessDescriptorProperty::CommandType
] = xProp
->getPropertyValue(PROPERTY_COMMAND_TYPE
);
1954 aDescriptor
[DataAccessDescriptorProperty::Connection
] = xProp
->getPropertyValue(PROPERTY_ACTIVE_CONNECTION
);
1955 aDescriptor
[DataAccessDescriptorProperty::Cursor
] <<= xCursorClone
;
1956 if ( aSelection
.hasElements() )
1958 aDescriptor
[DataAccessDescriptorProperty::Selection
] <<= aSelection
;
1959 aDescriptor
[DataAccessDescriptorProperty::BookmarkSelection
] <<= false;
1960 // these are selection indices
1961 // before we change this, all clients have to be adjusted
1962 // so that they recognize the new BookmarkSelection property!
1965 xDispatch
->dispatch(aParentUrl
, aDescriptor
.createPropertyValueSequence());
1967 catch( const Exception
& )
1969 DBG_UNHANDLED_EXCEPTION("dbaccess");
1975 case ID_BROWSER_CLOSE
:
1977 // if it's not 0, such an async close is already pending
1980 case ID_BROWSER_COPY
:
1981 if(m_pTreeView
->HasChildPathFocus())
1983 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
1984 std::unique_ptr
<weld::TreeIter
> xCursor(rTreeView
.make_iterator());
1985 if (rTreeView
.get_cursor(xCursor
.get()))
1986 copyEntry(*xCursor
);
1988 else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing() && getBrowserView()->getVclControl()->GetSelectRowCount() < 1)
1990 SbaGridControl
* pControl
= getBrowserView()->getVclControl();
1991 pControl
->copyCellText(pControl
->GetCurRow(), pControl
->GetCurColumnId());
1994 SbaXDataBrowserController::Execute(nId
,aArgs
);
1999 void SbaTableQueryBrowser::implAddDatasource( const OUString
& _rDataSourceName
, const SharedConnection
& _rxConnection
)
2001 OUString a
, b
, c
, d
, e
;
2002 implAddDatasource( _rDataSourceName
, a
, d
, b
, e
, c
, _rxConnection
);
2005 void SbaTableQueryBrowser::implAddDatasource(const OUString
& _rDbName
, OUString
& _rDbImage
,
2006 OUString
& _rQueryName
, OUString
& _rQueryImage
, OUString
& _rTableName
, OUString
& _rTableImage
,
2007 const SharedConnection
& _rxConnection
)
2009 SolarMutexGuard aGuard
;
2010 // initialize the names/images if necessary
2011 if (_rQueryName
.isEmpty())
2012 _rQueryName
= DBA_RES(RID_STR_QUERIES_CONTAINER
);
2013 if (_rTableName
.isEmpty())
2014 _rTableName
= DBA_RES(RID_STR_TABLES_CONTAINER
);
2016 if (_rQueryImage
.isEmpty())
2017 _rQueryImage
= ImageProvider::getFolderImageId(DatabaseObject::QUERY
);
2018 if (_rTableImage
.isEmpty())
2019 _rTableImage
= ImageProvider::getFolderImageId(DatabaseObject::TABLE
);
2021 if (_rDbImage
.isEmpty())
2022 _rDbImage
= ImageProvider::getDatabaseImage();
2024 // add the entry for the data source
2025 // special handling for data sources denoted by URLs - we do not want to display this ugly URL, do we?
2027 OUString sDSDisplayName
, sDataSourceId
;
2028 getDataSourceDisplayName_isURL( _rDbName
, sDSDisplayName
, sDataSourceId
);
2030 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2031 DBTreeListUserData
* pDSData
= new DBTreeListUserData
;
2032 pDSData
->eType
= etDatasource
;
2033 pDSData
->sAccessor
= sDataSourceId
;
2034 pDSData
->xConnection
= _rxConnection
;
2035 OUString
sId(OUString::number(reinterpret_cast<sal_uInt64
>(pDSData
)));
2037 std::unique_ptr
<weld::TreeIter
> xDatasourceEntry(rTreeView
.make_iterator());
2038 rTreeView
.insert(nullptr, -1, &sDSDisplayName
, &sId
, nullptr, nullptr, false, xDatasourceEntry
.get());
2039 rTreeView
.set_image(*xDatasourceEntry
, _rDbImage
);
2040 rTreeView
.set_text_emphasis(*xDatasourceEntry
, false, 0);
2042 // the child for the queries container
2044 DBTreeListUserData
* pQueriesData
= new DBTreeListUserData
;
2045 pQueriesData
->eType
= etQueryContainer
;
2046 sId
= OUString::number(reinterpret_cast<sal_uInt64
>(pQueriesData
));
2048 std::unique_ptr
<weld::TreeIter
> xRet(rTreeView
.make_iterator());
2049 rTreeView
.insert(xDatasourceEntry
.get(), -1, &_rQueryName
, &sId
,
2050 nullptr, nullptr, true /*ChildrenOnDemand*/, xRet
.get());
2051 rTreeView
.set_image(*xRet
, _rQueryImage
);
2052 rTreeView
.set_text_emphasis(*xRet
, false, 0);
2055 // the child for the tables container
2057 DBTreeListUserData
* pTablesData
= new DBTreeListUserData
;
2058 pTablesData
->eType
= etTableContainer
;
2059 sId
= OUString::number(reinterpret_cast<sal_uInt64
>(pTablesData
));
2061 std::unique_ptr
<weld::TreeIter
> xRet(rTreeView
.make_iterator());
2062 rTreeView
.insert(xDatasourceEntry
.get(), -1, &_rTableName
, &sId
,
2063 nullptr, nullptr, true /*ChildrenOnDemand*/, xRet
.get());
2064 rTreeView
.set_image(*xRet
, _rTableImage
);
2065 rTreeView
.set_text_emphasis(*xRet
, false, 0);
2069 void SbaTableQueryBrowser::initializeTreeModel()
2071 if (m_xDatabaseContext
.is())
2073 OUString aDBImage
, aQueriesImage
, aTablesImage
;
2074 OUString sQueriesName
, sTablesName
;
2076 // fill the model with the names of the registered datasources
2077 const Sequence
<OUString
> aDatasourceNames
= m_xDatabaseContext
->getElementNames();
2078 for (const OUString
& rDatasource
: aDatasourceNames
)
2079 implAddDatasource( rDatasource
, aDBImage
, sQueriesName
, aQueriesImage
, sTablesName
, aTablesImage
, SharedConnection() );
2083 void SbaTableQueryBrowser::populateTree(const Reference
<XNameAccess
>& _xNameAccess
,
2084 const weld::TreeIter
& rParent
,
2085 EntryType eEntryType
)
2087 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2088 rTreeView
.make_unsorted();
2090 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(rParent
).toUInt64());
2091 if (pData
) // don't ask if the nameaccess is already set see OnExpandEntry views and tables
2092 pData
->xContainer
= _xNameAccess
;
2096 const Sequence
<OUString
> aNames
= _xNameAccess
->getElementNames();
2097 for (const OUString
& rName
: aNames
)
2099 if( !m_pTreeView
->GetEntryPosByName(rName
, &rParent
))
2101 DBTreeListUserData
* pEntryData
= new DBTreeListUserData
;
2102 pEntryData
->eType
= eEntryType
;
2103 if ( eEntryType
== etQuery
)
2105 Reference
<XNameAccess
> xChild(_xNameAccess
->getByName(rName
),UNO_QUERY
);
2107 pEntryData
->eType
= etQueryContainer
;
2109 implAppendEntry(&rParent
, rName
, pEntryData
);
2113 catch(const Exception
&)
2115 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::populateTree: could not fill the tree");
2118 rTreeView
.make_sorted();
2121 std::unique_ptr
<weld::TreeIter
> SbaTableQueryBrowser::implAppendEntry(const weld::TreeIter
* pParent
, const OUString
& rName
, DBTreeListUserData
* pUserData
)
2123 EntryType eEntryType
= pUserData
->eType
;
2125 std::unique_ptr
<ImageProvider
> xImageProvider(getImageProviderFor(pParent
));
2127 OUString aImage
= xImageProvider
->getImageId(rName
, getDatabaseObjectType(eEntryType
));
2129 OUString
sId(OUString::number(reinterpret_cast<sal_uInt64
>(pUserData
)));
2130 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2131 std::unique_ptr
<weld::TreeIter
> xNewEntry(rTreeView
.make_iterator());
2132 rTreeView
.insert(pParent
, -1, &rName
, &sId
, nullptr, nullptr, eEntryType
== etQueryContainer
, xNewEntry
.get());
2133 rTreeView
.set_image(*xNewEntry
, aImage
);
2134 rTreeView
.set_text_emphasis(*xNewEntry
, false, 0);
2139 IMPL_LINK(SbaTableQueryBrowser
, OnExpandEntry
, const weld::TreeIter
&, rParent
, bool)
2141 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2142 if (rTreeView
.iter_has_child(rParent
))
2148 std::unique_ptr
<weld::TreeIter
> xFirstParent
= m_pTreeView
->GetRootLevelParent(&rParent
);
2149 OSL_ENSURE(xFirstParent
,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!");
2151 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(rParent
).toInt64());
2152 assert(pData
&& "SbaTableQueryBrowser::OnExpandEntry: No user data!");
2154 if (etTableContainer
== pData
->eType
)
2156 weld::WaitObject
aWaitCursor(getFrameWeld());
2158 // it could be that we already have a connection
2159 SharedConnection xConnection
;
2160 ensureConnection(xFirstParent
.get(), xConnection
);
2162 if ( xConnection
.is() )
2164 SQLExceptionInfo aInfo
;
2167 Reference
< XWarningsSupplier
> xWarnings(xConnection
, UNO_QUERY
);
2169 xWarnings
->clearWarnings();
2171 // first insert the views because the tables can also include
2172 // views but that time the bitmap is the wrong one
2173 // the nameaccess will be overwritten in populateTree
2174 Reference
<XViewsSupplier
> xViewSup(xConnection
,UNO_QUERY
);
2176 populateTree( xViewSup
->getViews(), rParent
, etTableOrView
);
2178 Reference
<XTablesSupplier
> xTabSup(xConnection
,UNO_QUERY
);
2181 populateTree( xTabSup
->getTables(), rParent
, etTableOrView
);
2182 Reference
<XContainer
> xCont(xTabSup
->getTables(),UNO_QUERY
);
2184 // add as listener to know when elements are inserted or removed
2185 xCont
->addContainerListener(this);
2191 SQLExceptionInfo
aWarnings(xWarnings
->getWarnings());
2192 // Obviously this if test is always false. So to avoid a Clang warning
2193 // "use of logical '&&' with constant operand" I put this in #if
2194 // 0. Yeah, I know it is fairly likely nobody will ever read this
2195 // comment and make a decision what to do here, so I could as well
2196 // have just binned this...
2197 if (aWarnings
.isValid() && sal_False
)
2199 SQLContext aContext
;
2200 aContext
.Message
= DBA_RES(STR_OPENTABLES_WARNINGS
);
2201 aContext
.Details
= DBA_RES(STR_OPENTABLES_WARNINGS_DETAILS
);
2202 aContext
.NextException
= aWarnings
.get();
2203 aWarnings
= aContext
;
2204 showError(aWarnings
);
2207 // TODO: we need a better concept for these warnings:
2208 // something like "don't show any warnings for this datasource, again" would be nice
2209 // But this requires an extension of the InteractionHandler and an additional property on the data source
2212 catch(const SQLContext
& e
) { aInfo
= e
; }
2213 catch(const SQLWarning
& e
) { aInfo
= e
; }
2214 catch(const SQLException
& e
) { aInfo
= e
; }
2215 catch(const WrappedTargetException
& e
)
2218 if(e
.TargetException
>>= aSql
)
2221 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnExpandEntry: something strange happened!");
2223 catch( const Exception
& )
2225 DBG_UNHANDLED_EXCEPTION("dbaccess");
2227 if (aInfo
.isValid())
2232 // 0 indicates that an error occurred
2236 // we have to expand the queries or bookmarks
2237 if (ensureEntryObject(rParent
))
2239 DBTreeListUserData
* pParentData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(rParent
).toUInt64());
2240 Reference
< XNameAccess
> xCollection( pParentData
->xContainer
, UNO_QUERY
);
2241 populateTree(xCollection
, rParent
, etQuery
);
2247 bool SbaTableQueryBrowser::ensureEntryObject(const weld::TreeIter
& rEntry
)
2249 EntryType eType
= getEntryType(rEntry
);
2251 // the user data of the entry
2252 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2253 DBTreeListUserData
* pEntryData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(rEntry
).toUInt64());
2254 OSL_ENSURE(pEntryData
,"ensureEntryObject: user data should already be set!");
2256 std::unique_ptr
<weld::TreeIter
> xDataSourceEntry
= m_pTreeView
->GetRootLevelParent(&rEntry
);
2258 bool bSuccess
= false;
2261 case etQueryContainer
:
2263 if ( pEntryData
->xContainer
.is() )
2270 std::unique_ptr
<weld::TreeIter
> xParent(rTreeView
.make_iterator(&rEntry
));
2271 if (rTreeView
.iter_parent(*xParent
))
2273 if (rTreeView
.iter_compare(*xParent
, *xDataSourceEntry
) != 0)
2275 OUString
aName(rTreeView
.get_text(rEntry
));
2276 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xParent
).toUInt64());
2279 Reference
< XNameAccess
> xNameAccess(pData
->xContainer
,UNO_QUERY
);
2280 if ( xNameAccess
.is() )
2281 pEntryData
->xContainer
.set(xNameAccess
->getByName(aName
),UNO_QUERY
);
2283 catch(const Exception
& )
2285 DBG_UNHANDLED_EXCEPTION("dbaccess");
2288 bSuccess
= pEntryData
->xContainer
.is();
2294 Reference
< XQueryDefinitionsSupplier
> xQuerySup
;
2295 m_xDatabaseContext
->getByName(getDataSourceAccessor(*xDataSourceEntry
)) >>= xQuerySup
;
2298 Reference
< XNameAccess
> xQueryDefs
= xQuerySup
->getQueryDefinitions();
2299 Reference
< XContainer
> xCont(xQueryDefs
, UNO_QUERY
);
2301 // add as listener to get notified if elements are inserted or removed
2302 xCont
->addContainerListener(this);
2304 pEntryData
->xContainer
= xQueryDefs
;
2305 bSuccess
= pEntryData
->xContainer
.is();
2308 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::ensureEntryObject: no XQueryDefinitionsSupplier interface!");
2311 catch( const Exception
& )
2313 DBG_UNHANDLED_EXCEPTION("dbaccess");
2320 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::ensureEntryObject: ooops ... missing some implementation here!");
2327 bool SbaTableQueryBrowser::implSelect(const svx::ODataAccessDescriptor
& _rDescriptor
, bool _bSelectDirect
)
2329 // extract the props
2330 OUString sDataSource
;
2332 sal_Int32 nCommandType
= CommandType::COMMAND
;
2333 bool bEscapeProcessing
= true;
2334 extractDescriptorProps(_rDescriptor
, sDataSource
, sCommand
, nCommandType
, bEscapeProcessing
);
2337 return implSelect( sDataSource
, sCommand
, nCommandType
, bEscapeProcessing
, SharedConnection(), _bSelectDirect
);
2340 bool SbaTableQueryBrowser::implLoadAnything(const OUString
& _rDataSourceName
, const OUString
& _rCommand
,
2341 const sal_Int32 nCommandType
, const bool _bEscapeProcessing
, const SharedConnection
& _rxConnection
)
2345 Reference
<XPropertySet
> xProp( getRowSet(), UNO_QUERY_THROW
);
2346 Reference
< XLoadable
> xLoadable( xProp
, UNO_QUERY_THROW
);
2347 // the values allowing the RowSet to re-execute
2348 xProp
->setPropertyValue(PROPERTY_DATASOURCENAME
, makeAny(_rDataSourceName
));
2349 if(_rxConnection
.is())
2350 xProp
->setPropertyValue( PROPERTY_ACTIVE_CONNECTION
, makeAny( _rxConnection
.getTyped() ) );
2352 // set this _before_ setting the connection, else the rowset would rebuild it ...
2353 xProp
->setPropertyValue(PROPERTY_COMMAND_TYPE
, makeAny(nCommandType
));
2354 xProp
->setPropertyValue(PROPERTY_COMMAND
, makeAny(_rCommand
));
2355 xProp
->setPropertyValue(PROPERTY_ESCAPE_PROCESSING
, css::uno::makeAny(_bEscapeProcessing
));
2358 xProp
->setPropertyValue(PROPERTY_FETCHDIRECTION
, makeAny(FetchDirection::FORWARD
));
2361 // the formatter depends on the data source we're working on, so rebuild it here ...
2364 // switch the grid to design mode while loading
2365 getBrowserView()->getGridControl()->setDesignMode(true);
2366 InitializeForm( xProp
);
2368 bool bSuccess
= true;
2372 Reference
< XNameContainer
> xColContainer(getFormComponent(), UNO_QUERY
);
2373 // first we have to clear the grid
2374 clearGridColumns(xColContainer
);
2376 FormErrorHelper
aHelper(this);
2378 bSuccess
= reloadForm(xLoadable
);
2380 // initialize the model
2381 InitializeGridModel(getFormComponent());
2383 Any aVal
= xProp
->getPropertyValue(PROPERTY_ISNEW
);
2384 if (aVal
.hasValue() && ::comphelper::getBOOL(aVal
))
2386 // then set the default values and the parameters given from the parent
2387 Reference
< XReset
> xReset(xProp
, UNO_QUERY
);
2392 initializePreviewMode();
2400 catch( const SQLException
& )
2402 Any
aException( ::cppu::getCaughtException() );
2403 showError( SQLExceptionInfo( aException
) );
2405 catch( const WrappedTargetException
& e
)
2407 if ( e
.TargetException
.isExtractableTo( ::cppu::UnoType
< SQLException
>::get() ) )
2408 showError( SQLExceptionInfo( e
.TargetException
) );
2411 TOOLS_WARN_EXCEPTION("dbaccess", "");
2414 catch(const Exception
&)
2416 DBG_UNHANDLED_EXCEPTION("dbaccess");
2423 bool SbaTableQueryBrowser::implSelect(const OUString
& _rDataSourceName
, const OUString
& _rCommand
,
2424 const sal_Int32 nCommandType
, const bool _bEscapeProcessing
,
2425 const SharedConnection
& _rxConnection
,
2426 bool _bSelectDirect
)
2428 if (_rDataSourceName
.getLength() && _rCommand
.getLength() && (-1 != nCommandType
))
2430 std::unique_ptr
<weld::TreeIter
> xDataSource
;
2431 std::unique_ptr
<weld::TreeIter
> xCommandType
;
2432 std::unique_ptr
<weld::TreeIter
> xCommand
= getObjectEntry( _rDataSourceName
, _rCommand
, nCommandType
, &xDataSource
, &xCommandType
, true, _rxConnection
);
2436 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2438 bool bSuccess
= true;
2439 if ( _bSelectDirect
)
2441 bSuccess
= implSelect(xCommand
.get());
2445 rTreeView
.select(*xCommand
);
2450 rTreeView
.scroll_to_row(*xCommand
);
2451 rTreeView
.set_cursor(*xCommand
);
2454 else if (!xCommandType
)
2456 if (m_xCurrentlyDisplayed
)
2458 // tell the old entry (if any) it has been deselected
2459 selectPath(m_xCurrentlyDisplayed
.get(), false);
2460 m_xCurrentlyDisplayed
.reset();
2463 // we have a command and need to display this in the rowset
2464 return implLoadAnything(_rDataSourceName
, _rCommand
, nCommandType
, _bEscapeProcessing
, _rxConnection
);
2470 IMPL_LINK_NOARG(SbaTableQueryBrowser
, OnSelectionChange
, LinkParamNone
*, void)
2472 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2473 std::unique_ptr
<weld::TreeIter
> xSelection(rTreeView
.make_iterator());
2474 if (!rTreeView
.get_selected(xSelection
.get()))
2476 implSelect(xSelection
.get());
2479 std::unique_ptr
<weld::TreeIter
> SbaTableQueryBrowser::implGetConnectionEntry(weld::TreeIter
& rEntry
) const
2481 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2482 std::unique_ptr
<weld::TreeIter
> xCurrentEntry(rTreeView
.make_iterator(&rEntry
));
2483 DBTreeListUserData
* pEntryData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xCurrentEntry
).toInt64());
2484 while (pEntryData
->eType
!= etDatasource
)
2486 rTreeView
.iter_parent(*xCurrentEntry
);
2487 pEntryData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xCurrentEntry
).toInt64());
2489 return xCurrentEntry
;
2492 bool SbaTableQueryBrowser::implSelect(const weld::TreeIter
* pEntry
)
2497 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2498 DBTreeListUserData
* pEntryData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*pEntry
).toUInt64());
2499 switch (pEntryData
->eType
)
2509 OSL_ENSURE(rTreeView
.get_iter_depth(*pEntry
) >= 2, "SbaTableQueryBrowser::implSelect: invalid entry!");
2511 // get the entry for the tables or queries
2512 std::unique_ptr
<weld::TreeIter
> xContainer
= rTreeView
.make_iterator(pEntry
);
2513 rTreeView
.iter_parent(*xContainer
);
2514 DBTreeListUserData
* pContainerData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xContainer
).toUInt64());
2516 // get the entry for the datasource
2517 std::unique_ptr
<weld::TreeIter
> xConnection
= implGetConnectionEntry(*xContainer
);
2518 DBTreeListUserData
* pConData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xConnection
).toUInt64());
2520 // reinitialize the rowset
2521 // but first check if it is necessary
2522 // get all old properties
2523 Reference
<XPropertySet
> xRowSetProps(getRowSet(),UNO_QUERY
);
2525 xRowSetProps
->getPropertyValue(PROPERTY_COMMAND
) >>= aOldName
;
2526 sal_Int32 nOldType
= 0;
2527 xRowSetProps
->getPropertyValue(PROPERTY_COMMAND_TYPE
) >>= nOldType
;
2528 Reference
<XConnection
> xOldConnection(xRowSetProps
->getPropertyValue(PROPERTY_ACTIVE_CONNECTION
),UNO_QUERY
);
2530 // the name of the table or query
2531 const OUString sSimpleName
= rTreeView
.get_text(*pEntry
);
2532 OUStringBuffer
sNameBuffer(sSimpleName
);
2533 if ( etQueryContainer
== pContainerData
->eType
)
2535 std::unique_ptr
<weld::TreeIter
> xTemp
= rTreeView
.make_iterator(xContainer
.get());
2536 std::unique_ptr
<weld::TreeIter
> xNextTemp
= rTreeView
.make_iterator(xTemp
.get());
2537 if (rTreeView
.iter_parent(*xNextTemp
))
2539 while (rTreeView
.iter_compare(*xNextTemp
, *xConnection
) != 0)
2541 sNameBuffer
.insert(0,'/');
2542 sNameBuffer
.insert(0, rTreeView
.get_text(*xTemp
));
2543 rTreeView
.copy_iterator(*xNextTemp
, *xTemp
);
2544 if (!rTreeView
.iter_parent(*xNextTemp
))
2549 OUString aName
= sNameBuffer
.makeStringAndClear();
2551 sal_Int32 nCommandType
= ( etTableContainer
== pContainerData
->eType
)
2552 ? CommandType::TABLE
2553 : CommandType::QUERY
;
2555 // check if need to rebuild the rowset
2556 bool bRebuild
= ( xOldConnection
!= pConData
->xConnection
)
2557 || ( nOldType
!= nCommandType
)
2558 || ( aName
!= aOldName
);
2560 Reference
< css::form::XLoadable
> xLoadable
= getLoadable();
2561 bRebuild
|= !xLoadable
->isLoaded();
2562 bool bSuccess
= true;
2567 weld::WaitObject
aWaitCursor(getFrameWeld());
2569 // tell the old entry it has been deselected
2570 selectPath(m_xCurrentlyDisplayed
.get(), false);
2571 m_xCurrentlyDisplayed
.reset();
2573 // not really loaded
2574 m_xCurrentlyDisplayed
= rTreeView
.make_iterator(pEntry
);
2575 // tell the new entry it has been selected
2576 selectPath(m_xCurrentlyDisplayed
.get());
2578 // get the name of the data source currently selected
2579 ensureConnection(m_xCurrentlyDisplayed
.get(), pConData
->xConnection
);
2581 if ( !pConData
->xConnection
.is() )
2583 unloadAndCleanup( false );
2587 Reference
<XNameAccess
> xNameAccess
;
2588 switch(nCommandType
)
2590 case CommandType::TABLE
:
2593 if ( !pContainerData
->xContainer
.is() )
2595 Reference
<XTablesSupplier
> xSup( pConData
->xConnection
, UNO_QUERY
);
2597 xNameAccess
= xSup
->getTables();
2599 pContainerData
->xContainer
= xNameAccess
;
2602 xNameAccess
.set( pContainerData
->xContainer
, UNO_QUERY
);
2605 case CommandType::QUERY
:
2607 if ( pContainerData
->xContainer
.is() )
2608 xNameAccess
.set( pContainerData
->xContainer
, UNO_QUERY
);
2611 Reference
<XQueriesSupplier
> xSup( pConData
->xConnection
, UNO_QUERY
);
2613 xNameAccess
= xSup
->getQueries();
2618 OUString
sStatus(DBA_RES(CommandType::TABLE
== nCommandType
? STR_LOADING_TABLE
: STR_LOADING_QUERY
));
2619 sStatus
= sStatus
.replaceFirst("$name$", aName
);
2620 BrowserViewStatusDisplay
aShowStatus(static_cast<UnoDataBrowserView
*>(getView()), sStatus
);
2622 bool bEscapeProcessing
= true;
2623 if(xNameAccess
.is() && xNameAccess
->hasByName(sSimpleName
))
2625 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*pEntry
).toUInt64());
2626 if ( !pData
->xObjectProperties
.is() )
2628 Reference
<XInterface
> xObject
;
2629 if(xNameAccess
->getByName(sSimpleName
) >>= xObject
) // remember the table or query object
2631 pData
->xObjectProperties
.set(xObject
, css::uno::UNO_QUERY
);
2632 // if the query contains a parameterized statement and preview is enabled we won't get any data.
2633 if ( nCommandType
== CommandType::QUERY
&& xObject
.is() )
2635 Reference
<XPropertySet
> xObjectProps(xObject
,UNO_QUERY
);
2636 xObjectProps
->getPropertyValue(PROPERTY_ESCAPE_PROCESSING
) >>= bEscapeProcessing
;
2640 xObjectProps
->getPropertyValue(PROPERTY_COMMAND
) >>= sSql
;
2641 Reference
< XMultiServiceFactory
> xFactory( pConData
->xConnection
, UNO_QUERY
);
2646 Reference
<XSingleSelectQueryAnalyzer
> xAnalyzer(xFactory
->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER
),UNO_QUERY
);
2647 if ( xAnalyzer
.is() )
2649 xAnalyzer
->setQuery(sSql
);
2650 Reference
<XParametersSupplier
> xParSup(xAnalyzer
,UNO_QUERY
);
2651 if ( xParSup
->getParameters()->getCount() > 0 )
2653 OUString sFilter
= " WHERE " + xAnalyzer
->getFilter();
2654 OUString sReplace
= sSql
.replaceFirst(sFilter
, "");
2655 xAnalyzer
->setQuery(sReplace
);
2656 Reference
<XSingleSelectQueryComposer
> xComposer(xAnalyzer
,UNO_QUERY
);
2657 xComposer
->setFilter("0=1");
2658 aName
= xAnalyzer
->getQuery();
2659 nCommandType
= CommandType::COMMAND
;
2665 DBG_UNHANDLED_EXCEPTION("dbaccess");
2674 OUString
sDataSourceName(getDataSourceAccessor(*xConnection
));
2675 bSuccess
= implLoadAnything( sDataSourceName
, aName
, nCommandType
, bEscapeProcessing
, pConData
->xConnection
);
2681 catch(const SQLException
& e
)
2683 showError(SQLExceptionInfo(e
));
2685 xRowSetProps
->setPropertyValue(PROPERTY_DATASOURCENAME
,Any());
2686 xRowSetProps
->setPropertyValue(PROPERTY_ACTIVE_CONNECTION
,Any());
2689 catch(WrappedTargetException
& e
)
2692 if(e
.TargetException
>>= aSql
)
2693 showError(SQLExceptionInfo(aSql
));
2695 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::implSelect: something strange happened!");
2697 xRowSetProps
->setPropertyValue(PROPERTY_DATASOURCENAME
,Any());
2698 xRowSetProps
->setPropertyValue(PROPERTY_ACTIVE_CONNECTION
,Any());
2701 catch(const Exception
&)
2704 xRowSetProps
->setPropertyValue(PROPERTY_DATASOURCENAME
,Any());
2705 xRowSetProps
->setPropertyValue(PROPERTY_ACTIVE_CONNECTION
,Any());
2712 std::unique_ptr
<weld::TreeIter
> SbaTableQueryBrowser::getEntryFromContainer(const Reference
<XNameAccess
>& rxNameAccess
)
2714 std::unique_ptr
<weld::TreeIter
> xContainer
;
2716 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2717 std::unique_ptr
<weld::TreeIter
> xDSLoop(rTreeView
.make_iterator(xContainer
.get()));
2718 if (rTreeView
.get_iter_first(*xDSLoop
))
2722 xContainer
= rTreeView
.make_iterator(xDSLoop
.get());
2723 if (rTreeView
.iter_children(*xContainer
))
2725 // 1st child is queries
2726 DBTreeListUserData
* pQueriesData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xContainer
).toUInt64());
2727 if (pQueriesData
&& pQueriesData
->xContainer
== rxNameAccess
)
2730 if (rTreeView
.iter_next_sibling(*xContainer
))
2732 // 2nd child is tables
2733 DBTreeListUserData
* pTablesData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xContainer
).toUInt64());
2734 if (pTablesData
&& pTablesData
->xContainer
== rxNameAccess
)
2740 while (rTreeView
.iter_next_sibling(*xDSLoop
));
2746 void SAL_CALL
SbaTableQueryBrowser::elementInserted(const ContainerEvent
& rEvent
)
2748 SolarMutexGuard aSolarGuard
;
2750 Reference
< XNameAccess
> xNames(rEvent
.Source
, UNO_QUERY
);
2751 // first search for a definition container where we can insert this element
2753 std::unique_ptr
<weld::TreeIter
> xEntry
= getEntryFromContainer(xNames
);
2754 if (xEntry
) // found one
2756 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2757 rTreeView
.make_unsorted();
2759 // insert the new entry into the tree
2760 DBTreeListUserData
* pContainerData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xEntry
).toUInt64());
2761 OSL_ENSURE(pContainerData
, "elementInserted: There must be user data for this type!");
2763 DBTreeListUserData
* pNewData
= new DBTreeListUserData
;
2764 bool bIsTable
= etTableContainer
== pContainerData
->eType
;
2767 rEvent
.Element
>>= pNewData
->xObjectProperties
;// remember the new element
2768 pNewData
->eType
= etTableOrView
;
2772 if (rTreeView
.iter_n_children(*xEntry
) < xNames
->getElementNames().getLength() - 1)
2774 // the item inserts its children on demand, but it has not been expanded yet. So ensure here and
2775 // now that it has all items
2776 populateTree(xNames
, *xEntry
, etQuery
);
2778 pNewData
->eType
= etQuery
;
2780 implAppendEntry(xEntry
.get(), ::comphelper::getString(rEvent
.Accessor
), pNewData
);
2782 rTreeView
.make_sorted();
2785 SbaXDataBrowserController::elementInserted(rEvent
);
2788 bool SbaTableQueryBrowser::isCurrentlyDisplayedChanged(const OUString
& rName
, const weld::TreeIter
& rContainer
)
2790 if (!m_xCurrentlyDisplayed
)
2792 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2793 if (getEntryType(*m_xCurrentlyDisplayed
) != getChildType(rContainer
))
2795 if (rTreeView
.get_text(*m_xCurrentlyDisplayed
) != rName
)
2797 std::unique_ptr
<weld::TreeIter
> xParent
= rTreeView
.make_iterator(m_xCurrentlyDisplayed
.get());
2798 return rTreeView
.iter_parent(*xParent
) && rTreeView
.iter_compare(*xParent
, rContainer
) == 0;
2801 void SAL_CALL
SbaTableQueryBrowser::elementRemoved( const ContainerEvent
& _rEvent
)
2803 SolarMutexGuard aSolarGuard
;
2805 Reference
< XNameAccess
> xNames(_rEvent
.Source
, UNO_QUERY
);
2806 // get the top-level representing the removed data source
2807 // and search for the queries and tables
2808 std::unique_ptr
<weld::TreeIter
> xContainer
= getEntryFromContainer(xNames
);
2811 // a query or table has been removed
2812 OUString aName
= ::comphelper::getString(_rEvent
.Accessor
);
2814 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2815 if (isCurrentlyDisplayedChanged(aName
, *xContainer
))
2817 // the element displayed currently has been replaced
2819 // we need to remember the old value
2820 std::unique_ptr
<weld::TreeIter
> xTemp
= rTreeView
.make_iterator(m_xCurrentlyDisplayed
.get());
2823 unloadAndCleanup( false ); // don't dispose the connection
2825 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xTemp
).toUInt64());
2826 rTreeView
.set_id(*xTemp
, OUString());
2827 delete pData
; // the data could be null because we have a table which isn't correct
2828 rTreeView
.remove(*xTemp
);
2832 // remove the entry from the model
2833 std::unique_ptr
<weld::TreeIter
> xChild(rTreeView
.make_iterator(xContainer
.get()));
2834 if (rTreeView
.get_iter_first(*xChild
))
2838 if (rTreeView
.get_text(*xChild
) == aName
)
2840 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xChild
).toUInt64());
2841 rTreeView
.set_id(*xChild
, OUString());
2843 rTreeView
.remove(*xChild
);
2846 } while (rTreeView
.iter_next_sibling(*xChild
));
2850 // maybe the object which is part of the document data source has been removed
2851 checkDocumentDataSource();
2854 SbaXDataBrowserController::elementRemoved(_rEvent
);
2857 void SAL_CALL
SbaTableQueryBrowser::elementReplaced( const ContainerEvent
& _rEvent
)
2859 SolarMutexGuard aSolarGuard
;
2861 Reference
< XNameAccess
> xNames(_rEvent
.Source
, UNO_QUERY
);
2862 std::unique_ptr
<weld::TreeIter
> xContainer
= getEntryFromContainer(xNames
);
2865 // a table or query as been replaced
2866 OUString aName
= ::comphelper::getString(_rEvent
.Accessor
);
2868 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2869 if (isCurrentlyDisplayedChanged(aName
, *xContainer
))
2870 { // the element displayed currently has been replaced
2872 // we need to remember the old value
2873 std::unique_ptr
<weld::TreeIter
> xTemp
= rTreeView
.make_iterator(m_xCurrentlyDisplayed
.get());
2874 unloadAndCleanup( false ); // don't dispose the connection
2876 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xTemp
).toUInt64());
2879 if ( etTableOrView
== pData
->eType
)
2881 // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2882 _rEvent
.Element
>>= pData
->xObjectProperties
; // remember the new element
2886 rTreeView
.set_id(*xTemp
, OUString());
2893 // find the entry for this name
2894 std::unique_ptr
<weld::TreeIter
> xChild(rTreeView
.make_iterator(xContainer
.get()));
2895 if (rTreeView
.get_iter_first(*xChild
))
2899 if (rTreeView
.get_text(*xChild
) == aName
)
2901 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xChild
).toUInt64());
2904 if ( etTableOrView
== pData
->eType
)
2906 // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2907 _rEvent
.Element
>>= pData
->xObjectProperties
; // remember the new element
2911 rTreeView
.set_id(*xChild
, OUString());
2917 } while (rTreeView
.iter_next_sibling(*xChild
));
2921 // maybe the object which is part of the document data source has been removed
2922 checkDocumentDataSource();
2924 else if (xNames
.get() == m_xDatabaseContext
.get())
2925 { // a datasource has been replaced in the context
2926 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::elementReplaced: no support for replaced data sources!");
2927 // very suspicious: the database context should not allow to replace data source, only to register
2931 SbaXDataBrowserController::elementReplaced(_rEvent
);
2934 void SbaTableQueryBrowser::impl_releaseConnection( SharedConnection
& _rxConnection
)
2936 // remove as event listener
2937 Reference
< XComponent
> xComponent( _rxConnection
, UNO_QUERY
);
2938 if ( xComponent
.is() )
2940 Reference
< XEventListener
> xListener( static_cast< ::cppu::OWeakObject
* >( this ), UNO_QUERY
);
2941 xComponent
->removeEventListener( xListener
);
2946 // temporary (hopefully!) hack for #i55274#
2947 Reference
< XFlushable
> xFlush( _rxConnection
, UNO_QUERY
);
2951 catch( const Exception
& )
2953 DBG_UNHANDLED_EXCEPTION("dbaccess");
2957 _rxConnection
.clear();
2958 // will implicitly dispose if we have the ownership, since xConnection is a SharedConnection
2961 void SbaTableQueryBrowser::disposeConnection(const weld::TreeIter
* pDSEntry
)
2963 OSL_ENSURE( pDSEntry
, "SbaTableQueryBrowser::disposeConnection: invalid entry (NULL)!" );
2964 OSL_ENSURE( impl_isDataSourceEntry( pDSEntry
), "SbaTableQueryBrowser::disposeConnection: invalid entry (not top-level)!" );
2968 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2969 DBTreeListUserData
* pTreeListData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*pDSEntry
).toUInt64());
2971 impl_releaseConnection(pTreeListData
->xConnection
);
2975 void SbaTableQueryBrowser::closeConnection(weld::TreeIter
& rDSEntry
, bool _bDisposeConnection
)
2977 OSL_ENSURE(impl_isDataSourceEntry(&rDSEntry
), "SbaTableQueryBrowser::closeConnection: invalid entry (not top-level)!");
2979 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
2981 // if one of the entries of the given DS is displayed currently, unload the form
2982 if (m_xCurrentlyDisplayed
)
2984 std::unique_ptr
<weld::TreeIter
> xRoot
= m_pTreeView
->GetRootLevelParent(m_xCurrentlyDisplayed
.get());
2985 if (rTreeView
.iter_compare(*xRoot
, rDSEntry
) == 0)
2986 unloadAndCleanup(_bDisposeConnection
);
2989 // collapse the query/table container
2990 std::unique_ptr
<weld::TreeIter
> xContainers(rTreeView
.make_iterator(&rDSEntry
));
2991 if (rTreeView
.iter_children(*xContainers
))
2995 std::unique_ptr
<weld::TreeIter
> xElements(rTreeView
.make_iterator(xContainers
.get()));
2996 if (rTreeView
.iter_children(*xElements
))
2998 rTreeView
.collapse_row(*xContainers
);
2999 // and delete their children (they are connection-relative)
3000 bool bElements
= true;
3003 std::unique_ptr
<weld::TreeIter
> xRemove(rTreeView
.make_iterator(xElements
.get()));
3004 bElements
= rTreeView
.iter_next_sibling(*xElements
);
3005 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xRemove
).toUInt64());
3006 rTreeView
.set_id(*xRemove
, OUString());
3008 rTreeView
.remove(*xRemove
);
3012 while (rTreeView
.iter_next_sibling(*xContainers
));
3015 // collapse the entry itself
3016 rTreeView
.collapse_row(rDSEntry
);
3018 // dispose/reset the connection
3019 if ( _bDisposeConnection
)
3020 disposeConnection(&rDSEntry
);
3023 void SbaTableQueryBrowser::unloadAndCleanup( bool _bDisposeConnection
)
3025 if (!m_xCurrentlyDisplayed
)
3029 std::unique_ptr
<weld::TreeIter
> xDSEntry
= m_pTreeView
->GetRootLevelParent(m_xCurrentlyDisplayed
.get());
3031 // de-select the path for the currently displayed table/query
3032 selectPath(m_xCurrentlyDisplayed
.get(), false);
3033 m_xCurrentlyDisplayed
.reset();
3037 // get the active connection. We need to dispose it.
3040 Reference
< XLoadable
> xLoadable
= getLoadable();
3041 if (xLoadable
->isLoaded())
3042 xLoadable
->unload();
3044 // clear the grid control
3045 Reference
< XNameContainer
> xConta(getControlModel(),UNO_QUERY
);
3046 clearGridColumns(xConta
);
3048 // dispose the connection
3049 if(_bDisposeConnection
)
3050 disposeConnection(xDSEntry
.get());
3052 catch(SQLException
& e
)
3054 showError(SQLExceptionInfo(e
));
3056 catch(WrappedTargetException
& e
)
3059 if(e
.TargetException
>>= aSql
)
3060 showError(SQLExceptionInfo(aSql
));
3062 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::unloadAndCleanup: something strange happened!");
3064 catch(const Exception
&)
3066 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::unloadAndCleanup: could not reset the form");
3072 Reference
< XInterface
> lcl_getDataSource( const Reference
< XDatabaseContext
>& _rxDatabaseContext
,
3073 const OUString
& _rDataSourceName
, const Reference
< XConnection
>& _rxConnection
)
3075 Reference
< XDataSource
> xDataSource
;
3078 if ( !_rDataSourceName
.isEmpty() && _rxDatabaseContext
->hasByName( _rDataSourceName
) )
3079 xDataSource
.set( _rxDatabaseContext
->getByName( _rDataSourceName
), UNO_QUERY_THROW
);
3081 if ( !xDataSource
.is() )
3083 Reference
< XChild
> xConnAsChild( _rxConnection
, UNO_QUERY
);
3084 if ( xConnAsChild
.is() )
3085 xDataSource
.set( xConnAsChild
->getParent(), UNO_QUERY_THROW
);
3088 catch( const Exception
& )
3090 DBG_UNHANDLED_EXCEPTION("dbaccess");
3092 return xDataSource
.get();
3096 void SbaTableQueryBrowser::impl_initialize()
3098 SolarMutexGuard aGuard
;
3099 // doin' a lot of VCL stuff here -> lock the SolarMutex
3101 // first initialize the parent
3102 SbaXDataBrowserController::impl_initialize();
3104 Reference
<XConnection
> xForeignConnection
;
3105 Reference
< XFrame
> xFrame
;
3107 OUString aTableName
, aCatalogName
, aSchemaName
;
3109 bool bEscapeProcessing
= true;
3110 sal_Int32 nInitialDisplayCommandType
= CommandType::COMMAND
;
3111 OUString sInitialDataSourceName
;
3112 OUString sInitialCommand
;
3114 const NamedValueCollection
& rArguments( getInitParams() );
3116 rArguments
.get_ensureType( PROPERTY_DATASOURCENAME
, sInitialDataSourceName
);
3117 rArguments
.get_ensureType( PROPERTY_COMMAND_TYPE
, nInitialDisplayCommandType
);
3118 rArguments
.get_ensureType( PROPERTY_COMMAND
, sInitialCommand
);
3119 rArguments
.get_ensureType( PROPERTY_ACTIVE_CONNECTION
, xForeignConnection
);
3120 rArguments
.get_ensureType( PROPERTY_UPDATE_CATALOGNAME
, aCatalogName
);
3121 rArguments
.get_ensureType( PROPERTY_UPDATE_SCHEMANAME
, aSchemaName
);
3122 rArguments
.get_ensureType( PROPERTY_UPDATE_TABLENAME
, aTableName
);
3123 rArguments
.get_ensureType( PROPERTY_ESCAPE_PROCESSING
, bEscapeProcessing
);
3124 rArguments
.get_ensureType( "Frame", xFrame
);
3125 rArguments
.get_ensureType( PROPERTY_SHOWMENU
, m_bShowMenu
);
3127 // disable the browser if either of ShowTreeViewButton (compatibility name) or EnableBrowser
3128 // is present and set to FALSE
3129 bool bDisableBrowser
= !rArguments
.getOrDefault( "ShowTreeViewButton", true ) // compatibility name
3130 || !rArguments
.getOrDefault( PROPERTY_ENABLE_BROWSER
, true );
3131 OSL_ENSURE( !rArguments
.has( "ShowTreeViewButton" ),
3132 "SbaTableQueryBrowser::impl_initialize: ShowTreeViewButton is superseded by EnableBrowser!" );
3133 m_bEnableBrowser
= !bDisableBrowser
;
3135 // hide the tree view it is disabled in general, or if the settings tell to hide it initially
3136 bool bHideTreeView
= ( !m_bEnableBrowser
)
3137 || !rArguments
.getOrDefault( "ShowTreeView", true ) // compatibility name
3138 || !rArguments
.getOrDefault( PROPERTY_SHOW_BROWSER
, true );
3139 OSL_ENSURE( !rArguments
.has( "ShowTreeView" ),
3140 "SbaTableQueryBrowser::impl_initialize: ShowTreeView is superseded by ShowBrowser!" );
3142 if ( bHideTreeView
)
3151 Sequence
< OUString
> aProperties(5);
3152 Sequence
< Any
> aValues(5);
3154 OUString
* pStringIter
= aProperties
.getArray();
3155 Any
* pValueIter
= aValues
.getArray();
3156 *pStringIter
++ = "AlwaysShowCursor";
3157 *pValueIter
++ <<= false;
3158 *pStringIter
++ = PROPERTY_BORDER
;
3159 *pValueIter
++ <<= sal_Int16(0);
3161 *pStringIter
++ = "HasNavigationBar";
3162 *pValueIter
++ <<= false;
3163 *pStringIter
++ = "HasRecordMarker";
3164 *pValueIter
++ <<= false;
3166 *pStringIter
++ = "Tabstop";
3167 *pValueIter
++ <<= false;
3169 Reference
< XMultiPropertySet
> xFormMultiSet(getFormComponent(), UNO_QUERY
);
3170 if ( xFormMultiSet
.is() )
3171 xFormMultiSet
->setPropertyValues(aProperties
, aValues
);
3173 catch(const Exception
&)
3175 DBG_UNHANDLED_EXCEPTION("dbaccess");
3179 // are we loaded into a (sub)frame of an embedded document (i.e. a form belonging to a database
3181 bool bSubFrameOfEmbeddedDocument
= false;
3184 Reference
<XFramesSupplier
> xSup
= xFrame
->getCreator();
3185 Reference
<XController
> xCont
= xSup
.is() ? xSup
->getController() : Reference
<XController
>();
3187 bSubFrameOfEmbeddedDocument
= xCont
.is() && ::dbtools::isEmbeddedInDatabase( xCont
->getModel(), xForeignConnection
);
3190 // if we have a connection at this point, it was either passed from outside, our
3191 // determined from an outer DB document. In both cases, do not dispose it later on.
3192 SharedConnection
xConnection( xForeignConnection
, SharedConnection::NoTakeOwnership
);
3194 // should we display all registered databases in the left hand side tree?
3195 // or only *one* special?
3196 bool bLimitedTreeEntries
= false;
3197 // if we're part of a frame which is a secondary frame of a database document, then only
3198 // display the database for this document, not all registered ones
3199 bLimitedTreeEntries
|= bSubFrameOfEmbeddedDocument
;
3200 // if the tree view is not to be displayed at all, then only display the data source
3201 // which was given as initial selection
3202 bLimitedTreeEntries
|= !m_bEnableBrowser
;
3204 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3205 rTreeView
.make_unsorted();
3207 if ( bLimitedTreeEntries
)
3209 if ( xConnection
.is() )
3211 startConnectionListening( xConnection
);
3213 // if no initial name was given, try to obtain one from the data source
3214 if ( sInitialDataSourceName
.isEmpty() )
3216 Reference
< XChild
> xChild( xConnection
, UNO_QUERY
);
3217 Reference
< XPropertySet
> xDataSourceProperties
;
3219 xDataSourceProperties
.set(xChild
->getParent(), css::uno::UNO_QUERY
);
3220 if ( xDataSourceProperties
.is() )
3224 OSL_VERIFY( xDataSourceProperties
->getPropertyValue( PROPERTY_NAME
) >>= sInitialDataSourceName
);
3226 catch( const Exception
& )
3228 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::impl_initialize: a connection parent which does not have a 'Name'!??" );
3234 implAddDatasource( sInitialDataSourceName
, xConnection
);
3236 std::unique_ptr
<weld::TreeIter
> xFirst(rTreeView
.make_iterator());
3237 if (rTreeView
.get_iter_first(*xFirst
))
3238 rTreeView
.expand_row(*xFirst
);
3241 initializeTreeModel();
3243 rTreeView
.make_sorted();
3245 if ( m_bEnableBrowser
)
3247 m_aDocScriptSupport
= ::std::optional
< bool >( false );
3251 // we are not used as "browser", but as mere view for a single table/query/command. In particular,
3252 // there is a specific database document which we belong to.
3253 Reference
< XOfficeDatabaseDocument
> xDocument( getDataSourceOrModel(
3254 lcl_getDataSource( m_xDatabaseContext
, sInitialDataSourceName
, xConnection
) ), UNO_QUERY
);
3255 m_aDocScriptSupport
= ::std::optional
< bool >( Reference
< XEmbeddedScripts
>( xDocument
, UNO_QUERY
).is() );
3258 if ( implSelect( sInitialDataSourceName
, sInitialCommand
, nInitialDisplayCommandType
, bEscapeProcessing
, xConnection
, true ) )
3262 Reference
< XPropertySet
> xRowSetProps(getRowSet(), UNO_QUERY
);
3263 xRowSetProps
->setPropertyValue(PROPERTY_UPDATE_CATALOGNAME
,makeAny(aCatalogName
));
3264 xRowSetProps
->setPropertyValue(PROPERTY_UPDATE_SCHEMANAME
,makeAny(aSchemaName
));
3265 xRowSetProps
->setPropertyValue(PROPERTY_UPDATE_TABLENAME
,makeAny(aTableName
));
3268 catch(const Exception
&)
3270 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::impl_initialize: could not set the update related names!");
3277 bool SbaTableQueryBrowser::haveExplorer() const
3279 return m_pTreeView
&& m_pTreeView
->IsVisible();
3282 void SbaTableQueryBrowser::hideExplorer()
3284 if (!haveExplorer())
3286 if (!getBrowserView())
3289 m_pTreeView
->Hide();
3290 m_pSplitter
->Hide();
3291 getBrowserView()->Resize();
3293 InvalidateFeature(ID_BROWSER_EXPLORER
);
3296 void SbaTableQueryBrowser::showExplorer()
3301 if (!getBrowserView())
3304 m_pTreeView
->Show();
3305 m_pSplitter
->Show();
3306 getBrowserView()->Resize();
3308 InvalidateFeature(ID_BROWSER_EXPLORER
);
3311 bool SbaTableQueryBrowser::ensureConnection(const weld::TreeIter
* pAnyEntry
, SharedConnection
& rConnection
)
3313 std::unique_ptr
<weld::TreeIter
> xDSEntry
= m_pTreeView
->GetRootLevelParent(pAnyEntry
);
3314 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3315 DBTreeListUserData
* pDSData
=
3317 ? reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xDSEntry
).toUInt64())
3320 return ensureConnection(xDSEntry
.get(), pDSData
, rConnection
);
3323 std::unique_ptr
< ImageProvider
> SbaTableQueryBrowser::getImageProviderFor(const weld::TreeIter
* pAnyEntry
)
3325 std::unique_ptr
<ImageProvider
> xImageProvider(new ImageProvider
);
3326 SharedConnection xConnection
;
3327 if (getExistentConnectionFor(pAnyEntry
, xConnection
))
3328 xImageProvider
.reset(new ImageProvider(xConnection
));
3329 return xImageProvider
;
3332 bool SbaTableQueryBrowser::getExistentConnectionFor(const weld::TreeIter
* pAnyEntry
, SharedConnection
& rConnection
)
3334 std::unique_ptr
<weld::TreeIter
> xDSEntry
= m_pTreeView
->GetRootLevelParent(pAnyEntry
);
3335 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3336 DBTreeListUserData
* pDSData
=
3338 ? reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xDSEntry
).toUInt64())
3341 rConnection
= pDSData
->xConnection
;
3342 return rConnection
.is();
3345 bool SbaTableQueryBrowser::impl_isDataSourceEntry(const weld::TreeIter
* pEntry
) const
3349 std::unique_ptr
<weld::TreeIter
> xRoot(m_pTreeView
->GetRootLevelParent(pEntry
));
3350 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3351 return rTreeView
.iter_compare(*xRoot
, *pEntry
) == 0;
3354 bool SbaTableQueryBrowser::ensureConnection(const weld::TreeIter
* pDSEntry
, void* pDSData
, SharedConnection
& rConnection
)
3356 OSL_ENSURE( impl_isDataSourceEntry( pDSEntry
), "SbaTableQueryBrowser::ensureConnection: this entry does not denote a data source!" );
3359 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3360 OUString aDSName
= rTreeView
.get_text(*pDSEntry
);
3362 DBTreeListUserData
* pTreeListData
= static_cast<DBTreeListUserData
*>(pDSData
);
3363 if ( pTreeListData
)
3364 rConnection
= pTreeListData
->xConnection
;
3366 if ( !rConnection
.is() && pTreeListData
)
3368 // show the "connecting to ..." status
3369 OUString
sConnecting(DBA_RES(STR_CONNECTING_DATASOURCE
));
3370 sConnecting
= sConnecting
.replaceFirst("$name$", aDSName
);
3371 BrowserViewStatusDisplay
aShowStatus(static_cast<UnoDataBrowserView
*>(getView()), sConnecting
);
3373 // build a string showing context information in case of error
3374 OUString
sConnectingContext(DBA_RES(STR_COULDNOTCONNECT_DATASOURCE
));
3375 sConnectingContext
= sConnectingContext
.replaceFirst("$name$", aDSName
);
3379 connect(getDataSourceAccessor(*pDSEntry
), sConnectingContext
, nullptr),
3380 SharedConnection::TakeOwnership
);
3382 // remember the connection
3383 pTreeListData
->xConnection
= rConnection
;
3386 return rConnection
.is();
3389 int SbaTableQueryBrowser::OnTreeEntryCompare(const weld::TreeIter
& rLHS
, const weld::TreeIter
& rRHS
)
3391 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3393 // we want the table entry and the end so we have to do a check
3394 if (isContainer(rRHS
))
3396 // don't use getEntryType (directly or indirectly) for the LHS:
3397 // LHS is currently being inserted, so it is not "completely valid" at the moment
3399 const EntryType eRight
= getEntryType(rRHS
);
3400 if (etTableContainer
== eRight
)
3401 // every other container should be placed _before_ the bookmark container
3404 const OUString sLeft
= rTreeView
.get_text(rLHS
);
3406 EntryType eLeft
= etTableContainer
;
3407 if (DBA_RES(RID_STR_TABLES_CONTAINER
) == sLeft
)
3408 eLeft
= etTableContainer
;
3409 else if (DBA_RES(RID_STR_QUERIES_CONTAINER
) == sLeft
)
3410 eLeft
= etQueryContainer
;
3412 if ( eLeft
== eRight
)
3415 if ( ( eLeft
== etTableContainer
) && ( eRight
== etQueryContainer
) )
3418 if ( ( eLeft
== etQueryContainer
) && ( eRight
== etTableContainer
) )
3421 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnTreeEntryCompare: unexpected case!" );
3425 OUString sLeftText
= rTreeView
.get_text(rLHS
);
3426 OUString sRightText
= rTreeView
.get_text(rRHS
);
3428 sal_Int32 nCompareResult
= 0; // equal by default
3430 if (m_xCollator
.is())
3434 nCompareResult
= m_xCollator
->compareString(sLeftText
, sRightText
);
3436 catch(const Exception
&)
3441 // default behaviour if we do not have a collator -> do the simple string compare
3442 nCompareResult
= sLeftText
.compareTo(sRightText
);
3444 return nCompareResult
;
3447 void SbaTableQueryBrowser::implAdministrate(weld::TreeIter
& rApplyTo
)
3451 // get the desktop object
3452 Reference
< XDesktop2
> xFrameLoader
= Desktop::create( getORB() );
3454 // the initial selection
3455 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3456 std::unique_ptr
<weld::TreeIter
> xTopLevelSelected(rTreeView
.make_iterator(&rApplyTo
));
3458 while (rTreeView
.get_iter_depth(*xTopLevelSelected
))
3459 rTreeView
.iter_parent(*xTopLevelSelected
);
3461 OUString sInitialSelection
= getDataSourceAccessor(*xTopLevelSelected
);
3463 Reference
< XDataSource
> xDataSource( getDataSourceByName( sInitialSelection
, getFrameWeld(), getORB(), nullptr ) );
3464 Reference
< XModel
> xDocumentModel( getDataSourceOrModel( xDataSource
), UNO_QUERY
);
3466 if ( xDocumentModel
.is() )
3468 Reference
< XInteractionHandler2
> xInteractionHandler(
3469 InteractionHandler::createWithParent(getORB(), nullptr) );
3471 ::comphelper::NamedValueCollection aLoadArgs
;
3472 aLoadArgs
.put( "Model", xDocumentModel
);
3473 aLoadArgs
.put( "InteractionHandler", xInteractionHandler
);
3474 aLoadArgs
.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG
);
3476 Sequence
< PropertyValue
> aLoadArgPV
;
3477 aLoadArgs
>>= aLoadArgPV
;
3479 xFrameLoader
->loadComponentFromURL(
3480 xDocumentModel
->getURL(),
3482 FrameSearchFlag::ALL
| FrameSearchFlag::GLOBAL
,
3487 catch( const Exception
& )
3489 DBG_UNHANDLED_EXCEPTION("dbaccess");
3493 bool SbaTableQueryBrowser::requestQuickHelp(const void* pUserData
, OUString
& rText
) const
3495 const DBTreeListUserData
* pData
= static_cast<const DBTreeListUserData
*>(pUserData
);
3496 if (pData
->eType
== etDatasource
&& !pData
->sAccessor
.isEmpty())
3498 rText
= ::svt::OFileNotation(pData
->sAccessor
).get( ::svt::OFileNotation::N_SYSTEM
);
3504 OUString
SbaTableQueryBrowser::getContextMenuResourceName() const
3509 IController
& SbaTableQueryBrowser::getCommandController()
3514 ::comphelper::OInterfaceContainerHelper2
* SbaTableQueryBrowser::getContextMenuInterceptors()
3516 return &m_aContextMenuInterceptors
;
3519 Any
SbaTableQueryBrowser::getCurrentSelection(weld::TreeView
& rControl
) const
3521 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3523 OSL_PRECOND( &rTreeView
== &rControl
,
3524 "SbaTableQueryBrowser::getCurrentSelection: where does this come from?" );
3526 if (&rTreeView
!= &rControl
)
3529 std::unique_ptr
<weld::TreeIter
> xSelected(rTreeView
.make_iterator());
3530 if (!rTreeView
.get_selected(xSelected
.get()))
3533 NamedDatabaseObject aSelectedObject
;
3534 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xSelected
).toUInt64());
3535 aSelectedObject
.Type
= static_cast< sal_Int32
>( pData
->eType
);
3537 switch ( aSelectedObject
.Type
)
3539 case DatabaseObject::QUERY
:
3540 case DatabaseObject::TABLE
:
3541 aSelectedObject
.Name
= rTreeView
.get_text(*xSelected
);
3544 case DatabaseObjectContainer::DATA_SOURCE
:
3545 case DatabaseObjectContainer::QUERIES
:
3546 case DatabaseObjectContainer::TABLES
:
3547 aSelectedObject
.Name
= getDataSourceAccessor(*xSelected
);
3551 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::getCurrentSelection: invalid (unexpected) object type!" );
3555 return makeAny( aSelectedObject
);
3558 vcl::Window
* SbaTableQueryBrowser::getMenuParent() const
3563 void SbaTableQueryBrowser::adjustMenuPosition(const weld::TreeView
&, ::Point
&) const
3567 bool SbaTableQueryBrowser::implGetQuerySignature( OUString
& _rCommand
, bool& _bEscapeProcessing
)
3570 _bEscapeProcessing
= false;
3574 // contain the dss (data source signature) of the form
3575 OUString sDataSourceName
;
3577 sal_Int32 nCommandType
= CommandType::COMMAND
;
3578 Reference
< XPropertySet
> xRowsetProps( getRowSet(), UNO_QUERY
);
3579 ODataAccessDescriptor
aDesc( xRowsetProps
);
3580 sDataSourceName
= aDesc
.getDataSource();
3581 aDesc
[ DataAccessDescriptorProperty::Command
] >>= sCommand
;
3582 aDesc
[ DataAccessDescriptorProperty::CommandType
] >>= nCommandType
;
3584 // do we need to do anything?
3585 if ( CommandType::QUERY
!= nCommandType
)
3588 // get the query object
3589 Reference
< XQueryDefinitionsSupplier
> xSuppQueries
;
3590 Reference
< XNameAccess
> xQueries
;
3591 Reference
< XPropertySet
> xQuery
;
3592 m_xDatabaseContext
->getByName( sDataSourceName
) >>= xSuppQueries
;
3593 if ( xSuppQueries
.is() )
3594 xQueries
= xSuppQueries
->getQueryDefinitions();
3595 if ( xQueries
.is() )
3596 xQueries
->getByName( sCommand
) >>= xQuery
;
3597 OSL_ENSURE( xQuery
.is(), "SbaTableQueryBrowser::implGetQuerySignature: could not retrieve the query object!" );
3599 // get the two properties we need
3602 xQuery
->getPropertyValue( PROPERTY_COMMAND
) >>= _rCommand
;
3603 _bEscapeProcessing
= ::cppu::any2bool( xQuery
->getPropertyValue( PROPERTY_ESCAPE_PROCESSING
) );
3607 catch( const Exception
& )
3609 DBG_UNHANDLED_EXCEPTION("dbaccess");
3615 void SbaTableQueryBrowser::frameAction(const css::frame::FrameActionEvent
& aEvent
)
3617 if (aEvent
.Frame
== m_xCurrentFrameParent
)
3619 if(aEvent
.Action
== FrameAction_COMPONENT_DETACHING
)
3620 implRemoveStatusListeners();
3621 else if (aEvent
.Action
== FrameAction_COMPONENT_REATTACHED
)
3622 connectExternalDispatches();
3625 SbaXDataBrowserController::frameAction(aEvent
);
3629 void SbaTableQueryBrowser::clearGridColumns(const Reference
< XNameContainer
>& _xColContainer
)
3631 // first we have to clear the grid
3632 Reference
< XInterface
> xColumn
;
3633 const Sequence
<OUString
> aColNames
= _xColContainer
->getElementNames();
3634 for (const OUString
& rName
: aColNames
)
3636 _xColContainer
->getByName(rName
) >>= xColumn
;
3637 _xColContainer
->removeByName(rName
);
3638 ::comphelper::disposeComponent(xColumn
);
3642 void SbaTableQueryBrowser::loadMenu(const Reference
< XFrame
>& _xFrame
)
3646 OGenericUnoController::loadMenu(_xFrame
);
3648 else if ( !m_bPreview
)
3650 Reference
< css::frame::XLayoutManager
> xLayoutManager
= getLayoutManager(_xFrame
);
3652 if ( xLayoutManager
.is() )
3654 xLayoutManager
->lock();
3655 xLayoutManager
->createElement( "private:resource/toolbar/toolbar" );
3656 xLayoutManager
->unlock();
3657 xLayoutManager
->doLayout();
3659 onLoadedMenu( xLayoutManager
);
3663 OUString
SbaTableQueryBrowser::getPrivateTitle() const
3666 if (m_xCurrentlyDisplayed
)
3668 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3669 std::unique_ptr
<weld::TreeIter
> xContainer
= rTreeView
.make_iterator(m_xCurrentlyDisplayed
.get());
3670 if (!rTreeView
.iter_parent(*xContainer
))
3672 // get the entry for the datasource
3673 std::unique_ptr
<weld::TreeIter
> xConnection
= implGetConnectionEntry(*xContainer
);
3674 OUString sName
= rTreeView
.get_text(*m_xCurrentlyDisplayed
);
3675 sTitle
= GetEntryText(*xConnection
);
3676 INetURLObject
aURL(sTitle
);
3677 if ( aURL
.GetProtocol() != INetProtocol::NotValid
)
3678 sTitle
= aURL
.getBase(INetURLObject::LAST_SEGMENT
,true,INetURLObject::DecodeMechanism::WithCharset
);
3679 if ( !sName
.isEmpty() )
3681 sName
+= " - " + sTitle
;
3689 bool SbaTableQueryBrowser::preReloadForm()
3692 if (!m_xCurrentlyDisplayed
)
3694 // switch the grid to design mode while loading
3695 getBrowserView()->getGridControl()->setDesignMode(true);
3696 // we had an invalid statement so we need to connect the column models
3697 Reference
<XPropertySet
> xRowSetProps(getRowSet(),UNO_QUERY
);
3698 svx::ODataAccessDescriptor
aDesc(xRowSetProps
);
3699 // extract the props
3700 OUString sDataSource
;
3702 sal_Int32 nCommandType
= CommandType::COMMAND
;
3703 bool bEscapeProcessing
= true;
3704 extractDescriptorProps(aDesc
, sDataSource
, sCommand
, nCommandType
, bEscapeProcessing
);
3705 if ( !sDataSource
.isEmpty() && !sCommand
.isEmpty() && (-1 != nCommandType
) )
3707 m_xCurrentlyDisplayed
= getObjectEntry(sDataSource
, sCommand
, nCommandType
, nullptr, nullptr);
3714 void SbaTableQueryBrowser::postReloadForm()
3716 InitializeGridModel(getFormComponent());
3720 Reference
< XEmbeddedScripts
> SAL_CALL
SbaTableQueryBrowser::getScriptContainer()
3722 // update our database document
3723 Reference
< XModel
> xDocument
;
3726 Reference
< XPropertySet
> xCursorProps( getRowSet(), UNO_QUERY_THROW
);
3727 Reference
< XConnection
> xConnection( xCursorProps
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
), UNO_QUERY
);
3728 if ( xConnection
.is() )
3730 Reference
< XChild
> xChild( xConnection
, UNO_QUERY_THROW
);
3731 Reference
< XDocumentDataSource
> xDataSource( xChild
->getParent(), UNO_QUERY_THROW
);
3732 xDocument
.set( xDataSource
->getDatabaseDocument(), UNO_QUERY_THROW
);
3735 catch( const Exception
& )
3737 DBG_UNHANDLED_EXCEPTION("dbaccess");
3739 Reference
< XEmbeddedScripts
> xScripts( xDocument
, UNO_QUERY
);
3740 OSL_ENSURE( xScripts
.is() || !xDocument
.is(),
3741 "SbaTableQueryBrowser::getScriptContainer: invalid database document!" );
3745 void SAL_CALL
SbaTableQueryBrowser::registerContextMenuInterceptor( const Reference
< XContextMenuInterceptor
>& Interceptor
)
3747 if ( Interceptor
.is() )
3748 m_aContextMenuInterceptors
.addInterface( Interceptor
);
3751 void SAL_CALL
SbaTableQueryBrowser::releaseContextMenuInterceptor( const Reference
< XContextMenuInterceptor
>& Interceptor
)
3753 if ( Interceptor
.is() )
3754 m_aContextMenuInterceptors
.removeInterface( Interceptor
);
3757 void SAL_CALL
SbaTableQueryBrowser::registeredDatabaseLocation( const DatabaseRegistrationEvent
& Event
)
3759 SolarMutexGuard aGuard
;
3760 implAddDatasource( Event
.Name
, SharedConnection() );
3763 void SbaTableQueryBrowser::impl_cleanupDataSourceEntry(const OUString
& rDataSourceName
)
3765 // get the top-level representing the removed data source
3766 weld::TreeView
& rTreeView
= m_pTreeView
->GetWidget();
3767 std::unique_ptr
<weld::TreeIter
> xDataSourceEntry(rTreeView
.make_iterator());
3768 bool bDataSourceEntry
= rTreeView
.get_iter_first(*xDataSourceEntry
);
3769 while (bDataSourceEntry
)
3771 if (rTreeView
.get_text(*xDataSourceEntry
) == rDataSourceName
)
3773 bDataSourceEntry
= rTreeView
.iter_next_sibling(*xDataSourceEntry
);
3776 OSL_ENSURE( bDataSourceEntry
, "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: do not know this data source!" );
3777 if (!bDataSourceEntry
)
3780 if (isSelected(*xDataSourceEntry
))
3782 // a table or query belonging to the deleted data source is currently being displayed.
3786 std::unique_ptr
<weld::TreeIter
> xChild(rTreeView
.make_iterator(xDataSourceEntry
.get()));
3787 if (rTreeView
.iter_children(*xChild
))
3791 // delete any user data of the child entries of the to-be-removed entry
3792 const DBTreeListUserData
* pData
= reinterpret_cast<const DBTreeListUserData
*>(rTreeView
.get_id(*xChild
).toUInt64());
3793 rTreeView
.set_id(*xChild
, OUString());
3795 } while (rTreeView
.iter_next_sibling(*xChild
));
3799 DBTreeListUserData
* pData
= reinterpret_cast<DBTreeListUserData
*>(rTreeView
.get_id(*xDataSourceEntry
).toUInt64());
3800 rTreeView
.set_id(*xDataSourceEntry
, OUString());
3802 rTreeView
.remove(*xDataSourceEntry
);
3805 void SAL_CALL
SbaTableQueryBrowser::revokedDatabaseLocation( const DatabaseRegistrationEvent
& Event
)
3807 SolarMutexGuard aGuard
;
3809 impl_cleanupDataSourceEntry( Event
.Name
);
3811 // maybe the object which is part of the document data source has been removed
3812 checkDocumentDataSource();
3815 void SAL_CALL
SbaTableQueryBrowser::changedDatabaseLocation( const DatabaseRegistrationEvent
& Event
)
3817 SolarMutexGuard aGuard
;
3819 // in case the data source was expanded, and connected, we need to clean it up
3820 // for simplicity, just do as if the data source were completely removed and re-added
3821 impl_cleanupDataSourceEntry( Event
.Name
);
3822 implAddDatasource( Event
.Name
, SharedConnection() );
3825 } // namespace dbaui
3827 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */