Commit bbb10d8b authored by Stepan Salenikovich's avatar Stepan Salenikovich Committed by Guillaume Roguez

gnome: move current calls view into separate widget

Refs #73154

Change-Id: I020007fadd96dc06052f8ca060260051ef2720ec
parent 82b1acf4
......@@ -201,6 +201,8 @@ SET( SRC_FILES
src/backends/edscontactbackend.cpp
src/delegates/pixbufdelegate.h
src/delegates/pixbufdelegate.cpp
src/callsview.h
src/callsview.cpp
src/contactsview.h
src/contactsview.cpp
src/historyview.h
......
/*
* Copyright (C) 2015 Savoir-Faire Linux Inc.
* Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#include "callsview.h"
#include <gtk/gtk.h>
#include "models/gtkqtreemodel.h"
#include <callmodel.h>
#include <QtCore/QItemSelectionModel>
#include "utils/models.h"
struct _CallsView
{
GtkScrolledWindow parent;
};
struct _CallsViewClass
{
GtkScrolledWindowClass parent_class;
};
typedef struct _CallsViewPrivate CallsViewPrivate;
struct _CallsViewPrivate
{
GtkWidget *treeview_calls;
QMetaObject::Connection selection_updated;
};
G_DEFINE_TYPE_WITH_PRIVATE(CallsView, calls_view, GTK_TYPE_SCROLLED_WINDOW);
#define CALLS_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CALLS_VIEW_TYPE, CallsViewPrivate))
static void
update_call_model_selection(GtkTreeSelection *selection, G_GNUC_UNUSED gpointer user_data)
{
QModelIndex current = get_index_from_selection(selection);
if (current.isValid())
CallModel::instance()->selectionModel()->setCurrentIndex(current, QItemSelectionModel::ClearAndSelect);
else
CallModel::instance()->selectionModel()->clearCurrentIndex();
}
static void
calls_view_init(CallsView *self)
{
CallsViewPrivate *priv = CALLS_VIEW_GET_PRIVATE(self);
/* disable vertical scroll... we always want all the calls to be visible */
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_NEVER);
g_object_set(self, "height-request", 100, NULL);
priv->treeview_calls = gtk_tree_view_new();
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(priv->treeview_calls), FALSE);
/* disable default search, we will handle it ourselves via LRC;
* otherwise the search steals input focus on key presses */
gtk_tree_view_set_enable_search(GTK_TREE_VIEW(priv->treeview_calls), FALSE);
gtk_container_add(GTK_CONTAINER(self), priv->treeview_calls);
/* call model */
GtkQTreeModel *call_model;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
call_model = gtk_q_tree_model_new(
CallModel::instance(),
4,
Call::Role::Name, G_TYPE_STRING,
Call::Role::Number, G_TYPE_STRING,
Call::Role::Length, G_TYPE_STRING,
Call::Role::State, G_TYPE_STRING);
gtk_tree_view_set_model(GTK_TREE_VIEW(priv->treeview_calls), GTK_TREE_MODEL(call_model));
renderer = gtk_cell_renderer_text_new();
g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", 0, NULL);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_calls), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Duration", renderer, "text", 2, NULL);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_calls), column);
/* connect signals to and from the slection model of the call model */
priv->selection_updated = QObject::connect(
CallModel::instance()->selectionModel(),
&QItemSelectionModel::currentChanged,
[=](const QModelIndex & current, const QModelIndex & previous) {
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_calls));
/* first unselect the previous */
if (previous.isValid()) {
GtkTreeIter old_iter;
if (gtk_q_tree_model_source_index_to_iter(call_model, previous, &old_iter)) {
gtk_tree_selection_unselect_iter(selection, &old_iter);
} else {
g_warning("Trying to unselect invalid GtkTreeIter");
}
}
/* select the current */
if (current.isValid()) {
GtkTreeIter new_iter;
if (gtk_q_tree_model_source_index_to_iter(call_model, current, &new_iter)) {
gtk_tree_selection_select_iter(selection, &new_iter);
} else {
g_warning("SelectionModel of CallModel changed to invalid QModelIndex?");
}
}
}
);
GtkTreeSelection *call_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_calls));
g_signal_connect(call_selection, "changed", G_CALLBACK(update_call_model_selection), NULL);
gtk_widget_show_all(GTK_WIDGET(self));
}
static void
calls_view_dispose(GObject *object)
{
CallsView *self = CALLS_VIEW(object);
CallsViewPrivate *priv = CALLS_VIEW_GET_PRIVATE(self);
QObject::disconnect(priv->selection_updated);
G_OBJECT_CLASS(calls_view_parent_class)->dispose(object);
}
static void
calls_view_finalize(GObject *object)
{
G_OBJECT_CLASS(calls_view_parent_class)->finalize(object);
}
static void
calls_view_class_init(CallsViewClass *klass)
{
G_OBJECT_CLASS(klass)->finalize = calls_view_finalize;
G_OBJECT_CLASS(klass)->dispose = calls_view_dispose;
}
GtkWidget *
calls_view_new()
{
gpointer self = g_object_new(CALLS_VIEW_TYPE, NULL);
return (GtkWidget *)self;
}
GtkTreeSelection *
calls_view_get_selection(CallsView *calls_view)
{
g_return_val_if_fail(IS_CALLS_VIEW(calls_view), NULL);
CallsViewPrivate *priv = CALLS_VIEW_GET_PRIVATE(calls_view);
return gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_calls));
}
\ No newline at end of file
/*
* Copyright (C) 2015 Savoir-Faire Linux Inc.
* Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifndef _CALLSVIEW_H
#define _CALLSVIEW_H
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define CALLS_VIEW_TYPE (calls_view_get_type ())
#define CALLS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLS_VIEW_TYPE, CallsView))
#define CALLS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CALLS_VIEW_TYPE, CallsViewClass))
#define IS_CALLS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CALLS_VIEW_TYPE))
#define IS_CALLS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CALLS_VIEW_TYPE))
typedef struct _CallsView CallsView;
typedef struct _CallsViewClass CallsViewClass;
GType calls_view_get_type (void) G_GNUC_CONST;
GtkWidget *calls_view_new (void);
GtkTreeSelection *calls_view_get_selection(CallsView *calls_view);
G_END_DECLS
#endif /* _CALLSVIEW_H */
......@@ -58,6 +58,7 @@
#include "historyview.h"
#include "utils/models.h"
#include "generalsettingsview.h"
#include "callsview.h"
#define CALL_VIEW_NAME "calls"
#define CREATE_ACCOUNT_1_VIEW_NAME "create1"
......@@ -95,7 +96,7 @@ struct _RingMainWindowPrivate
GtkWidget *radiobutton_contacts;
GtkWidget *radiobutton_history;
GtkWidget *radiobutton_presence;
GtkWidget *treeview_call;
GtkWidget *vbox_left_pane;
GtkWidget *search_entry;
GtkWidget *stack_main_view;
GtkWidget *vbox_call_view;
......@@ -110,8 +111,7 @@ struct _RingMainWindowPrivate
GtkWidget *radiobutton_account_settings;
GtkWidget *label_ring_id;
Account *active_ring_account;
QMetaObject::Connection active_ring_account_updates;
QMetaObject::Connection selection_updated;
gboolean show_settings;
......@@ -139,16 +139,6 @@ G_DEFINE_TYPE_WITH_PRIVATE(RingMainWindow, ring_main_window, GTK_TYPE_APPLICATIO
#define RING_MAIN_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), RING_MAIN_WINDOW_TYPE, RingMainWindowPrivate))
static void
update_call_model_selection(GtkTreeSelection *selection, G_GNUC_UNUSED gpointer user_data)
{
QModelIndex current = get_index_from_selection(selection);
if (current.isValid())
CallModel::instance()->selectionModel()->setCurrentIndex(current, QItemSelectionModel::ClearAndSelect);
else
CallModel::instance()->selectionModel()->clearCurrentIndex();
}
static void
call_selection_changed(GtkTreeSelection *selection, gpointer win)
{
......@@ -159,7 +149,7 @@ call_selection_changed(GtkTreeSelection *selection, gpointer win)
QModelIndex idx = get_index_from_selection(selection);
if (idx.isValid()) {
QVariant state = CallModel::instance()->data(idx, static_cast<int>(Call::Role::LifeCycleState));
QVariant state = idx.data(static_cast<int>(Call::Role::LifeCycleState));
GtkWidget *new_call_view = NULL;
char* new_call_view_name = NULL;
......@@ -978,61 +968,12 @@ ring_main_window_init(RingMainWindow *win)
g_signal_connect(priv->radiobutton_account_settings, "toggled", G_CALLBACK(show_account_settings), win);
g_signal_connect(priv->radiobutton_general_settings, "toggled", G_CALLBACK(show_general_settings), win);
/* call model */
GtkQTreeModel *call_model;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
call_model = gtk_q_tree_model_new(CallModel::instance(), 4,
Call::Role::Name, G_TYPE_STRING,
Call::Role::Number, G_TYPE_STRING,
Call::Role::Length, G_TYPE_STRING,
Call::Role::State, G_TYPE_STRING);
gtk_tree_view_set_model(GTK_TREE_VIEW(priv->treeview_call), GTK_TREE_MODEL(call_model));
renderer = gtk_cell_renderer_text_new();
g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", 0, NULL);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_call), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Duration", renderer, "text", 2, NULL);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_append_column(GTK_TREE_VIEW(priv->treeview_call), column);
/* connect signals to and from UserActionModel to sync selection betwee
* the QModel and the GtkTreeView */
QObject::connect(
CallModel::instance()->selectionModel(),
&QItemSelectionModel::currentChanged,
[=](const QModelIndex & current, const QModelIndex & previous) {
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_call));
/* first unselect the previous */
if (previous.isValid()) {
GtkTreeIter old_iter;
if (gtk_q_tree_model_source_index_to_iter(call_model, previous, &old_iter)) {
gtk_tree_selection_unselect_iter(selection, &old_iter);
} else {
g_warning("Trying to unselect invalid GtkTreeIter");
}
}
/* select the current */
if (current.isValid()) {
GtkTreeIter new_iter;
if (gtk_q_tree_model_source_index_to_iter(call_model, current, &new_iter)) {
gtk_tree_selection_select_iter(selection, &new_iter);
} else {
g_warning("SelectionModel of CallModel changed to invalid QModelIndex?");
}
}
}
);
GtkTreeSelection *call_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_call));
g_signal_connect(call_selection, "changed", G_CALLBACK(update_call_model_selection), NULL);
/* calls view */
GtkWidget *calls_view = calls_view_new();
gtk_box_pack_start(GTK_BOX(priv->vbox_left_pane),
calls_view,
FALSE, TRUE, 0);
gtk_box_reorder_child(GTK_BOX(priv->vbox_left_pane), calls_view, 0);
/* connect to call state changes to update relevant view(s) */
QObject::connect(
......@@ -1079,12 +1020,13 @@ ring_main_window_init(RingMainWindow *win)
gtk_stack_add_named(GTK_STACK(priv->stack_call_view), placeholder_view, DEFAULT_VIEW_NAME);
/* connect signals */
GtkTreeSelection *call_selection = calls_view_get_selection(CALLS_VIEW(calls_view));
g_signal_connect(call_selection, "changed", G_CALLBACK(call_selection_changed), win);
g_signal_connect(priv->button_placecall, "clicked", G_CALLBACK(search_entry_placecall), win);
g_signal_connect(priv->search_entry, "activate", G_CALLBACK(search_entry_placecall), win);
/* style of search entry */
gtk_widget_override_font(priv->search_entry, pango_font_description_from_string("15")); //"monospace 15"));
gtk_widget_override_font(priv->search_entry, pango_font_description_from_string("15"));
/* autocompletion */
priv->q_completion_model = new NumberCompletionModel();
......@@ -1093,7 +1035,7 @@ ring_main_window_init(RingMainWindow *win)
GtkCellArea *completion_area = gtk_cell_area_box_new();
/* photo renderer */
renderer = gtk_cell_renderer_pixbuf_new();
GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
gtk_cell_area_box_pack_start(GTK_CELL_AREA_BOX(completion_area),
renderer,
TRUE, /* expand */
......@@ -1194,6 +1136,11 @@ ring_main_window_init(RingMainWindow *win)
static void
ring_main_window_dispose(GObject *object)
{
RingMainWindow *self = RING_MAIN_WINDOW(object);
RingMainWindowPrivate *priv = RING_MAIN_WINDOW_GET_PRIVATE(self);
QObject::disconnect(priv->selection_updated);
G_OBJECT_CLASS(ring_main_window_parent_class)->dispose(object);
}
......@@ -1219,7 +1166,7 @@ ring_main_window_class_init(RingMainWindowClass *klass)
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass),
"/cx/ring/RingGnome/ringmainwindow.ui");
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, treeview_call);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, vbox_left_pane);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, stack_contacts_history_presence);
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);
......
......@@ -166,37 +166,12 @@
<!-- TODO: save the user set position of the pane -->
<property name="position">350</property>
<child>
<object class="GtkBox" id="vbox_left">
<object class="GtkBox" id="vbox_left_pane">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<!-- current calls view -->
<child>
<object class="GtkScrolledWindow" id="scrolledwindow_calls">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vscrollbar_policy">never</property>
<property name="height-request">100</property>
<!-- <property name="shadow_type">in</property> -->
<child>
<object class="GtkTreeView" id="treeview_call">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="enable-search">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<!-- end current calls view -->
<property name="spacing">10</property>
<!-- calls view goes here -->
<!-- contacts/history/presence view -->
<child>
<object class="GtkStack" id="stack_contacts_history_presence">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment