summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2022-11-27 21:19:45 +0000
committerCaolán McNamara <caolanm@redhat.com>2022-11-28 17:28:10 +0100
commit61f42c31b02c569ad22cad5e71b20cb0df8fd1f8 (patch)
treef5460eed195e73594cdc7d7d774700a4274705ea /sw
parentb40f46548fee555b89626e6b17177a1d600b82c1 (diff)
Resolves: tdf#147203 allow dnd between autotext categories
restores various methods removed as unused since original regression at commit 4830a1bae89a8ed60696503e315ffd42c70dff74 Date: Thu May 30 16:12:23 2019 +0100 weld SwGlossaryDlg Change-Id: I5c6186b9f45f3c0957926de2861eb6bc76dda73d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143363 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/shellio.hxx2
-rw-r--r--sw/source/core/inc/SwXMLTextBlocks.hxx1
-rw-r--r--sw/source/core/inc/swblocks.hxx1
-rw-r--r--sw/source/core/swg/SwXMLTextBlocks.cxx53
-rw-r--r--sw/source/core/swg/swblocks.cxx10
-rw-r--r--sw/source/ui/misc/glossary.cxx117
-rw-r--r--sw/source/uibase/dochdl/gloshdl.cxx22
-rw-r--r--sw/source/uibase/inc/gloshdl.hxx2
-rw-r--r--sw/source/uibase/inc/glossary.hxx3
-rw-r--r--sw/uiconfig/swriter/ui/autotext.ui2
10 files changed, 213 insertions, 0 deletions
diff --git a/sw/inc/shellio.hxx b/sw/inc/shellio.hxx
index e476b530fd8a..0fe3985597ef 100644
--- a/sw/inc/shellio.hxx
+++ b/sw/inc/shellio.hxx
@@ -327,6 +327,8 @@ public:
bool Delete( sal_uInt16 );
void Rename( sal_uInt16, const OUString*, const OUString* );
+ ErrCode const & CopyBlock( SwTextBlocks const & rSource, OUString& rSrcShort,
+ const OUString& rLong );
bool BeginGetDoc( sal_uInt16 ); // Read text modules.
void EndGetDoc(); // Release text modules.
diff --git a/sw/source/core/inc/SwXMLTextBlocks.hxx b/sw/source/core/inc/SwXMLTextBlocks.hxx
index bd6458e717d0..9132b5993e8f 100644
--- a/sw/source/core/inc/SwXMLTextBlocks.hxx
+++ b/sw/source/core/inc/SwXMLTextBlocks.hxx
@@ -61,6 +61,7 @@ public:
virtual ~SwXMLTextBlocks() override;
virtual ErrCode Delete( sal_uInt16 ) override;
virtual ErrCode Rename( sal_uInt16, const OUString& ) override;
+ virtual ErrCode CopyBlock( SwImpBlocks& rImp, OUString& rShort, const OUString& rLong) override;
virtual void ClearDoc() override;
virtual ErrCode GetDoc( sal_uInt16 ) override;
virtual ErrCode BeginPutDoc( const OUString&, const OUString& ) override;
diff --git a/sw/source/core/inc/swblocks.hxx b/sw/source/core/inc/swblocks.hxx
index d822acbe26ab..7bd877ad653d 100644
--- a/sw/source/core/inc/swblocks.hxx
+++ b/sw/source/core/inc/swblocks.hxx
@@ -106,6 +106,7 @@ public:
virtual ErrCode Delete( sal_uInt16 ) = 0;
virtual ErrCode Rename( sal_uInt16, const OUString& ) = 0;
+ virtual ErrCode CopyBlock( SwImpBlocks& rImp, OUString& rShort, const OUString& rLong) = 0;
virtual ErrCode GetDoc( sal_uInt16 ) = 0;
virtual ErrCode BeginPutDoc( const OUString&, const OUString& ) = 0;
virtual ErrCode PutDoc() = 0;
diff --git a/sw/source/core/swg/SwXMLTextBlocks.cxx b/sw/source/core/swg/SwXMLTextBlocks.cxx
index f48d007db3c4..3bb108cbf22e 100644
--- a/sw/source/core/swg/SwXMLTextBlocks.cxx
+++ b/sw/source/core/swg/SwXMLTextBlocks.cxx
@@ -232,6 +232,59 @@ ErrCode SwXMLTextBlocks::Rename( sal_uInt16 nIdx, const OUString& rNewShort )
return ERRCODE_NONE;
}
+ErrCode SwXMLTextBlocks::CopyBlock( SwImpBlocks& rDestImp, OUString& rShort,
+ const OUString& rLong)
+{
+ ErrCode nError = ERRCODE_NONE;
+ OpenFile();
+ rDestImp.OpenFile(false);
+ const OUString aGroup( rShort );
+ bool bTextOnly = IsOnlyTextBlock ( rShort ) ;//pImp->pBlkRoot->IsStream( aGroup );
+ sal_uInt16 nIndex = GetIndex ( rShort );
+ OUString sPackageName( GetPackageName (nIndex) );
+ OUString sDestShortName( sPackageName );
+ sal_uInt16 nIdx = 0;
+
+ OSL_ENSURE( m_xBlkRoot.is(), "No storage set" );
+ if(!m_xBlkRoot.is())
+ return ERR_SWG_WRITE_ERROR;
+
+ uno::Reference < container::XNameAccess > xAccess(static_cast<SwXMLTextBlocks&>(rDestImp).m_xBlkRoot);
+ while ( xAccess->hasByName( sDestShortName ) )
+ {
+ ++nIdx;
+ // If someone is that crazy ...
+ if(USHRT_MAX == nIdx)
+ {
+ CloseFile();
+ rDestImp.CloseFile();
+ return ERR_SWG_WRITE_ERROR;
+ }
+ sDestShortName = sPackageName + OUString::number( nIdx );
+ }
+
+ try
+ {
+ uno::Reference < embed::XStorage > rSourceRoot = m_xBlkRoot->openStorageElement( aGroup, embed::ElementModes::READ );
+ uno::Reference < embed::XStorage > rDestRoot = static_cast<SwXMLTextBlocks&>(rDestImp).m_xBlkRoot->openStorageElement( sDestShortName, embed::ElementModes::READWRITE );
+ rSourceRoot->copyToStorage( rDestRoot );
+ }
+ catch (const uno::Exception&)
+ {
+ nError = ERR_SWG_WRITE_ERROR;
+ }
+
+ if(!nError)
+ {
+ rShort = sDestShortName;
+ static_cast<SwXMLTextBlocks&>(rDestImp).AddName( rShort, rLong, bTextOnly );
+ static_cast<SwXMLTextBlocks&>(rDestImp).MakeBlockList();
+ }
+ CloseFile();
+ rDestImp.CloseFile();
+ return nError;
+}
+
ErrCode SwXMLTextBlocks::StartPutBlock( const OUString& rShort, const OUString& rPackageName )
{
OSL_ENSURE( m_xBlkRoot.is(), "No storage set" );
diff --git a/sw/source/core/swg/swblocks.cxx b/sw/source/core/swg/swblocks.cxx
index d9ccbe4c56c3..fb4769311724 100644
--- a/sw/source/core/swg/swblocks.cxx
+++ b/sw/source/core/swg/swblocks.cxx
@@ -346,6 +346,16 @@ void SwTextBlocks::Rename( sal_uInt16 n, const OUString* s, const OUString* l )
m_pImp->Touch();
}
+ErrCode const & SwTextBlocks::CopyBlock( SwTextBlocks const & rSource, OUString& rSrcShort,
+ const OUString& rLong )
+{
+ if (m_pImp->m_bInPutMuchBlocks)
+ m_nErr = ERR_SWG_INTERNAL_ERROR;
+ else
+ m_nErr = m_pImp->CopyBlock(*rSource.m_pImp, rSrcShort, rLong);
+ return m_nErr;
+}
+
bool SwTextBlocks::BeginGetDoc( sal_uInt16 n )
{
if( m_pImp && !m_pImp->m_bInPutMuchBlocks )
diff --git a/sw/source/ui/misc/glossary.cxx b/sw/source/ui/misc/glossary.cxx
index 2f3347d1e1ef..ae3ce4f06666 100644
--- a/sw/source/ui/misc/glossary.cxx
+++ b/sw/source/ui/misc/glossary.cxx
@@ -22,6 +22,7 @@
#include <o3tl/any.hxx>
#include <vcl/event.hxx>
#include <vcl/svapp.hxx>
+#include <vcl/transfer.hxx>
#include <vcl/weld.hxx>
#include <svl/stritem.hxx>
#include <svl/macitem.hxx>
@@ -176,6 +177,117 @@ IMPL_LINK(SwGlossaryDlg, TextFilterHdl, OUString&, rTest, bool)
return true;
}
+class SwGlossaryDropTarget : public DropTargetHelper
+{
+private:
+ weld::TreeView& m_rTreeView;
+ SwGlossaryHdl* m_pGlosHdl;
+
+ virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override
+ {
+ weld::TreeView* pSource = m_rTreeView.get_drag_source();
+ if (!pSource || pSource != &m_rTreeView)
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xSelected(pSource->make_iterator());
+ bool bSelected = pSource->get_selected(xSelected.get());
+ if (!bSelected)
+ return DND_ACTION_NONE;
+
+ while (pSource->get_iter_depth(*xSelected))
+ (void)pSource->iter_parent(*xSelected);
+
+ GroupUserData* pSrcRootData = weld::fromId<GroupUserData*>(pSource->get_id(*xSelected));
+ GroupUserData* pDestRootData = nullptr;
+
+ std::unique_ptr<weld::TreeIter> xDestEntry(m_rTreeView.make_iterator());
+ bool bEntry = m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xDestEntry.get(), true);
+ if (bEntry)
+ {
+ while (m_rTreeView.get_iter_depth(*xDestEntry))
+ (void)m_rTreeView.iter_parent(*xDestEntry);
+ pDestRootData = weld::fromId<GroupUserData*>(m_rTreeView.get_id(*xDestEntry));
+ }
+ if (pDestRootData == pSrcRootData)
+ return DND_ACTION_NONE;
+ sal_uInt8 nRet = DND_ACTION_COPY;
+ const bool bCheckForMove = rEvt.mnAction & DND_ACTION_MOVE;
+ if (bCheckForMove && !pSrcRootData->bReadonly)
+ nRet |= DND_ACTION_MOVE;
+ return nRet;
+ }
+
+ virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override
+ {
+ weld::TreeView* pSource = m_rTreeView.get_drag_source();
+ if (!pSource)
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xDestEntry(m_rTreeView.make_iterator());
+ bool bEntry = m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xDestEntry.get(), true);
+ if (!bEntry)
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xSelected(pSource->make_iterator());
+ bool bSelected = pSource->get_selected(xSelected.get());
+ if (!bSelected)
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xSrcParent(pSource->make_iterator(xSelected.get()));
+ while (pSource->get_iter_depth(*xSrcParent))
+ (void)pSource->iter_parent(*xSrcParent);
+
+ std::unique_ptr<weld::TreeIter> xDestParent(pSource->make_iterator(xDestEntry.get()));
+ while (pSource->get_iter_depth(*xDestParent))
+ (void)pSource->iter_parent(*xDestParent);
+
+ GroupUserData* pSrcParent = weld::fromId<GroupUserData*>(pSource->get_id(*xSrcParent));
+ GroupUserData* pDestParent = weld::fromId<GroupUserData*>(m_rTreeView.get_id(*xDestParent));
+
+ if (pDestParent != pSrcParent)
+ {
+ weld::WaitObject aBusy(&m_rTreeView);
+
+ OUString sSourceGroup = pSrcParent->sGroupName
+ + OUStringChar(GLOS_DELIM)
+ + OUString::number(pSrcParent->nPathIdx);
+
+ m_pGlosHdl->SetCurGroup(sSourceGroup);
+ OUString sTitle(pSource->get_text(*xSelected));
+ OUString sShortName(pSource->get_id(*xSelected));
+
+ OUString sDestName = pDestParent->sGroupName
+ + OUStringChar(GLOS_DELIM)
+ + OUString::number(pDestParent->nPathIdx);
+
+ bool bIsMove = rEvt.mnAction & DND_ACTION_MOVE;
+
+ const bool bRet = m_pGlosHdl->CopyOrMove(sSourceGroup, sShortName,
+ sDestName, sTitle, bIsMove);
+
+ if(bRet)
+ {
+ m_rTreeView.insert(xDestParent.get(), -1, &sTitle, &sShortName,
+ nullptr, nullptr, false, nullptr);
+ if (bIsMove)
+ {
+ pSource->remove(*xSelected);
+ }
+ }
+ }
+
+ return DND_ACTION_NONE;
+ }
+
+public:
+ SwGlossaryDropTarget(weld::TreeView& rTreeView, SwGlossaryHdl* pGlosHdl)
+ : DropTargetHelper(rTreeView.get_drop_target())
+ , m_rTreeView(rTreeView)
+ , m_pGlosHdl(pGlosHdl)
+ {
+ }
+};
+
SwGlossaryDlg::SwGlossaryDlg(SfxViewFrame const * pViewFrame,
SwGlossaryHdl * pGlosHdl, SwWrtShell *pWrtShell)
: SfxDialogController(pViewFrame->GetFrameWeld(), "modules/swriter/ui/autotext.ui", "AutoTextDialog")
@@ -221,6 +333,11 @@ SwGlossaryDlg::SwGlossaryDlg(SfxViewFrame const * pViewFrame,
m_xCategoryBox->connect_row_activated(LINK(this, SwGlossaryDlg, NameDoubleClick));
m_xCategoryBox->connect_changed(LINK(this, SwGlossaryDlg, GrpSelect));
m_xCategoryBox->connect_key_press(LINK(this, SwGlossaryDlg, KeyInputHdl));
+
+ m_xDropTarget.reset(new SwGlossaryDropTarget(*m_xCategoryBox, pGlosHdl));
+ rtl::Reference<TransferDataContainer> xHelper(new TransferDataContainer);
+ m_xCategoryBox->enable_drag_source(xHelper, DND_ACTION_COPYMOVE);
+
m_xBibBtn->connect_clicked(LINK(this,SwGlossaryDlg,BibHdl));
m_xInsertBtn->connect_clicked(LINK(this,SwGlossaryDlg,InsertHdl));
diff --git a/sw/source/uibase/dochdl/gloshdl.cxx b/sw/source/uibase/dochdl/gloshdl.cxx
index 9f2e070162c4..4820584268aa 100644
--- a/sw/source/uibase/dochdl/gloshdl.cxx
+++ b/sw/source/uibase/dochdl/gloshdl.cxx
@@ -196,6 +196,28 @@ void SwGlossaryHdl::RenameGroup(const OUString& rOld, OUString& rNew, const OUSt
}
}
+bool SwGlossaryHdl::CopyOrMove(const OUString& rSourceGroupName, OUString& rSourceShortName,
+ const OUString& rDestGroupName, const OUString& rLongName, bool bMove)
+{
+ std::unique_ptr<SwTextBlocks> pSourceGroup = m_rStatGlossaries.GetGroupDoc(rSourceGroupName);
+ std::unique_ptr<SwTextBlocks> pDestGroup = m_rStatGlossaries.GetGroupDoc(rDestGroupName);
+ if (pDestGroup->IsReadOnly() || (bMove && pSourceGroup->IsReadOnly()) )
+ {
+ return false;
+ }
+
+ //The index must be determined here because rSourceShortName maybe changed in CopyBlock
+ sal_uInt16 nDeleteIdx = pSourceGroup->GetIndex( rSourceShortName );
+ OSL_ENSURE(USHRT_MAX != nDeleteIdx, "entry not found");
+ ErrCode nRet = pSourceGroup->CopyBlock( *pDestGroup, rSourceShortName, rLongName );
+ if(!nRet && bMove)
+ {
+ // the index must be existing
+ nRet = pSourceGroup->Delete( nDeleteIdx ) ? ERRCODE_NONE : ErrCode(1);
+ }
+ return !nRet;
+}
+
// delete an autotext-file-group
bool SwGlossaryHdl::DelGroup(const OUString &rGrpName)
{
diff --git a/sw/source/uibase/inc/gloshdl.hxx b/sw/source/uibase/inc/gloshdl.hxx
index 812609fdbba3..530d0b6bc4a0 100644
--- a/sw/source/uibase/inc/gloshdl.hxx
+++ b/sw/source/uibase/inc/gloshdl.hxx
@@ -62,6 +62,8 @@ public:
bool Rename( const OUString& rOldShortName, const OUString& rNewShortName,
const OUString& rNewName);
+ bool CopyOrMove( const OUString& rSourceGroupName, OUString& rSourceShortName,
+ const OUString& rDestGroupName, const OUString& rLongName, bool bMove );
bool HasShortName(const OUString &rShortName) const;
// when NewGlossary is called from Basic then the previously set group should
// be newly created if applicable.
diff --git a/sw/source/uibase/inc/glossary.hxx b/sw/source/uibase/inc/glossary.hxx
index ada07976450f..d0a99a86a664 100644
--- a/sw/source/uibase/inc/glossary.hxx
+++ b/sw/source/uibase/inc/glossary.hxx
@@ -39,6 +39,8 @@ class SwOneExampleFrame;
const short RET_EDIT = 100;
+class SwGlossaryDropTarget;
+
class SwGlossaryDlg final : public SfxDialogController
{
friend class SwNewGlosNameDlg;
@@ -76,6 +78,7 @@ class SwGlossaryDlg final : public SfxDialogController
std::unique_ptr<weld::Button> m_xPathBtn;
std::unique_ptr<SwOneExampleFrame> m_xExampleFrame;
std::unique_ptr<weld::CustomWeld> m_xExampleFrameWin;
+ std::unique_ptr<SwGlossaryDropTarget> m_xDropTarget;
void EnableShortName(bool bOn = true);
void ShowPreview();
diff --git a/sw/uiconfig/swriter/ui/autotext.ui b/sw/uiconfig/swriter/ui/autotext.ui
index ce59f4b19ade..19f3c636176f 100644
--- a/sw/uiconfig/swriter/ui/autotext.ui
+++ b/sw/uiconfig/swriter/ui/autotext.ui
@@ -484,7 +484,9 @@
<property name="model">liststore1</property>
<property name="headers-visible">False</property>
<property name="headers-clickable">False</property>
+ <property name="reorderable">True</property>
<property name="search-column">0</property>
+ <property name="enable-tree-lines">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>