diff --git a/src/calls-call-record-row.c b/src/calls-call-record-row.c
index 3e0495e..2bd3731 100644
--- a/src/calls-call-record-row.c
+++ b/src/calls-call-record-row.c
@@ -44,6 +44,13 @@ struct _CallsCallRecordRow
GtkLabel *target;
GtkLabel *time;
GtkButton *button;
+ GtkPopover *popover;
+ GtkGesture *gesture;
+ GtkEventBox *event_box;
+
+ GMenu *context_menu;
+
+ GActionMap *action_map;
CallsCallRecord *record;
gulong answered_notify_handler_id;
@@ -392,6 +399,45 @@ setup_contact (CallsCallRecordRow *self)
}
+static void
+context_menu (GtkWidget *self,
+ GdkEvent *event)
+{
+ gtk_popover_popup (CALLS_CALL_RECORD_ROW (self)->popover);
+}
+
+
+static gboolean
+calls_call_record_row_popup_menu (GtkWidget *self)
+{
+ context_menu (self, NULL);
+ return TRUE;
+}
+
+
+static void
+long_pressed (GtkGestureLongPress *gesture,
+ gdouble x,
+ gdouble y,
+ GtkWidget *self)
+{
+ context_menu (self, NULL);
+}
+
+
+static gboolean
+calls_call_record_row_button_press_event (GtkWidget *self,
+ GdkEventButton *event)
+{
+ if (gdk_event_triggers_context_menu ((GdkEvent *) event))
+ {
+ context_menu (self, (GdkEvent *) event);
+ return TRUE;
+ }
+ return GTK_WIDGET_CLASS (calls_call_record_row_parent_class)->button_press_event (self, event);
+}
+
+
static void
set_property (GObject *object,
guint property_id,
@@ -480,6 +526,8 @@ dispose (GObject *object)
g_clear_object (&self->contact);
g_clear_object (&self->contacts);
+ g_clear_object (&self->action_map);
+ g_clear_object (&self->gesture);
calls_clear_source (&self->date_change_timeout);
calls_clear_signal (self->record, &self->answered_notify_handler_id);
@@ -501,6 +549,9 @@ calls_call_record_row_class_init (CallsCallRecordRowClass *klass)
object_class->get_property = get_property;
object_class->dispose = dispose;
+ widget_class->popup_menu = calls_call_record_row_popup_menu;
+ widget_class->button_press_event = calls_call_record_row_button_press_event;
+
props[PROP_RECORD] =
g_param_spec_object ("record",
"Record",
@@ -524,18 +575,59 @@ calls_call_record_row_class_init (CallsCallRecordRowClass *klass)
gtk_widget_class_bind_template_child (widget_class, CallsCallRecordRow, target);
gtk_widget_class_bind_template_child (widget_class, CallsCallRecordRow, time);
gtk_widget_class_bind_template_child (widget_class, CallsCallRecordRow, button);
+
+ gtk_widget_class_bind_template_child (widget_class, CallsCallRecordRow, event_box);
+ gtk_widget_class_bind_template_child (widget_class, CallsCallRecordRow, popover);
+ gtk_widget_class_bind_template_child (widget_class, CallsCallRecordRow, context_menu);
}
+static void
+delete_call_activated (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer data)
+{
+ GtkWidget *self = GTK_WIDGET (data);
+ g_signal_emit_by_name (CALLS_CALL_RECORD_ROW (self)->record, "call-delete");
+}
+
+
+static GActionEntry entries[] =
+{
+ { "delete-call", delete_call_activated, NULL, NULL, NULL},
+};
+
+
static void
calls_call_record_row_init (CallsCallRecordRow *self)
{
+ GAction *act;
gtk_widget_init_template (GTK_WIDGET (self));
g_signal_connect (self->avatar,
"notify::text",
G_CALLBACK (avatar_text_changed_cb),
NULL);
+
+ self->action_map = G_ACTION_MAP (g_simple_action_group_new ());
+ g_action_map_add_action_entries (self->action_map,
+ entries,
+ G_N_ELEMENTS (entries),
+ self);
+ gtk_widget_insert_action_group (GTK_WIDGET (self),
+ "row-history",
+ G_ACTION_GROUP (self->action_map));
+
+ act = g_action_map_lookup_action (self->action_map, "delete-call");
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (act), TRUE);
+
+ self->gesture = gtk_gesture_long_press_new (GTK_WIDGET (self->event_box));
+ gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (self->gesture), TRUE);
+ g_signal_connect (self->gesture, "pressed", G_CALLBACK (long_pressed), self);
+
+ gtk_popover_bind_model (self->popover,
+ G_MENU_MODEL (self->context_menu),
+ "row-history");
}
diff --git a/src/calls-call-record.c b/src/calls-call-record.c
index d9d904f..7ca5dc5 100644
--- a/src/calls-call-record.c
+++ b/src/calls-call-record.c
@@ -55,6 +55,12 @@ enum {
};
static GParamSpec *props[PROP_LAST_PROP];
+enum {
+ SIGNAL_CALL_DELETE,
+ SIGNAL_LAST_SIGNAL,
+};
+static guint signals [SIGNAL_LAST_SIGNAL];
+
static void
get_property (GObject *object,
@@ -167,6 +173,15 @@ calls_call_record_class_init (CallsCallRecordClass *klass)
object_class->get_property = get_property;
object_class->set_property = set_property;
+ signals[SIGNAL_CALL_DELETE] =
+ g_signal_new ("call-delete",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 0, NULL);
+
gom_resource_class_set_table (resource_class, "calls");
diff --git a/src/calls-history-box.c b/src/calls-history-box.c
index 85569e0..4d6bac6 100644
--- a/src/calls-history-box.c
+++ b/src/calls-history-box.c
@@ -102,13 +102,51 @@ header_cb (GtkListBoxRow *row,
}
}
+static void
+delete_call_cb (CallsCallRecord *record,
+ CallsHistoryBox *self)
+{
+ guint position;
+ guint id;
+ gboolean ok;
+
+ g_return_if_fail (CALLS_IS_CALL_RECORD (record));
+
+ ok = calls_find_in_store (self->model,
+ record,
+ &position);
+
+ g_object_get (G_OBJECT (record),
+ "id",
+ &id,
+ NULL);
+
+ if (!ok)
+ {
+ g_warning ("Could not find record with id %u in model",
+ id);
+ return;
+ }
+
+ g_list_store_remove ((GListStore *) self->model, position);
+
+ update(self);
+}
+
static GtkWidget *
create_row_cb (CallsCallRecord *record,
CallsHistoryBox *self)
{
- return GTK_WIDGET (calls_call_record_row_new (record,
- self->contacts));
+ GtkWidget *row_widget;
+ row_widget = GTK_WIDGET (calls_call_record_row_new (record,
+ self->contacts));
+
+ g_signal_connect (record,
+ "call-delete",
+ G_CALLBACK (delete_call_cb),
+ self);
+ return row_widget;
}
diff --git a/src/calls-record-store.c b/src/calls-record-store.c
index d9e5e3d..d8bd93f 100644
--- a/src/calls-record-store.c
+++ b/src/calls-record-store.c
@@ -81,6 +81,56 @@ struct _CallsRecordStore
G_DEFINE_TYPE (CallsRecordStore, calls_record_store, G_TYPE_LIST_STORE);
+static void
+delete_record_cb (GomResource *resource,
+ GAsyncResult *res,
+ CallsRecordStore *self)
+{
+ g_autoptr (GError) error = NULL;
+ gboolean ok;
+ guint id;
+
+ ok = gom_resource_delete_finish (resource,
+ res,
+ &error);
+
+ g_object_get (G_OBJECT (resource),
+ "id",
+ &id,
+ NULL);
+
+ if (!ok)
+ {
+ if (error)
+ {
+ g_warning ("Error deleting call record with id %u from database %s",
+ id, error->message);
+ return;
+ }
+ else
+ {
+ g_warning ("Unknown error deleting call record with id %u from database",
+ id);
+ }
+ }
+ else {
+ g_debug ("Successfully deleted call record with id %u from database",
+ id);
+ }
+
+}
+
+
+static void
+delete_call_cb (CallsCallRecord *record,
+ CallsRecordStore *self)
+{
+ gom_resource_delete_async (GOM_RESOURCE (record),
+ (GAsyncReadyCallback) delete_record_cb,
+ self);
+}
+
+
static void
load_calls_fetch_cb (GomResourceGroup *group,
GAsyncResult *res,
@@ -127,6 +177,11 @@ load_calls_fetch_cb (GomResourceGroup *group,
{
g_date_time_unref (end);
}
+
+ g_signal_connect (record,
+ "call-delete",
+ G_CALLBACK (delete_call_cb),
+ self);
}
g_list_store_splice (G_LIST_STORE (self),
diff --git a/src/ui/call-record-row.ui b/src/ui/call-record-row.ui
index 484a11e..6ac37aa 100644
--- a/src/ui/call-record-row.ui
+++ b/src/ui/call-record-row.ui
@@ -8,94 +8,110 @@
False
False
-