gnome: add contact/history sorting
Refs #73115
Change-Id: I7fee71c7ef330c705a010ed1aa75ff1ec1b6d426
diff --git a/src/contactsview.cpp b/src/contactsview.cpp
index 4414a8a..8b0f93e 100644
--- a/src/contactsview.cpp
+++ b/src/contactsview.cpp
@@ -32,7 +32,6 @@
#include <gtk/gtk.h>
#include "models/gtkqsortfiltertreemodel.h"
-#include "models/activeitemproxymodel.h"
#include <categorizedcontactmodel.h>
#include <personmodel.h>
#include "utils/calling.h"
@@ -41,6 +40,7 @@
#include <contactmethod.h>
#include "defines.h"
#include "utils/models.h"
+#include <QtCore/QItemSelectionModel>
#define COPY_DATA_KEY "copy_data"
@@ -58,7 +58,7 @@
struct _ContactsViewPrivate
{
- ActiveItemProxyModel *q_contact_model;
+ CategorizedContactModel::SortedProxy *q_sorted_proxy;
};
G_DEFINE_TYPE_WITH_PRIVATE(ContactsView, contacts_view, GTK_TYPE_BOX);
@@ -351,15 +351,20 @@
* otherwise the search steals input focus on key presses */
gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview_contacts), FALSE);
+ /* initial set up to be categorized by name and sorted alphabetically */
+ priv->q_sorted_proxy = CategorizedContactModel::SortedProxy::instance();
CategorizedContactModel::instance()->setUnreachableHidden(true);
- priv->q_contact_model = new ActiveItemProxyModel(CategorizedContactModel::instance());
- priv->q_contact_model->setSortRole(Qt::DisplayRole);
- priv->q_contact_model->setSortLocaleAware(true);
- priv->q_contact_model->setSortCaseSensitivity(Qt::CaseInsensitive);
- priv->q_contact_model->sort(0);
+
+ /* for now we always want to sort by ascending order */
+ priv->q_sorted_proxy->model()->sort(0);
+
+ /* select default category (the first one, which is by name) */
+ priv->q_sorted_proxy->categorySelectionModel()->setCurrentIndex(
+ priv->q_sorted_proxy->categoryModel()->index(0, 0),
+ QItemSelectionModel::ClearAndSelect);
GtkQSortFilterTreeModel *contact_model = gtk_q_sort_filter_tree_model_new(
- (QSortFilterProxyModel *)priv->q_contact_model,
+ priv->q_sorted_proxy->model(),
1,
Qt::DisplayRole, G_TYPE_STRING);
gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_contacts), GTK_TREE_MODEL(contact_model));
@@ -413,11 +418,6 @@
static void
contacts_view_finalize(GObject *object)
{
- ContactsView *self = CONTACTS_VIEW(object);
- ContactsViewPrivate *priv = CONTACTS_VIEW_GET_PRIVATE(self);
-
- delete priv->q_contact_model;
-
G_OBJECT_CLASS(contacts_view_parent_class)->finalize(object);
}
@@ -434,4 +434,4 @@
gpointer self = g_object_new(CONTACTS_VIEW_TYPE, NULL);
return (GtkWidget *)self;
-}
\ No newline at end of file
+}
diff --git a/src/contactsview.h b/src/contactsview.h
index df0c0ae..43c097d 100644
--- a/src/contactsview.h
+++ b/src/contactsview.h
@@ -44,8 +44,9 @@
typedef struct _ContactsView ContactsView;
typedef struct _ContactsViewClass ContactsViewClass;
-GType contacts_view_get_type (void) G_GNUC_CONST;
-GtkWidget *contacts_view_new (void);
+GType contacts_view_get_type (void) G_GNUC_CONST;
+GtkWidget *contacts_view_new (void);
+// void contact_view_set_sorting(ContactsView *self, int sort);
G_END_DECLS
diff --git a/src/historyview.cpp b/src/historyview.cpp
index f28b762..4ee3e43 100644
--- a/src/historyview.cpp
+++ b/src/historyview.cpp
@@ -42,6 +42,7 @@
#include "utils/models.h"
#include <contactmethod.h>
#include <QtCore/QDateTime> // for date time formatting
+#include <QtCore/QItemSelectionModel>
struct _HistoryView
{
@@ -57,7 +58,8 @@
struct _HistoryViewPrivate
{
- QSortFilterProxyModel *q_history_model;
+ CategorizedHistoryModel::SortedProxy *q_sorted_proxy;
+ QMetaObject::Connection category_changed;
};
G_DEFINE_TYPE_WITH_PRIVATE(HistoryView, history_view, GTK_TYPE_BOX);
@@ -195,16 +197,6 @@
}
static void
-expand_if_child(G_GNUC_UNUSED GtkTreeModel *tree_model,
- GtkTreePath *path,
- G_GNUC_UNUSED GtkTreeIter *iter,
- GtkTreeView *treeview)
-{
- if (gtk_tree_path_get_depth(path) == 2)
- gtk_tree_view_expand_to_path(treeview, path);
-}
-
-static void
render_call_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
@@ -353,14 +345,35 @@
* otherwise the search steals input focus on key presses */
gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview_history), FALSE);
- /* sort the history in descending order by date */
- priv->q_history_model = new QSortFilterProxyModel();
- priv->q_history_model->setSourceModel(CategorizedHistoryModel::instance());
- priv->q_history_model->setSortRole(static_cast<int>(Call::Role::Date));
- priv->q_history_model->sort(0,Qt::DescendingOrder);
+ /* instantiate history proxy model */
+ priv->q_sorted_proxy = CategorizedHistoryModel::SortedProxy::instance();
+
+ /* for now there is no way in the UI to pick whether sorting is ascending
+ * or descending, so we do it in the code when the category changes */
+ priv->category_changed = QObject::connect(
+ priv->q_sorted_proxy->categorySelectionModel(),
+ &QItemSelectionModel::currentChanged,
+ [=] (const QModelIndex ¤t, G_GNUC_UNUSED const QModelIndex &previous)
+ {
+ if (current.isValid()) {
+ if (current.row() == 0) {
+ /* sort in descending order for the date */
+ priv->q_sorted_proxy->model()->sort(0, Qt::DescendingOrder);
+ } else {
+ /* ascending order for verything else */
+ priv->q_sorted_proxy->model()->sort(0);
+ }
+ }
+ }
+ );
+
+ /* select default category (the first one, which is by date) */
+ priv->q_sorted_proxy->categorySelectionModel()->setCurrentIndex(
+ priv->q_sorted_proxy->categoryModel()->index(0, 0),
+ QItemSelectionModel::ClearAndSelect);
GtkQSortFilterTreeModel *history_model = gtk_q_sort_filter_tree_model_new(
- priv->q_history_model,
+ priv->q_sorted_proxy->model(),
5,
Qt::DisplayRole, G_TYPE_STRING,
Call::Role::Number, G_TYPE_STRING,
@@ -444,14 +457,8 @@
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_history), column);
gtk_tree_view_column_set_resizable(column, TRUE);
- /* expand the first row, which should be the most recent calls */
- gtk_tree_view_expand_row(GTK_TREE_VIEW(treeview_history),
- gtk_tree_path_new_from_string("0"),
- FALSE);
-
g_signal_connect(treeview_history, "row-activated", G_CALLBACK(activate_history_item), NULL);
g_signal_connect(treeview_history, "button-press-event", G_CALLBACK(history_popup_menu), treeview_history);
- g_signal_connect(history_model, "row-inserted", G_CALLBACK(expand_if_child), treeview_history);
gtk_widget_show_all(GTK_WIDGET(self));
}
@@ -459,17 +466,16 @@
static void
history_view_dispose(GObject *object)
{
+ HistoryViewPrivate *priv = HISTORY_VIEW_GET_PRIVATE(object);
+
+ QObject::disconnect(priv->category_changed);
+
G_OBJECT_CLASS(history_view_parent_class)->dispose(object);
}
static void
history_view_finalize(GObject *object)
{
- HistoryView *self = HISTORY_VIEW(object);
- HistoryViewPrivate *priv = HISTORY_VIEW_GET_PRIVATE(self);
-
- delete priv->q_history_model;
-
G_OBJECT_CLASS(history_view_parent_class)->finalize(object);
}
@@ -486,4 +492,4 @@
gpointer self = g_object_new(HISTORY_VIEW_TYPE, NULL);
return (GtkWidget *)self;
-}
\ No newline at end of file
+}
diff --git a/src/ringmainwindow.cpp b/src/ringmainwindow.cpp
index d1acd36..7d6b314 100644
--- a/src/ringmainwindow.cpp
+++ b/src/ringmainwindow.cpp
@@ -56,6 +56,7 @@
#include "utils/calling.h"
#include "frequentcontactsview.h"
#include "contactsview.h"
+#include <categorizedcontactmodel.h>
#include "historyview.h"
#include "utils/models.h"
#include "generalsettingsview.h"
@@ -97,6 +98,8 @@
GtkWidget *radiobutton_contacts;
GtkWidget *radiobutton_history;
GtkWidget *radiobutton_presence;
+ GtkWidget *combobox_history_sort;
+ GtkWidget *combobox_contacts_sort;
GtkWidget *vbox_left_pane;
GtkWidget *vbox_contacts;
GtkWidget *search_entry;
@@ -327,6 +330,10 @@
(GSourceFunc)grab_focus_on_widget,
gtk_stack_get_visible_child(GTK_STACK(priv->stack_contacts_history_presence)),
NULL);
+
+ /* show the correct sorting combobox */
+ gtk_widget_show(priv->combobox_contacts_sort);
+ gtk_widget_hide(priv->combobox_history_sort);
}
static void
@@ -346,6 +353,10 @@
(GSourceFunc)grab_focus_on_widget,
gtk_stack_get_visible_child(GTK_STACK(priv->stack_contacts_history_presence)),
NULL);
+
+ /* show the correct sorting combobox */
+ gtk_widget_hide(priv->combobox_contacts_sort);
+ gtk_widget_hide(priv->combobox_history_sort);
}
static void
@@ -365,6 +376,10 @@
(GSourceFunc)grab_focus_on_widget,
gtk_stack_get_visible_child(GTK_STACK(priv->stack_contacts_history_presence)),
NULL);
+
+ /* show the correct sorting combobox */
+ gtk_widget_hide(priv->combobox_contacts_sort);
+ gtk_widget_show(priv->combobox_history_sort);
}
static gboolean
@@ -994,12 +1009,18 @@
gtk_stack_add_named(GTK_STACK(priv->stack_contacts_history_presence),
contacts_view,
VIEW_CONTACTS);
+ gtk_combo_box_set_qmodel(GTK_COMBO_BOX(priv->combobox_contacts_sort),
+ (QAbstractItemModel *)CategorizedContactModel::SortedProxy::instance()->categoryModel(),
+ CategorizedContactModel::SortedProxy::instance()->categorySelectionModel());
/* history view */
GtkWidget *history_view = history_view_new();
gtk_stack_add_named(GTK_STACK(priv->stack_contacts_history_presence),
history_view,
VIEW_HISTORY);
+ gtk_combo_box_set_qmodel(GTK_COMBO_BOX(priv->combobox_history_sort),
+ (QAbstractItemModel *)CategorizedHistoryModel::SortedProxy::instance()->categoryModel(),
+ CategorizedHistoryModel::SortedProxy::instance()->categorySelectionModel());
/* presence view/model */
GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
@@ -1018,6 +1039,8 @@
/* TODO: make this linked to the client settings so that the last shown view is the same on startup */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->radiobutton_contacts), TRUE);
+ gtk_widget_show(priv->combobox_contacts_sort);
+ gtk_widget_hide(priv->combobox_history_sort);
/* TODO: replace stack paceholder view */
GtkWidget *placeholder_view = gtk_tree_view_new();
@@ -1177,6 +1200,8 @@
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, radiobutton_contacts);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, radiobutton_history);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, radiobutton_presence);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, combobox_history_sort);
+ gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, combobox_contacts_sort);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, ring_menu);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, image_ring);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, ring_settings);
diff --git a/src/utils/models.cpp b/src/utils/models.cpp
index 59da48e..f6d6d31 100644
--- a/src/utils/models.cpp
+++ b/src/utils/models.cpp
@@ -181,11 +181,14 @@
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(box), renderer,
"text", 0, NULL);
+ /* sync the initial selection */
+ gtk_combo_box_set_active_index(box, selection_model->currentIndex());
+
/* connect signals to and from the selection model */
connection = QObject::connect(
selection_model,
&QItemSelectionModel::currentChanged,
- [=](const QModelIndex & current, G_GNUC_UNUSED const QModelIndex & previous) {
+ [=](const QModelIndex current, G_GNUC_UNUSED const QModelIndex & previous) {
gtk_combo_box_set_active_index(box, current);
}
);
@@ -194,8 +197,5 @@
G_CALLBACK(update_selection),
selection_model);
- /* sync the initial selection */
- gtk_combo_box_set_active_index(box, selection_model->currentIndex());
-
return connection;
-}
\ No newline at end of file
+}
diff --git a/ui/ringmainwindow.ui b/ui/ringmainwindow.ui
index 3d07d83..cdc2d4a 100644
--- a/ui/ringmainwindow.ui
+++ b/ui/ringmainwindow.ui
@@ -211,15 +211,14 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
- <property name="homogeneous">True</property>
<property name="margin-top">5</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkRadioButton" id="radiobutton_contacts">
- <property name="label" translatable="yes">contacts</property>
- <!-- TODO: make visible when feature ready -->
+ <property name="label" translatable="yes">Contacts</property>
+ <property name="tooltip-text">Contacts</property>
<property name="visible">True</property>
<property name="image">image_contacts</property>
<property name="draw_indicator">False</property>
@@ -228,7 +227,8 @@
</child>
<child>
<object class="GtkRadioButton" id="radiobutton_history">
- <property name="label" translatable="yes">history</property>
+ <property name="label" translatable="yes">History</property>
+ <property name="tooltip-text">History</property>
<property name="visible">True</property>
<property name="image">image_history</property>
<property name="draw_indicator">False</property>
@@ -238,7 +238,8 @@
</child>
<child>
<object class="GtkRadioButton" id="radiobutton_presence">
- <property name="label" translatable="yes">online</property>
+<!-- <property name="label" translatable="yes">online</property> -->
+ <property name="tooltip-text">Presence</property>
<!-- TODO: make visible when feature ready -->
<property name="visible">False</property>
<property name="image">image_presence</property>
@@ -247,6 +248,26 @@
</object>
<packing></packing>
</child>
+ <child>
+ <object class="GtkComboBox" id="combobox_history_sort">
+ <!-- set to visible when showing history view -->
+ <property name="visible">False</property>
+ <property name="can_focus">True</property>
+ <!-- TODO: save the selected sorting in settings -->
+ <property name="active">0</property>
+ </object>
+ <packing></packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox_contacts_sort">
+ <!-- set to visible when showing contacts view -->
+ <property name="visible">False</property>
+ <property name="can_focus">True</property>
+ <!-- TODO: save the selected sorting in settings -->
+ <property name="active">0</property>
+ </object>
+ <packing></packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>