diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-04-04 14:30:03 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-04-06 19:53:00 +0200 |
commit | 5c32ba63163d9556ff89782a8074924cdf9dc554 (patch) | |
tree | 66acbb3b4c298c9f0cbff75f9e36bf3d759b7a0f /dbaccess/source | |
parent | 6f31c63e35abef03e6f938bbddc8778b70a62d43 (diff) |
weld OTableSubscriptionPage
Change-Id: I55c23448480384c9a7d78cd55550bb4812ebde72
Reviewed-on: https://gerrit.libreoffice.org/70314
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'dbaccess/source')
-rw-r--r-- | dbaccess/source/ui/browser/unodatbr.cxx | 6 | ||||
-rw-r--r-- | dbaccess/source/ui/control/dbtreelistbox.cxx | 2 | ||||
-rw-r--r-- | dbaccess/source/ui/control/tabletree.cxx | 446 | ||||
-rw-r--r-- | dbaccess/source/ui/dlg/tablespage.cxx | 254 | ||||
-rw-r--r-- | dbaccess/source/ui/dlg/tablespage.hxx | 18 | ||||
-rw-r--r-- | dbaccess/source/ui/inc/dbtreelistbox.hxx | 3 | ||||
-rw-r--r-- | dbaccess/source/ui/inc/imageprovider.hxx | 13 | ||||
-rw-r--r-- | dbaccess/source/ui/inc/tabletree.hxx | 123 | ||||
-rw-r--r-- | dbaccess/source/ui/misc/imageprovider.cxx | 53 |
9 files changed, 755 insertions, 163 deletions
diff --git a/dbaccess/source/ui/browser/unodatbr.cxx b/dbaccess/source/ui/browser/unodatbr.cxx index ee49f5b1f3e6..31251082622e 100644 --- a/dbaccess/source/ui/browser/unodatbr.cxx +++ b/dbaccess/source/ui/browser/unodatbr.cxx @@ -1077,12 +1077,12 @@ namespace virtual ~FilterByEntryDataId() {} - virtual bool includeEntry( SvTreeListEntry* _pEntry ) const override; + virtual bool includeEntry(const void* pEntry) const override; }; - bool FilterByEntryDataId::includeEntry( SvTreeListEntry* _pEntry ) const + bool FilterByEntryDataId::includeEntry(const void* pUserData) const { - DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() ); + const DBTreeListUserData* pData = static_cast<const DBTreeListUserData*>(pUserData); return ( !pData || ( pData->sAccessor == sId ) ); } } diff --git a/dbaccess/source/ui/control/dbtreelistbox.cxx b/dbaccess/source/ui/control/dbtreelistbox.cxx index 921130037653..0d8912d92bcb 100644 --- a/dbaccess/source/ui/control/dbtreelistbox.cxx +++ b/dbaccess/source/ui/control/dbtreelistbox.cxx @@ -117,7 +117,7 @@ SvTreeListEntry* DBTreeListBox::GetEntryPosByName( const OUString& aName, SvTree if (pItem && pItem->GetText() == aName) { - if (!_pFilter || _pFilter->includeEntry(pEntry)) + if (!_pFilter || _pFilter->includeEntry(pEntry->GetUserData())) // found break; } diff --git a/dbaccess/source/ui/control/tabletree.cxx b/dbaccess/source/ui/control/tabletree.cxx index 9e8b7de36fb5..b89fa02bbe60 100644 --- a/dbaccess/source/ui/control/tabletree.cxx +++ b/dbaccess/source/ui/control/tabletree.cxx @@ -74,6 +74,15 @@ OTableTreeListBox::OTableTreeListBox(vcl::Window* pParent, WinBits nWinStyle) implSetDefaultImages(); } +TableTreeListBox::TableTreeListBox(std::unique_ptr<weld::TreeView> xTreeView) + : m_xImageProvider(new ImageProvider) + , m_bVirtualRoot(false) + , m_bNoEmptyFolders(false) + , m_xTreeView(std::move(xTreeView)) +{ + m_xTreeView->make_sorted(); +} + VCL_BUILDER_FACTORY_CONSTRUCTOR(OTableTreeListBox, 0) void OTableTreeListBox::implSetDefaultImages() @@ -131,6 +140,12 @@ void OTableTreeListBox::implOnNewConnection( const Reference< XConnection >& _rx m_xImageProvider.reset( new ImageProvider( m_xConnection ) ); } +void TableTreeListBox::implOnNewConnection( const Reference< XConnection >& _rxConnection ) +{ + m_xConnection = _rxConnection; + m_xImageProvider.reset( new ImageProvider( m_xConnection ) ); +} + void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConnection ) { Sequence< OUString > sTables, sViews; @@ -173,6 +188,48 @@ void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConn UpdateTableList( _rxConnection, sTables, sViews ); } +void TableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConnection ) +{ + Sequence< OUString > sTables, sViews; + + OUString sCurrentActionError; + try + { + Reference< XTablesSupplier > xTableSupp( _rxConnection, UNO_QUERY_THROW ); + sCurrentActionError = DBA_RES(STR_NOTABLEINFO); + + Reference< XNameAccess > xTables,xViews; + + Reference< XViewsSupplier > xViewSupp( _rxConnection, UNO_QUERY ); + if ( xViewSupp.is() ) + { + xViews = xViewSupp->getViews(); + if (xViews.is()) + sViews = xViews->getElementNames(); + } + + xTables = xTableSupp->getTables(); + if (xTables.is()) + sTables = xTables->getElementNames(); + } + catch(RuntimeException&) + { + OSL_FAIL("OTableTreeListBox::UpdateTableList : caught an RuntimeException!"); + } + catch ( const SQLException& ) + { + throw; + } + catch(Exception&) + { + css::uno::Any anyEx = cppu::getCaughtException(); + // a non-SQLException exception occurred ... simply throw an SQLException + throw SQLException(sCurrentActionError, nullptr, "", 0, anyEx); + } + + UpdateTableList( _rxConnection, sTables, sViews ); +} + namespace { struct OViewSetter @@ -216,6 +273,27 @@ void OTableTreeListBox::UpdateTableList( UpdateTableList( _rxConnection, aTables ); } +void TableTreeListBox::UpdateTableList( + const Reference< XConnection >& _rxConnection, + const Sequence< OUString>& _rTables, + const Sequence< OUString>& _rViews + ) +{ + TNames aTables; + aTables.resize(_rTables.getLength()); + try + { + Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData(), UNO_QUERY_THROW ); + std::transform( _rTables.begin(), _rTables.end(), + aTables.begin(), OViewSetter( _rViews, xMeta->supportsMixedCaseQuotedIdentifiers() ) ); + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } + UpdateTableList( _rxConnection, aTables ); +} + namespace { std::vector< OUString > lcl_getMetaDataStrings_throw( const Reference< XResultSet >& _rxMetaDataResult, sal_Int32 _nColumnIndex ) @@ -305,6 +383,92 @@ void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConn } } +void TableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConnection, const TNames& _rTables ) +{ + implOnNewConnection( _rxConnection ); + + // throw away all the old stuff + m_xTreeView->clear(); + + try + { + if (haveVirtualRoot()) + { + OUString sRootEntryText; + if ( std::none_of(_rTables.begin(),_rTables.end(), + [] (const TNames::value_type& name) { return !name.second; }) ) + sRootEntryText = DBA_RES(STR_ALL_TABLES); + else if ( std::none_of(_rTables.begin(),_rTables.end(), + [] (const TNames::value_type& name) { return name.second; }) ) + sRootEntryText = DBA_RES(STR_ALL_VIEWS); + else + sRootEntryText = DBA_RES(STR_ALL_TABLES_AND_VIEWS); + OUString sId(OUString::number(DatabaseObjectContainer::TABLES)); + OUString sImageId = ImageProvider::getFolderImageId(DatabaseObject::TABLE); + std::unique_ptr<weld::TreeIter> xRet(m_xTreeView->make_iterator()); + m_xTreeView->insert(nullptr, -1, nullptr, &sId, nullptr, nullptr, nullptr, false, xRet.get()); + m_xTreeView->set_image(*xRet, sImageId, -1); + m_xTreeView->set_toggle(*xRet, TRISTATE_FALSE, 0); + m_xTreeView->set_text(*xRet, sRootEntryText, 1); + } + + if ( _rTables.empty() ) + // nothing to do (besides inserting the root entry) + return; + + // get the table/view names + Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData(), UNO_QUERY_THROW ); + for (auto const& table : _rTables) + { + // add the entry + implAddEntry( + xMeta, + table.first, + false + ); + } + + if ( !m_bNoEmptyFolders && lcl_shouldDisplayEmptySchemasAndCatalogs( _rxConnection ) ) + { + bool bSupportsCatalogs = xMeta->supportsCatalogsInDataManipulation(); + bool bSupportsSchemas = xMeta->supportsSchemasInDataManipulation(); + + if ( bSupportsCatalogs || bSupportsSchemas ) + { + // we display empty catalogs if the DB supports catalogs, and they're noted at the beginning of a + // composed name. Otherwise, we display empty schematas. (also see the tree structure explained in + // implAddEntry) + bool bCatalogs = bSupportsCatalogs && xMeta->isCatalogAtStart(); + + std::vector< OUString > aFolderNames( lcl_getMetaDataStrings_throw( + bCatalogs ? xMeta->getCatalogs() : xMeta->getSchemas(), 1 ) ); + sal_Int32 nFolderType = bCatalogs ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA; + + OUString sImageId = ImageProvider::getFolderImageId(DatabaseObject::TABLE); + + std::unique_ptr<weld::TreeIter> xRootEntry(getAllObjectsEntry()); + std::unique_ptr<weld::TreeIter> xRet(m_xTreeView->make_iterator()); + for (auto const& folderName : aFolderNames) + { + std::unique_ptr<weld::TreeIter> xFolder(GetEntryPosByName(folderName, xRootEntry.get())); + if (!xFolder) + { + OUString sId(OUString::number(nFolderType)); + m_xTreeView->insert(xRootEntry.get(), -1, nullptr, &sId, nullptr, nullptr, nullptr, false, xRet.get()); + m_xTreeView->set_image(*xRet, sImageId, -1); + m_xTreeView->set_toggle(*xRet, TRISTATE_FALSE, 0); + m_xTreeView->set_text(*xRet, folderName, 1); + } + } + } + } + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } +} + bool OTableTreeListBox::isWildcardChecked(SvTreeListEntry* _pEntry) { if (_pEntry) @@ -316,17 +480,39 @@ bool OTableTreeListBox::isWildcardChecked(SvTreeListEntry* _pEntry) return false; } +bool TableTreeListBox::isWildcardChecked(weld::TreeIter& rEntry) +{ +// return m_xTreeView->get_text_emphasis(rEntry, 2); + return m_xTreeView->get_text_emphasis(rEntry, 1); +} + void OTableTreeListBox::checkWildcard(SvTreeListEntry* _pEntry) { SetCheckButtonState(_pEntry, SvButtonState::Checked); checkedButton_noBroadcast(_pEntry); } +void TableTreeListBox::checkWildcard(weld::TreeIter& rEntry) +{ + m_xTreeView->set_toggle(rEntry, TRISTATE_TRUE, 0); + checkedButton_noBroadcast(rEntry); +} + SvTreeListEntry* OTableTreeListBox::getAllObjectsEntry() const { return haveVirtualRoot() ? First() : nullptr; } +std::unique_ptr<weld::TreeIter> TableTreeListBox::getAllObjectsEntry() const +{ + if (!haveVirtualRoot()) + return nullptr; + auto xRet = m_xTreeView->make_iterator(); + if (!m_xTreeView->get_iter_first(*xRet)) + return nullptr; + return xRet; +} + void OTableTreeListBox::checkedButton_noBroadcast(SvTreeListEntry* _pEntry) { OMarkableTreeListBox::checkedButton_noBroadcast(_pEntry); @@ -340,6 +526,52 @@ void OTableTreeListBox::checkedButton_noBroadcast(SvTreeListEntry* _pEntry) implEmphasize(_pEntry, SvButtonState::Checked == eState); } +void TableTreeListBox::checkedButton_noBroadcast(weld::TreeIter& rEntry) +{ + TriState eState = m_xTreeView->get_toggle(rEntry, 0); + OSL_ENSURE(TRISTATE_INDET != eState, "OTableTreeListBox::CheckButtonHdl: user action which lead to TRISTATE?"); + + if (m_xTreeView->iter_has_child(rEntry)) // if it has children, check those too + { + std::unique_ptr<weld::TreeIter> xChildEntry(m_xTreeView->make_iterator(&rEntry)); + std::unique_ptr<weld::TreeIter> xSiblingEntry(m_xTreeView->make_iterator(&rEntry)); + bool bChildEntry = m_xTreeView->iter_next(*xChildEntry); + bool bSiblingEntry = m_xTreeView->iter_next_sibling(*xSiblingEntry); + while (bChildEntry && (!bSiblingEntry || !xChildEntry->equal(*xSiblingEntry))) + { + m_xTreeView->set_toggle(*xChildEntry, eState, 0); + bChildEntry = m_xTreeView->iter_next(*xChildEntry); + } + } + + if (m_xTreeView->is_selected(rEntry)) + { + m_xTreeView->selected_foreach([this, eState](weld::TreeIter& rSelected){ + m_xTreeView->set_toggle(rSelected, eState, 0); + if (m_xTreeView->iter_has_child(rSelected)) // if it has children, check those too + { + std::unique_ptr<weld::TreeIter> xChildEntry(m_xTreeView->make_iterator(&rSelected)); + std::unique_ptr<weld::TreeIter> xSiblingEntry(m_xTreeView->make_iterator(&rSelected)); + bool bChildEntry = m_xTreeView->iter_next(*xChildEntry); + bool bSiblingEntry = m_xTreeView->iter_next_sibling(*xSiblingEntry); + while (bChildEntry && (!bSiblingEntry || !xChildEntry->equal(*xSiblingEntry))) + { + m_xTreeView->set_toggle(*xChildEntry, eState, 0); + bChildEntry = m_xTreeView->iter_next(*xChildEntry); + } + } + return false; + }); + } + + CheckButtons(); + + // if an entry has children, it makes a difference if the entry is checked + // because all children are checked or if the user checked it explicitly. + // So we track explicit (un)checking + implEmphasize(rEntry, eState == TRISTATE_TRUE); +} + void OTableTreeListBox::implEmphasize(SvTreeListEntry* _pEntry, bool _bChecked, bool _bUpdateDescendants, bool _bUpdateAncestors) { OSL_ENSURE(_pEntry, "OTableTreeListBox::implEmphasize: invalid entry (NULL)!"); @@ -378,6 +610,39 @@ void OTableTreeListBox::implEmphasize(SvTreeListEntry* _pEntry, bool _bChecked, } } +void TableTreeListBox::implEmphasize(weld::TreeIter& rEntry, bool _bChecked, bool _bUpdateDescendants, bool _bUpdateAncestors) +{ + // special emphasizing handling for the "all objects" entry + bool bAllObjectsEntryAffected = haveVirtualRoot() && (getAllObjectsEntry()->equal(rEntry)); + if ( m_xTreeView->iter_has_child(rEntry) // the entry has children + || bAllObjectsEntryAffected // or it is the "all objects" entry + ) + { + m_xTreeView->set_text_emphasis(rEntry, _bChecked, 1); + } + + if (_bUpdateDescendants) + { + std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(&rEntry)); + // remove the mark for all children of the checked entry + bool bChildLoop = m_xTreeView->iter_children(*xChild); + while (bChildLoop) + { + if (m_xTreeView->iter_has_child(*xChild)) + implEmphasize(*xChild, false, true, false); + bChildLoop = m_xTreeView->iter_next_sibling(*xChild); + } + } + + if (_bUpdateAncestors) + { + std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rEntry)); + // remove the mark for all ancestors of the entry + if (m_xTreeView->iter_parent(*xParent)) + implEmphasize(*xParent, false, false); + } +} + void OTableTreeListBox::InitEntry(SvTreeListEntry* _pEntry, const OUString& _rString, const Image& _rCollapsedBitmap, const Image& _rExpandedBitmap, SvLBoxButtonKind _eButtonKind) { OMarkableTreeListBox::InitEntry(_pEntry, _rString, _rCollapsedBitmap, _rExpandedBitmap, _eButtonKind); @@ -451,6 +716,86 @@ SvTreeListEntry* OTableTreeListBox::implAddEntry( return pRet; } +void TableTreeListBox::implAddEntry( + const Reference< XDatabaseMetaData >& _rxMeta, + const OUString& _rTableName, + bool _bCheckName + ) +{ + OSL_PRECOND( _rxMeta.is(), "OTableTreeListBox::implAddEntry: invalid meta data!" ); + if ( !_rxMeta.is() ) + return; + + // split the complete name into its components + OUString sCatalog, sSchema, sName; + qualifiedNameComponents( _rxMeta, _rTableName, sCatalog, sSchema, sName, ::dbtools::EComposeRule::InDataManipulation ); + + std::unique_ptr<weld::TreeIter> xParentEntry(getAllObjectsEntry()); + + // if the DB uses catalog at the start of identifiers, then our hierarchy is + // catalog + // +- schema + // +- table + // else it is + // schema + // +- catalog + // +- table + bool bCatalogAtStart = _rxMeta->isCatalogAtStart(); + const OUString& rFirstName = bCatalogAtStart ? sCatalog : sSchema; + const sal_Int32 nFirstFolderType = bCatalogAtStart ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA; + const OUString& rSecondName = bCatalogAtStart ? sSchema : sCatalog; + const sal_Int32 nSecondFolderType = bCatalogAtStart ? DatabaseObjectContainer::SCHEMA : DatabaseObjectContainer::CATALOG; + + if ( !rFirstName.isEmpty() ) + { + std::unique_ptr<weld::TreeIter> xFolder(GetEntryPosByName(rFirstName, xParentEntry.get())); + if (!xFolder) + { + xFolder = m_xTreeView->make_iterator(); + OUString sId(OUString::number(nFirstFolderType)); + OUString sImageId = ImageProvider::getFolderImageId(DatabaseObject::TABLE); + m_xTreeView->insert(xParentEntry.get(), -1, nullptr, &sId, nullptr, nullptr, nullptr, false, xFolder.get()); + m_xTreeView->set_image(*xFolder, sImageId, -1); + m_xTreeView->set_toggle(*xFolder, TRISTATE_FALSE, 0); + m_xTreeView->set_text(*xFolder, rFirstName, 1); + } + xParentEntry = std::move(xFolder); + } + + if ( !rSecondName.isEmpty() ) + { + std::unique_ptr<weld::TreeIter> xFolder(GetEntryPosByName(rSecondName, xParentEntry.get())); + if (!xFolder) + { + xFolder = m_xTreeView->make_iterator(); + OUString sId(OUString::number(nSecondFolderType)); + OUString sImageId = ImageProvider::getFolderImageId(DatabaseObject::TABLE); + m_xTreeView->insert(xParentEntry.get(), -1, nullptr, &sId, nullptr, nullptr, nullptr, false, xFolder.get()); + m_xTreeView->set_image(*xFolder, sImageId, -1); + m_xTreeView->set_toggle(*xFolder, TRISTATE_FALSE, 0); + m_xTreeView->set_text(*xFolder, rSecondName, 1); + } + xParentEntry = std::move(xFolder); + } + + if (!_bCheckName || !GetEntryPosByName(sName, xParentEntry.get())) + { + std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator(); + m_xTreeView->insert(xParentEntry.get(), -1, nullptr, nullptr, nullptr, nullptr, nullptr, false, xEntry.get()); + + auto xGraphic = m_xImageProvider->getXGraphic(_rTableName, DatabaseObject::TABLE); + if (xGraphic.is()) + m_xTreeView->set_image(*xEntry, xGraphic, -1); + else + { + OUString sImageId(m_xImageProvider->getImageId(_rTableName, DatabaseObject::TABLE)); + m_xTreeView->set_image(*xEntry, sImageId, -1); + } + m_xTreeView->set_toggle(*xEntry, TRISTATE_FALSE, 0); + m_xTreeView->set_text(*xEntry, sName, 1); + } +} + NamedDatabaseObject OTableTreeListBox::describeObject( SvTreeListEntry* _pEntry ) { NamedDatabaseObject aObject; @@ -596,6 +941,107 @@ void OTableTreeListBox::removedTable( const OUString& _rName ) } } +std::unique_ptr<weld::TreeIter> TableTreeListBox::GetEntryPosByName(const OUString& aName, weld::TreeIter* pStart, const IEntryFilter* _pFilter) const +{ + auto xEntry(m_xTreeView->make_iterator(pStart)); + if (!pStart && !m_xTreeView->get_iter_first(*xEntry)) + return nullptr; + + do + { + if (m_xTreeView->get_text(*xEntry) == aName) + { + if (!_pFilter || _pFilter->includeEntry(reinterpret_cast<void*>(m_xTreeView->get_id(*xEntry).toUInt64()))) + { + // found + return xEntry; + } + } + } while (m_xTreeView->iter_next(*xEntry)); + + return nullptr; +} + +void TableTreeListBox::CheckButtons() +{ + auto xEntry(m_xTreeView->make_iterator()); + if (!m_xTreeView->get_iter_first(*xEntry)) + return; + + do + { + implDetermineState(*xEntry); + } while (m_xTreeView->iter_next_sibling(*xEntry)); +} + +TriState TableTreeListBox::implDetermineState(weld::TreeIter& rEntry) +{ + TriState eState = m_xTreeView->get_toggle(rEntry, 0); + if (!m_xTreeView->iter_has_child(rEntry)) + // nothing to do in this bottom-up routine if there are no children ... + return eState; + + // loop through the children and check their states + sal_uInt16 nCheckedChildren = 0; + sal_uInt16 nChildrenOverall = 0; + + std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(&rEntry)); + bool bChildLoop = m_xTreeView->iter_children(*xChild); + while (bChildLoop) + { + TriState eChildState = implDetermineState(*xChild); + if (eChildState == TRISTATE_INDET) + break; + if (eChildState == TRISTATE_TRUE) + ++nCheckedChildren; + ++nChildrenOverall; + bChildLoop = m_xTreeView->iter_next_sibling(*xChild); + } + + if (bChildLoop) + { + // we did not finish the loop because at least one of the children is in tristate + eState = TRISTATE_INDET; + + // but this means that we did not finish all the siblings of pChildLoop, + // so their checking may be incorrect at the moment + // -> correct this + while (bChildLoop) + { + implDetermineState(*xChild); + bChildLoop = m_xTreeView->iter_next_sibling(*xChild); + } + } + else + { + // none if the children are in tristate + if (nCheckedChildren) + { + // we have at least one child checked + if (nCheckedChildren != nChildrenOverall) + { + // not all children are checked + eState = TRISTATE_INDET; + } + else + { + // all children are checked + eState = TRISTATE_TRUE; + } + } + else + { + // no children are checked + eState = TRISTATE_FALSE; + } + } + + // finally set the entry to the state we just determined + m_xTreeView->set_toggle(rEntry, eState, 0); + + return eState; +} + } // namespace dbaui /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/ui/dlg/tablespage.cxx b/dbaccess/source/ui/dlg/tablespage.cxx index 233157aa66f0..d5b8ec000344 100644 --- a/dbaccess/source/ui/dlg/tablespage.cxx +++ b/dbaccess/source/ui/dlg/tablespage.cxx @@ -66,32 +66,25 @@ namespace dbaui using namespace ::comphelper; // OTableSubscriptionPage - OTableSubscriptionPage::OTableSubscriptionPage(vcl::Window* pParent, const SfxItemSet& _rCoreAttrs, + OTableSubscriptionPage::OTableSubscriptionPage(TabPageParent pParent, const SfxItemSet& _rCoreAttrs, OTableSubscriptionDialog* _pTablesDlg) - : OGenericAdministrationPage(pParent, "TablesFilterPage", - "dbaccess/ui/tablesfilterpage.ui", _rCoreAttrs) + : OGenericAdministrationPage(pParent, "dbaccess/ui/tablesfilterpage.ui", "TablesFilterPage", _rCoreAttrs) , m_bCatalogAtStart(true) , m_pTablesDlg(_pTablesDlg) + , m_xTables(m_xBuilder->weld_widget("TablesFilterPage")) + , m_xTablesList(new TableTreeListBox(m_xBuilder->weld_tree_view("treeview"))) { - get(m_pTables, "TablesFilterPage"); + m_xTablesList->init(); - get(m_pTablesList, "treeview"); - m_pTablesList->init(); - m_pTablesList->set_width_request(56 * m_pTablesList->approximate_char_width()); - m_pTablesList->set_height_request(12 * m_pTablesList->GetTextHeight()); + weld::TreeView& rWidget = m_xTablesList->GetWidget(); - m_pTablesList->SetCheckHandler(LINK(this,OGenericAdministrationPage,OnControlModified)); + rWidget.set_size_request(rWidget.get_approximate_digit_width() * 48, + rWidget.get_height_rows(12)); // initialize the TabListBox - m_pTablesList->SetSelectionMode( SelectionMode::Multiple ); - m_pTablesList->SetDragDropMode( DragDropMode::NONE ); - m_pTablesList->EnableInplaceEditing( false ); - m_pTablesList->SetStyle(m_pTablesList->GetStyle() | WB_BORDER | WB_HASLINES | WB_HASLINESATROOT | WB_SORT | WB_HASBUTTONS | WB_HSCROLL |WB_HASBUTTONSATROOT); + rWidget.set_selection_mode(SelectionMode::Multiple); - m_pTablesList->Clear(); - - m_pTablesList->SetCheckButtonHdl(LINK(this, OTableSubscriptionPage, OnTreeEntryButtonChecked)); - m_pTablesList->SetCheckHandler(LINK(this, OTableSubscriptionPage, OnTreeEntryChecked)); + rWidget.connect_toggled(LINK(this, OTableSubscriptionPage, OnTreeEntryChecked)); } OTableSubscriptionPage::~OTableSubscriptionPage() @@ -107,34 +100,10 @@ namespace dbaui ::comphelper::disposeComponent(m_xCurrentConnection); } catch (RuntimeException&) { } - m_pTables.clear(); - m_pTablesList.clear(); m_pTablesDlg.clear(); OGenericAdministrationPage::dispose(); } - void OTableSubscriptionPage::StateChanged( StateChangedType nType ) - { - OGenericAdministrationPage::StateChanged( nType ); - - if ( nType == StateChangedType::ControlBackground ) - { - // Check if we need to get new images for normal/high contrast mode - m_pTablesList->notifyHiContrastChanged(); - } - } - void OTableSubscriptionPage::DataChanged( const DataChangedEvent& rDCEvt ) - { - OGenericAdministrationPage::DataChanged( rDCEvt ); - - if ((( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) || - ( rDCEvt.GetType() == DataChangedEventType::DISPLAY )) && - ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE )) - { - // Check if we need to get new images for normal/high contrast mode - m_pTablesList->notifyHiContrastChanged(); - } - } void OTableSubscriptionPage::implCheckTables(const Sequence< OUString >& _rTables) { // the meta data for the current connection, used for splitting up table names @@ -155,7 +124,7 @@ namespace dbaui // check the ones which are in the list OUString sCatalog, sSchema, sName; - SvTreeListEntry* pRootEntry = m_pTablesList->getAllObjectsEntry(); + std::unique_ptr<weld::TreeIter> xRootEntry(m_xTablesList->getAllObjectsEntry()); for (const OUString& rIncludeTable : _rTables) { @@ -168,34 +137,34 @@ namespace dbaui bool bAllSchemas = (1 == sSchema.getLength()) && ('%' == sSchema[0]); // the catalog entry - SvTreeListEntry* pCatalog = m_pTablesList->GetEntryPosByName(sCatalog, pRootEntry); - if (!(pCatalog || sCatalog.isEmpty())) + std::unique_ptr<weld::TreeIter> xCatalog(m_xTablesList->GetEntryPosByName(sCatalog, xRootEntry.get())); + if (!(xCatalog || sCatalog.isEmpty())) // the table (resp. its catalog) referred in this filter entry does not exist anymore continue; - if (bAllSchemas && pCatalog) + if (bAllSchemas && xCatalog) { - m_pTablesList->checkWildcard(pCatalog); + m_xTablesList->checkWildcard(*xCatalog); continue; } // the schema entry - SvTreeListEntry* pSchema = m_pTablesList->GetEntryPosByName(sSchema, (pCatalog ? pCatalog : pRootEntry)); - if (!(pSchema || sSchema.isEmpty())) + std::unique_ptr<weld::TreeIter> xSchema = m_xTablesList->GetEntryPosByName(sSchema, (xCatalog ? xCatalog.get() : xRootEntry.get())); + if (!(xSchema || sSchema.isEmpty())) // the table (resp. its schema) referred in this filter entry does not exist anymore continue; - if (bAllTables && pSchema) + if (bAllTables && xSchema) { - m_pTablesList->checkWildcard(pSchema); + m_xTablesList->checkWildcard(*xSchema); continue; } - SvTreeListEntry* pEntry = m_pTablesList->GetEntryPosByName(sName, pSchema ? pSchema : (pCatalog ? pCatalog : pRootEntry) ); - if (pEntry) - m_pTablesList->SetCheckButtonState(pEntry, SvButtonState::Checked); + std::unique_ptr<weld::TreeIter> xEntry(m_xTablesList->GetEntryPosByName(sName, xSchema ? xSchema.get() : (xCatalog ? xCatalog.get() : xRootEntry.get()))); + if (xEntry) + m_xTablesList->GetWidget().set_toggle(*xEntry, TRISTATE_TRUE, 0); } - m_pTablesList->CheckButtons(); + m_xTablesList->CheckButtons(); } void OTableSubscriptionPage::implCompleteTablesCheck( const css::uno::Sequence< OUString >& _rTableFilter ) @@ -236,7 +205,7 @@ namespace dbaui { if (!m_pTablesDlg->getCurrentSettings(aConnectionParams)) { - m_pTablesList->Clear(); + m_xTablesList->GetWidget().clear(); m_pTablesDlg->endExecution(); return; } @@ -265,9 +234,8 @@ namespace dbaui try { - WaitObject aWaitCursor(this); - m_pTablesList->GetModel()->SetSortMode(SortAscending); - m_pTablesList->GetModel()->SetCompareHdl(LINK(this, OTableSubscriptionPage, OnTreeEntryCompare)); + weld::WaitObject aWaitCursor(GetDialogFrameWeld()); + m_xTablesList->GetWidget().set_sort_order(false); Reference<XPropertySet> xProp = m_pTablesDlg->getCurrentDataSource(); OSL_ENSURE(xProp.is(),"No data source set!"); @@ -296,7 +264,7 @@ namespace dbaui if ( m_xCurrentConnection.is() ) { - m_pTablesList->UpdateTableList( m_xCurrentConnection ); + m_xTablesList->UpdateTableList( m_xCurrentConnection ); if (m_pTablesDlg) m_pTablesDlg->successfullyConnected(); } @@ -312,8 +280,8 @@ namespace dbaui vcl::Window *pParent = GetParentDialog(); OSQLMessageBox aMessageBox(pParent ? pParent->GetFrameWeld() : nullptr, aErrorInfo); aMessageBox.run(); - m_pTables->Enable(false); - m_pTablesList->Clear(); + m_xTables->set_sensitive(false); + m_xTablesList->GetWidget().clear(); if ( m_pTablesDlg ) { @@ -353,13 +321,15 @@ namespace dbaui implCompleteTablesCheck( aTableFilter ); // expand the first entry by default - SvTreeListEntry* pExpand = m_pTablesList->getAllObjectsEntry(); - while (pExpand) + std::unique_ptr<weld::TreeIter> xExpand = m_xTablesList->getAllObjectsEntry(); + while (xExpand) { - m_pTablesList->Expand(pExpand); - pExpand = m_pTablesList->FirstChild(pExpand); - if (pExpand && pExpand->NextSibling()) - pExpand = nullptr; + m_xTablesList->GetWidget().expand_row(*xExpand); + if (!m_xTablesList->GetWidget().iter_children(*xExpand)) + break; + std::unique_ptr<weld::TreeIter> xSibling(m_xTablesList->GetWidget().make_iterator(xExpand.get())); + if (m_xTablesList->GetWidget().iter_next_sibling(*xSibling)) + xExpand.reset(); } // update the toolbox according the current selection and check state @@ -368,16 +338,22 @@ namespace dbaui void OTableSubscriptionPage::CheckAll( bool _bCheck ) { - SvButtonState eState = _bCheck ? SvButtonState::Checked : SvButtonState::Unchecked; - SvTreeListEntry* pEntry = m_pTablesList->First(); - while (pEntry) + std::unique_ptr<weld::TreeIter> xEntry(m_xTablesList->GetWidget().make_iterator()); + if (m_xTablesList->GetWidget().get_iter_first(*xEntry)) { - m_pTablesList->SetCheckButtonState( pEntry, eState); - pEntry = m_pTablesList->Next(pEntry); + do + { + m_xTablesList->GetWidget().set_toggle(*xEntry, _bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, 0); + } + while (m_xTablesList->GetWidget().iter_next(*xEntry)); } - if (_bCheck && m_pTablesList->getAllObjectsEntry()) - m_pTablesList->checkWildcard(m_pTablesList->getAllObjectsEntry()); + if (_bCheck) + { + auto xRoot = m_xTablesList->getAllObjectsEntry(); + if (xRoot) + m_xTablesList->checkWildcard(*xRoot); + } } DeactivateRC OTableSubscriptionPage::DeactivatePage(SfxItemSet* _pSet) @@ -393,88 +369,66 @@ namespace dbaui return nResult; } - IMPL_LINK_NOARG( OTableSubscriptionPage, OnTreeEntryButtonChecked, SvTreeListBox*, void ) + + IMPL_LINK_NOARG(OTableSubscriptionPage, OnTreeEntryChecked, const row_col&, void) { + weld::TreeView& rTreeView = m_xTablesList->GetWidget(); + std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator()); + if (rTreeView.get_cursor(xEntry.get())) + m_xTablesList->checkedButton_noBroadcast(*xEntry); callModifiedHdl(); } - IMPL_LINK( OTableSubscriptionPage, OnTreeEntryChecked, void*, _pControl, void ) - { - OnControlModified(_pControl); - } - IMPL_LINK( OTableSubscriptionPage, OnTreeEntryCompare, const SvSortData&, _rSortData, sal_Int32 ) - { - const SvTreeListEntry* pLHS = _rSortData.pLeft; - const SvTreeListEntry* pRHS = _rSortData.pRight; - OSL_ENSURE(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!"); - - const SvLBoxString* pLeftTextItem = static_cast<const SvLBoxString*>(pLHS->GetFirstItem(SvLBoxItemType::String)); - const SvLBoxString* pRightTextItem = static_cast<const SvLBoxString*>(pRHS->GetFirstItem(SvLBoxItemType::String)); - OSL_ENSURE(pLeftTextItem && pRightTextItem, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid text items!"); - - OUString sLeftText = pLeftTextItem->GetText(); - OUString sRightText = pRightTextItem->GetText(); - - sal_Int32 nCompareResult = 0; // equal by default - - if (m_xCollator.is()) - { - try - { - nCompareResult = m_xCollator->compareString(sLeftText, sRightText); - } - catch(Exception&) - { - } - } - else - // default behaviour if we do not have a collator -> do the simple string compare - nCompareResult = sLeftText.compareTo(sRightText); - - return nCompareResult; - } Sequence< OUString > OTableSubscriptionPage::collectDetailedSelection() const { Sequence< OUString > aTableFilter; static const char sWildcard[] = "%"; - const SvTreeListEntry* pAllObjectsEntry = m_pTablesList->getAllObjectsEntry(); - if (!pAllObjectsEntry) + std::unique_ptr<weld::TreeIter> xAllObjectsEntry(m_xTablesList->getAllObjectsEntry()); + if (!xAllObjectsEntry) return aTableFilter; - SvTreeListEntry* pEntry = m_pTablesList->GetModel()->Next(const_cast<SvTreeListEntry*>(pAllObjectsEntry)); - while(pEntry) + std::unique_ptr<weld::TreeIter> xEntry(m_xTablesList->GetWidget().make_iterator(xAllObjectsEntry.get())); + if (!m_xTablesList->GetWidget().iter_next(*xEntry)) + xEntry.reset(); + while (xEntry) { bool bCatalogWildcard = false; bool bSchemaWildcard = false; - SvTreeListEntry* pSchema = nullptr; - SvTreeListEntry* pCatalog = nullptr; + std::unique_ptr<weld::TreeIter> xSchema; + std::unique_ptr<weld::TreeIter> xCatalog; - if (m_pTablesList->GetCheckButtonState(pEntry) == SvButtonState::Checked && !m_pTablesList->GetModel()->HasChildren(pEntry)) + if (m_xTablesList->GetWidget().get_toggle(*xEntry, 0) == TRISTATE_TRUE && !m_xTablesList->GetWidget().iter_has_child(*xEntry)) { // checked and a leaf, which means it's no catalog, no schema, but a real table OUStringBuffer sComposedName; OUString sCatalog; - if(m_pTablesList->GetModel()->HasParent(pEntry)) + if (m_xTablesList->GetWidget().get_iter_depth(*xEntry)) { - pSchema = m_pTablesList->GetModel()->GetParent(pEntry); - if (pAllObjectsEntry == pSchema) + xSchema = m_xTablesList->GetWidget().make_iterator(xEntry.get()); + m_xTablesList->GetWidget().iter_parent(*xSchema); + if (xAllObjectsEntry->equal(*xSchema)) + { // do not want to have the root entry - pSchema = nullptr; + xSchema.reset(); + } - if (pSchema) + if (xSchema) { // it's a real schema entry, not the "all objects" root - if(m_pTablesList->GetModel()->HasParent(pSchema)) + if (m_xTablesList->GetWidget().get_iter_depth(*xSchema)) { - pCatalog = m_pTablesList->GetModel()->GetParent(pSchema); - if (pAllObjectsEntry == pCatalog) + xCatalog = m_xTablesList->GetWidget().make_iterator(xSchema.get()); + m_xTablesList->GetWidget().iter_parent(*xCatalog); + if (xAllObjectsEntry->equal(*xCatalog)) + { // do not want to have the root entry - pCatalog = nullptr; + xCatalog.reset(); + } - if (pCatalog) + if (xCatalog) { // it's a real catalog entry, not the "all objects" root - bCatalogWildcard = OTableTreeListBox::isWildcardChecked(pCatalog); + bCatalogWildcard = m_xTablesList->isWildcardChecked(*xCatalog); if (m_bCatalogAtStart) { - sComposedName.append(m_pTablesList->GetEntryText( pCatalog )).append(m_sCatalogSeparator); + sComposedName.append(m_xTablesList->GetWidget().get_text(*xCatalog)).append(m_sCatalogSeparator); if (bCatalogWildcard) sComposedName.append(sWildcard); } @@ -484,19 +438,19 @@ namespace dbaui sCatalog = sWildcard; else sCatalog.clear(); - sCatalog += m_sCatalogSeparator + m_pTablesList->GetEntryText( pCatalog ); + sCatalog += m_sCatalogSeparator + m_xTablesList->GetWidget().get_text(*xCatalog) ; } } } - bSchemaWildcard = OTableTreeListBox::isWildcardChecked(pSchema); - sComposedName.append(m_pTablesList->GetEntryText( pSchema )).append("."); + bSchemaWildcard = m_xTablesList->isWildcardChecked(*xSchema); + sComposedName.append(m_xTablesList->GetWidget().get_text(*xSchema)).append("."); } if (bSchemaWildcard) sComposedName.append(sWildcard); } if (!bSchemaWildcard && !bCatalogWildcard) - sComposedName.append(m_pTablesList->GetEntryText( pEntry )); + sComposedName.append(m_xTablesList->GetWidget().get_text(*xEntry)); if (!m_bCatalogAtStart && !bCatalogWildcard) sComposedName.append(sCatalog); @@ -509,26 +463,35 @@ namespace dbaui } if (bCatalogWildcard) - pEntry = implNextSibling(pCatalog); + xEntry = implNextSibling(xCatalog.get()); else if (bSchemaWildcard) - pEntry = implNextSibling(pSchema); + xEntry = implNextSibling(xSchema.get()); else - pEntry = m_pTablesList->GetModel()->Next(pEntry); + { + if (!m_xTablesList->GetWidget().iter_next(*xEntry)) + xEntry.reset(); + } } return aTableFilter; } - SvTreeListEntry* OTableSubscriptionPage::implNextSibling(SvTreeListEntry* _pEntry) const + std::unique_ptr<weld::TreeIter> OTableSubscriptionPage::implNextSibling(weld::TreeIter* pEntry) const { - SvTreeListEntry* pReturn = nullptr; - if (_pEntry) + std::unique_ptr<weld::TreeIter> xReturn; + if (pEntry) { - pReturn = _pEntry->NextSibling(); - if (!pReturn) - pReturn = implNextSibling(m_pTablesList->GetParent(_pEntry)); + xReturn = m_xTablesList->GetWidget().make_iterator(pEntry); + if (!m_xTablesList->GetWidget().iter_next_sibling(*xReturn)) + { + std::unique_ptr<weld::TreeIter> xParent = m_xTablesList->GetWidget().make_iterator(pEntry); + if (m_xTablesList->GetWidget().iter_parent(*xParent)) + xReturn = implNextSibling(xParent.get()); + else + xReturn.reset(); + } } - return pReturn; + return xReturn; } bool OTableSubscriptionPage::FillItemSet( SfxItemSet* _rCoreAttrs ) @@ -544,7 +507,8 @@ namespace dbaui if ( m_xCurrentConnection.is() ) { // collect the table filter data only if we have a connection - else no tables are displayed at all Sequence< OUString > aTableFilter; - if (dbaui::OTableTreeListBox::isWildcardChecked(m_pTablesList->getAllObjectsEntry())) + auto xRoot = m_xTablesList->getAllObjectsEntry(); + if (xRoot && m_xTablesList->isWildcardChecked(*xRoot)) { aTableFilter.realloc(1); aTableFilter[0] = "%"; @@ -565,7 +529,7 @@ namespace dbaui void OTableSubscriptionPage::fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) { - _rControlList.emplace_back(new ODisableWrapper<VclContainer>(m_pTables)); + _rControlList.emplace_back(new ODisableWidgetWrapper<weld::Widget>(m_xTables.get())); } } // namespace dbaui diff --git a/dbaccess/source/ui/dlg/tablespage.hxx b/dbaccess/source/ui/dlg/tablespage.hxx index aaaebdb01acb..d432b1f917b6 100644 --- a/dbaccess/source/ui/dlg/tablespage.hxx +++ b/dbaccess/source/ui/dlg/tablespage.hxx @@ -35,9 +35,6 @@ namespace dbaui :public OGenericAdministrationPage { private: - VclPtr<VclContainer> m_pTables; - VclPtr<OTableTreeListBox> m_pTablesList; - OUString m_sCatalogSeparator; bool m_bCatalogAtStart : 1; @@ -47,15 +44,15 @@ namespace dbaui m_xCollator; VclPtr<OTableSubscriptionDialog> m_pTablesDlg; + std::unique_ptr<weld::Widget> m_xTables; + std::unique_ptr<TableTreeListBox> m_xTablesList; + public: virtual bool FillItemSet(SfxItemSet* _rCoreAttrs) override; virtual DeactivateRC DeactivatePage(SfxItemSet* _pSet) override; using OGenericAdministrationPage::DeactivatePage; - virtual void StateChanged( StateChangedType nStateChange ) override; - virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; - - OTableSubscriptionPage( vcl::Window* pParent, const SfxItemSet& _rCoreAttrs ,OTableSubscriptionDialog* _pTablesDlg); + OTableSubscriptionPage(TabPageParent pParent, const SfxItemSet& _rCoreAttrs ,OTableSubscriptionDialog* _pTablesDlg); virtual ~OTableSubscriptionPage() override; virtual void dispose() override; @@ -63,16 +60,15 @@ namespace dbaui virtual void fillControls(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override; virtual void fillWindows(std::vector< std::unique_ptr<ISaveValueWrapper> >& _rControlList) override; - DECL_LINK( OnTreeEntryCompare, const SvSortData&, sal_Int32 ); - DECL_LINK( OnTreeEntryChecked, void*, void ); - DECL_LINK( OnTreeEntryButtonChecked, SvTreeListBox*, void ); + typedef std::pair<int, int> row_col; + DECL_LINK(OnTreeEntryChecked, const row_col&, void); /** check the tables in <member>m_aTablesList</member> according to <arg>_rTables</arg> */ void implCheckTables(const css::uno::Sequence< OUString >& _rTables); /// returns the next sibling, if not available, the next sibling of the parent, a.s.o. - SvTreeListEntry* implNextSibling(SvTreeListEntry* _pEntry) const; + std::unique_ptr<weld::TreeIter> implNextSibling(weld::TreeIter* pEntry) const; /** return the current selection in <member>m_aTablesList</member> */ diff --git a/dbaccess/source/ui/inc/dbtreelistbox.hxx b/dbaccess/source/ui/inc/dbtreelistbox.hxx index 7e3beb87d480..f66b07a5ffc2 100644 --- a/dbaccess/source/ui/inc/dbtreelistbox.hxx +++ b/dbaccess/source/ui/inc/dbtreelistbox.hxx @@ -26,6 +26,7 @@ #include <vcl/treelistbox.hxx> #include <vcl/timer.hxx> +#include <vcl/weld.hxx> #include <memory> #include <set> @@ -40,7 +41,7 @@ namespace dbaui class IEntryFilter { public: - virtual bool includeEntry( SvTreeListEntry* _pEntry ) const = 0; + virtual bool includeEntry(const void* pUserData) const = 0; protected: ~IEntryFilter() {} diff --git a/dbaccess/source/ui/inc/imageprovider.hxx b/dbaccess/source/ui/inc/imageprovider.hxx index d9e7b53e55b3..ee8a5a44d8d6 100644 --- a/dbaccess/source/ui/inc/imageprovider.hxx +++ b/dbaccess/source/ui/inc/imageprovider.hxx @@ -22,6 +22,7 @@ #include <vcl/image.hxx> +#include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/sdbc/XConnection.hpp> #include <com/sun/star/sdb/application/DatabaseObject.hpp> @@ -77,6 +78,15 @@ namespace dbaui Image& _out_rImage ); + OUString getImageId( + const OUString& _rName, + const sal_Int32 _nDatabaseObjectType + ); + + // check whether the connection can give us an icon + css::uno::Reference<css::graphic::XGraphic> getXGraphic(const OUString& _rName, + const sal_Int32 _nDatabaseObjectType); + /** returns the default image to be used for a database object In opposite to getImages, this method does not check the concrete object @@ -119,6 +129,9 @@ namespace dbaui static Image getFolderImage( sal_Int32 _nDatabaseObjectType ); + static OUString getFolderImageId( + sal_Int32 _nDatabaseObjectType + ); /** retrieves the image to be used for a database as a whole. @return diff --git a/dbaccess/source/ui/inc/tabletree.hxx b/dbaccess/source/ui/inc/tabletree.hxx index 22047acba375..e5f9e32a5e21 100644 --- a/dbaccess/source/ui/inc/tabletree.hxx +++ b/dbaccess/source/ui/inc/tabletree.hxx @@ -29,6 +29,7 @@ #include <com/sun/star/sdbc/XConnection.hpp> #include <com/sun/star/sdbc/XDriver.hpp> #include <com/sun/star/sdb/application/NamedDatabaseObject.hpp> +#include <vcl/weld.hxx> #include <memory> namespace dbaui @@ -118,7 +119,7 @@ public: /** determine if the given entry is 'wildcard checked' @see checkWildcard */ - static bool isWildcardChecked(SvTreeListEntry* _pEntry); + static bool isWildcardChecked(SvTreeListEntry* pEntry); private: virtual void InitEntry(SvTreeListEntry* _pEntry, const OUString& _rString, const Image& _rCollapsedBitmap, const Image& _rExpandedBitmap, SvLBoxButtonKind _eButtonKind) override; @@ -158,6 +159,126 @@ private: }; +class TableTreeListBox +{ + css::uno::Reference< css::sdbc::XConnection > + m_xConnection; // the connection we're working for, set in implOnNewConnection, called by UpdateTableList + std::unique_ptr< ImageProvider > + m_xImageProvider; // provider for our images + bool m_bVirtualRoot; // should the first entry be visible + bool m_bNoEmptyFolders; // should empty catalogs/schematas be prevented from being displayed? + std::unique_ptr<weld::TreeView> m_xTreeView; + +public: + TableTreeListBox(std::unique_ptr<weld::TreeView> xTreeView); + + weld::TreeView& GetWidget() { return *m_xTreeView; } + + void init() { m_bVirtualRoot = true; } + + typedef std::pair< OUString, bool > TTableViewName; + typedef std::vector< TTableViewName > TNames; + + void suppressEmptyFolders() { m_bNoEmptyFolders = true; } + + /** determines whether the given entry denotes a tables folder + */ + static bool isFolderEntry( const SvTreeListEntry* _pEntry ); + + /** fill the table list with the tables belonging to the connection described by the parameters + @param _rxConnection + the connection, which must support the service com.sun.star.sdb.Connection + @throws + <type scope="css::sdbc">SQLException</type> if no connection could be created + */ + void UpdateTableList( + const css::uno::Reference< css::sdbc::XConnection >& _rxConnection + ); + + /** fill the table list with the tables and views determined by the two given containers. + The views sequence is used to determine which table is of type view. + @param _rxConnection the connection where you got the object names from. Must not be NULL. + Used to split the full qualified names into its parts. + @param _rTables table/view sequence + @param _rViews view sequence + */ + void UpdateTableList( + const css::uno::Reference< css::sdbc::XConnection >& _rxConnection, + const css::uno::Sequence< OUString>& _rTables, + const css::uno::Sequence< OUString>& _rViews + ); + + /** returns a NamedDatabaseObject record which describes the given entry + */ + css::sdb::application::NamedDatabaseObject + describeObject( SvTreeListEntry* _pEntry ); + + /** to be used if a foreign instance added a table + */ + SvTreeListEntry* addedTable( const OUString& _rName ); + + /** to be used if a foreign instance removed a table + */ + void removedTable( const OUString& _rName ); + + /** returns the fully qualified name of a table entry + @param _pEntry + the entry whose name is to be obtained. Must not denote a folder entry. + */ + OUString getQualifiedTableName( SvTreeListEntry* _pEntry ) const; + + SvTreeListEntry* getEntryByQualifiedName( const OUString& _rName ); + + std::unique_ptr<weld::TreeIter> getAllObjectsEntry() const; + + /** does a wildcard check of the given entry + <p>There are two different 'checked' states: If the user checks all children of an entry, this is different + from checking the entry itself. The second is called 'wildcard' checking, 'cause in the resulting + table filter it's represented by a wildcard.</p> + */ + void checkWildcard(weld::TreeIter& rEntry); + + /** determine if the given entry is 'wildcard checked' + @see checkWildcard + */ + bool isWildcardChecked(weld::TreeIter& rEntry); + + std::unique_ptr<weld::TreeIter> GetEntryPosByName(const OUString& aName, weld::TreeIter* pStart = nullptr, const IEntryFilter* _pFilter = nullptr) const; + + void CheckButtons(); // make the button states consistent (bottom-up) + + void checkedButton_noBroadcast(weld::TreeIter& rEntry); +private: + TriState implDetermineState(weld::TreeIter& rEntry); + + void implEmphasize(weld::TreeIter& rEntry, bool _bChecked, bool _bUpdateDescendants = true, bool _bUpdateAncestors = true); + + /** adds the given entry to our list + @precond + our image provider must already have been reset to the connection to which the meta data + belong. + */ + void implAddEntry( + const css::uno::Reference< css::sdbc::XDatabaseMetaData >& _rxMeta, + const OUString& _rTableName, + bool _bCheckName = true + ); + + void implOnNewConnection( const css::uno::Reference< css::sdbc::XConnection >& _rxConnection ); + + bool haveVirtualRoot() const { return m_bVirtualRoot; } + + /** fill the table list with the tables and views determined by the two given containers + @param _rxConnection the connection where you got the object names from. Must not be NULL. + Used to split the full qualified names into its parts. + @param _rTables table/view sequence, the second argument is <TRUE/> if it is a table, otherwise it is a view. + */ + void UpdateTableList( + const css::uno::Reference< css::sdbc::XConnection >& _rxConnection, + const TNames& _rTables + ); +}; + } // namespace dbaui #endif // INCLUDED_DBACCESS_SOURCE_UI_INC_TABLETREE_HXX diff --git a/dbaccess/source/ui/misc/imageprovider.cxx b/dbaccess/source/ui/misc/imageprovider.cxx index a17795afc449..426f99252537 100644 --- a/dbaccess/source/ui/misc/imageprovider.cxx +++ b/dbaccess/source/ui/misc/imageprovider.cxx @@ -21,7 +21,6 @@ #include <stringconstants.hxx> #include <bitmaps.hlst> -#include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/graphic/GraphicColorMode.hpp> #include <com/sun/star/sdb/application/XTableUIProvider.hpp> #include <com/sun/star/sdbcx/XViewsSupplier.hpp> @@ -144,6 +143,33 @@ namespace dbaui } } + OUString ImageProvider::getImageId(const OUString& _rName, const sal_Int32 _nDatabaseObjectType) + { + if (_nDatabaseObjectType != DatabaseObject::TABLE) + { + // for types other than tables, the icon does not depend on the concrete object + return getDefaultImageResourceID( _nDatabaseObjectType ); + } + else + { + // no -> determine by type + OUString sImageResourceID; + lcl_getTableImageResourceID_nothrow( *m_pData, _rName, sImageResourceID ); + return sImageResourceID; + } + } + + Reference<XGraphic> ImageProvider::getXGraphic(const OUString& _rName, const sal_Int32 _nDatabaseObjectType) + { + Reference<XGraphic> xGraphic; + if (_nDatabaseObjectType == DatabaseObject::TABLE) + { + // check whether the connection can give us an icon + lcl_getConnectionProvidedTableIcon_nothrow( *m_pData, _rName, xGraphic ); + } + return xGraphic; + } + Image ImageProvider::getDefaultImage( sal_Int32 _nDatabaseObjectType ) { Image aObjectImage; @@ -205,6 +231,31 @@ namespace dbaui return aFolderImage; } + OUString ImageProvider::getFolderImageId( sal_Int32 _nDatabaseObjectType ) + { + OUString sImageResourceID; + switch ( _nDatabaseObjectType ) + { + case DatabaseObject::QUERY: + sImageResourceID = QUERYFOLDER_TREE_ICON; + break; + case DatabaseObject::FORM: + sImageResourceID = FORMFOLDER_TREE_ICON; + break; + case DatabaseObject::REPORT: + sImageResourceID = REPORTFOLDER_TREE_ICON; + break; + case DatabaseObject::TABLE: + sImageResourceID = TABLEFOLDER_TREE_ICON; + break; + default: + OSL_FAIL( "ImageProvider::getDefaultImage: invalid database object type!" ); + break; + } + + return sImageResourceID; + } + Image ImageProvider::getDatabaseImage() { return Image(StockImage::Yes, DATABASE_TREE_ICON); |