include/vcl/weld.hxx                     |    2 
 sw/source/ui/misc/bookmark.cxx           |  134 ++++++++++++++++++++-----------
 sw/source/uibase/inc/bookmark.hxx        |   23 +++--
 sw/uiconfig/swriter/ui/insertbookmark.ui |    5 +
 vcl/source/app/salvtables.cxx            |   13 +++
 vcl/unx/gtk3/gtk3gtkinst.cxx             |   21 ++++
 6 files changed, 146 insertions(+), 52 deletions(-)

New commits:
commit b6ca3a24f78f1deca2ad6d01d667f6a8db5a498c
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Thu Jun 20 20:59:00 2019 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri Jun 21 10:56:48 2019 +0200

    Resolves: tdf#126005 make bookmark treeview sortable
    
    and use iterators into the tree
    
    Change-Id: I38eb24d71cc089bf61baa221324a983c1eb782c9
    Reviewed-on: https://gerrit.libreoffice.org/74486
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    Tested-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 449190f7a92c..7393131fea14 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -877,6 +877,8 @@ public:
 
     virtual void set_selection_mode(SelectionMode eMode) = 0;
     virtual int count_selected_rows() const = 0;
+    // remove the selected nodes
+    virtual void remove_selection() = 0;
 
     void set_toggle_columns_as_radio(const std::vector<int>& rCols) { 
m_aRadioIndexes = rCols; }
 
diff --git a/sw/source/ui/misc/bookmark.cxx b/sw/source/ui/misc/bookmark.cxx
index 11144f55b703..089c34c9b68d 100644
--- a/sw/source/ui/misc/bookmark.cxx
+++ b/sw/source/ui/misc/bookmark.cxx
@@ -94,16 +94,12 @@ IMPL_LINK_NOARG(SwInsertBookmarkDlg, DeleteHdl, 
weld::Button&, void)
 {
     if (!ValidateBookmarks())
         return;
-    std::vector<int> aSelectedRows(m_xBookmarksBox->get_selected_rows());
-    if (aSelectedRows.empty())
-        return;
-    std::sort(aSelectedRows.begin(), aSelectedRows.end());
 
-    for (size_t i = aSelectedRows.size(); i; --i)
-    {
-        int nRow = aSelectedRows[i-1];
+    int nSelectedRows(0);
+
+    m_xBookmarksBox->selected_foreach([this, &nSelectedRows](weld::TreeIter& 
rEntry){
         // remove from model
-        sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(nRow).toInt64());
+        sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(rEntry).toInt64());
         OUString sRemoved = pBookmark->GetName();
         IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess();
         pMarkAccess->deleteMark(pMarkAccess->findMark(sRemoved));
@@ -112,11 +108,20 @@ IMPL_LINK_NOARG(SwInsertBookmarkDlg, DeleteHdl, 
weld::Button&, void)
         aReq.Done();
         aTableBookmarks.erase(std::remove(aTableBookmarks.begin(), 
aTableBookmarks.end(),
                               std::make_pair(pBookmark, sRemoved)), 
aTableBookmarks.end());
-        // remove from BookmarkTable
-        m_xBookmarksBox->remove(nRow);
-    }
-    m_xBookmarksBox->unselect_all();
-    m_xEditBox->set_text("");
+
+        ++nSelectedRows;
+
+        return false;
+    });
+
+    if (!nSelectedRows)
+        return;
+
+    // remove from BookmarkTable
+    m_xBookmarksBox->remove_selection();
+
+    ValidateBookmarks();
+
     m_xDeleteBtn->set_sensitive(false);
     m_xGotoBtn->set_sensitive(false);
     m_xRenameBtn->set_sensitive(false);
@@ -143,23 +148,21 @@ IMPL_LINK_NOARG(SwInsertBookmarkDlg, SelectionChangedHdl, 
weld::TreeView&, void)
         return;
 
     OUStringBuffer sEditBoxText;
-
-    std::vector<int> aSelectedRows(m_xBookmarksBox->get_selected_rows());
-    std::sort(aSelectedRows.begin(), aSelectedRows.end());
-    for (size_t i = aSelectedRows.size(); i; --i)
-    {
-        int nRow = aSelectedRows[i-1];
-        sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(nRow).toInt64());
+    int nSelectedRows = 0;
+    m_xBookmarksBox->selected_foreach([this, &sEditBoxText, 
&nSelectedRows](weld::TreeIter& rEntry){
+        sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(rEntry).toInt64());
         const OUString& sEntryName = pBookmark->GetName();
-        sEditBoxText.append(sEntryName);
-        if (i > 1)
+        if (!sEditBoxText.isEmpty())
             sEditBoxText.append(";");
-    }
-    if (!aSelectedRows.empty())
+        sEditBoxText.append(sEntryName);
+        ++nSelectedRows;
+        return false;
+    });
+    if (nSelectedRows)
     {
         m_xInsertBtn->set_sensitive(false);
-        m_xGotoBtn->set_sensitive(aSelectedRows.size() == 1);
-        m_xRenameBtn->set_sensitive(aSelectedRows.size() == 1);
+        m_xGotoBtn->set_sensitive(nSelectedRows == 1);
+        m_xRenameBtn->set_sensitive(nSelectedRows == 1);
         m_xDeleteBtn->set_sensitive(true);
         m_xEditBox->set_text(sEditBoxText.makeStringAndClear());
     }
