sync OTableTreeListBox and TableTreeListBox

Change-Id: I52c26e055c599e266221d6092957a0e764744e20
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100409
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/dbaccess/source/ui/control/tabletree.cxx b/dbaccess/source/ui/control/tabletree.cxx
index 414cacb..b565b62 100644
--- a/dbaccess/source/ui/control/tabletree.cxx
+++ b/dbaccess/source/ui/control/tabletree.cxx
@@ -62,6 +62,8 @@ namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::Database
OTableTreeListBox::OTableTreeListBox(vcl::Window* pParent, WinBits nWinStyle)
    : DBTreeListBox(pParent, nWinStyle)
    , m_xImageProvider( new ImageProvider )
    , m_bVirtualRoot(false)
    , m_bNoEmptyFolders( false )
{
    InitButtonData();

@@ -326,6 +328,20 @@ void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConn

    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);
            InsertEntry( sRootEntryText, nullptr, false, TREELIST_APPEND, reinterpret_cast< void* >( DatabaseObjectContainer::TABLES ) );
        }

        if ( _rTables.empty() )
            // nothing to do (besides inserting the root entry)
            return;
@@ -335,14 +351,10 @@ void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConn
        for (auto const& table : _rTables)
        {
            // add the entry
            implAddEntry(
                xMeta,
                table.first,
                false
            );
            implAddEntry(xMeta, table.first, false);
        }

        if ( lcl_shouldDisplayEmptySchemasAndCatalogs( _rxConnection ) )
        if ( !m_bNoEmptyFolders && lcl_shouldDisplayEmptySchemasAndCatalogs( _rxConnection ) )
        {
            bool bSupportsCatalogs = xMeta->supportsCatalogsInDataManipulation();
            bool bSupportsSchemas = xMeta->supportsSchemasInDataManipulation();
@@ -358,11 +370,12 @@ void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConn
                    bCatalogs ? xMeta->getCatalogs() : xMeta->getSchemas(), 1 ) );
                sal_Int32 nFolderType = bCatalogs ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA;

                SvTreeListEntry* pRootEntry = getAllObjectsEntry();
                for (auto const& folderName : aFolderNames)
                {
                    SvTreeListEntry* pFolder = GetEntryPosByName( folderName, nullptr );
                    SvTreeListEntry* pFolder = GetEntryPosByName( folderName, pRootEntry );
                    if ( !pFolder )
                        InsertEntry( folderName, nullptr, false, TREELIST_APPEND, reinterpret_cast< void* >( nFolderType ) );
                        InsertEntry( folderName, pRootEntry, false, TREELIST_APPEND, reinterpret_cast< void* >( nFolderType ) );
                }
            }
        }
@@ -419,7 +432,7 @@ void TableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConne
        for (auto const& table : _rTables)
        {
            // add the entry
            implAddEntry(xMeta, table.first);
            implAddEntry(xMeta, table.first, false);
        }

        if ( !m_bNoEmptyFolders && lcl_shouldDisplayEmptySchemasAndCatalogs( _rxConnection ) )
@@ -467,11 +480,28 @@ void TableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConne
    m_xTreeView->make_sorted();
}

bool OTableTreeListBox::isWildcardChecked(SvTreeListEntry* _pEntry)
{
    if (_pEntry)
    {
        OBoldListboxString* pTextItem = static_cast<OBoldListboxString*>(_pEntry->GetFirstItem(SvLBoxItemType::String));
        if (pTextItem)
            return pTextItem->isEmphasized();
    }
    return false;
}

bool TableTreeListBox::isWildcardChecked(const weld::TreeIter& rEntry)
{
    return m_xTreeView->get_text_emphasis(rEntry, 0);
}

void OTableTreeListBox::checkWildcard(SvTreeListEntry* _pEntry)
{
    SetCheckButtonState(_pEntry, SvButtonState::Checked);
    checkedButton_noBroadcast(_pEntry);
}

