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@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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)
|
||||
|
||||
+62
-156
@@ -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 )
|
||||
IMPL_LINK_NOARG(FmFieldWin, DragBeginHdl, weld::TreeView&, bool)
|
||||
{
|
||||
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*/ )
|
||||
{
|
||||
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;
|
||||
aDescriptor[ DataAccessDescriptorProperty::DataSource ] <<= GetDatabaseName();
|
||||
aDescriptor[ DataAccessDescriptorProperty::Connection ] <<= GetConnection().getTyped();
|
||||
aDescriptor[ DataAccessDescriptorProperty::Command ] <<= GetObjectName();
|
||||
aDescriptor[ DataAccessDescriptorProperty::CommandType ]<<= GetObjectType();
|
||||
aDescriptor[ DataAccessDescriptorProperty::ColumnName ] <<= pSelected->sColumnName;
|
||||
|
||||
rtl::Reference<OColumnTransferable> pTransferColumn = new OColumnTransferable(
|
||||
aDescriptor, ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR
|
||||
);
|
||||
EndSelection();
|
||||
pTransferColumn->StartDrag( this, DND_ACTION_COPY );
|
||||
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: */
|
||||
|
||||
+18
-45
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
static void signalDragEnd(GtkWidget*, GdkDragContext*, gpointer)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user