@@ -176,11 +179,11 @@ IMPL_LINK_NOARG(SwInsertBookmarkDlg, RenameHdl, 
weld::Button&, void)
 {
     if (!ValidateBookmarks())
         return;
-    int nSelected = m_xBookmarksBox->get_selected_index();
-    if (nSelected == -1)
+    auto xSelected = m_xBookmarksBox->get_selected();
+    if (!xSelected)
         return;
 
-    sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(nSelected).toInt64());
+    sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(*xSelected).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();
@@ -228,11 +231,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
-    int nSelected = m_xBookmarksBox->get_selected_index();
-    if (nSelected == -1)
+    auto xSelected = m_xBookmarksBox->get_selected();
+    if (!xSelected)
         return;
 
-    sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(nSelected).toInt64());
+    sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xBookmarksBox->get_id(*xSelected).toInt64());
 
     rSh.EnterStdMode();
     rSh.GotoMark(pBookmark);
@@ -297,6 +300,7 @@ SwInsertBookmarkDlg::SwInsertBookmarkDlg(weld::Window* 
pParent, SwWrtShell& rS,
     , rSh(rS)
     , rReq(rRequest)
     , m_nLastBookmarksCount(0)
+    , m_bSorted(false)
     , m_xEditBox(m_xBuilder->weld_entry("name"))
     , m_xInsertBtn(m_xBuilder->weld_button("insert"))
     , m_xDeleteBtn(m_xBuilder->weld_button("delete"))
@@ -309,6 +313,7 @@ SwInsertBookmarkDlg::SwInsertBookmarkDlg(weld::Window* 
pParent, SwWrtShell& rS,
 {
     m_xBookmarksBox->connect_changed(LINK(this, SwInsertBookmarkDlg, 
SelectionChangedHdl));
     m_xBookmarksBox->connect_row_activated(LINK(this, SwInsertBookmarkDlg, 
DoubleClickHdl));
+    m_xBookmarksBox->connect_column_clicked(LINK(this, SwInsertBookmarkDlg, 
HeaderBarClick));
     m_xEditBox->connect_changed(LINK(this, SwInsertBookmarkDlg, ModifyHdl));
     m_xInsertBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, InsertHdl));
     m_xDeleteBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, DeleteHdl));
@@ -328,6 +333,35 @@ SwInsertBookmarkDlg::SwInsertBookmarkDlg(weld::Window* 
pParent, SwWrtShell& rS,
     sRemoveWarning = SwResId(STR_REMOVE_WARNING);
 }
 
+IMPL_LINK(SwInsertBookmarkDlg, HeaderBarClick, int, nColumn, void)
+{
+    if (!m_bSorted)
+    {
+        m_xBookmarksBox->make_sorted();
+        m_bSorted = true;
+    }
+
+    bool bSortAtoZ = m_xBookmarksBox->get_sort_order();
+
+    //set new arrow positions in headerbar
+    if (nColumn == m_xBookmarksBox->get_sort_column())
+    {
+        bSortAtoZ = !bSortAtoZ;
+        m_xBookmarksBox->set_sort_order(bSortAtoZ);
+    }
+    else
+    {
+        m_xBookmarksBox->set_sort_indicator(TRISTATE_INDET, 
m_xBookmarksBox->get_sort_column());
+        m_xBookmarksBox->set_sort_column(nColumn);
+    }
+
+    if (nColumn != -1)
+    {
+        //sort lists
+        m_xBookmarksBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : 
TRISTATE_FALSE, nColumn);
+    }
+}
+
 SwInsertBookmarkDlg::~SwInsertBookmarkDlg()
 {
 }
@@ -345,6 +379,14 @@ 
BookmarkTable::BookmarkTable(std::unique_ptr<weld::TreeView> xControl)
     m_xControl->set_selection_mode(SelectionMode::Multiple);
 }
 
