include/svx/dbaexchange.hxx | 12 - include/vcl/transfer.hxx | 2 include/vcl/treelistbox.hxx | 6 include/vcl/weld.hxx | 10 + svx/UIConfig_svx.mk | 1 svx/source/fmcomp/dbaexchange.cxx | 29 ++-- svx/source/form/tabwin.cxx | 220 ++++++++++-------------------------- svx/source/inc/tabwin.hxx | 63 ++-------- svx/uiconfig/ui/formfielddialog.ui | 99 ++++++++++++++++ vcl/inc/treeglue.hxx | 7 - vcl/inc/unx/gtk/gtkinst.hxx | 7 + vcl/source/app/salvtables.cxx | 14 +- vcl/source/treelist/treelistbox.cxx | 27 +++- vcl/unx/gtk3/gtk3gtkframe.cxx | 34 ++++- vcl/unx/gtk3/gtk3gtkinst.cxx | 98 +++++++++++++++- 15 files changed, 381 insertions(+), 248 deletions(-)
New commits: commit 19d17a739cc61341ca74cfa485e919c6012fe28c Author: Caolán McNamara <[email protected]> AuthorDate: Fri Nov 29 10:21:11 2019 +0000 Commit: Caolán McNamara <[email protected]> CommitDate: Sun Dec 1 20:51:12 2019 +0100 weld FmFieldWin needs drag source support fixes a leak of ColumnInfo data as well Change-Id: I671834726aed3fd4de096b56baaa592f51a9e73e Reviewed-on: https://gerrit.libreoffice.org/84147 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Caolán McNamara <[email protected]> diff --git a/include/svx/dbaexchange.hxx b/include/svx/dbaexchange.hxx index d831dc4e2ed0..bccdf5bacf00 100644 --- a/include/svx/dbaexchange.hxx +++ b/include/svx/dbaexchange.hxx @@ -51,15 +51,17 @@ namespace svx //= OColumnTransferable - class SAL_WARN_UNUSED SVX_DLLPUBLIC OColumnTransferable final : public TransferableHelper + class SAL_WARN_UNUSED SVX_DLLPUBLIC OColumnTransferable final : public TransferDataContainer { public: + OColumnTransferable(ColumnTransferFormatFlags nFormats); + /** construct the transferable from a data access descriptor Note that some of the aspects, in particular all which cannot be represented as string, can only be transported via the CTF_COLUMN_DESCRIPTOR format. - @param _rDescriptor + @param rDescriptor The descriptor for the column. It must contain at least <ul><li>information sufficient to create a connection, that is, either one of DataSource, DatabaseLocation, ConnectionResource, and DataAccessDescriptorProperty::Connection</li> @@ -68,10 +70,8 @@ namespace svx <li>a ColumnName or ColumnObject</li> </ul> */ - OColumnTransferable( - const ODataAccessDescriptor& _rDescriptor, - ColumnTransferFormatFlags _nFormats - ); + void setDescriptor(const ODataAccessDescriptor& rDescriptor); + /** construct the transferable from a DatabaseForm component and a field name diff --git a/include/vcl/transfer.hxx b/include/vcl/transfer.hxx index 75af922a007c..a0b773984d3b 100644 --- a/include/vcl/transfer.hxx +++ b/include/vcl/transfer.hxx @@ -483,7 +483,7 @@ public: struct TransferDataContainer_Impl; -class VCL_DLLPUBLIC TransferDataContainer final : public TransferableHelper +class VCL_DLLPUBLIC TransferDataContainer : public TransferableHelper { std::unique_ptr<TransferDataContainer_Impl> pImpl; diff --git a/include/vcl/treelistbox.hxx b/include/vcl/treelistbox.hxx index ecb1ce8029af..cb4945a96717 100644 --- a/include/vcl/treelistbox.hxx +++ b/include/vcl/treelistbox.hxx @@ -225,9 +225,13 @@ class VCL_DLLPUBLIC SvTreeListBox SelectionMode eSelMode; sal_Int32 nMinWidthInChars; + sal_Int8 mnDragAction; + SvTreeListEntry* pEdEntry; SvLBoxItem* pEdItem; + rtl::Reference<TransferDataContainer> m_xTransferHelper; + protected: std::unique_ptr<SvImpLBox> pImpl; short nColumns; @@ -726,6 +730,8 @@ public: void SetForceMakeVisible(bool bEnable); virtual FactoryFunction GetUITestFactory() const override; + + void SetDragHelper(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants); }; class SvInplaceEdit2 diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index abe71e42fedb..e7025b134506 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -63,6 +63,7 @@ enum class PointerStyle; class SvNumberFormatter; class KeyEvent; class MouseEvent; +class TransferDataContainer; class OutputDevice; class VirtualDevice; struct SystemEnvData; @@ -686,7 +687,10 @@ protected: Link<const TreeIter&, bool> m_aExpandingHdl; Link<TreeView&, void> m_aVisibleRangeChangedHdl; Link<TreeView&, void> m_aModelChangedHdl; + // if handler returns true, then menu has been show and event is consumed Link<const CommandEvent&, bool> m_aPopupMenuHdl; + // if handler returns true, drag is disallowed + Link<TreeView&, bool> m_aDragBeginHdl; std::function<int(const weld::TreeIter&, const weld::TreeIter&)> m_aCustomSort; std::vector<int> m_aRadioIndexes; @@ -937,6 +941,12 @@ public: m_aPopupMenuHdl = rLink; } + virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rTransferrable, + sal_uInt8 eDNDConstants) + = 0; + + void connect_drag_begin(const Link<TreeView&, bool>& rLink) { m_aDragBeginHdl = rLink; } + //all of them void select_all() { unselect(-1); } void unselect_all() { select(-1); } diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk index 9f6a55c266e3..f4a7e0abddb4 100644 --- a/svx/UIConfig_svx.mk +++ b/svx/UIConfig_svx.mk @@ -49,6 +49,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\ svx/uiconfig/ui/fontworkgallerydialog \ svx/uiconfig/ui/fontworkspacingdialog \ svx/uiconfig/ui/formdatamenu \ + svx/uiconfig/ui/formfielddialog \ svx/uiconfig/ui/formlinkwarndialog \ svx/uiconfig/ui/formnavimenu \ svx/uiconfig/ui/functionmenu \ diff --git a/svx/source/fmcomp/dbaexchange.cxx b/svx/source/fmcomp/dbaexchange.cxx index 0e6df6cfb871..698a7e6e6055 100644 --- a/svx/source/fmcomp/dbaexchange.cxx +++ b/svx/source/fmcomp/dbaexchange.cxx @@ -42,18 +42,22 @@ namespace svx using namespace ::com::sun::star::container; using namespace ::com::sun::star::datatransfer; - OColumnTransferable::OColumnTransferable(const ODataAccessDescriptor& _rDescriptor, ColumnTransferFormatFlags _nFormats ) - :m_nFormatFlags(_nFormats) + OColumnTransferable::OColumnTransferable(ColumnTransferFormatFlags nFormats) + : m_nFormatFlags(nFormats) + { + } + + void OColumnTransferable::setDescriptor(const ODataAccessDescriptor& rDescriptor) { OUString sDataSource, sDatabaseLocation, sConnectionResource, sCommand, sFieldName; - if ( _rDescriptor.has( DataAccessDescriptorProperty::DataSource ) ) _rDescriptor[ DataAccessDescriptorProperty::DataSource ] >>= sDataSource; - if ( _rDescriptor.has( DataAccessDescriptorProperty::DatabaseLocation ) ) _rDescriptor[ DataAccessDescriptorProperty::DatabaseLocation ] >>= sDatabaseLocation; - if ( _rDescriptor.has( DataAccessDescriptorProperty::ConnectionResource ) ) _rDescriptor[ DataAccessDescriptorProperty::ConnectionResource ] >>= sConnectionResource; - if ( _rDescriptor.has( DataAccessDescriptorProperty::Command ) ) _rDescriptor[ DataAccessDescriptorProperty::Command ] >>= sCommand; - if ( _rDescriptor.has( DataAccessDescriptorProperty::ColumnName ) ) _rDescriptor[ DataAccessDescriptorProperty::ColumnName ] >>= sFieldName; + if ( rDescriptor.has( DataAccessDescriptorProperty::DataSource ) ) rDescriptor[ DataAccessDescriptorProperty::DataSource ] >>= sDataSource; + if ( rDescriptor.has( DataAccessDescriptorProperty::DatabaseLocation ) ) rDescriptor[ DataAccessDescriptorProperty::DatabaseLocation ] >>= sDatabaseLocation; + if ( rDescriptor.has( DataAccessDescriptorProperty::ConnectionResource ) ) rDescriptor[ DataAccessDescriptorProperty::ConnectionResource ] >>= sConnectionResource; + if ( rDescriptor.has( DataAccessDescriptorProperty::Command ) ) rDescriptor[ DataAccessDescriptorProperty::Command ] >>= sCommand; + if ( rDescriptor.has( DataAccessDescriptorProperty::ColumnName ) ) rDescriptor[ DataAccessDescriptorProperty::ColumnName ] >>= sFieldName; sal_Int32 nCommandType = CommandType::TABLE; - OSL_VERIFY( _rDescriptor[ DataAccessDescriptorProperty::CommandType ] >>= nCommandType ); + OSL_VERIFY( rDescriptor[ DataAccessDescriptorProperty::CommandType ] >>= nCommandType ); implConstruct( @@ -62,14 +66,13 @@ namespace svx if ( m_nFormatFlags & ColumnTransferFormatFlags::COLUMN_DESCRIPTOR ) { - if ( _rDescriptor.has( DataAccessDescriptorProperty::Connection ) ) - m_aDescriptor[ DataAccessDescriptorProperty::Connection ] = _rDescriptor[ DataAccessDescriptorProperty::Connection ]; - if ( _rDescriptor.has( DataAccessDescriptorProperty::ColumnObject ) ) - m_aDescriptor[ DataAccessDescriptorProperty::ColumnObject ] = _rDescriptor[ DataAccessDescriptorProperty::ColumnObject ]; + if ( rDescriptor.has( DataAccessDescriptorProperty::Connection ) ) + m_aDescriptor[ DataAccessDescriptorProperty::Connection ] = rDescriptor[ DataAccessDescriptorProperty::Connection ]; + if ( rDescriptor.has( DataAccessDescriptorProperty::ColumnObject ) ) + m_aDescriptor[ DataAccessDescriptorProperty::ColumnObject ] = rDescriptor[ DataAccessDescriptorProperty::ColumnObject ]; } } - OColumnTransferable::OColumnTransferable(const Reference< XPropertySet >& _rxForm, const OUString& _rFieldName, const Reference< XPropertySet >& _rxColumn, const Reference< XConnection >& _rxConnection, ColumnTransferFormatFlags _nFormats) diff --git a/svx/source/form/tabwin.cxx b/svx/source/form/tabwin.cxx index 8e91d42804d4..09ab384fdcdc 100644 --- a/svx/source/form/tabwin.cxx +++ b/svx/source/form/tabwin.cxx @@ -24,7 +24,6 @@ #include <svx/strings.hrc> #include <svx/svxids.hrc> -#include <svx/dbaexchange.hxx> #include <com/sun/star/sdb/CommandType.hpp> #include <com/sun/star/sdbcx/XTablesSupplier.hpp> #include <com/sun/star/sdb/XQueriesSupplier.hpp> @@ -59,8 +58,6 @@ const long STD_WIN_SIZE_X = 120; const long STD_WIN_SIZE_Y = 150; -const long LISTBOX_BORDER = 2; - using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::uno; @@ -74,8 +71,6 @@ using namespace ::svxform; using namespace ::svx; using namespace ::dbtools; -namespace { - struct ColumnInfo { OUString const sColumnName; @@ -85,9 +80,7 @@ struct ColumnInfo } }; -} - -static void lcl_addToList( SvTreeListBox& _rListBox, const uno::Reference< container::XNameAccess>& i_xColumns ) +void FmFieldWin::addToList(const uno::Reference< container::XNameAccess>& i_xColumns ) { const uno::Sequence< OUString > aEntries = i_xColumns->getElementNames(); for ( const OUString& rEntry : aEntries ) @@ -96,124 +89,77 @@ static void lcl_addToList( SvTreeListBox& _rListBox, const uno::Reference< conta OUString sLabel; if ( xColumn->getPropertySetInfo()->hasPropertyByName(FM_PROP_LABEL) ) xColumn->getPropertyValue(FM_PROP_LABEL) >>= sLabel; + m_aListBoxData.emplace_back(new ColumnInfo(rEntry)); + OUString sId(OUString::number(reinterpret_cast<sal_Int64>(m_aListBoxData.back().get()))); if ( !sLabel.isEmpty() ) - _rListBox.InsertEntry( sLabel, nullptr, false, TREELIST_APPEND, new ColumnInfo(rEntry) ); + m_xListBox->append(sId, sLabel); else - _rListBox.InsertEntry( rEntry, nullptr, false, TREELIST_APPEND, new ColumnInfo(rEntry) ); + m_xListBox->append(sId, rEntry); } } -FmFieldWinListBox::FmFieldWinListBox( FmFieldWin* pParent ) - :SvTreeListBox( pParent, WB_HASBUTTONS|WB_BORDER ) - ,pTabWin( pParent ) -{ - SetHelpId( HID_FIELD_SEL ); - - SetHighlightRange( ); -} - -FmFieldWinListBox::~FmFieldWinListBox() -{ - disposeOnce(); -} - -void FmFieldWinListBox::dispose() -{ - pTabWin.clear(); - SvTreeListBox::dispose(); -} - - -sal_Int8 FmFieldWinListBox::AcceptDrop( const AcceptDropEvent& /*rEvt*/ ) -{ - return DND_ACTION_NONE; -} - - -sal_Int8 FmFieldWinListBox::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ ) +IMPL_LINK_NOARG(FmFieldWin, DragBeginHdl, weld::TreeView&, bool) { - return DND_ACTION_NONE; -} - - -bool FmFieldWinListBox::DoubleClickHdl() -{ - if ( pTabWin->createSelectionControls() ) - return true; - - return SvTreeListBox::DoubleClickHdl(); -} - - -void FmFieldWinListBox::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ ) -{ - SvTreeListEntry* pSelected = FirstSelected(); + ColumnInfo* pSelected = reinterpret_cast<ColumnInfo*>(m_xListBox->get_selected_id().toInt64()); if (!pSelected) + { // no drag without a field - return; + return true; + } svx::ODataAccessDescriptor aDescriptor; - aDescriptor[ DataAccessDescriptorProperty::DataSource ] <<= pTabWin->GetDatabaseName(); - aDescriptor[ DataAccessDescriptorProperty::Connection ] <<= pTabWin->GetConnection().getTyped(); - aDescriptor[ DataAccessDescriptorProperty::Command ] <<= pTabWin->GetObjectName(); - aDescriptor[ DataAccessDescriptorProperty::CommandType ]<<= pTabWin->GetObjectType(); - ColumnInfo* pInfo = static_cast<ColumnInfo*>(pSelected->GetUserData()); - aDescriptor[ DataAccessDescriptorProperty::ColumnName ] <<= pInfo->sColumnName; - - rtl::Reference<OColumnTransferable> pTransferColumn = new OColumnTransferable( - aDescriptor, ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR - ); - EndSelection(); - pTransferColumn->StartDrag( this, DND_ACTION_COPY ); + aDescriptor[ DataAccessDescriptorProperty::DataSource ] <<= GetDatabaseName(); + aDescriptor[ DataAccessDescriptorProperty::Connection ] <<= GetConnection().getTyped(); + aDescriptor[ DataAccessDescriptorProperty::Command ] <<= GetObjectName(); + aDescriptor[ DataAccessDescriptorProperty::CommandType ]<<= GetObjectType(); + aDescriptor[ DataAccessDescriptorProperty::ColumnName ] <<= pSelected->sColumnName; + + m_xHelper->setDescriptor(aDescriptor); + + return false; } -FmFieldWin::FmFieldWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr, vcl::Window* _pParent) - :SfxFloatingWindow(_pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE)) - ,SfxControllerItem(SID_FM_FIELDS_CONTROL, *_pBindings) - ,::comphelper::OPropertyChangeListener(m_aMutex) - ,m_nObjectType(0) +FmFieldWin::FmFieldWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr, weld::Window* _pParent) + : SfxModelessDialogController(_pBindings, _pMgr, _pParent, "svx/ui/formfielddialog.ui", "FormFieldDialog") + , SfxControllerItem(SID_FM_FIELDS_CONTROL, *_pBindings) + , comphelper::OPropertyChangeListener(m_aMutex) + , m_xListBox(m_xBuilder->weld_tree_view("treeview")) + , m_nObjectType(0) { - SetHelpId( HID_FIELD_SEL_WIN ); + m_xDialog->set_help_id(HID_FIELD_SEL_WIN); + m_xListBox->set_help_id(HID_FIELD_SEL); + + m_xListBox->connect_row_activated(LINK(this, FmFieldWin, RowActivatedHdl)); + m_xHelper.set(new OColumnTransferable( + ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR + )); + rtl::Reference<TransferDataContainer> xHelper(m_xHelper.get()); + m_xListBox->enable_drag_source(xHelper, DND_ACTION_COPY); + m_xListBox->connect_drag_begin(LINK(this, FmFieldWin, DragBeginHdl)); - SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor()) ); - pListBox = VclPtr<FmFieldWinListBox>::Create( this ); - pListBox->Show(); UpdateContent(nullptr); - SetSizePixel(Size(STD_WIN_SIZE_X,STD_WIN_SIZE_Y)); + m_xDialog->set_size_request(STD_WIN_SIZE_X, STD_WIN_SIZE_Y); } - FmFieldWin::~FmFieldWin() { - disposeOnce(); -} - -void FmFieldWin::dispose() -{ - if (m_pChangeListener.is()) + if (m_xChangeListener.is()) { - m_pChangeListener->dispose(); - m_pChangeListener.clear(); + m_xChangeListener->dispose(); + m_xChangeListener.clear(); } - pListBox.disposeAndClear(); ::SfxControllerItem::dispose(); - SfxFloatingWindow::dispose(); } - -void FmFieldWin::GetFocus() +IMPL_LINK_NOARG(FmFieldWin, RowActivatedHdl, weld::TreeView&, bool) { - if ( pListBox ) - pListBox->GrabFocus(); - else - SfxFloatingWindow::GetFocus(); + return createSelectionControls(); } - -bool FmFieldWin::createSelectionControls( ) +bool FmFieldWin::createSelectionControls() { - SvTreeListEntry* pSelected = pListBox->FirstSelected(); - if ( pSelected ) + ColumnInfo* pSelected = reinterpret_cast<ColumnInfo*>(m_xListBox->get_selected_id().toInt64()); + if (pSelected) { // build a descriptor for the currently selected field ODataAccessDescriptor aDescr; @@ -223,8 +169,7 @@ bool FmFieldWin::createSelectionControls( ) aDescr[ DataAccessDescriptorProperty::Command ] <<= GetObjectName(); aDescr[ DataAccessDescriptorProperty::CommandType ] <<= GetObjectType(); - ColumnInfo* pInfo = static_cast<ColumnInfo*>(pSelected->GetUserData()); - aDescr[ DataAccessDescriptorProperty::ColumnName ] <<= pInfo->sColumnName;//OUString( pListBox->GetEntryText( pSelected) ); + aDescr[ DataAccessDescriptorProperty::ColumnName ] <<= pSelected->sColumnName; // transfer this to the SFX world SfxUnoAnyItem aDescriptorItem( SID_FM_DATACCESS_DESCRIPTOR, makeAny( aDescr.createPropertyValueSequence() ) ); @@ -240,30 +185,12 @@ bool FmFieldWin::createSelectionControls( ) return nullptr != pSelected; } - -bool FmFieldWin::PreNotify( NotifyEvent& _rNEvt ) -{ - if ( MouseNotifyEvent::KEYINPUT == _rNEvt.GetType() ) - { - const vcl::KeyCode& rKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode(); - if ( ( 0 == rKeyCode.GetModifier() ) && ( KEY_RETURN == rKeyCode.GetCode() ) ) - { - if ( createSelectionControls() ) - return true; - } - } - - return SfxFloatingWindow::PreNotify( _rNEvt ); -} - - void FmFieldWin::_propertyChanged(const css::beans::PropertyChangeEvent& evt) { css::uno::Reference< css::form::XForm > xForm(evt.Source, css::uno::UNO_QUERY); UpdateContent(xForm); } - void FmFieldWin::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) { if (!pState || SID_FM_FIELDS_CONTROL != nSID) @@ -278,12 +205,12 @@ void FmFieldWin::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoo UpdateContent(nullptr); } - void FmFieldWin::UpdateContent(FmFormShell const * pShell) { - pListBox->Clear(); + m_xListBox->clear(); + m_aListBoxData.clear(); OUString aTitle(SvxResId(RID_STR_FIELDSELECTION)); - SetText( aTitle ); + m_xDialog->set_title(aTitle); if (!pShell || !pShell->GetImpl()) return; @@ -293,15 +220,15 @@ void FmFieldWin::UpdateContent(FmFormShell const * pShell) UpdateContent( xForm ); } - void FmFieldWin::UpdateContent(const css::uno::Reference< css::form::XForm > & xForm) { try { // delete ListBox - pListBox->Clear(); + m_xListBox->clear(); + m_aListBoxData.clear(); OUString aTitle(SvxResId(RID_STR_FIELDSELECTION)); - SetText(aTitle); + m_xDialog->set_title(aTitle); if (!xForm.is()) return; @@ -328,7 +255,7 @@ void FmFieldWin::UpdateContent(const css::uno::Reference< css::form::XForm > & x Reference< XComponent > xKeepFieldsAlive; Reference< XNameAccess > xColumns = getFieldsByCommandDescriptor( m_aConnection, m_nObjectType, m_aObjectName,xKeepFieldsAlive ); if ( xColumns.is() ) - lcl_addToList(*pListBox,xColumns); + addToList(xColumns); } // set prefix @@ -348,19 +275,19 @@ void FmFieldWin::UpdateContent(const css::uno::Reference< css::form::XForm > & x } // listen for changes at ControlSource in PropertySet - if (m_pChangeListener.is()) + if (m_xChangeListener.is()) { - m_pChangeListener->dispose(); - m_pChangeListener.clear(); + m_xChangeListener->dispose(); + m_xChangeListener.clear(); } - m_pChangeListener = new ::comphelper::OPropertyChangeMultiplexer(this, xSet); - m_pChangeListener->addProperty(FM_PROP_DATASOURCE); - m_pChangeListener->addProperty(FM_PROP_COMMAND); - m_pChangeListener->addProperty(FM_PROP_COMMANDTYPE); + m_xChangeListener = new ::comphelper::OPropertyChangeMultiplexer(this, xSet); + m_xChangeListener->addProperty(FM_PROP_DATASOURCE); + m_xChangeListener->addProperty(FM_PROP_COMMAND); + m_xChangeListener->addProperty(FM_PROP_COMMANDTYPE); // set title aTitle += " " + aPrefix + " " + m_aObjectName; - SetText( aTitle ); + m_xDialog->set_title(aTitle); } catch( const Exception& ) { @@ -368,41 +295,20 @@ void FmFieldWin::UpdateContent(const css::uno::Reference< css::form::XForm > & x } } - -void FmFieldWin::Resize() -{ - SfxFloatingWindow::Resize(); - - Size aOutputSize( GetOutputSizePixel() ); - - - // adapt size of css::form::ListBox - Point aLBPos( LISTBOX_BORDER, LISTBOX_BORDER ); - Size aLBSize( aOutputSize ); - aLBSize.AdjustWidth( -(2*LISTBOX_BORDER) ); - aLBSize.AdjustHeight( -(2*LISTBOX_BORDER) ); - - pListBox->SetPosSizePixel( aLBPos, aLBSize ); -} - - void FmFieldWin::FillInfo( SfxChildWinInfo& rInfo ) const { rInfo.bVisible = false; } - -SFX_IMPL_FLOATINGWINDOW(FmFieldWinMgr, SID_FM_ADD_FIELD) - +SFX_IMPL_MODELESSDIALOGCONTOLLER(FmFieldWinMgr, SID_FM_ADD_FIELD) FmFieldWinMgr::FmFieldWinMgr(vcl::Window* _pParent, sal_uInt16 _nId, SfxBindings* _pBindings, SfxChildWinInfo const * _pInfo) :SfxChildWindow(_pParent, _nId) { - SetWindow( VclPtr<FmFieldWin>::Create(_pBindings, this, _pParent) ); + SetController(std::make_shared<FmFieldWin>(_pBindings, this, _pParent->GetFrameWeld())); SetHideNotDelete(true); - static_cast<SfxFloatingWindow*>(GetWindow())->Initialize( _pInfo ); + static_cast<FmFieldWin*>(GetController().get())->Initialize(_pInfo); } - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/inc/tabwin.hxx b/svx/source/inc/tabwin.hxx index 9645ff5a1343..17bdbe6da534 100644 --- a/svx/source/inc/tabwin.hxx +++ b/svx/source/inc/tabwin.hxx @@ -23,6 +23,7 @@ #include <sfx2/basedlgs.hxx> #include <sfx2/childwin.hxx> #include <sfx2/ctrlitem.hxx> +#include <svx/dbaexchange.hxx> #include <com/sun/star/form/XForm.hpp> #include <comphelper/propmultiplex.hxx> @@ -30,61 +31,34 @@ #include <connectivity/dbtools.hxx> -class FmFieldWin; -class FmFieldWinListBox - :public SvTreeListBox -{ - VclPtr<FmFieldWin> pTabWin; - -protected: -// virtual void Command( const CommandEvent& rEvt ); - -public: - FmFieldWinListBox( FmFieldWin* pParent ); - virtual ~FmFieldWinListBox() override; - virtual void dispose() override; - - sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override; - sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override; - -protected: - // DragSourceHelper - virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ) override; - - // SvTreeListBox - virtual bool DoubleClickHdl() override; - - using SvTreeListBox::ExecuteDrop; -}; - - class FmFormShell; +struct ColumnInfo; - -class FmFieldWin :public SfxFloatingWindow - ,public SfxControllerItem - ,public ::comphelper::OPropertyChangeListener +class FmFieldWin : public SfxModelessDialogController + , public SfxControllerItem + , public ::comphelper::OPropertyChangeListener { ::osl::Mutex m_aMutex; - VclPtr<FmFieldWinListBox> pListBox; + std::unique_ptr<weld::TreeView> m_xListBox; + std::vector<std::unique_ptr<ColumnInfo>> m_aListBoxData; ::dbtools::SharedConnection m_aConnection; OUString m_aDatabaseName, m_aObjectName; sal_Int32 m_nObjectType; - rtl::Reference<::comphelper::OPropertyChangeMultiplexer> m_pChangeListener; + rtl::Reference<comphelper::OPropertyChangeMultiplexer> m_xChangeListener; + rtl::Reference<svx::OColumnTransferable> m_xHelper; + void addToList(const css::uno::Reference<css::container::XNameAccess>& i_xColumns); + + DECL_LINK(RowActivatedHdl, weld::TreeView&, bool); + DECL_LINK(DragBeginHdl, weld::TreeView&, bool); public: - FmFieldWin(SfxBindings *pBindings, - SfxChildWindow *pMgr, vcl::Window* pParent); + FmFieldWin(SfxBindings *pBindings, SfxChildWindow *pMgr, weld::Window* pParent); virtual ~FmFieldWin() override; - virtual void dispose() override; - virtual void Resize() override; - using SfxFloatingWindow::Close; - virtual void GetFocus() override; - virtual bool PreNotify( NotifyEvent& _rNEvt ) override; + virtual void StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) override; @@ -92,10 +66,10 @@ public: void UpdateContent(const css::uno::Reference< css::form::XForm > &); void FillInfo( SfxChildWinInfo& rInfo ) const override; - const OUString& GetDatabaseName() const { return m_aDatabaseName; } + const OUString& GetDatabaseName() const { return m_aDatabaseName; } const ::dbtools::SharedConnection& GetConnection() const { return m_aConnection; } - const OUString& GetObjectName() const { return m_aObjectName; } - sal_Int32 GetObjectType() const { return m_nObjectType; } + const OUString& GetObjectName() const { return m_aObjectName; } + sal_Int32 GetObjectType() const { return m_nObjectType; } bool createSelectionControls( ); @@ -105,7 +79,6 @@ protected: protected: using SfxControllerItem::GetBindings; - using SfxFloatingWindow::StateChanged; }; diff --git a/svx/uiconfig/ui/formfielddialog.ui b/svx/uiconfig/ui/formfielddialog.ui new file mode 100644 index 000000000000..3a3d56441852 --- /dev/null +++ b/svx/uiconfig/ui/formfielddialog.ui @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.22.1 --> +<interface domain="svx"> + <requires lib="gtk+" version="3.18"/> + <object class="GtkTreeStore" id="liststore1"> + <columns> + <!-- column-name text --> + <column type="gchararray"/> + <!-- column-name id --> + <column type="gchararray"/> + </columns> + </object> + <object class="GtkDialog" id="FormFieldDialog"> + <property name="can_focus">False</property> + <property name="border_width">6</property> + <property name="default_width">0</property> + <property name="default_height">0</property> + <property name="type_hint">dialog</property> + <child> + <placeholder/> + </child> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox1"> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area1"> + <property name="can_focus">False</property> + <property name="no_show_all">True</property> + <property name="layout_style">end</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkGrid" id="container"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">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> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="treeview"> + <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">0</property> + <property name="show_expanders">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="Macro Library List-selection2"/> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn3"> + <property name="resizable">True</property> + <child> + <object class="GtkCellRendererText" id="cellrenderer1"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> +</interface> diff --git a/vcl/inc/treeglue.hxx b/vcl/inc/treeglue.hxx index 69975035bbcc..9de3a9d4222a 100644 --- a/vcl/inc/treeglue.hxx +++ b/vcl/inc/treeglue.hxx @@ -56,7 +56,7 @@ public: class LclTabListBox final : public SvTabListBox { Link<SvTreeListBox*, void> m_aModelChangedHdl; - Link<SvTreeListBox*, void> m_aStartDragHdl; + Link<SvTreeListBox*, bool> m_aStartDragHdl; Link<SvTreeListBox*, void> m_aEndDragHdl; Link<SvTreeListEntry*, bool> m_aEditingEntryHdl; Link<std::pair<SvTreeListEntry*, OUString>, bool> m_aEditedEntryHdl; @@ -68,7 +68,7 @@ public: } void SetModelChangedHdl(const Link<SvTreeListBox*, void>& rLink) { m_aModelChangedHdl = rLink; } - void SetStartDragHdl(const Link<SvTreeListBox*, void>& rLink) { m_aStartDragHdl = rLink; } + void SetStartDragHdl(const Link<SvTreeListBox*, bool>& rLink) { m_aStartDragHdl = rLink; } void SetEndDragHdl(const Link<SvTreeListBox*, void>& rLink) { m_aEndDragHdl = rLink; } void SetEditingEntryHdl(const Link<SvTreeListEntry*, bool>& rLink) { @@ -86,7 +86,8 @@ public: virtual void StartDrag(sal_Int8 nAction, const Point& rPosPixel) override { - m_aStartDragHdl.Call(this); + if (m_aStartDragHdl.Call(this)) + return; SvTabListBox::StartDrag(nAction, rPosPixel); } diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx index 74409d3cb51f..b4a516b3a28a 100644 --- a/vcl/inc/unx/gtk/gtkinst.hxx +++ b/vcl/inc/unx/gtk/gtkinst.hxx @@ -150,6 +150,13 @@ public: { } + void set_datatransfer(const css::uno::Reference<css::datatransfer::XTransferable>& rTrans, + const css::uno::Reference<css::datatransfer::dnd::XDragSourceListener>& rListener); + + std::vector<GtkTargetEntry> FormatsToGtk(const css::uno::Sequence<css::datatransfer::DataFlavor> &rFormats); + + void setActiveDragSource(); + virtual ~GtkDragSource() override; // XDragSource diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index b7e974e02195..3bfc4e1e92a7 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -3438,7 +3438,7 @@ private: DECL_LINK(HeaderBarClickedHdl, HeaderBar*, void); DECL_LINK(ToggleHdl, SvLBoxButtonData*, void); DECL_LINK(ModelChangedHdl, SvTreeListBox*, void); - DECL_LINK(StartDragHdl, SvTreeListBox*, void); + DECL_LINK(StartDragHdl, SvTreeListBox*, bool); DECL_STATIC_LINK(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void); DECL_LINK(EditingEntryHdl, SvTreeListEntry*, bool); typedef std::pair<SvTreeListEntry*, OUString> IterString; @@ -4350,6 +4350,11 @@ public: set_id(rVclIter.iter, rId); } + virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants) override + { + m_xTreeView->SetDragHelper(rHelper, eDNDConstants); + } + virtual void set_selection_mode(SelectionMode eMode) override { m_xTreeView->SetSelectionMode(eMode); @@ -4582,7 +4587,7 @@ public: else { static_cast<LclTabListBox&>(*m_xTreeView).SetEndDragHdl(Link<SvTreeListBox*, void>()); - static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(Link<SvTreeListBox*, void>()); + static_cast<LclTabListBox&>(*m_xTreeView).SetStartDragHdl(Link<SvTreeListBox*, bool>()); static_cast<LclTabListBox&>(*m_xTreeView).SetModelChangedHdl(Link<SvTreeListBox*, void>()); } m_xTreeView->SetPopupMenuHdl(Link<const CommandEvent&, bool>()); @@ -4651,9 +4656,12 @@ IMPL_LINK_NOARG(SalInstanceTreeView, ModelChangedHdl, SvTreeListBox*, void) signal_model_changed(); } -IMPL_LINK_NOARG(SalInstanceTreeView, StartDragHdl, SvTreeListBox*, void) +IMPL_LINK_NOARG(SalInstanceTreeView, StartDragHdl, SvTreeListBox*, bool) { + if (m_aDragBeginHdl.Call(*this)) + return true; g_DragSource = this; + return false; } IMPL_STATIC_LINK_NOARG(SalInstanceTreeView, FinishDragHdl, SvTreeListBox*, void) diff --git a/vcl/source/treelist/treelistbox.cxx b/vcl/source/treelist/treelistbox.cxx index 601574b95d23..fc73a389bfb2 100644 --- a/vcl/source/treelist/treelistbox.cxx +++ b/vcl/source/treelist/treelistbox.cxx @@ -373,6 +373,7 @@ SvTreeListBox::SvTreeListBox(vcl::Window* pParent, WinBits nWinStyle) : mbQuickSearch(false), eSelMode(SelectionMode::NONE), nMinWidthInChars(0), + mnDragAction(DND_ACTION_COPYMOVE | DND_ACTION_LINK), mbCenterAndClipText(false) { nImpFlags = SvTreeListBoxFlags::NONE; @@ -1152,7 +1153,6 @@ void SvTreeListBox::SetupDragOrigin() void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel ) { - Point aEventPos( rPosPixel ); MouseEvent aMouseEvt( aEventPos, 1, MouseEventModifiers::SELECT, MOUSE_LEFT ); MouseButtonUp( aMouseEvt ); @@ -1170,8 +1170,17 @@ void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel ) return; } - rtl::Reference<TransferDataContainer> pContainer = new TransferDataContainer; - nDragDropMode = NotifyStartDrag( *pContainer, pEntry ); + rtl::Reference<TransferDataContainer> xContainer = m_xTransferHelper; + + if (!xContainer) + { + xContainer.set(new TransferDataContainer); + // apparently some (unused) content is needed + xContainer->CopyAnyData( SotClipboardFormatId::TREELISTBOX, + "unused", SAL_N_ELEMENTS("unused") ); + } + + nDragDropMode = NotifyStartDrag( *xContainer, pEntry ); if( nDragDropMode == DragDropMode::NONE || 0 == GetSelectionCount() ) { nDragDropMode = nOldDragMode; @@ -1181,10 +1190,6 @@ void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel ) SetupDragOrigin(); - // apparently some (unused) content is needed - pContainer->CopyAnyData( SotClipboardFormatId::TREELISTBOX, - "unused", SAL_N_ELEMENTS("unused") ); - bool bOldUpdateMode = Control::IsUpdateMode(); Control::SetUpdateMode( true ); Update(); @@ -1196,7 +1201,13 @@ void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel ) // (GetSourceListBox()->EnableSelectionAsDropTarget( true, true );) EnableSelectionAsDropTarget( false ); - pContainer->StartDrag( this, DND_ACTION_COPYMOVE | DND_ACTION_LINK, GetDragFinishedHdl() ); + xContainer->StartDrag(this, mnDragAction, GetDragFinishedHdl()); +} + +void SvTreeListBox::SetDragHelper(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants) +{ + m_xTransferHelper = rHelper; + mnDragAction = eDNDConstants; } void SvTreeListBox::DragFinished( sal_Int8 diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index 91df150c26cf..8483304923e9 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -4231,18 +4231,38 @@ sal_uIntPtr GtkSalFrame::GetNativeWindowHandle() return GetNativeWindowHandle(m_pWindow); } +void GtkDragSource::set_datatransfer(const css::uno::Reference<css::datatransfer::XTransferable>& rTrans, + const css::uno::Reference<css::datatransfer::dnd::XDragSourceListener>& rListener) +{ + m_xListener = rListener; + m_xTrans = rTrans; +} + +void GtkDragSource::setActiveDragSource() +{ + // For LibreOffice internal D&D we provide the Transferable without Gtk + // intermediaries as a shortcut, see tdf#100097 for how dbaccess depends on this + g_ActiveDragSource = this; + g_DropSuccessSet = false; + g_DropSuccess = false; +} + +std::vector<GtkTargetEntry> GtkDragSource::FormatsToGtk(const css::uno::Sequence<css::datatransfer::DataFlavor> &rFormats) +{ + return m_aConversionHelper.FormatsToGtk(rFormats); +} + void GtkDragSource::startDrag(const datatransfer::dnd::DragGestureEvent& rEvent, sal_Int8 sourceActions, sal_Int32 /*cursor*/, sal_Int32 /*image*/, const css::uno::Reference<css::datatransfer::XTransferable>& rTrans, const css::uno::Reference<css::datatransfer::dnd::XDragSourceListener>& rListener) { - m_xListener = rListener; - m_xTrans = rTrans; + set_datatransfer(rTrans, rListener); if (m_pFrame) { - css::uno::Sequence<css::datatransfer::DataFlavor> aFormats = rTrans->getTransferDataFlavors(); - std::vector<GtkTargetEntry> aGtkTargets(m_aConversionHelper.FormatsToGtk(aFormats)); + auto aFormats = m_xTrans->getTransferDataFlavors(); + std::vector<GtkTargetEntry> aGtkTargets(FormatsToGtk(aFormats)); GtkTargetList *pTargetList = gtk_target_list_new(aGtkTargets.data(), aGtkTargets.size()); gint nDragButton = 1; // default to left button @@ -4257,11 +4277,7 @@ void GtkDragSource::startDrag(const datatransfer::dnd::DragGestureEvent& rEvent, nDragButton = 2; } - // For LibreOffice internal D&D we provide the Transferable without Gtk - // intermediaries as a shortcut, see tdf#100097 for how dbaccess depends on this - g_ActiveDragSource = this; - g_DropSuccessSet = false; - g_DropSuccess = false; + setActiveDragSource(); m_pFrame->startDrag(nDragButton, rEvent.DragOriginX, rEvent.DragOriginY, VclToGdk(sourceActions), pTargetList); diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 976ed97be496..39b3357fe4a2 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -22,6 +22,7 @@ #include <headless/svpvd.hxx> #include <headless/svpbmp.hxx> #include <vcl/inputtypes.hxx> +#include <vcl/transfer.hxx> #include <unx/genpspgraphics.h> #include <rtl/strbuf.hxx> #include <sal/log.hxx> @@ -7945,6 +7946,18 @@ namespace return -1; } + GdkDragAction VclToGdk(sal_Int8 dragOperation) + { + GdkDragAction eRet(static_cast<GdkDragAction>(0)); + if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_COPY) + eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_COPY); + if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_MOVE) + eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_MOVE); + if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_LINK) + eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_LINK); + return eRet; + } + struct GtkInstanceTreeIter : public weld::TreeIter { GtkInstanceTreeIter(const GtkInstanceTreeIter* pOrig) @@ -7993,6 +8006,7 @@ private: std::vector<int> m_aSavedSortColumns; std::vector<int> m_aViewColToModelCol; std::vector<int> m_aModelColToViewCol; + rtl::Reference<GtkDragSource> m_xDragSource; bool m_bWorkAroundBadDragRegion; bool m_bInDrag; gint m_nTextCol; @@ -8008,6 +8022,9 @@ private: gulong m_nPopupMenuSignalId; gulong m_nDragBeginSignalId; gulong m_nDragEndSignalId; + gulong m_nDragFailedSignalId; + gulong m_nDragDataDeleteignalId; + gulong m_nDragGetSignalId; gulong m_nKeyPressSignalId; ImplSVEvent* m_pChangeEvent; @@ -8392,15 +8409,63 @@ private: return default_sort_func(pModel, a, b, m_xSorter.get()); } - static void signalDragBegin(GtkWidget*, GdkDragContext*, gpointer widget) + static void signalDragBegin(GtkWidget*, GdkDragContext* context, gpointer widget) { GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); - g_DragSource = pThis; + pThis->signal_drag_begin(context); + } + + void ensure_drag_source() + { + if (!m_xDragSource) + { + m_xDragSource.set(new GtkDragSource); + + m_nDragFailedSignalId = g_signal_connect(m_pWidget, "drag-failed", G_CALLBACK(signalDragFailed), this); + m_nDragDataDeleteignalId = g_signal_connect(m_pWidget, "drag-data-delete", G_CALLBACK(signalDragDelete), this); + m_nDragGetSignalId = g_signal_connect(m_pWidget, "drag-data-get", G_CALLBACK(signalDragDataGet), this); + } } - static void signalDragEnd(GtkWidget*, GdkDragContext*, gpointer) + void signal_drag_begin(GdkDragContext* context) + { + if (m_aDragBeginHdl.Call(*this)) + { + gtk_drag_cancel(context); + return; + } + g_DragSource = this; + if (!m_xDragSource) + return; + m_xDragSource->setActiveDragSource(); + } + + static void signalDragEnd(GtkWidget* /*widget*/, GdkDragContext* context, gpointer widget) { g_DragSource = nullptr; + GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); + if (pThis->m_xDragSource.is()) + pThis->m_xDragSource->dragEnd(context); + } + + static gboolean signalDragFailed(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkDragResult /*result*/, gpointer widget) + { + GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); + pThis->m_xDragSource->dragFailed(); + return false; + } + + static void signalDragDelete(GtkWidget* /*widget*/, GdkDragContext* /*context*/, gpointer widget) + { + GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); + pThis->m_xDragSource->dragDelete(); + } + + static void signalDragDataGet(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkSelectionData *data, guint info, + guint /*time*/, gpointer widget) + { + GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); + pThis->m_xDragSource->dragDataGet(data, info); } bool signal_key_press(GdkEventKey* pEvent) @@ -8463,6 +8528,9 @@ public: , m_nPopupMenuSignalId(g_signal_connect(pTreeView, "popup-menu", G_CALLBACK(signalPopupMenu), this)) , m_nDragBeginSignalId(g_signal_connect(pTreeView, "drag-begin", G_CALLBACK(signalDragBegin), this)) , m_nDragEndSignalId(g_signal_connect(pTreeView, "drag-end", G_CALLBACK(signalDragEnd), this)) + , m_nDragFailedSignalId(0) + , m_nDragDataDeleteignalId(0) + , m_nDragGetSignalId(0) , m_nKeyPressSignalId(g_signal_connect(pTreeView, "key-press-event", G_CALLBACK(signalKeyPress), this)) , m_pChangeEvent(nullptr) { @@ -9649,6 +9717,24 @@ public: gtk_widget_hide(m_pWidget); } + virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants) override + { + css::uno::Reference<css::datatransfer::XTransferable> xTrans(rHelper.get()); + css::uno::Reference<css::datatransfer::dnd::XDragSourceListener> xListener(rHelper.get()); + + ensure_drag_source(); + + auto aFormats = xTrans->getTransferDataFlavors(); + std::vector<GtkTargetEntry> aGtkTargets(m_xDragSource->FormatsToGtk(aFormats)); + + gtk_tree_view_enable_model_drag_source(m_pTreeView, GDK_BUTTON1_MASK, aGtkTargets.data(), aGtkTargets.size(), VclToGdk(eDNDConstants)); + + for (auto &a : aGtkTargets) + g_free(a.target); + + m_xDragSource->set_datatransfer(xTrans, xListener); + } + virtual void set_selection_mode(SelectionMode eMode) override { disable_notify_events(); @@ -9876,6 +9962,12 @@ public: g_signal_handler_disconnect(m_pTreeView, m_nKeyPressSignalId); g_signal_handler_disconnect(m_pTreeView, m_nDragEndSignalId); g_signal_handler_disconnect(m_pTreeView, m_nDragBeginSignalId); + if (m_nDragFailedSignalId) + g_signal_handler_disconnect(m_pTreeView, m_nDragFailedSignalId); + if (m_nDragDataDeleteignalId) + g_signal_handler_disconnect(m_pTreeView, m_nDragDataDeleteignalId); + if (m_nDragGetSignalId) + g_signal_handler_disconnect(m_pTreeView, m_nDragGetSignalId); g_signal_handler_disconnect(m_pTreeView, m_nPopupMenuSignalId); GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore); g_signal_handler_disconnect(pModel, m_nRowDeletedSignalId); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
