20#include <core_resource.hxx>
25#include <com/sun/star/sdb/application/DatabaseObject.hpp>
26#include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp>
27#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
28#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
29#include <com/sun/star/sdbc/SQLException.hpp>
30#include <com/sun/star/sdbc/XRow.hpp>
32#include <osl/diagnose.h>
51namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
52namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer;
57 , m_xImageProvider(new ImageProvider)
58 , m_bVirtualRoot(false)
59 , m_bNoEmptyFolders(false)
60 , m_bShowToggles(bShowToggles)
68 sal_Int32 nEntryType =
m_xTreeView->get_id(rEntry).toInt32();
69 return ( nEntryType == DatabaseObjectContainer::TABLES )
70 || ( nEntryType == DatabaseObjectContainer::CATALOG )
71 || ( nEntryType == DatabaseObjectContainer::SCHEMA );
84 OUString sCurrentActionError;
88 sCurrentActionError =
DBA_RES(STR_NOTABLEINFO);
95 xViews = xViewSupp->getViews();
97 sViews = xViews->getElementNames();
100 xTables = xTableSupp->getTables();
102 sTables = xTables->getElementNames();
108 catch (
const SQLException& )
116 throw SQLException(sCurrentActionError,
nullptr,
"", 0, anyEx);
130 OTableTreeListBox::TNames::value_type operator() (
const OUString& name)
132 OTableTreeListBox::TNames::value_type aRet;
135 [
this, &name](
const OUString& lhs)
136 { return m_aEqualFunctor(lhs, name); } );
145 const Reference< XConnection >& _rxConnection,
146 const Sequence< OUString>& _rTables,
147 const Sequence< OUString>& _rViews
151 aTables.resize(_rTables.getLength());
154 Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData(), UNO_SET_THROW );
155 std::transform( _rTables.begin(), _rTables.end(),
156 aTables.begin(), OViewSetter( _rViews, xMeta->supportsMixedCaseQuotedIdentifiers() ) );
167 std::vector< OUString > lcl_getMetaDataStrings_throw(
const Reference< XResultSet >& _rxMetaDataResult, sal_Int32 _nColumnIndex )
169 std::vector< OUString > aStrings;
170 Reference< XRow > xRow( _rxMetaDataResult, UNO_QUERY_THROW );
171 while ( _rxMetaDataResult->next() )
172 aStrings.push_back( xRow->getString( _nColumnIndex ) );
176 bool lcl_shouldDisplayEmptySchemasAndCatalogs(
const Reference< XConnection >& _rxConnection )
179 return aMetaData.displayEmptyTableFolders();
195 OUString sRootEntryText;
196 if ( std::none_of(_rTables.begin(),_rTables.end(),
197 [] (
const TNames::value_type& name) { return !name.second; }) )
198 sRootEntryText =
DBA_RES(STR_ALL_TABLES);
199 else if ( std::none_of(_rTables.begin(),_rTables.end(),
200 [] (
const TNames::value_type& name) { return name.second; }) )
201 sRootEntryText =
DBA_RES(STR_ALL_VIEWS);
203 sRootEntryText =
DBA_RES(STR_ALL_TABLES_AND_VIEWS);
204 OUString
sId(OUString::number(DatabaseObjectContainer::TABLES));
206 std::unique_ptr<weld::TreeIter> xRet(
m_xTreeView->make_iterator());
207 m_xTreeView->insert(
nullptr, -1,
nullptr, &
sId,
nullptr,
nullptr,
false, xRet.get());
215 if ( _rTables.empty() )
220 Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData(), UNO_SET_THROW );
221 for (
auto const& table : _rTables)
227 if ( !
m_bNoEmptyFolders && lcl_shouldDisplayEmptySchemasAndCatalogs( _rxConnection ) )
229 bool bSupportsCatalogs = xMeta->supportsCatalogsInDataManipulation();
230 bool bSupportsSchemas = xMeta->supportsSchemasInDataManipulation();
232 if ( bSupportsCatalogs || bSupportsSchemas )
237 bool bCatalogs = bSupportsCatalogs && xMeta->isCatalogAtStart();
239 std::vector< OUString > aFolderNames( lcl_getMetaDataStrings_throw(
240 bCatalogs ? xMeta->getCatalogs() : xMeta->getSchemas(), 1 ) );
241 sal_Int32 nFolderType =
bCatalogs ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA;
246 std::unique_ptr<weld::TreeIter> xRet(
m_xTreeView->make_iterator());
247 for (
auto const& folderName : aFolderNames)
249 std::unique_ptr<weld::TreeIter> xFolder(
GetEntryPosByName(folderName, xRootEntry.get()));
252 OUString
sId(OUString::number(nFolderType));
253 m_xTreeView->insert(xRootEntry.get(), -1,
nullptr, &
sId,
nullptr,
nullptr,
false, xRet.get());
264 catch (
const Exception& )
300 OSL_ENSURE(
TRISTATE_INDET != eState,
"OTableTreeListBox::CheckButtonHdl: user action which lead to TRISTATE?");
304 std::unique_ptr<weld::TreeIter> xChildEntry(
m_xTreeView->make_iterator(&rEntry));
305 std::unique_ptr<weld::TreeIter> xSiblingEntry(
m_xTreeView->make_iterator(&rEntry));
306 bool bChildEntry =
m_xTreeView->iter_next(*xChildEntry);
307 bool bSiblingEntry =
m_xTreeView->iter_next_sibling(*xSiblingEntry);
308 while (bChildEntry && (!bSiblingEntry || !xChildEntry->equal(*xSiblingEntry)))
311 bChildEntry =
m_xTreeView->iter_next(*xChildEntry);
321 std::unique_ptr<weld::TreeIter> xChildEntry(m_xTreeView->make_iterator(&rSelected));
322 std::unique_ptr<weld::TreeIter> xSiblingEntry(m_xTreeView->make_iterator(&rSelected));
323 bool bChildEntry = m_xTreeView->iter_next(*xChildEntry);
324 bool bSiblingEntry = m_xTreeView->iter_next_sibling(*xSiblingEntry);
325 while (bChildEntry && (!bSiblingEntry || !xChildEntry->equal(*xSiblingEntry)))
327 m_xTreeView->set_toggle(*xChildEntry, eState);
328 bChildEntry = m_xTreeView->iter_next(*xChildEntry);
340 implEmphasize(rEntry, eState == TRISTATE_TRUE);
343void OTableTreeListBox::implEmphasize(
const weld::TreeIter& rEntry,
bool _bChecked,
bool _bUpdateDescendants,
bool _bUpdateAncestors)
346 bool bAllObjectsEntryAffected = haveVirtualRoot() && (getAllObjectsEntry()->equal(rEntry));
347 if ( m_xTreeView->iter_has_child(rEntry)
348 || bAllObjectsEntryAffected
351 m_xTreeView->set_text_emphasis(rEntry, _bChecked, 0);
354 if (_bUpdateDescendants)
356 std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(&rEntry));
358 bool bChildLoop = m_xTreeView->iter_children(*xChild);
361 if (m_xTreeView->iter_has_child(*xChild))
362 implEmphasize(*xChild,
false,
true,
false);
363 bChildLoop = m_xTreeView->iter_next_sibling(*xChild);
367 if (_bUpdateAncestors)
369 std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rEntry));
371 if (m_xTreeView->iter_parent(*xParent))
372 implEmphasize(*xParent,
false,
false);
376std::unique_ptr<weld::TreeIter> OTableTreeListBox::implAddEntry(
378 const OUString& _rTableName,
382 OSL_PRECOND( _rxMeta.is(),
"OTableTreeListBox::implAddEntry: invalid meta data!" );
390 std::unique_ptr<weld::TreeIter> xParentEntry(getAllObjectsEntry());
400 bool bCatalogAtStart = _rxMeta->isCatalogAtStart();
402 const sal_Int32 nFirstFolderType = bCatalogAtStart ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA;
404 const sal_Int32 nSecondFolderType = bCatalogAtStart ? DatabaseObjectContainer::SCHEMA : DatabaseObjectContainer::CATALOG;
406 if ( !rFirstName.isEmpty() )
408 std::unique_ptr<weld::TreeIter> xFolder(GetEntryPosByName(rFirstName, xParentEntry.get()));
411 xFolder = m_xTreeView->make_iterator();
412 OUString
sId(OUString::number(nFirstFolderType));
414 m_xTreeView->insert(xParentEntry.get(), -1,
nullptr, &
sId,
nullptr,
nullptr,
false, xFolder.get());
415 m_xTreeView->set_image(*xFolder, sImageId, -1);
418 m_xTreeView->set_text(*xFolder, rFirstName, 0);
419 m_xTreeView->set_text_emphasis(*xFolder,
false, 0);
421 xParentEntry = std::move(xFolder);
424 if ( !rSecondName.isEmpty() )
426 std::unique_ptr<weld::TreeIter> xFolder(GetEntryPosByName(rSecondName, xParentEntry.get()));
429 xFolder = m_xTreeView->make_iterator();
430 OUString
sId(OUString::number(nSecondFolderType));
432 m_xTreeView->insert(xParentEntry.get(), -1,
nullptr, &
sId,
nullptr,
nullptr,
false, xFolder.get());
433 m_xTreeView->set_image(*xFolder, sImageId, -1);
436 m_xTreeView->set_text(*xFolder, rSecondName, 0);
437 m_xTreeView->set_text_emphasis(*xFolder,
false, 0);
439 xParentEntry = std::move(xFolder);
442 if (!_bCheckName || !GetEntryPosByName(
sName, xParentEntry.get()))
444 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
445 m_xTreeView->insert(xParentEntry.get(), -1,
nullptr,
nullptr,
nullptr,
nullptr,
false, xEntry.get());
449 m_xTreeView->set_image(*xEntry, xGraphic, -1);
453 m_xTreeView->set_image(*xEntry, sImageId, -1);
457 m_xTreeView->set_text(*xEntry,
sName, 0);
458 m_xTreeView->set_text_emphasis(*xEntry,
false, 0);
466NamedDatabaseObject OTableTreeListBox::describeObject(
const weld::TreeIter& rEntry)
468 NamedDatabaseObject aObject;
470 sal_Int32 nEntryType = m_xTreeView->get_id(rEntry).toInt32();
472 if ( nEntryType == DatabaseObjectContainer::TABLES )
474 aObject.Type = DatabaseObjectContainer::TABLES;
476 else if ( ( nEntryType == DatabaseObjectContainer::CATALOG )
477 || ( nEntryType == DatabaseObjectContainer::SCHEMA )
485 aObject.Name = getQualifiedTableName(rEntry);
491std::unique_ptr<weld::TreeIter> OTableTreeListBox::addedTable(
const OUString& rName)
496 if ( impl_getAndAssertMetaData( xMeta ) )
497 return implAddEntry( xMeta, rName );
510 OSL_PRECOND( _out_rMetaData.is(),
"OTableTreeListBox::impl_getAndAssertMetaData: invalid current connection!" );
511 return _out_rMetaData.is();
514OUString OTableTreeListBox::getQualifiedTableName(
const weld::TreeIter& rEntry)
const
516 OSL_PRECOND( !isFolderEntry(rEntry),
"OTableTreeListBox::getQualifiedTableName: folder entries not allowed here!" );
521 if ( !impl_getAndAssertMetaData( xMeta ) )
528 std::unique_ptr<weld::TreeIter> xSchema(m_xTreeView->make_iterator(&rEntry));
529 bool bSchema = m_xTreeView->iter_parent(*xSchema);
532 std::unique_ptr<weld::TreeIter> xCatalog(m_xTreeView->make_iterator(xSchema.get()));
533 bool bCatalog = m_xTreeView->iter_parent(*xCatalog);
535 || ( xMeta->supportsCatalogsInDataManipulation()
536 && !xMeta->supportsSchemasInDataManipulation()
542 xCatalog = std::move(xSchema);
545 sCatalog = m_xTreeView->get_text(*xCatalog);
548 sSchema = m_xTreeView->get_text(*xSchema);
550 sTable = m_xTreeView->get_text(rEntry);
552 return ::dbtools::composeTableName( xMeta,
sCatalog,
sSchema, sTable,
false, ::dbtools::EComposeRule::InDataManipulation );
561std::unique_ptr<weld::TreeIter> OTableTreeListBox::getEntryByQualifiedName(
const OUString& rName)
566 if ( !impl_getAndAssertMetaData( xMeta ) )
573 std::unique_ptr<weld::TreeIter> xParent(getAllObjectsEntry());
574 std::unique_ptr<weld::TreeIter> xCat;
575 std::unique_ptr<weld::TreeIter> xSchema;
580 xParent = std::move(xCat);
585 xSchema = GetEntryPosByName(
sSchema, xParent.get());
587 xParent = std::move(xSchema);
590 return GetEntryPosByName(
sName, xParent.get());
599void OTableTreeListBox::removedTable(
const OUString& rName)
603 std::unique_ptr<weld::TreeIter> xEntry = getEntryByQualifiedName(rName);
605 m_xTreeView->remove(*xEntry);
613void OTableTreeListBox::CheckButtons()
618 auto xEntry(m_xTreeView->make_iterator());
619 if (!m_xTreeView->get_iter_first(*xEntry))
624 implDetermineState(*xEntry);
625 }
while (m_xTreeView->iter_next_sibling(*xEntry));
633 TriState eState = m_xTreeView->get_toggle(rEntry);
634 if (!m_xTreeView->iter_has_child(rEntry))
639 sal_uInt16 nCheckedChildren = 0;
640 sal_uInt16 nChildrenOverall = 0;
642 std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(&rEntry));
643 bool bChildLoop = m_xTreeView->iter_children(*xChild);
646 TriState eChildState = implDetermineState(*xChild);
652 bChildLoop = m_xTreeView->iter_next_sibling(*xChild);
665 implDetermineState(*xChild);
666 bChildLoop = m_xTreeView->iter_next_sibling(*xChild);
672 if (nCheckedChildren)
675 if (nCheckedChildren != nChildrenOverall)
694 m_xTreeView->set_toggle(rEntry, eState);
std::unique_ptr< weld::Builder > m_xBuilder
std::unique_ptr< TreeListBox > m_xTreeListBox
std::vector< TTableViewName > TNames
void checkWildcard(const weld::TreeIter &rEntry)
does a wildcard check of the given entry
void UpdateTableList(const css::uno::Reference< css::sdbc::XConnection > &_rxConnection)
fill the table list with the tables belonging to the connection described by the parameters
OTableTreeListBox(std::unique_ptr< weld::TreeView > xTreeView, bool bShowToggles)
bool haveVirtualRoot() const
bool isWildcardChecked(const weld::TreeIter &rEntry)
determine if the given entry is 'wildcard checked'
void checkedButton_noBroadcast(const weld::TreeIter &rEntry)
css::uno::Reference< css::sdbc::XConnection > m_xConnection
std::unique_ptr< weld::TreeIter > getAllObjectsEntry() const
void implOnNewConnection(const css::uno::Reference< css::sdbc::XConnection > &_rxConnection)
std::unique_ptr< weld::TreeIter > implAddEntry(const css::uno::Reference< css::sdbc::XDatabaseMetaData > &_rxMeta, const OUString &_rTableName, bool _bCheckName=true)
adds the given entry to our list @precond our image provider must already have been reset to the conn...
std::unique_ptr< ImageProvider > m_xImageProvider
bool isFolderEntry(const weld::TreeIter &rEntry) const
determines whether the given entry denotes a tables folder
std::unique_ptr< weld::TreeIter > GetEntryPosByName(std::u16string_view rName, const weld::TreeIter *pStart=nullptr, const IEntryFilter *pFilter=nullptr) const
std::unique_ptr< weld::TreeView > m_xTreeView
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
Any SAL_CALL getCaughtException()
Reference< XConnection > m_xConnection
::comphelper::UStringMixEqual m_aEqualFunctor
const Sequence< OUString > m_aViews