+std::unique_ptr<weld::TreeIter> BookmarkTable::get_selected() const
+{
+    std::unique_ptr<weld::TreeIter> xIter(m_xControl->make_iterator());
+    if (!m_xControl->get_selected(xIter.get()))
+        xIter.reset();
+    return xIter;
+}
+
 void BookmarkTable::InsertBookmark(sw::mark::IMark* pMark)
 {
     sw::mark::IBookmark* pBookmark = dynamic_cast<sw::mark::IBookmark*>(pMark);
@@ -393,34 +435,36 @@ void BookmarkTable::InsertBookmark(sw::mark::IMark* pMark)
     m_xControl->set_text(nRow, sHideCondition, 4);
 }
 
-int BookmarkTable::GetRowByBookmarkName(const OUString& sName)
+std::unique_ptr<weld::TreeIter> BookmarkTable::GetRowByBookmarkName(const 
OUString& sName)
 {
-    for (int i = 0, nCount = m_xControl->n_children(); i < nCount; ++i)
-    {
-        sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xControl->get_id(i).toInt64());
+    std::unique_ptr<weld::TreeIter> xRet;
+    m_xControl->all_foreach([this, &sName, &xRet](weld::TreeIter& rEntry){
+        sw::mark::IMark* pBookmark = 
reinterpret_cast<sw::mark::IMark*>(m_xControl->get_id(rEntry).toInt64());
         if (pBookmark->GetName() == sName)
         {
-            return i;
+            xRet = m_xControl->make_iterator(&rEntry);
+            return true;
         }
-    }
-    return -1;
+        return false;
+    });
+    return xRet;
 }
 
 sw::mark::IMark* BookmarkTable::GetBookmarkByName(const OUString& sName)
 {
-    int nEntry = GetRowByBookmarkName(sName);
-    if (nEntry == -1)
+    auto xEntry = GetRowByBookmarkName(sName);
+    if (!xEntry)
         return nullptr;
 
-    return 
reinterpret_cast<sw::mark::IMark*>(m_xControl->get_id(nEntry).toInt64());
+    return 
reinterpret_cast<sw::mark::IMark*>(m_xControl->get_id(*xEntry).toInt64());
 }
 
 void BookmarkTable::SelectByName(const OUString& sName)
 {
-    int nEntry = GetRowByBookmarkName(sName);
-    if (nEntry == -1)
+    auto xEntry = GetRowByBookmarkName(sName);
+    if (!xEntry)
         return;
-    select(nEntry);
+    select(*xEntry);
 }
 
 OUString BookmarkTable::GetNameProposal()
diff --git a/sw/source/uibase/inc/bookmark.hxx 
b/sw/source/uibase/inc/bookmark.hxx
index 8dcc15d53eda..8f51602dbfbb 100644
--- a/sw/source/uibase/inc/bookmark.hxx
+++ b/sw/source/uibase/inc/bookmark.hxx
@@ -32,7 +32,7 @@ class SfxRequest;
 class BookmarkTable
 {
     std::unique_ptr<weld::TreeView> m_xControl;
-    int                 GetRowByBookmarkName(const OUString& sName);
+    std::unique_ptr<weld::TreeIter> GetRowByBookmarkName(const OUString& 
sName);
 public:
     BookmarkTable(std::unique_ptr<weld::TreeView> xControl);
     void                InsertBookmark(sw::mark::IMark* pMark);
@@ -42,16 +42,23 @@ public:
 
     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(); }
+    std::unique_ptr<weld::TreeIter> get_selected() const;
     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                remove(const weld::TreeIter& rIter) { 
m_xControl->remove(rIter); }
+    void                select(const weld::TreeIter& rIter) { 
m_xControl->select(rIter); }
+    void                remove_selection() { m_xControl->remove_selection(); }
+    OUString            get_id(const weld::TreeIter& rIter) const { return 
m_xControl->get_id(rIter); }
+    void set_sort_indicator(TriState eState, int nColumn = -1) { 
m_xControl->set_sort_indicator(eState, nColumn); }
+    void selected_foreach(const std::function<bool(weld::TreeIter&)>& func) { 
m_xControl->selected_foreach(func); }
 
     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); }
+    void connect_column_clicked(const Link<int, void>& rLink) { 
m_xControl->connect_column_clicked(rLink); }
+    void make_sorted() { m_xControl->make_sorted(); }
+    bool get_sort_order() const { return m_xControl->get_sort_order(); }
+    void set_sort_order(bool bAscending) { 
m_xControl->set_sort_order(bAscending); }
+    int get_sort_column() const { return m_xControl->get_sort_column(); }
+    void set_sort_column(int nColumn) { m_xControl->set_sort_column(nColumn); }
 
     static const OUString aForbiddenChars;
     static const char     cSeparator;
@@ -64,6 +71,7 @@ class SwInsertBookmarkDlg : public SfxDialogController
     SfxRequest&                         rReq;
     std::vector<std::pair<sw::mark::IMark*, OUString>> aTableBookmarks;
     sal_Int32                           m_nLastBookmarksCount;
