weld DBTreeListBox
Change-Id: I4b7369a496339b9bbab0c885c7360a5d7818a62e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100329
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/dbaccess/UIConfig_dbaccess.mk b/dbaccess/UIConfig_dbaccess.mk
index feaa35c..8a4229e 100644
--- a/dbaccess/UIConfig_dbaccess.mk
+++ b/dbaccess/UIConfig_dbaccess.mk
@@ -23,6 +23,7 @@ $(eval $(call gb_UIConfig_add_uifiles,dbaccess, \
dbaccess/uiconfig/ui/copytablepage \
dbaccess/uiconfig/ui/dbaseindexdialog \
dbaccess/uiconfig/ui/dbasepage \
dbaccess/uiconfig/ui/dbtreelist \
dbaccess/uiconfig/ui/dbwizconnectionpage \
dbaccess/uiconfig/ui/dbwizmysqlintropage \
dbaccess/uiconfig/ui/dbwizmysqlnativepage \
diff --git a/dbaccess/source/ui/app/AppController.cxx b/dbaccess/source/ui/app/AppController.cxx
index 958d5d9c..67bd857 100644
--- a/dbaccess/source/ui/app/AppController.cxx
+++ b/dbaccess/source/ui/app/AppController.cxx
@@ -97,6 +97,7 @@
#include <strings.hrc>
#include <defaultobjectnamecheck.hxx>
#include <databaseobjectview.hxx>
#include <dbtreelistbox.hxx>
#include "AppDetailView.hxx"
#include <linkeddocuments.hxx>
#include <UITools.hxx>
@@ -1683,15 +1684,23 @@ bool OApplicationController::onContainerSelect(ElementType _eType)
return true;
}
bool OApplicationController::onEntryDoubleClick( SvTreeListBox const & _rTree )
bool OApplicationController::onEntryDoubleClick(const weld::TreeView& rTreeView)
{
if ( getContainer() && getContainer()->isLeaf( _rTree.GetHdlEntry() ) )
OApplicationView* pContainer = getContainer();
if (!pContainer)
return false; // not handled
std::unique_ptr<weld::TreeIter> xHdlEntry = rTreeView.make_iterator();
if (!rTreeView.get_cursor(xHdlEntry.get()))
return false;
if (pContainer->isLeaf(rTreeView, *xHdlEntry))
{
try
{
// opens a new frame with either the table or the query or report or form or view
openElementWithArguments(
getContainer()->getQualifiedName( _rTree.GetHdlEntry() ),
getContainer()->getQualifiedName(xHdlEntry.get()),
getContainer()->getElementType(),
E_OPEN_NORMAL,
0,
@@ -1703,6 +1712,7 @@ bool OApplicationController::onEntryDoubleClick( SvTreeListBox const & _rTree )
DBG_UNHANDLED_EXCEPTION("dbaccess");
}
}
return false; // not handled
}
@@ -2237,7 +2247,7 @@ void OApplicationController::onDeleteEntry()
executeChecked(nId,Sequence<PropertyValue>());
}
OUString OApplicationController::getContextMenuResourceName( Control& /*_rControl*/ ) const
OUString OApplicationController::getContextMenuResourceName() const
{
return "edit";
}
@@ -2264,6 +2274,11 @@ bool OApplicationController::requestQuickHelp( const SvTreeListEntry* /*_pEntry*
return false;
}
bool OApplicationController::requestQuickHelp(const void* /*pUserData*/, OUString& /*rText*/) const
{
return false;
}
bool OApplicationController::requestDrag( const Point& /*_rPosPixel*/ )
{
rtl::Reference<TransferableHelper> pTransfer;
@@ -2288,6 +2303,32 @@ bool OApplicationController::requestDrag( const Point& /*_rPosPixel*/ )
return pTransfer.is();
}
bool OApplicationController::requestDrag(const weld::TreeIter& /*rEntry*/)
{
rtl::Reference<TransferableHelper> pTransfer;
OApplicationView* pContainer = getContainer();
if (pContainer && pContainer->getSelectionCount())
{
try
{
pTransfer = copyObject( );
if ( pTransfer && getContainer()->getDetailView() )
{
ElementType eType = getContainer()->getElementType();
pTransfer->StartDrag( getContainer()->getDetailView()->getTreeWindow(), ((eType == E_FORM || eType == E_REPORT) ? DND_ACTION_COPYMOVE : DND_ACTION_COPY) );
}
}
catch(const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess");
}
}
return pTransfer.is();
}
sal_Int8 OApplicationController::queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors )
{
sal_Int8 nActionAskedFor = _rEvt.mnAction;
@@ -2306,11 +2347,11 @@ sal_Int8 OApplicationController::queryDrop( const AcceptDropEvent& _rEvt, const
sal_Int8 nAction = OComponentTransferable::canExtractComponentDescriptor(_rFlavors,eType == E_FORM) ? DND_ACTION_COPY : DND_ACTION_NONE;
if ( nAction != DND_ACTION_NONE )
{
SvTreeListEntry* pHitEntry = pView->getEntry(_rEvt.maPosPixel);
auto xHitEntry = pView->getEntry(_rEvt.maPosPixel);
OUString sName;
if ( pHitEntry )
if (xHitEntry)
{
sName = pView->getQualifiedName( pHitEntry );
sName = pView->getQualifiedName(xHitEntry.get());
if ( !sName.isEmpty() )
{
Reference< XHierarchicalNameAccess > xContainer(getElements(pView->getElementType()),UNO_QUERY);
@@ -2371,9 +2412,9 @@ sal_Int8 OApplicationController::executeDrop( const ExecuteDropEvent& _rEvt )
else if ( OComponentTransferable::canExtractComponentDescriptor(aDroppedData.GetDataFlavorExVector(),m_aAsyncDrop.nType == E_FORM) )
{
m_aAsyncDrop.aDroppedData = OComponentTransferable::extractComponentDescriptor(aDroppedData);
SvTreeListEntry* pHitEntry = pView->getEntry(_rEvt.maPosPixel);
if ( pHitEntry )
m_aAsyncDrop.aUrl = pView->getQualifiedName( pHitEntry );
auto xHitEntry = pView->getEntry(_rEvt.maPosPixel);
if ( xHitEntry )
m_aAsyncDrop.aUrl = pView->getQualifiedName(xHitEntry.get());
sal_Int8 nAction = _rEvt.mnAction;
Reference<XContent> xContent;
diff --git a/dbaccess/source/ui/app/AppController.hxx b/dbaccess/source/ui/app/AppController.hxx
index 6f7c1f6..1abf501 100644
--- a/dbaccess/source/ui/app/AppController.hxx
+++ b/dbaccess/source/ui/app/AppController.hxx
@@ -57,8 +57,14 @@ namespace com::sun::star {
}
}
namespace weld
{
class TreeView;
}
namespace dbaui
{
class TreeListBox;
class SubComponentManager;
class OApplicationController;
class OApplicationView;
@@ -442,7 +448,8 @@ namespace dbaui
<TRUE/> if the double click event has been handled by the called, and should not
be processed further.
*/
bool onEntryDoubleClick(SvTreeListBox const & _rTree);
bool onEntryDoubleClick(const weld::TreeView& rTree);
/** called when a container (category) in the application view has been selected
@param _pTree
The tree list box.
@@ -450,22 +457,28 @@ namespace dbaui
<TRUE/> if the container could be changed otherwise <FALSE/>
*/
bool onContainerSelect(ElementType _eType);
/** called when an entry in a tree view has been selected
@param _pEntry
the selected entry
*/
void onSelectionChanged();
/** called when a "Copy" command is executed in a tree view
*/
void onCopyEntry();
/** called when a "Paste" command is executed in a tree view
*/
void onPasteEntry();
/** called when a "Delete" command is executed in a tree view
*/
void onDeleteEntry();
/// called when the preview mode was changed
void previewChanged( sal_Int32 _nMode);
/// called when an object container of any kind was found during enumerating tree view elements
void containerFound( const css::uno::Reference< css::container::XContainer >& _xContainer);
@@ -474,12 +487,14 @@ namespace dbaui
// IControlActionListener overridables
virtual bool requestQuickHelp( const SvTreeListEntry* _pEntry, OUString& _rText ) const override;
virtual bool requestQuickHelp(const void* pUserData, OUString& rText) const override;
virtual bool requestDrag( const Point& _rPosPixel ) override;
virtual bool requestDrag(const weld::TreeIter& rEntry) override;
virtual sal_Int8 queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors ) override;
virtual sal_Int8 executeDrop( const ExecuteDropEvent& _rEvt ) override;
// IContextMenuProvider
virtual OUString getContextMenuResourceName( Control& _rControl ) const override;
virtual OUString getContextMenuResourceName() const override;
virtual IController& getCommandController() override;
virtual ::comphelper::OInterfaceContainerHelper2*
getContextMenuInterceptors() override;
diff --git a/dbaccess/source/ui/app/AppDetailPageHelper.cxx b/dbaccess/source/ui/app/AppDetailPageHelper.cxx
index 502ad24..27a4ed7 100644
--- a/dbaccess/source/ui/app/AppDetailPageHelper.cxx
+++ b/dbaccess/source/ui/app/AppDetailPageHelper.cxx
@@ -54,7 +54,6 @@
#include <toolkit/awt/vclxmenu.hxx>
#include <tools/stream.hxx>
#include <rtl/ustrbuf.hxx>
#include <vcl/treelistentry.hxx>
#include "AppController.hxx"
#include <com/sun/star/document/XDocumentProperties.hpp>
@@ -82,39 +81,44 @@ namespace dbaui
namespace
{
SvTreeListEntry* lcl_findEntry_impl(DBTreeListBox const & rTree, const OUString& _rName, SvTreeListEntry* _pFirst)
bool lcl_findEntry_impl(const TreeListBox& rTree, const OUString& rName, weld::TreeIter& rIter)
{
SvTreeListEntry* pReturn = nullptr;
bool bReturn = false;
sal_Int32 nIndex = 0;
OUString sName( _rName.getToken(0,'/',nIndex) );
OUString sName( rName.getToken(0,'/',nIndex) );
SvTreeListEntry* pEntry = _pFirst;
while( pEntry )
const weld::TreeView& rTreeView = rTree.GetWidget();
bool bEntry = true;
do
{
if ( rTree.GetEntryText(pEntry) == sName )
if (rTreeView.get_text(rIter) == sName)
{
if ( nIndex != -1 )
{
sName = _rName.getToken(0,'/',nIndex);
pEntry = rTree.FirstChild(pEntry);
sName = rName.getToken(0,'/',nIndex);
bEntry = rTreeView.iter_children(rIter);
}
else
{
pReturn = pEntry;
bReturn = true;
break;
}
}
else
pEntry = pEntry->NextSibling();
bEntry = rTreeView.iter_next_sibling(rIter);
}
return pReturn;
while (bEntry);
return bReturn;
}
SvTreeListEntry* lcl_findEntry(DBTreeListBox const & rTree, const OUString& _rName,SvTreeListEntry* _pFirst)
bool lcl_findEntry(const TreeListBox& rTree, const OUString& rName, weld::TreeIter& rIter)
{
sal_Int32 nIndex = 0;
OUString sErase = _rName.getToken(0,'/',nIndex); // we don't want to have the "private:forms" part
return (nIndex != -1 ? lcl_findEntry_impl(rTree,_rName.copy(sErase.getLength() + 1),_pFirst) : nullptr);
OUString sErase = rName.getToken(0,'/',nIndex); // we don't want to have the "private:forms" part
return nIndex != -1 && lcl_findEntry_impl(rTree, rName.copy(sErase.getLength() + 1), rIter);
}
class OTablePreviewWindow : public vcl::Window
{
DECL_LINK(OnDisableInput, void*, void);
@@ -197,7 +201,7 @@ OAppDetailPageHelper::OAppDetailPageHelper(vcl::Window* _pParent,OAppBorderWindo
m_xWindow = VCLUnoHelper::GetInterface( m_pTablePreview );
for (VclPtr<DBTreeListBox> & rpBox : m_pLists)
for (VclPtr<InterimDBTreeListBox> & rpBox : m_pLists)
rpBox = nullptr;
ImplInitSettings();
}
@@ -221,13 +225,11 @@ void OAppDetailPageHelper::dispose()
OSL_FAIL("Exception thrown while disposing preview frame!");
}
for (VclPtr<DBTreeListBox> & rpBox : m_pLists)
for (VclPtr<InterimDBTreeListBox> & rpBox : m_pLists)
{
if ( rpBox )
{
rpBox->clearCurrentSelection();
rpBox->Hide();
rpBox->clearCurrentSelection(); // why a second time?
rpBox.disposeAndClear();
}
}
@@ -257,77 +259,74 @@ void OAppDetailPageHelper::selectAll()
int nPos = getVisibleControlIndex();
if ( nPos < E_ELEMENT_TYPE_COUNT )
{
m_pLists[nPos]->SelectAll(true);
m_pLists[nPos]->GetWidget().select_all();
}
}
void OAppDetailPageHelper::sort(int _nPos,SvSortMode _eSortMode )
void OAppDetailPageHelper::sort(int nPos, bool bAscending)
{
OSL_ENSURE(m_pLists[_nPos],"List can not be NULL! ->GPF");
SvTreeList* pModel = m_pLists[_nPos]->GetModel();
SvSortMode eOldSortMode = pModel->GetSortMode();
pModel->SetSortMode(_eSortMode);
if ( eOldSortMode != _eSortMode )
pModel->Resort();
assert(m_pLists[nPos] && "List can not be NULL! ->GPF");
m_pLists[nPos]->GetWidget().set_sort_order(bAscending);
}
bool OAppDetailPageHelper::isSortUp() const
{
SvSortMode eSortMode = SortNone;
bool bAscending = false;
int nPos = getVisibleControlIndex();
if ( nPos < E_ELEMENT_TYPE_COUNT )
{
SvTreeList* pModel = m_pLists[nPos]->GetModel();
eSortMode = pModel->GetSortMode();
}
return eSortMode == SortAscending;
if (nPos < E_ELEMENT_TYPE_COUNT)
bAscending = m_pLists[nPos]->GetWidget().get_sort_order();
return bAscending;
}
void OAppDetailPageHelper::sortDown()
{
int nPos = getVisibleControlIndex();
if ( nPos < E_ELEMENT_TYPE_COUNT )
sort(nPos,SortDescending);
sort(nPos, false);
}
void OAppDetailPageHelper::sortUp()
{
int nPos = getVisibleControlIndex();
if ( nPos < E_ELEMENT_TYPE_COUNT )
sort(nPos,SortAscending);
sort(nPos, true);
}
void OAppDetailPageHelper::getSelectionElementNames( std::vector< OUString>& _rNames ) const
void OAppDetailPageHelper::getSelectionElementNames(std::vector<OUString>& rNames) const
{
int nPos = getVisibleControlIndex();
if ( nPos >= E_ELEMENT_TYPE_COUNT )
return;
DBTreeListBox& rTree = *m_pLists[nPos];
sal_Int32 nCount = rTree.GetEntryCount();
_rNames.reserve(nCount);
SvTreeListEntry* pEntry = rTree.FirstSelected();
InterimDBTreeListBox& rTree = *m_pLists[nPos];
weld::TreeView& rTreeView = rTree.GetWidget();
sal_Int32 nCount = rTreeView.n_children();
rNames.reserve(nCount);
ElementType eType = getElementType();
while( pEntry )
{
rTreeView.selected_foreach([this, eType, &rTreeView, &rNames](weld::TreeIter& rEntry){
if ( eType == E_TABLE )
{
if( rTree.GetChildCount(pEntry) == 0 )
_rNames.push_back( getQualifiedName( pEntry ) );
if (!rTreeView.iter_has_child(rEntry))
rNames.push_back(getQualifiedName(&rEntry));
}
else
{
OUString sName = rTree.GetEntryText(pEntry);
SvTreeListEntry* pParent = rTree.GetParent(pEntry);
while(pParent)
OUString sName = rTreeView.get_text(rEntry);
std::unique_ptr<weld::TreeIter> xParent(rTreeView.make_iterator(&rEntry));
bool bParent = rTreeView.iter_parent(*xParent);
while (bParent)
{
sName = rTree.GetEntryText(pParent) + "/" + sName;
pParent = rTree.GetParent(pParent);
sName = rTreeView.get_text(*xParent) + "/" + sName;
bParent = rTreeView.iter_parent(*xParent);
}
_rNames.push_back(sName);
rNames.push_back(sName);
}
pEntry = rTree.NextSelected(pEntry);
}
return false;
});
}
void OAppDetailPageHelper::describeCurrentSelectionForControl( const Control& _rControl, Sequence< NamedDatabaseObject >& _out_rSelectedObjects )
@@ -343,10 +342,10 @@ void OAppDetailPageHelper::describeCurrentSelectionForControl( const Control& _r
OSL_FAIL( "OAppDetailPageHelper::describeCurrentSelectionForControl: invalid control!" );
}
void OAppDetailPageHelper::describeCurrentSelectionForType( const ElementType _eType, Sequence< NamedDatabaseObject >& _out_rSelectedObjects )
void OAppDetailPageHelper::describeCurrentSelectionForType(const ElementType eType, Sequence< NamedDatabaseObject >& _out_rSelectedObjects)
{
OSL_ENSURE( _eType < E_ELEMENT_TYPE_COUNT, "OAppDetailPageHelper::describeCurrentSelectionForType: invalid type!" );
DBTreeListBox* pList = ( _eType < E_ELEMENT_TYPE_COUNT ) ? m_pLists[ _eType ].get() : nullptr;
OSL_ENSURE( eType < E_ELEMENT_TYPE_COUNT, "OAppDetailPageHelper::describeCurrentSelectionForType: invalid type!" );
InterimDBTreeListBox* pList = ( eType < E_ELEMENT_TYPE_COUNT ) ? m_pLists[ eType ].get() : nullptr;
OSL_ENSURE( pList, "OAppDetailPageHelper::describeCurrentSelectionForType: "
"You really should ensure this type has already been viewed before!" );
if ( !pList )
@@ -354,60 +353,57 @@ void OAppDetailPageHelper::describeCurrentSelectionForType( const ElementType _e
std::vector< NamedDatabaseObject > aSelected;
SvTreeListEntry* pEntry = pList->FirstSelected();
while( pEntry )
{
weld::TreeView& rTreeView = pList->GetWidget();
rTreeView.selected_foreach([pList, eType, &rTreeView, &aSelected](weld::TreeIter& rEntry){
NamedDatabaseObject aObject;
switch ( _eType )
switch (eType)
{
case E_TABLE:
{
OTableTreeListBox& rTableTree = dynamic_cast< OTableTreeListBox& >( *pList );
aObject = rTableTree.describeObject( pEntry );
}
break;
case E_QUERY:
aObject.Type = DatabaseObject::QUERY;
aObject.Name = pList->GetEntryText( pEntry );
break;
case E_FORM:
case E_REPORT:
{
OUString sName = pList->GetEntryText(pEntry);
SvTreeListEntry* pParent = pList->GetParent(pEntry);
while ( pParent )
case E_TABLE:
{
OUStringBuffer buffer;
buffer.append( pList->GetEntryText( pParent ) );
buffer.append( '/' );
buffer.append( sName );
sName = buffer.makeStringAndClear();
pParent = pList->GetParent( pParent );
OTableTreeListBox& rTableTree = dynamic_cast<OTableTreeListBox&>(*pList);
aObject = rTableTree.describeObject(rEntry);
break;
}
case E_QUERY:
aObject.Type = DatabaseObject::QUERY;
aObject.Name = rTreeView.get_text(rEntry);
break;
case E_FORM:
case E_REPORT:
{
OUString sName = rTreeView.get_text(rEntry);
std::unique_ptr<weld::TreeIter> xParent(rTreeView.make_iterator(&rEntry));
bool bParent = rTreeView.iter_parent(*xParent);
while (bParent)
{
OUStringBuffer buffer;
buffer.append(rTreeView.get_text(*xParent));
buffer.append('/');
buffer.append(sName);
sName = buffer.makeStringAndClear();
if ( isLeaf( pEntry ) )
aObject.Type = ( _eType == E_FORM ) ? DatabaseObject::FORM : DatabaseObject::REPORT;
else
aObject.Type = ( _eType == E_FORM ) ? DatabaseObjectContainer::FORMS_FOLDER : DatabaseObjectContainer::REPORTS_FOLDER;
aObject.Name = sName;
}
break;
default:
OSL_FAIL( "OAppDetailPageHelper::describeCurrentSelectionForType: unexpected type!" );
break;
bParent = rTreeView.iter_parent(*xParent);
}
if (isLeaf(rTreeView, rEntry))
aObject.Type = (eType == E_FORM) ? DatabaseObject::FORM : DatabaseObject::REPORT;
else
aObject.Type = (eType == E_FORM) ? DatabaseObjectContainer::FORMS_FOLDER : DatabaseObjectContainer::REPORTS_FOLDER;
aObject.Name = sName;
break;
}
default:
OSL_FAIL( "OAppDetailPageHelper::describeCurrentSelectionForType: unexpected type!" );
break;
}
if ( !aObject.Name.isEmpty() )
{
aSelected.push_back( aObject );
}
if (!aObject.Name.isEmpty())
aSelected.push_back(aObject);
pEntry = pList->NextSelected(pEntry);
}
return false;
});
_out_rSelectedObjects = comphelper::containerToSequence( aSelected );
_out_rSelectedObjects = comphelper::containerToSequence(aSelected);
}
void OAppDetailPageHelper::selectElements(const Sequence< OUString>& _aNames)
@@ -416,19 +412,21 @@ void OAppDetailPageHelper::selectElements(const Sequence< OUString>& _aNames)
if ( nPos >= E_ELEMENT_TYPE_COUNT )
return;
DBTreeListBox& rTree = *m_pLists[nPos];
rTree.SelectAll(false);
InterimDBTreeListBox& rTree = *m_pLists[nPos];
weld::TreeView& rTreeView = rTree.GetWidget();
rTreeView.unselect_all();
const OUString* pIter = _aNames.getConstArray();
const OUString* pEnd = pIter + _aNames.getLength();
for(;pIter != pEnd;++pIter)
{
SvTreeListEntry* pEntry = rTree.GetEntryPosByName(*pIter);
if ( pEntry )
rTree.Select(pEntry);
auto xEntry = rTree.GetEntryPosByName(*pIter);
if (!xEntry)
continue;
rTreeView.select(*xEntry);
}
}
OUString OAppDetailPageHelper::getQualifiedName( SvTreeListEntry* _pEntry ) const
OUString OAppDetailPageHelper::getQualifiedName(weld::TreeIter* _pEntry) const
{
int nPos = getVisibleControlIndex();
OUString sComposedName;
@@ -437,28 +435,32 @@ OUString OAppDetailPageHelper::getQualifiedName( SvTreeListEntry* _pEntry ) cons
return sComposedName;
OSL_ENSURE(m_pLists[nPos],"Tables tree view is NULL! -> GPF");
DBTreeListBox& rTree = *m_pLists[nPos];
InterimDBTreeListBox& rTree = *m_pLists[nPos];
weld::TreeView& rTreeView = rTree.GetWidget();
SvTreeListEntry* pEntry = _pEntry;
if ( !pEntry )
pEntry = rTree.FirstSelected();
std::unique_ptr<weld::TreeIter> xEntry(rTreeView.make_iterator(_pEntry));
if (!_pEntry)
{
if (!rTreeView.get_selected(xEntry.get()))
xEntry.reset();
}
if ( !pEntry )
if (!xEntry)
return sComposedName;
if ( getElementType() == E_TABLE )
{
const OTableTreeListBox& rTreeView = dynamic_cast< const OTableTreeListBox& >( *m_pLists[nPos] );
sComposedName = rTreeView.getQualifiedTableName( pEntry );
const OTableTreeListBox& rTableTreeListBox = dynamic_cast<const OTableTreeListBox&>(*m_pLists[nPos]);
sComposedName = rTableTreeListBox.getQualifiedTableName(*xEntry);
}
else
{
sComposedName = rTree.GetEntryText(pEntry);
SvTreeListEntry* pParent = rTree.GetParent(pEntry);
while(pParent)
sComposedName = rTreeView.get_text(*xEntry);
bool bParent = rTreeView.iter_parent(*xEntry);
while (bParent)
{
sComposedName = rTree.GetEntryText(pParent) + "/" + sComposedName;
pParent = rTree.GetParent(pParent);
sComposedName = rTreeView.get_text(*xEntry) + "/" + sComposedName;
bParent = rTreeView.iter_parent(*xEntry);
}
}
@@ -477,13 +479,9 @@ sal_Int32 OAppDetailPageHelper::getSelectionCount()
int nPos = getVisibleControlIndex();
if ( nPos < E_ELEMENT_TYPE_COUNT )
{
DBTreeListBox& rTree = *m_pLists[nPos];
SvTreeListEntry* pEntry = rTree.FirstSelected();
while( pEntry )
{
++nCount;
pEntry = rTree.NextSelected(pEntry);
}
InterimDBTreeListBox& rTree = *m_pLists[nPos];
weld::TreeView& rTreeView = rTree.GetWidget();
nCount = rTreeView.count_selected_rows();
}
return nCount;
}
@@ -494,16 +492,16 @@ sal_Int32 OAppDetailPageHelper::getElementCount() const
int nPos = getVisibleControlIndex();
if ( nPos < E_ELEMENT_TYPE_COUNT )
{
nCount = m_pLists[nPos]->GetEntryCount();
InterimDBTreeListBox& rTree = *m_pLists[nPos];
weld::TreeView& rTreeView = rTree.GetWidget();
nCount = rTreeView.n_children();
}
return nCount;
}
bool OAppDetailPageHelper::isLeaf(SvTreeListEntry const * _pEntry)
bool OAppDetailPageHelper::isLeaf(const weld::TreeView& rTreeView, const weld::TreeIter& rEntry)
{
if ( !_pEntry )
return false;
sal_Int32 nEntryType = reinterpret_cast< sal_IntPtr >( _pEntry->GetUserData() );
sal_Int32 nEntryType = rTreeView.get_id(rEntry).toInt32();
return !( ( nEntryType == DatabaseObjectContainer::TABLES )
|| ( nEntryType == DatabaseObjectContainer::CATALOG )
|| ( nEntryType == DatabaseObjectContainer::SCHEMA )
@@ -517,24 +515,29 @@ bool OAppDetailPageHelper::isALeafSelected() const
bool bLeafSelected = false;
if ( nPos < E_ELEMENT_TYPE_COUNT )
{
DBTreeListBox& rTree = *m_pLists[nPos];
SvTreeListEntry* pEntry = rTree.FirstSelected( );
while( !bLeafSelected && pEntry )
{
bLeafSelected = isLeaf( pEntry );
pEntry = rTree.NextSelected(pEntry);
}
InterimDBTreeListBox& rTree = *m_pLists[nPos];
weld::TreeView& rTreeView = rTree.GetWidget();
rTreeView.selected_foreach([&rTreeView, &bLeafSelected](weld::TreeIter& rEntry){
bLeafSelected = isLeaf(rTreeView, rEntry);
return bLeafSelected;
});
}
return bLeafSelected;
}
SvTreeListEntry* OAppDetailPageHelper::getEntry( const Point& _aPosPixel) const
std::unique_ptr<weld::TreeIter> OAppDetailPageHelper::getEntry( const Point& _aPosPixel) const
{
SvTreeListEntry* pReturn = nullptr;
std::unique_ptr<weld::TreeIter> xReturn;
int nPos = getVisibleControlIndex();
if ( nPos < E_ELEMENT_TYPE_COUNT )
pReturn = m_pLists[nPos]->GetEntry( _aPosPixel, true );
return pReturn;
{
InterimDBTreeListBox& rTree = *m_pLists[nPos];
weld::TreeView& rTreeView = rTree.GetWidget();
xReturn = rTreeView.make_iterator();
if (!rTreeView.get_dest_row_at_pos(_aPosPixel, xReturn.get(), false))
xReturn.reset();
}
return xReturn;
}
void OAppDetailPageHelper::createTablesPage(const Reference< XConnection>& _xConnection)
@@ -543,26 +546,22 @@ void OAppDetailPageHelper::createTablesPage(const Reference< XConnection>& _xCon
if ( !m_pLists[E_TABLE] )
{
VclPtrInstance<OTableTreeListBox> pTreeView(this,
WB_HASLINES | WB_SORT | WB_HASBUTTONS | WB_HSCROLL |WB_HASBUTTONSATROOT | WB_TABSTOP);
VclPtrInstance<OTableTreeListBox> pTreeView(this, false); // false means: do not show any buttons
pTreeView->SetHelpId(HID_APP_TABLE_TREE);
m_pLists[E_TABLE] = pTreeView;
m_pLists[E_TABLE] = createTree(pTreeView);
createTree( pTreeView,
ImageProvider::getDefaultImage( DatabaseObject::TABLE )
);
pTreeView->notifyHiContrastChanged();
m_aBorder->SetZOrder(pTreeView, ZOrderFlags::Behind);
}
if ( !m_pLists[E_TABLE]->GetEntryCount() )
weld::TreeView& rTreeView = m_pLists[E_TABLE]->GetWidget();
if (!rTreeView.n_children())
{
static_cast<OTableTreeListBox*>(m_pLists[E_TABLE].get())->UpdateTableList(_xConnection);
SvTreeListEntry* pEntry = m_pLists[E_TABLE]->First();
if ( pEntry )
m_pLists[E_TABLE]->Expand(pEntry);
m_pLists[E_TABLE]->SelectAll(false);
std::unique_ptr<weld::TreeIter> xFirst(rTreeView.make_iterator());
if (rTreeView.get_iter_first(*xFirst))
rTreeView.expand_row(*xFirst);
rTreeView.unselect_all();
}
setDetailPage(m_pLists[E_TABLE]);
@@ -589,20 +588,16 @@ void OAppDetailPageHelper::createPage(ElementType _eType,const Reference< XNameA
OSL_ENSURE(E_TABLE != _eType,"E_TABLE isn't allowed.");
OString sHelpId;
Image aFolderImage;
switch( _eType )
{
case E_FORM:
sHelpId = HID_APP_FORM_TREE;
aFolderImage = ImageProvider::getFolderImage( DatabaseObject::FORM );
break;
case E_REPORT:
sHelpId = HID_APP_REPORT_TREE;
aFolderImage = ImageProvider::getFolderImage( DatabaseObject::REPORT );
break;
case E_QUERY:
sHelpId = HID_APP_QUERY_TREE;
aFolderImage = ImageProvider::getFolderImage( DatabaseObject::QUERY );
break;
default:
OSL_FAIL("Illegal call!");
@@ -611,16 +606,19 @@ void OAppDetailPageHelper::createPage(ElementType _eType,const Reference< XNameA
if ( !m_pLists[_eType] )
{
m_pLists[_eType] = createSimpleTree( sHelpId, aFolderImage );
m_pLists[_eType] = createSimpleTree(sHelpId);
}
if ( m_pLists[_eType] )
{
if ( !m_pLists[_eType]->GetEntryCount() && _xContainer.is() )
weld::TreeView& rTreeView = m_pLists[_eType]->GetWidget();
if (!rTreeView.n_children() && _xContainer.is())
{
rTreeView.make_unsorted();
fillNames( _xContainer, _eType, sImageId, nullptr );
rTreeView.make_sorted();
m_pLists[_eType]->SelectAll(false);
rTreeView.unselect_all();
}
setDetailPage(m_pLists[_eType]);
}
@@ -663,12 +661,12 @@ namespace
}
void OAppDetailPageHelper::fillNames( const Reference< XNameAccess >& _xContainer, const ElementType _eType,
const OUString& rImageId, SvTreeListEntry* _pParent )
const OUString& rImageId, weld::TreeIter* _pParent )
{
OSL_ENSURE(_xContainer.is(),"Data source is NULL! -> GPF");
OSL_ENSURE( ( _eType >= E_TABLE ) && ( _eType < E_ELEMENT_TYPE_COUNT ), "OAppDetailPageHelper::fillNames: invalid type!" );
DBTreeListBox* pList = m_pLists[ _eType ].get();
InterimDBTreeListBox* pList = m_pLists[ _eType ].get();
OSL_ENSURE( pList, "OAppDetailPageHelper::fillNames: you really should create the list before calling this!" );
if ( !pList )
return;
@@ -676,6 +674,9 @@ void OAppDetailPageHelper::fillNames( const Reference< XNameAccess >& _xContaine
if ( !(_xContainer.is() && _xContainer->hasElements()) )
return;
weld::TreeView& rTreeView = pList->GetWidget();
std::unique_ptr<weld::TreeIter> xRet = rTreeView.make_iterator();
const sal_Int32 nFolderIndicator = lcl_getFolderIndicatorForType( _eType );
Sequence< OUString> aSeq = _xContainer->getElementNames();
@@ -683,66 +684,63 @@ void OAppDetailPageHelper::fillNames( const Reference< XNameAccess >& _xContaine
const OUString* pEnd = pIter + aSeq.getLength();
for(;pIter != pEnd;++pIter)
{
SvTreeListEntry* pEntry = nullptr;
Reference<XNameAccess> xSubElements(_xContainer->getByName(*pIter),UNO_QUERY);
if ( xSubElements.is() )
{
pEntry = pList->InsertEntry( *pIter, _pParent, false, TREELIST_APPEND, reinterpret_cast< void* >( nFolderIndicator ) );
OUString sId(OUString::number(nFolderIndicator));
rTreeView.insert(_pParent, -1, nullptr, &sId, nullptr, nullptr, false, xRet.get());
rTreeView.set_text(*xRet, *pIter, 0);
rTreeView.set_text_emphasis(*xRet, false, 0);
getBorderWin().getView()->getAppController().containerFound( Reference< XContainer >( xSubElements, UNO_QUERY ) );
fillNames( xSubElements, _eType, rImageId, pEntry );
fillNames( xSubElements, _eType, rImageId, xRet.get());
}
else
{
pEntry = pList->InsertEntry( *pIter, _pParent );
Image aImage(StockImage::Yes, rImageId);
pList->SetExpandedEntryBmp(pEntry, aImage);
pList->SetCollapsedEntryBmp(pEntry, aImage);
rTreeView.insert(_pParent, -1, nullptr, nullptr, nullptr, nullptr, false, xRet.get());
rTreeView.set_text(*xRet, *pIter, 0);
rTreeView.set_text_emphasis(*xRet, false, 0);
rTreeView.set_image(*xRet, rImageId);
}
}
}
DBTreeListBox* OAppDetailPageHelper::createSimpleTree( const OString& _sHelpId, const Image& _rImage)
InterimDBTreeListBox* OAppDetailPageHelper::createSimpleTree(const OString& rHelpId)
{
VclPtrInstance<DBTreeListBox> pTreeView(this,
WB_HASLINES | WB_SORT | WB_HASBUTTONS | WB_HSCROLL |WB_HASBUTTONSATROOT | WB_TABSTOP);
pTreeView->SetHelpId( _sHelpId );
return createTree( pTreeView, _rImage );
VclPtrInstance<InterimDBTreeListBox> pTreeView(this);
pTreeView->SetHelpId(rHelpId);
return createTree(pTreeView);
}
DBTreeListBox* OAppDetailPageHelper::createTree( DBTreeListBox* _pTreeView, const Image& _rImage )
InterimDBTreeListBox* OAppDetailPageHelper::createTree(InterimDBTreeListBox* pTreeView)
{
weld::WaitObject aWaitCursor(GetFrameWeld());
_pTreeView->SetStyle(_pTreeView->GetStyle() | WB_HASLINES | WB_SORT | WB_HASBUTTONS | WB_HSCROLL |WB_HASBUTTONSATROOT | WB_TABSTOP);
_pTreeView->GetModel()->SetSortMode(SortAscending);
_pTreeView->EnableCheckButton( nullptr ); // do not show any buttons
_pTreeView->SetSelectionMode(SelectionMode::Multiple);
pTreeView->setCopyHandler(LINK(this, OAppDetailPageHelper, OnCopyEntry));
pTreeView->setPasteHandler(LINK(this, OAppDetailPageHelper, OnPasteEntry));
pTreeView->setDeleteHandler(LINK(this, OAppDetailPageHelper, OnDeleteEntry));
_pTreeView->SetDefaultCollapsedEntryBmp( _rImage );
_pTreeView->SetDefaultExpandedEntryBmp( _rImage );
weld::TreeView& rTreeView = pTreeView->GetWidget();
rTreeView.make_sorted();
rTreeView.set_selection_mode(SelectionMode::Multiple);
_pTreeView->SetDoubleClickHdl(LINK(this, OAppDetailPageHelper, OnEntryDoubleClick));
_pTreeView->SetEnterKeyHdl(LINK(this, OAppDetailPageHelper, OnEntryEnterKey));
_pTreeView->SetSelChangeHdl(LINK(this, OAppDetailPageHelper, OnEntrySelChange));
rTreeView.connect_row_activated(LINK(this, OAppDetailPageHelper, OnEntryDoubleClick));
_pTreeView->setCopyHandler(LINK(this, OAppDetailPageHelper, OnCopyEntry));
_pTreeView->setPasteHandler(LINK(this, OAppDetailPageHelper, OnPasteEntry));
_pTreeView->setDeleteHandler(LINK(this, OAppDetailPageHelper, OnDeleteEntry));
pTreeView->SetSelChangeHdl(LINK(this, OAppDetailPageHelper, OnEntrySelChange));
_pTreeView->setControlActionListener( &getBorderWin().getView()->getAppController() );
_pTreeView->setContextMenuProvider( &getBorderWin().getView()->getAppController() );
pTreeView->setControlActionListener(&getBorderWin().getView()->getAppController());
pTreeView->setContextMenuProvider(&getBorderWin().getView()->getAppController());
return _pTreeView;
return pTreeView;
}
void OAppDetailPageHelper::clearPages()
{
showPreview(nullptr);
for (VclPtr<DBTreeListBox> & rpBox : m_pLists)
for (VclPtr<InterimDBTreeListBox> & rpBox : m_pLists)
{
if ( rpBox )
rpBox->Clear();
rpBox->GetWidget().clear();
}
}
@@ -754,51 +752,58 @@ bool OAppDetailPageHelper::isFilled() const
return i != E_ELEMENT_TYPE_COUNT;
}
void OAppDetailPageHelper::elementReplaced(ElementType _eType
,const OUString& _rOldName
,const OUString& _rNewName )
void OAppDetailPageHelper::elementReplaced(ElementType eType,
const OUString& rOldName,
const OUString& rNewName)
{
DBTreeListBox* pTreeView = getCurrentView();
if ( !pTreeView )
InterimDBTreeListBox* pTreeView = getCurrentView();
if (!pTreeView)
return;
SvTreeListEntry* pEntry = nullptr;
switch( _eType )
weld::TreeView& rTreeView = pTreeView->GetWidget();
rTreeView.make_unsorted();
switch (eType)
{
case E_TABLE:
static_cast<OTableTreeListBox*>(pTreeView)->removedTable( _rOldName );
static_cast<OTableTreeListBox*>(pTreeView)->addedTable( _rNewName );
return;
case E_QUERY:
pEntry = lcl_findEntry_impl(*pTreeView,_rOldName,pTreeView->First());
static_cast<OTableTreeListBox*>(pTreeView)->removedTable(rOldName);
static_cast<OTableTreeListBox*>(pTreeView)->addedTable(rNewName);
break;
case E_QUERY:
{
std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
if (rTreeView.get_iter_first(*xIter) && lcl_findEntry_impl(*pTreeView, rOldName, *xIter))
rTreeView.set_text(*xIter, rNewName);
break;
}
case E_FORM:
case E_REPORT:
pEntry = lcl_findEntry(*pTreeView,_rOldName,pTreeView->First());
{
std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
if (rTreeView.get_iter_first(*xIter) && lcl_findEntry(*pTreeView, rOldName, *xIter))
rTreeView.set_text(*xIter, rNewName);
break;
}
default:
OSL_FAIL("Invalid element type");
}
OSL_ENSURE(pEntry,"Do you know that the name isn't existence!");
if ( pEntry )
{
pTreeView->SetEntryText(pEntry,_rNewName);
}
rTreeView.make_sorted();
}
SvTreeListEntry* OAppDetailPageHelper::elementAdded(ElementType _eType,const OUString& _rName, const Any& _rObject )
std::unique_ptr<weld::TreeIter> OAppDetailPageHelper::elementAdded(ElementType _eType,const OUString& _rName, const Any& _rObject )
{
SvTreeListEntry* pRet = nullptr;
DBTreeListBox* pTreeView = m_pLists[_eType].get();
std::unique_ptr<weld::TreeIter> xRet;
InterimDBTreeListBox* pTreeView = m_pLists[_eType].get();
weld::TreeView& rTreeView = pTreeView->GetWidget();
rTreeView.make_unsorted();
if( _eType == E_TABLE && pTreeView )
{
pRet = static_cast<OTableTreeListBox*>(pTreeView)->addedTable( _rName );
xRet = static_cast<OTableTreeListBox*>(pTreeView)->addedTable( _rName );
}
else if ( pTreeView )
{
SvTreeListEntry* pEntry = nullptr;
std::unique_ptr<weld::TreeIter> xEntry;
Reference<XChild> xChild(_rObject,UNO_QUERY);
if ( xChild.is() && E_QUERY != _eType )
{
@@ -806,7 +811,9 @@ SvTreeListEntry* OAppDetailPageHelper::elementAdded(ElementType _eType,const OUS
if ( xContent.is() )
{
OUString sName = xContent->getIdentifier()->getContentIdentifier();
pEntry = lcl_findEntry(*pTreeView,sName,pTreeView->First());
std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
if (rTreeView.get_iter_first(*xIter) && lcl_findEntry(*pTreeView, sName, *xIter))
xEntry = std::move(xIter);
}
}
@@ -815,58 +822,66 @@ SvTreeListEntry* OAppDetailPageHelper::elementAdded(ElementType _eType,const OUS
if ( xContainer.is() )
{
const sal_Int32 nFolderIndicator = lcl_getFolderIndicatorForType( _eType );
pRet = pTreeView->InsertEntry( _rName, pEntry, false, TREELIST_APPEND, reinterpret_cast< void* >( nFolderIndicator ) );
fillNames( xContainer, _eType, sImageId, pRet );
OUString sId(OUString::number(nFolderIndicator));
xRet = rTreeView.make_iterator();
rTreeView.insert(xEntry.get(), -1, nullptr, &sId, nullptr, nullptr, false, xRet.get());
rTreeView.set_text(*xRet, _rName, 0);
rTreeView.set_text_emphasis(*xRet, false, 0);
fillNames(xContainer, _eType, sImageId, xRet.get());
}
else
{
pRet = pTreeView->InsertEntry( _rName, pEntry );
Image aImage(StockImage::Yes, sImageId);
pTreeView->SetExpandedEntryBmp( pRet, aImage );
pTreeView->SetCollapsedEntryBmp( pRet, aImage );
xRet = rTreeView.make_iterator();
rTreeView.insert(xEntry.get(), -1, nullptr, nullptr, nullptr, nullptr, false, xRet.get());
rTreeView.set_text(*xRet, _rName, 0);
rTreeView.set_text_emphasis(*xRet, false, 0);
rTreeView.set_image(*xRet, sImageId);
}
}
return pRet;
rTreeView.make_sorted();
return xRet;
}
void OAppDetailPageHelper::elementRemoved( ElementType _eType,const OUString& _rName )
{
DBTreeListBox* pTreeView = getCurrentView();
InterimDBTreeListBox* pTreeView = getCurrentView();
if ( !pTreeView )
return;
weld::TreeView& rTreeView = pTreeView->GetWidget();
switch( _eType )
{
case E_TABLE:
// we don't need to clear the table here, it is already done by the dispose listener
static_cast< OTableTreeListBox* >( pTreeView )->removedTable( _rName );
static_cast<OTableTreeListBox*>(pTreeView)->removedTable(_rName);
break;
case E_QUERY:
if (auto pEntry = lcl_findEntry_impl(*pTreeView, _rName, pTreeView->First()))
pTreeView->GetModel()->Remove(pEntry);
{
std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
if (rTreeView.get_iter_first(*xIter) && lcl_findEntry_impl(*pTreeView, _rName, *xIter))
rTreeView.remove(*xIter);
break;
}
case E_FORM:
case E_REPORT:
if (auto pEntry = lcl_findEntry(*pTreeView, _rName, pTreeView->First()))
pTreeView->GetModel()->Remove(pEntry);
{
std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
if (rTreeView.get_iter_first(*xIter) && lcl_findEntry(*pTreeView, _rName, *xIter))
rTreeView.remove(*xIter);
break;
}
default:
OSL_FAIL("Invalid element type");
}
if ( !pTreeView->GetEntryCount() )
if (!rTreeView.n_children())
showPreview(nullptr);
}
IMPL_LINK(OAppDetailPageHelper, OnEntryEnterKey, DBTreeListBox*, _pTree, void )
IMPL_LINK(OAppDetailPageHelper, OnEntryDoubleClick, weld::TreeView&, rTreeView, bool)
{
OnEntryDoubleClick(_pTree);
}
IMPL_LINK(OAppDetailPageHelper, OnEntryDoubleClick, SvTreeListBox*, _pTree, bool)
{
OSL_ENSURE( _pTree, "OAppDetailPageHelper, OnEntryDoubleClick: invalid callback!" );
bool bHandled = ( _pTree != nullptr ) && getBorderWin().getView()->getAppController().onEntryDoubleClick( *_pTree );
return bHandled;
return getBorderWin().getView()->getAppController().onEntryDoubleClick(rTreeView);
}
IMPL_LINK_NOARG(OAppDetailPageHelper, OnEntrySelChange, LinkParamNone*, void)
@@ -970,7 +985,8 @@ void OAppDetailPageHelper::switchPreview(PreviewMode _eMode,bool _bForce)
// simulate a selectionChanged event at the controller, to force the preview to be updated
if ( isPreviewEnabled() )
{
if ( getCurrentView() && getCurrentView()->FirstSelected() )
InterimDBTreeListBox* pCurrent = getCurrentView();
if (pCurrent && pCurrent->GetWidget().get_selected(nullptr))
{
getBorderWin().getView()->getAppController().onSelectionChanged();
}
@@ -1163,14 +1179,14 @@ IMPL_LINK_NOARG(OAppDetailPageHelper, OnDropdownClickHdl, ToolBox*, void)
void OAppDetailPageHelper::KeyInput( const KeyEvent& rKEvt )
{
SvTreeListBox* pCurrentView = getCurrentView();
InterimDBTreeListBox* pCurrentView = getCurrentView();
OSL_PRECOND( pCurrentView, "OAppDetailPageHelper::KeyInput: how this?" );
sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
if ( ( KEY_RETURN == nCode ) && pCurrentView )
{
getBorderWin().getView()->getAppController().onEntryDoubleClick( *pCurrentView );
getBorderWin().getView()->getAppController().onEntryDoubleClick(pCurrentView->GetWidget());
}
else
Window::KeyInput(rKEvt);
@@ -1185,16 +1201,8 @@ void OAppDetailPageHelper::DataChanged( const DataChangedEvent& rDCEvt )
(rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
(rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
{
ImplInitSettings();
if ( m_pLists[ E_TABLE ] )
{
OTableTreeListBox* pTableTree = dynamic_cast< OTableTreeListBox* >( m_pLists[ E_TABLE ].get() );
OSL_ENSURE( pTableTree != nullptr, "OAppDetailPageHelper::DataChanged: a tree list for tables which is no TableTreeList?" );
if ( pTableTree )
pTableTree->notifyHiContrastChanged();
}
}
}
diff --git a/dbaccess/source/ui/app/AppDetailPageHelper.hxx b/dbaccess/source/ui/app/AppDetailPageHelper.hxx
index 1dd89d8..bda4444 100644
--- a/dbaccess/source/ui/app/AppDetailPageHelper.hxx
+++ b/dbaccess/source/ui/app/AppDetailPageHelper.hxx
@@ -27,12 +27,12 @@
#include <com/sun/star/ucb/XContent.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <AppElementType.hxx>
#include <vcl/treelistbox.hxx>
#include <svtools/DocumentInfoPreview.hxx>
#include <vcl/fixed.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/graph.hxx>
#include <vcl/GraphicObject.hxx>
#include <vcl/weld.hxx>
namespace com::sun::star::awt { class XWindow; }
namespace com::sun::star::frame { class XFrame2; }
@@ -43,6 +43,8 @@ namespace com::sun::star::io { class XPersist; }
namespace dbaui
{
class OAppBorderWindow;
class InterimDBTreeListBox;
class TreeListBox;
class DBTreeListBox;
class OPreviewWindow : public vcl::Window
@@ -71,11 +73,12 @@ namespace dbaui
void setGraphic(const Graphic& _rGraphic ) { m_aGraphicObj.SetGraphic(_rGraphic); }
};
// A helper class for the controls in the detail page.
// Combines general functionality.
class OAppDetailPageHelper : public vcl::Window
{
VclPtr<DBTreeListBox> m_pLists[ELEMENT_COUNT];
VclPtr<InterimDBTreeListBox> m_pLists[ELEMENT_COUNT];
OAppBorderWindow& m_rBorderWin;
VclPtr<FixedLine> m_aFL;
VclPtr<ToolBox> m_aTBPreview;
@@ -94,12 +97,12 @@ namespace dbaui
int getVisibleControlIndex() const;
/** sorts the entries in the tree list box.
@param _nPos
@param nPos
Which list should be sorted.
@param _eSortMode
How should be sorted.
@param bAscending
If sort should be Ascending of Descending
*/
void sort(int _nPos,SvSortMode _eSortMode );
void sort(int nPos, bool bAscending);
/** retrieves the resource ids of the images representing elements of the given type
*/
@@ -118,7 +121,7 @@ namespace dbaui
void fillNames( const css::uno::Reference< css::container::XNameAccess >& _xContainer,
const ElementType _eType,
const OUString& rImageId,
SvTreeListEntry* _pParent );
weld::TreeIter* _pParent );
/** sets the detail page
@param _pWindow
@@ -129,25 +132,20 @@ namespace dbaui
/** sets all HandleCallbacks
@param _pTreeView
The newly created DBTreeListBox
@param _rImage
the resource id of the default icon
@return
The new tree.
*/
DBTreeListBox* createTree( DBTreeListBox* _pTreeView, const Image& _rImage );
InterimDBTreeListBox* createTree(InterimDBTreeListBox* pTreeView);
/** creates the tree and sets all HandleCallbacks
@param _nHelpId
The help id of the control
@param _nCollapsedBitmap
The image to use in high contrast mode.
@return
The new tree.
*/
DBTreeListBox* createSimpleTree( const OString& _sHelpId, const Image& _rImage);
InterimDBTreeListBox* createSimpleTree(const OString& rHelpId);
DECL_LINK( OnEntryDoubleClick, SvTreeListBox*, bool );
DECL_LINK( OnEntryEnterKey, DBTreeListBox*, void );
DECL_LINK( OnEntryDoubleClick, weld::TreeView&, bool );
DECL_LINK( OnEntrySelChange, LinkParamNone*, void );
DECL_LINK( OnCopyEntry, LinkParamNone*, void );
@@ -185,7 +183,7 @@ namespace dbaui
/** returns the current visible tree list box
*/
DBTreeListBox* getCurrentView() const
InterimDBTreeListBox* getCurrentView() const
{
ElementType eType = getElementType();
return (eType != E_NONE ) ? m_pLists[static_cast<sal_Int32>(eType)].get() : nullptr;
@@ -236,7 +234,7 @@ namespace dbaui
@return
the qualified name
*/
OUString getQualifiedName( SvTreeListEntry* _pEntry ) const;
OUString getQualifiedName( weld::TreeIter* _pEntry ) const;
/// return the element of currently select entry
ElementType getElementType() const;
@@ -248,12 +246,14 @@ namespace dbaui
sal_Int32 getElementCount() const;
/** returns if an entry is a leaf
@param _pEntry
@param rTreeView
The TreeView rEntry belongs to
@param rEntry
The entry to check
@return
<TRUE/> if the entry is a leaf, otherwise <FALSE/>
*/
static bool isLeaf(SvTreeListEntry const * _pEntry);
static bool isLeaf(const weld::TreeView& rTreeView, const weld::TreeIter& rEntry);
/** returns if one of the selected entries is a leaf
@return
@@ -261,7 +261,7 @@ namespace dbaui
*/
bool isALeafSelected() const;
SvTreeListEntry* getEntry( const Point& _aPosPixel ) const;
std::unique_ptr<weld::TreeIter> getEntry(const Point& rPosPixel) const;
/// clears the detail pages
void clearPages();
@@ -279,9 +279,9 @@ namespace dbaui
@param _rxConn
If we insert a table, the connection must be set.
*/
SvTreeListEntry* elementAdded(ElementType eType
,const OUString& _rName
,const css::uno::Any& _rObject );
std::unique_ptr<weld::TreeIter> elementAdded(ElementType eType,
const OUString& rName,
const css::uno::Any& rObject);
/** replaces an objects name with a new one
@param _eType
diff --git a/dbaccess/source/ui/app/AppDetailView.cxx b/dbaccess/source/ui/app/AppDetailView.cxx
index e6e318c..3430d0b 100644
--- a/dbaccess/source/ui/app/AppDetailView.cxx
+++ b/dbaccess/source/ui/app/AppDetailView.cxx
@@ -406,14 +406,14 @@ const TaskPaneData& OApplicationDetailView::impl_getTaskPaneData( ElementType _e
return rData;
}
OUString OApplicationDetailView::getQualifiedName( SvTreeListEntry* _pEntry ) const
OUString OApplicationDetailView::getQualifiedName(weld::TreeIter* _pEntry) const
{
return m_pControlHelper->getQualifiedName( _pEntry );
}
bool OApplicationDetailView::isLeaf(SvTreeListEntry const * _pEntry)
bool OApplicationDetailView::isLeaf(const weld::TreeView& rTreeView, const weld::TreeIter& rEntry)
{
return OAppDetailPageHelper::isLeaf(_pEntry);
return OAppDetailPageHelper::isLeaf(rTreeView, rEntry);
}
bool OApplicationDetailView::isALeafSelected() const
@@ -483,9 +483,9 @@ void OApplicationDetailView::selectElements(const Sequence< OUString>& _aNames)
m_pControlHelper->selectElements( _aNames );
}
SvTreeListEntry* OApplicationDetailView::getEntry( const Point& _aPoint ) const
std::unique_ptr<weld::TreeIter> OApplicationDetailView::getEntry(const Point& rPoint) const
{
return m_pControlHelper->getEntry(_aPoint);
return m_pControlHelper->getEntry(rPoint);
}
bool OApplicationDetailView::isCutAllowed()
@@ -506,9 +506,9 @@ void OApplicationDetailView::cut() { }
void OApplicationDetailView::paste() { }
SvTreeListEntry* OApplicationDetailView::elementAdded(ElementType _eType,const OUString& _rName, const Any& _rObject )
std::unique_ptr<weld::TreeIter> OApplicationDetailView::elementAdded(ElementType _eType,const OUString& _rName, const Any& _rObject )
{
return m_pControlHelper->elementAdded(_eType,_rName, _rObject );
return m_pControlHelper->elementAdded(_eType, _rName, _rObject);
}
void OApplicationDetailView::elementRemoved(ElementType _eType,const OUString& _rName )
diff --git a/dbaccess/source/ui/app/AppDetailView.hxx b/dbaccess/source/ui/app/AppDetailView.hxx
index a00e7f4..c551db1 100644
--- a/dbaccess/source/ui/app/AppDetailView.hxx
+++ b/dbaccess/source/ui/app/AppDetailView.hxx
@@ -158,15 +158,17 @@ namespace dbaui
@return
the qualified name
*/
OUString getQualifiedName( SvTreeListEntry* _pEntry ) const;
OUString getQualifiedName(weld::TreeIter* _pEntry) const;
/** returns if an entry is a leaf
@param _pEntry
@param rTreeView
The TreeView pEntry belongs to
@param rEntry
The entry to check
@return
<TRUE/> if the entry is a leaf, otherwise <FALSE/>
*/
static bool isLeaf(SvTreeListEntry const * _pEntry);
static bool isLeaf(const weld::TreeView& rTreeView, const weld::TreeIter& rEntry);
/** returns if one of the selected entries is a leaf
@return
@@ -241,9 +243,9 @@ namespace dbaui
@param _rxConn
If we insert a table, the connection must be set.
*/
SvTreeListEntry* elementAdded(ElementType eType
,const OUString& _rName
,const css::uno::Any& _rObject );
std::unique_ptr<weld::TreeIter> elementAdded(ElementType eType,
const OUString& rName,
const css::uno::Any& rObject);
/** replaces an objects name with a new one
@param _eType
@@ -303,7 +305,7 @@ namespace dbaui
const OUString& _sName,
bool _bTable);
SvTreeListEntry* getEntry( const Point& _aPoint ) const;
std::unique_ptr<weld::TreeIter> getEntry(const Point& rPosPixel) const;
vcl::Window* getTreeWindow() const;
private:
diff --git a/dbaccess/source/ui/app/AppView.cxx b/dbaccess/source/ui/app/AppView.cxx
index 5ab8ba3..5aa3c2c 100644
--- a/dbaccess/source/ui/app/AppView.cxx
+++ b/dbaccess/source/ui/app/AppView.cxx
@@ -294,16 +294,16 @@ void OApplicationView::paste()
pTest->paste();
}
OUString OApplicationView::getQualifiedName( SvTreeListEntry* _pEntry ) const
OUString OApplicationView::getQualifiedName(weld::TreeIter* _pEntry) const
{
OSL_ENSURE(m_pWin && getDetailView(),"Detail view is NULL! -> GPF");
return getDetailView()->getQualifiedName( _pEntry );
}
bool OApplicationView::isLeaf(SvTreeListEntry const * _pEntry) const
bool OApplicationView::isLeaf(const weld::TreeView& rTreeView, const weld::TreeIter& rEntry) const
{
OSL_ENSURE(m_pWin && getDetailView(),"Detail view is NULL! -> GPF");
return OApplicationDetailView::isLeaf(_pEntry);
return OApplicationDetailView::isLeaf(rTreeView, rEntry);
}
bool OApplicationView::isALeafSelected() const
@@ -384,7 +384,7 @@ void OApplicationView::selectElements(const Sequence< OUString>& _aNames)
getDetailView()->selectElements( _aNames );
}
SvTreeListEntry* OApplicationView::elementAdded(ElementType eType,const OUString& _rName, const Any& _rObject )
std::unique_ptr<weld::TreeIter> OApplicationView::elementAdded(ElementType eType,const OUString& _rName, const Any& _rObject )
{
OSL_ENSURE(m_pWin && getDetailView(),"Detail view is NULL! -> GPF");
return getDetailView()->elementAdded(eType,_rName,_rObject);
@@ -418,10 +418,10 @@ void OApplicationView::selectContainer(ElementType _eType)
getPanel()->selectContainer(_eType);
}
SvTreeListEntry* OApplicationView::getEntry( const Point& _aPosPixel ) const
std::unique_ptr<weld::TreeIter> OApplicationView::getEntry(const Point& rPosPixel) const
{
OSL_ENSURE(m_pWin && getDetailView(),"Detail view is NULL! -> GPF");
return getDetailView()->getEntry(_aPosPixel);
return getDetailView()->getEntry(rPosPixel);
}
PreviewMode OApplicationView::getPreviewMode() const
diff --git a/dbaccess/source/ui/app/AppView.hxx b/dbaccess/source/ui/app/AppView.hxx
index 0d49295..d8f2224 100644
--- a/dbaccess/source/ui/app/AppView.hxx
+++ b/dbaccess/source/ui/app/AppView.hxx
@@ -31,6 +31,11 @@ namespace com::sun::star::beans { class XPropertySet; }
class Control;
class SvTreeListEntry;
namespace weld
{
class TreeIter;
class TreeView;
}
class MnemonicGenerator;
namespace dbaui
@@ -136,15 +141,17 @@ namespace dbaui
@return
the qualified name
*/
OUString getQualifiedName( SvTreeListEntry* _pEntry ) const;
OUString getQualifiedName(weld::TreeIter* _pEntry) const;
/** returns if an entry is a leaf
@param _pEntry
@param rTreeView
The TreeView rEntry belongs to
@param rEntry
The entry to check
@return
<TRUE/> if the entry is a leaf, otherwise <FALSE/>
*/
bool isLeaf(SvTreeListEntry const * _pEntry) const;
bool isLeaf(const weld::TreeView& rTreeView, const weld::TreeIter& rEntry) const;
/** returns if one of the selected entries is a leaf
@return
@@ -218,9 +225,9 @@ namespace dbaui
@param _rxConn
If we insert a table, the connection must be set.
*/
SvTreeListEntry* elementAdded(ElementType _eType
,const OUString& _rName
,const css::uno::Any& _rObject );
std::unique_ptr<weld::TreeIter> elementAdded(ElementType eType,
const OUString& rName,
const css::uno::Any& rObject);
/** replaces an objects name with a new one
@param _eType
@@ -289,7 +296,7 @@ namespace dbaui
const OUString& _sName,
bool _bTable);
SvTreeListEntry* getEntry( const Point& _aPosPixel ) const;
std::unique_ptr<weld::TreeIter> getEntry(const Point& rPosPixel) const;
};
}
#endif // INCLUDED_DBACCESS_SOURCE_UI_APP_APPVIEW_HXX
diff --git a/dbaccess/source/ui/browser/dsbrowserDnD.cxx b/dbaccess/source/ui/browser/dsbrowserDnD.cxx
index cd8c124..0b9888f 100644
--- a/dbaccess/source/ui/browser/dsbrowserDnD.cxx
+++ b/dbaccess/source/ui/browser/dsbrowserDnD.cxx
@@ -191,6 +191,12 @@ namespace dbaui
return pTransfer.is();
}
bool SbaTableQueryBrowser::requestDrag(const weld::TreeIter& /*rEntry*/)
{
return false;
}
IMPL_LINK_NOARG(SbaTableQueryBrowser, OnCopyEntry, LinkParamNone*, void)
{
SvTreeListEntry* pSelected = m_pTreeView->getListBox().FirstSelected();
diff --git a/dbaccess/source/ui/browser/unodatbr.cxx b/dbaccess/source/ui/browser/unodatbr.cxx
index 43a7006..4caa3f4 100644
--- a/dbaccess/source/ui/browser/unodatbr.cxx
+++ b/dbaccess/source/ui/browser/unodatbr.cxx
@@ -3380,13 +3380,19 @@ bool SbaTableQueryBrowser::requestQuickHelp( const SvTreeListEntry* _pEntry, OUS
return false;
}
OUString SbaTableQueryBrowser::getContextMenuResourceName( Control& _rControl ) const
bool SbaTableQueryBrowser::requestQuickHelp(const void* pUserData, OUString& rText) const
{
OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl,
"SbaTableQueryBrowser::getContextMenuResourceName: where does this come from?" );
if ( &m_pTreeView->getListBox() != &_rControl )
return OUString();
const DBTreeListUserData* pData = static_cast<const DBTreeListUserData*>(pUserData);
if (pData->eType == etDatasource && !pData->sAccessor.isEmpty())
{
rText = ::svt::OFileNotation(pData->sAccessor).get( ::svt::OFileNotation::N_SYSTEM);
return true;
}
return false;
}
OUString SbaTableQueryBrowser::getContextMenuResourceName() const
{
return "explorer";
}
diff --git a/dbaccess/source/ui/control/dbtreelistbox.cxx b/dbaccess/source/ui/control/dbtreelistbox.cxx
index 4fbb348..8be8061 100644
--- a/dbaccess/source/ui/control/dbtreelistbox.cxx
+++ b/dbaccess/source/ui/control/dbtreelistbox.cxx
@@ -29,13 +29,14 @@
#include <comphelper/interfacecontainer2.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/propertyvalue.hxx>
#include <vcl/help.hxx>
#include <dbaccess/IController.hxx>
#include <framework/actiontriggerhelper.hxx>
#include <toolkit/awt/vclxmenu.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/treelistentry.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/event.hxx>
#include <vcl/help.hxx>
#include <vcl/treelistentry.hxx>
#include <memory>
@@ -61,6 +62,139 @@ DBTreeListBox::DBTreeListBox( vcl::Window* pParent, WinBits nWinStyle )
init();
}
InterimDBTreeListBox::InterimDBTreeListBox(vcl::Window* pParent)
: InterimItemWindow(pParent, "dbaccess/ui/dbtreelist.ui", "DBTreeList")
, TreeListBox(m_xBuilder->weld_tree_view("treeview"))
{
InitControlBase(&GetWidget());
}
InterimDBTreeListBox::~InterimDBTreeListBox()
{
disposeOnce();
}
void InterimDBTreeListBox::dispose()
{
implStopSelectionTimer();
m_xTreeView.reset();
InterimItemWindow::dispose();
}
bool InterimDBTreeListBox::DoChildKeyInput(const KeyEvent& rKEvt)
{
return ChildKeyInput(rKEvt);
}
TreeListBoxDropTarget::TreeListBoxDropTarget(TreeListBox& rTreeView)
: DropTargetHelper(rTreeView.GetWidget().get_drop_target())
, m_rTreeView(rTreeView)
{
}
sal_Int8 TreeListBoxDropTarget::AcceptDrop(const AcceptDropEvent& rEvt)
{
sal_Int8 nAccept = m_rTreeView.AcceptDrop(rEvt);
if (nAccept != DND_ACTION_NONE)
{
// to enable the autoscroll when we're close to the edges
weld::TreeView& rWidget = m_rTreeView.GetWidget();
rWidget.get_dest_row_at_pos(rEvt.maPosPixel, nullptr, true);
}
return nAccept;
}
sal_Int8 TreeListBoxDropTarget::ExecuteDrop(const ExecuteDropEvent& rEvt)
{
return m_rTreeView.ExecuteDrop(rEvt);
}
TreeListBox::TreeListBox(std::unique_ptr<weld::TreeView> xTreeView)
: m_xTreeView(std::move(xTreeView))
, m_aDropTargetHelper(*this)
, m_pActionListener(nullptr)
, m_pContextMenuProvider(nullptr)
{
m_xTreeView->make_sorted();
m_xTreeView->connect_key_press(LINK(this, TreeListBox, KeyInputHdl));
m_xTreeView->connect_changed(LINK(this, TreeListBox, SelectHdl));
m_xTreeView->connect_query_tooltip(LINK(this, TreeListBox, QueryTooltipHdl));
m_xTreeView->connect_popup_menu(LINK(this, TreeListBox, CommandHdl));
m_xTreeView->connect_drag_begin(LINK(this, TreeListBox, DragBeginHdl));
m_aTimer.SetTimeout(900);
m_aTimer.SetInvokeHandler(LINK(this, TreeListBox, OnTimeOut));
}
bool TreeListBox::DoChildKeyInput(const KeyEvent& /*rKEvt*/)
{
// nothing by default
return false;
}
bool TreeListBox::DoContextMenu(const CommandEvent& /*rCEvt*/)
{
return false;
}
IMPL_LINK(TreeListBox, CommandHdl, const CommandEvent&, rCEvt, bool)
{
return DoContextMenu(rCEvt);
}
IMPL_LINK(TreeListBox, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
bool bHandled = false;
switch (eFunc)
{
case KeyFuncType::COPY:
bHandled = m_aCopyHandler.IsSet() && !m_xTreeView->get_selected(nullptr);
if (bHandled)
m_aCopyHandler.Call(nullptr);
break;
case KeyFuncType::PASTE:
bHandled = m_aPasteHandler.IsSet() && !m_xTreeView->get_selected(nullptr);
if (bHandled)
m_aPasteHandler.Call(nullptr);
break;
case KeyFuncType::DELETE:
bHandled = m_aDeleteHandler.IsSet() && !m_xTreeView->get_selected(nullptr);
if (bHandled)
m_aDeleteHandler.Call(nullptr);
break;
default:
break;
}
return bHandled || DoChildKeyInput(rKEvt);
}
void TreeListBox::implStopSelectionTimer()
{
if ( m_aTimer.IsActive() )
m_aTimer.Stop();
}
void TreeListBox::implStartSelectionTimer()
{
implStopSelectionTimer();
m_aTimer.Start();
}
IMPL_LINK_NOARG(TreeListBox, SelectHdl, weld::TreeView&, void)
{
implStartSelectionTimer();
}
TreeListBox::~TreeListBox()
{
}
void DBTreeListBox::init()
{
SetSpaceBetweenEntries(SPACEBETWEENENTRIES);
@@ -121,6 +255,27 @@ SvTreeListEntry* DBTreeListBox::GetEntryPosByName( const OUString& aName, SvTree
return pEntry;
}
std::unique_ptr<weld::TreeIter> TreeListBox::GetEntryPosByName(const OUString& aName, const 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 DBTreeListBox::RequestingChildren( SvTreeListEntry* pParent )
{
if (m_aPreExpandHandler.IsSet() && !m_aPreExpandHandler.Call(pParent))
@@ -262,6 +417,83 @@ sal_Int8 DBTreeListBox::ExecuteDrop( const ExecuteDropEvent& _rEvt )
return DND_ACTION_NONE;
}
IMPL_LINK(TreeListBox, DragBeginHdl, bool&, rUnsetDragIcon, bool)
{
rUnsetDragIcon = false;
if (m_pActionListener)
{
m_xDragedEntry = m_xTreeView->make_iterator();
if (!m_xTreeView->get_selected(m_xDragedEntry.get()))
m_xDragedEntry.reset();
if (m_xDragedEntry && m_pActionListener->requestDrag(*m_xDragedEntry))
{
// if the (asynchronous) drag started, stop the selection timer
implStopSelectionTimer();
return false;
}
}
return true;
}
sal_Int8 TreeListBox::AcceptDrop(const AcceptDropEvent& rEvt)
{
sal_Int8 nDropOption = DND_ACTION_NONE;
if ( m_pActionListener )
{
::Point aDropPos = rEvt.maPosPixel;
std::unique_ptr<weld::TreeIter> xDropTarget(m_xTreeView->make_iterator());
if (!m_xTreeView->get_dest_row_at_pos(aDropPos, xDropTarget.get(), true))
xDropTarget.reset();
// check if drag is on child entry, which is not allowed
std::unique_ptr<weld::TreeIter> xParent;
if (rEvt.mnAction & DND_ACTION_MOVE)
{
if (!m_xDragedEntry) // no entry to move
return m_pActionListener->queryDrop(rEvt, m_aDropTargetHelper.GetDataFlavorExVector());
if (xDropTarget)
{
xParent = m_xTreeView->make_iterator(xDropTarget.get());
if (!m_xTreeView->iter_parent(*xParent))
xParent.reset();
}
while (xParent && m_xTreeView->iter_compare(*xParent, *m_xDragedEntry) != 0)
{
if (!m_xTreeView->iter_parent(*xParent))
xParent.reset();
}
}
if (!xParent)
{
nDropOption = m_pActionListener->queryDrop(rEvt, m_aDropTargetHelper.GetDataFlavorExVector());
// check if move is allowed
if ( nDropOption & DND_ACTION_MOVE )
{
if (!m_xDragedEntry || !xDropTarget ||
m_xTreeView->iter_compare(*m_xDragedEntry, *xDropTarget) == 0 ||
GetEntryPosByName(m_xTreeView->get_text(*m_xDragedEntry), xDropTarget.get()))
{
nDropOption = nDropOption & ~DND_ACTION_MOVE;//DND_ACTION_NONE;
}
}
}
}
return nDropOption;
}
sal_Int8 TreeListBox::ExecuteDrop(const ExecuteDropEvent& rEvt)
{
if (m_pActionListener)
m_pActionListener->executeDrop(rEvt);
m_xTreeView->unset_drag_dest_row();
return DND_ACTION_NONE;
}
void DBTreeListBox::StartDrag( sal_Int8 /*_nAction*/, const Point& _rPosPixel )
{
if ( m_pActionListener )
@@ -307,6 +539,17 @@ void DBTreeListBox::RequestHelp( const HelpEvent& rHEvt )
SvTreeListBox::RequestHelp( rHEvt );
}
IMPL_LINK(TreeListBox, QueryTooltipHdl, const weld::TreeIter&, rIter, OUString)
{
OUString sQuickHelpText;
if (m_pActionListener &&
m_pActionListener->requestQuickHelp(reinterpret_cast<void*>(m_xTreeView->get_id(rIter).toUInt64()), sQuickHelpText))
{
return sQuickHelpText;
}
return m_xTreeView->get_tooltip_text();
}
void DBTreeListBox::KeyInput( const KeyEvent& rKEvt )
{
KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
@@ -458,12 +701,128 @@ namespace
}
}
bool InterimDBTreeListBox::DoContextMenu(const CommandEvent& rCEvt)
{
if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
return false;
const ::Point& rPos = rCEvt.GetMousePosPixel();
std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
if (m_xTreeView->get_dest_row_at_pos(rPos, xIter.get(), false) && !m_xTreeView->is_selected(*xIter))
{
m_xTreeView->unselect_all();
m_xTreeView->set_cursor(*xIter);
m_xTreeView->select(*xIter);
SelectHdl(*m_xTreeView);
}
if (!m_pContextMenuProvider)
return false;
OUString aResourceName(m_pContextMenuProvider->getContextMenuResourceName());
if (aResourceName.isEmpty())
return false;
css::uno::Sequence< css::uno::Any > aArgs( 3 );
aArgs[0] <<= comphelper::makePropertyValue( "Value", aResourceName );
aArgs[1] <<= comphelper::makePropertyValue( "Frame", m_pContextMenuProvider->getCommandController().getXController()->getFrame() );
aArgs[2] <<= comphelper::makePropertyValue( "IsContextMenu", true );
css::uno::Reference< css::uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
css::uno::Reference<css::frame::XPopupMenuController> xMenuController
(xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
"com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext), css::uno::UNO_QUERY);
if (!xMenuController.is())
return false;
rtl::Reference xPopupMenu( new VCLXPopupMenu );
xMenuController->setPopupMenu( xPopupMenu.get() );
VclPtr<PopupMenu> pContextMenu( static_cast< PopupMenu* >( xPopupMenu->GetMenu() ) );
// allow context menu interception
::comphelper::OInterfaceContainerHelper2* pInterceptors = m_pContextMenuProvider->getContextMenuInterceptors();
if (pInterceptors && pInterceptors->getLength())
{
OUString aMenuIdentifier( "private:resource/popupmenu/" + aResourceName );
ContextMenuExecuteEvent aEvent;
aEvent.SourceWindow = VCLUnoHelper::GetInterface( this );
aEvent.ExecutePosition.X = -1;
aEvent.ExecutePosition.Y = -1;
aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
pContextMenu.get(), &aMenuIdentifier );
aEvent.Selection = new SelectionSupplier( m_pContextMenuProvider->getCurrentSelection( *this ) );
::comphelper::OInterfaceIteratorHelper2 aIter( *pInterceptors );
bool bModifiedMenu = false;
bool bAskInterceptors = true;
while ( aIter.hasMoreElements() && bAskInterceptors )
{
Reference< XContextMenuInterceptor > xInterceptor( aIter.next(), UNO_QUERY );
if ( !xInterceptor.is() )
continue;
try
{
ContextMenuInterceptorAction eAction = xInterceptor->notifyContextMenuExecute( aEvent );
switch ( eAction )
{
case ContextMenuInterceptorAction_CANCELLED:
return false;
case ContextMenuInterceptorAction_EXECUTE_MODIFIED:
bModifiedMenu = true;
bAskInterceptors = false;
break;
case ContextMenuInterceptorAction_CONTINUE_MODIFIED:
bModifiedMenu = true;
bAskInterceptors = true;
break;
default:
OSL_FAIL( "DBTreeListBox::CreateContextMenu: unexpected return value of the interceptor call!" );
[[fallthrough]];
case ContextMenuInterceptorAction_IGNORED:
break;
}
}
catch( const DisposedException& e )
{
if ( e.Context == xInterceptor )
aIter.remove();
}
}
if ( bModifiedMenu )
{
pContextMenu->Clear();
::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer(
pContextMenu, aEvent.ActionTriggerContainer );
aEvent.ActionTriggerContainer.clear();
}
}
// do action for selected entry in popup menu
pContextMenu->Execute(this, rPos);
pContextMenu.disposeAndClear();
css::uno::Reference<css::lang::XComponent> xComponent(xMenuController, css::uno::UNO_QUERY);
if (xComponent.is())
xComponent->dispose();
xMenuController.clear();
return true;
}
VclPtr<PopupMenu> DBTreeListBox::CreateContextMenu()
{
if ( !m_pContextMenuProvider )
return nullptr;
OUString aResourceName( m_pContextMenuProvider->getContextMenuResourceName( *this ) );
OUString aResourceName( m_pContextMenuProvider->getContextMenuResourceName() );
if ( aResourceName.isEmpty() )
return nullptr;
@@ -569,6 +928,13 @@ IMPL_LINK_NOARG(DBTreeListBox, OnTimeOut, Timer*, void)
m_aSelChangeHdl.Call( nullptr );
}
IMPL_LINK_NOARG(TreeListBox, OnTimeOut, Timer*, void)
{
implStopSelectionTimer();
m_aSelChangeHdl.Call( nullptr );
}
void DBTreeListBox::StateChanged( StateChangedType nStateChange )
{
if ( nStateChange == StateChangedType::Visible )
diff --git a/dbaccess/source/ui/control/tabletree.cxx b/dbaccess/source/ui/control/tabletree.cxx
index b565b62..99bcfad 100644
--- a/dbaccess/source/ui/control/tabletree.cxx
+++ b/dbaccess/source/ui/control/tabletree.cxx
@@ -36,7 +36,6 @@
#include <vcl/event.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <vcl/treelistentry.hxx>
#include <algorithm>
@@ -59,88 +58,40 @@ namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer;
// OTableTreeListBox
OTableTreeListBox::OTableTreeListBox(vcl::Window* pParent, WinBits nWinStyle)
: DBTreeListBox(pParent, nWinStyle)
, m_xImageProvider( new ImageProvider )
, m_bVirtualRoot(false)
, m_bNoEmptyFolders( false )
{
InitButtonData();
implSetDefaultImages();
}
void OTableTreeListBox::InitButtonData()
{
m_pCheckButton.reset( new SvLBoxButtonData( this ) );
EnableCheckButton( m_pCheckButton.get() );
}
void OTableTreeListBox::dispose()
{
m_pCheckButton.reset();
DBTreeListBox::dispose();
}
TableTreeListBox::TableTreeListBox(std::unique_ptr<weld::TreeView> xTreeView)
: m_xImageProvider(new ImageProvider)
OTableTreeListBox::OTableTreeListBox(vcl::Window* pParent, bool bShowToggles)
: InterimDBTreeListBox(pParent)
, m_xImageProvider(new ImageProvider)
, m_bVirtualRoot(false)
, m_bNoEmptyFolders(false)
, m_bShowToggles(true)
, m_xTreeView(std::move(xTreeView))
, m_bShowToggles(bShowToggles)
{
m_xTreeView->enable_toggle_buttons(weld::ColumnToggleType::Check);
if (m_bShowToggles)
m_xTreeView->enable_toggle_buttons(weld::ColumnToggleType::Check);
}
void OTableTreeListBox::implSetDefaultImages()
OTableTreeListBox::~OTableTreeListBox()
{
SetDefaultExpandedEntryBmp( ImageProvider::getFolderImage( DatabaseObject::TABLE ) );
SetDefaultCollapsedEntryBmp( ImageProvider::getFolderImage( DatabaseObject::TABLE ) );
}
bool OTableTreeListBox::isFolderEntry( const SvTreeListEntry* _pEntry )
TableTreeListBox::TableTreeListBox(std::unique_ptr<weld::TreeView> xTreeView, bool bShowToggles)
: TreeListBox(std::move(xTreeView))
, m_xImageProvider(new ImageProvider)
, m_bVirtualRoot(false)
, m_bNoEmptyFolders(false)
, m_bShowToggles(bShowToggles)
{
sal_Int32 nEntryType = reinterpret_cast< sal_IntPtr >( _pEntry->GetUserData() );
if (m_bShowToggles)
m_xTreeView->enable_toggle_buttons(weld::ColumnToggleType::Check);
}
bool OTableTreeListBox::isFolderEntry(const weld::TreeIter& rEntry) const
{
sal_Int32 nEntryType = m_xTreeView->get_id(rEntry).toInt32();
return ( nEntryType == DatabaseObjectContainer::TABLES )
|| ( nEntryType == DatabaseObjectContainer::CATALOG )
|| ( nEntryType == DatabaseObjectContainer::SCHEMA );
}
void OTableTreeListBox::notifyHiContrastChanged()
{
implSetDefaultImages();
SvTreeListEntry* pEntryLoop = First();
while (pEntryLoop)
{
size_t nCount = pEntryLoop->ItemCount();
for (size_t i=0;i<nCount;++i)
{
SvLBoxItem& rItem = pEntryLoop->GetItem(i);
if (rItem.GetType() == SvLBoxItemType::ContextBmp)
{
SvLBoxContextBmp& rContextBitmapItem = static_cast< SvLBoxContextBmp& >( rItem );
Image aImage;
if ( isFolderEntry( pEntryLoop ) )
{
aImage = ImageProvider::getFolderImage( DatabaseObject::TABLE );
}
else
{
OUString sCompleteName( getQualifiedTableName( pEntryLoop ) );
m_xImageProvider->getImages( sCompleteName, DatabaseObject::TABLE, aImage );
}
rContextBitmapItem.SetBitmap1( aImage );
rContextBitmapItem.SetBitmap2( aImage );
break;
}
}
pEntryLoop = Next(pEntryLoop);
}
}
void OTableTreeListBox::implOnNewConnection( const Reference< XConnection >& _rxConnection )
{
m_xConnection = _rxConnection;
@@ -153,7 +104,7 @@ void TableTreeListBox::implOnNewConnection( const Reference< XConnection >& _rxC
m_xImageProvider.reset( new ImageProvider( m_xConnection ) );
}
void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConnection )
void OTableTreeListBox::UpdateTableList(const Reference<XConnection>& _rxConnection)
{
Sequence< OUString > sTables, sViews;
@@ -324,7 +275,8 @@ void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConn
implOnNewConnection( _rxConnection );
// throw away all the old stuff
Clear();
m_xTreeView->clear();
m_xTreeView->make_unsorted();
try
{
@@ -339,7 +291,15 @@ void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConn
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 ) );
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, false, xRet.get());
m_xTreeView->set_image(*xRet, sImageId, -1);
if (m_bShowToggles)
m_xTreeView->set_toggle(*xRet, TRISTATE_FALSE);
m_xTreeView->set_text(*xRet, sRootEntryText, 0);
m_xTreeView->set_text_emphasis(*xRet, false, 0);
}
if ( _rTables.empty() )
@@ -370,12 +330,23 @@ void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConn
bCatalogs ? xMeta->getCatalogs() : xMeta->getSchemas(), 1 ) );
sal_Int32 nFolderType = bCatalogs ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA;
SvTreeListEntry* pRootEntry = getAllObjectsEntry();
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)
{
SvTreeListEntry* pFolder = GetEntryPosByName( folderName, pRootEntry );
if ( !pFolder )
InsertEntry( folderName, pRootEntry, false, TREELIST_APPEND, reinterpret_cast< void* >( nFolderType ) );
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, false, xRet.get());
m_xTreeView->set_image(*xRet, sImageId, -1);
if (m_bShowToggles)
m_xTreeView->set_toggle(*xRet, TRISTATE_FALSE);
m_xTreeView->set_text(*xRet, folderName, 0);
m_xTreeView->set_text_emphasis(*xRet, false, 0);
}
}
}
}
@@ -384,11 +355,8 @@ void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConn
{
DBG_UNHANDLED_EXCEPTION("dbaccess");
}
}
void TableTreeListBox::DisableCheckButtons()
{
m_bShowToggles = false;
m_xTreeView->make_sorted();
}
void TableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConnection, const TNames& _rTables )
@@ -480,15 +448,9 @@ void TableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConne
m_xTreeView->make_sorted();
}
bool OTableTreeListBox::isWildcardChecked(SvTreeListEntry* _pEntry)
bool OTableTreeListBox::isWildcardChecked(const weld::TreeIter& rEntry)
{
if (_pEntry)
{
OBoldListboxString* pTextItem = static_cast<OBoldListboxString*>(_pEntry->GetFirstItem(SvLBoxItemType::String));
if (pTextItem)
return pTextItem->isEmphasized();
}
return false;
return m_xTreeView->get_text_emphasis(rEntry, 0);
}
bool TableTreeListBox::isWildcardChecked(const weld::TreeIter& rEntry)
@@ -496,10 +458,12 @@ bool TableTreeListBox::isWildcardChecked(const weld::TreeIter& rEntry)
return m_xTreeView->get_text_emphasis(rEntry, 0);
}
void OTableTreeListBox::checkWildcard(SvTreeListEntry* _pEntry)
void OTableTreeListBox::checkWildcard(weld::TreeIter& rEntry)
{
SetCheckButtonState(_pEntry, SvButtonState::Checked);
checkedButton_noBroadcast(_pEntry);
if (!m_bShowToggles)
return;
m_xTreeView->set_toggle(rEntry, TRISTATE_TRUE);
checkedButton_noBroadcast(rEntry);
}
void TableTreeListBox::checkWildcard(weld::TreeIter& rEntry)
@@ -510,9 +474,14 @@ void TableTreeListBox::checkWildcard(weld::TreeIter& rEntry)
checkedButton_noBroadcast(rEntry);
}
SvTreeListEntry* OTableTreeListBox::getAllObjectsEntry() const
std::unique_ptr<weld::TreeIter> OTableTreeListBox::getAllObjectsEntry() const
{
return haveVirtualRoot() ? First() : nullptr;
if (!haveVirtualRoot())
return nullptr;
auto xRet = m_xTreeView->make_iterator();
if (!m_xTreeView->get_iter_first(*xRet))
return nullptr;
return xRet;
}
std::unique_ptr<weld::TreeIter> TableTreeListBox::getAllObjectsEntry() const
@@ -525,48 +494,61 @@ std::unique_ptr<weld::TreeIter> TableTreeListBox::getAllObjectsEntry() const
return xRet;
}
void OTableTreeListBox::checkedButton_noBroadcast(SvTreeListEntry* _pEntry)
void OTableTreeListBox::checkedButton_noBroadcast(const weld::TreeIter& rEntry)
{
SvButtonState eState = GetCheckButtonState( _pEntry);
if (GetModel()->HasChildren(_pEntry)) // if it has children, check those too
if (!m_bShowToggles)
return;
TriState eState = m_xTreeView->get_toggle(rEntry);
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
{
SvTreeListEntry* pChildEntry = GetModel()->Next(_pEntry);
SvTreeListEntry* pSiblingEntry = _pEntry->NextSibling();
while(pChildEntry && pChildEntry != pSiblingEntry)
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)))
{
SetCheckButtonState(pChildEntry, eState);
pChildEntry = GetModel()->Next(pChildEntry);
m_xTreeView->set_toggle(*xChildEntry, eState);
bChildEntry = m_xTreeView->iter_next(*xChildEntry);
}
}
SvTreeListEntry* pEntry = IsSelected(_pEntry) ? FirstSelected() : nullptr;
while(pEntry)
if (m_xTreeView->is_selected(rEntry))
{
SetCheckButtonState(pEntry,eState);
if(GetModel()->HasChildren(pEntry)) // if it has children, check those too
{
SvTreeListEntry* pChildEntry = GetModel()->Next(pEntry);
SvTreeListEntry* pSiblingEntry = pEntry->NextSibling();
while(pChildEntry && pChildEntry != pSiblingEntry)
m_xTreeView->selected_foreach([this, eState](weld::TreeIter& rSelected){
m_xTreeView->set_toggle(rSelected, eState);
if (m_xTreeView->iter_has_child(rSelected)) // if it has children, check those too
{
SetCheckButtonState(pChildEntry,eState);
pChildEntry = GetModel()->Next(pChildEntry);
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);
bChildEntry = m_xTreeView->iter_next(*xChildEntry);
}
}
}
pEntry = NextSelected(pEntry);
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(_pEntry, SvButtonState::Checked == eState);
implEmphasize(rEntry, eState == TRISTATE_TRUE);
}
SvButtonState OTableTreeListBox::implDetermineState(SvTreeListEntry* _pEntry)
TriState OTableTreeListBox::implDetermineState(weld::TreeIter& rEntry)
{
SvButtonState eState = GetCheckButtonState(_pEntry);
if (!GetModel()->HasChildren(_pEntry))
if (!m_bShowToggles)
return TRISTATE_FALSE;
TriState eState = m_xTreeView->get_toggle(rEntry);
if (!m_xTreeView->iter_has_child(rEntry))
// nothing to do in this bottom-up routine if there are no children ...
return eState;
@@ -574,109 +556,76 @@ SvButtonState OTableTreeListBox::implDetermineState(SvTreeListEntry* _pEntry)
sal_uInt16 nCheckedChildren = 0;
sal_uInt16 nChildrenOverall = 0;
SvTreeListEntry* pChildLoop = GetModel()->FirstChild(_pEntry);
while (pChildLoop)
std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(&rEntry));
bool bChildLoop = m_xTreeView->iter_children(*xChild);
while (bChildLoop)
{
SvButtonState eChildState = implDetermineState(pChildLoop);
if (SvButtonState::Tristate == eChildState)
TriState eChildState = implDetermineState(*xChild);
if (eChildState == TRISTATE_INDET)
break;
if (SvButtonState::Checked == eChildState)
if (eChildState == TRISTATE_TRUE)
++nCheckedChildren;
++nChildrenOverall;
pChildLoop = pChildLoop->NextSibling();
bChildLoop = m_xTreeView->iter_next_sibling(*xChild);
}
if (pChildLoop)
if (bChildLoop)
{
// we did not finish the loop because at least one of the children is in tristate
eState = SvButtonState::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 (pChildLoop)
while (bChildLoop)
{
implDetermineState(pChildLoop);
pChildLoop = pChildLoop->NextSibling();
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 = SvButtonState::Tristate;
eState = TRISTATE_INDET;
}
else
{
// all children are checked
eState = SvButtonState::Checked;
eState = TRISTATE_TRUE;
}
}
else
{
// no children are checked
eState = SvButtonState::Unchecked;
eState = TRISTATE_FALSE;
}
}
// finally set the entry to the state we just determined
SetCheckButtonState(_pEntry, eState);
m_xTreeView->set_toggle(rEntry, eState);
return eState;
}
void OTableTreeListBox::CheckButtons()
{
SvTreeListEntry* pEntry = GetModel()->First();
while (pEntry)
if (!m_bShowToggles)
return;
auto xEntry(m_xTreeView->make_iterator());
if (!m_xTreeView->get_iter_first(*xEntry))
return;
do
{
implDetermineState(pEntry);
pEntry = pEntry->NextSibling();
}
}
void OTableTreeListBox::CheckButtonHdl()
{
checkedButton_noBroadcast(GetHdlEntry());
m_aCheckButtonHandler.Call(this);
}
void OTableTreeListBox::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& _rRect)
{
if (!IsEnabled())
{
vcl::Font aOldFont = rRenderContext.GetFont();
vcl::Font aNewFont(aOldFont);
StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
aNewFont.SetColor(aSystemStyle.GetDisableColor());
rRenderContext.SetFont(aNewFont);
DBTreeListBox::Paint(rRenderContext, _rRect);
rRenderContext.SetFont(aOldFont);
}
else
DBTreeListBox::Paint(rRenderContext, _rRect);
}
void OTableTreeListBox::KeyInput( const KeyEvent& rKEvt )
{
// only if there are spaces
if (rKEvt.GetKeyCode().GetCode() == KEY_SPACE && !rKEvt.GetKeyCode().IsShift() && !rKEvt.GetKeyCode().IsMod1())
{
SvTreeListEntry* pCurrentHandlerEntry = GetHdlEntry();
if(pCurrentHandlerEntry)
{
SvButtonState eState = GetCheckButtonState( pCurrentHandlerEntry);
if(eState == SvButtonState::Checked)
SetCheckButtonState( pCurrentHandlerEntry, SvButtonState::Unchecked);
else
SetCheckButtonState( pCurrentHandlerEntry, SvButtonState::Checked);
CheckButtonHdl();
}
else
DBTreeListBox::KeyInput(rKEvt);
}
else
DBTreeListBox::KeyInput(rKEvt);
implDetermineState(*xEntry);
} while (m_xTreeView->iter_next_sibling(*xEntry));
}
void TableTreeListBox::checkedButton_noBroadcast(const weld::TreeIter& rEntry)
@@ -727,41 +676,36 @@ void TableTreeListBox::checkedButton_noBroadcast(const weld::TreeIter& rEntry)
implEmphasize(rEntry, eState == TRISTATE_TRUE);
}
void OTableTreeListBox::implEmphasize(SvTreeListEntry* _pEntry, bool _bChecked, bool _bUpdateDescendants, bool _bUpdateAncestors)
void OTableTreeListBox::implEmphasize(const weld::TreeIter& rEntry, bool _bChecked, bool _bUpdateDescendants, bool _bUpdateAncestors)
{
OSL_ENSURE(_pEntry, "OTableTreeListBox::implEmphasize: invalid entry (NULL)!");
// 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
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
)
{
OBoldListboxString* pTextItem = static_cast<OBoldListboxString*>(_pEntry->GetFirstItem(SvLBoxItemType::String));
if (pTextItem)
pTextItem->emphasize(_bChecked);
if (bAllObjectsEntryAffected)
InvalidateEntry(_pEntry);
m_xTreeView->set_text_emphasis(rEntry, _bChecked, 0);
}
if (_bUpdateDescendants)
{
std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(&rEntry));
// remove the mark for all children of the checked entry
SvTreeListEntry* pChildLoop = FirstChild(_pEntry);
while (pChildLoop)
bool bChildLoop = m_xTreeView->iter_children(*xChild);
while (bChildLoop)
{
if (GetModel()->HasChildren(pChildLoop))
implEmphasize(pChildLoop, false, true, false);
pChildLoop = pChildLoop->NextSibling();
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 (GetModel()->HasParent(_pEntry))
implEmphasize(GetParent(_pEntry), false, false);
if (m_xTreeView->iter_parent(*xParent))
implEmphasize(*xParent, false, false);
}
}
@@ -798,20 +742,7 @@ void TableTreeListBox::implEmphasize(const weld::TreeIter& rEntry, bool _bChecke
}
}
void OTableTreeListBox::InitEntry(SvTreeListEntry* _pEntry, const OUString& _rString, const Image& _rCollapsedBitmap, const Image& _rExpandedBitmap)
{
DBTreeListBox::InitEntry(_pEntry, _rString, _rCollapsedBitmap, _rExpandedBitmap);
// replace the text item with our own one
SvLBoxItem* pTextItem = _pEntry->GetFirstItem(SvLBoxItemType::String);
OSL_ENSURE(pTextItem, "OTableTreeListBox::InitEntry: no text item!?");
size_t nTextPos = _pEntry->GetPos(pTextItem);
OSL_ENSURE(SvTreeListEntry::ITEM_NOT_FOUND != nTextPos, "OTableTreeListBox::InitEntry: no text item pos!");
_pEntry->ReplaceItem(std::make_unique<OBoldListboxString>(_rString), nTextPos);
}
SvTreeListEntry* OTableTreeListBox::implAddEntry(
std::unique_ptr<weld::TreeIter> OTableTreeListBox::implAddEntry(
const Reference< XDatabaseMetaData >& _rxMeta,
const OUString& _rTableName,
bool _bCheckName
@@ -825,7 +756,7 @@ SvTreeListEntry* OTableTreeListBox::implAddEntry(
OUString sCatalog, sSchema, sName;
qualifiedNameComponents( _rxMeta, _rTableName, sCatalog, sSchema, sName, ::dbtools::EComposeRule::InDataManipulation );
SvTreeListEntry* pParentEntry = getAllObjectsEntry();
std::unique_ptr<weld::TreeIter> xParentEntry(getAllObjectsEntry());
// if the DB uses catalog at the start of identifiers, then our hierarchy is
// catalog
@@ -843,32 +774,62 @@ SvTreeListEntry* OTableTreeListBox::implAddEntry(
if ( !rFirstName.isEmpty() )
{
SvTreeListEntry* pFolder = GetEntryPosByName( rFirstName, pParentEntry );
if ( !pFolder )
pFolder = InsertEntry( rFirstName, pParentEntry, false, TREELIST_APPEND, reinterpret_cast< void* >( nFirstFolderType ) );
pParentEntry = pFolder;
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, false, xFolder.get());
m_xTreeView->set_image(*xFolder, sImageId, -1);
if (m_bShowToggles)
m_xTreeView->set_toggle(*xFolder, TRISTATE_FALSE);
m_xTreeView->set_text(*xFolder, rFirstName, 0);
m_xTreeView->set_text_emphasis(*xFolder, false, 0);
}
xParentEntry = std::move(xFolder);
}
if ( !rSecondName.isEmpty() )
{
SvTreeListEntry* pFolder = GetEntryPosByName( rSecondName, pParentEntry );
if ( !pFolder )
pFolder = InsertEntry( rSecondName, pParentEntry, false, TREELIST_APPEND, reinterpret_cast< void* >( nSecondFolderType ) );
pParentEntry = pFolder;
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, false, xFolder.get());
m_xTreeView->set_image(*xFolder, sImageId, -1);
if (m_bShowToggles)
m_xTreeView->set_toggle(*xFolder, TRISTATE_FALSE);
m_xTreeView->set_text(*xFolder, rSecondName, 0);
m_xTreeView->set_text_emphasis(*xFolder, false, 0);
}
xParentEntry = std::move(xFolder);
}
SvTreeListEntry* pRet = nullptr;
if ( !_bCheckName || !GetEntryPosByName( sName, pParentEntry ) )
if (!_bCheckName || !GetEntryPosByName(sName, xParentEntry.get()))
{
pRet = InsertEntry( sName, pParentEntry );
std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
m_xTreeView->insert(xParentEntry.get(), -1, nullptr, nullptr, nullptr, nullptr, false, xEntry.get());
Image aImage;
m_xImageProvider->getImages( _rTableName, DatabaseObject::TABLE, aImage );
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);
SetExpandedEntryBmp( pRet, aImage );
SetCollapsedEntryBmp( pRet, aImage );
return xEntry;
}
return pRet;
return nullptr;
}
void TableTreeListBox::implAddEntry(
@@ -957,11 +918,11 @@ void TableTreeListBox::implAddEntry(
}
}
NamedDatabaseObject OTableTreeListBox::describeObject( SvTreeListEntry* _pEntry )
NamedDatabaseObject OTableTreeListBox::describeObject(weld::TreeIter& rEntry)
{
NamedDatabaseObject aObject;
sal_Int32 nEntryType = reinterpret_cast< sal_IntPtr >( _pEntry->GetUserData() );
sal_Int32 nEntryType = m_xTreeView->get_id(rEntry).toInt32();
if ( nEntryType == DatabaseObjectContainer::TABLES )
{
@@ -976,19 +937,19 @@ NamedDatabaseObject OTableTreeListBox::describeObject( SvTreeListEntry* _pEntry
else
{
aObject.Type = DatabaseObject::TABLE;
aObject.Name = getQualifiedTableName( _pEntry );
aObject.Name = getQualifiedTableName(rEntry);
}
return aObject;
}
SvTreeListEntry* OTableTreeListBox::addedTable( const OUString& _rName )
std::unique_ptr<weld::TreeIter> OTableTreeListBox::addedTable(const OUString& rName)
{
try
{
Reference< XDatabaseMetaData > xMeta;
if ( impl_getAndAssertMetaData( xMeta ) )
return implAddEntry( xMeta, _rName );
return implAddEntry( xMeta, rName );
}
catch( const Exception& )
{
@@ -1005,9 +966,9 @@ bool OTableTreeListBox::impl_getAndAssertMetaData( Reference< XDatabaseMetaData
return _out_rMetaData.is();
}
OUString OTableTreeListBox::getQualifiedTableName( SvTreeListEntry* _pEntry ) const
OUString OTableTreeListBox::getQualifiedTableName(weld::TreeIter& rEntry) const
{
OSL_PRECOND( !isFolderEntry( _pEntry ), "OTableTreeListBox::getQualifiedTableName: folder entries not allowed here!" );
OSL_PRECOND( !isFolderEntry(rEntry), "OTableTreeListBox::getQualifiedTableName: folder entries not allowed here!" );
try
{
@@ -1019,27 +980,29 @@ OUString OTableTreeListBox::getQualifiedTableName( SvTreeListEntry* _pEntry ) co
OUString sSchema;
OUString sTable;
SvTreeListEntry* pSchema = GetParent( _pEntry );
if ( pSchema )
std::unique_ptr<weld::TreeIter> xSchema(m_xTreeView->make_iterator(&rEntry));
bool bSchema = m_xTreeView->iter_parent(*xSchema);
if (bSchema)
{
SvTreeListEntry* pCatalog = GetParent( pSchema );
if ( pCatalog
std::unique_ptr<weld::TreeIter> xCatalog(m_xTreeView->make_iterator(xSchema.get()));
bool bCatalog = m_xTreeView->iter_parent(*xCatalog);
if ( bCatalog
|| ( xMeta->supportsCatalogsInDataManipulation()
&& !xMeta->supportsSchemasInDataManipulation()
) // here we support catalog but no schema
)
{
if ( pCatalog == nullptr )
if (!bCatalog)
{
pCatalog = pSchema;
pSchema = nullptr;
xCatalog = std::move(xSchema);
bSchema = false;
}
sCatalog = GetEntryText( pCatalog );
sCatalog = m_xTreeView->get_text(*xCatalog);
}
if ( pSchema )
sSchema = GetEntryText(pSchema);
if (bSchema)
sSchema = m_xTreeView->get_text(*xSchema);
}
sTable = GetEntryText( _pEntry );
sTable = m_xTreeView->get_text(rEntry);
return ::dbtools::composeTableName( xMeta, sCatalog, sSchema, sTable, false, ::dbtools::EComposeRule::InDataManipulation );
}
@@ -1050,7 +1013,7 @@ OUString OTableTreeListBox::getQualifiedTableName( SvTreeListEntry* _pEntry ) co
return OUString();
}
SvTreeListEntry* OTableTreeListBox::getEntryByQualifiedName( const OUString& _rName )
std::unique_ptr<weld::TreeIter> OTableTreeListBox::getEntryByQualifiedName(const OUString& rName)
{
try
{
@@ -1060,26 +1023,26 @@ SvTreeListEntry* OTableTreeListBox::getEntryByQualifiedName( const OUString& _rN
// split the complete name into its components
OUString sCatalog, sSchema, sName;
qualifiedNameComponents(xMeta, _rName, sCatalog, sSchema, sName,::dbtools::EComposeRule::InDataManipulation);
qualifiedNameComponents(xMeta, rName, sCatalog, sSchema, sName,::dbtools::EComposeRule::InDataManipulation);
SvTreeListEntry* pParent = getAllObjectsEntry();
SvTreeListEntry* pCat = nullptr;
SvTreeListEntry* pSchema = nullptr;
if ( !sCatalog.isEmpty() )
std::unique_ptr<weld::TreeIter> xParent(getAllObjectsEntry());
std::unique_ptr<weld::TreeIter> xCat;
std::unique_ptr<weld::TreeIter> xSchema;
if (!sCatalog.isEmpty())
{
pCat = GetEntryPosByName(sCatalog, pParent);
if ( pCat )
pParent = pCat;
xCat = GetEntryPosByName(sCatalog);
if (xCat)
xParent = std::move(xCat);
}
if ( !sSchema.isEmpty() )
if (!sSchema.isEmpty())
{
pSchema = GetEntryPosByName(sSchema, pParent);
if ( pSchema )
pParent = pSchema;
xSchema = GetEntryPosByName(sSchema, xParent.get());
if (xSchema)
xParent = std::move(xSchema);
}
return GetEntryPosByName(sName, pParent);
return GetEntryPosByName(sName, xParent.get());
}
catch( const Exception& )
{
@@ -1088,13 +1051,13 @@ SvTreeListEntry* OTableTreeListBox::getEntryByQualifiedName( const OUString& _rN
return nullptr;
}
void OTableTreeListBox::removedTable( const OUString& _rName )
void OTableTreeListBox::removedTable(const OUString& rName)
{
try
{
SvTreeListEntry* pEntry = getEntryByQualifiedName( _rName );
if ( pEntry )
GetModel()->Remove( pEntry );
std::unique_ptr<weld::TreeIter> xEntry = getEntryByQualifiedName(rName);
if (xEntry)
m_xTreeView->remove(*xEntry);
}
catch( const Exception& )
{
@@ -1102,27 +1065,6 @@ void OTableTreeListBox::removedTable( const OUString& _rName )
}
}
std::unique_ptr<weld::TreeIter> TableTreeListBox::GetEntryPosByName(const OUString& aName, const 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()
{
if (!m_bShowToggles)
diff --git a/dbaccess/source/ui/dlg/adtabdlg.cxx b/dbaccess/source/ui/dlg/adtabdlg.cxx
index 35e29ed..485bb39 100644
--- a/dbaccess/source/ui/dlg/adtabdlg.cxx
+++ b/dbaccess/source/ui/dlg/adtabdlg.cxx
@@ -335,7 +335,8 @@ OAddTableDlg::OAddTableDlg(weld::Window* pParent, IAddTableDialogContext& _rCont
, m_rContext(_rContext)
, m_xCaseTables(m_xBuilder->weld_radio_button("tables"))
, m_xCaseQueries(m_xBuilder->weld_radio_button("queries"))
, m_xTableList(new TableTreeListBox(m_xBuilder->weld_tree_view("tablelist")))
// false means: do not show any buttons
, m_xTableList(new TableTreeListBox(m_xBuilder->weld_tree_view("tablelist"), false))
, m_xQueryList(m_xBuilder->weld_tree_view("querylist"))
, m_xAddButton(m_xBuilder->weld_button("add"))
, m_xCloseButton(m_xBuilder->weld_button("close"))
@@ -356,7 +357,6 @@ OAddTableDlg::OAddTableDlg(weld::Window* pParent, IAddTableDialogContext& _rCont
m_xQueryList->connect_changed( LINK( this, OAddTableDlg, TableListSelectHdl ) );
rTableList.set_selection_mode(SelectionMode::Single);
m_xTableList->DisableCheckButtons(); // do not show any buttons
m_xTableList->SuppressEmptyFolders();
m_xQueryList->set_selection_mode(SelectionMode::Single);
diff --git a/dbaccess/source/ui/dlg/tablespage.cxx b/dbaccess/source/ui/dlg/tablespage.cxx
index 2fa7195..3440b90 100644
--- a/dbaccess/source/ui/dlg/tablespage.cxx
+++ b/dbaccess/source/ui/dlg/tablespage.cxx
@@ -55,7 +55,7 @@ namespace dbaui
, m_bCatalogAtStart(true)
, m_pTablesDlg(pTablesDlg)
, m_xTables(m_xBuilder->weld_widget("TablesFilterPage"))
, m_xTablesList(new TableTreeListBox(m_xBuilder->weld_tree_view("treeview")))
, m_xTablesList(new TableTreeListBox(m_xBuilder->weld_tree_view("treeview"), true))
{
m_xTablesList->init();
diff --git a/dbaccess/source/ui/inc/callbacks.hxx b/dbaccess/source/ui/inc/callbacks.hxx
index 8a607db..e18a655 100644
--- a/dbaccess/source/ui/inc/callbacks.hxx
+++ b/dbaccess/source/ui/inc/callbacks.hxx
@@ -31,6 +31,11 @@ struct ExecuteDropEvent;
namespace comphelper { class OInterfaceContainerHelper2; }
namespace weld
{
class TreeIter;
}
namespace dbaui
{
@@ -43,11 +48,13 @@ namespace dbaui
@return <FALSE/> if the default quick help text should be used
*/
virtual bool requestQuickHelp( const SvTreeListEntry* _pEntry, OUString& _rText ) const = 0;
virtual bool requestQuickHelp(const void* pUserData, OUString& rText) const = 0;
/** handler for StartDrag requests
@return <TRUE/> if a drag operation was started
*/
virtual bool requestDrag( const Point& _rPosPixel ) = 0;
virtual bool requestDrag(const Point& _rPosPixel) = 0;
virtual bool requestDrag(const weld::TreeIter& rEntry) = 0;
/** check whether or not a drop request should be accepted
*/
@@ -69,7 +76,7 @@ namespace dbaui
Supposed to be a valid name from uiconfig/<module>/popupmenu folder.
*/
virtual OUString getContextMenuResourceName( Control& _rControl ) const = 0;
virtual OUString getContextMenuResourceName() const = 0;
/** returns the controller which is responsible for providing states of certain features,
and executing them.
diff --git a/dbaccess/source/ui/inc/dbtreelistbox.hxx b/dbaccess/source/ui/inc/dbtreelistbox.hxx
index f79abe8..70b891f 100644
--- a/dbaccess/source/ui/inc/dbtreelistbox.hxx
+++ b/dbaccess/source/ui/inc/dbtreelistbox.hxx
@@ -23,8 +23,10 @@
#include <com/sun/star/frame/XPopupMenuController.hpp>
#include <vcl/InterimItemWindow.hxx>
#include <vcl/treelistbox.hxx>
#include <vcl/timer.hxx>
#include <vcl/weld.hxx>
#include <memory>
#include <set>
@@ -133,6 +135,88 @@ namespace dbaui
protected:
using SvTreeListBox::ExecuteDrop;
};
class TreeListBox;
class TreeListBoxDropTarget : public DropTargetHelper
{
private:
TreeListBox& m_rTreeView;
virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
public:
TreeListBoxDropTarget(TreeListBox& rTreeView);
};
class TreeListBox
{
protected:
std::unique_ptr<weld::TreeView> m_xTreeView;
TreeListBoxDropTarget m_aDropTargetHelper;
std::unique_ptr<weld::TreeIter> m_xDragedEntry;
IControlActionListener* m_pActionListener;
IContextMenuProvider* m_pContextMenuProvider;
DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
DECL_LINK(SelectHdl, weld::TreeView&, void);
DECL_LINK(QueryTooltipHdl, const weld::TreeIter&, OUString);
DECL_LINK(CommandHdl, const CommandEvent&, bool);
DECL_LINK(DragBeginHdl, bool&, bool);
private:
Timer m_aTimer; // is needed for table updates
Link<LinkParamNone*,void> m_aSelChangeHdl; // handler to be called (asynchronously) when the selection changes in any way
Link<LinkParamNone*,void> m_aCopyHandler; // called when someone press CTRL+C
Link<LinkParamNone*,void> m_aPasteHandler; // called when someone press CTRL+V
Link<LinkParamNone*,void> m_aDeleteHandler; // called when someone press DELETE Key
DECL_LINK(OnTimeOut, Timer*, void);
protected:
void implStopSelectionTimer();
void implStartSelectionTimer();
virtual bool DoChildKeyInput(const KeyEvent& rKEvt);
virtual bool DoContextMenu(const CommandEvent& rCEvt);
public:
TreeListBox(std::unique_ptr<weld::TreeView> xTreeView);
virtual ~TreeListBox();
std::unique_ptr<weld::TreeIter> GetEntryPosByName(const OUString& rName,
const weld::TreeIter* pStart = nullptr,
const IEntryFilter* pFilter = nullptr) const;
void setControlActionListener(IControlActionListener* pListener) { m_pActionListener = pListener; }
void setContextMenuProvider(IContextMenuProvider* pContextMenuProvider) { m_pContextMenuProvider = pContextMenuProvider; }
weld::TreeView& GetWidget() { return *m_xTreeView; }
const weld::TreeView& GetWidget() const { return *m_xTreeView; }
sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt);
sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt);
void SetSelChangeHdl( const Link<LinkParamNone*,void>& _rHdl ) { m_aSelChangeHdl = _rHdl; }
void setCopyHandler(const Link<LinkParamNone*,void>& _rHdl) { m_aCopyHandler = _rHdl; }
void setPasteHandler(const Link<LinkParamNone*,void>& _rHdl) { m_aPasteHandler = _rHdl; }
void setDeleteHandler(const Link<LinkParamNone*,void>& _rHdl) { m_aDeleteHandler = _rHdl; }
};
class InterimDBTreeListBox : public InterimItemWindow
, public TreeListBox
{
public:
InterimDBTreeListBox(vcl::Window* pParent);
virtual void dispose() override;
virtual ~InterimDBTreeListBox() override;
protected:
virtual bool DoChildKeyInput(const KeyEvent& rKEvt) override;
virtual bool DoContextMenu(const CommandEvent& rCEvt) override;
};
}
#endif // INCLUDED_DBACCESS_SOURCE_UI_INC_DBTREELISTBOX_HXX
diff --git a/dbaccess/source/ui/inc/tabletree.hxx b/dbaccess/source/ui/inc/tabletree.hxx
index 97b1ba7..53e4259 100644
--- a/dbaccess/source/ui/inc/tabletree.hxx
+++ b/dbaccess/source/ui/inc/tabletree.hxx
@@ -26,43 +26,36 @@
#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdb/application/NamedDatabaseObject.hpp>
#include <vcl/weld.hxx>
#include <memory>
namespace dbaui
{
// OTableTreeListBox
class OTableTreeListBox final : public DBTreeListBox
class OTableTreeListBox final : public InterimDBTreeListBox
{
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?
bool m_bShowToggles; // show toggle buttons
public:
OTableTreeListBox(vcl::Window* pParent, WinBits nWinStyle);
virtual void dispose() override;
OTableTreeListBox(vcl::Window* pParent, bool bShowToggles);
virtual ~OTableTreeListBox();
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();
void SuppressEmptyFolders() { m_bNoEmptyFolders = true; }
/** determines whether the given entry denotes a tables folder
*/
static bool isFolderEntry( const SvTreeListEntry* _pEntry );
bool isFolderEntry(const weld::TreeIter& rEntry) const;
/** fill the table list with the tables belonging to the connection described by the parameters
@param _rxConnection
@@ -87,28 +80,21 @@ public:
const css::uno::Sequence< OUString>& _rViews
);
/** returns a NamedDatabaseObject record which describes the given entry
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>
*/
css::sdb::application::NamedDatabaseObject
describeObject( SvTreeListEntry* _pEntry );
void checkWildcard(weld::TreeIter& rEntry);
/** to be used if a foreign instance added a table
/** determine if the given entry is 'wildcard checked'
@see checkWildcard
*/
SvTreeListEntry* addedTable( const OUString& _rName );
bool isWildcardChecked(const weld::TreeIter& rEntry);
/** 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 );
SvTreeListEntry* getAllObjectsEntry() const;
void CheckButtons(); // make the button states consistent (bottom-up)
/** 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
@@ -123,32 +109,29 @@ public:
static bool isWildcardChecked(SvTreeListEntry* pEntry);
private:
virtual void InitEntry(SvTreeListEntry* _pEntry, const OUString& _rString, const Image& _rCollapsedBitmap, const Image& _rExpandedBitmap) override;
void CheckButtonHdl();
virtual void CheckButtonHdl() override;
void checkedButton_noBroadcast(SvTreeListEntry* _pEntry);
void checkedButton_noBroadcast(const weld::TreeIter& rEntry);
void implEmphasize(SvTreeListEntry* _pEntry, bool _bChecked, bool _bUpdateDescendants = true, bool _bUpdateAncestors = true);
void implEmphasize(const 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.
*/
SvTreeListEntry* implAddEntry(
std::unique_ptr<weld::TreeIter> implAddEntry(
const css::uno::Reference< css::sdbc::XDatabaseMetaData >& _rxMeta,
const OUString& _rTableName,
bool _bCheckName = true
const OUString& _rTableName, bool _bCheckName = true
);
void implSetDefaultImages();
void implOnNewConnection( const css::uno::Reference< css::sdbc::XConnection >& _rxConnection );
bool impl_getAndAssertMetaData( css::uno::Reference< css::sdbc::XDatabaseMetaData >& _out_rMetaData ) const;
bool haveVirtualRoot() const { return m_bVirtualRoot; }
public:
/** 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.
@@ -159,21 +142,32 @@ private:
const TNames& _rTables
);
void InitButtonData();
/** returns a NamedDatabaseObject record which describes the given entry
*/
css::sdb::application::NamedDatabaseObject
describeObject(weld::TreeIter& rEntry);
/// 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; }
/** to be used if a foreign instance added a table
*/
std::unique_ptr<weld::TreeIter> addedTable(const OUString& rName);
SvButtonState implDetermineState(SvTreeListEntry* _pEntry);
/** to be used if a foreign instance removed a table
*/
void removedTable( const OUString& _rName );
TriState implDetermineState(weld::TreeIter& rEntry);
// determines the check state of the given entry, by analyzing the states of all descendants
void CheckButtons(); // make the button states consistent (bottom-up)
/** 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(weld::TreeIter& rEntry) const;
virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& _rRect) override;
virtual void KeyInput( const KeyEvent& rKEvt ) override;
std::unique_ptr<weld::TreeIter> getEntryByQualifiedName(const OUString& rName);
};
class TableTreeListBox
class TableTreeListBox : public TreeListBox
{
css::uno::Reference< css::sdbc::XConnection >
m_xConnection; // the connection we're working for, set in implOnNewConnection, called by UpdateTableList
@@ -182,12 +176,9 @@ class TableTreeListBox
bool m_bVirtualRoot; // should the first entry be visible
bool m_bNoEmptyFolders; // should empty catalogs/schematas be prevented from being displayed?
bool m_bShowToggles; // show toggle buttons
std::unique_ptr<weld::TreeView> m_xTreeView;
public:
TableTreeListBox(std::unique_ptr<weld::TreeView> xTreeView);
weld::TreeView& GetWidget() { return *m_xTreeView; }
TableTreeListBox(std::unique_ptr<weld::TreeView> xTreeView, bool bShowToggles);
void init() { m_bVirtualRoot = true; }
@@ -195,7 +186,6 @@ public:
typedef std::vector< TTableViewName > TNames;
void SuppressEmptyFolders() { m_bNoEmptyFolders = true; }
void DisableCheckButtons();
/** determines whether the given entry denotes a tables folder
*/
@@ -231,7 +221,7 @@ public:
/** to be used if a foreign instance added a table
*/
SvTreeListEntry* addedTable( const OUString& _rName );
std::unique_ptr<weld::TreeIter> addedTable( const OUString& _rName );
/** to be used if a foreign instance removed a table
*/
@@ -259,8 +249,6 @@ public:
*/
bool isWildcardChecked(const weld::TreeIter& rEntry);
std::unique_ptr<weld::TreeIter> GetEntryPosByName(const OUString& aName, const weld::TreeIter* pStart = nullptr, const IEntryFilter* _pFilter = nullptr) const;
void CheckButtons(); // make the button states consistent (bottom-up)
void checkedButton_noBroadcast(const weld::TreeIter& rEntry);
@@ -284,6 +272,7 @@ private:
bool haveVirtualRoot() const { return m_bVirtualRoot; }
public:
/** 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.
@@ -293,6 +282,17 @@ private:
const css::uno::Reference< css::sdbc::XConnection >& _rxConnection,
const TNames& _rTables
);
/** returns a NamedDatabaseObject record which describes the given entry
*/
css::sdb::application::NamedDatabaseObject
describeObject(weld::TreeIter& rEntry);
/** 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(weld::TreeIter& rEntry) const;
};
} // namespace dbaui
diff --git a/dbaccess/source/ui/inc/unodatbr.hxx b/dbaccess/source/ui/inc/unodatbr.hxx
index 498b634..810586a 100644
--- a/dbaccess/source/ui/inc/unodatbr.hxx
+++ b/dbaccess/source/ui/inc/unodatbr.hxx
@@ -214,12 +214,14 @@ namespace dbaui
// IControlActionListener overridables
virtual bool requestQuickHelp( const SvTreeListEntry* _pEntry, OUString& _rText ) const override;
virtual bool requestQuickHelp(const void* pUserData, OUString& rText) const override;
virtual bool requestDrag( const Point& _rPosPixel ) override;
virtual bool requestDrag(const weld::TreeIter& rEntry) override;
virtual sal_Int8 queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors ) override;
virtual sal_Int8 executeDrop( const ExecuteDropEvent& _rEvt ) override;
// IContextMenuProvider
virtual OUString getContextMenuResourceName( Control& _rControl ) const override;
virtual OUString getContextMenuResourceName() const override;
virtual IController& getCommandController() override;
virtual ::comphelper::OInterfaceContainerHelper2*
getContextMenuInterceptors() override;
diff --git a/dbaccess/source/ui/querydesign/QTableWindow.cxx b/dbaccess/source/ui/querydesign/QTableWindow.cxx
index 754c6e1..cc70e12 100644
--- a/dbaccess/source/ui/querydesign/QTableWindow.cxx
+++ b/dbaccess/source/ui/querydesign/QTableWindow.cxx
@@ -30,7 +30,6 @@
#include <com/sun/star/sdbc/SQLException.hpp>
#include "TableFieldInfo.hxx"
#include <comphelper/stl_types.hxx>
#include <vcl/treelistentry.hxx>
#include <comphelper/types.hxx>
using namespace ::com::sun::star::sdbc;
diff --git a/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx b/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
index 2b23a3e..1e00cc9b 100644
--- a/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
+++ b/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
@@ -42,7 +42,6 @@
#include <o3tl/safeint.hxx>
#include <osl/diagnose.h>
#include <i18nlangtag/languagetag.hxx>
#include <vcl/treelistentry.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/svapp.hxx>
diff --git a/dbaccess/source/ui/querydesign/TableWindow.cxx b/dbaccess/source/ui/querydesign/TableWindow.cxx
index f7ec40c..02f45af 100644
--- a/dbaccess/source/ui/querydesign/TableWindow.cxx
+++ b/dbaccess/source/ui/querydesign/TableWindow.cxx
@@ -39,8 +39,8 @@
#include <bitmaps.hlst>
#include <TableWindowAccess.hxx>
#include <connectivity/dbtools.hxx>
#include <vcl/treelistentry.hxx>
#include <vcl/builder.hxx>
#include <vcl/menu.hxx>
using namespace dbaui;
using namespace ::utl;
diff --git a/dbaccess/uiconfig/ui/dbtreelist.ui b/dbaccess/uiconfig/ui/dbtreelist.ui
new file mode 100644
index 0000000..042e770
--- /dev/null
+++ b/dbaccess/uiconfig/ui/dbtreelist.ui
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.36.0 -->
<interface domain="dba">
<requires lib="gtk+" version="3.18"/>
<object class="GtkTreeStore" id="liststore1">
<columns>
<!-- column-name expander -->
<column type="GdkPixbuf"/>
<!-- column-name check1 -->
<column type="gboolean"/>
<!-- 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="GtkBox" id="DBTreeList">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="border_width">0</property>
<property name="spacing">6</property>
<property name="homogeneous">True</property>
<child>
<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>
<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">liststore1</property>
<property name="headers_visible">False</property>
<property name="reorderable">True</property>
<property name="search_column">2</property>
<property name="enable_tree_lines">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="GtkCellRendererPixbuf" id="cellrenderertext5"/>
<attributes>
<attribute name="pixbuf">0</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererToggle" id="cellrenderer5"/>
<attributes>
<attribute name="visible">4</attribute>
<attribute name="active">1</attribute>
<attribute name="inconsistent">5</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn9">
<property name="spacing">6</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext6"/>
<attributes>
<attribute name="text">2</attribute>
<attribute name="weight">6</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</interface>