diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-03-14 12:51:31 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-03-15 09:57:43 +0100 |
commit | 8bddb3c77048814b370351e0eb72c31f289fb34f (patch) | |
tree | 8b081c15b1779301eee613e6f24de1371dd77265 | |
parent | f5efc3cb9d2bbcaaca95e15a03815e8f8eda7b09 (diff) |
add drop target support to welded widget
refactor the mega-widget dnd drop target to be reused at
mini-widget level
and weld SwInsertBookmarkDlg
Change-Id: I3f36e1cd902ecf166e369d0a05902d3df2b4f791
Reviewed-on: https://gerrit.libreoffice.org/69274
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | include/vcl/weld.hxx | 10 | ||||
-rw-r--r-- | sw/inc/swabstdlg.hxx | 2 | ||||
-rw-r--r-- | sw/source/ui/dialog/swdlgfact.cxx | 8 | ||||
-rw-r--r-- | sw/source/ui/dialog/swdlgfact.hxx | 2 | ||||
-rw-r--r-- | sw/source/ui/misc/bookmark.cxx | 273 | ||||
-rw-r--r-- | sw/source/uibase/inc/bookmark.hxx | 62 | ||||
-rw-r--r-- | sw/source/uibase/inc/condedit.hxx | 35 | ||||
-rw-r--r-- | sw/source/uibase/shells/textsh1.cxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/utlui/condedit.cxx | 61 | ||||
-rw-r--r-- | sw/uiconfig/swriter/ui/insertbookmark.ui | 201 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 7 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkinst.hxx | 18 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 5 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkframe.cxx | 65 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 59 |
15 files changed, 545 insertions, 265 deletions
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index a3aeaf223142..75b33607d1dd 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -38,6 +38,13 @@ namespace awt { class XWindow; } +namespace datatransfer +{ +namespace dnd +{ +class XDropTarget; +} +} namespace graphic { class XGraphic; @@ -206,6 +213,8 @@ public: virtual VclPtr<VirtualDevice> create_virtual_device() const = 0; + virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> get_drop_target() = 0; + virtual ~Widget() {} }; @@ -903,6 +912,7 @@ public: // nEndPos can be -1 in order to select all text virtual void select_region(int nStartPos, int nEndPos) = 0; virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) = 0; + // nCursorPos can be -1 to set to the end virtual void set_position(int nCursorPos) = 0; virtual int get_position() const = 0; virtual void set_editable(bool bEditable) = 0; diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx index ac53affc4664..cef81a8148cb 100644 --- a/sw/inc/swabstdlg.hxx +++ b/sw/inc/swabstdlg.hxx @@ -373,7 +373,7 @@ public: virtual VclPtr<SfxAbstractDialog> CreateSwAddressAbstractDlg(weld::Window* pParent, const SfxItemSet& rSet) = 0; virtual VclPtr<AbstractSwAsciiFilterDlg> CreateSwAsciiFilterDlg(weld::Window* pParent, SwDocShell& rDocSh, SvStream* pStream) = 0; - virtual VclPtr<VclAbstractDialog> CreateSwInsertBookmarkDlg( vcl::Window *pParent, SwWrtShell &rSh, SfxRequest& rReq ) = 0; + virtual VclPtr<VclAbstractDialog> CreateSwInsertBookmarkDlg(weld::Window *pParent, SwWrtShell &rSh, SfxRequest& rReq) = 0; virtual VclPtr<AbstractSwBreakDlg> CreateSwBreakDlg(weld::Window *pParent, SwWrtShell &rSh) = 0; virtual VclPtr<VclAbstractDialog> CreateSwChangeDBDlg(SwView& rVw) = 0; diff --git a/sw/source/ui/dialog/swdlgfact.cxx b/sw/source/ui/dialog/swdlgfact.cxx index 1566aba4c060..3292b44eb7ec 100644 --- a/sw/source/ui/dialog/swdlgfact.cxx +++ b/sw/source/ui/dialog/swdlgfact.cxx @@ -778,12 +778,10 @@ VclPtr<AbstractSwAsciiFilterDlg> SwAbstractDialogFactory_Impl::CreateSwAsciiFilt return VclPtr<AbstractSwAsciiFilterDlg_Impl>::Create(std::make_unique<SwAsciiFilterDlg>(pParent, rDocSh, pStream)); } -VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwInsertBookmarkDlg( vcl::Window *pParent, - SwWrtShell &rSh, - SfxRequest& rReq ) +VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwInsertBookmarkDlg(weld::Window *pParent, + SwWrtShell &rSh, SfxRequest& rReq) { - VclPtr<SwInsertBookmarkDlg> pDlg = VclPtr<SwInsertBookmarkDlg>::Create( pParent, rSh, rReq ); - return VclPtr<VclAbstractDialog_Impl>::Create( pDlg ); + return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_unique<SwInsertBookmarkDlg>(pParent, rSh, rReq)); } VclPtr<AbstractSwBreakDlg> SwAbstractDialogFactory_Impl::CreateSwBreakDlg(weld::Window* pParent, SwWrtShell &rSh) diff --git a/sw/source/ui/dialog/swdlgfact.hxx b/sw/source/ui/dialog/swdlgfact.hxx index 308a603c572a..8fb02a4c4ac6 100644 --- a/sw/source/ui/dialog/swdlgfact.hxx +++ b/sw/source/ui/dialog/swdlgfact.hxx @@ -597,7 +597,7 @@ public: virtual VclPtr<SfxAbstractDialog> CreateSwAddressAbstractDlg(weld::Window* pParent, const SfxItemSet& rSet) override; virtual VclPtr<AbstractSwAsciiFilterDlg> CreateSwAsciiFilterDlg(weld::Window* pParent, SwDocShell& rDocSh, SvStream* pStream) override; - virtual VclPtr<VclAbstractDialog> CreateSwInsertBookmarkDlg( vcl::Window *pParent, SwWrtShell &rSh, SfxRequest& rReq ) override; + virtual VclPtr<VclAbstractDialog> CreateSwInsertBookmarkDlg(weld::Window *pParent, SwWrtShell &rSh, SfxRequest& rReq) override; virtual VclPtr<AbstractSwBreakDlg> CreateSwBreakDlg(weld::Window *pParent, SwWrtShell &rSh) override; virtual VclPtr<VclAbstractDialog> CreateSwChangeDBDlg(SwView& rVw) override; virtual VclPtr<SfxAbstractTabDialog> CreateSwCharDlg(weld::Window* pParent, SwView& pVw, const SfxItemSet& rCoreSet, diff --git a/sw/source/ui/misc/bookmark.cxx b/sw/source/ui/misc/bookmark.cxx index fabcae7a521e..32631b20d2f5 100644 --- a/sw/source/ui/misc/bookmark.cxx +++ b/sw/source/ui/misc/bookmark.cxx @@ -42,14 +42,14 @@ const OUString BookmarkTable::aForbiddenChars("/\\@*?\",#"); const char BookmarkTable::cSeparator(';'); // callback to modify EditBox -IMPL_LINK_NOARG(SwInsertBookmarkDlg, ModifyHdl, Edit&, void) +IMPL_LINK_NOARG(SwInsertBookmarkDlg, ModifyHdl, weld::Entry&, void) { ValidateBookmarks(); - m_pBookmarksBox->SelectAll(false); + m_xBookmarksBox->unselect_all(); // if a string has been pasted from the clipboard then // there may be illegal characters in the box // sanitization - OUString sTmp = m_pEditBox->GetText(); + OUString sTmp = m_xEditBox->get_text(); OUString sMsg; const sal_Int32 nLen = sTmp.getLength(); for (sal_Int32 i = 0; i < BookmarkTable::aForbiddenChars.getLength(); i++) @@ -61,8 +61,8 @@ IMPL_LINK_NOARG(SwInsertBookmarkDlg, ModifyHdl, Edit&, void) } if (sTmp.getLength() != nLen) { - m_pEditBox->SetText(sTmp); - std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(), + m_xEditBox->set_text(sTmp); + std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Info, VclButtonsType::Ok, sRemoveWarning + sMsg)); xInfoBox->run(); @@ -74,36 +74,38 @@ IMPL_LINK_NOARG(SwInsertBookmarkDlg, ModifyHdl, Edit&, void) while (!sTmp.isEmpty() && nTokenIndex >= 0) { OUString aToken = sTmp.getToken(0, BookmarkTable::cSeparator, nTokenIndex); - if (m_pBookmarksBox->GetBookmarkByName(aToken)) + if (m_xBookmarksBox->GetBookmarkByName(aToken)) { - m_pBookmarksBox->SelectByName(aToken); + m_xBookmarksBox->SelectByName(aToken); nSelectedEntries++; } nEntries++; } // allow to add new bookmark only if one name provided and it's not taken - m_pInsertBtn->Enable(nEntries == 1 && nSelectedEntries == 0); + m_xInsertBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 0); // allow to delete only if all bookmarks are recognized - m_pDeleteBtn->Enable(nEntries > 0 && nSelectedEntries == nEntries); - m_pGotoBtn->Enable(nEntries == 1 && nSelectedEntries == 1); - m_pRenameBtn->Enable(nEntries == 1 && nSelectedEntries == 1); + m_xDeleteBtn->set_sensitive(nEntries > 0 && nSelectedEntries == nEntries); + m_xGotoBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1); + m_xRenameBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1); } // callback to delete a text mark -IMPL_LINK_NOARG(SwInsertBookmarkDlg, DeleteHdl, Button*, void) +IMPL_LINK_NOARG(SwInsertBookmarkDlg, DeleteHdl, weld::Button&, void) { if (!ValidateBookmarks()) return; - if (m_pBookmarksBox->GetSelectionCount() == 0) + std::vector<int> aSelectedRows(m_xBookmarksBox->get_selected_rows()); + if (aSelectedRows.empty()) return; + std::sort(aSelectedRows.begin(), aSelectedRows.end()); - SvTreeListEntry* pSelected = m_pBookmarksBox->FirstSelected(); - for (sal_Int32 i = m_pBookmarksBox->GetSelectionCount(); i; i--) + for (size_t i = aSelectedRows.size(); i; --i) { + int nRow = aSelectedRows[i-1]; // remove from model - sw::mark::IMark* pBookmark = static_cast<sw::mark::IMark*>(pSelected->GetUserData()); + sw::mark::IMark* pBookmark = reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(nRow).toInt64()); OUString sRemoved = pBookmark->GetName(); IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess(); pMarkAccess->deleteMark(pMarkAccess->findMark(sRemoved)); @@ -113,76 +115,74 @@ IMPL_LINK_NOARG(SwInsertBookmarkDlg, DeleteHdl, Button*, void) aTableBookmarks.erase(std::remove(aTableBookmarks.begin(), aTableBookmarks.end(), std::make_pair(pBookmark, sRemoved)), aTableBookmarks.end()); // remove from BookmarkTable - SvTreeListEntry* nextSelected = m_pBookmarksBox->NextSelected(pSelected); - m_pBookmarksBox->RemoveEntry(pSelected); - pSelected = nextSelected; + m_xBookmarksBox->remove(nRow); } - m_pBookmarksBox->SelectAll(false); - m_pEditBox->SetText(""); - m_pDeleteBtn->Disable(); - m_pGotoBtn->Disable(); - m_pRenameBtn->Disable(); - m_pInsertBtn->Disable(); + m_xBookmarksBox->unselect_all(); + m_xEditBox->set_text(""); + m_xDeleteBtn->set_sensitive(false); + m_xGotoBtn->set_sensitive(false); + m_xRenameBtn->set_sensitive(false); + m_xInsertBtn->set_sensitive(false); } // callback to a goto button -IMPL_LINK_NOARG(SwInsertBookmarkDlg, GotoHdl, Button*, void) +IMPL_LINK_NOARG(SwInsertBookmarkDlg, GotoHdl, weld::Button&, void) { GotoSelectedBookmark(); } -IMPL_LINK_NOARG(SwInsertBookmarkDlg, DoubleClickHdl, SvTreeListBox*, bool) +IMPL_LINK_NOARG(SwInsertBookmarkDlg, DoubleClickHdl, weld::TreeView&, void) { GotoSelectedBookmark(); - return true; } -IMPL_LINK_NOARG(SwInsertBookmarkDlg, SelectionChangedHdl, SvTreeListBox*, void) +IMPL_LINK_NOARG(SwInsertBookmarkDlg, SelectionChangedHdl, weld::TreeView&, void) { if (!ValidateBookmarks()) return; // this event should fired only if we change selection by clicking on BookmarkTable entry - if (!m_pBookmarksBox->HasFocus()) + if (!m_xBookmarksBox->has_focus()) return; OUStringBuffer sEditBoxText; - SvTreeListEntry* pSelected = m_pBookmarksBox->FirstSelected(); - for (sal_Int32 i = m_pBookmarksBox->GetSelectionCount(); i; i--) + + std::vector<int> aSelectedRows(m_xBookmarksBox->get_selected_rows()); + std::sort(aSelectedRows.begin(), aSelectedRows.end()); + for (size_t i = aSelectedRows.size(); i; --i) { - sw::mark::IMark* pBookmark = static_cast<sw::mark::IMark*>(pSelected->GetUserData()); + int nRow = aSelectedRows[i-1]; + sw::mark::IMark* pBookmark = reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(nRow).toInt64()); const OUString& sEntryName = pBookmark->GetName(); sEditBoxText.append(sEntryName); - if (i > 1) + if (nRow > 1) sEditBoxText.append(";"); - pSelected = m_pBookmarksBox->NextSelected(pSelected); } - if (m_pBookmarksBox->GetSelectionCount() > 0) + if (!aSelectedRows.empty()) { - m_pInsertBtn->Disable(); - m_pGotoBtn->Enable(m_pBookmarksBox->GetSelectionCount() == 1); - m_pRenameBtn->Enable(m_pBookmarksBox->GetSelectionCount() == 1); - m_pDeleteBtn->Enable(); - m_pEditBox->SetText(sEditBoxText.makeStringAndClear()); + m_xInsertBtn->set_sensitive(false); + m_xGotoBtn->set_sensitive(aSelectedRows.size() == 1); + m_xRenameBtn->set_sensitive(aSelectedRows.size() == 1); + m_xDeleteBtn->set_sensitive(true); + m_xEditBox->set_text(sEditBoxText.makeStringAndClear()); } else { - m_pInsertBtn->Enable(); - m_pGotoBtn->Disable(); - m_pRenameBtn->Disable(); - m_pDeleteBtn->Disable(); + m_xInsertBtn->set_sensitive(true); + m_xGotoBtn->set_sensitive(false); + m_xRenameBtn->set_sensitive(false); + m_xDeleteBtn->set_sensitive(false); } } -IMPL_LINK_NOARG(SwInsertBookmarkDlg, RenameHdl, Button*, void) +IMPL_LINK_NOARG(SwInsertBookmarkDlg, RenameHdl, weld::Button&, void) { if (!ValidateBookmarks()) return; - if (m_pBookmarksBox->GetSelectionCount() == 0) + int nSelected = m_xBookmarksBox->get_selected_index(); + if (nSelected == -1) return; - SvTreeListEntry* pSelected = m_pBookmarksBox->FirstSelected(); - sw::mark::IMark* pBookmark = static_cast<sw::mark::IMark*>(pSelected->GetUserData()); - + sw::mark::IMark* pBookmark = reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(nSelected).toInt64()); uno::Reference<frame::XModel> xModel = rSh.GetView().GetDocShell()->GetBaseModel(); uno::Reference<text::XBookmarksSupplier> xBkms(xModel, uno::UNO_QUERY); uno::Reference<container::XNameAccess> xNameAccess = xBkms->getBookmarks(); @@ -191,37 +191,37 @@ IMPL_LINK_NOARG(SwInsertBookmarkDlg, RenameHdl, Button*, void) aObj >>= xTmp; uno::Reference<container::XNamed> xNamed(xTmp, uno::UNO_QUERY); SwAbstractDialogFactory& rFact = swui::GetFactory(); - ScopedVclPtr<AbstractSwRenameXNamedDlg> pDlg(rFact.CreateSwRenameXNamedDlg(GetFrameWeld(), xNamed, xNameAccess)); + ScopedVclPtr<AbstractSwRenameXNamedDlg> pDlg(rFact.CreateSwRenameXNamedDlg(m_xDialog.get(), xNamed, xNameAccess)); pDlg->SetForbiddenChars(BookmarkTable::aForbiddenChars + OUStringLiteral1(BookmarkTable::cSeparator)); if (pDlg->Execute()) { ValidateBookmarks(); - m_pDeleteBtn->Disable(); - m_pGotoBtn->Disable(); - m_pRenameBtn->Disable(); - m_pInsertBtn->Disable(); + m_xDeleteBtn->set_sensitive(false); + m_xGotoBtn->set_sensitive(false); + m_xRenameBtn->set_sensitive(false); + m_xInsertBtn->set_sensitive(false); } } // callback to a insert button. Inserts a new text mark to the current position. -IMPL_LINK_NOARG(SwInsertBookmarkDlg, InsertHdl, Button*, void) +IMPL_LINK_NOARG(SwInsertBookmarkDlg, InsertHdl, weld::Button&, void) { - OUString sBookmark = m_pEditBox->GetText(); - rSh.SetBookmark2(vcl::KeyCode(), sBookmark, m_pHideCB->IsChecked(), m_pConditionED->GetText()); + OUString sBookmark = m_xEditBox->get_text(); + rSh.SetBookmark2(vcl::KeyCode(), sBookmark, m_xHideCB->get_active(), m_xConditionED->get_text()); rReq.AppendItem(SfxStringItem(FN_INSERT_BOOKMARK, sBookmark)); rReq.Done(); if (!rReq.IsDone()) rReq.Ignore(); - EndDialog(RET_OK); + m_xDialog->response(RET_OK); } -IMPL_LINK(SwInsertBookmarkDlg, ChangeHideHdl, Button *, pBox, void) +IMPL_LINK(SwInsertBookmarkDlg, ChangeHideHdl, weld::ToggleButton&, rBox, void) { - bool bHide = static_cast<CheckBox*>(pBox)->IsChecked(); - m_pConditionED->Enable(bHide); - m_pConditionFT->Enable(bHide); + bool bHide = rBox.get_active(); + m_xConditionED->set_sensitive(bHide); + m_xConditionFT->set_sensitive(bHide); } void SwInsertBookmarkDlg::GotoSelectedBookmark() @@ -230,10 +230,11 @@ void SwInsertBookmarkDlg::GotoSelectedBookmark() return; // if no entries selected we can't jump anywhere // shouldn't be needed as we disable GoTo button when jump is not possible - if (m_pBookmarksBox->GetSelectionCount() == 0) + int nSelected = m_xBookmarksBox->get_selected_index(); + if (nSelected == -1) return; - sw::mark::IMark* pBookmark = static_cast<sw::mark::IMark*>(m_pBookmarksBox->FirstSelected()->GetUserData()); + sw::mark::IMark* pBookmark = reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(nSelected).toInt64()); rSh.EnterStdMode(); rSh.GotoMark(pBookmark); @@ -244,7 +245,7 @@ bool SwInsertBookmarkDlg::ValidateBookmarks() if (HaveBookmarksChanged()) { PopulateTable(); - m_pEditBox->SetText(""); + m_xEditBox->set_text(""); return false; } return true; @@ -278,7 +279,7 @@ bool SwInsertBookmarkDlg::HaveBookmarksChanged() void SwInsertBookmarkDlg::PopulateTable() { aTableBookmarks.clear(); - m_pBookmarksBox->Clear(); + m_xBookmarksBox->clear(); IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess(); for (IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin(); @@ -286,91 +287,64 @@ void SwInsertBookmarkDlg::PopulateTable() { if (IDocumentMarkAccess::MarkType::BOOKMARK == IDocumentMarkAccess::GetType(**ppBookmark)) { - m_pBookmarksBox->InsertBookmark(ppBookmark->get()); + m_xBookmarksBox->InsertBookmark(ppBookmark->get()); aTableBookmarks.emplace_back(ppBookmark->get(), ppBookmark->get()->GetName()); } } m_nLastBookmarksCount = pMarkAccess->getBookmarksCount(); } -void SwInsertBookmarkDlg::Apply() -{ -} - -SwInsertBookmarkDlg::SwInsertBookmarkDlg(vcl::Window* pParent, SwWrtShell& rS, SfxRequest& rRequest) - : SvxStandardDialog(pParent, "InsertBookmarkDialog", "modules/swriter/ui/insertbookmark.ui") +SwInsertBookmarkDlg::SwInsertBookmarkDlg(weld::Window* pParent, SwWrtShell& rS, SfxRequest& rRequest) + : SfxDialogController(pParent, "modules/swriter/ui/insertbookmark.ui", "InsertBookmarkDialog") , rSh(rS) , rReq(rRequest) , m_nLastBookmarksCount(0) + , m_xEditBox(m_xBuilder->weld_entry("name")) + , m_xInsertBtn(m_xBuilder->weld_button("insert")) + , m_xDeleteBtn(m_xBuilder->weld_button("delete")) + , m_xGotoBtn(m_xBuilder->weld_button("goto")) + , m_xRenameBtn(m_xBuilder->weld_button("rename")) + , m_xHideCB(m_xBuilder->weld_check_button("hide")) + , m_xConditionFT(m_xBuilder->weld_label("condlabel")) + , m_xConditionED(new SwConditionEdit(m_xBuilder->weld_entry("withcond"))) + , m_xBookmarksBox(new BookmarkTable(m_xBuilder->weld_tree_view("bookmarks"))) { - get(m_pBookmarksContainer, "bookmarks"); - get(m_pEditBox, "name"); - get(m_pInsertBtn, "insert"); - get(m_pDeleteBtn, "delete"); - get(m_pGotoBtn, "goto"); - get(m_pRenameBtn, "rename"); - get(m_pHideCB, "hide"); - get(m_pConditionFT, "condlabel"); - get(m_pConditionED, "withcond"); - - m_pBookmarksBox = VclPtr<BookmarkTable>::Create(*m_pBookmarksContainer); - - m_pBookmarksBox->SetSelectHdl(LINK(this, SwInsertBookmarkDlg, SelectionChangedHdl)); - m_pBookmarksBox->SetDeselectHdl(LINK(this, SwInsertBookmarkDlg, SelectionChangedHdl)); - m_pBookmarksBox->SetDoubleClickHdl(LINK(this, SwInsertBookmarkDlg, DoubleClickHdl)); - m_pEditBox->SetModifyHdl(LINK(this, SwInsertBookmarkDlg, ModifyHdl)); - m_pInsertBtn->SetClickHdl(LINK(this, SwInsertBookmarkDlg, InsertHdl)); - m_pDeleteBtn->SetClickHdl(LINK(this, SwInsertBookmarkDlg, DeleteHdl)); - m_pGotoBtn->SetClickHdl(LINK(this, SwInsertBookmarkDlg, GotoHdl)); - m_pRenameBtn->SetClickHdl(LINK(this, SwInsertBookmarkDlg, RenameHdl)); - m_pHideCB->SetClickHdl(LINK(this, SwInsertBookmarkDlg, ChangeHideHdl)); - - m_pDeleteBtn->Disable(); - m_pGotoBtn->Disable(); - m_pRenameBtn->Disable(); + m_xBookmarksBox->connect_changed(LINK(this, SwInsertBookmarkDlg, SelectionChangedHdl)); + m_xBookmarksBox->connect_row_activated(LINK(this, SwInsertBookmarkDlg, DoubleClickHdl)); + m_xEditBox->connect_changed(LINK(this, SwInsertBookmarkDlg, ModifyHdl)); + m_xInsertBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, InsertHdl)); + m_xDeleteBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, DeleteHdl)); + m_xGotoBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, GotoHdl)); + m_xRenameBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, RenameHdl)); + m_xHideCB->connect_toggled(LINK(this, SwInsertBookmarkDlg, ChangeHideHdl)); + + m_xDeleteBtn->set_sensitive(false); + m_xGotoBtn->set_sensitive(false); + m_xRenameBtn->set_sensitive(false); PopulateTable(); - m_pEditBox->SetText(m_pBookmarksBox->GetNameProposal()); - m_pEditBox->SetCursorAtLast(); + m_xEditBox->set_text(m_xBookmarksBox->GetNameProposal()); + m_xEditBox->set_position(-1); sRemoveWarning = SwResId(STR_REMOVE_WARNING); } SwInsertBookmarkDlg::~SwInsertBookmarkDlg() { - disposeOnce(); } -void SwInsertBookmarkDlg::dispose() +BookmarkTable::BookmarkTable(std::unique_ptr<weld::TreeView> xControl) + : m_xControl(std::move(xControl)) { - m_pBookmarksBox.disposeAndClear(); - m_pBookmarksContainer.clear(); - m_pInsertBtn.clear(); - m_pDeleteBtn.clear(); - m_pGotoBtn.clear(); - m_pEditBox.clear(); - m_pRenameBtn.clear(); - m_pHideCB.clear(); - m_pConditionFT.clear(); - m_pConditionED.clear(); - SvxStandardDialog::dispose(); -} - -BookmarkTable::BookmarkTable(SvSimpleTableContainer& rParent) : - SvSimpleTable(rParent, 0) -{ - static long nTabs[] = { 0, 40, 150, 300, 340 }; - - SetTabs(SAL_N_ELEMENTS(nTabs), nTabs, MapUnit::MapPixel); - SetSelectionMode(SelectionMode::Multiple); - InsertHeaderEntry(SwResId(STR_PAGE)); - InsertHeaderEntry(SwResId(STR_BOOKMARK_NAME)); - InsertHeaderEntry(SwResId(STR_BOOKMARK_TEXT)); - InsertHeaderEntry(SwResId(STR_BOOKMARK_HIDDEN)); - InsertHeaderEntry(SwResId(STR_BOOKMARK_CONDITION)); - - rParent.SetTable(this); + m_xControl->set_size_request(450, 250); + std::vector<int> aWidths; + aWidths.push_back(40); + aWidths.push_back(110); + aWidths.push_back(150); + aWidths.push_back(60); + m_xControl->set_column_fixed_widths(aWidths); + m_xControl->set_selection_mode(SelectionMode::Multiple); } void BookmarkTable::InsertBookmark(sw::mark::IMark* pMark) @@ -413,51 +387,51 @@ void BookmarkTable::InsertBookmark(sw::mark::IMark* pMark) sHidden = "Yes"; const OUString& sHideCondition = pBookmark->GetHideCondition(); OUString sPageNum = OUString::number(SwPaM(pMark->GetMarkStart()).GetPageNum()); - OUString sColumnData = sPageNum + "\t" + pBookmark->GetName() + "\t" + sBookmarkNodeText + "\t" + sHidden + "\t" + sHideCondition; - InsertEntryToColumn(sColumnData, TREELIST_APPEND, 0xffff, pMark); + int nRow = m_xControl->n_children(); + m_xControl->append(OUString::number(reinterpret_cast<sal_Int64>(pMark)), sPageNum); + m_xControl->set_text(nRow, pBookmark->GetName(), 1); + m_xControl->set_text(nRow, sBookmarkNodeText, 2); + m_xControl->set_text(nRow, sHidden, 3); + m_xControl->set_text(nRow, sHideCondition, 4); } -SvTreeListEntry* BookmarkTable::GetRowByBookmarkName(const OUString& sName) +int BookmarkTable::GetRowByBookmarkName(const OUString& sName) { - SvTreeListEntry* pEntry = First(); - while (pEntry) + for (int i = 0, nCount = m_xControl->n_children(); i < nCount; ++i) { - sw::mark::IMark* pBookmark = static_cast<sw::mark::IMark*>(pEntry->GetUserData()); + sw::mark::IMark* pBookmark = reinterpret_cast<sw::mark::IMark*>(m_xControl->get_id(i).toInt64()); if (pBookmark->GetName() == sName) { - return pEntry; + return i; } - pEntry = Next(pEntry); } - return nullptr; + return -1; } sw::mark::IMark* BookmarkTable::GetBookmarkByName(const OUString& sName) { - SvTreeListEntry* pEntry = GetRowByBookmarkName(sName); - if (!pEntry) + int nEntry = GetRowByBookmarkName(sName); + if (nEntry == -1) return nullptr; - return static_cast<sw::mark::IMark*>(pEntry->GetUserData()); + return reinterpret_cast<sw::mark::IMark*>(m_xControl->get_id(nEntry).toInt64()); } void BookmarkTable::SelectByName(const OUString& sName) { - SvTreeListEntry* pEntry = GetRowByBookmarkName(sName); - if (!pEntry) + int nEntry = GetRowByBookmarkName(sName); + if (nEntry == -1) return; - - Select(pEntry); + select(nEntry); } OUString BookmarkTable::GetNameProposal() { OUString sDefaultBookmarkName = SwResId(STR_BOOKMARK_DEF_NAME); sal_Int32 nHighestBookmarkId = 0; - SvTreeListEntry* pEntry = First(); - while (pEntry) + for (int i = 0, nCount = m_xControl->n_children(); i < nCount; ++i) { - sw::mark::IMark* pBookmark = static_cast<sw::mark::IMark*>(pEntry->GetUserData()); + sw::mark::IMark* pBookmark = reinterpret_cast<sw::mark::IMark*>(m_xControl->get_id(i).toInt64()); const OUString& sName = pBookmark->GetName(); sal_Int32 nIndex = 0; if (sName.getToken(0, ' ', nIndex) == sDefaultBookmarkName) @@ -465,7 +439,6 @@ OUString BookmarkTable::GetNameProposal() sal_Int32 nCurrBookmarkId = sName.getToken(0, ' ', nIndex).toInt32(); nHighestBookmarkId = std::max<sal_Int32>(nHighestBookmarkId, nCurrBookmarkId); } - pEntry = Next(pEntry); } return sDefaultBookmarkName + " " + OUString::number(nHighestBookmarkId + 1); } diff --git a/sw/source/uibase/inc/bookmark.hxx b/sw/source/uibase/inc/bookmark.hxx index 98682a941ffe..755783abd789 100644 --- a/sw/source/uibase/inc/bookmark.hxx +++ b/sw/source/uibase/inc/bookmark.hxx @@ -33,46 +33,60 @@ class SwWrtShell; class SfxRequest; -class BookmarkTable : public SvSimpleTable +class BookmarkTable { - SvTreeListEntry* GetRowByBookmarkName(const OUString& sName); + std::unique_ptr<weld::TreeView> m_xControl; + int GetRowByBookmarkName(const OUString& sName); public: - BookmarkTable(SvSimpleTableContainer& rParent); + BookmarkTable(std::unique_ptr<weld::TreeView> xControl); void InsertBookmark(sw::mark::IMark* pMark); void SelectByName(const OUString& sName); sw::mark::IMark* GetBookmarkByName(const OUString& sName); OUString GetNameProposal(); + void unselect_all() { m_xControl->unselect_all(); } + bool has_focus() const { return m_xControl->has_focus(); } + int n_children() const { return m_xControl->n_children(); } + int get_selected_index() const { return m_xControl->get_selected_index(); } + std::vector<int> get_selected_rows() const { return m_xControl->get_selected_rows(); } + void clear() { m_xControl->clear(); } + void remove(int nRow) { m_xControl->remove(nRow); } + void select(int nRow) { m_xControl->select(nRow); } + OUString get_id(int nRow) const { return m_xControl->get_id(nRow); } + + void connect_changed(const Link<weld::TreeView&, void>& rLink) { m_xControl->connect_changed(rLink); } + void connect_row_activated(const Link<weld::TreeView&, void>& rLink) { m_xControl->connect_row_activated(rLink); } + static const OUString aForbiddenChars; static const char cSeparator; }; -class SwInsertBookmarkDlg: public SvxStandardDialog +class SwInsertBookmarkDlg : public SfxDialogController { - VclPtr<SvSimpleTableContainer> m_pBookmarksContainer; - VclPtr<BookmarkTable> m_pBookmarksBox; - VclPtr<Edit> m_pEditBox; - VclPtr<PushButton> m_pInsertBtn; - VclPtr<PushButton> m_pDeleteBtn; - VclPtr<PushButton> m_pGotoBtn; - VclPtr<PushButton> m_pRenameBtn; - VclPtr<CheckBox> m_pHideCB; - VclPtr<FixedText> m_pConditionFT; - VclPtr<ConditionEdit> m_pConditionED; OUString sRemoveWarning; SwWrtShell& rSh; SfxRequest& rReq; std::vector<std::pair<sw::mark::IMark*, OUString>> aTableBookmarks; sal_Int32 m_nLastBookmarksCount; - DECL_LINK(ModifyHdl, Edit&, void); - DECL_LINK(InsertHdl, Button*, void); - DECL_LINK(DeleteHdl, Button*, void); - DECL_LINK(RenameHdl, Button*, void); - DECL_LINK(GotoHdl, Button*, void); - DECL_LINK(SelectionChangedHdl, SvTreeListBox*, void); - DECL_LINK(DoubleClickHdl, SvTreeListBox*, bool); - DECL_LINK(ChangeHideHdl, Button *, void); + std::unique_ptr<weld::Entry> m_xEditBox; + std::unique_ptr<weld::Button> m_xInsertBtn; + std::unique_ptr<weld::Button> m_xDeleteBtn; + std::unique_ptr<weld::Button> m_xGotoBtn; + std::unique_ptr<weld::Button> m_xRenameBtn; + std::unique_ptr<weld::CheckButton> m_xHideCB; + std::unique_ptr<weld::Label> m_xConditionFT; + std::unique_ptr<SwConditionEdit> m_xConditionED; + std::unique_ptr<BookmarkTable> m_xBookmarksBox; + + DECL_LINK(ModifyHdl, weld::Entry&, void); + DECL_LINK(InsertHdl, weld::Button&, void); + DECL_LINK(DeleteHdl, weld::Button&, void); + DECL_LINK(RenameHdl, weld::Button&, void); + DECL_LINK(GotoHdl, weld::Button&, void); + DECL_LINK(SelectionChangedHdl, weld::TreeView&, void); + DECL_LINK(DoubleClickHdl, weld::TreeView&, void); + DECL_LINK(ChangeHideHdl, weld::ToggleButton&, void); // Fill table with bookmarks void PopulateTable(); @@ -83,12 +97,10 @@ class SwInsertBookmarkDlg: public SvxStandardDialog bool ValidateBookmarks(); bool HaveBookmarksChanged(); void GotoSelectedBookmark(); - virtual void Apply() override; public: - SwInsertBookmarkDlg(vcl::Window* pParent, SwWrtShell& rSh, SfxRequest& rReq); + SwInsertBookmarkDlg(weld::Window* pParent, SwWrtShell& rSh, SfxRequest& rReq); virtual ~SwInsertBookmarkDlg() override; - virtual void dispose() override; }; #endif diff --git a/sw/source/uibase/inc/condedit.hxx b/sw/source/uibase/inc/condedit.hxx index 1f7c3225fb38..972e9574bbce 100644 --- a/sw/source/uibase/inc/condedit.hxx +++ b/sw/source/uibase/inc/condedit.hxx @@ -21,6 +21,7 @@ #include <vcl/edit.hxx> #include <vcl/transfer.hxx> +#include <vcl/weld.hxx> #include <swdllapi.h> class SW_DLLPUBLIC ConditionEdit : public Edit, public DropTargetHelper @@ -44,6 +45,40 @@ public: } }; +class SwConditionEdit; + +class SW_DLLPUBLIC SwConditionEditDropTarget : public DropTargetHelper +{ +private: + SwConditionEdit& m_rEdit; + + SAL_DLLPRIVATE virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override; + SAL_DLLPRIVATE virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override; + +public: + SwConditionEditDropTarget(SwConditionEdit& rEdit); +}; + +class SW_DLLPUBLIC SwConditionEdit +{ + std::unique_ptr<weld::Entry> m_xControl; + SwConditionEditDropTarget m_aDropTargetHelper; + bool bBrackets, bEnableDrop; + +public: + SwConditionEdit(std::unique_ptr<weld::Entry> xControl); + + OUString get_text() const { return m_xControl->get_text(); } + bool get_sensitive() const { return m_xControl->get_sensitive(); } + void set_sensitive(bool bSensitive) { m_xControl->set_sensitive(bSensitive); } + weld::Entry& get_widget() { return *m_xControl; } + + void ShowBrackets(bool bShow) { bBrackets = bShow; } + bool GetBrackets() const { return bBrackets; } + void SetDropEnable(bool bFlag) { bEnableDrop = bFlag; } + bool GetDropEnable() const { return bEnableDrop; } +}; + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index 5d533a91954a..dfdde52dd3e7 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -690,7 +690,7 @@ void SwTextShell::Execute(SfxRequest &rReq) else { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwInsertBookmarkDlg( GetView().GetWindow(), rWrtSh, rReq )); + ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwInsertBookmarkDlg(GetView().GetFrameWeld(), rWrtSh, rReq)); pDlg->Execute(); } diff --git a/sw/source/uibase/utlui/condedit.cxx b/sw/source/uibase/utlui/condedit.cxx index 18c6341e20c8..f1a77a2a740a 100644 --- a/sw/source/uibase/utlui/condedit.cxx +++ b/sw/source/uibase/utlui/condedit.cxx @@ -87,4 +87,65 @@ sal_Int8 ConditionEdit::ExecuteDrop( const ExecuteDropEvent& rEvt ) return nRet; } +SwConditionEdit::SwConditionEdit(std::unique_ptr<weld::Entry> xControl) + : m_xControl(std::move(xControl)) + , m_aDropTargetHelper(*this) + , bBrackets(true) + , bEnableDrop(true) +{ +} + +sal_Int8 SwConditionEditDropTarget::AcceptDrop( const AcceptDropEvent& /*rEvt*/ ) +{ + return OColumnTransferable::canExtractColumnDescriptor + ( GetDataFlavorExVector(), + ColumnTransferFormatFlags::COLUMN_DESCRIPTOR ) + ? DND_ACTION_COPY + : DND_ACTION_NONE; +} + +SwConditionEditDropTarget::SwConditionEditDropTarget(SwConditionEdit& rEdit) + : DropTargetHelper(rEdit.get_widget().get_drop_target()) + , m_rEdit(rEdit) +{ +} + +sal_Int8 SwConditionEditDropTarget::ExecuteDrop( const ExecuteDropEvent& rEvt ) +{ + sal_Int8 nRet = DND_ACTION_NONE; + if (m_rEdit.GetDropEnable()) + { + TransferableDataHelper aData( rEvt.maDropEvent.Transferable ); + + const DataFlavorExVector& rVector = aData.GetDataFlavorExVector(); + if (OColumnTransferable::canExtractColumnDescriptor(rVector, ColumnTransferFormatFlags::COLUMN_DESCRIPTOR)) + { + ODataAccessDescriptor aColDesc = OColumnTransferable::extractColumnDescriptor( + aData); + OUString sDBName; + bool bBrackets = m_rEdit.GetBrackets(); + if (bBrackets) + sDBName += "["; + OUString sTmp; + sTmp = aColDesc.getDataSource(); + sDBName += sTmp; + sDBName += "."; + + aColDesc[DataAccessDescriptorProperty::Command] >>= sTmp; + sDBName += sTmp; + sDBName += "."; + + aColDesc[DataAccessDescriptorProperty::ColumnName] >>= sTmp; + sDBName += sTmp; + if (bBrackets) + sDBName += "]"; + + m_rEdit.get_widget().set_text( sDBName ); + nRet = DND_ACTION_COPY; + } + } + return nRet; +} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/uiconfig/swriter/ui/insertbookmark.ui b/sw/uiconfig/swriter/ui/insertbookmark.ui index 3e106e40285f..0aa5af987570 100644 --- a/sw/uiconfig/swriter/ui/insertbookmark.ui +++ b/sw/uiconfig/swriter/ui/insertbookmark.ui @@ -1,18 +1,81 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> +<!-- Generated with glade 3.22.1 --> <interface domain="sw"> <requires lib="gtk+" version="3.18"/> - <requires lib="LibreOffice" version="1.0"/> + <object class="GtkTreeStore" id="liststore1"> + <columns> + <!-- column-name text --> + <column type="gchararray"/> + <!-- column-name text2 --> + <column type="gchararray"/> + <!-- column-name text3 --> + <column type="gchararray"/> + <!-- column-name text4 --> + <column type="gchararray"/> + <!-- column-name text5 --> + <column type="gchararray"/> + <!-- column-name id --> + <column type="gchararray"/> + </columns> + </object> <object class="GtkDialog" id="InsertBookmarkDialog"> <property name="can_focus">False</property> <property name="border_width">6</property> <property name="title" translatable="yes" context="insertbookmark|InsertBookmarkDialog">Bookmark</property> + <property name="modal">True</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="hexpand">True</property> + <property name="vexpand">True</property> <property name="orientation">vertical</property> <property name="spacing">12</property> + <child internal-child="action_area"> + <object class="GtkButtonBox"> + <property name="can_focus">False</property> + <child> + <object class="GtkButton" id="close"> + <property name="label">gtk-close</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </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="GtkButton" id="help"> + <property name="label">gtk-help</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + <property name="secondary">True</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">5</property> + </packing> + </child> <child> <object class="GtkBox" id="box1"> <property name="visible">True</property> @@ -22,6 +85,7 @@ <object class="GtkEntry" id="name"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="activates_default">True</property> <property name="max_width_chars">0</property> </object> <packing> @@ -60,6 +124,7 @@ <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="halign">start</property> + <property name="use_underline">True</property> <property name="draw_indicator">True</property> </object> <packing> @@ -78,6 +143,7 @@ <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes" context="insertbookmark|condlabel">_With condition</property> + <property name="use_underline">True</property> <property name="mnemonic_widget">withcond</property> </object> <packing> @@ -87,9 +153,10 @@ </packing> </child> <child> - <object class="swlo-ConditionEdit" id="withcond"> + <object class="GtkEntry" id="withcond"> <property name="visible">True</property> <property name="can_focus">True</property> + <property name="activates_default">True</property> </object> <packing> <property name="expand">True</property> @@ -105,13 +172,91 @@ </packing> </child> <child> - <object class="svtlo-SvSimpleTableContainer" id="bookmarks"> - <property name="width_request">350</property> - <property name="height_request">250</property> + <object class="GtkScrolledWindow"> <property name="visible">True</property> <property name="can_focus">True</property> - <child internal-child="selection"> - <object class="GtkTreeSelection"/> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="bookmarks"> + <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="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="treeviewcolumn0"> + <property name="resizable">True</property> + <property name="spacing">6</property> + <property name="title" translatable="yes" context="insertbookmark|page">Page</property> + <child> + <object class="GtkCellRendererText" id="cellrenderer0"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn1"> + <property name="resizable">True</property> + <property name="spacing">6</property> + <property name="title" translatable="yes" context="insertbookmark|name">Name</property> + <child> + <object class="GtkCellRendererText" id="cellrenderer1"/> + <attributes> + <attribute name="text">1</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn2"> + <property name="resizable">True</property> + <property name="spacing">6</property> + <property name="title" translatable="yes" context="insertbookmark|text">Text</property> + <child> + <object class="GtkCellRendererText" id="cellrenderer2"/> + <attributes> + <attribute name="text">2</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn3"> + <property name="resizable">True</property> + <property name="spacing">6</property> + <property name="title" translatable="yes" context="insertbookmark|hidden">Hidden</property> + <child> + <object class="GtkCellRendererText" id="cellrenderer3"/> + <attributes> + <attribute name="text">3</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn4"> + <property name="resizable">True</property> + <property name="spacing">6</property> + <property name="title" translatable="yes" context="insertbookmark|condition">Condition</property> + <child> + <object class="GtkCellRendererText" id="cellrenderer4"/> + <attributes> + <attribute name="text">4</attribute> + </attributes> + </child> + </object> + </child> + </object> </child> </object> <packing> @@ -174,48 +319,10 @@ <property name="position">4</property> </packing> </child> - <child internal-child="action_area" id="dialog-action_area1"> - <object class="GtkButtonBox"> - <property name="can_focus">False</property> - <child> - <object class="GtkButton" id="help"> - <property name="label">gtk-help</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="close"> - <property name="label">gtk-close</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">end</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">5</property> - </packing> - </child> </object> </child> <action-widgets> + <action-widget response="-7">close</action-widget> <action-widget response="-11">help</action-widget> </action-widgets> </object> diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index 248c896b28a1..d67046a940ae 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -219,8 +219,6 @@ class GtkSalFrame : public SalFrame cairo_region_t* m_pRegion; GtkDropTarget* m_pDropTarget; GtkDragSource* m_pDragSource; - bool m_bInDrag; - GtkDnDTransferable* m_pFormatConversionRequest; bool m_bGeometryIsProvisional; #else GdkRegion* m_pRegion; @@ -419,11 +417,6 @@ public: m_pDragSource = nullptr; } - void SetFormatConversionRequest(GtkDnDTransferable *pRequest) - { - m_pFormatConversionRequest = pRequest; - } - void startDrag(gint nButton, gint nDragOriginX, gint nDragOriginY, GdkDragAction sourceActions, GtkTargetList* pTargetList); diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx index 83e56184ddb1..c0e073cca845 100644 --- a/vcl/inc/unx/gtk/gtkinst.hxx +++ b/vcl/inc/unx/gtk/gtkinst.hxx @@ -76,23 +76,25 @@ protected: std::map<OUString, GdkAtom> m_aMimeTypeToAtom; std::vector<css::datatransfer::DataFlavor> getTransferDataFlavorsAsVector(GdkAtom *targets, gint n_targets); -public: +public: virtual css::uno::Any SAL_CALL getTransferData(const css::datatransfer::DataFlavor& rFlavor) override = 0; - virtual std::vector<css::datatransfer::DataFlavor> getTransferDataFlavorsAsVector() = 0; - virtual css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL getTransferDataFlavors() override; virtual sal_Bool SAL_CALL isDataFlavorSupported(const css::datatransfer::DataFlavor& rFlavor) override; }; +class GtkDnDTransferable; + class GtkDropTarget : public cppu::WeakComponentImplHelper<css::datatransfer::dnd::XDropTarget, css::lang::XInitialization, css::lang::XServiceInfo> { osl::Mutex m_aMutex; GtkSalFrame* m_pFrame; + GtkDnDTransferable* m_pFormatConversionRequest; bool m_bActive; + bool m_bInDrag; sal_Int8 m_nDefaultActions; std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> m_aListeners; public: @@ -121,6 +123,16 @@ public: void fire_dragOver(const css::datatransfer::dnd::DropTargetDragEvent& dtde); void fire_drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde); void fire_dragExit(const css::datatransfer::dnd::DropTargetEvent& dte); + + void SetFormatConversionRequest(GtkDnDTransferable *pRequest) + { + m_pFormatConversionRequest = pRequest; + } + + gboolean signalDragDrop(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, guint time); + gboolean signalDragMotion(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, guint time); + void signalDragDropReceived(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, GtkSelectionData* data, guint ttype, guint time); + void signalDragLeave(GtkWidget* pWidget, GdkDragContext* context, guint time); }; class GtkDragSource : public cppu::WeakComponentImplHelper<css::datatransfer::dnd::XDragSource, diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 7c0dd9c85cef..de75da50d37b 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -621,6 +621,11 @@ public: return VclPtr<VirtualDevice>::Create(*Application::GetDefaultDevice(), DeviceFormat::DEFAULT, DeviceFormat::DEFAULT); } + virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> get_drop_target() override + { + return m_xWidget->GetDropTarget(); + } + SystemWindow* getSystemWindow() { return m_xWidget->GetSystemWindow(); diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index 33c4b5e7b071..8de0b605b916 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -1074,8 +1074,6 @@ void GtkSalFrame::InitCommon() m_pRegion = nullptr; m_pDropTarget = nullptr; m_pDragSource = nullptr; - m_bInDrag = false; - m_pFormatConversionRequest = nullptr; m_bGeometryIsProvisional = false; m_ePointerStyle = static_cast<PointerStyle>(0xffff); m_pSalMenu = nullptr; @@ -3468,15 +3466,15 @@ class GtkDnDTransferable : public GtkTransferable GdkDragContext *m_pContext; guint m_nTime; GtkWidget *m_pWidget; - GtkSalFrame *m_pFrame; + GtkDropTarget* m_pDropTarget; GMainLoop *m_pLoop; GtkSelectionData *m_pData; public: - GtkDnDTransferable(GdkDragContext *pContext, guint nTime, GtkWidget *pWidget, GtkSalFrame *pFrame) + GtkDnDTransferable(GdkDragContext *pContext, guint nTime, GtkWidget *pWidget, GtkDropTarget *pDropTarget) : m_pContext(pContext) , m_nTime(nTime) , m_pWidget(pWidget) - , m_pFrame(pFrame) + , m_pDropTarget(pDropTarget) , m_pLoop(nullptr) , m_pData(nullptr) { @@ -3498,7 +3496,7 @@ public: */ { m_pLoop = g_main_loop_new(nullptr, true); - m_pFrame->SetFormatConversionRequest(this); + m_pDropTarget->SetFormatConversionRequest(this); gtk_drag_get_data(m_pWidget, m_pContext, it->second, m_nTime); @@ -3511,7 +3509,7 @@ public: g_main_loop_unref(m_pLoop); m_pLoop = nullptr; - m_pFrame->SetFormatConversionRequest(nullptr); + m_pDropTarget->SetFormatConversionRequest(nullptr); } css::uno::Any aRet; @@ -3561,12 +3559,15 @@ GtkDragSource* GtkDragSource::g_ActiveDragSource; gboolean GtkSalFrame::signalDragDrop(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, guint time, gpointer frame) { GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - if (!pThis->m_pDropTarget) return false; + return pThis->m_pDropTarget->signalDragDrop(pWidget, context, x, y, time); +} +gboolean GtkDropTarget::signalDragDrop(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, guint time) +{ css::datatransfer::dnd::DropTargetDropEvent aEvent; - aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(pThis->m_pDropTarget); + aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(this); aEvent.Context = new GtkDropTargetDropContext(context, time); aEvent.LocationX = x; aEvent.LocationY = y; @@ -3590,14 +3591,15 @@ gboolean GtkSalFrame::signalDragDrop(GtkWidget* pWidget, GdkDragContext* context if (GtkDragSource::g_ActiveDragSource) xTransferable = GtkDragSource::g_ActiveDragSource->GetTransferrable(); else - xTransferable = new GtkDnDTransferable(context, time, pWidget, pThis); + xTransferable = new GtkDnDTransferable(context, time, pWidget, this); aEvent.Transferable = xTransferable; - pThis->m_pDropTarget->fire_drop(aEvent); + fire_drop(aEvent); return true; } + class GtkDropTargetDragContext : public cppu::WeakImplHelper<css::datatransfer::dnd::XDropTargetDragContext> { GdkDragContext *m_pContext; @@ -3620,10 +3622,16 @@ public: } }; -void GtkSalFrame::signalDragDropReceived(GtkWidget* /*pWidget*/, GdkDragContext * /*context*/, gint /*x*/, gint /*y*/, GtkSelectionData* data, guint /*ttype*/, guint /*time*/, gpointer frame) +void GtkSalFrame::signalDragDropReceived(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, GtkSelectionData* data, guint ttype, guint time, gpointer frame) { GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); + if (!pThis->m_pDropTarget) + return; + pThis->m_pDropTarget->signalDragDropReceived(pWidget, context, x, y, data, ttype, time); +} +void GtkDropTarget::signalDragDropReceived(GtkWidget* /*pWidget*/, GdkDragContext * /*context*/, gint /*x*/, gint /*y*/, GtkSelectionData* data, guint /*ttype*/, guint /*time*/) +{ /* * If we get a drop, then we will call like gtk_clipboard_wait_for_contents * with a loop inside a loop to get the right format, so if this is the @@ -3631,24 +3639,28 @@ void GtkSalFrame::signalDragDropReceived(GtkWidget* /*pWidget*/, GdkDragContext * * don't look at me like that. */ - if (!pThis->m_pFormatConversionRequest) + if (!m_pFormatConversionRequest) return; - pThis->m_pFormatConversionRequest->LoopEnd(gtk_selection_data_copy(data)); + m_pFormatConversionRequest->LoopEnd(gtk_selection_data_copy(data)); } gboolean GtkSalFrame::signalDragMotion(GtkWidget *pWidget, GdkDragContext *context, gint x, gint y, guint time, gpointer frame) { GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); - if (!pThis->m_pDropTarget) return false; + return pThis->m_pDropTarget->signalDragMotion(pWidget, context, x, y, time); +} - if (!pThis->m_bInDrag) + +gboolean GtkDropTarget::signalDragMotion(GtkWidget *pWidget, GdkDragContext *context, gint x, gint y, guint time) +{ + if (!m_bInDrag) gtk_drag_highlight(pWidget); css::datatransfer::dnd::DropTargetDragEnterEvent aEvent; - aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(pThis->m_pDropTarget); + aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(this); GtkDropTargetDragContext* pContext = new GtkDropTargetDragContext(context, time); //preliminary accept the Drag and select the preferred action, the fire_* will //inform the original caller of our choice and the callsite can decide @@ -3686,7 +3698,7 @@ gboolean GtkSalFrame::signalDragMotion(GtkWidget *pWidget, GdkDragContext *conte aEvent.DropAction = GdkToVcl(eAction); aEvent.SourceActions = nSourceActions; - if (!pThis->m_bInDrag) + if (!m_bInDrag) { css::uno::Reference<css::datatransfer::XTransferable> xTransferable; // For LibreOffice internal D&D we provide the Transferable without Gtk @@ -3694,26 +3706,31 @@ gboolean GtkSalFrame::signalDragMotion(GtkWidget *pWidget, GdkDragContext *conte if (GtkDragSource::g_ActiveDragSource) xTransferable = GtkDragSource::g_ActiveDragSource->GetTransferrable(); else - xTransferable = new GtkDnDTransferable(context, time, pWidget, pThis); + xTransferable = new GtkDnDTransferable(context, time, pWidget, this); css::uno::Sequence<css::datatransfer::DataFlavor> aFormats = xTransferable->getTransferDataFlavors(); aEvent.SupportedDataFlavors = aFormats; - pThis->m_pDropTarget->fire_dragEnter(aEvent); - pThis->m_bInDrag = true; + fire_dragEnter(aEvent); + m_bInDrag = true; } else { - pThis->m_pDropTarget->fire_dragOver(aEvent); + fire_dragOver(aEvent); } return true; } -void GtkSalFrame::signalDragLeave(GtkWidget *pWidget, GdkDragContext * /*context*/, guint /*time*/, gpointer frame) +void GtkSalFrame::signalDragLeave(GtkWidget *pWidget, GdkDragContext *context, guint time, gpointer frame) { GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); if (!pThis->m_pDropTarget) return; - pThis->m_bInDrag = false; + pThis->m_pDropTarget->signalDragLeave(pWidget, context, time); +} + +void GtkDropTarget::signalDragLeave(GtkWidget* pWidget, GdkDragContext* /*context*/, guint /*time*/) +{ + m_bInDrag = false; gtk_drag_unhighlight(pWidget); } diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 49c6a64bc3f6..d15928180331 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -721,7 +721,9 @@ Reference< XInterface > GtkInstance::CreateClipboard(const Sequence< Any >& argu GtkDropTarget::GtkDropTarget() : WeakComponentImplHelper(m_aMutex) , m_pFrame(nullptr) + , m_pFormatConversionRequest(nullptr) , m_bActive(false) + , m_bInDrag(false) , m_nDefaultActions(0) { } @@ -860,7 +862,7 @@ void GtkDropTarget::setDefaultActions(sal_Int8 nDefaultActions) Reference< XInterface > GtkInstance::CreateDropTarget() { - return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new GtkDropTarget()) ); + return Reference<XInterface>(static_cast<cppu::OWeakObject*>(new GtkDropTarget)); } GtkDragSource::~GtkDragSource() @@ -1289,6 +1291,12 @@ private: gulong m_nButtonPressSignalId; gulong m_nMotionSignalId; gulong m_nButtonReleaseSignalId; + gulong m_nDragMotionSignalId; + gulong m_nDragDropSignalId; + gulong m_nDragDropReceivedSignalId; + gulong m_nDragLeaveSignalId; + + rtl::Reference<GtkDropTarget> m_xDropTarget; static void signalSizeAllocate(GtkWidget*, GdkRectangle* allocation, gpointer widget) { @@ -1422,6 +1430,30 @@ private: return true; } + static gboolean signalDragMotion(GtkWidget *pWidget, GdkDragContext *context, gint x, gint y, guint time, gpointer widget) + { + GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); + return pThis->m_xDropTarget->signalDragMotion(pWidget, context, x, y, time); + } + + static gboolean signalDragDrop(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, guint time, gpointer widget) + { + GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); + return pThis->m_xDropTarget->signalDragDrop(pWidget, context, x, y, time); + } + + static void signalDragDropReceived(GtkWidget* pWidget, GdkDragContext* context, gint x, gint y, GtkSelectionData* data, guint ttype, guint time, gpointer widget) + { + GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); + pThis->m_xDropTarget->signalDragDropReceived(pWidget, context, x, y, data, ttype, time); + } + + static void signalDragLeave(GtkWidget *pWidget, GdkDragContext *context, guint time, gpointer widget) + { + GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); + pThis->m_xDropTarget->signalDragLeave(pWidget, context, time); + } + public: GtkInstanceWidget(GtkWidget* pWidget, GtkInstanceBuilder* pBuilder, bool bTakeOwnership) : m_pWidget(pWidget) @@ -1437,6 +1469,10 @@ public: , m_nButtonPressSignalId(0) , m_nMotionSignalId(0) , m_nButtonReleaseSignalId(0) + , m_nDragMotionSignalId(0) + , m_nDragDropSignalId(0) + , m_nDragDropReceivedSignalId(0) + , m_nDragLeaveSignalId(0) { } @@ -1816,8 +1852,29 @@ public: bool get_frozen() const { return m_bFrozen; } + virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> get_drop_target() override + { + if (!m_xDropTarget) + { + m_xDropTarget.set(new GtkDropTarget); + m_nDragMotionSignalId = g_signal_connect(m_pWidget, "drag-motion", G_CALLBACK(signalDragMotion), this); + m_nDragDropSignalId = g_signal_connect(m_pWidget, "drag-drop", G_CALLBACK(signalDragDrop), this); + m_nDragDropReceivedSignalId = g_signal_connect(m_pWidget, "drag-data-received", G_CALLBACK(signalDragDropReceived), this); + m_nDragLeaveSignalId = g_signal_connect(m_pWidget, "drag-leave", G_CALLBACK(signalDragLeave), this); + } + return m_xDropTarget.get(); + } + virtual ~GtkInstanceWidget() override { + if (m_nDragMotionSignalId) + g_signal_handler_disconnect(m_pWidget, m_nDragMotionSignalId); + if (m_nDragDropSignalId) + g_signal_handler_disconnect(m_pWidget, m_nDragDropSignalId); + if (m_nDragDropReceivedSignalId) + g_signal_handler_disconnect(m_pWidget, m_nDragDropReceivedSignalId); + if (m_nDragLeaveSignalId) + g_signal_handler_disconnect(m_pWidget, m_nDragLeaveSignalId); if (m_nKeyPressSignalId) g_signal_handler_disconnect(m_pWidget, m_nKeyPressSignalId); if (m_nKeyReleaseSignalId) |