+    bool                                m_bSorted;
 
     std::unique_ptr<weld::Entry> m_xEditBox;
     std::unique_ptr<weld::Button> m_xInsertBtn;
@@ -82,6 +90,7 @@ class SwInsertBookmarkDlg : public SfxDialogController
     DECL_LINK(GotoHdl, weld::Button&, void);
     DECL_LINK(SelectionChangedHdl, weld::TreeView&, void);
     DECL_LINK(DoubleClickHdl, weld::TreeView&, void);
+    DECL_LINK(HeaderBarClick, int, void);
     DECL_LINK(ChangeHideHdl, weld::ToggleButton&, void);
 
     // Fill table with bookmarks
diff --git a/sw/uiconfig/swriter/ui/insertbookmark.ui 
b/sw/uiconfig/swriter/ui/insertbookmark.ui
index 0aa5af987570..bc9c3896f1d3 100644
--- a/sw/uiconfig/swriter/ui/insertbookmark.ui
+++ b/sw/uiconfig/swriter/ui/insertbookmark.ui
@@ -196,6 +196,7 @@
                     <property name="resizable">True</property>
                     <property name="spacing">6</property>
                     <property name="title" translatable="yes" 
context="insertbookmark|page">Page</property>
+                    <property name="clickable">True</property>
                     <child>
                       <object class="GtkCellRendererText" id="cellrenderer0"/>
                       <attributes>
@@ -209,6 +210,7 @@
                     <property name="resizable">True</property>
                     <property name="spacing">6</property>
                     <property name="title" translatable="yes" 
context="insertbookmark|name">Name</property>
+                    <property name="clickable">True</property>
                     <child>
                       <object class="GtkCellRendererText" id="cellrenderer1"/>
                       <attributes>
@@ -222,6 +224,7 @@
                     <property name="resizable">True</property>
                     <property name="spacing">6</property>
                     <property name="title" translatable="yes" 
context="insertbookmark|text">Text</property>
+                    <property name="clickable">True</property>
                     <child>
                       <object class="GtkCellRendererText" id="cellrenderer2"/>
                       <attributes>
@@ -235,6 +238,7 @@
                     <property name="resizable">True</property>
                     <property name="spacing">6</property>
                     <property name="title" translatable="yes" 
context="insertbookmark|hidden">Hidden</property>
+                    <property name="clickable">True</property>
                     <child>
                       <object class="GtkCellRendererText" id="cellrenderer3"/>
                       <attributes>
@@ -248,6 +252,7 @@
                     <property name="resizable">True</property>
                     <property name="spacing">6</property>
                     <property name="title" translatable="yes" 
context="insertbookmark|condition">Condition</property>
+                    <property name="clickable">True</property>
                     <child>
                       <object class="GtkCellRendererText" id="cellrenderer4"/>
                       <attributes>
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index d001efdd1db3..1330b125320f 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -3590,6 +3590,19 @@ public:
         m_xTreeView->SetScrolledHdl(LINK(this, SalInstanceTreeView, 
VisibleRangeChangedHdl));
     }
 
+    virtual void remove_selection() override
+    {
+        disable_notify_events();
+        SvTreeListEntry* pSelected = m_xTreeView->FirstSelected();
+        while (pSelected)
+        {
+            SvTreeListEntry* pNextSelected = 
m_xTreeView->NextSelected(pSelected);
+            m_xTreeView->RemoveEntry(pSelected);
+            pSelected = pNextSelected;
+        }
+        enable_notify_events();
+    }
+
     virtual bool is_selected(const weld::TreeIter& rIter) const override
     {
         const SalInstanceTreeIter& rVclIter = static_cast<const 
SalInstanceTreeIter&>(rIter);
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 22a29bb875dd..764cb78a30ff 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -7705,6 +7705,27 @@ public:
         enable_notify_events();
     }
 
+    virtual void remove_selection() override
+    {
+        disable_notify_events();
+
+        std::vector<GtkTreeIter> aIters;
+        GtkTreeModel* pModel;
+        GList* pList = 
gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(m_pTreeView), 
&pModel);
+        for (GList* pItem = g_list_first(pList); pItem; pItem = 
g_list_next(pItem))
+        {
+            GtkTreePath* path = static_cast<GtkTreePath*>(pItem->data);
+            aIters.emplace_back();
+            gtk_tree_model_get_iter(pModel, &aIters.back(), path);
+        }
+        g_list_free_full(pList, 
reinterpret_cast<GDestroyNotify>(gtk_tree_path_free));
+
+        for (auto& iter : aIters)
+            gtk_tree_store_remove(m_pTreeStore, &iter);
+
+        enable_notify_events();
+    }
+
     virtual void select(const weld::TreeIter& rIter) override
     {
         assert(gtk_tree_view_get_model(m_pTreeView) && "don't select when 
frozen");
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to