summaryrefslogtreecommitdiff
path: root/dbaccess
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-04-04 14:30:03 +0100
committerCaolán McNamara <caolanm@redhat.com>2019-04-06 19:53:00 +0200
commit5c32ba63163d9556ff89782a8074924cdf9dc554 (patch)
tree66acbb3b4c298c9f0cbff75f9e36bf3d759b7a0f /dbaccess
parent6f31c63e35abef03e6f938bbddc8778b70a62d43 (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')
-rw-r--r--dbaccess/source/ui/browser/unodatbr.cxx6
-rw-r--r--dbaccess/source/ui/control/dbtreelistbox.cxx2
-rw-r--r--dbaccess/source/ui/control/tabletree.cxx446
-rw-r--r--dbaccess/source/ui/dlg/tablespage.cxx254
-rw-r--r--dbaccess/source/ui/dlg/tablespage.hxx18
-rw-r--r--dbaccess/source/ui/inc/dbtreelistbox.hxx3
-rw-r--r--dbaccess/source/ui/inc/imageprovider.hxx13
-rw-r--r--dbaccess/source/ui/inc/tabletree.hxx123
-rw-r--r--dbaccess/source/ui/misc/imageprovider.cxx53
-rw-r--r--dbaccess/uiconfig/ui/tablesfilterpage.ui75
10 files changed, 820 insertions, 173 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);
diff --git a/dbaccess/uiconfig/ui/tablesfilterpage.ui b/dbaccess/uiconfig/ui/tablesfilterpage.ui
index c568e2101bdf..682f215cbaf9 100644
--- a/dbaccess/uiconfig/ui/tablesfilterpage.ui
+++ b/dbaccess/uiconfig/ui/tablesfilterpage.ui
@@ -1,8 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.16.0 on Tue Jan 21 15:00:47 2014 -->
+<!-- Generated with glade 3.22.1 -->
<interface domain="dba">
<requires lib="gtk+" version="3.18"/>
- <requires lib="LibreOffice" version="1.0"/>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ <!-- column-name weight1 -->
+ <column type="gint"/>
+ </columns>
+ </object>
<object class="GtkFrame" id="TablesFilterPage">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -30,33 +47,71 @@
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
<property name="label" translatable="yes" context="tablesfilterpage|label2">Mark the tables that should be visible for the applications.</property>
<property name="wrap">True</property>
<property name="max_width_chars">56</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
</packing>
</child>
<child>
- <object class="dbulo-OTableTreeListBox" id="treeview:border">
+ <object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection1"/>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="treeview">
+ <property name="width_request">-1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">1</property>
+ <property name="enable_tree_lines">True</property>
+ <property name="show_expanders">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn8">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">4</attribute>
+ <attribute name="active">0</attribute>
+ <attribute name="inconsistent">5</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext5"/>
+ <attributes>
+ <attribute name="pixbuf">1</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext6"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ <attribute name="weight">5</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
</packing>
</child>
</object>