LibreOffice Module dbaccess (master) 1
unodatbr.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <browserids.hxx>
21#include <core_resource.hxx>
22#include <helpids.h>
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>
31
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>
74
77#include <comphelper/types.hxx>
81#include <svl/filenotation.hxx>
86#include <osl/diagnose.h>
87#include <sal/log.hxx>
88#include <tools/multisel.hxx>
89#include <tools/urlobj.hxx>
91#include <utility>
92#include <vcl/split.hxx>
93#include <vcl/svapp.hxx>
94#include <vcl/toolbox.hxx>
95#include <vcl/settings.hxx>
96#include <vcl/weld.hxx>
97
98#include <memory>
99
100using namespace ::com::sun::star::uno;
101using namespace ::com::sun::star::awt;
102using namespace ::com::sun::star::sdb;
103using namespace ::com::sun::star::sdb::application;
104using namespace ::com::sun::star::sdbc;
105using namespace ::com::sun::star::sdbcx;
106using namespace ::com::sun::star::beans;
107using namespace ::com::sun::star::util;
108using namespace ::com::sun::star::frame;
109using namespace ::com::sun::star::container;
110using namespace ::com::sun::star::lang;
111using namespace ::com::sun::star::ui::dialogs;
112using namespace ::com::sun::star::task;
113using namespace ::com::sun::star::form;
114using namespace ::com::sun::star::io;
115using namespace ::com::sun::star::i18n;
116using namespace ::com::sun::star::view;
117using namespace ::com::sun::star::datatransfer;
118using namespace ::com::sun::star::document;
119using namespace ::com::sun::star::ui;
120using namespace ::dbtools;
121using namespace ::comphelper;
122using namespace ::svx;
123
124// SbaTableQueryBrowser
125extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
127 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
128{
129 SolarMutexGuard aGuard;
130 return cppu::acquire(new ::dbaui::SbaTableQueryBrowser(context));
131}
132
133namespace dbaui
134{
135
136namespace DatabaseObject = css::sdb::application::DatabaseObject;
137namespace DatabaseObjectContainer = css::sdb::application::DatabaseObjectContainer;
138
139static void SafeAddPropertyListener(const Reference< XPropertySet > & xSet, const OUString& rPropName, XPropertyChangeListener* pListener)
140{
141 Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
142 if (xInfo->hasPropertyByName(rPropName))
143 xSet->addPropertyChangeListener(rPropName, pListener);
144}
145
146static void SafeRemovePropertyListener(const Reference< XPropertySet > & xSet, const OUString& rPropName, XPropertyChangeListener* pListener)
147{
148 Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
149 if (xInfo->hasPropertyByName(rPropName))
150 xSet->removePropertyChangeListener(rPropName, pListener);
151}
152
154{
155 return "org.openoffice.comp.dbu.ODatasourceBrowser";
156}
157
158css::uno::Sequence<OUString> SAL_CALL SbaTableQueryBrowser::getSupportedServiceNames()
159{
160 return { "com.sun.star.sdb.DataSourceBrowser" };
161}
162
165 ,m_aSelectionListeners( getMutex() )
166 ,m_aContextMenuInterceptors( getMutex() )
167 ,m_aTableCopyHelper(this)
168 ,m_pTreeView(nullptr)
169 ,m_pSplitter(nullptr)
170 ,m_nAsyncDrop(nullptr)
171 ,m_bQueryEscapeProcessing( false )
172 ,m_bShowMenu(false)
173 ,m_bInSuspend(false)
174 ,m_bEnableBrowser(true)
175{
176}
177
179{
180 if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
181 {
182 SAL_WARN("dbaccess.ui", "Please check who doesn't dispose this component!");
183 // increment ref count to prevent double call of Dtor
184 osl_atomic_increment( &m_refCount );
185 dispose();
186 }
188 m_pTreeView.reset();
190}
191
193{
194 if ( _rType.equals( cppu::UnoType<XScriptInvocationContext>::get() ) )
195 {
196 OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::queryInterface: did not initialize this, yet!" );
199 return Any();
200 }
201
203 if (!aReturn.hasValue())
205 return aReturn;
206}
207
209{
210 Sequence< Type > aTypes( ::comphelper::concatSequences(
213 ) );
214
215 OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::getTypes: did not initialize this, yet!" );
217 {
218 auto [begin, end] = asNonConstRange(aTypes);
219 auto newEnd = std::remove_if( begin, end,
220 [](const Type& type)
222 aTypes.realloc( std::distance(begin, newEnd) );
223 }
224 return aTypes;
225}
226
228{
229 return css::uno::Sequence<sal_Int8>();
230}
231
233{
234 SolarMutexGuard aGuard;
235 // doin' a lot of VCL stuff here -> lock the SolarMutex
236
237 // kiss our listeners goodbye
238 css::lang::EventObject aEvt(*this);
241
242 if (getBrowserView())
243 {
244 // Need to do some cleanup of the data pointed to the tree view entries before we remove the treeview
246 m_pTreeView = nullptr;
247 getBrowserView()->setTreeView(nullptr);
248 }
249
250 // remove ourself as status listener
252
253 // check out from all the objects we are listening
254 // the frame
255 if (m_xCurrentFrameParent.is())
256 m_xCurrentFrameParent->removeFrameActionListener(static_cast<css::frame::XFrameActionListener*>(this));
257
258 // remove the container listener from the database context
259 try
260 {
261 Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
262 xDatabaseRegistrations->removeDatabaseRegistrationsListener( this );
263 }
264 catch( const Exception& )
265 {
266 DBG_UNHANDLED_EXCEPTION("dbaccess");
267 }
268
270}
271
273{
274 if ( !SbaXDataBrowserController::Construct( pParent ) )
275 return false;
276
277 try
278 {
279 Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW );
280 xDatabaseRegistrations->addDatabaseRegistrationsListener( this );
281
282 // the collator for the string compares
283 m_xCollator = Collator::create( getORB() );
284 m_xCollator->loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0 );
285 }
286 catch(const Exception&)
287 {
288 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::Construct: could not create (or start listening at) the database context!");
289 }
290
291 // some help ids
292 if (!getBrowserView() || !getBrowserView()->getVclControl())
293 return true;
294
295 // create controls and set sizes
296 const tools::Long nFrameWidth = getBrowserView()->LogicToPixel(::Size(3, 0), MapMode(MapUnit::MapAppFont)).Width();
297
299 m_pSplitter->SetPosSizePixel( ::Point(0,0), ::Size(nFrameWidth,0) );
300 m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) );
301
303
304 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
305 rTreeView.connect_expanding(LINK(this, SbaTableQueryBrowser, OnExpandEntry));
306
307 m_pTreeView->setCopyHandler(LINK(this, SbaTableQueryBrowser, OnCopyEntry));
308
309 m_pTreeView->setContextMenuProvider( this );
310 m_pTreeView->setControlActionListener( this );
311 m_pTreeView->SetHelpId(HID_CTL_TREEVIEW);
312
313 // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide
314 m_pSplitter->SetSplitPosPixel(getBrowserView()->LogicToPixel(::Size(80, 0), MapMode(MapUnit::MapAppFont)).Width());
315
318
319 // fill view with data
320 rTreeView.set_sort_order(true);
321 rTreeView.set_sort_func([this](const weld::TreeIter& rLeft, const weld::TreeIter& rRight){
322 return OnTreeEntryCompare(rLeft, rRight);
323 });
324 rTreeView.make_sorted();
325 m_pTreeView->SetSelChangeHdl(LINK(this, SbaTableQueryBrowser, OnSelectionChange));
326 m_pTreeView->show_container();
327
328 // TODO
330 if (getBrowserView()->getVclControl()->GetHeaderBar())
332 InvalidateFeature(ID_BROWSER_EXPLORER);
333
334 return true;
335}
336
337namespace
338{
339 struct SelectValueByName
340 {
341 const Any& operator()( OUString const& i_name ) const
342 {
343 return m_rCollection.get( i_name );
344 }
345
346 explicit SelectValueByName( ::comphelper::NamedValueCollection const& i_collection )
347 :m_rCollection( i_collection )
348 {
349 }
350
352 };
353}
354
356{
357 try
358 {
359 Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW );
360 bool bEscapeProcessing = false;
361 OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
362 if ( !bEscapeProcessing )
363 // don't touch or interpret anything if escape processing is disabled
364 return;
365
367 if ( !xComposer.is() )
368 // can't do anything. Already reported via assertion in createParser_nothrow.
369 return;
370
371 // the tables participating in the statement
372 const Reference< XTablesSupplier > xSuppTables( xComposer, UNO_QUERY_THROW );
373 const Reference< XNameAccess > xTableNames( xSuppTables->getTables(), UNO_SET_THROW );
374
375 // the columns participating in the statement
376 const Reference< XColumnsSupplier > xSuppColumns( xComposer, UNO_QUERY_THROW );
377 const Reference< XNameAccess > xColumnNames( xSuppColumns->getColumns(), UNO_SET_THROW );
378
379 // check if the order columns apply to tables which really exist in the statement
380 const Reference< XIndexAccess > xOrderColumns( xComposer->getOrderColumns(), UNO_SET_THROW );
381 const sal_Int32 nOrderColumns( xOrderColumns->getCount() );
382 bool invalidColumn = nOrderColumns == 0;
383 for ( sal_Int32 c=0; ( c < nOrderColumns ) && !invalidColumn; ++c )
384 {
385 const Reference< XPropertySet > xOrderColumn( xOrderColumns->getByIndex(c), UNO_QUERY_THROW );
386 OUString sTableName;
387 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName );
388 OUString sColumnName;
389 OSL_VERIFY( xOrderColumn->getPropertyValue( PROPERTY_NAME ) >>= sColumnName );
390
391 if ( sTableName.isEmpty() )
392 {
393 if ( !xColumnNames->hasByName( sColumnName ) )
394 {
395 invalidColumn = true;
396 break;
397 }
398 }
399 else
400 {
401 if ( !xTableNames->hasByName( sTableName ) )
402 {
403 invalidColumn = true;
404 break;
405 }
406
407 const Reference< XColumnsSupplier > xSuppTableColumns( xTableNames->getByName( sTableName ), UNO_QUERY_THROW );
408 const Reference< XNameAccess > xTableColumnNames( xSuppTableColumns->getColumns(), UNO_SET_THROW );
409 if ( !xTableColumnNames->hasByName( sColumnName ) )
410 {
411 invalidColumn = true;
412 break;
413 }
414 }
415 }
416
417 if ( invalidColumn )
418 {
419 // reset the complete order statement at both the row set and the parser
420 xRowSetProps->setPropertyValue( PROPERTY_ORDER, Any( OUString() ) );
421 xComposer->setOrder( "" );
422 }
423
424 // check if the columns participating in the filter refer to existing tables
425 // TODO: there's no API at all for this. The method which comes nearest to what we need is
426 // "getStructuredFilter", but it returns pure column names only. That is, for a statement like
427 // "SELECT * FROM <table> WHERE <other_table>.<column> = <value>", it will return "<column>". But
428 // there's no API at all to retrieve the information about "<other_table>" - which is what would
429 // be needed here.
430 // That'd be a chance to replace getStructuredFilter with something more reasonable.
431 // So, what really would be handy, is some
432 // XNormalizedFilter getNormalizedFilter();
433 // with
434 // interface XDisjunctiveFilterExpression
435 // {
436 // XConjunctiveFilterTerm getTerm( int index );
437 // }
438 // interface XConjunctiveFilterTerm
439 // {
440 // ComparisonPredicate getPredicate( int index );
441 // }
442 // struct ComparisonPredicate
443 // {
444 // XComparisonOperand Lhs;
445 // SQLFilterOperator Operator;
446 // XComparisonOperand Rhs;
447 // }
448 // interface XComparisonOperand
449 // {
450 // SQLFilterOperand Type;
451 // XPropertySet getColumn();
452 // string getLiteral();
453 // ...
454 // }
455 // enum SQLFilterOperand { Column, Literal, ... }
456 // ... or something like this...
457 }
458 catch( const Exception& )
459 {
460 DBG_UNHANDLED_EXCEPTION("dbaccess");
461 }
462}
463
465{
467 return true;
468
469 // this method set all format settings from the original table or query
470 try
471 {
472 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
473 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*m_xCurrentlyDisplayed));
474 ENSURE_OR_RETURN_FALSE( pData, "SbaTableQueryBrowser::InitializeForm: No user data set at the currently displayed entry!" );
475 ENSURE_OR_RETURN_FALSE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeForm: No table available!" );
476
477 Reference< XPropertySetInfo > xPSI( pData->xObjectProperties->getPropertySetInfo(), UNO_SET_THROW );
478
480
481 const OUString aTransferProperties[] =
482 {
483 OUString(PROPERTY_APPLYFILTER),
484 OUString(PROPERTY_FILTER),
485 OUString(PROPERTY_HAVING_CLAUSE),
486 OUString(PROPERTY_ORDER)
487 };
488 for (const auto & aTransferProperty : aTransferProperties)
489 {
490 if ( !xPSI->hasPropertyByName( aTransferProperty ) )
491 continue;
492 aPropertyValues.put( aTransferProperty, pData->xObjectProperties->getPropertyValue( aTransferProperty ) );
493 }
494
495 std::vector< OUString > aNames( aPropertyValues.getNames() );
496 std::sort(aNames.begin(), aNames.end());
498
499 Sequence< Any > aPropValues( aNames.size() );
500 std::transform( aNames.begin(), aNames.end(), aPropValues.getArray(), SelectValueByName( aPropertyValues ) );
501
502 Reference< XMultiPropertySet > xFormMultiSet( i_formProperties, UNO_QUERY_THROW );
503 xFormMultiSet->setPropertyValues( aPropNames, aPropValues );
504
506 }
507 catch ( const Exception& )
508 {
509 DBG_UNHANDLED_EXCEPTION("dbaccess");
510 return false;
511 }
512
513 return true;
514}
515
517{
518 if ( getBrowserView() && getBrowserView()->getVclControl() )
519 {
520 getBrowserView()->getVclControl()->AlwaysEnableInput( false );
521 getBrowserView()->getVclControl()->EnableInput( false );
523 }
524 Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY);
525 if ( xDataSourceSet.is() )
526 {
527 xDataSourceSet->setPropertyValue("AllowInserts",Any(false));
528 xDataSourceSet->setPropertyValue("AllowUpdates",Any(false));
529 xDataSourceSet->setPropertyValue("AllowDeletes",Any(false));
530 }
531}
532
534{
535 try
536 {
537 Reference< css::form::XGridColumnFactory > xColFactory(xGrid, UNO_QUERY);
538 Reference< XNameContainer > xColContainer(xGrid, UNO_QUERY);
539 clearGridColumns( xColContainer );
540
541 Reference< XLoadable > xFormAsLoadable;
542 if (xGrid.is())
543 xFormAsLoadable.set(xGrid->getParent(), css::uno::UNO_QUERY);
544 if (xFormAsLoadable.is() && xFormAsLoadable->isLoaded())
545 {
546 // set the formats from the table
548 {
549 Sequence< OUString> aProperties(6 + ( m_bPreview ? 5 : 0 ));
550 Sequence< Any> aValues(6 + ( m_bPreview ? 5 : 0 ));
551
552 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
553 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*m_xCurrentlyDisplayed));
554 OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeGridModel: No table available!" );
555 if ( !pData->xObjectProperties.is() )
556 return;
557
558 OUString* pStringIter = aProperties.getArray();
559 Any* pValueIter = aValues.getArray();
560 if ( m_bPreview )
561 {
562 *pStringIter++ = "AlwaysShowCursor";
563 *pValueIter++ <<= false;
564 *pStringIter++ = PROPERTY_BORDER;
565 *pValueIter++ <<= sal_Int16(0);
566 }
567
568 *pStringIter++ = PROPERTY_FONT;
569 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_FONT);
570 *pStringIter++ = PROPERTY_TEXTEMPHASIS;
571 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTEMPHASIS);
572 *pStringIter++ = PROPERTY_TEXTRELIEF;
573 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTRELIEF);
574 if ( m_bPreview )
575 {
576 *pStringIter++ = "HasNavigationBar";
577 *pValueIter++ <<= false;
578 *pStringIter++ = "HasRecordMarker";
579 *pValueIter++ <<= false;
580 }
581 *pStringIter++ = PROPERTY_ROW_HEIGHT;
582 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_ROW_HEIGHT);
583 if ( m_bPreview )
584 {
585 *pStringIter++ = "Tabstop";
586 *pValueIter++ <<= false;
587 }
588 *pStringIter++ = PROPERTY_TEXTCOLOR;
589 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTCOLOR);
590 *pStringIter++ = PROPERTY_TEXTLINECOLOR;
591 *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTLINECOLOR);
592
593 Reference< XMultiPropertySet > xFormMultiSet(xGrid, UNO_QUERY);
594 xFormMultiSet->setPropertyValues(aProperties, aValues);
595 }
596
597 // get the formats supplier of the database we're working with
598 Reference< css::util::XNumberFormatsSupplier > xSupplier = getNumberFormatter()->getNumberFormatsSupplier();
599
600 Reference<XConnection> xConnection;
601 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
602 xRowSetProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
603 OSL_ENSURE(xConnection.is(),"A ActiveConnection should normally exists!");
604
605 Reference<XChild> xChild(xConnection,UNO_QUERY);
606 Reference<XPropertySet> xDataSourceProp(xChild->getParent(),UNO_QUERY);
607 bool bSuppressVersionCol = false;
608 OSL_VERIFY( xDataSourceProp->getPropertyValue( PROPERTY_SUPPRESSVERSIONCL ) >>= bSuppressVersionCol );
609
610 // insert the column into the gridcontrol so that we see something :-)
611 OUString aCurrentModelType;
612 Reference<XColumnsSupplier> xSupCols(getRowSet(),UNO_QUERY);
613 Reference<XNameAccess> xColumns = xSupCols->getColumns();
614
615 OUString sDefaultProperty;
618 const Sequence<OUString> aColNames = xColumns->getElementNames();
619 for (const OUString& rName : aColNames)
620 {
621 xColumn.set( xColumns->getByName( rName ), UNO_QUERY_THROW );
622 xColPSI.set( xColumn->getPropertySetInfo(), UNO_SET_THROW );
623
624 // ignore the column when it is a rowversion one
625 if ( bSuppressVersionCol
626 && xColPSI->hasPropertyByName( PROPERTY_ISROWVERSION )
627 && ::cppu::any2bool( xColumn->getPropertyValue( PROPERTY_ISROWVERSION ) )
628 )
629 continue;
630
631 // use the result set column's type to determine the type of grid column to create
632 bool bFormattedIsNumeric = true;
633 sal_Int32 nType = ::comphelper::getINT32( xColumn->getPropertyValue( PROPERTY_TYPE ) );
634
635 std::vector< NamedValue > aInitialValues;
636 std::vector< OUString > aCopyProperties;
637 Any aDefault;
638
639 switch(nType)
640 {
641 case DataType::BIT:
642 case DataType::BOOLEAN:
643 {
644 aCurrentModelType = "CheckBox";
645 aInitialValues.emplace_back( "VisualEffect", Any( VisualEffect::FLAT ) );
646 sDefaultProperty = PROPERTY_DEFAULTSTATE;
647
648 sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
649 OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable );
650 aInitialValues.emplace_back(
651 "TriState",
652 Any( ColumnValue::NO_NULLS != nNullable )
653 );
654 if ( ColumnValue::NO_NULLS == nNullable )
655 aDefault <<= sal_Int16(TRISTATE_FALSE);
656 }
657 break;
658
659 case DataType::LONGVARCHAR:
660 case DataType::CLOB:
661 aInitialValues.emplace_back( "MultiLine", Any( true ) );
662 [[fallthrough]];
663 case DataType::BINARY:
664 case DataType::VARBINARY:
665 case DataType::LONGVARBINARY:
666 aCurrentModelType = "TextField";
667 sDefaultProperty = PROPERTY_DEFAULTTEXT;
668 break;
669
670 case DataType::VARCHAR:
671 case DataType::CHAR:
672 bFormattedIsNumeric = false;
673 [[fallthrough]];
674 default:
675 aCurrentModelType = "FormattedField";
676 sDefaultProperty = PROPERTY_EFFECTIVEDEFAULT;
677
678 if ( xSupplier.is() )
679 aInitialValues.emplace_back( "FormatsSupplier", Any( xSupplier ) );
680 aInitialValues.emplace_back( "TreatAsNumber", Any( bFormattedIsNumeric ) );
681 aCopyProperties.emplace_back(PROPERTY_FORMATKEY );
682 break;
683 }
684
685 aInitialValues.emplace_back( PROPERTY_CONTROLSOURCE, Any( rName ) );
686 OUString sLabel;
687 xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel;
688 if ( !sLabel.isEmpty() )
689 aInitialValues.emplace_back( PROPERTY_LABEL, Any( sLabel ) );
690 else
691 aInitialValues.emplace_back( PROPERTY_LABEL, Any( rName ) );
692
693 Reference< XPropertySet > xGridCol( xColFactory->createColumn( aCurrentModelType ), UNO_SET_THROW );
694 Reference< XPropertySetInfo > xGridColPSI( xGridCol->getPropertySetInfo(), UNO_SET_THROW );
695
696 // calculate the default
697 if ( xGridColPSI->hasPropertyByName( PROPERTY_CONTROLDEFAULT ) )
698 {
699 aDefault = xColumn->getPropertyValue( PROPERTY_CONTROLDEFAULT );
700 // default value
701 if ( nType == DataType::BIT || nType == DataType::BOOLEAN )
702 {
703 if ( aDefault.hasValue() )
704 aDefault <<= (comphelper::getString(aDefault).toInt32() == 0) ? sal_Int16(TRISTATE_FALSE) : sal_Int16(TRISTATE_TRUE);
705 else
706 aDefault <<= sal_Int16(TRISTATE_INDET);
707 }
708 }
709
710 if ( aDefault.hasValue() )
711 aInitialValues.emplace_back( sDefaultProperty, aDefault );
712
713 // transfer properties from the definition to the UNO-model :
714 aCopyProperties.emplace_back(PROPERTY_HIDDEN );
715 aCopyProperties.emplace_back(PROPERTY_WIDTH );
716
717 // help text to display for the column
718 Any aDescription;
719 if ( xColPSI->hasPropertyByName( PROPERTY_HELPTEXT ) )
720 aDescription = xColumn->getPropertyValue( PROPERTY_HELPTEXT );
721 OUString sTemp;
722 aDescription >>= sTemp;
723 if ( sTemp.isEmpty() )
724 xColumn->getPropertyValue( PROPERTY_DESCRIPTION ) >>= sTemp;
725
726 aDescription <<= sTemp;
727 aInitialValues.emplace_back( PROPERTY_HELPTEXT, aDescription );
728
729 // ... horizontal justify
730 Any aAlign; aAlign <<= sal_Int16( 0 );
731 Any aColAlign( xColumn->getPropertyValue( PROPERTY_ALIGN ) );
732 if ( aColAlign.hasValue() )
733 aAlign <<= sal_Int16( ::comphelper::getINT32( aColAlign ) );
734 aInitialValues.emplace_back( PROPERTY_ALIGN, aAlign );
735
736 // don't allow the mouse to scroll in the cells
737 if ( xGridColPSI->hasPropertyByName( PROPERTY_MOUSE_WHEEL_BEHAVIOR ) )
738 aInitialValues.emplace_back( PROPERTY_MOUSE_WHEEL_BEHAVIOR, Any( MouseWheelBehavior::SCROLL_DISABLED ) );
739
740 // now set all those values
741 for (auto const& property : aInitialValues)
742 {
743 xGridCol->setPropertyValue( property.Name, property.Value );
744 }
745 for (auto const& copyPropertyName : aCopyProperties)
746 xGridCol->setPropertyValue( copyPropertyName, xColumn->getPropertyValue(copyPropertyName) );
747
748 xColContainer->insertByName(rName, Any(xGridCol));
749 }
750 }
751 }
752 catch(const Exception&)
753 {
754 DBG_UNHANDLED_EXCEPTION("dbaccess");
755 }
756}
757
759 const weld::TreeIter* pCurrentlyDisplayed,
760 const Reference<XPropertySet>& rxSource)
761{
763 if (pCurrentlyDisplayed)
764 {
765 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*pCurrentlyDisplayed));
766 Reference<XColumnsSupplier> xColumnsSup(pData->xObjectProperties,UNO_QUERY);
767 Reference<XNameAccess> xNames = xColumnsSup->getColumns();
768 OUString aName;
769 rxSource->getPropertyValue(PROPERTY_NAME) >>= aName;
770 if(xNames.is() && xNames->hasByName(aName))
771 xRet.set(xNames->getByName(aName),UNO_QUERY);
772 }
773 return xRet;
774}
775
776void SbaTableQueryBrowser::transferChangedControlProperty(const OUString& _rProperty, const Any& _rNewValue)
777{
779 {
780 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
781 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*m_xCurrentlyDisplayed));
782 Reference< XPropertySet > xObjectProps = pData->xObjectProperties;
783 OSL_ENSURE(xObjectProps.is(),"SbaTableQueryBrowser::transferChangedControlProperty: no table/query object!");
784 if (xObjectProps.is())
785 xObjectProps->setPropertyValue(_rProperty, _rNewValue);
786 }
787}
788
789void SbaTableQueryBrowser::propertyChange(const PropertyChangeEvent& evt)
790{
792
793 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
794
795 try
796 {
797 Reference< XPropertySet > xSource(evt.Source, UNO_QUERY);
798 if (!xSource.is())
799 return;
800 // one of the many properties which require us to update the definition ?
801 // a column's width ?
802 else if (evt.PropertyName == PROPERTY_WIDTH)
803 { // a column width has changed -> update the model
804 // (the update of the view is done elsewhere)
805 Reference<XPropertySet> xProp = getColumnHelper(rTreeView, m_xCurrentlyDisplayed.get(), xSource);
806 if(xProp.is())
807 {
808 if(!evt.NewValue.hasValue())
809 xProp->setPropertyValue(PROPERTY_WIDTH,Any(sal_Int32(227)));
810 else
811 xProp->setPropertyValue(PROPERTY_WIDTH,evt.NewValue);
812 }
813 }
814
815 // a column's 'visible' state ?
816 else if (evt.PropertyName == PROPERTY_HIDDEN)
817 {
818 Reference<XPropertySet> xProp = getColumnHelper(rTreeView, m_xCurrentlyDisplayed.get(), xSource);
819 if(xProp.is())
820 xProp->setPropertyValue(PROPERTY_HIDDEN,evt.NewValue);
821 }
822
823 // a columns alignment ?
824 else if (evt.PropertyName == PROPERTY_ALIGN)
825 {
826 Reference<XPropertySet> xProp = getColumnHelper(rTreeView, m_xCurrentlyDisplayed.get(), xSource);
827 try
828 {
829 if(xProp.is())
830 {
831 if(evt.NewValue.hasValue())
832 {
833 sal_Int16 nAlign = 0;
834 if(evt.NewValue >>= nAlign)
835 xProp->setPropertyValue(PROPERTY_ALIGN,Any(sal_Int32(nAlign)));
836 else
837 xProp->setPropertyValue(PROPERTY_ALIGN,evt.NewValue);
838 }
839 else
840 xProp->setPropertyValue(PROPERTY_ALIGN,Any(css::awt::TextAlign::LEFT));
841 }
842 }
843 catch( const Exception& )
844 {
845 DBG_UNHANDLED_EXCEPTION("dbaccess");
846 }
847 }
848
849 // a column's format ?
850 else if ( evt.PropertyName == PROPERTY_FORMATKEY
851 && (TypeClass_LONG == evt.NewValue.getValueTypeClass())
852 )
853 {
854 // update the model (means the definition object)
855 Reference<XPropertySet> xProp = getColumnHelper(rTreeView, m_xCurrentlyDisplayed.get(), xSource);
856 if(xProp.is())
857 xProp->setPropertyValue(PROPERTY_FORMATKEY,evt.NewValue);
858 }
859
860 // some table definition properties ?
861 // the height of the rows in the grid ?
862 else if (evt.PropertyName == PROPERTY_ROW_HEIGHT)
863 {
865 {
866 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*m_xCurrentlyDisplayed));
867 OSL_ENSURE( pData->xObjectProperties.is(), "No table available!" );
868
869 bool bDefault = !evt.NewValue.hasValue();
870 if (bDefault)
871 pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,Any(sal_Int32(45)));
872 else
873 pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,evt.NewValue);
874 }
875 }
876
877 else if ( evt.PropertyName == PROPERTY_FONT // the font ?
878 || evt.PropertyName == PROPERTY_TEXTCOLOR // the text color ?
879 || evt.PropertyName == PROPERTY_FILTER // the filter ?
880 || evt.PropertyName == PROPERTY_HAVING_CLAUSE // the having clause ?
881 || evt.PropertyName == PROPERTY_ORDER // the sort ?
882 || evt.PropertyName == PROPERTY_APPLYFILTER // the appliance of the filter ?
883 || evt.PropertyName == PROPERTY_TEXTLINECOLOR // the text line color ?
884 || evt.PropertyName == PROPERTY_TEXTEMPHASIS // the text emphasis ?
885 || evt.PropertyName == PROPERTY_TEXTRELIEF // the text relief ?
886 )
887 {
888 transferChangedControlProperty(evt.PropertyName, evt.NewValue);
889 }
890 }
891 catch( const Exception& )
892 {
893 DBG_UNHANDLED_EXCEPTION("dbaccess");
894 }
895}
896
898{
899 SolarMutexGuard aSolarGuard;
900 ::osl::MutexGuard aGuard( getMutex() );
901 if ( getView() && getView()->IsInModalMode() )
902 return false;
903 bool bRet = false;
904 if ( !m_bInSuspend )
905 {
906 m_bInSuspend = true;
907 if ( rBHelper.bDisposed )
908 throw DisposedException( OUString(), *this );
909
910 bRet = SbaXDataBrowserController::suspend(bSuspend);
911 if ( bRet && getView() )
912 getView()->Hide();
913
914 m_bInSuspend = false;
915 }
916
917 return bRet;
918}
919
920void SAL_CALL SbaTableQueryBrowser::statusChanged( const FeatureStateEvent& _rEvent )
921{
922 // search the external dispatcher causing this call
923 Reference< XDispatch > xSource(_rEvent.Source, UNO_QUERY);
924 bool bFound = false;
925 for (auto & externalFeature : m_aExternalFeatures)
926 {
927 if ( _rEvent.FeatureURL.Complete == externalFeature.second.aURL.Complete)
928 {
929 bFound = true;
930 OSL_ENSURE( xSource.get() == externalFeature.second.xDispatcher.get(), "SbaTableQueryBrowser::statusChanged: inconsistent!" );
931 // update the enabled state
932 externalFeature.second.bEnabled = _rEvent.IsEnabled;
933
934 switch ( externalFeature.first )
935 {
937 {
938 // if it's the slot for the document data source, remember the state
939 Sequence< PropertyValue > aDescriptor;
940 bool bProperFormat = _rEvent.State >>= aDescriptor;
941 OSL_ENSURE(bProperFormat, "SbaTableQueryBrowser::statusChanged: need a data access descriptor here!");
943
944 OSL_ENSURE( ( m_aDocumentDataSource.has(DataAccessDescriptorProperty::DataSource)
945 || m_aDocumentDataSource.has(DataAccessDescriptorProperty::DatabaseLocation)
946 )
947 && m_aDocumentDataSource.has(DataAccessDescriptorProperty::Command)
948 && m_aDocumentDataSource.has(DataAccessDescriptorProperty::CommandType),
949 "SbaTableQueryBrowser::statusChanged: incomplete descriptor!");
950
951 // check if we know the object which is set as document data source
953 }
954 break;
955
956 default:
957 // update the toolbox
958 implCheckExternalSlot( externalFeature.first );
959 break;
960 }
961 break;
962 }
963 }
964
965 OSL_ENSURE(bFound, "SbaTableQueryBrowser::statusChanged: don't know who sent this!");
966}
967
969{
970 std::unique_ptr<weld::TreeIter> xDataSourceEntry;
971 std::unique_ptr<weld::TreeIter> xContainerEntry;
972 std::unique_ptr<weld::TreeIter> xObjectEntry = getObjectEntry(m_aDocumentDataSource, &xDataSourceEntry, &xContainerEntry);
973 bool bKnownDocDataSource = static_cast<bool>(xObjectEntry);
974 if (!bKnownDocDataSource)
975 {
976 if (xDataSourceEntry)
977 {
978 // at least the data source is known
979 if (xContainerEntry)
980 {
981 bKnownDocDataSource = true; // assume we know it.
982 // TODO: should we expand the object container? This may be too expensive just for checking...
983 }
984 else
985 {
986 if (m_aDocumentDataSource.has(DataAccessDescriptorProperty::CommandType)
987 && m_aDocumentDataSource.has(DataAccessDescriptorProperty::Command))
988 { // maybe we have a command to be displayed ?
989 sal_Int32 nCommandType = CommandType::TABLE;
990 m_aDocumentDataSource[DataAccessDescriptorProperty::CommandType] >>= nCommandType;
991
992 OUString sCommand;
993 m_aDocumentDataSource[DataAccessDescriptorProperty::Command] >>= sCommand;
994
995 bKnownDocDataSource = (CommandType::COMMAND == nCommandType) && (!sCommand.isEmpty());
996 }
997 }
998 }
999 }
1000
1001 if ( !bKnownDocDataSource )
1003
1004 // update the toolbox
1006}
1007
1008void SbaTableQueryBrowser::extractDescriptorProps(const svx::ODataAccessDescriptor& _rDescriptor, OUString& _rDataSource, OUString& _rCommand, sal_Int32& _rCommandType, bool& _rEscapeProcessing)
1009{
1010 _rDataSource = _rDescriptor.getDataSource();
1011 if ( _rDescriptor.has(DataAccessDescriptorProperty::Command) )
1012 _rDescriptor[DataAccessDescriptorProperty::Command] >>= _rCommand;
1013 if ( _rDescriptor.has(DataAccessDescriptorProperty::CommandType) )
1014 _rDescriptor[DataAccessDescriptorProperty::CommandType] >>= _rCommandType;
1015
1016 // escape processing is the only one allowed not to be present
1017 _rEscapeProcessing = true;
1018 if (_rDescriptor.has(DataAccessDescriptorProperty::EscapeProcessing))
1019 _rEscapeProcessing = ::cppu::any2bool(_rDescriptor[DataAccessDescriptorProperty::EscapeProcessing]);
1020}
1021
1022namespace
1023{
1024 bool getDataSourceDisplayName_isURL( const OUString& _rDS, OUString& _rDisplayName, OUString& _rUniqueId )
1025 {
1026 INetURLObject aURL( _rDS );
1027 if ( aURL.GetProtocol() != INetProtocol::NotValid )
1028 {
1030 _rUniqueId = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1031 return true;
1032 }
1033 _rDisplayName = _rDS;
1034 _rUniqueId.clear();
1035 return false;
1036 }
1037
1038 struct FilterByEntryDataId : public IEntryFilter
1039 {
1040 OUString sId;
1041 explicit FilterByEntryDataId( OUString _aId ) : sId(std::move( _aId )) { }
1042
1043 virtual ~FilterByEntryDataId() {}
1044
1045 virtual bool includeEntry(const void* pEntry) const override;
1046 };
1047
1048 bool FilterByEntryDataId::includeEntry(const void* pUserData) const
1049 {
1050 const DBTreeListUserData* pData = static_cast<const DBTreeListUserData*>(pUserData);
1051 return ( !pData || ( pData->sAccessor == sId ) );
1052 }
1053}
1054
1056{
1057 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
1058 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(rDataSourceEntry));
1059 OSL_ENSURE( pData, "SbaTableQueryBrowser::getDataSourceAccessor: invalid entry data!" );
1060 OSL_ENSURE( pData->eType == etDatasource, "SbaTableQueryBrowser::getDataSourceAccessor: entry does not denote a data source!" );
1061 return !pData->sAccessor.isEmpty() ? pData->sAccessor : GetEntryText(rDataSourceEntry);
1062}
1063
1064std::unique_ptr<weld::TreeIter> SbaTableQueryBrowser::getObjectEntry(const OUString& _rDataSource, const OUString& _rCommand, sal_Int32 nCommandType,
1065 std::unique_ptr<weld::TreeIter>* ppDataSourceEntry, std::unique_ptr<weld::TreeIter>* ppContainerEntry, bool bExpandAncestors,
1066 const SharedConnection& _rxConnection )
1067{
1068 if (ppDataSourceEntry)
1069 ppDataSourceEntry->reset();
1070 if (ppContainerEntry)
1071 ppContainerEntry->reset();
1072
1073 std::unique_ptr<weld::TreeIter> xObject;
1074 if ( m_pTreeView )
1075 {
1076 // look for the data source entry
1077 OUString sDisplayName, sDataSourceId;
1078 bool bIsDataSourceURL = getDataSourceDisplayName_isURL( _rDataSource, sDisplayName, sDataSourceId );
1079 // the display name may differ from the URL for readability reasons
1080 // #i33699#
1081
1082 FilterByEntryDataId aFilter( sDataSourceId );
1083 std::unique_ptr<weld::TreeIter> xDataSource = m_pTreeView->GetEntryPosByName( sDisplayName, nullptr, &aFilter );
1084 if (!xDataSource) // check if the data source name is a file location
1085 {
1086 if ( bIsDataSourceURL )
1087 {
1088 // special case, the data source is a URL
1089 // add new entries to the list box model
1090 implAddDatasource( _rDataSource, _rxConnection );
1091 xDataSource = m_pTreeView->GetEntryPosByName( sDisplayName, nullptr, &aFilter );
1092 OSL_ENSURE( xDataSource, "SbaTableQueryBrowser::getObjectEntry: hmm - did not find it again!" );
1093 }
1094 }
1095
1096 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
1097
1098 if (xDataSource)
1099 {
1100 if (ppDataSourceEntry)
1101 {
1102 // (caller wants to have it...)
1103 *ppDataSourceEntry = rTreeView.make_iterator(xDataSource.get());
1104 }
1105
1106 // expand if required so
1107 if (bExpandAncestors)
1108 rTreeView.expand_row(*xDataSource);
1109
1110 // look for the object container
1111 std::unique_ptr<weld::TreeIter> xCommandType;
1112 if (nCommandType == CommandType::QUERY || nCommandType == CommandType::TABLE)
1113 {
1114 xCommandType = rTreeView.make_iterator(xDataSource.get());
1115 if (!rTreeView.iter_children(*xCommandType))
1116 xCommandType.reset();
1117 else
1118 {
1119 // 1st child is queries, so we're already done if looking for CommandType::QUERY
1120
1121 // 2nd child is tables
1122 if (nCommandType == CommandType::TABLE && !rTreeView.iter_next_sibling(*xCommandType))
1123 xCommandType.reset();
1124 }
1125 }
1126
1127 if (xCommandType)
1128 {
1129 if (ppContainerEntry)
1130 {
1131 // (caller wants to have it...)
1132 *ppContainerEntry = rTreeView.make_iterator(xCommandType.get());
1133 }
1134
1135 rTreeView.make_unsorted();
1136
1137 // expand if required so
1138 if (bExpandAncestors)
1139 {
1140 rTreeView.expand_row(*xCommandType);
1141 }
1142
1143 // look for the object
1144 sal_Int32 nIndex = 0;
1145 do
1146 {
1147 OUString sPath;
1148 switch (nCommandType)
1149 {
1150 case CommandType::TABLE:
1151 sPath = _rCommand;
1152 nIndex = -1;
1153 break;
1154
1155 case CommandType::QUERY:
1156 sPath = _rCommand.getToken( 0, '/', nIndex );
1157 break;
1158
1159 default:
1160 assert(false);
1161 }
1162 xObject = m_pTreeView->GetEntryPosByName(sPath, xCommandType.get());
1163 if (xObject)
1164 rTreeView.copy_iterator(*xObject, *xCommandType);
1165 else
1166 xCommandType.reset();
1167 if ( nIndex >= 0 )
1168 {
1169 if (ensureEntryObject(*xObject))
1170 {
1171 DBTreeListUserData* pParentData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xObject));
1172 Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
1173 sal_Int32 nIndex2 = nIndex;
1174 sPath = _rCommand.getToken( 0, '/', nIndex2 );
1175 try
1176 {
1177 if ( xCollection->hasByName(sPath) )
1178 {
1179 if(!m_pTreeView->GetEntryPosByName(sPath, xObject.get()))
1180 {
1181 Reference<XNameAccess> xChild(xCollection->getByName(sPath),UNO_QUERY);
1182 DBTreeListUserData* pEntryData = new DBTreeListUserData;
1183 pEntryData->eType = etQuery;
1184 if ( xChild.is() )
1185 {
1186 pEntryData->eType = etQueryContainer;
1187 }
1188 implAppendEntry(xObject.get(), sPath, pEntryData);
1189 }
1190 }
1191 }
1192 catch(const Exception&)
1193 {
1194 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::populateTree: could not fill the tree");
1195 }
1196 }
1197 }
1198 }
1199 while ( nIndex >= 0 );
1200
1201 rTreeView.make_sorted();
1202 }
1203 }
1204 }
1205 return xObject;
1206}
1207
1208std::unique_ptr<weld::TreeIter> SbaTableQueryBrowser::getObjectEntry(const svx::ODataAccessDescriptor& rDescriptor,
1209 std::unique_ptr<weld::TreeIter>* ppDataSourceEntry, std::unique_ptr<weld::TreeIter>* ppContainerEntry)
1210{
1211 // extract the props from the descriptor
1212 OUString sDataSource;
1213 OUString sCommand;
1214 sal_Int32 nCommandType = CommandType::COMMAND;
1215 bool bEscapeProcessing = true;
1216 extractDescriptorProps(rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
1217
1218 return getObjectEntry(sDataSource, sCommand, nCommandType, ppDataSourceEntry, ppContainerEntry, false /*bExpandAncestors*/);
1219}
1220
1222{
1223 Reference< XDispatchProvider > xProvider( getFrame(), UNO_QUERY );
1224 OSL_ENSURE(xProvider.is(), "SbaTableQueryBrowser::connectExternalDispatches: no DispatchProvider !");
1225 if (!xProvider.is())
1226 return;
1227
1228 if ( m_aExternalFeatures.empty() )
1229 {
1230 const char* pURLs[] = {
1231 ".uno:DataSourceBrowser/DocumentDataSource",
1232 ".uno:DataSourceBrowser/FormLetter",
1233 ".uno:DataSourceBrowser/InsertColumns",
1234 ".uno:DataSourceBrowser/InsertContent",
1235 };
1236 const sal_uInt16 nIds[] = {
1241 };
1242
1243 for ( size_t i=0; i < std::size( pURLs ); ++i )
1244 {
1245 URL aURL;
1246 aURL.Complete = OUString::createFromAscii( pURLs[i] );
1247 if ( m_xUrlTransformer.is() )
1248 m_xUrlTransformer->parseStrict( aURL );
1249 m_aExternalFeatures[ nIds[ i ] ] = ExternalFeature( std::move(aURL) );
1250 }
1251 }
1252
1253 for (auto & externalFeature : m_aExternalFeatures)
1254 {
1255 externalFeature.second.xDispatcher = xProvider->queryDispatch(
1256 externalFeature.second.aURL, "_parent", FrameSearchFlag::PARENT
1257 );
1258
1259 if ( externalFeature.second.xDispatcher.get() == static_cast< XDispatch* >( this ) )
1260 {
1261 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::connectExternalDispatches: this should not happen anymore!" );
1262 // (nowadays, the URLs aren't in our SupportedFeatures list anymore, so we should
1263 // not supply a dispatcher for this)
1264 externalFeature.second.xDispatcher.clear();
1265 }
1266
1267 if ( externalFeature.second.xDispatcher.is() )
1268 {
1269 try
1270 {
1271 externalFeature.second.xDispatcher->addStatusListener( this, externalFeature.second.aURL );
1272 }
1273 catch( const Exception& )
1274 {
1275 DBG_UNHANDLED_EXCEPTION("dbaccess");
1276 }
1277 }
1278
1279 implCheckExternalSlot( externalFeature.first );
1280 }
1281}
1282
1284{
1285 if ( !m_xMainToolbar.is() )
1286 return;
1287
1289 ToolBox* pToolbox = dynamic_cast< ToolBox* >( pToolboxWindow.get() );
1290 OSL_ENSURE( pToolbox, "SbaTableQueryBrowser::implCheckExternalSlot: cannot obtain the toolbox window!" );
1291
1292 // check if we have to hide this item from the toolbox
1293 if ( pToolbox )
1294 {
1295 bool bHaveDispatcher = m_aExternalFeatures[ _nId ].xDispatcher.is();
1296 if ( bHaveDispatcher != pToolbox->IsItemVisible( ToolBoxItemId(_nId) ) )
1297 bHaveDispatcher ? pToolbox->ShowItem( ToolBoxItemId(_nId) ) : pToolbox->HideItem( ToolBoxItemId(_nId) );
1298 }
1299
1300 // and invalidate this feature in general
1301 InvalidateFeature( _nId );
1302}
1303
1304void SAL_CALL SbaTableQueryBrowser::disposing( const css::lang::EventObject& _rSource )
1305{
1306 // our frame ?
1307 Reference< css::frame::XFrame > xSourceFrame(_rSource.Source, UNO_QUERY);
1308 if (m_xCurrentFrameParent.is() && (xSourceFrame == m_xCurrentFrameParent))
1309 m_xCurrentFrameParent->removeFrameActionListener(static_cast<css::frame::XFrameActionListener*>(this));
1310 else
1311 {
1312 // search the external dispatcher causing this call in our map
1313 Reference< XDispatch > xSource(_rSource.Source, UNO_QUERY);
1314 if(xSource.is())
1315 {
1316 ExternalFeaturesMap::const_iterator aLoop = m_aExternalFeatures.begin();
1317 ExternalFeaturesMap::const_iterator aEnd = m_aExternalFeatures.end();
1318 while (aLoop != aEnd)
1319 {
1320 if ( aLoop->second.xDispatcher.get() == xSource.get() )
1321 {
1322 sal_uInt16 nSlot = aLoop->first;
1323
1324 // remove it
1325 aLoop = m_aExternalFeatures.erase(aLoop);
1326
1327 // maybe update the UI
1328 implCheckExternalSlot(nSlot);
1329
1330 // continue, the same XDispatch may be responsible for more than one URL
1331 }
1332 ++aLoop;
1333 }
1334 }
1335 else
1336 {
1337 Reference<XConnection> xCon(_rSource.Source, UNO_QUERY);
1338 if ( xCon.is() && m_pTreeView )
1339 {
1340 // our connection is in dispose so we have to find the entry equal with this connection
1341 // and close it what means to collapse the entry
1342 // get the top-level representing the removed data source
1343 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
1344 std::unique_ptr<weld::TreeIter> xDSLoop(rTreeView.make_iterator());
1345 if (rTreeView.get_iter_first(*xDSLoop))
1346 {
1347 do
1348 {
1349 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xDSLoop));
1350 if ( pData && pData->xConnection == xCon )
1351 {
1352 // we set the connection to null to avoid a second disposing of the connection
1353 pData->xConnection.clear();
1354 closeConnection(*xDSLoop, false);
1355 break;
1356 }
1357 }
1358 while (rTreeView.iter_next_sibling(*xDSLoop));
1359 }
1360 }
1361 else
1363 }
1364 }
1365}
1366
1368{
1369 // clear all old dispatches
1370 for (auto const& externalFeature : m_aExternalFeatures)
1371 {
1372 if ( externalFeature.second.xDispatcher.is() )
1373 {
1374 try
1375 {
1376 externalFeature.second.xDispatcher->removeStatusListener( this, externalFeature.second.aURL );
1377 }
1378 catch (Exception&)
1379 {
1380 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::implRemoveStatusListeners: could not remove a status listener!");
1381 }
1382 }
1383 }
1384 m_aExternalFeatures.clear();
1385}
1386
1387sal_Bool SAL_CALL SbaTableQueryBrowser::select( const Any& _rSelection )
1388{
1389 SolarMutexGuard aGuard;
1390 // doin' a lot of VCL stuff here -> lock the SolarMutex
1391
1392 Sequence< PropertyValue > aDescriptorSequence;
1393 if (!(_rSelection >>= aDescriptorSequence))
1394 throw IllegalArgumentException(OUString(), *this, 1);
1395 // TODO: error message
1396
1397 ODataAccessDescriptor aDescriptor;
1398 try
1399 {
1400 aDescriptor = ODataAccessDescriptor(aDescriptorSequence);
1401 }
1402 catch(const Exception&)
1403 {
1404 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::select: could not extract the descriptor!");
1405 }
1406
1407 // check the presence of the props we need
1408 if ( !(aDescriptor.has(DataAccessDescriptorProperty::DataSource) || aDescriptor.has(DataAccessDescriptorProperty::DatabaseLocation)) || !aDescriptor.has(DataAccessDescriptorProperty::Command) || !aDescriptor.has(DataAccessDescriptorProperty::CommandType))
1409 throw IllegalArgumentException(OUString(), *this, 1);
1410 // TODO: error message
1411
1412 return implSelect(aDescriptor,true);
1413}
1414
1416{
1417 Any aReturn;
1418
1419 try
1420 {
1421 Reference< XLoadable > xLoadable(getRowSet(), UNO_QUERY);
1422 if (xLoadable.is() && xLoadable->isLoaded())
1423 {
1424 Reference< XPropertySet > aFormProps(getRowSet(), UNO_QUERY);
1425 ODataAccessDescriptor aDescriptor(aFormProps);
1426 // remove properties which are not part of our "selection"
1427 aDescriptor.erase(DataAccessDescriptorProperty::Connection);
1428 aDescriptor.erase(DataAccessDescriptorProperty::Cursor);
1429
1430 aReturn <<= aDescriptor.createPropertyValueSequence();
1431 }
1432 }
1433 catch( const Exception& )
1434 {
1435 DBG_UNHANDLED_EXCEPTION("dbaccess");
1436 }
1437
1438 return aReturn;
1439}
1440
1442{
1444}
1445
1447{
1449}
1450
1452{
1454
1455 if (m_xCurrentFrameParent.is())
1456 m_xCurrentFrameParent->removeFrameActionListener(static_cast<css::frame::XFrameActionListener*>(this));
1457
1458 SbaXDataBrowserController::attachFrame(_xFrame);
1459
1460 Reference< XFrame > xCurrentFrame( getFrame() );
1461 if ( xCurrentFrame.is() )
1462 {
1463 m_xCurrentFrameParent = xCurrentFrame->findFrame("_parent",FrameSearchFlag::PARENT);
1464 if ( m_xCurrentFrameParent.is() )
1465 m_xCurrentFrameParent->addFrameActionListener(static_cast<css::frame::XFrameActionListener*>(this));
1466
1467 // obtain our toolbox
1468 try
1469 {
1470 Reference< XPropertySet > xFrameProps( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW );
1472 xFrameProps->getPropertyValue("LayoutManager"),
1473 UNO_QUERY );
1474
1475 if ( xLayouter.is() )
1476 {
1478 xLayouter->getElement( "private:resource/toolbar/toolbar" ),
1479 UNO_SET_THROW );
1480 m_xMainToolbar.set(xUI->getRealInterface(), css::uno::UNO_QUERY);
1481 OSL_ENSURE( m_xMainToolbar.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" );
1482 }
1483 }
1484 catch( const Exception& )
1485 {
1486 DBG_UNHANDLED_EXCEPTION("dbaccess");
1487 }
1488 }
1489
1490 // get the dispatchers for the external slots
1492}
1493
1495{
1497 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1498 if (xSourceSet.is())
1499 {
1500 xSourceSet->addPropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1501 xSourceSet->addPropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1502 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1503 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1504 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1505 xSourceSet->addPropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1506 }
1507
1508}
1509
1511{
1513 Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY);
1514 if (xSourceSet.is())
1515 {
1516 xSourceSet->removePropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this));
1517 xSourceSet->removePropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this));
1518 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this));
1519 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this));
1520 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this));
1521 xSourceSet->removePropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this));
1522 }
1523}
1524
1526{
1527 if(getBrowserView())
1528 {
1530 if (!pControl->IsEditing())
1531 InvalidateFeature(ID_BROWSER_COPY);
1532 }
1534}
1535
1537{
1538 if(getBrowserView())
1539 {
1541 if (!pControl->IsEditing())
1542 InvalidateFeature(ID_BROWSER_COPY);
1543 }
1545}
1546
1548{
1550 SafeAddPropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1551 SafeAddPropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1552 SafeAddPropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1553 SafeAddPropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1554}
1555
1557{
1559 SafeRemovePropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this));
1560 SafeRemovePropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this));
1561 SafeRemovePropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this));
1562 SafeRemovePropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this));
1563}
1564
1566{
1568 unloadAndCleanup( false );
1569}
1570
1572{
1574
1575 m_sQueryCommand.clear();
1577
1578 if (isValid() && !loadingCancelled())
1579 {
1580 // did we load a query?
1581 bool bTemporary; // needed because we m_bQueryEscapeProcessing is only one bit wide (and we want to pass it by reference)
1582 if ( implGetQuerySignature( m_sQueryCommand, bTemporary ) )
1583 m_bQueryEscapeProcessing = bTemporary;
1584 }
1585
1586 // if the form has been loaded, this means that our "selection" has changed
1587 css::lang::EventObject aEvent( *this );
1588 m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent );
1589}
1590
1592{
1593 bool bEnabled = false;
1594 ExternalFeaturesMap::const_iterator aPos = m_aExternalFeatures.find( _nId );
1595 if ( ( m_aExternalFeatures.end() != aPos ) && aPos->second.xDispatcher.is() )
1596 bEnabled = aPos->second.bEnabled;
1597 return bEnabled;
1598}
1599
1601{
1602 FeatureState aReturn;
1603 // (disabled automatically)
1604
1605 // no chance without a view
1606 if (!getBrowserView() || !getBrowserView()->getVclControl())
1607 return aReturn;
1608
1609 switch ( nId )
1610 {
1612 aReturn.bEnabled = true;
1613 return aReturn;
1614
1615 case ID_BROWSER_CLOSE:
1616 // the close button should always be enabled
1617 aReturn.bEnabled = !m_bEnableBrowser;
1618 return aReturn;
1619
1620 // "toggle explorer" is always enabled (if we have an explorer)
1622 aReturn.bEnabled = m_bEnableBrowser;
1623 aReturn.bChecked = haveExplorer();
1624 return aReturn;
1625
1628
1629 case ID_BROWSER_COPY:
1630 if ( !m_pTreeView->HasChildPathFocus() )
1631 // handled below
1632 break;
1633 [[fallthrough]];
1634 case ID_TREE_CLOSE_CONN:
1636 {
1637 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
1638 std::unique_ptr<weld::TreeIter> xCurrentEntry(rTreeView.make_iterator());
1639 if (!rTreeView.get_cursor(xCurrentEntry.get()))
1640 return aReturn;
1641
1642 EntryType eType = getEntryType(*xCurrentEntry);
1643 if ( eType == etUnknown )
1644 return aReturn;
1645
1646 std::unique_ptr<weld::TreeIter> xDataSourceEntry = m_pTreeView->GetRootLevelParent(xCurrentEntry.get());
1647 DBTreeListUserData* pDSData
1648 = xDataSourceEntry
1649 ? weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xDataSourceEntry))
1650 : nullptr;
1651
1652 if ( nId == ID_TREE_CLOSE_CONN )
1653 {
1654 aReturn.bEnabled = ( pDSData != nullptr ) && pDSData->xConnection.is();
1655 }
1656 else if ( nId == ID_TREE_EDIT_DATABASE )
1657 {
1659 "/org.openoffice.Office.DataAccess/Policies/Features/Common" ) );
1660 bool bHaveEditDatabase( true );
1661 OSL_VERIFY( aConfig.getNodeValue( "EditDatabaseFromDataSourceView" ) >>= bHaveEditDatabase );
1662 aReturn.bEnabled = getORB().is() && xDataSourceEntry && bHaveEditDatabase;
1663 }
1664 else if ( nId == ID_BROWSER_COPY )
1665 {
1666 aReturn.bEnabled = isEntryCopyAllowed(*xCurrentEntry);
1667 }
1668
1669 return aReturn;
1670 }
1671 }
1672
1673 // all slots not handled above are not available if no form is loaded
1674 if (!isLoaded())
1675 return aReturn;
1676
1677 try
1678 {
1679 bool bHandled = false;
1680 switch (nId)
1681 {
1683 // the slot is enabled if we have an external dispatcher able to handle it,
1684 // and the dispatcher must have enabled the slot in general
1686 bHandled = true;
1687 break;
1688 case ID_BROWSER_REFRESH:
1689 aReturn.bEnabled = true;
1690 bHandled = true;
1691 break;
1692 }
1693
1694 if (bHandled)
1695 return aReturn;
1696
1697 // no chance without valid models
1698 if (isValid() && !isValidCursor() && nId != ID_BROWSER_CLOSE)
1699 return aReturn;
1700
1701 switch (nId)
1702 {
1706 {
1707 // the slot is enabled if we have an external dispatcher able to handle it,
1708 // and the dispatcher must have enabled the slot in general
1709 aReturn.bEnabled = getExternalSlotState( nId );
1710
1711 // for the Insert* slots, we need at least one selected row
1713 aReturn.bEnabled = aReturn.bEnabled && getBrowserView()->getVclControl()->GetSelectRowCount();
1714
1715 // disabled for native queries which are not saved within the database
1716 Reference< XPropertySet > xDataSource(getRowSet(), UNO_QUERY);
1717 try
1718 {
1719 aReturn.bEnabled = aReturn.bEnabled && xDataSource.is();
1720
1721 if (xDataSource.is())
1722 {
1723 sal_Int32 nType = ::comphelper::getINT32(xDataSource->getPropertyValue(PROPERTY_COMMAND_TYPE));
1724 aReturn.bEnabled = aReturn.bEnabled &&
1725 ( ::comphelper::getBOOL(xDataSource->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) ||
1727 }
1728 }
1729 catch(DisposedException&)
1730 {
1731 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::GetState: object already disposed!");
1732 }
1733 catch( const Exception& )
1734 {
1735 DBG_UNHANDLED_EXCEPTION("dbaccess");
1736 }
1737 }
1738 break;
1739
1740 case ID_BROWSER_TITLE:
1741 {
1742 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1743 sal_Int32 nCommandType = CommandType::TABLE;
1744 xProp->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nCommandType;
1745 OUString sTitle;
1746 switch (nCommandType)
1747 {
1748 case CommandType::TABLE:
1749 sTitle = DBA_RES(STR_TBL_TITLE); break;
1750 case CommandType::QUERY:
1751 case CommandType::COMMAND:
1752 sTitle = DBA_RES(STR_QRY_TITLE); break;
1753 default:
1754 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::GetState: unknown command type!");
1755 }
1756 OUString aName;
1757 xProp->getPropertyValue(PROPERTY_COMMAND) >>= aName;
1758 OUString sObject(aName);
1759
1760 aReturn.sTitle = sTitle.replaceFirst("#", sObject);
1761 aReturn.bEnabled = true;
1762 }
1763 break;
1769 // aReturn.bEnabled &= getDefinition() && !getDefinition()->GetDatabase()->IsReadOnly();
1770 break;
1771
1772 case ID_BROWSER_COPY:
1773 OSL_ENSURE( !m_pTreeView->HasChildPathFocus(), "SbaTableQueryBrowser::GetState( ID_BROWSER_COPY ): this should have been handled above!" );
1774 if (getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing())
1775 {
1777 if ( pControl->GetSelectRowCount() )
1778 {
1779 aReturn.bEnabled = m_aCurrentFrame.isActive();
1780 break;
1781 }
1782 else
1783 aReturn.bEnabled = pControl->canCopyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
1784 break;
1785 }
1786 [[fallthrough]];
1787 default:
1789 }
1790 }
1791 catch(const Exception&)
1792 {
1793 DBG_UNHANDLED_EXCEPTION("dbaccess");
1794 }
1795
1796 return aReturn;
1797
1798}
1799
1801{
1802 switch (nId)
1803 {
1804 default:
1806 break;
1807
1809 {
1810 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
1811 std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
1812 if (rTreeView.get_cursor(xIter.get()))
1813 implAdministrate(*xIter);
1814 break;
1815 }
1816 case ID_TREE_CLOSE_CONN:
1817 {
1818 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
1819 std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
1820 if (rTreeView.get_cursor(xIter.get()))
1821 {
1822 xIter = m_pTreeView->GetRootLevelParent(xIter.get());
1823 closeConnection(*xIter);
1824 }
1825 break;
1826 }
1828 svx::administrateDatabaseRegistration( getFrameWeld() );
1829 break;
1830
1831 case ID_BROWSER_REFRESH:
1832 {
1833 if ( !SaveModified( ) )
1834 // nothing to do
1835 break;
1836
1837 bool bFullReinit = false;
1838 // check if the query signature (if the form is based on a query) has changed
1839 if ( !m_sQueryCommand.isEmpty() )
1840 {
1841 OUString sNewQueryCommand;
1842 bool bNewQueryEP;
1843
1844 bool bIsQuery =
1845 implGetQuerySignature( sNewQueryCommand, bNewQueryEP );
1846 OSL_ENSURE( bIsQuery, "SbaTableQueryBrowser::Execute: was a query before, but is not anymore?" );
1847
1848 bFullReinit = ( sNewQueryCommand != m_sQueryCommand ) || ( m_bQueryEscapeProcessing != bNewQueryEP );
1849 }
1850 if ( !bFullReinit )
1851 {
1852 // let the base class do a simple reload
1854 break;
1855 }
1856 [[fallthrough]];
1857 }
1858
1860 {
1861 if ( !SaveModified() )
1862 // nothing to do
1863 break;
1864
1865 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
1866 std::unique_ptr<weld::TreeIter> xSelected = m_xCurrentlyDisplayed ?
1867 rTreeView.make_iterator(m_xCurrentlyDisplayed.get()) : nullptr;
1868
1869 // unload
1870 unloadAndCleanup( false );
1871
1872 // reselect the entry
1873 if ( xSelected )
1874 {
1875 implSelect(xSelected.get());
1876 }
1877 else
1878 {
1879 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1881 }
1882 }
1883 break;
1884
1887 break;
1888
1891 break;
1892
1896 if (getBrowserView() && isValidCursor())
1897 {
1898 // the URL the slot id is assigned to
1899 OSL_ENSURE( m_aExternalFeatures.find( nId ) != m_aExternalFeatures.end(),
1900 "SbaTableQueryBrowser::Execute( ID_BROWSER_?): how could this ever be enabled?" );
1901 URL aParentUrl = m_aExternalFeatures[ nId ].aURL;
1902
1903 // let the dispatcher execute the slot
1905 if (xDispatch.is())
1906 {
1907 // set the properties for the dispatch
1908
1909 // first fill the selection
1911 MultiSelection* pSelection = const_cast<MultiSelection*>(pGrid->GetSelection());
1912 Sequence< Any > aSelection;
1913 if ( !pGrid->IsAllSelected() )
1914 { // transfer the selected rows only if not all rows are selected
1915 // (all rows means the whole table)
1916 // #i3832#
1917 if (pSelection != nullptr)
1918 {
1919 aSelection.realloc(pSelection->GetSelectCount());
1920 tools::Long nIdx = pSelection->FirstSelected();
1921 Any* pSelectionNos = aSelection.getArray();
1922 while (nIdx != SFX_ENDOFSELECTION)
1923 {
1924 *pSelectionNos++ <<= static_cast<sal_Int32>(nIdx + 1);
1925 nIdx = pSelection->NextSelected();
1926 }
1927 }
1928 }
1929
1930 Reference< XResultSet > xCursorClone;
1931 try
1932 {
1933 Reference< XResultSetAccess > xResultSetAccess(getRowSet(),UNO_QUERY);
1934 if (xResultSetAccess.is())
1935 xCursorClone = xResultSetAccess->createResultSet();
1936 }
1937 catch(DisposedException&)
1938 {
1939 SAL_WARN("dbaccess.ui", "Object already disposed!");
1940 }
1941 catch(const Exception&)
1942 {
1943 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not clone the cursor!");
1944 }
1945
1946 Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY);
1947
1948 try
1949 {
1950 ODataAccessDescriptor aDescriptor;
1951 OUString sDataSourceName;
1952 xProp->getPropertyValue(PROPERTY_DATASOURCENAME) >>= sDataSourceName;
1953
1954 aDescriptor.setDataSource(sDataSourceName);
1955 aDescriptor[DataAccessDescriptorProperty::Command] = xProp->getPropertyValue(PROPERTY_COMMAND);
1956 aDescriptor[DataAccessDescriptorProperty::CommandType] = xProp->getPropertyValue(PROPERTY_COMMAND_TYPE);
1957 aDescriptor[DataAccessDescriptorProperty::Connection] = xProp->getPropertyValue(PROPERTY_ACTIVE_CONNECTION);
1958 aDescriptor[DataAccessDescriptorProperty::Cursor] <<= xCursorClone;
1959 if ( aSelection.hasElements() )
1960 {
1961 aDescriptor[DataAccessDescriptorProperty::Selection] <<= aSelection;
1962 aDescriptor[DataAccessDescriptorProperty::BookmarkSelection] <<= false;
1963 // these are selection indices
1964 // before we change this, all clients have to be adjusted
1965 // so that they recognize the new BookmarkSelection property!
1966 }
1967
1968 xDispatch->dispatch(aParentUrl, aDescriptor.createPropertyValueSequence());
1969 }
1970 catch( const Exception& )
1971 {
1972 DBG_UNHANDLED_EXCEPTION("dbaccess");
1973 }
1974 }
1975 }
1976 break;
1977
1978 case ID_BROWSER_CLOSE:
1979 closeTask();
1980 // if it's not 0, such an async close is already pending
1981 break;
1982
1983 case ID_BROWSER_COPY:
1984 if(m_pTreeView->HasChildPathFocus())
1985 {
1986 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
1987 std::unique_ptr<weld::TreeIter> xCursor(rTreeView.make_iterator());
1988 if (rTreeView.get_cursor(xCursor.get()))
1989 copyEntry(*xCursor);
1990 }
1991 else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing() && getBrowserView()->getVclControl()->GetSelectRowCount() < 1)
1992 {
1994 pControl->copyCellText(pControl->GetCurRow(), pControl->GetCurColumnId());
1995 }
1996 else
1998 break;
1999 }
2000}
2001
2002void SbaTableQueryBrowser::implAddDatasource( const OUString& _rDataSourceName, const SharedConnection& _rxConnection )
2003{
2004 OUString a, b, c, d, e;
2005 implAddDatasource( _rDataSourceName, a, d, b, e, c, _rxConnection );
2006}
2007
2008void SbaTableQueryBrowser::implAddDatasource(const OUString& _rDbName, OUString& _rDbImage,
2009 OUString& _rQueryName, OUString& _rQueryImage, OUString& _rTableName, OUString& _rTableImage,
2010 const SharedConnection& _rxConnection)
2011{
2012 SolarMutexGuard aGuard;
2013 // initialize the names/images if necessary
2014 if (_rQueryName.isEmpty())
2015 _rQueryName = DBA_RES(RID_STR_QUERIES_CONTAINER);
2016 if (_rTableName.isEmpty())
2017 _rTableName = DBA_RES(RID_STR_TABLES_CONTAINER);
2018
2019 if (_rQueryImage.isEmpty())
2020 _rQueryImage = ImageProvider::getFolderImageId(DatabaseObject::QUERY);
2021 if (_rTableImage.isEmpty())
2022 _rTableImage = ImageProvider::getFolderImageId(DatabaseObject::TABLE);
2023
2024 if (_rDbImage.isEmpty())
2025 _rDbImage = ImageProvider::getDatabaseImage();
2026
2027 // add the entry for the data source
2028 // special handling for data sources denoted by URLs - we do not want to display this ugly URL, do we?
2029 // #i33699#
2030 OUString sDSDisplayName, sDataSourceId;
2031 getDataSourceDisplayName_isURL( _rDbName, sDSDisplayName, sDataSourceId );
2032
2033 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2035 pDSData->eType = etDatasource;
2036 pDSData->sAccessor = sDataSourceId;
2037 pDSData->xConnection = _rxConnection;
2038 OUString sId(weld::toId(pDSData));
2039
2040 std::unique_ptr<weld::TreeIter> xDatasourceEntry(rTreeView.make_iterator());
2041 rTreeView.insert(nullptr, -1, &sDSDisplayName, &sId, nullptr, nullptr, false, xDatasourceEntry.get());
2042 rTreeView.set_image(*xDatasourceEntry, _rDbImage);
2043 rTreeView.set_text_emphasis(*xDatasourceEntry, false, 0);
2044
2045 // the child for the queries container
2046 {
2047 DBTreeListUserData* pQueriesData = new DBTreeListUserData;
2048 pQueriesData->eType = etQueryContainer;
2049 sId = weld::toId(pQueriesData);
2050
2051 std::unique_ptr<weld::TreeIter> xRet(rTreeView.make_iterator());
2052 rTreeView.insert(xDatasourceEntry.get(), -1, &_rQueryName, &sId,
2053 nullptr, nullptr, true /*ChildrenOnDemand*/, xRet.get());
2054 rTreeView.set_image(*xRet, _rQueryImage);
2055 rTreeView.set_text_emphasis(*xRet, false, 0);
2056 }
2057
2058 // the child for the tables container
2059 {
2060 DBTreeListUserData* pTablesData = new DBTreeListUserData;
2061 pTablesData->eType = etTableContainer;
2062 sId = weld::toId(pTablesData);
2063
2064 std::unique_ptr<weld::TreeIter> xRet(rTreeView.make_iterator());
2065 rTreeView.insert(xDatasourceEntry.get(), -1, &_rTableName, &sId,
2066 nullptr, nullptr, true /*ChildrenOnDemand*/, xRet.get());
2067 rTreeView.set_image(*xRet, _rTableImage);
2068 rTreeView.set_text_emphasis(*xRet, false, 0);
2069 }
2070}
2071
2073{
2074 if (m_xDatabaseContext.is())
2075 {
2076 OUString aDBImage, aQueriesImage, aTablesImage;
2077 OUString sQueriesName, sTablesName;
2078
2079 // fill the model with the names of the registered datasources
2080 const Sequence<OUString> aDatasourceNames = m_xDatabaseContext->getElementNames();
2081 for (const OUString& rDatasource : aDatasourceNames)
2082 implAddDatasource( rDatasource, aDBImage, sQueriesName, aQueriesImage, sTablesName, aTablesImage, SharedConnection() );
2083 }
2084}
2085
2087 const weld::TreeIter& rParent,
2088 EntryType eEntryType)
2089{
2090 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2091 rTreeView.make_unsorted();
2092
2093 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(rParent));
2094 if (pData) // don't ask if the nameaccess is already set see OnExpandEntry views and tables
2095 pData->xContainer = _xNameAccess;
2096
2097 try
2098 {
2099 const Sequence<OUString> aNames = _xNameAccess->getElementNames();
2100 for (const OUString& rName : aNames)
2101 {
2102 if( !m_pTreeView->GetEntryPosByName(rName, &rParent))
2103 {
2104 DBTreeListUserData* pEntryData = new DBTreeListUserData;
2105 pEntryData->eType = eEntryType;
2106 if ( eEntryType == etQuery )
2107 {
2108 Reference<XNameAccess> xChild(_xNameAccess->getByName(rName),UNO_QUERY);
2109 if ( xChild.is() )
2110 pEntryData->eType = etQueryContainer;
2111 }
2112 implAppendEntry(&rParent, rName, pEntryData);
2113 }
2114 }
2115 }
2116 catch(const Exception&)
2117 {
2118 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::populateTree: could not fill the tree");
2119 }
2120
2121 rTreeView.make_sorted();
2122}
2123
2124std::unique_ptr<weld::TreeIter> SbaTableQueryBrowser::implAppendEntry(const weld::TreeIter* pParent, const OUString& rName, const DBTreeListUserData* pUserData)
2125{
2126 EntryType eEntryType = pUserData->eType;
2127
2128 std::unique_ptr<ImageProvider> xImageProvider(getImageProviderFor(pParent));
2129
2130 OUString aImage = xImageProvider->getImageId(rName, getDatabaseObjectType(eEntryType));
2131
2132 OUString sId(weld::toId(pUserData));
2133 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2134 std::unique_ptr<weld::TreeIter> xNewEntry(rTreeView.make_iterator());
2135 rTreeView.insert(pParent, -1, &rName, &sId, nullptr, nullptr, eEntryType == etQueryContainer, xNewEntry.get());
2136 rTreeView.set_image(*xNewEntry, aImage);
2137 rTreeView.set_text_emphasis(*xNewEntry, false, 0);
2138
2139 return xNewEntry;
2140}
2141
2142IMPL_LINK(SbaTableQueryBrowser, OnExpandEntry, const weld::TreeIter&, rParent, bool)
2143{
2144 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2145 if (rTreeView.iter_has_child(rParent))
2146 {
2147 // nothing to do...
2148 return true;
2149 }
2150
2151 std::unique_ptr<weld::TreeIter> xFirstParent = m_pTreeView->GetRootLevelParent(&rParent);
2152 OSL_ENSURE(xFirstParent,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!");
2153
2154 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(rParent));
2155 assert(pData && "SbaTableQueryBrowser::OnExpandEntry: No user data!");
2156
2157 if (etTableContainer == pData->eType)
2158 {
2159 weld::WaitObject aWaitCursor(getFrameWeld());
2160
2161 // it could be that we already have a connection
2162 SharedConnection xConnection;
2163 ensureConnection(xFirstParent.get(), xConnection);
2164
2165 if ( xConnection.is() )
2166 {
2167 SQLExceptionInfo aInfo;
2168 try
2169 {
2170 Reference< XWarningsSupplier > xWarnings(xConnection, UNO_QUERY);
2171 if (xWarnings.is())
2172 xWarnings->clearWarnings();
2173
2174 // first insert the views because the tables can also include
2175 // views but that time the bitmap is the wrong one
2176 // the nameaccess will be overwritten in populateTree
2177 Reference<XViewsSupplier> xViewSup(xConnection,UNO_QUERY);
2178 if(xViewSup.is())
2179 populateTree( xViewSup->getViews(), rParent, etTableOrView );
2180
2181 Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY);
2182 if(xTabSup.is())
2183 {
2184 populateTree( xTabSup->getTables(), rParent, etTableOrView );
2185 Reference<XContainer> xCont(xTabSup->getTables(),UNO_QUERY);
2186 if(xCont.is())
2187 // add as listener to know when elements are inserted or removed
2188 xCont->addContainerListener(this);
2189 }
2190
2191 if (xWarnings.is())
2192 {
2193#if 0
2194 SQLExceptionInfo aWarnings(xWarnings->getWarnings());
2195// Obviously this if test is always false. So to avoid a Clang warning
2196// "use of logical '&&' with constant operand" I put this in #if
2197// 0. Yeah, I know it is fairly likely nobody will ever read this
2198// comment and make a decision what to do here, so I could as well
2199// have just binned this...
2200 if (aWarnings.isValid() && sal_False)
2201 {
2202 SQLContext aContext;
2203 aContext.Message = DBA_RES(STR_OPENTABLES_WARNINGS);
2204 aContext.Details = DBA_RES(STR_OPENTABLES_WARNINGS_DETAILS);
2205 aContext.NextException = aWarnings.get();
2206 aWarnings = aContext;
2207 showError(aWarnings);
2208 }
2209#endif
2210 // TODO: we need a better concept for these warnings:
2211 // something like "don't show any warnings for this datasource, again" would be nice
2212 // But this requires an extension of the InteractionHandler and an additional property on the data source
2213 }
2214 }
2215 catch(const SQLContext& e) { aInfo = e; }
2216 catch(const SQLWarning& e) { aInfo = e; }
2217 catch(const SQLException& e) { aInfo = e; }
2218 catch(const WrappedTargetException& e)
2219 {
2220 SQLException aSql;
2221 if(e.TargetException >>= aSql)
2222 aInfo = aSql;
2223 else
2224 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnExpandEntry: something strange happened!");
2225 }
2226 catch( const Exception& )
2227 {
2228 DBG_UNHANDLED_EXCEPTION("dbaccess");
2229 }
2230 if (aInfo.isValid())
2231 showError(aInfo);
2232 }
2233 else
2234 return false;
2235 // 0 indicates that an error occurred
2236 }
2237 else
2238 {
2239 // we have to expand the queries or bookmarks
2240 if (ensureEntryObject(rParent))
2241 {
2242 DBTreeListUserData* pParentData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(rParent));
2243 Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY );
2244 populateTree(xCollection, rParent, etQuery);
2245 }
2246 }
2247 return true;
2248}
2249
2251{
2252 EntryType eType = getEntryType(rEntry);
2253
2254 // the user data of the entry
2255 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2256 DBTreeListUserData* pEntryData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(rEntry));
2257 OSL_ENSURE(pEntryData,"ensureEntryObject: user data should already be set!");
2258
2259 std::unique_ptr<weld::TreeIter> xDataSourceEntry = m_pTreeView->GetRootLevelParent(&rEntry);
2260
2261 bool bSuccess = false;
2262 switch (eType)
2263 {
2264 case etQueryContainer:
2265 {
2266 if ( pEntryData->xContainer.is() )
2267 {
2268 // nothing to do
2269 bSuccess = true;
2270 break;
2271 }
2272
2273 std::unique_ptr<weld::TreeIter> xParent(rTreeView.make_iterator(&rEntry));
2274 if (rTreeView.iter_parent(*xParent))
2275 {
2276 if (rTreeView.iter_compare(*xParent, *xDataSourceEntry) != 0)
2277 {
2278 OUString aName(rTreeView.get_text(rEntry));
2279 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xParent));
2280 try
2281 {
2282 Reference< XNameAccess > xNameAccess(pData->xContainer,UNO_QUERY);
2283 if ( xNameAccess.is() )
2284 pEntryData->xContainer.set(xNameAccess->getByName(aName),UNO_QUERY);
2285 }
2286 catch(const Exception& )
2287 {
2288 DBG_UNHANDLED_EXCEPTION("dbaccess");
2289 }
2290
2291 bSuccess = pEntryData->xContainer.is();
2292 }
2293 else
2294 {
2295 try
2296 {
2298 m_xDatabaseContext->getByName(getDataSourceAccessor(*xDataSourceEntry)) >>= xQuerySup;
2299 if (xQuerySup.is())
2300 {
2301 Reference< XNameAccess > xQueryDefs = xQuerySup->getQueryDefinitions();
2302 Reference< XContainer > xCont(xQueryDefs, UNO_QUERY);
2303 if (xCont.is())
2304 // add as listener to get notified if elements are inserted or removed
2305 xCont->addContainerListener(this);
2306
2307 pEntryData->xContainer = xQueryDefs;
2308 bSuccess = pEntryData->xContainer.is();
2309 }
2310 else {
2311 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::ensureEntryObject: no XQueryDefinitionsSupplier interface!");
2312 }
2313 }
2314 catch( const Exception& )
2315 {
2316 DBG_UNHANDLED_EXCEPTION("dbaccess");
2317 }
2318 }
2319 }
2320 break;
2321 }
2322 default:
2323 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::ensureEntryObject: ooops ... missing some implementation here!");
2324 // TODO ...
2325 break;
2326 }
2327 return bSuccess;
2328}
2329
2330bool SbaTableQueryBrowser::implSelect(const svx::ODataAccessDescriptor& _rDescriptor, bool _bSelectDirect)
2331{
2332 // extract the props
2333 OUString sDataSource;
2334 OUString sCommand;
2335 sal_Int32 nCommandType = CommandType::COMMAND;
2336 bool bEscapeProcessing = true;
2337 extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing);
2338
2339 // select it
2340 return implSelect( sDataSource, sCommand, nCommandType, bEscapeProcessing, SharedConnection(), _bSelectDirect );
2341}
2342
2343bool SbaTableQueryBrowser::implLoadAnything(const OUString& _rDataSourceName, const OUString& _rCommand,
2344 const sal_Int32 nCommandType, const bool _bEscapeProcessing, const SharedConnection& _rxConnection)
2345{
2346 try
2347 {
2348 Reference<XPropertySet> xProp( getRowSet(), UNO_QUERY_THROW );
2349 Reference< XLoadable > xLoadable( xProp, UNO_QUERY_THROW );
2350 // the values allowing the RowSet to re-execute
2351 xProp->setPropertyValue(PROPERTY_DATASOURCENAME, Any(_rDataSourceName));
2352 if(_rxConnection.is())
2353 xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, Any( _rxConnection.getTyped() ) );
2354
2355 // set this _before_ setting the connection, else the rowset would rebuild it ...
2356 xProp->setPropertyValue(PROPERTY_COMMAND_TYPE, Any(nCommandType));
2357 xProp->setPropertyValue(PROPERTY_COMMAND, Any(_rCommand));
2358 xProp->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, css::uno::Any(_bEscapeProcessing));
2359 if ( m_bPreview )
2360 {
2361 xProp->setPropertyValue(PROPERTY_FETCHDIRECTION, Any(FetchDirection::FORWARD));
2362 }
2363
2364 // the formatter depends on the data source we're working on, so rebuild it here ...
2365 initFormatter();
2366
2367 // switch the grid to design mode while loading
2368 getBrowserView()->getGridControl()->setDesignMode(true);
2369 InitializeForm( xProp );
2370
2371 bool bSuccess = true;
2372
2373 {
2374 {
2375 Reference< XNameContainer > xColContainer(getFormComponent(), UNO_QUERY);
2376 // first we have to clear the grid
2377 clearGridColumns(xColContainer);
2378 }
2380 // load the form
2381 bSuccess = reloadForm(xLoadable);
2382
2383 // initialize the model
2385
2386 Any aVal = xProp->getPropertyValue(PROPERTY_ISNEW);
2387 if (aVal.hasValue() && ::comphelper::getBOOL(aVal))
2388 {
2389 // then set the default values and the parameters given from the parent
2390 Reference< XReset> xReset(xProp, UNO_QUERY);
2391 xReset->reset();
2392 }
2393
2394 if ( m_bPreview )
2396
2397 LoadFinished(true);
2398 }
2399
2400 InvalidateAll();
2401 return bSuccess;
2402 }
2403 catch( const SQLException& )
2404 {
2405 Any aException( ::cppu::getCaughtException() );
2406 showError( SQLExceptionInfo( aException ) );
2407 }
2408 catch( const WrappedTargetException& e )
2409 {
2410 if ( e.TargetException.isExtractableTo( ::cppu::UnoType< SQLException >::get() ) )
2411 showError( SQLExceptionInfo( e.TargetException ) );
2412 else
2413 {
2414 TOOLS_WARN_EXCEPTION("dbaccess", "");
2415 }
2416 }
2417 catch(const Exception&)
2418 {
2419 DBG_UNHANDLED_EXCEPTION("dbaccess");
2420 }
2421
2422 InvalidateAll();
2423 return false;
2424}
2425
2426bool SbaTableQueryBrowser::implSelect(const OUString& _rDataSourceName, const OUString& _rCommand,
2427 const sal_Int32 nCommandType, const bool _bEscapeProcessing,
2428 const SharedConnection& _rxConnection,
2429 bool _bSelectDirect)
2430{
2431 if (!_rDataSourceName.getLength() || !_rCommand.getLength() || (-1 == nCommandType))
2432 return false;
2433
2434 std::unique_ptr<weld::TreeIter> xDataSource;
2435 std::unique_ptr<weld::TreeIter> xCommandType;
2436 std::unique_ptr<weld::TreeIter> xCommand = getObjectEntry( _rDataSourceName, _rCommand, nCommandType, &xDataSource, &xCommandType, true, _rxConnection );
2437
2438 if (xCommand)
2439 {
2440 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2441
2442 bool bSuccess = true;
2443 if ( _bSelectDirect )
2444 {
2445 bSuccess = implSelect(xCommand.get());
2446 }
2447 else
2448 {
2449 rTreeView.select(*xCommand);
2450 }
2451
2452 if ( bSuccess )
2453 {
2454 rTreeView.scroll_to_row(*xCommand);
2455 rTreeView.set_cursor(*xCommand);
2456 }
2457 }
2458 else if (!xCommandType)
2459 {
2461 {
2462 // tell the old entry (if any) it has been deselected
2463 selectPath(m_xCurrentlyDisplayed.get(), false);
2464 m_xCurrentlyDisplayed.reset();
2465 }
2466
2467 // we have a command and need to display this in the rowset
2468 return implLoadAnything(_rDataSourceName, _rCommand, nCommandType, _bEscapeProcessing, _rxConnection);
2469 }
2470 return false;
2471}
2472
2474{
2475 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2476 std::unique_ptr<weld::TreeIter> xSelection(rTreeView.make_iterator());
2477 if (!rTreeView.get_selected(xSelection.get()))
2478 xSelection.reset();
2479 implSelect(xSelection.get());
2480}
2481
2482std::unique_ptr<weld::TreeIter> SbaTableQueryBrowser::implGetConnectionEntry(const weld::TreeIter& rEntry) const
2483{
2484 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2485 std::unique_ptr<weld::TreeIter> xCurrentEntry(rTreeView.make_iterator(&rEntry));
2486 DBTreeListUserData* pEntryData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xCurrentEntry));
2487 while (pEntryData->eType != etDatasource)
2488 {
2489 rTreeView.iter_parent(*xCurrentEntry);
2490 pEntryData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xCurrentEntry));
2491 }
2492 return xCurrentEntry;
2493}
2494
2496{
2497 if ( !pEntry )
2498 return false;
2499
2500 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2501 DBTreeListUserData* pEntryData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*pEntry));
2502 switch (pEntryData->eType)
2503 {
2504 case etTableOrView:
2505 case etQuery:
2506 break;
2507 default:
2508 // nothing to do
2509 return false;
2510 }
2511
2512 OSL_ENSURE(rTreeView.get_iter_depth(*pEntry) >= 2, "SbaTableQueryBrowser::implSelect: invalid entry!");
2513
2514 // get the entry for the tables or queries
2515 std::unique_ptr<weld::TreeIter> xContainer = rTreeView.make_iterator(pEntry);
2516 rTreeView.iter_parent(*xContainer);
2517 DBTreeListUserData* pContainerData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xContainer));
2518
2519 // get the entry for the datasource
2520 std::unique_ptr<weld::TreeIter> xConnection = implGetConnectionEntry(*xContainer);
2521 DBTreeListUserData* pConData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xConnection));
2522
2523 // reinitialize the rowset
2524 // but first check if it is necessary
2525 // get all old properties
2526 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
2527 OUString aOldName;
2528 xRowSetProps->getPropertyValue(PROPERTY_COMMAND) >>= aOldName;
2529 sal_Int32 nOldType = 0;
2530 xRowSetProps->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nOldType;
2531 Reference<XConnection> xOldConnection(xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY);
2532
2533 // the name of the table or query
2534 const OUString sSimpleName = rTreeView.get_text(*pEntry);
2535 OUStringBuffer sNameBuffer(sSimpleName);
2536 if ( etQueryContainer == pContainerData->eType )
2537 {
2538 std::unique_ptr<weld::TreeIter> xTemp = rTreeView.make_iterator(xContainer.get());
2539 std::unique_ptr<weld::TreeIter> xNextTemp = rTreeView.make_iterator(xTemp.get());
2540 if (rTreeView.iter_parent(*xNextTemp))
2541 {
2542 while (rTreeView.iter_compare(*xNextTemp, *xConnection) != 0)
2543 {
2544 sNameBuffer.insert(0, rTreeView.get_text(*xTemp) + "/");
2545 rTreeView.copy_iterator(*xNextTemp, *xTemp);
2546 if (!rTreeView.iter_parent(*xNextTemp))
2547 break;
2548 }
2549 }
2550 }
2551 OUString aName = sNameBuffer.makeStringAndClear();
2552
2553 sal_Int32 nCommandType = ( etTableContainer == pContainerData->eType)
2556
2557 // check if need to rebuild the rowset
2558 bool bRebuild = ( xOldConnection != pConData->xConnection )
2559 || ( nOldType != nCommandType )
2560 || ( aName != aOldName );
2561
2563 bRebuild |= !xLoadable->isLoaded();
2564 bool bSuccess = true;
2565 if ( bRebuild )
2566 {
2567 try
2568 {
2569 weld::WaitObject aWaitCursor(getFrameWeld());
2570
2571 // tell the old entry it has been deselected
2572 selectPath(m_xCurrentlyDisplayed.get(), false);
2573 m_xCurrentlyDisplayed.reset();
2574
2575 // not really loaded
2576 m_xCurrentlyDisplayed = rTreeView.make_iterator(pEntry);
2577 // tell the new entry it has been selected
2579
2580 // get the name of the data source currently selected
2582
2583 if ( !pConData->xConnection.is() )
2584 {
2585 unloadAndCleanup( false );
2586 return false;
2587 }
2588
2589 Reference<XNameAccess> xNameAccess;
2590 switch(nCommandType)
2591 {
2592 case CommandType::TABLE:
2593 {
2594 // only for tables
2595 if ( !pContainerData->xContainer.is() )
2596 {
2597 Reference<XTablesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2598 if(xSup.is())
2599 xNameAccess = xSup->getTables();
2600
2601 pContainerData->xContainer = xNameAccess;
2602 }
2603 else
2604 xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2605 }
2606 break;
2607 case CommandType::QUERY:
2608 {
2609 if ( pContainerData->xContainer.is() )
2610 xNameAccess.set( pContainerData->xContainer, UNO_QUERY );
2611 else
2612 {
2613 Reference<XQueriesSupplier> xSup( pConData->xConnection, UNO_QUERY );
2614 if(xSup.is())
2615 xNameAccess = xSup->getQueries();
2616 }
2617 }
2618 break;
2619 }
2620 OUString sStatus(DBA_RES(CommandType::TABLE == nCommandType ? STR_LOADING_TABLE : STR_LOADING_QUERY));
2621 sStatus = sStatus.replaceFirst("$name$", aName);
2622 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sStatus);
2623
2624 bool bEscapeProcessing = true;
2625 if(xNameAccess.is() && xNameAccess->hasByName(sSimpleName))
2626 {
2627 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*pEntry));
2628 if ( !pData->xObjectProperties.is() )
2629 {
2630 Reference<XInterface> xObject;
2631 if(xNameAccess->getByName(sSimpleName) >>= xObject) // remember the table or query object
2632 {
2633 pData->xObjectProperties.set(xObject, css::uno::UNO_QUERY);
2634 // if the query contains a parameterized statement and preview is enabled we won't get any data.
2635 if ( nCommandType == CommandType::QUERY && xObject.is() )
2636 {
2637 Reference<XPropertySet> xObjectProps(xObject,UNO_QUERY);
2638 xObjectProps->getPropertyValue(PROPERTY_ESCAPE_PROCESSING) >>= bEscapeProcessing;
2639 if ( m_bPreview )
2640 {
2641 OUString sSql;
2642 xObjectProps->getPropertyValue(PROPERTY_COMMAND) >>= sSql;
2644 if (xFactory.is())
2645 {
2646 try
2647 {
2649 if ( xAnalyzer.is() )
2650 {
2651 xAnalyzer->setQuery(sSql);
2652 Reference<XParametersSupplier> xParSup(xAnalyzer,UNO_QUERY);
2653 if ( xParSup->getParameters()->getCount() > 0 )
2654 {
2655 OUString sFilter = " WHERE " + xAnalyzer->getFilter();
2656 OUString sReplace = sSql.replaceFirst(sFilter, "");
2657 xAnalyzer->setQuery(sReplace);
2658 Reference<XSingleSelectQueryComposer> xComposer(xAnalyzer,UNO_QUERY);
2659 xComposer->setFilter("0=1");
2660 aName = xAnalyzer->getQuery();
2661 nCommandType = CommandType::COMMAND;
2662 }
2663 }
2664 }
2665 catch (Exception&)
2666 {
2667 DBG_UNHANDLED_EXCEPTION("dbaccess");
2668 }
2669 }
2670 }
2671 }
2672 }
2673 }
2674 }
2675
2676 OUString sDataSourceName(getDataSourceAccessor(*xConnection));
2677 bSuccess = implLoadAnything( sDataSourceName, aName, nCommandType, bEscapeProcessing, pConData->xConnection );
2678 if ( !bSuccess )
2679 { // clean up
2680 criticalFail();
2681 }
2682 }
2683 catch(const SQLException& e)
2684 {
2686 // reset the values
2687 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2688 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2689 bSuccess = false;
2690 }
2691 catch(WrappedTargetException& e)
2692 {
2693 SQLException aSql;
2694 if(e.TargetException >>= aSql)
2696 else
2697 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::implSelect: something strange happened!");
2698 // reset the values
2699 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2700 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2701 bSuccess = false;
2702 }
2703 catch(const Exception&)
2704 {
2705 // reset the values
2706 xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any());
2707 xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any());
2708 bSuccess = false;
2709 }
2710 }
2711 return bSuccess;
2712}
2713
2714std::unique_ptr<weld::TreeIter> SbaTableQueryBrowser::getEntryFromContainer(const Reference<XNameAccess>& rxNameAccess)
2715{
2716 std::unique_ptr<weld::TreeIter> xContainer;
2717
2718 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2719 std::unique_ptr<weld::TreeIter> xDSLoop(rTreeView.make_iterator(xContainer.get()));
2720 if (rTreeView.get_iter_first(*xDSLoop))
2721 {
2722 do
2723 {
2724 xContainer = rTreeView.make_iterator(xDSLoop.get());
2725 if (rTreeView.iter_children(*xContainer))
2726 {
2727 // 1st child is queries
2728 DBTreeListUserData* pQueriesData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xContainer));
2729 if (pQueriesData && pQueriesData->xContainer == rxNameAccess)
2730 break;
2731
2732 if (rTreeView.iter_next_sibling(*xContainer))
2733 {
2734 // 2nd child is tables
2735 DBTreeListUserData* pTablesData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xContainer));
2736 if (pTablesData && pTablesData->xContainer == rxNameAccess)
2737 break;
2738 }
2739 }
2740 xContainer.reset();
2741 }
2742 while (rTreeView.iter_next_sibling(*xDSLoop));
2743 }
2744
2745 return xContainer;
2746}
2747
2748void SAL_CALL SbaTableQueryBrowser::elementInserted(const ContainerEvent& rEvent)
2749{
2750 SolarMutexGuard aSolarGuard;
2751
2752 Reference< XNameAccess > xNames(rEvent.Source, UNO_QUERY);
2753 // first search for a definition container where we can insert this element
2754
2755 std::unique_ptr<weld::TreeIter> xEntry = getEntryFromContainer(xNames);
2756 if (xEntry) // found one
2757 {
2758 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2759 rTreeView.make_unsorted();
2760
2761 // insert the new entry into the tree
2762 DBTreeListUserData* pContainerData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xEntry));
2763 OSL_ENSURE(pContainerData, "elementInserted: There must be user data for this type!");
2764
2765 DBTreeListUserData* pNewData = new DBTreeListUserData;
2766 bool bIsTable = etTableContainer == pContainerData->eType;
2767 if ( bIsTable )
2768 {
2769 rEvent.Element >>= pNewData->xObjectProperties;// remember the new element
2770 pNewData->eType = etTableOrView;
2771 }
2772 else
2773 {
2774 if (rTreeView.iter_n_children(*xEntry) < xNames->getElementNames().getLength() - 1)
2775 {
2776 // the item inserts its children on demand, but it has not been expanded yet. So ensure here and
2777 // now that it has all items
2778 populateTree(xNames, *xEntry, etQuery);
2779 }
2780 pNewData->eType = etQuery;
2781 }
2782 implAppendEntry(xEntry.get(), ::comphelper::getString(rEvent.Accessor), pNewData);
2783
2784 rTreeView.make_sorted();
2785 }
2786 else
2788}
2789
2790bool SbaTableQueryBrowser::isCurrentlyDisplayedChanged(std::u16string_view rName, const weld::TreeIter& rContainer)
2791{
2793 return false;
2794 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2795 if (getEntryType(*m_xCurrentlyDisplayed) != getChildType(rContainer))
2796 return false;
2797 if (rTreeView.get_text(*m_xCurrentlyDisplayed) != rName)
2798 return false;
2799 std::unique_ptr<weld::TreeIter> xParent = rTreeView.make_iterator(m_xCurrentlyDisplayed.get());
2800 return rTreeView.iter_parent(*xParent) && rTreeView.iter_compare(*xParent, rContainer) == 0;
2801}
2802
2803void SAL_CALL SbaTableQueryBrowser::elementRemoved( const ContainerEvent& _rEvent )
2804{
2805 SolarMutexGuard aSolarGuard;
2806
2807 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2808 // get the top-level representing the removed data source
2809 // and search for the queries and tables
2810 std::unique_ptr<weld::TreeIter> xContainer = getEntryFromContainer(xNames);
2811 if (xContainer)
2812 {
2813 // a query or table has been removed
2814 OUString aName = ::comphelper::getString(_rEvent.Accessor);
2815
2816 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2817 if (isCurrentlyDisplayedChanged(aName, *xContainer))
2818 {
2819 // the element displayed currently has been replaced
2820
2821 // we need to remember the old value
2822 std::unique_ptr<weld::TreeIter> xTemp = rTreeView.make_iterator(m_xCurrentlyDisplayed.get());
2823
2824 // unload
2825 unloadAndCleanup( false ); // don't dispose the connection
2826
2827 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xTemp));
2828 rTreeView.set_id(*xTemp, OUString());
2829 delete pData; // the data could be null because we have a table which isn't correct
2830 rTreeView.remove(*xTemp);
2831 }
2832 else
2833 {
2834 // remove the entry from the model
2835 std::unique_ptr<weld::TreeIter> xChild(rTreeView.make_iterator(xContainer.get()));
2836 if (rTreeView.get_iter_first(*xChild))
2837 {
2838 do
2839 {
2840 if (rTreeView.get_text(*xChild) == aName)
2841 {
2842 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xChild));
2843 rTreeView.set_id(*xChild, OUString());
2844 delete pData;
2845 rTreeView.remove(*xChild);
2846 break;
2847 }
2848 } while (rTreeView.iter_next_sibling(*xChild));
2849 }
2850 }
2851
2852 // maybe the object which is part of the document data source has been removed
2854 }
2855 else
2857}
2858
2859void SAL_CALL SbaTableQueryBrowser::elementReplaced( const ContainerEvent& _rEvent )
2860{
2861 SolarMutexGuard aSolarGuard;
2862
2863 Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY);
2864 std::unique_ptr<weld::TreeIter> xContainer = getEntryFromContainer(xNames);
2865 if (xContainer)
2866 {
2867 // a table or query as been replaced
2868 OUString aName = ::comphelper::getString(_rEvent.Accessor);
2869
2870 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2871 if (isCurrentlyDisplayedChanged(aName, *xContainer))
2872 { // the element displayed currently has been replaced
2873
2874 // we need to remember the old value
2875 std::unique_ptr<weld::TreeIter> xTemp = rTreeView.make_iterator(m_xCurrentlyDisplayed.get());
2876 unloadAndCleanup( false ); // don't dispose the connection
2877
2878 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xTemp));
2879 if (pData)
2880 {
2881 if ( etTableOrView == pData->eType )
2882 {
2883 // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2884 _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2885 }
2886 else
2887 {
2888 rTreeView.set_id(*xTemp, OUString());
2889 delete pData;
2890 }
2891 }
2892 }
2893 else
2894 {
2895 // find the entry for this name
2896 std::unique_ptr<weld::TreeIter> xChild(rTreeView.make_iterator(xContainer.get()));
2897 if (rTreeView.get_iter_first(*xChild))
2898 {
2899 do
2900 {
2901 if (rTreeView.get_text(*xChild) == aName)
2902 {
2903 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xChild));
2904 if (pData)
2905 {
2906 if ( etTableOrView == pData->eType )
2907 {
2908 // only insert userdata when we have a table because the query is only a commanddefinition object and not a query
2909 _rEvent.Element >>= pData->xObjectProperties; // remember the new element
2910 }
2911 else
2912 {
2913 rTreeView.set_id(*xChild, OUString());
2914 delete pData;
2915 }
2916 }
2917 break;
2918 }
2919 } while (rTreeView.iter_next_sibling(*xChild));
2920 }
2921 }
2922
2923 // maybe the object which is part of the document data source has been removed
2925 }
2926 else if (xNames.get() == m_xDatabaseContext.get())
2927 { // a datasource has been replaced in the context
2928 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::elementReplaced: no support for replaced data sources!");
2929 // very suspicious: the database context should not allow to replace data source, only to register
2930 // and revoke them
2931 }
2932 else
2934}
2935
2937{
2938 // remove as event listener
2939 Reference< XComponent > xComponent( _rxConnection, UNO_QUERY );
2940 if ( xComponent.is() )
2941 {
2942 Reference< XEventListener > xListener( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY );
2943 xComponent->removeEventListener( xListener );
2944 }
2945
2946 try
2947 {
2948 // temporary (hopefully!) hack for #i55274#
2949 Reference< XFlushable > xFlush( _rxConnection, UNO_QUERY );
2950 if ( xFlush.is() )
2951 xFlush->flush();
2952 }
2953 catch( const Exception& )
2954 {
2955 DBG_UNHANDLED_EXCEPTION("dbaccess");
2956 }
2957
2958 // clear
2959 _rxConnection.clear();
2960 // will implicitly dispose if we have the ownership, since xConnection is a SharedConnection
2961}
2962
2964{
2965 OSL_ENSURE( pDSEntry, "SbaTableQueryBrowser::disposeConnection: invalid entry (NULL)!" );
2966 OSL_ENSURE( impl_isDataSourceEntry( pDSEntry ), "SbaTableQueryBrowser::disposeConnection: invalid entry (not top-level)!" );
2967
2968 if (pDSEntry)
2969 {
2970 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2971 DBTreeListUserData* pTreeListData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*pDSEntry));
2972 if (pTreeListData)
2973 impl_releaseConnection(pTreeListData->xConnection);
2974 }
2975}
2976
2977void SbaTableQueryBrowser::closeConnection(const weld::TreeIter& rDSEntry, bool _bDisposeConnection)
2978{
2979 OSL_ENSURE(impl_isDataSourceEntry(&rDSEntry), "SbaTableQueryBrowser::closeConnection: invalid entry (not top-level)!");
2980
2981 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
2982
2983 // if one of the entries of the given DS is displayed currently, unload the form
2985 {
2986 std::unique_ptr<weld::TreeIter> xRoot = m_pTreeView->GetRootLevelParent(m_xCurrentlyDisplayed.get());
2987 if (rTreeView.iter_compare(*xRoot, rDSEntry) == 0)
2988 unloadAndCleanup(_bDisposeConnection);
2989 }
2990
2991 // collapse the query/table container
2992 std::unique_ptr<weld::TreeIter> xContainers(rTreeView.make_iterator(&rDSEntry));
2993 if (rTreeView.iter_children(*xContainers))
2994 {
2995 do
2996 {
2997 std::unique_ptr<weld::TreeIter> xElements(rTreeView.make_iterator(xContainers.get()));
2998 if (rTreeView.iter_children(*xElements))
2999 {
3000 rTreeView.collapse_row(*xContainers);
3001 // and delete their children (they are connection-relative)
3002 bool bElements = true;
3003 while (bElements)
3004 {
3005 std::unique_ptr<weld::TreeIter> xRemove(rTreeView.make_iterator(xElements.get()));
3006 bElements = rTreeView.iter_next_sibling(*xElements);
3007 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xRemove));
3008 rTreeView.set_id(*xRemove, OUString());
3009 delete pData;
3010 rTreeView.remove(*xRemove);
3011 }
3012 }
3013 }
3014 while (rTreeView.iter_next_sibling(*xContainers));
3015 }
3016
3017 // collapse the entry itself
3018 rTreeView.collapse_row(rDSEntry);
3019
3020 // dispose/reset the connection
3021 if ( _bDisposeConnection )
3022 disposeConnection(&rDSEntry);
3023}
3024
3025void SbaTableQueryBrowser::unloadAndCleanup( bool _bDisposeConnection )
3026{
3028 // nothing to do
3029 return;
3030
3031 std::unique_ptr<weld::TreeIter> xDSEntry = m_pTreeView->GetRootLevelParent(m_xCurrentlyDisplayed.get());
3032
3033 // de-select the path for the currently displayed table/query
3034 selectPath(m_xCurrentlyDisplayed.get(), false);
3035 m_xCurrentlyDisplayed.reset();
3036
3037 try
3038 {
3039 // get the active connection. We need to dispose it.
3040
3041 // unload the form
3042 Reference< XLoadable > xLoadable = getLoadable();
3043 if (xLoadable->isLoaded())
3044 xLoadable->unload();
3045
3046 // clear the grid control
3047 Reference< XNameContainer > xConta(getControlModel(),UNO_QUERY);
3048 clearGridColumns(xConta);
3049
3050 // dispose the connection
3051 if(_bDisposeConnection)
3052 disposeConnection(xDSEntry.get());
3053 }
3054 catch(SQLException& e)
3055 {
3057 }
3058 catch(WrappedTargetException& e)
3059 {
3060 SQLException aSql;
3061 if(e.TargetException >>= aSql)
3063 else
3064 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::unloadAndCleanup: something strange happened!");
3065 }
3066 catch(const Exception&)
3067 {
3068 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::unloadAndCleanup: could not reset the form");
3069 }
3070}
3071
3072namespace
3073{
3074 Reference< XInterface > lcl_getDataSource( const Reference< XDatabaseContext >& _rxDatabaseContext,
3075 const OUString& _rDataSourceName, const Reference< XConnection >& _rxConnection )
3076 {
3077 Reference< XDataSource > xDataSource;
3078 try
3079 {
3080 if ( !_rDataSourceName.isEmpty() && _rxDatabaseContext->hasByName( _rDataSourceName ) )
3081 xDataSource.set( _rxDatabaseContext->getByName( _rDataSourceName ), UNO_QUERY_THROW );
3082
3083 if ( !xDataSource.is() )
3084 {
3085 Reference< XChild > xConnAsChild( _rxConnection, UNO_QUERY );
3086 if ( xConnAsChild.is() )
3087 xDataSource.set( xConnAsChild->getParent(), UNO_QUERY_THROW );
3088 }
3089 }
3090 catch( const Exception& )
3091 {
3092 DBG_UNHANDLED_EXCEPTION("dbaccess");
3093 }
3094 return xDataSource;
3095 }
3096}
3097
3099{
3100 SolarMutexGuard aGuard;
3101 // doin' a lot of VCL stuff here -> lock the SolarMutex
3102
3103 // first initialize the parent
3104 SbaXDataBrowserController::impl_initialize();
3105
3106 Reference<XConnection> xForeignConnection;
3108
3109 OUString aTableName, aCatalogName, aSchemaName;
3110
3111 bool bEscapeProcessing = true;
3112 sal_Int32 nInitialDisplayCommandType = CommandType::COMMAND;
3113 OUString sInitialDataSourceName;
3114 OUString sInitialCommand;
3115
3116 const NamedValueCollection& rArguments( getInitParams() );
3117
3118 rArguments.get_ensureType( PROPERTY_DATASOURCENAME, sInitialDataSourceName );
3119 rArguments.get_ensureType( PROPERTY_COMMAND_TYPE, nInitialDisplayCommandType );
3120 rArguments.get_ensureType( PROPERTY_COMMAND, sInitialCommand );
3121 rArguments.get_ensureType( PROPERTY_ACTIVE_CONNECTION, xForeignConnection );
3122 rArguments.get_ensureType( PROPERTY_UPDATE_CATALOGNAME, aCatalogName );
3123 rArguments.get_ensureType( PROPERTY_UPDATE_SCHEMANAME, aSchemaName );
3124 rArguments.get_ensureType( PROPERTY_UPDATE_TABLENAME, aTableName );
3125 rArguments.get_ensureType( PROPERTY_ESCAPE_PROCESSING, bEscapeProcessing );
3126 rArguments.get_ensureType( "Frame", xFrame );
3128
3129 // disable the browser if either of ShowTreeViewButton (compatibility name) or EnableBrowser
3130 // is present and set to FALSE
3131 bool bDisableBrowser = !rArguments.getOrDefault( "ShowTreeViewButton", true ) // compatibility name
3132 || !rArguments.getOrDefault( PROPERTY_ENABLE_BROWSER, true );
3133 OSL_ENSURE( !rArguments.has( "ShowTreeViewButton" ),
3134 "SbaTableQueryBrowser::impl_initialize: ShowTreeViewButton is superseded by EnableBrowser!" );
3135 m_bEnableBrowser = !bDisableBrowser;
3136
3137 // hide the tree view it is disabled in general, or if the settings tell to hide it initially
3138 bool bHideTreeView = ( !m_bEnableBrowser )
3139 || !rArguments.getOrDefault( "ShowTreeView", true ) // compatibility name
3140 || !rArguments.getOrDefault( PROPERTY_SHOW_BROWSER, true );
3141 OSL_ENSURE( !rArguments.has( "ShowTreeView" ),
3142 "SbaTableQueryBrowser::impl_initialize: ShowTreeView is superseded by ShowBrowser!" );
3143
3144 if ( bHideTreeView )
3145 hideExplorer();
3146 else
3147 showExplorer();
3148
3149 if ( m_bPreview )
3150 {
3151 try
3152 {
3154 {
3155 "AlwaysShowCursor", PROPERTY_BORDER, "HasNavigationBar", "HasRecordMarker", "Tabstop"
3156 };
3157 Sequence< Any> aValues
3158 {
3159 Any(false), Any(sal_Int16(0)), Any(false), Any(false), Any(false)
3160 };
3161 Reference< XMultiPropertySet > xFormMultiSet(getFormComponent(), UNO_QUERY);
3162 if ( xFormMultiSet.is() )
3163 xFormMultiSet->setPropertyValues(aProperties, aValues);
3164 }
3165 catch(const Exception&)
3166 {
3167 DBG_UNHANDLED_EXCEPTION("dbaccess");
3168 }
3169 }
3170
3171 // are we loaded into a (sub)frame of an embedded document (i.e. a form belonging to a database
3172 // document)?
3173 bool bSubFrameOfEmbeddedDocument = false;
3174 if ( xFrame.is() )
3175 {
3176 Reference<XFramesSupplier> xSup = xFrame->getCreator();
3177 Reference<XController> xCont = xSup.is() ? xSup->getController() : Reference<XController>();
3178
3179 bSubFrameOfEmbeddedDocument = xCont.is() && ::dbtools::isEmbeddedInDatabase( xCont->getModel(), xForeignConnection );
3180 }
3181
3182 // if we have a connection at this point, it was either passed from outside, our
3183 // determined from an outer DB document. In both cases, do not dispose it later on.
3184 SharedConnection xConnection( xForeignConnection, SharedConnection::NoTakeOwnership );
3185
3186 // should we display all registered databases in the left hand side tree?
3187 // or only *one* special?
3188 bool bLimitedTreeEntries = false;
3189 // if we're part of a frame which is a secondary frame of a database document, then only
3190 // display the database for this document, not all registered ones
3191 bLimitedTreeEntries |= bSubFrameOfEmbeddedDocument;
3192 // if the tree view is not to be displayed at all, then only display the data source
3193 // which was given as initial selection
3194 bLimitedTreeEntries |= !m_bEnableBrowser;
3195
3196 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3197 rTreeView.make_unsorted();
3198
3199 if ( bLimitedTreeEntries )
3200 {
3201 if ( xConnection.is() )
3202 {
3203 startConnectionListening( xConnection );
3204
3205 // if no initial name was given, try to obtain one from the data source
3206 if ( sInitialDataSourceName.isEmpty() )
3207 {
3208 Reference< XChild > xChild( xConnection, UNO_QUERY );
3209 Reference< XPropertySet > xDataSourceProperties;
3210 if ( xChild.is() )
3211 xDataSourceProperties.set(xChild->getParent(), css::uno::UNO_QUERY);
3212 if ( xDataSourceProperties.is() )
3213 {
3214 try
3215 {
3216 OSL_VERIFY( xDataSourceProperties->getPropertyValue( PROPERTY_NAME ) >>= sInitialDataSourceName );
3217 }
3218 catch( const Exception& )
3219 {
3220 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::impl_initialize: a connection parent which does not have a 'Name'!??" );
3221 }
3222 }
3223 }
3224 }
3225
3226 implAddDatasource( sInitialDataSourceName, xConnection );
3227
3228 std::unique_ptr<weld::TreeIter> xFirst(rTreeView.make_iterator());
3229 if (rTreeView.get_iter_first(*xFirst))
3230 rTreeView.expand_row(*xFirst);
3231 }
3232 else
3234
3235 rTreeView.make_sorted();
3236
3237 if ( m_bEnableBrowser )
3238 {
3239 m_aDocScriptSupport = ::std::optional< bool >( false );
3240 }
3241 else
3242 {
3243 // we are not used as "browser", but as mere view for a single table/query/command. In particular,
3244 // there is a specific database document which we belong to.
3246 lcl_getDataSource( m_xDatabaseContext, sInitialDataSourceName, xConnection ) ), UNO_QUERY );
3247 m_aDocScriptSupport = ::std::optional< bool >( Reference< XEmbeddedScripts >( xDocument, UNO_QUERY ).is() );
3248 }
3249
3250 if ( implSelect( sInitialDataSourceName, sInitialCommand, nInitialDisplayCommandType, bEscapeProcessing, xConnection, true ) )
3251 {
3252 try
3253 {
3254 Reference< XPropertySet > xRowSetProps(getRowSet(), UNO_QUERY);
3255 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_CATALOGNAME,Any(aCatalogName));
3256 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_SCHEMANAME,Any(aSchemaName));
3257 xRowSetProps->setPropertyValue(PROPERTY_UPDATE_TABLENAME,Any(aTableName));
3258
3259 }
3260 catch(const Exception&)
3261 {
3262 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::impl_initialize: could not set the update related names!");
3263 }
3264 }
3265
3266 InvalidateAll();
3267}
3268
3270{
3271 return m_pTreeView && m_pTreeView->IsVisible();
3272}
3273
3275{
3276 if (!haveExplorer())
3277 return;
3278 if (!getBrowserView())
3279 return;
3280
3281 m_pTreeView->Hide();
3282 m_pSplitter->Hide();
3284
3285 InvalidateFeature(ID_BROWSER_EXPLORER);
3286}
3287
3289{
3290 if (haveExplorer())
3291 return;
3292
3293 if (!getBrowserView())
3294 return;
3295
3296 m_pTreeView->Show();
3297 m_pSplitter->Show();
3299
3300 InvalidateFeature(ID_BROWSER_EXPLORER);
3301}
3302
3304{
3305 std::unique_ptr<weld::TreeIter> xDSEntry = m_pTreeView->GetRootLevelParent(pAnyEntry);
3306 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3307 DBTreeListUserData* pDSData =
3308 xDSEntry
3309 ? weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xDSEntry))
3310 : nullptr;
3311
3312 return ensureConnection(xDSEntry.get(), pDSData, rConnection);
3313}
3314
3315std::unique_ptr< ImageProvider > SbaTableQueryBrowser::getImageProviderFor(const weld::TreeIter* pAnyEntry)
3316{
3317 std::unique_ptr<ImageProvider> xImageProvider(new ImageProvider);
3318 SharedConnection xConnection;
3319 if (getExistentConnectionFor(pAnyEntry, xConnection))
3320 xImageProvider.reset(new ImageProvider(xConnection));
3321 return xImageProvider;
3322}
3323
3325{
3326 std::unique_ptr<weld::TreeIter> xDSEntry = m_pTreeView->GetRootLevelParent(pAnyEntry);
3327 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3328 DBTreeListUserData* pDSData =
3329 xDSEntry
3330 ? weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xDSEntry))
3331 : nullptr;
3332 if (pDSData)
3333 rConnection = pDSData->xConnection;
3334 return rConnection.is();
3335}
3336
3338{
3339 if (!pEntry)
3340 return false;
3341 std::unique_ptr<weld::TreeIter> xRoot(m_pTreeView->GetRootLevelParent(pEntry));
3342 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3343 return rTreeView.iter_compare(*xRoot, *pEntry) == 0;
3344}
3345
3346bool SbaTableQueryBrowser::ensureConnection(const weld::TreeIter* pDSEntry, void* pDSData, SharedConnection& rConnection)
3347{
3348 OSL_ENSURE( impl_isDataSourceEntry( pDSEntry ), "SbaTableQueryBrowser::ensureConnection: this entry does not denote a data source!" );
3349 if (pDSEntry)
3350 {
3351 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3352 OUString aDSName = rTreeView.get_text(*pDSEntry);
3353
3354 DBTreeListUserData* pTreeListData = static_cast<DBTreeListUserData*>(pDSData);
3355 if ( pTreeListData )
3356 rConnection = pTreeListData->xConnection;
3357
3358 if ( !rConnection.is() && pTreeListData )
3359 {
3360 // show the "connecting to ..." status
3361 OUString sConnecting(DBA_RES(STR_CONNECTING_DATASOURCE));
3362 sConnecting = sConnecting.replaceFirst("$name$", aDSName);
3363 BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sConnecting);
3364
3365 // build a string showing context information in case of error
3366 OUString sConnectingContext(DBA_RES(STR_COULDNOTCONNECT_DATASOURCE));
3367 sConnectingContext = sConnectingContext.replaceFirst("$name$", aDSName);
3368
3369 // connect
3370 rConnection.reset(
3371 connect(getDataSourceAccessor(*pDSEntry), sConnectingContext, nullptr),
3373
3374 // remember the connection
3375 pTreeListData->xConnection = rConnection;
3376 }
3377 }
3378 return rConnection.is();
3379}
3380
3382{
3383 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3384
3385 // we want the table entry and the end so we have to do a check
3386 if (isContainer(rRHS))
3387 {
3388 // don't use getEntryType (directly or indirectly) for the LHS:
3389 // LHS is currently being inserted, so it is not "completely valid" at the moment
3390
3391 const EntryType eRight = getEntryType(rRHS);
3392 if (etTableContainer == eRight)
3393 // every other container should be placed _before_ the bookmark container
3394 return -1;
3395
3396 const OUString sLeft = rTreeView.get_text(rLHS);
3397
3399 if (DBA_RES(RID_STR_TABLES_CONTAINER) == sLeft)
3400 eLeft = etTableContainer;
3401 else if (DBA_RES(RID_STR_QUERIES_CONTAINER) == sLeft)
3402 eLeft = etQueryContainer;
3403
3404 if ( eLeft == eRight )
3405 return 0;
3406
3407 if ( ( eLeft == etTableContainer ) && ( eRight == etQueryContainer ) )
3408 return 1;
3409
3410 if ( ( eLeft == etQueryContainer ) && ( eRight == etTableContainer ) )
3411 return -1;
3412
3413 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::OnTreeEntryCompare: unexpected case!" );
3414 return 0;
3415 }
3416
3417 OUString sLeftText = rTreeView.get_text(rLHS);
3418 OUString sRightText = rTreeView.get_text(rRHS);
3419
3420 sal_Int32 nCompareResult = 0; // equal by default
3421
3422 if (m_xCollator.is())
3423 {
3424 try
3425 {
3426 nCompareResult = m_xCollator->compareString(sLeftText, sRightText);
3427 }
3428 catch(const Exception&)
3429 {
3430 }
3431 }
3432 else
3433 // default behaviour if we do not have a collator -> do the simple string compare
3434 nCompareResult = sLeftText.compareTo(sRightText);
3435
3436 return nCompareResult;
3437}
3438
3440{
3441 try
3442 {
3443 // get the desktop object
3444 Reference< XDesktop2 > xFrameLoader = Desktop::create( getORB() );
3445
3446 // the initial selection
3447 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3448 std::unique_ptr<weld::TreeIter> xTopLevelSelected(rTreeView.make_iterator(&rApplyTo));
3449
3450 while (rTreeView.get_iter_depth(*xTopLevelSelected))
3451 rTreeView.iter_parent(*xTopLevelSelected);
3452
3453 OUString sInitialSelection = getDataSourceAccessor(*xTopLevelSelected);
3454
3455 Reference< XDataSource > xDataSource( getDataSourceByName( sInitialSelection, getFrameWeld(), getORB(), nullptr ) );
3456 Reference< XModel > xDocumentModel( getDataSourceOrModel( xDataSource ), UNO_QUERY );
3457
3458 if ( xDocumentModel.is() )
3459 {
3460 Reference< XInteractionHandler2 > xInteractionHandler(
3461 InteractionHandler::createWithParent(getORB(), nullptr) );
3462
3464 aLoadArgs.put( "Model", xDocumentModel );
3465 aLoadArgs.put( "InteractionHandler", xInteractionHandler );
3466 aLoadArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
3467
3468 Sequence< PropertyValue > aLoadArgPV;
3469 aLoadArgs >>= aLoadArgPV;
3470
3471 xFrameLoader->loadComponentFromURL(
3472 xDocumentModel->getURL(),
3473 "_default",
3474 FrameSearchFlag::ALL | FrameSearchFlag::GLOBAL,
3475 aLoadArgPV
3476 );
3477 }
3478 }
3479 catch( const Exception& )
3480 {
3481 DBG_UNHANDLED_EXCEPTION("dbaccess");
3482 }
3483}
3484
3485bool SbaTableQueryBrowser::requestQuickHelp(const void* pUserData, OUString& rText) const
3486{
3487 const DBTreeListUserData* pData = static_cast<const DBTreeListUserData*>(pUserData);
3488 if (pData->eType == etDatasource && !pData->sAccessor.isEmpty())
3489 {
3491 return true;
3492 }
3493 return false;
3494}
3495
3497{
3498 return "explorer";
3499}
3500
3502{
3503 return *this;
3504}
3505
3507{
3509}
3510
3512{
3513 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3514
3515 OSL_PRECOND( &rTreeView == &rControl,
3516 "SbaTableQueryBrowser::getCurrentSelection: where does this come from?" );
3517
3518 if (&rTreeView != &rControl)
3519 return Any();
3520
3521 std::unique_ptr<weld::TreeIter> xSelected(rTreeView.make_iterator());
3522 if (!rTreeView.get_selected(xSelected.get()))
3523 return Any();
3524
3525 NamedDatabaseObject aSelectedObject;
3526 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xSelected));
3527 aSelectedObject.Type = static_cast< sal_Int32 >( pData->eType );
3528
3529 switch ( aSelectedObject.Type )
3530 {
3533 aSelectedObject.Name = rTreeView.get_text(*xSelected);
3534 break;
3535
3536 case DatabaseObjectContainer::DATA_SOURCE:
3537 case DatabaseObjectContainer::QUERIES:
3538 case DatabaseObjectContainer::TABLES:
3539 aSelectedObject.Name = getDataSourceAccessor(*xSelected);
3540 break;
3541
3542 default:
3543 SAL_WARN("dbaccess.ui", "SbaTableQueryBrowser::getCurrentSelection: invalid (unexpected) object type!" );
3544 break;
3545 }
3546
3547 return Any( aSelectedObject );
3548}
3549
3551{
3552 return m_pTreeView;
3553}
3554
3556{
3557}
3558
3559bool SbaTableQueryBrowser::implGetQuerySignature( OUString& _rCommand, bool& _bEscapeProcessing )
3560{
3561 _rCommand.clear();
3562 _bEscapeProcessing = false;
3563
3564 try
3565 {
3566 // contain the dss (data source signature) of the form
3567 OUString sDataSourceName;
3568 OUString sCommand;
3569 sal_Int32 nCommandType = CommandType::COMMAND;
3570 Reference< XPropertySet > xRowsetProps( getRowSet(), UNO_QUERY );
3571 ODataAccessDescriptor aDesc( xRowsetProps );
3572 sDataSourceName = aDesc.getDataSource();
3573 aDesc[ DataAccessDescriptorProperty::Command ] >>= sCommand;
3574 aDesc[ DataAccessDescriptorProperty::CommandType ] >>= nCommandType;
3575
3576 // do we need to do anything?
3577 if ( CommandType::QUERY != nCommandType )
3578 return false;
3579
3580 // get the query object
3582 Reference< XNameAccess > xQueries;
3584 m_xDatabaseContext->getByName( sDataSourceName ) >>= xSuppQueries;
3585 if ( xSuppQueries.is() )
3586 xQueries = xSuppQueries->getQueryDefinitions();
3587 if ( xQueries.is() )
3588 xQueries->getByName( sCommand ) >>= xQuery;
3589 OSL_ENSURE( xQuery.is(), "SbaTableQueryBrowser::implGetQuerySignature: could not retrieve the query object!" );
3590
3591 // get the two properties we need
3592 if ( xQuery.is() )
3593 {
3594 xQuery->getPropertyValue( PROPERTY_COMMAND ) >>= _rCommand;
3595 _bEscapeProcessing = ::cppu::any2bool( xQuery->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) );
3596 return true;
3597 }
3598 }
3599 catch( const Exception& )
3600 {
3601 DBG_UNHANDLED_EXCEPTION("dbaccess");
3602 }
3603
3604 return false;
3605}
3606
3607void SbaTableQueryBrowser::frameAction(const css::frame::FrameActionEvent& aEvent)
3608{
3609 if (aEvent.Frame == m_xCurrentFrameParent)
3610 {
3611 if(aEvent.Action == FrameAction_COMPONENT_DETACHING)
3613 else if (aEvent.Action == FrameAction_COMPONENT_REATTACHED)
3615 }
3616 else
3618
3619}
3620
3622{
3623 // first we have to clear the grid
3625 const Sequence<OUString> aColNames = _xColContainer->getElementNames();
3626 for (const OUString& rName : aColNames)
3627 {
3628 _xColContainer->getByName(rName) >>= xColumn;
3629 _xColContainer->removeByName(rName);
3630 ::comphelper::disposeComponent(xColumn);
3631 }
3632}
3633
3635{
3636 if ( m_bShowMenu )
3637 {
3639 }
3640 else if ( !m_bPreview )
3641 {
3642 Reference< css::frame::XLayoutManager > xLayoutManager = getLayoutManager(_xFrame);
3643
3644 if ( xLayoutManager.is() )
3645 {
3646 xLayoutManager->lock();
3647 xLayoutManager->createElement( "private:resource/toolbar/toolbar" );
3648 xLayoutManager->unlock();
3649 xLayoutManager->doLayout();
3650 }
3651 onLoadedMenu( xLayoutManager );
3652 }
3653}
3654
3656{
3657 OUString sTitle;
3659 {
3660 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3661 std::unique_ptr<weld::TreeIter> xContainer = rTreeView.make_iterator(m_xCurrentlyDisplayed.get());
3662 if (!rTreeView.iter_parent(*xContainer))
3663 return OUString();
3664 // get the entry for the datasource
3665 std::unique_ptr<weld::TreeIter> xConnection = implGetConnectionEntry(*xContainer);
3666 OUString sName = rTreeView.get_text(*m_xCurrentlyDisplayed);
3667 sTitle = GetEntryText(*xConnection);
3668 INetURLObject aURL(sTitle);
3669 if ( aURL.GetProtocol() != INetProtocol::NotValid )
3671 if ( !sName.isEmpty() )
3672 {
3673 sName += " - " + sTitle;
3674 sTitle = sName;
3675 }
3676 }
3677
3678 return sTitle;
3679}
3680
3682{
3683 bool bIni = false;
3685 {
3686 // switch the grid to design mode while loading
3687 getBrowserView()->getGridControl()->setDesignMode(true);
3688 // we had an invalid statement so we need to connect the column models
3689 Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY);
3690 svx::ODataAccessDescriptor aDesc(xRowSetProps);
3691 // extract the props
3692 OUString sDataSource;
3693 OUString sCommand;
3694 sal_Int32 nCommandType = CommandType::COMMAND;
3695 bool bEscapeProcessing = true;
3696 extractDescriptorProps(aDesc, sDataSource, sCommand, nCommandType, bEscapeProcessing);
3697 if ( !sDataSource.isEmpty() && !sCommand.isEmpty() && (-1 != nCommandType) )
3698 {
3699 m_xCurrentlyDisplayed = getObjectEntry(sDataSource, sCommand, nCommandType, nullptr, nullptr);
3700 bIni = true;
3701 }
3702 }
3703 return bIni;
3704}
3705
3707{
3709 LoadFinished(true);
3710}
3711
3713{
3714 // update our database document
3715 Reference< XModel > xDocument;
3716 try
3717 {
3718 Reference< XPropertySet > xCursorProps( getRowSet(), UNO_QUERY_THROW );
3719 Reference< XConnection > xConnection( xCursorProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY );
3720 if ( xConnection.is() )
3721 {
3722 Reference< XChild > xChild( xConnection, UNO_QUERY_THROW );
3723 Reference< XDocumentDataSource > xDataSource( xChild->getParent(), UNO_QUERY_THROW );
3724 xDocument.set( xDataSource->getDatabaseDocument(), UNO_QUERY_THROW );
3725 }
3726 }
3727 catch( const Exception& )
3728 {
3729 DBG_UNHANDLED_EXCEPTION("dbaccess");
3730 }
3731 Reference< XEmbeddedScripts > xScripts( xDocument, UNO_QUERY );
3732 OSL_ENSURE( xScripts.is() || !xDocument.is(),
3733 "SbaTableQueryBrowser::getScriptContainer: invalid database document!" );
3734 return xScripts;
3735}
3736
3738{
3739 if ( Interceptor.is() )
3741}
3742
3744{
3745 if ( Interceptor.is() )
3747}
3748
3749void SAL_CALL SbaTableQueryBrowser::registeredDatabaseLocation( const DatabaseRegistrationEvent& Event )
3750{
3751 SolarMutexGuard aGuard;
3752 implAddDatasource( Event.Name, SharedConnection() );
3753}
3754
3755void SbaTableQueryBrowser::impl_cleanupDataSourceEntry(std::u16string_view rDataSourceName)
3756{
3757 // get the top-level representing the removed data source
3758 weld::TreeView& rTreeView = m_pTreeView->GetWidget();
3759 std::unique_ptr<weld::TreeIter> xDataSourceEntry(rTreeView.make_iterator());
3760 bool bDataSourceEntry = rTreeView.get_iter_first(*xDataSourceEntry);
3761 while (bDataSourceEntry)
3762 {
3763 if (rTreeView.get_text(*xDataSourceEntry) == rDataSourceName)
3764 break;
3765 bDataSourceEntry = rTreeView.iter_next_sibling(*xDataSourceEntry);
3766 }
3767
3768 OSL_ENSURE( bDataSourceEntry, "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: do not know this data source!" );
3769 if (!bDataSourceEntry)
3770 return;
3771
3772 if (isSelected(*xDataSourceEntry))
3773 {
3774 // a table or query belonging to the deleted data source is currently being displayed.
3776 }
3777
3778 std::unique_ptr<weld::TreeIter> xChild(rTreeView.make_iterator(xDataSourceEntry.get()));
3779 if (rTreeView.iter_children(*xChild))
3780 {
3781 do
3782 {
3783 // delete any user data of the child entries of the to-be-removed entry
3784 const DBTreeListUserData* pData = weld::fromId<const DBTreeListUserData*>(rTreeView.get_id(*xChild));
3785 rTreeView.set_id(*xChild, OUString());
3786 delete pData;
3787 } while (rTreeView.iter_next_sibling(*xChild));
3788 }
3789
3790 // remove the entry
3791 DBTreeListUserData* pData = weld::fromId<DBTreeListUserData*>(rTreeView.get_id(*xDataSourceEntry));
3792 rTreeView.set_id(*xDataSourceEntry, OUString());
3793 delete pData;
3794 rTreeView.remove(*xDataSourceEntry);
3795}
3796
3797void SAL_CALL SbaTableQueryBrowser::revokedDatabaseLocation( const DatabaseRegistrationEvent& Event )
3798{
3799 SolarMutexGuard aGuard;
3800
3801 impl_cleanupDataSourceEntry( Event.Name );
3802
3803 // maybe the object which is part of the document data source has been removed
3805}
3806
3807void SAL_CALL SbaTableQueryBrowser::changedDatabaseLocation( const DatabaseRegistrationEvent& Event )
3808{
3809 SolarMutexGuard aGuard;
3810
3811 // in case the data source was expanded, and connected, we need to clean it up
3812 // for simplicity, just do as if the data source were completely removed and re-added
3813 impl_cleanupDataSourceEntry( Event.Name );
3814 implAddDatasource( Event.Name, SharedConnection() );
3815}
3816
3817} // namespace dbaui
3818
3819/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sName
PropertyValueVector_t aPropertyValues
PropertiesInfo aProperties
AnyEventRef aEvent
double d
#define ID_BROWSER_FORMLETTER
Definition: browserids.hxx:37
#define ID_TREE_ADMINISTRATE
Definition: browserids.hxx:62
#define ID_TREE_CLOSE_CONN
Definition: browserids.hxx:60
#define ID_BROWSER_INSERTCONTENT
Definition: browserids.hxx:38
#define ID_BROWSER_CLOSE
Definition: browserids.hxx:92
#define ID_BROWSER_ROWHEIGHT
Definition: browserids.hxx:52
#define ID_BROWSER_REMOVEFILTER
Definition: browserids.hxx:46
#define ID_BROWSER_REFRESH
Definition: browserids.hxx:48
#define ID_BROWSER_EXPLORER
Definition: browserids.hxx:54
#define ID_BROWSER_TABLEATTR
Definition: browserids.hxx:51
#define ID_BROWSER_DOCUMENT_DATASOURCE
Definition: browserids.hxx:55
#define ID_BROWSER_TITLE
Definition: browserids.hxx:34
#define ID_BROWSER_REFRESH_REBUILD
Definition: browserids.hxx:75
#define ID_BROWSER_INSERTCOLUMNS
Definition: browserids.hxx:36
#define ID_BROWSER_COPY
Definition: browserids.hxx:24
#define ID_BROWSER_COLWIDTH
Definition: browserids.hxx:50
#define ID_BROWSER_COLATTRSET
Definition: browserids.hxx:49
#define ID_TREE_EDIT_DATABASE
Definition: browserids.hxx:59
static const AllSettings & GetSettings()
void ForceHideScrollbars()
bool canCopyCellText(sal_Int32 _nRow, sal_uInt16 _nColId)
void copyCellText(sal_Int32 _nRow, sal_uInt16 _nColId)
sal_Int32 GetSelectCount() const
sal_Int32 FirstSelected()
sal_Int32 NextSelected()
bool IsItemVisible(ToolBoxItemId nItemId) const
void ShowItem(ToolBoxItemId nItemId, bool bVisible=true)
void HideItem(ToolBoxItemId nItemId)
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
void reset(reference_type *pBody)
reference_type * get() const
static VclPtr< reference_type > Create(Arg &&... arg)
bool has(const OUString &_rValueName) const
bool get_ensureType(const OUString &_rValueName, VALUE_TYPE &_out_rValue) const
const css::uno::Any & get(const OUString &_rValueName) const
bool put(const OUString &_rValueName, const VALUE_TYPE &_rValue)
VALUE_TYPE getOrDefault(const OUString &_rValueName, const VALUE_TYPE &_rDefault) const
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
sal_Int32 addInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
css::uno::Type const & get()
virtual void Resize() override
Definition: dataview.cxx:91
virtual void loadMenu(const css::uno::Reference< css::frame::XFrame > &_xFrame)
HeaderBar * GetHeaderBar() const
Definition: sbagrid.hxx:223
bool IsAllSelected() const
Definition: sbagrid.hxx:221
virtual IController & getCommandController() override
returns the controller which is responsible for providing states of certain features,...
Definition: unodatbr.cxx:3501
css::uno::Reference< css::i18n::XCollator > m_xCollator
Definition: unodatbr.hxx:66
void transferChangedControlProperty(const OUString &_rProperty, const css::uno::Any &_rNewValue)
Definition: unodatbr.cxx:776
void clearTreeModel()
clears the tree list box
virtual void criticalFail() override
Definition: unodatbr.cxx:1565
void checkDocumentDataSource()
checks if m_aDocumentDataSource describes a known object
Definition: unodatbr.cxx:968
::comphelper::OInterfaceContainerHelper2 m_aSelectionListeners
Definition: unodatbr.hxx:87
void impl_cleanupDataSourceEntry(std::u16string_view _rDataSourceName)
removes (and cleans up) the entry for the given data source
Definition: unodatbr.cxx:3755
virtual void addModelListeners(const css::uno::Reference< css::awt::XControlModel > &_xGridControlModel) override
Definition: unodatbr.cxx:1494
svx::ODataAccessDescriptor m_aDocumentDataSource
Definition: unodatbr.hxx:84
void impl_sanitizeRowSetClauses_nothrow()
checks whether the Order/Filter clauses set at our row set are valid, removes them if not so
Definition: unodatbr.cxx:355
void InitializeGridModel(const css::uno::Reference< css::form::XFormComponent > &xGrid)
Definition: unodatbr.cxx:533
virtual void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
Definition: unodatbr.cxx:2748
void initializePreviewMode()
called whenever the content of the browser is used for preview, as the very last action of the load p...
Definition: unodatbr.cxx:516
VclPtr< Splitter > m_pSplitter
Definition: unodatbr.hxx:97
void closeConnection(const weld::TreeIter &rEntry, bool bDisposeConnection=true)
close the connection (and collapse the list entries) of the given list entries
Definition: unodatbr.cxx:2977
void populateTree(const css::uno::Reference< css::container::XNameAccess > &xNameAccess, const weld::TreeIter &rParent, EntryType eEntryType)
Definition: unodatbr.cxx:2086
css::uno::Reference< css::awt::XWindow > m_xMainToolbar
Definition: unodatbr.hxx:68
void disposeConnection(const weld::TreeIter *xpDSEntry)
Definition: unodatbr.cxx:2963
void implAdministrate(const weld::TreeIter &rApplyTo)
Definition: unodatbr.cxx:3439
EntryType getChildType(const weld::TreeIter &rEntry) const
::comphelper::OInterfaceContainerHelper2 m_aContextMenuInterceptors
Definition: unodatbr.hxx:88
virtual ~SbaTableQueryBrowser() override
Definition: unodatbr.cxx:178
bool ensureConnection(const weld::TreeIter *pDSEntry, void *pDSData, SharedConnection &rConnection)
Definition: unodatbr.cxx:3346
void selectPath(const weld::TreeIter *pEntry, bool bSelect=true)
virtual FeatureState GetState(sal_uInt16 nId) const override
Definition: unodatbr.cxx:1600
virtual bool Construct(vcl::Window *pParent) override
Definition: unodatbr.cxx:272
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unodatbr.cxx:158
void implAddDatasource(const OUString &_rDbName, OUString &_rDbImage, OUString &_rQueryName, OUString &_rQueryImage, OUString &_rTableName, OUString &_rTableImage, const SharedConnection &_rxConnection)
add an entry (including the subentries for queries/tables) to the list model
Definition: unodatbr.cxx:2008
virtual css::uno::Any SAL_CALL getSelection() override
Definition: unodatbr.cxx:1415
virtual void SAL_CALL attachFrame(const css::uno::Reference< css::frame::XFrame > &xFrame) override
Definition: unodatbr.cxx:1451
virtual void AddColumnListener(const css::uno::Reference< css::beans::XPropertySet > &xCol) override
Definition: unodatbr.cxx:1547
bool isCurrentlyDisplayedChanged(std::u16string_view rName, const weld::TreeIter &rContainer)
checks if the currently displayed entry changed
Definition: unodatbr.cxx:2790
std::unique_ptr< weld::TreeIter > getObjectEntry(const svx::ODataAccessDescriptor &rDescriptor, std::unique_ptr< weld::TreeIter > *ppDataSourceEntry, std::unique_ptr< weld::TreeIter > *ppContainerEntry)
retrieves the tree entry for the object described by <arg>_rDescriptor</arg>
Definition: unodatbr.cxx:1208
virtual sal_Bool SAL_CALL select(const css::uno::Any &aSelection) override
VclPtr< InterimDBTreeListBox > m_pTreeView
Definition: unodatbr.hxx:96
virtual void SAL_CALL disposing() override
Definition: unodatbr.cxx:232
virtual OUString getContextMenuResourceName() const override
returns the context menu resource name for the control
Definition: unodatbr.cxx:3496
virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent &Event) override
Definition: unodatbr.cxx:920
bool isEntryCopyAllowed(const weld::TreeIter &rEntry) const
int OnTreeEntryCompare(const weld::TreeIter &rLHS, const weld::TreeIter &rRHS)
Definition: unodatbr.cxx:3381
static void clearGridColumns(const css::uno::Reference< css::container::XNameContainer > &_xColContainer)
Definition: unodatbr.cxx:3621
bool getExternalSlotState(sal_uInt16 _nId) const
get the state of an external slot
Definition: unodatbr.cxx:1591
virtual void removeModelListeners(const css::uno::Reference< css::awt::XControlModel > &_xGridControlModel) override
Definition: unodatbr.cxx:1510
static sal_Int32 getDatabaseObjectType(EntryType _eType)
returns a DatabaseObject value corresponding to the given EntryType
bool ensureEntryObject(const weld::TreeIter &rEntry)
Definition: unodatbr.cxx:2250
std::unique_ptr< weld::TreeIter > getEntryFromContainer(const css::uno::Reference< css::container::XNameAccess > &rxNameAccess)
search in the tree for query- or tablecontainer equal to this interface and return this container ent...
Definition: unodatbr.cxx:2714
bool implSelect(const svx::ODataAccessDescriptor &_rDescriptor, bool _bSelectDirect=false)
Definition: unodatbr.cxx:2330
bool getExistentConnectionFor(const weld::TreeIter *pDSEntry, SharedConnection &rConnection)
Definition: unodatbr.cxx:3324
virtual sal_Bool SAL_CALL suspend(sal_Bool bSuspend) override
Definition: unodatbr.cxx:897
virtual void SAL_CALL addSelectionChangeListener(const css::uno::Reference< css::view::XSelectionChangeListener > &xListener) override
Definition: unodatbr.cxx:1441
virtual bool preReloadForm() override
Definition: unodatbr.cxx:3681
virtual bool InitializeForm(const css::uno::Reference< css::beans::XPropertySet > &i_formProperties) override
Definition: unodatbr.cxx:464
virtual void SAL_CALL changedDatabaseLocation(const css::sdb::DatabaseRegistrationEvent &Event) override
Definition: unodatbr.cxx:3807
virtual ::comphelper::OInterfaceContainerHelper2 * getContextMenuInterceptors() override
returns the container of registered context menu interceptors, or NULL if the implementation does not...
Definition: unodatbr.cxx:3506
SbaTableQueryBrowser(const css::uno::Reference< css::uno::XComponentContext > &_rM)
Definition: unodatbr.cxx:163
virtual void SAL_CALL revokedDatabaseLocation(const css::sdb::DatabaseRegistrationEvent &Event) override
Definition: unodatbr.cxx:3797
std::unique_ptr< ImageProvider > getImageProviderFor(const weld::TreeIter *pAnyEntry)
returns an image provider which works with the connection belonging to the given entry
Definition: unodatbr.cxx:3315
virtual css::uno::Reference< css::document::XEmbeddedScripts > SAL_CALL getScriptContainer() override
Definition: unodatbr.cxx:3712
void impl_releaseConnection(SharedConnection &_rxConnection)
flushes and disposes the given connection, and de-registers as listener
Definition: unodatbr.cxx:2936
bool impl_isDataSourceEntry(const weld::TreeIter *pEntry) const
Definition: unodatbr.cxx:3337
::std::optional< bool > m_aDocScriptSupport
Definition: unodatbr.hxx:106
virtual void loadMenu(const css::uno::Reference< css::frame::XFrame > &_xFrame) override
Definition: unodatbr.cxx:3634
virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
Definition: unodatbr.cxx:2803
virtual vcl::Window * getMenuParent() const override
Definition: unodatbr.cxx:3550
virtual bool requestQuickHelp(const void *pUserData, OUString &rText) const override
requests a quick help text to display
Definition: unodatbr.cxx:3485
virtual void SAL_CALL frameAction(const css::frame::FrameActionEvent &aEvent) override
Definition: unodatbr.cxx:3607
std::unique_ptr< weld::TreeIter > m_xCurrentlyDisplayed
Definition: unodatbr.hxx:98
OUString getDataSourceAccessor(const weld::TreeIter &rDataSourceEntry) const
retrieves the data source URL/name for the given entry representing a data source
Definition: unodatbr.cxx:1055
std::unique_ptr< weld::TreeIter > implGetConnectionEntry(const weld::TreeIter &rEntry) const
Definition: unodatbr.cxx:2482
css::uno::Reference< css::frame::XFrame > m_xCurrentFrameParent
Definition: unodatbr.hxx:67
OUString GetEntryText(const weld::TreeIter &rEntry) const
virtual void SAL_CALL registerContextMenuInterceptor(const css::uno::Reference< css::ui::XContextMenuInterceptor > &Interceptor) override
Definition: unodatbr.cxx:3737
static void extractDescriptorProps(const svx::ODataAccessDescriptor &_rDescriptor, OUString &_rDataSource, OUString &_rCommand, sal_Int32 &_rCommandType, bool &_rEscapeProcessing)
Definition: unodatbr.cxx:1008
virtual void SAL_CALL releaseContextMenuInterceptor(const css::uno::Reference< css::ui::XContextMenuInterceptor > &Interceptor) override
Definition: unodatbr.cxx:3743
std::unique_ptr< weld::TreeIter > implAppendEntry(const weld::TreeIter *pParent, const OUString &rName, const DBTreeListUserData *pUserData)
inserts an entry into the tree
Definition: unodatbr.cxx:2124
static bool isContainer(EntryType _eType)
Definition: unodatbr.hxx:321
virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent &evt) override
Definition: unodatbr.cxx:789
virtual void ColumnChanged() override
Definition: unodatbr.cxx:1536
virtual OUString getPrivateTitle() const override
Definition: unodatbr.cxx:3655
virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent &Event) override
Definition: unodatbr.cxx:2859
ExternalFeaturesMap m_aExternalFeatures
Definition: unodatbr.hxx:82
void copyEntry(const weld::TreeIter &rEntry)
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: unodatbr.cxx:227
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: unodatbr.cxx:208
bool implGetQuerySignature(OUString &_rCommand, bool &_bEscapeProcessing)
get the signature (command/escape processing) of the query the form is based on
Definition: unodatbr.cxx:3559
virtual OUString SAL_CALL getImplementationName() override
Definition: unodatbr.cxx:153
virtual void impl_initialize() override
Definition: unodatbr.cxx:3098
EntryType getEntryType(const weld::TreeIter &rEntry) const
virtual void postReloadForm() override
Definition: unodatbr.cxx:3706
virtual void adjustMenuPosition(const weld::TreeView &rControl, ::Point &rPos) const override
adjust rPos which is initially relative to rControl to be relative to the window of getMenuParent
Definition: unodatbr.cxx:3555
void implCheckExternalSlot(sal_uInt16 _nId)
Definition: unodatbr.cxx:1283
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &_rType) override
Definition: unodatbr.cxx:192
bool isSelected(const weld::TreeIter &rEntry) const
bool implLoadAnything(const OUString &_rDataSourceName, const OUString &_rCommand, const sal_Int32 _nCommandType, const bool _bEscapeProcessing, const SharedConnection &_rxConnection)
loads the grid control with the data object specified (which may be a table, a query or a command)
Definition: unodatbr.cxx:2343
virtual void SAL_CALL removeSelectionChangeListener(const css::uno::Reference< css::view::XSelectionChangeListener > &xListener) override
Definition: unodatbr.cxx:1446
void unloadAndCleanup(bool _bDisposeConnection=true)
unloads the form, empties the grid model, cleans up anything related to the currently displayed objec...
Definition: unodatbr.cxx:3025
virtual void Execute(sal_uInt16 nId, const css::uno::Sequence< css::beans::PropertyValue > &aArgs) override
Definition: unodatbr.cxx:1800
virtual void RowChanged() override
Definition: unodatbr.cxx:1525
virtual css::uno::Any getCurrentSelection(weld::TreeView &rControl) const override
returns the current selection in the given control
Definition: unodatbr.cxx:3511
virtual void SAL_CALL registeredDatabaseLocation(const css::sdb::DatabaseRegistrationEvent &Event) override
Definition: unodatbr.cxx:3749
virtual void RemoveColumnListener(const css::uno::Reference< css::beans::XPropertySet > &xCol) override
Definition: unodatbr.cxx:1556
virtual void LoadFinished(bool _bWasSynch) override
Definition: unodatbr.cxx:1571
const css::uno::Reference< css::form::XLoadable > & getLoadable() const
Definition: brwctrlr.hxx:122
virtual void RowChanged() override
Definition: brwctrlr.cxx:2224
virtual void RemoveColumnListener(const css::uno::Reference< css::beans::XPropertySet > &xCol)
Definition: brwctrlr.cxx:812
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: brwctrlr.cxx:478
virtual void LoadFinished(bool bWasSynch)
Definition: brwctrlr.cxx:2426
virtual void SAL_CALL frameAction(const css::frame::FrameActionEvent &aEvent) override
Definition: brwctrlr.cxx:1184
virtual void SAL_CALL disposing() override
Definition: brwctrlr.cxx:1118
const css::uno::Reference< css::form::XFormComponent > & getFormComponent() const
Definition: brwctrlr.hxx:124
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &_rType) override
Definition: brwctrlr.cxx:491
const css::uno::Reference< css::util::XNumberFormatter > & getNumberFormatter() const
Definition: brwctrlr.hxx:126
virtual sal_Bool SAL_CALL suspend(sal_Bool bSuspend) override
Definition: brwctrlr.cxx:1108
bool SaveModified(bool bAskFor=true)
Definition: brwctrlr.cxx:2148
virtual FeatureState GetState(sal_uInt16 nId) const override
Definition: brwctrlr.cxx:1346
virtual void AddColumnListener(const css::uno::Reference< css::beans::XPropertySet > &xCol)
Definition: brwctrlr.cxx:807
UnoDataBrowserView * getBrowserView() const
Definition: brwctrlr.hxx:138
const css::uno::Reference< css::sdbc::XRowSet > & getRowSet() const
Definition: brwctrlr.hxx:121
virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent &evt) override
Definition: brwctrlr.cxx:1022
virtual bool Construct(vcl::Window *pParent) override
Definition: brwctrlr.cxx:691
virtual void addModelListeners(const css::uno::Reference< css::awt::XControlModel > &_xGridControlModel)
Definition: brwctrlr.cxx:830
virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent &Event) override
Definition: brwctrlr.cxx:1095
virtual void removeModelListeners(const css::uno::Reference< css::awt::XControlModel > &_xGridControlModel)
Definition: brwctrlr.cxx:845
virtual void ColumnChanged() override
Definition: brwctrlr.cxx:2229
virtual void Execute(sal_uInt16 nId, const css::uno::Sequence< css::beans::PropertyValue > &aArgs) override
Definition: brwctrlr.cxx:1811
virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
Definition: brwctrlr.cxx:1086
css::uno::Reference< css::sdb::XSingleSelectQueryComposer > createParser_nothrow()
Definition: brwctrlr.cxx:1658
css::uno::Reference< css::awt::XControlModel > getControlModel() const
Definition: brwctrlr.hxx:125
virtual void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
Definition: brwctrlr.cxx:1077
bool reloadForm(const css::uno::Reference< css::form::XLoadable > &_rxLoadable)
loads or reloads the form
Definition: brwctrlr.cxx:594
SbaGridControl * getVclControl() const
Definition: brwview.cxx:244
const css::uno::Reference< css::awt::XControl > & getGridControl() const
Definition: brwview.hxx:51
void setSplitter(Splitter *pSplitter)
for the same reason the view column count isn't the same as the model column count
Definition: brwview.cxx:144
void setTreeView(InterimDBTreeListBox *pTreeView)
Definition: brwview.cxx:151
const css::uno::Any & get() const
OUString get(NOTATION _eOutputNotation) const
void initializeFrom(const css::uno::Sequence< css::beans::PropertyValue > &_rValues)
bool has(DataAccessDescriptorProperty _eWhich) const
OUString getDataSource() const
css::uno::Any getNodeValue(const OUString &_rPath) const noexcept
static OConfigurationTreeRoot createWithComponentContext(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, const OUString &_rPath, sal_Int32 _nDepth=-1, CREATION_MODE _eMode=CM_UPDATABLE)
const css::uno::Reference< INTERFACE > & getTyped() const
void reset(const css::uno::Reference< INTERFACE > &_rxComponent, AssignmentMode _eMode=TakeOwnership)
Point LogicToPixel(const Point &rLogicPt) const
void SetHelpId(const OUString &)
virtual void scroll_to_row(int row)=0
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const=0
virtual bool get_selected(TreeIter *pIter) const=0
virtual void make_sorted()=0
virtual void expand_row(const TreeIter &rIter)=0
virtual OUString get_text(int row, int col=-1) const=0
virtual void set_text_emphasis(int row, bool bOn, int col)=0
virtual void insert(const TreeIter *pParent, int pos, const OUString *pStr, const OUString *pId, const OUString *pIconName, VirtualDevice *pImageSurface, bool bChildrenOnDemand, TreeIter *pRet)=0
virtual int iter_n_children(const TreeIter &rIter) const=0
void connect_expanding(const Link< const TreeIter &, bool > &rLink)
virtual void set_image(int row, const OUString &rImage, int col=-1)=0
virtual bool get_iter_first(TreeIter &rIter) const=0
virtual void copy_iterator(const TreeIter &rSource, TreeIter &rDest) const=0
virtual void remove(int pos)=0
virtual bool iter_next_sibling(TreeIter &rIter) const=0
virtual void select(int pos)=0
virtual bool iter_parent(TreeIter &rIter) const=0
virtual void set_sort_func(const std::function< int(const weld::TreeIter &, const weld::TreeIter &)> &func)
virtual int iter_compare(const TreeIter &a, const TreeIter &b) const=0
virtual void collapse_row(const TreeIter &rIter)=0
virtual bool iter_children(TreeIter &rIter) const=0
virtual void set_id(int row, const OUString &rId)=0
virtual bool iter_has_child(const TreeIter &rIter) const=0
virtual bool get_cursor(TreeIter *pIter) const=0
virtual void set_cursor(int pos)=0
virtual void set_sort_order(bool bAscending)=0
virtual int get_iter_depth(const TreeIter &rIter) const=0
virtual void make_unsorted()=0
virtual OUString get_id(int pos) const=0
#define DBA_RES(id)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define ENSURE_OR_RETURN_FALSE(c, m)
#define DBG_UNHANDLED_EXCEPTION(...)
Reference< XDispatch > xDispatch
ULONG m_refCount
Any aHelper
Reference< XSingleServiceFactory > xFactory
Reference< XColumn > xColumn
sal_Int32 nNullable
TRISTATE_FALSE
TRISTATE_INDET
TRISTATE_TRUE
OUString sDisplayName
Definition: generalpage.cxx:79
OUString eType
Definition: generalpage.cxx:78
constexpr OUStringLiteral HID_CTL_TABBROWSER
Definition: helpids.h:26
constexpr OUStringLiteral HID_DATABROWSE_HEADER
Definition: helpids.h:25
constexpr OUStringLiteral HID_CTL_TREEVIEW
Definition: helpids.h:27
URL aURL
Definition: intercept.cxx:87
Reference< XNameAccess > _xNameAccess
sal_Int32 nIndex
OUString aName
uno_Any a
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
#define SFX_ENDOFSELECTION
@ Exception
const LanguageTag & getLocale()
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
OUString getString(const Any &_rAny)
Type
IMPL_LINK_NOARG(OApplicationController, OnClipboardChanged, TransferableDataHelper *, void)
css::uno::Reference< css::sdbc::XDataSource > getDataSourceByName(const OUString &_rDataSourceName, weld::Window *_pErrorMessageParent, const css::uno::Reference< css::uno::XComponentContext > &_rxContext, ::dbtools::SQLExceptionInfo *_pErrorInfo)
retrieves a data source given by name or URL, and displays an error if this fails
IMPL_LINK(OApplicationController, OnSelectContainer, void *, _pType, void)
css::uno::Reference< css::uno::XInterface > getDataSourceOrModel(const css::uno::Reference< css::uno::XInterface > &_xObject)
returns either the model when data source is given as parameter, or returns a data source when a mode...
::utl::SharedUNOComponent< css::sdbc::XConnection > SharedConnection
Definition: commontypes.hxx:35
static void SafeRemovePropertyListener(const Reference< XPropertySet > &xSet, const OUString &rPropName, XPropertyChangeListener *pListener)
Definition: unodatbr.cxx:146
static Reference< XPropertySet > getColumnHelper(const weld::TreeView &rTreeView, const weld::TreeIter *pCurrentlyDisplayed, const Reference< XPropertySet > &rxSource)
Definition: unodatbr.cxx:758
static void SafeAddPropertyListener(const Reference< XPropertySet > &xSet, const OUString &rPropName, XPropertyChangeListener *pListener)
Definition: unodatbr.cxx:139
void showError(const SQLExceptionInfo &_rInfo, const Reference< XWindow > &_xParent, const Reference< XComponentContext > &_rxContext)
::osl::Mutex & getMutex()
int i
enumrange< T >::Iterator begin(enumrange< T >)
SwView * getView(const uno::Reference< frame::XModel > &xModel)
end
sal_uInt16 administrateDatabaseRegistration(weld::Window *_parentWindow)
void dispose()
long Long
OUString toId(const void *pValue)
sal_Int16 nId
const PropertyStruct aPropNames[]
QPRO_FUNC_TYPE nType
const Color aColNames[SC_RANGECOLORS]
constexpr OUStringLiteral PROPERTY_WIDTH(u"Width")
constexpr OUStringLiteral PROPERTY_COMMAND(u"Command")
constexpr OUStringLiteral PROPERTY_TEXTCOLOR(u"TextColor")
constexpr OUStringLiteral PROPERTY_FETCHDIRECTION(u"FetchDirection")
constexpr OUStringLiteral PROPERTY_DEFAULTTEXT(u"DefaultText")
constexpr OUStringLiteral PROPERTY_HAVING_CLAUSE(u"HavingClause")
constexpr OUStringLiteral PROPERTY_UPDATE_TABLENAME(u"UpdateTableName")
constexpr OUStringLiteral PROPERTY_EFFECTIVEDEFAULT(u"EffectiveDefault")
constexpr OUStringLiteral PROPERTY_CONTROLSOURCE(u"DataField")
constexpr OUStringLiteral PROPERTY_CONTROLDEFAULT(u"ControlDefault")
constexpr OUStringLiteral PROPERTY_LABEL(u"Label")
constexpr OUStringLiteral PROPERTY_ISROWVERSION(u"IsRowVersion")
constexpr OUStringLiteral PROPERTY_ISNULLABLE(u"IsNullable")
constexpr OUStringLiteral PROPERTY_UPDATE_SCHEMANAME(u"UpdateSchemaName")
constexpr OUStringLiteral PROPERTY_DESCRIPTION(u"Description")
constexpr OUStringLiteral PROPERTY_FORMATKEY(u"FormatKey")
constexpr OUStringLiteral PROPERTY_APPLYFILTER(u"ApplyFilter")
constexpr OUStringLiteral PROPERTY_DEFAULTSTATE(u"DefaultState")
constexpr OUStringLiteral SERVICE_NAME_SINGLESELECTQUERYCOMPOSER
Definition: strings.hxx:201
constexpr OUStringLiteral PROPERTY_BORDER(u"Border")
constexpr OUStringLiteral PROPERTY_MOUSE_WHEEL_BEHAVIOR(u"MouseWheelBehavior")
constexpr OUStringLiteral PROPERTY_TEXTEMPHASIS(u"FontEmphasisMark")
constexpr OUStringLiteral PROPERTY_FILTER(u"Filter")
constexpr OUStringLiteral PROPERTY_ACTIVE_CONNECTION(u"ActiveConnection")
constexpr OUStringLiteral PROPERTY_TABLENAME(u"TableName")
constexpr OUStringLiteral PROPERTY_FONT(u"FontDescriptor")
constexpr OUStringLiteral PROPERTY_ESCAPE_PROCESSING(u"EscapeProcessing")
constexpr OUStringLiteral PROPERTY_TEXTLINECOLOR(u"TextLineColor")
constexpr OUStringLiteral PROPERTY_HELPTEXT(u"HelpText")
constexpr OUStringLiteral PROPERTY_ENABLE_BROWSER(u"EnableBrowser")
constexpr OUStringLiteral PROPERTY_SUPPRESSVERSIONCL(u"SuppressVersionColumns")
constexpr OUStringLiteral PROPERTY_TYPE(u"Type")
constexpr OUStringLiteral PROPERTY_NAME(u"Name")
constexpr OUStringLiteral PROPERTY_TEXTRELIEF(u"FontRelief")
constexpr OUStringLiteral PROPERTY_UPDATE_CATALOGNAME(u"UpdateCatalogName")
constexpr OUStringLiteral PROPERTY_SHOWMENU(u"ShowMenu")
constexpr OUStringLiteral PROPERTY_DATASOURCENAME(u"DataSourceName")
constexpr OUStringLiteral PROPERTY_HIDDEN(u"Hidden")
constexpr OUStringLiteral PROPERTY_ALIGN(u"Align")
constexpr OUStringLiteral PROPERTY_ROW_HEIGHT(u"RowHeight")
constexpr OUStringLiteral PROPERTY_COMMAND_TYPE(u"CommandType")
constexpr OUStringLiteral PROPERTY_ORDER(u"Order")
constexpr OUStringLiteral PROPERTY_ISNEW(u"IsNew")
constexpr OUStringLiteral PROPERTY_SHOW_BROWSER(u"ShowBrowser")
SbaTableQueryBrowser::EntryType eType
Definition: dbtreemodel.hxx:46
css::uno::Reference< css::uno::XInterface > xContainer
if the entry denotes an object container, this is the UNO interface for this container
Definition: dbtreemodel.hxx:43
css::uno::Reference< css::beans::XPropertySet > xObjectProperties
if the entry denotes a table or query, this is the respective UNO object
Definition: dbtreemodel.hxx:40
SharedConnection xConnection
if the entry denotes a data source, this is the connection for this data source (if already connectio...
Definition: dbtreemodel.hxx:45
describes the state of a feature
std::optional< bool > bChecked
std::optional< OUString > sTitle
Reference< XFrame > xFrame
the frame which the component resides in. Must not be <NULL>
#define sal_False
unsigned char sal_Bool
ResultType type
OUString sId
Definition: unodatbr.cxx:1040
::comphelper::NamedValueCollection const & m_rCollection
Definition: unodatbr.cxx:351
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * org_openoffice_comp_dbu_ODatasourceBrowser_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: unodatbr.cxx:126
WinBits const WB_HSCROLL
const SvXMLTokenMapEntry aTypes[]