From 6a1ce14da10db5687adff3175cf293dc89404a91 Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Thu, 30 Aug 2018 10:09:53 +0200 Subject: [PATCH 01/12] meson: Add config.h This will be used to factorize project-related information like APP_ID. --- meson.build | 1 + src/meson.build | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/meson.build b/meson.build index c6ce587..b052571 100644 --- a/meson.build +++ b/meson.build @@ -26,6 +26,7 @@ project('call', 'c', default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ], ) +calls_id = 'sm.puri.Calls' subdir('libgdbofono') subdir('src') diff --git a/src/meson.build b/src/meson.build index 2a215b1..8c3d966 100644 --- a/src/meson.build +++ b/src/meson.build @@ -57,6 +57,20 @@ calls_dummy_sources = ['calls-dummy-call.c', 'calls-dummy-call.h', 'calls-dummy-provider.c', 'calls-dummy-provider.h', ] +config_data = configuration_data() +config_data.set_quoted('APP_ID', calls_id) + +config_h_in = configure_file( + output: 'config.h.in', + configuration: config_data +) + +config_h = vcs_tag( + fallback: '', + input: config_h_in, + output: 'config.h', +) + calls_enum_headers = ['calls-call.h'] calls_enum_sources = gnome.mkenums_simple('enum-types', sources : calls_enum_headers) From bc6295f5fefc1339978b6776f0dfb01444fa2717 Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Thu, 30 Aug 2018 10:26:00 +0200 Subject: [PATCH 02/12] main: Use APP_ID from config.h --- src/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 0dc5d0e..a283d4d 100644 --- a/src/main.c +++ b/src/main.c @@ -32,8 +32,7 @@ #include "calls-main-window.h" #include "calls-mm-provider.h" #include "calls-new-call-box.h" - -#define APP_ID "sm.puri.Calls" +#include "config.h" static void show_window (GtkApplication *app) From 7e2a1f376af44f7d86e1aa8d4031f1badb12e2bc Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Wed, 1 Aug 2018 12:57:40 +0200 Subject: [PATCH 03/12] main-window: Add the 'call-added' and 'call-removed' signals These will be used in the next commit to notify of added and removed, which will be needed to display the calls in a secondary window. --- src/calls-main-window.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/calls-main-window.c b/src/calls-main-window.c index ee1de9a..8bebe25 100644 --- a/src/calls-main-window.c +++ b/src/calls-main-window.c @@ -71,6 +71,14 @@ enum { static GParamSpec *props[PROP_LAST_PROP]; +enum { + SIGNAL_CALL_ADDED, + SIGNAL_CALL_REMOVED, + SIGNAL_LAST_SIGNAL, +}; +static guint signals [SIGNAL_LAST_SIGNAL]; + + CallsMainWindow * calls_main_window_new (GtkApplication *application, CallsProvider *provider) { @@ -262,6 +270,8 @@ add_call (CallsMainWindow *self, CallsCall *call) CallsCallHolder *holder; CallsCallDisplay *display; + g_signal_emit (self, signals[SIGNAL_CALL_ADDED], 0, call); + g_signal_connect_swapped (call, "message", G_CALLBACK (show_message), self); @@ -309,6 +319,8 @@ remove_call (CallsMainWindow *self, CallsCall *call, const gchar *reason) g_return_if_fail (CALLS_IS_MAIN_WINDOW (self)); g_return_if_fail (CALLS_IS_CALL (call)); + g_signal_emit (self, signals[SIGNAL_CALL_REMOVED], 0, call, reason); + found = find_call_holder (self, &n_items, &position, &holder, find_call_holder_by_call, call); g_return_if_fail (found); @@ -566,6 +578,28 @@ calls_main_window_class_init (CallsMainWindowClass *klass) g_object_class_install_properties (object_class, PROP_LAST_PROP, props); + signals[SIGNAL_CALL_ADDED] = + g_signal_new ("call-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 1, + CALLS_TYPE_CALL); + + signals[SIGNAL_CALL_REMOVED] = + g_signal_new ("call-removed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 2, + CALLS_TYPE_CALL, + G_TYPE_STRING); + + gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/calls/ui/main-window.ui"); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, info); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, info_label); From b547c344e57c5476c9fd7ceabe0e35790cecf06a Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Wed, 1 Aug 2018 12:51:55 +0200 Subject: [PATCH 04/12] Add CallsCallWindow --- src/calls-call-window.c | 393 +++++++++++++++++++++++++++++++++++++++ src/calls-call-window.h | 46 +++++ src/calls.gresources.xml | 1 + src/meson.build | 1 + src/ui/call-window.ui | 153 +++++++++++++++ 5 files changed, 594 insertions(+) create mode 100644 src/calls-call-window.c create mode 100644 src/calls-call-window.h create mode 100644 src/ui/call-window.ui diff --git a/src/calls-call-window.c b/src/calls-call-window.c new file mode 100644 index 0000000..36652e0 --- /dev/null +++ b/src/calls-call-window.c @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calls is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calls. If not, see . + * + * Authors: + * Bob Ham + * Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "calls-call-window.h" +#include "calls-origin.h" +#include "calls-call-holder.h" +#include "calls-call-selector-item.h" +#include "calls-new-call-box.h" +#include "util.h" + +#include +#include + +#define HANDY_USE_UNSTABLE_API +#include + + +struct _CallsCallWindow +{ + GtkApplicationWindow parent_instance; + + GListStore *call_holders; + CallsCallHolder *focus; + + GtkInfoBar *info; + GtkLabel *info_label; + + GtkStack *main_stack; + GtkStack *header_bar_stack; + GtkButton *show_calls; + GtkStack *call_stack; + GtkFlowBox *call_selector; +}; + +enum { + ORIGIN_STORE_COLUMN_NAME, + ORIGIN_STORE_COLUMN_ORIGIN +}; + +G_DEFINE_TYPE (CallsCallWindow, calls_call_window, GTK_TYPE_APPLICATION_WINDOW); + + +CallsCallWindow * +calls_call_window_new (GtkApplication *application) +{ + return g_object_new (CALLS_TYPE_CALL_WINDOW, + "application", application, + NULL); +} + + +static void +update_visibility (CallsCallWindow *self) +{ + guint calls = g_list_model_get_n_items (G_LIST_MODEL (self->call_holders)); + + gtk_widget_set_visible (GTK_WIDGET (self), calls > 0); + gtk_widget_set_sensitive (GTK_WIDGET (self->show_calls), calls > 1); + + if (calls == 0) + { + gtk_stack_set_visible_child_name (self->main_stack, "calls"); + } + else if (calls == 1) + { + gtk_stack_set_visible_child_name (self->main_stack, "active-call"); + } +} + + +static void +show_message (CallsCallWindow *self, + const gchar *text, + GtkMessageType type) +{ + gtk_info_bar_set_message_type (self->info, type); + gtk_label_set_text (self->info_label, text); + gtk_widget_show (GTK_WIDGET (self->info)); + gtk_widget_queue_allocate (GTK_WIDGET (self)); +} + + +static void +info_response_cb (GtkInfoBar *infobar, + gint response_id, + CallsCallWindow *self) +{ + gtk_widget_hide (GTK_WIDGET (self->info)); + gtk_widget_queue_allocate (GTK_WIDGET (self)); +} + + +static GtkWidget * +call_holders_create_widget_cb (CallsCallHolder *holder, + CallsCallWindow *self) +{ + return GTK_WIDGET (calls_call_holder_get_selector_item (holder)); +} + + +static void +new_call_submitted_cb (CallsCallWindow *self, + CallsOrigin *origin, + const gchar *number, + CallsNewCallBox *new_call_box) +{ + g_return_if_fail (CALLS_IS_CALL_WINDOW (self)); + + calls_origin_dial (origin, number); +} + + +typedef gboolean (*FindCallHolderFunc) (CallsCallHolder *holder, + gpointer user_data); + + +static gboolean +find_call_holder_by_call (CallsCallHolder *holder, + gpointer user_data) +{ + CallsCallData *data = calls_call_holder_get_data (holder); + + return calls_call_data_get_call (data) == user_data; +} + + +/** Search through the list of call holders, returning the total + number of items in the list, the position of the holder within the + list and a pointer to the holder itself. */ +static gboolean +find_call_holder (CallsCallWindow *self, + guint *n_itemsp, + guint *positionp, + CallsCallHolder **holderp, + FindCallHolderFunc predicate, + gpointer user_data) +{ + GListModel * const model = G_LIST_MODEL (self->call_holders); + const guint n_items = g_list_model_get_n_items (model); + guint position = 0; + CallsCallHolder *holder; + + for (position = 0; position < n_items; ++position) + { + holder = CALLS_CALL_HOLDER (g_list_model_get_item (model, position)); + + if (predicate (holder, user_data)) + { +#define out(var) \ + if (var##p) \ + { \ + *var##p = var ; \ + } + + out (n_items); + out (position); + out (holder); + +#undef out + + return TRUE; + } + } + + return FALSE; +} + + +static void +set_focus (CallsCallWindow *self, + CallsCallHolder *holder) +{ + if (!holder) + { + holder = g_list_model_get_item (G_LIST_MODEL (self->call_holders), 0); + + if (!holder) + { + /* No calls */ + self->focus = NULL; + return; + } + } + + self->focus = holder; + + gtk_stack_set_visible_child_name (self->main_stack, "active-call"); + gtk_stack_set_visible_child_name (self->header_bar_stack, "active-call"); + gtk_stack_set_visible_child + (self->call_stack, + GTK_WIDGET (calls_call_holder_get_display (holder))); +} + + +static void +show_calls_clicked_cb (GtkButton *button, + CallsCallWindow *self) +{ + /* FIXME Setting only one of them should be enough as the properties are binded. */ + gtk_stack_set_visible_child_name (self->main_stack, "calls"); + gtk_stack_set_visible_child_name (self->header_bar_stack, "calls"); +} + + +static void +call_selector_child_activated_cb (GtkFlowBox *box, + GtkFlowBoxChild *child, + CallsCallWindow *self) +{ + GtkWidget *widget = gtk_bin_get_child (GTK_BIN (child)); + CallsCallSelectorItem *item = CALLS_CALL_SELECTOR_ITEM (widget); + CallsCallHolder *holder = calls_call_selector_item_get_holder (item); + + update_visibility (self); + set_focus (self, holder); +} + + +void +calls_call_window_add_call (CallsCallWindow *self, + CallsCall *call) +{ + CallsCallHolder *holder; + CallsCallDisplay *display; + + g_return_if_fail (CALLS_IS_CALL_WINDOW (self)); + g_return_if_fail (CALLS_IS_CALL (call)); + + g_signal_connect_swapped (call, "message", + G_CALLBACK (show_message), self); + + holder = calls_call_holder_new (call); + + display = calls_call_holder_get_display (holder); + gtk_stack_add_named (self->call_stack, GTK_WIDGET (display), + calls_call_get_number (call)); + + g_list_store_append (self->call_holders, holder); + + update_visibility (self); + set_focus (self, holder); +} + + +static void +remove_call_holder (CallsCallWindow *self, + guint n_items, + guint position, + CallsCallHolder *holder) +{ + g_list_store_remove (self->call_holders, position); + gtk_container_remove (GTK_CONTAINER (self->call_stack), + GTK_WIDGET (calls_call_holder_get_display (holder))); + + update_visibility (self); + if (self->focus == holder) + { + set_focus (self, NULL); + } +} + +void +calls_call_window_remove_call (CallsCallWindow *self, + CallsCall *call, + const gchar *reason) +{ + guint n_items, position; + CallsCallHolder *holder; + gboolean found; + + g_return_if_fail (CALLS_IS_CALL_WINDOW (self)); + g_return_if_fail (CALLS_IS_CALL (call)); + + found = find_call_holder (self, &n_items, &position, &holder, + find_call_holder_by_call, call); + g_return_if_fail (found); + + remove_call_holder (self, n_items, position, holder); + + if (!reason) + { + reason = "Call ended for unknown reason"; + } + show_message(self, reason, GTK_MESSAGE_INFO); +} + + +static void +remove_calls (CallsCallWindow *self) +{ + GList *children, *child; + + /* Safely remove the call stack's children. */ + children = gtk_container_get_children (GTK_CONTAINER (self->call_stack)); + for (child = children; child != NULL; child = child->next) + gtk_container_remove (GTK_CONTAINER (self->call_stack), + GTK_WIDGET (child->data)); + g_list_free (children); + + g_list_store_remove_all (self->call_holders); + + update_visibility (self); +} + + +static void +constructed (GObject *object) +{ + GObjectClass *parent_class = g_type_class_peek (GTK_TYPE_APPLICATION_WINDOW); + CallsCallWindow *self = CALLS_CALL_WINDOW (object); + + gtk_flow_box_bind_model (self->call_selector, + G_LIST_MODEL (self->call_holders), + (GtkFlowBoxCreateWidgetFunc) call_holders_create_widget_cb, + NULL, NULL); + + parent_class->constructed (object); +} + + +static void +calls_call_window_init (CallsCallWindow *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); + + self->call_holders = g_list_store_new (CALLS_TYPE_CALL_HOLDER); + + update_visibility (self); +} + + +static void +dispose (GObject *object) +{ + GObjectClass *parent_class = g_type_class_peek (GTK_TYPE_APPLICATION_WINDOW); + CallsCallWindow *self = CALLS_CALL_WINDOW (object); + + if (self->call_holders) + { + remove_calls (self); + } + + g_clear_object (&self->call_holders); + + parent_class->dispose (object); +} + + +static void +calls_call_window_class_init (CallsCallWindowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->constructed = constructed; + object_class->dispose = dispose; + + gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/calls/ui/call-window.ui"); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, info); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, info_label); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, main_stack); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, header_bar_stack); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, show_calls); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, call_stack); + gtk_widget_class_bind_template_child (widget_class, CallsCallWindow, call_selector); + gtk_widget_class_bind_template_callback (widget_class, info_response_cb); + gtk_widget_class_bind_template_callback (widget_class, call_selector_child_activated_cb); + gtk_widget_class_bind_template_callback (widget_class, show_calls_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, new_call_submitted_cb); +} diff --git a/src/calls-call-window.h b/src/calls-call-window.h new file mode 100644 index 0000000..695e008 --- /dev/null +++ b/src/calls-call-window.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calls is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calls. If not, see . + * + * Authors: + * Bob Ham + * Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef CALLS_CALL_WINDOW_H__ +#define CALLS_CALL_WINDOW_H__ + +#include + +#include "calls-call.h" + +G_BEGIN_DECLS + +#define CALLS_TYPE_CALL_WINDOW (calls_call_window_get_type ()) + +G_DECLARE_FINAL_TYPE (CallsCallWindow, calls_call_window, CALLS, CALL_WINDOW, GtkApplicationWindow); + +CallsCallWindow *calls_call_window_new (GtkApplication *application); +void calls_call_window_add_call (CallsCallWindow *self, CallsCall *call); +void calls_call_window_remove_call (CallsCallWindow *self, CallsCall *call, const gchar *reason); + +G_END_DECLS + +#endif /* CALLS_CALL_WINDOW_H__ */ diff --git a/src/calls.gresources.xml b/src/calls.gresources.xml index 355bfc8..59991dd 100644 --- a/src/calls.gresources.xml +++ b/src/calls.gresources.xml @@ -4,6 +4,7 @@ main-window.ui call-display.ui call-selector-item.ui + call-window.ui encryption-indicator.ui history-box.ui new-call-box.ui diff --git a/src/meson.build b/src/meson.build index 8c3d966..fffd99e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -45,6 +45,7 @@ calls_sources = ['calls-message-source.c', 'calls-message-source.h', 'calls-call-holder.c', 'calls-call-holder.h', 'calls-call-display.c', 'calls-call-display.h', 'calls-call-selector-item.c', 'calls-call-selector-item.h', + 'calls-call-window.c', 'calls-call-window.h', 'calls-encryption-indicator.c', 'calls-encryption-indicator.h', 'calls-history-box.c', 'calls-history-box.h', 'calls-new-call-box.c', 'calls-new-call-box.h', diff --git a/src/ui/call-window.ui b/src/ui/call-window.ui new file mode 100644 index 0000000..10c0f95 --- /dev/null +++ b/src/ui/call-window.ui @@ -0,0 +1,153 @@ + + + + + + + From 09670ea9c87446261b9baab96de0605bac738a39 Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Wed, 1 Aug 2018 12:57:40 +0200 Subject: [PATCH 05/12] Display calls in the call window. --- src/main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main.c b/src/main.c index a283d4d..ed84205 100644 --- a/src/main.c +++ b/src/main.c @@ -27,6 +27,7 @@ #define HANDY_USE_UNSTABLE_API #include +#include "calls-call-window.h" #include "calls-encryption-indicator.h" #include "calls-history-box.h" #include "calls-main-window.h" @@ -41,6 +42,7 @@ show_window (GtkApplication *app) GDBusConnection *connection; CallsProvider *provider; CallsMainWindow *main_window; + CallsCallWindow *call_window; CALLS_TYPE_ENCRYPTION_INDICATOR; CALLS_TYPE_HISTORY_BOX; @@ -63,6 +65,13 @@ show_window (GtkApplication *app) gtk_window_set_title (GTK_WINDOW (main_window), "Calls"); gtk_widget_show_all (GTK_WIDGET (main_window)); + + call_window = calls_call_window_new (app); + + g_signal_connect_swapped (main_window, "call-added", + G_CALLBACK (calls_call_window_add_call), call_window); + g_signal_connect_swapped (main_window, "call-removed", + G_CALLBACK (calls_call_window_remove_call), call_window); } int From 65d7943e88662096cb8106e8d9356b48cd0476a0 Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Wed, 1 Aug 2018 13:13:25 +0200 Subject: [PATCH 06/12] main-window: Don't display calls --- src/calls-main-window.c | 109 ---------------------------------------- src/ui/main-window.ui | 59 ---------------------- 2 files changed, 168 deletions(-) diff --git a/src/calls-main-window.c b/src/calls-main-window.c index 8bebe25..e1b35c4 100644 --- a/src/calls-main-window.c +++ b/src/calls-main-window.c @@ -48,10 +48,6 @@ struct _CallsMainWindow GtkLabel *info_label; GtkStack *main_stack; - GtkButton *back; - GtkStack *call_stack; - GtkScrolledWindow *call_scroll; - GtkFlowBox *call_selector; GtkListStore *origin_store; }; @@ -121,14 +117,6 @@ new_call_submitted_cb (CallsMainWindow *self, } -static GtkWidget * -call_holders_create_widget_cb (CallsCallHolder *holder, - CallsMainWindow *self) -{ - return GTK_WIDGET (calls_call_holder_get_selector_item (holder)); -} - - typedef gboolean (*FindCallHolderFunc) (CallsCallHolder *holder, gpointer user_data); @@ -201,66 +189,6 @@ set_focus (CallsMainWindow *self, CallsCallHolder *holder) } self->focus = holder; - - gtk_stack_set_visible_child - (self->call_stack, - GTK_WIDGET (calls_call_holder_get_display (holder))); -} - - -static void -back_clicked_cb (GtkButton *back, - CallsMainWindow *self) -{ - gtk_stack_set_visible_child (self->call_stack, GTK_WIDGET (self->call_scroll)); - gtk_stack_set_visible_child (self->main_stack, GTK_WIDGET (self->call_stack)); -} - - -static void -call_selector_child_activated_cb (GtkFlowBox *box, - GtkFlowBoxChild *child, - CallsMainWindow *self) -{ - GtkWidget *widget = gtk_bin_get_child (GTK_BIN (child)); - CallsCallSelectorItem *item = CALLS_CALL_SELECTOR_ITEM (widget); - CallsCallHolder *holder = calls_call_selector_item_get_holder (item); - - set_focus (self, holder); -} - - -/** Possibly show various call widgets */ -static void -show_calls (CallsMainWindow *self, guint old_call_count) -{ - if (old_call_count == 0) - { - gtk_stack_add_titled (self->main_stack, - GTK_WIDGET (self->call_stack), - "call", "Call"); - } - - if (old_call_count > 0) - { - gtk_widget_show (GTK_WIDGET (self->back)); - } -} - - -static void -hide_calls (CallsMainWindow *self, guint call_count) -{ - if (call_count == 0) - { - gtk_container_remove (GTK_CONTAINER (self->main_stack), - GTK_WIDGET (self->call_stack)); - } - - if (call_count <= 1) - { - gtk_widget_hide (GTK_WIDGET (self->back)); - } } @@ -268,22 +196,14 @@ static void add_call (CallsMainWindow *self, CallsCall *call) { CallsCallHolder *holder; - CallsCallDisplay *display; g_signal_emit (self, signals[SIGNAL_CALL_ADDED], 0, call); g_signal_connect_swapped (call, "message", G_CALLBACK (show_message), self); - show_calls (self, g_list_model_get_n_items (G_LIST_MODEL (self->call_holders))); - holder = calls_call_holder_new (call); - display = calls_call_holder_get_display (holder); - gtk_stack_add_named (self->call_stack, GTK_WIDGET (display), - calls_call_get_number (call)); - gtk_stack_set_visible_child (self->main_stack, GTK_WIDGET (self->call_stack)); - g_list_store_append (self->call_holders, holder); set_focus (self, holder); @@ -298,15 +218,11 @@ remove_call_holder (CallsMainWindow *self, CallsCallHolder *holder) { g_list_store_remove (self->call_holders, position); - gtk_container_remove (GTK_CONTAINER (self->call_stack), - GTK_WIDGET (calls_call_holder_get_display (holder))); if (self->focus == holder) { set_focus (self, NULL); } - - hide_calls (self, n_items - 1); } static void @@ -508,24 +424,6 @@ set_property (GObject *object, } -static void -constructed (GObject *object) -{ - GObjectClass *parent_class = g_type_class_peek (GTK_TYPE_APPLICATION_WINDOW); - CallsMainWindow *self = CALLS_MAIN_WINDOW (object); - - gtk_container_remove (GTK_CONTAINER (self->main_stack), - GTK_WIDGET (self->call_stack)); - - gtk_flow_box_bind_model (self->call_selector, - G_LIST_MODEL (self->call_holders), - (GtkFlowBoxCreateWidgetFunc) call_holders_create_widget_cb, - NULL, NULL); - - parent_class->constructed (object); -} - - static void calls_main_window_init (CallsMainWindow *self) { @@ -565,7 +463,6 @@ calls_main_window_class_init (CallsMainWindowClass *klass) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->set_property = set_property; - object_class->constructed = constructed; object_class->dispose = dispose; props[PROP_PROVIDER] = @@ -604,13 +501,7 @@ calls_main_window_class_init (CallsMainWindowClass *klass) gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, info); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, info_label); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, main_stack); - gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, back); - gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, call_stack); - gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, call_scroll); - gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, call_selector); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, origin_store); gtk_widget_class_bind_template_callback (widget_class, info_response_cb); - gtk_widget_class_bind_template_callback (widget_class, call_selector_child_activated_cb); - gtk_widget_class_bind_template_callback (widget_class, back_clicked_cb); gtk_widget_class_bind_template_callback (widget_class, new_call_submitted_cb); } diff --git a/src/ui/main-window.ui b/src/ui/main-window.ui index 87a3c42..3b868b6 100644 --- a/src/ui/main-window.ui +++ b/src/ui/main-window.ui @@ -25,26 +25,6 @@ True False - - - True - True - True - - - - True - False - go-previous-symbolic - - - - - False - True - 0 - - True @@ -122,45 +102,6 @@ True False - - - True - False - - - True - True - never - - - True - False - - - True - False - vertical - True - 12 - 12 - none - - - - - - - - page0 - page0 - - - - - call - Call - - True From e58ce3f08d8de7e8dd6db3b6783f04ebdab2b7fd Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Thu, 30 Aug 2018 08:50:37 +0200 Subject: [PATCH 07/12] main-window: Add the 'about' action This will be needed by the next commit to display an "About" dialog via the corresponding entry in the app menu that will be added. This also adds the PACKAGE_URL, PACKAGE_VERSION and VCS_TAG configuration data. --- meson.build | 2 ++ src/calls-main-window.c | 74 +++++++++++++++++++++++++++++++++++++++++ src/meson.build | 3 ++ 3 files changed, 79 insertions(+) diff --git a/meson.build b/meson.build index b052571..a3d9195 100644 --- a/meson.build +++ b/meson.build @@ -27,6 +27,8 @@ project('call', 'c', ) calls_id = 'sm.puri.Calls' +calls_homepage = 'https://source.puri.sm/Librem5/calls' +calls_version = meson.project_version() subdir('libgdbofono') subdir('src') diff --git a/src/calls-main-window.c b/src/calls-main-window.c index e1b35c4..9fc0aac 100644 --- a/src/calls-main-window.c +++ b/src/calls-main-window.c @@ -27,6 +27,7 @@ #include "calls-call-holder.h" #include "calls-call-selector-item.h" #include "calls-new-call-box.h" +#include "config.h" #include "util.h" #include @@ -75,6 +76,56 @@ enum { static guint signals [SIGNAL_LAST_SIGNAL]; +static void +about_action (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + CallsMainWindow *self = user_data; + + const gchar *version = NULL; + + static const gchar *authors[] = { + "Adrien Plazas ", + "Bob Ham ", + "Guido Günther ", + NULL + }; + + static const gchar *artists[] = { + "Tobias Bernard ", + NULL + }; + + static const gchar *documenters[] = { + "Heather Ellsworth ", + NULL + }; + + version = g_str_equal (VCS_TAG, "") ? PACKAGE_VERSION: + PACKAGE_VERSION "-" VCS_TAG; + + gtk_show_about_dialog (GTK_WINDOW (self), + "artists", artists, + "authors", authors, + "copyright", "Copyright © 2018 Purism", + "documenters", documenters, + "license-type", GTK_LICENSE_GPL_3_0, + "logo-icon-name", APP_ID, + "program-name", _("Calls"), + "translator-credits", _("translator-credits"), + "version", version, + "website", PACKAGE_URL, + NULL); +} + + +static const GActionEntry window_entries [] = +{ + { "about", about_action }, +}; + + CallsMainWindow * calls_main_window_new (GtkApplication *application, CallsProvider *provider) { @@ -424,6 +475,28 @@ set_property (GObject *object, } +static void +constructed (GObject *object) +{ + GObjectClass *parent_class = g_type_class_peek (GTK_TYPE_APPLICATION_WINDOW); + CallsMainWindow *self = CALLS_MAIN_WINDOW (object); + GSimpleActionGroup *simple_action_group; + + /* Add actions */ + simple_action_group = g_simple_action_group_new (); + g_action_map_add_action_entries (G_ACTION_MAP (simple_action_group), + window_entries, + G_N_ELEMENTS (window_entries), + self); + gtk_widget_insert_action_group (GTK_WIDGET (self), + "win", + G_ACTION_GROUP (simple_action_group)); + g_object_unref (simple_action_group); + + parent_class->constructed (object); +} + + static void calls_main_window_init (CallsMainWindow *self) { @@ -463,6 +536,7 @@ calls_main_window_class_init (CallsMainWindowClass *klass) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->set_property = set_property; + object_class->constructed = constructed; object_class->dispose = dispose; props[PROP_PROVIDER] = diff --git a/src/meson.build b/src/meson.build index fffd99e..98bbcc3 100644 --- a/src/meson.build +++ b/src/meson.build @@ -60,6 +60,9 @@ calls_dummy_sources = ['calls-dummy-call.c', 'calls-dummy-call.h', config_data = configuration_data() config_data.set_quoted('APP_ID', calls_id) +config_data.set_quoted('PACKAGE_URL', calls_homepage) +config_data.set_quoted('PACKAGE_VERSION', calls_version) +config_data.set_quoted('VCS_TAG', '@VCS_TAG@') config_h_in = configure_file( output: 'config.h.in', From 1a16271bcb6b5fb6fbbd8cb8ab5bc5eb094f3a34 Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Thu, 2 Aug 2018 12:48:16 +0200 Subject: [PATCH 08/12] Add CallsHistoryHeaderBar --- src/calls-history-header-bar.c | 49 +++++++++++++++++++++ src/calls-history-header-bar.h | 38 ++++++++++++++++ src/calls.gresources.xml | 1 + src/meson.build | 1 + src/ui/history-header-bar.ui | 80 ++++++++++++++++++++++++++++++++++ 5 files changed, 169 insertions(+) create mode 100644 src/calls-history-header-bar.c create mode 100644 src/calls-history-header-bar.h create mode 100644 src/ui/history-header-bar.ui diff --git a/src/calls-history-header-bar.c b/src/calls-history-header-bar.c new file mode 100644 index 0000000..86cc6a4 --- /dev/null +++ b/src/calls-history-header-bar.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calls is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calls. If not, see . + * + * Author: Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "calls-history-header-bar.h" + +struct _CallsHistoryHeaderBar +{ + GtkHeaderBar parent_instance; +}; + +G_DEFINE_TYPE (CallsHistoryHeaderBar, calls_history_header_bar, GTK_TYPE_HEADER_BAR); + + +static void +calls_history_header_bar_init (CallsHistoryHeaderBar *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); +} + + +static void +calls_history_header_bar_class_init (CallsHistoryHeaderBarClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/calls/ui/history-header-bar.ui"); +} + diff --git a/src/calls-history-header-bar.h b/src/calls-history-header-bar.h new file mode 100644 index 0000000..b7958af --- /dev/null +++ b/src/calls-history-header-bar.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calls is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calls. If not, see . + * + * Author: Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef CALLS_HISTORY_HEADER_BAR_H__ +#define CALLS_HISTORY_HEADER_BAR_H__ + +#include + +G_BEGIN_DECLS + +#define CALLS_TYPE_HISTORY_HEADER_BAR (calls_history_header_bar_get_type ()) + +G_DECLARE_FINAL_TYPE (CallsHistoryHeaderBar, calls_history_header_bar, CALLS, HISTORY_HEADER_BAR, GtkHeaderBar); + +G_END_DECLS + +#endif /* CALLS_HISTORY_HEADER_BAR_H__ */ diff --git a/src/calls.gresources.xml b/src/calls.gresources.xml index 59991dd..ad8716e 100644 --- a/src/calls.gresources.xml +++ b/src/calls.gresources.xml @@ -7,6 +7,7 @@ call-window.ui encryption-indicator.ui history-box.ui + history-header-bar.ui new-call-box.ui diff --git a/src/meson.build b/src/meson.build index 98bbcc3..55e753c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -48,6 +48,7 @@ calls_sources = ['calls-message-source.c', 'calls-message-source.h', 'calls-call-window.c', 'calls-call-window.h', 'calls-encryption-indicator.c', 'calls-encryption-indicator.h', 'calls-history-box.c', 'calls-history-box.h', + 'calls-history-header-bar.c', 'calls-history-header-bar.h', 'calls-new-call-box.c', 'calls-new-call-box.h', 'calls-main-window.c', 'calls-main-window.h', 'util.c', 'util.h', diff --git a/src/ui/history-header-bar.ui b/src/ui/history-header-bar.ui new file mode 100644 index 0000000..4a61ba8 --- /dev/null +++ b/src/ui/history-header-bar.ui @@ -0,0 +1,80 @@ + + + + + + + True + + + False + 12 + vertical + True + + + True + About + win.about + True + + + + + + + From b9d353dd58f5f736de8c23f1f4865d87ff717d7f Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Thu, 2 Aug 2018 12:49:51 +0200 Subject: [PATCH 09/12] Add CallsNewCallHeaderBar --- src/calls-new-call-header-bar.c | 49 +++++++++++++++++++++++++++++++++ src/calls-new-call-header-bar.h | 38 +++++++++++++++++++++++++ src/calls.gresources.xml | 1 + src/meson.build | 1 + src/ui/new-call-header-bar.ui | 43 +++++++++++++++++++++++++++++ 5 files changed, 132 insertions(+) create mode 100644 src/calls-new-call-header-bar.c create mode 100644 src/calls-new-call-header-bar.h create mode 100644 src/ui/new-call-header-bar.ui diff --git a/src/calls-new-call-header-bar.c b/src/calls-new-call-header-bar.c new file mode 100644 index 0000000..cbdca6e --- /dev/null +++ b/src/calls-new-call-header-bar.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calls is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calls. If not, see . + * + * Author: Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "calls-new-call-header-bar.h" + +struct _CallsNewCallHeaderBar +{ + GtkHeaderBar parent_instance; +}; + +G_DEFINE_TYPE (CallsNewCallHeaderBar, calls_new_call_header_bar, GTK_TYPE_HEADER_BAR); + + +static void +calls_new_call_header_bar_init (CallsNewCallHeaderBar *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); +} + + +static void +calls_new_call_header_bar_class_init (CallsNewCallHeaderBarClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gtk_widget_class_set_template_from_resource (widget_class, "/sm/puri/calls/ui/new-call-header-bar.ui"); +} + diff --git a/src/calls-new-call-header-bar.h b/src/calls-new-call-header-bar.h new file mode 100644 index 0000000..7eae143 --- /dev/null +++ b/src/calls-new-call-header-bar.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 Purism SPC + * + * This file is part of Calls. + * + * Calls is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calls is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calls. If not, see . + * + * Author: Adrien Plazas + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#ifndef CALLS_NEW_CALL_HEADER_BAR_H__ +#define CALLS_NEW_CALL_HEADER_BAR_H__ + +#include + +G_BEGIN_DECLS + +#define CALLS_TYPE_NEW_CALL_HEADER_BAR (calls_new_call_header_bar_get_type ()) + +G_DECLARE_FINAL_TYPE (CallsNewCallHeaderBar, calls_new_call_header_bar, CALLS, NEW_CALL_HEADER_BAR, GtkHeaderBar); + +G_END_DECLS + +#endif /* CALLS_NEW_CALL_HEADER_BAR_H__ */ diff --git a/src/calls.gresources.xml b/src/calls.gresources.xml index ad8716e..73577f7 100644 --- a/src/calls.gresources.xml +++ b/src/calls.gresources.xml @@ -9,5 +9,6 @@ history-box.ui history-header-bar.ui new-call-box.ui + new-call-header-bar.ui diff --git a/src/meson.build b/src/meson.build index 55e753c..0ad652b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -50,6 +50,7 @@ calls_sources = ['calls-message-source.c', 'calls-message-source.h', 'calls-history-box.c', 'calls-history-box.h', 'calls-history-header-bar.c', 'calls-history-header-bar.h', 'calls-new-call-box.c', 'calls-new-call-box.h', + 'calls-new-call-header-bar.c', 'calls-new-call-header-bar.h', 'calls-main-window.c', 'calls-main-window.h', 'util.c', 'util.h', ] diff --git a/src/ui/new-call-header-bar.ui b/src/ui/new-call-header-bar.ui new file mode 100644 index 0000000..90cf991 --- /dev/null +++ b/src/ui/new-call-header-bar.ui @@ -0,0 +1,43 @@ + + + + + + From 68cc256018d71f2ca7bf860795f7f0d65b954a1d Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Thu, 2 Aug 2018 13:03:55 +0200 Subject: [PATCH 10/12] main-window: Add the 'new-call' and 'back' actions These will be used by the header bar to switch between the call history page and the new call page. --- src/calls-main-window.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/calls-main-window.c b/src/calls-main-window.c index 9fc0aac..27ca8ad 100644 --- a/src/calls-main-window.c +++ b/src/calls-main-window.c @@ -49,6 +49,7 @@ struct _CallsMainWindow GtkLabel *info_label; GtkStack *main_stack; + GtkStack *header_bar_stack; GtkListStore *origin_store; }; @@ -120,9 +121,33 @@ about_action (GSimpleAction *action, } +static void +new_call_action (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + CallsMainWindow *self = user_data; + + gtk_stack_set_visible_child_name (self->header_bar_stack, "new-call"); +} + + +static void +back_action (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + CallsMainWindow *self = user_data; + + gtk_stack_set_visible_child_name (self->header_bar_stack, "history"); +} + + static const GActionEntry window_entries [] = { { "about", about_action }, + { "new-call", new_call_action }, + { "back", back_action }, }; @@ -575,6 +600,7 @@ calls_main_window_class_init (CallsMainWindowClass *klass) gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, info); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, info_label); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, main_stack); + gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, header_bar_stack); gtk_widget_class_bind_template_child (widget_class, CallsMainWindow, origin_store); gtk_widget_class_bind_template_callback (widget_class, info_response_cb); gtk_widget_class_bind_template_callback (widget_class, new_call_submitted_cb); From e0a1329218ba2912e9e923c8c4e22af2307295fe Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Thu, 2 Aug 2018 13:05:57 +0200 Subject: [PATCH 11/12] main-window: Replace the stack switcher by a header bar Drop the in-window content stack witcher and replace it by a header bar containing both a CallsHistoryHeaderBar and a CallsNewCallHeaderBar. --- src/main.c | 4 ++++ src/ui/main-window.ui | 49 ++++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/main.c b/src/main.c index ed84205..5609e92 100644 --- a/src/main.c +++ b/src/main.c @@ -30,9 +30,11 @@ #include "calls-call-window.h" #include "calls-encryption-indicator.h" #include "calls-history-box.h" +#include "calls-history-header-bar.h" #include "calls-main-window.h" #include "calls-mm-provider.h" #include "calls-new-call-box.h" +#include "calls-new-call-header-bar.h" #include "config.h" static void @@ -46,7 +48,9 @@ show_window (GtkApplication *app) CALLS_TYPE_ENCRYPTION_INDICATOR; CALLS_TYPE_HISTORY_BOX; + CALLS_TYPE_HISTORY_HEADER_BAR; CALLS_TYPE_NEW_CALL_BOX; + CALLS_TYPE_NEW_CALL_HEADER_BAR; HDY_TYPE_DIALER; connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); diff --git a/src/ui/main-window.ui b/src/ui/main-window.ui index 3b868b6..74c0a15 100644 --- a/src/ui/main-window.ui +++ b/src/ui/main-window.ui @@ -21,31 +21,6 @@ True False vertical - - - True - False - - - True - False - center - 0 - main_stack - - - True - True - 1 - - - - - False - True - 0 - - False @@ -135,7 +110,29 @@ - + + False + True + + + + False + True + + + history + + + + + False + True + + + new-call + + + \ No newline at end of file From 7682aa102944c2a035753a1b8754311eede60e6d Mon Sep 17 00:00:00 2001 From: Adrien Plazas Date: Thu, 2 Aug 2018 13:23:09 +0200 Subject: [PATCH 12/12] main-window: Move calls history before the new call box This makes the calls history the page visible by default, matching the final design. --- src/ui/main-window.ui | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/ui/main-window.ui b/src/ui/main-window.ui index 74c0a15..dfab70a 100644 --- a/src/ui/main-window.ui +++ b/src/ui/main-window.ui @@ -77,6 +77,16 @@ True False + + + True + True + + + history + History + + True @@ -89,17 +99,6 @@ New call - - - True - True - - - history - History - 3 - - True