[Libreoffice-commits] core.git: include/svx include/vcl svx/source svx/uiconfig svx/UIConfig_svx.mk vcl/inc vcl/source vcl/unx
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Sun Dec 1 19:51:55 UTC 2019
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 <caolanm at redhat.com>
AuthorDate: Fri Nov 29 10:21:11 2019 +0000
Commit: Caolán McNamara <caolanm at redhat.com>
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 <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
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);
More information about the Libreoffice-commits
mailing list