diff options
author | Caolán McNamara <caolanm@redhat.com> | 2022-11-27 21:19:45 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2022-11-28 17:28:10 +0100 |
commit | 61f42c31b02c569ad22cad5e71b20cb0df8fd1f8 (patch) | |
tree | f5460eed195e73594cdc7d7d774700a4274705ea | |
parent | b40f46548fee555b89626e6b17177a1d600b82c1 (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>
-rw-r--r-- | sw/inc/shellio.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/inc/SwXMLTextBlocks.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/inc/swblocks.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/swg/SwXMLTextBlocks.cxx | 53 | ||||
-rw-r--r-- | sw/source/core/swg/swblocks.cxx | 10 | ||||
-rw-r--r-- | sw/source/ui/misc/glossary.cxx | 117 | ||||
-rw-r--r-- | sw/source/uibase/dochdl/gloshdl.cxx | 22 | ||||
-rw-r--r-- | sw/source/uibase/inc/gloshdl.hxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/inc/glossary.hxx | 3 | ||||
-rw-r--r-- | sw/uiconfig/swriter/ui/autotext.ui | 2 |
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> |