void TableTreeListBox::checkWildcard(weld::TreeIter& rEntry)
{
    if (!m_bShowToggles)
@@ -480,6 +510,11 @@ void TableTreeListBox::checkWildcard(weld::TreeIter& rEntry)
    checkedButton_noBroadcast(rEntry);
}

SvTreeListEntry* OTableTreeListBox::getAllObjectsEntry() const
{
    return haveVirtualRoot() ? First() : nullptr;
}

std::unique_ptr<weld::TreeIter> TableTreeListBox::getAllObjectsEntry() const
{
    if (!haveVirtualRoot())
@@ -600,6 +635,7 @@ void OTableTreeListBox::CheckButtons()
void OTableTreeListBox::CheckButtonHdl()
{
    checkedButton_noBroadcast(GetHdlEntry());
    m_aCheckButtonHandler.Call(this);
}

void OTableTreeListBox::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& _rRect)
@@ -695,11 +731,18 @@ void OTableTreeListBox::implEmphasize(SvTreeListEntry* _pEntry, bool _bChecked, 
{
    OSL_ENSURE(_pEntry, "OTableTreeListBox::implEmphasize: invalid entry (NULL)!");

    if ( GetModel()->HasChildren(_pEntry) )             // the entry has children
    // special emphasizing handling for the "all objects" entry
    bool bAllObjectsEntryAffected = haveVirtualRoot() && (getAllObjectsEntry() == _pEntry);
    if  (   GetModel()->HasChildren(_pEntry)              // the entry has children
        ||  bAllObjectsEntryAffected                    // or it is the "all objects" entry
        )
    {
        OBoldListboxString* pTextItem = static_cast<OBoldListboxString*>(_pEntry->GetFirstItem(SvLBoxItemType::String));
        if (pTextItem)
            pTextItem->emphasize(_bChecked);

        if (bAllObjectsEntryAffected)
            InvalidateEntry(_pEntry);
    }

    if (_bUpdateDescendants)
@@ -782,7 +825,7 @@ SvTreeListEntry* OTableTreeListBox::implAddEntry(
    OUString sCatalog, sSchema, sName;
    qualifiedNameComponents( _rxMeta, _rTableName, sCatalog, sSchema, sName, ::dbtools::EComposeRule::InDataManipulation );

    SvTreeListEntry* pParentEntry = nullptr;
    SvTreeListEntry* pParentEntry = getAllObjectsEntry();

    // if the DB uses catalog at the start of identifiers, then our hierarchy is
    //   catalog
@@ -830,7 +873,8 @@ SvTreeListEntry* OTableTreeListBox::implAddEntry(

void TableTreeListBox::implAddEntry(
        const Reference< XDatabaseMetaData >& _rxMeta,
        const OUString& _rTableName
        const OUString& _rTableName,
        bool _bCheckName
    )
{
    OSL_PRECOND( _rxMeta.is(), "OTableTreeListBox::implAddEntry: invalid meta data!" );
@@ -893,21 +937,24 @@ void TableTreeListBox::implAddEntry(
        xParentEntry = std::move(xFolder);
    }

    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
    m_xTreeView->insert(xParentEntry.get(), -1, 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
    if (!_bCheckName || !GetEntryPosByName(sName, xParentEntry.get()))
    {
        OUString sImageId(m_xImageProvider->getImageId(_rTableName, DatabaseObject::TABLE));
        m_xTreeView->set_image(*xEntry, sImageId, -1);
        std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
        m_xTreeView->insert(xParentEntry.get(), -1, 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);
        }
        if (m_bShowToggles)
            m_xTreeView->set_toggle(*xEntry, TRISTATE_FALSE);
        m_xTreeView->set_text(*xEntry, sName, 0);
        m_xTreeView->set_text_emphasis(*xEntry, false, 0);
    }
    if (m_bShowToggles)
        m_xTreeView->set_toggle(*xEntry, TRISTATE_FALSE);
    m_xTreeView->set_text(*xEntry, sName, 0);
    m_xTreeView->set_text_emphasis(*xEntry, false, 0);
}

NamedDatabaseObject OTableTreeListBox::describeObject( SvTreeListEntry* _pEntry )
@@ -1015,7 +1062,7 @@ SvTreeListEntry* OTableTreeListBox::getEntryByQualifiedName( const OUString& _rN
        OUString sCatalog, sSchema, sName;
        qualifiedNameComponents(xMeta, _rName, sCatalog, sSchema, sName,::dbtools::EComposeRule::InDataManipulation);

        SvTreeListEntry* pParent = nullptr;
        SvTreeListEntry* pParent = getAllObjectsEntry();
        SvTreeListEntry* pCat = nullptr;
        SvTreeListEntry* pSchema = nullptr;
        if ( !sCatalog.isEmpty() )
diff --git a/dbaccess/source/ui/inc/tabletree.hxx b/dbaccess/source/ui/inc/tabletree.hxx
index 179fce2..97b1ba7 100644
--- a/dbaccess/source/ui/inc/tabletree.hxx
+++ b/dbaccess/source/ui/inc/tabletree.hxx
@@ -36,18 +36,26 @@ namespace dbaui
class OTableTreeListBox final : public DBTreeListBox
{
    std::unique_ptr<SvLBoxButtonData> m_pCheckButton;
    Link<void*,void>    m_aCheckButtonHandler;

    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?

public:
    OTableTreeListBox(vcl::Window* pParent, WinBits nWinStyle);
    virtual void dispose() override;

    void init() { m_bVirtualRoot = true; }

    typedef std::pair< OUString, bool > TTableViewName;
    typedef std::vector< TTableViewName >         TNames;

    void    suppressEmptyFolders() { m_bNoEmptyFolders = true; }

    /** call when HiContrast change.
    */
    void notifyHiContrastChanged();
@@ -100,10 +108,24 @@ public:

    SvTreeListEntry*    getEntryByQualifiedName( const OUString& _rName );

    SvTreeListEntry*    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(SvTreeListEntry* _pEntry);

    /** determine if the given entry is 'wildcard checked'
        @see checkWildcard
    */
    static bool     isWildcardChecked(SvTreeListEntry* pEntry);

private:
    virtual void InitEntry(SvTreeListEntry* _pEntry, const OUString& _rString, const Image& _rCollapsedBitmap, const Image& _rExpandedBitmap) override;

    virtual void    CheckButtonHdl() override;
    virtual void CheckButtonHdl() override;
    void checkedButton_noBroadcast(SvTreeListEntry* _pEntry);

    void implEmphasize(SvTreeListEntry* _pEntry, bool _bChecked, bool _bUpdateDescendants = true, bool _bUpdateAncestors = true);
@@ -125,6 +147,8 @@ private:

    bool    impl_getAndAssertMetaData( css::uno::Reference< css::sdbc::XDatabaseMetaData >& _out_rMetaData ) const;

    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.
@@ -137,6 +161,9 @@ private:

    void InitButtonData();

    /// the handler given is called whenever the check state of one or more items changed
    void SetCheckHandler(const Link<void*,void>& _rHdl) { m_aCheckButtonHandler = _rHdl; }

    SvButtonState   implDetermineState(SvTreeListEntry* _pEntry);
        // determines the check state of the given entry, by analyzing the states of all descendants

@@ -170,6 +197,10 @@ public:
    void    SuppressEmptyFolders() { m_bNoEmptyFolders = true; }
    void    DisableCheckButtons();

    /** 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
@@ -193,6 +224,27 @@ public:
                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
@@ -224,7 +276,8 @@ private:
    */
    void implAddEntry(
            const css::uno::Reference< css::sdbc::XDatabaseMetaData >& _rxMeta,
            const OUString& _rTableName
            const OUString& _rTableName,
            bool _bCheckName = true
        );

    void    implOnNewConnection( const css::uno::Reference< css::sdbc::XConnection >& _rxConnection );