Commit e9933249 authored by Stepan Salenikovich's avatar Stepan Salenikovich Committed by gerrit2

search entry: open chat view instead of call

This changes the default behaviour of the search entry, the button
next to it, and the autocompletion drop down to opening the chat view
with the selected CM/Person instead of placing a new call. This allows
people who wish to simply chat with a new RingID to do so, instead of
first having to call that RingID or add it to a Contact in their
addressbook.

Additionally, a setting has been added to change this behaviour, so
that (typically) SIP users can easily place new calls by entering phone
numbers in the search entry.

Also, a "Place call" button has been added to the chat view (when not
in a call), so that users can easily call someone they are chatting with
without having to double click on that contact in the contacts list.

Change-Id: Ia833fb36620fd34afdbb3c3a4357c212a87f8796
Tuleap: #953
parent eea501d6
......@@ -44,5 +44,10 @@
<summary>Main window height.</summary>
<description>Main window height.</description>
</key>
<key name="search-entry-places-call" type="b">
<default>false</default>
<summary>Entering a number in the search entry places a new call.</summary>
<description>Entering a number in the search entry places a new call. If false, then this will instead open a chat view.</description>
</key>
</schema>
</schemalist>
......@@ -30,6 +30,7 @@
#include "ringnotify.h"
#include "numbercategory.h"
#include <QtCore/QDateTime>
#include "utils/calling.h"
static constexpr GdkRGBA RING_BLUE = {0.0508, 0.594, 0.676, 1.0}; // outgoing msg color: (13, 152, 173)
......@@ -55,6 +56,7 @@ struct _ChatViewPrivate
GtkWidget *label_peer;
GtkWidget *combobox_cm;
GtkWidget *button_close_chatview;
GtkWidget *button_placecall;
/* only one of the three following pointers should be non void;
* either this is an in-call chat (and so the in-call chat APIs will be used)
......@@ -117,7 +119,7 @@ send_chat(G_GNUC_UNUSED GtkWidget *widget, ChatView *self)
if (!cm->sendOfflineTextMessage(messages))
g_warning("message failed to send"); // TODO: warn the user about this in the UI
} else {
g_warning("no ContactMethod chosen; message not esnt");
g_warning("no ContactMethod chosen; message not sent");
}
} else if (priv->cm) {
if (!priv->cm->sendOfflineTextMessage(messages))
......@@ -144,6 +146,27 @@ hide_chat_view(G_GNUC_UNUSED GtkWidget *widget, ChatView *self)
g_signal_emit(G_OBJECT(self), chat_view_signals[HIDE_VIEW_CLICKED], 0);
}
static void
placecall_clicked(ChatView *self)
{
auto priv = CHAT_VIEW_GET_PRIVATE(self);
if (priv->person) {
// get the chosen cm
auto active = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->combobox_cm));
if (active >= 0) {
auto cm = priv->person->phoneNumbers().at(active);
place_new_call(cm);
} else {
g_warning("no ContactMethod chosen; cannot place call");
}
} else if (priv->cm) {
place_new_call(priv->cm);
} else {
g_warning("no Person or ContactMethod set; cannot place call");
}
}
static void
chat_view_init(ChatView *view)
{
......@@ -161,6 +184,8 @@ chat_view_init(ChatView *view)
g_signal_connect(adjustment, "changed", G_CALLBACK(scroll_to_bottom), NULL);
g_signal_connect(priv->button_close_chatview, "clicked", G_CALLBACK(hide_chat_view), view);
g_signal_connect_swapped(priv->button_placecall, "clicked", G_CALLBACK(placecall_clicked), view);
}
static void
......@@ -179,6 +204,7 @@ chat_view_class_init(ChatViewClass *klass)
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, label_peer);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, combobox_cm);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, button_close_chatview);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, button_placecall);
chat_view_signals[NEW_MESSAGES_DISPLAYED] = g_signal_new (
"new-messages-displayed",
......@@ -406,6 +432,9 @@ update_contact_methods(ChatView *self)
/* if there is only one CM, make the combo box insensitive */
if (cms.size() < 2)
gtk_widget_set_sensitive(priv->combobox_cm, FALSE);
/* if no CMs make the call button insensitive */
gtk_widget_set_sensitive(priv->button_placecall, !cms.isEmpty());
}
static void
......
......@@ -55,6 +55,7 @@ struct _GeneralSettingsViewPrivate
GtkWidget *checkbutton_bringtofront;
GtkWidget *checkbutton_callnotifications;
GtkWidget *checkbutton_chatnotifications;
GtkWidget *checkbutton_searchentryplacescall;
GtkWidget *radiobutton_chatright;
GtkWidget *radiobutton_chatbottom;
GtkWidget *box_profil_settings;
......@@ -156,6 +157,9 @@ general_settings_view_init(GeneralSettingsView *self)
g_settings_bind(priv->settings, "enable-chat-notifications",
priv->checkbutton_chatnotifications, "active",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind(priv->settings, "search-entry-places-call",
priv->checkbutton_searchentryplacescall, "active",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind(priv->settings, "chat-pane-horizontal",
priv->radiobutton_chatright, "active",
G_SETTINGS_BIND_DEFAULT);
......@@ -186,6 +190,7 @@ general_settings_view_class_init(GeneralSettingsViewClass *klass)
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_bringtofront);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_callnotifications);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_chatnotifications);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, checkbutton_searchentryplacescall);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, radiobutton_chatright);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, radiobutton_chatbottom);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), GeneralSettingsView, adjustment_history_duration);
......
......@@ -29,6 +29,7 @@
// Qt
#include <QtCore/QItemSelectionModel>
#include <QtCore/QSortFilterProxyModel>
#include <QtCore/QDateTime>
// LRC
#include <callmodel.h>
......@@ -110,7 +111,7 @@ struct _RingMainWindowPrivate
GtkWidget *vbox_call_view;
GtkWidget *frame_call;
GtkWidget *welcome_view;
GtkWidget *button_placecall;
GtkWidget *button_new_conversation ;
GtkWidget *account_settings_view;
GtkWidget *media_settings_view;
GtkWidget *general_settings_view;
......@@ -447,23 +448,29 @@ selection_changed(RingMainWindow *win)
}
static void
search_entry_placecall(G_GNUC_UNUSED GtkWidget *entry, gpointer win)
search_entry_activated(GtkWidget *entry, RingMainWindow *self)
{
RingMainWindowPrivate *priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(win));
RingMainWindowPrivate *priv = RING_MAIN_WINDOW_GET_PRIVATE(self);
const gchar *number_entered = gtk_entry_get_text(GTK_ENTRY(priv->search_entry));
const auto *number_entered = gtk_entry_get_text(GTK_ENTRY(entry));
if (number_entered && strlen(number_entered) > 0) {
auto cm = PhoneDirectoryModel::instance().getNumber(number_entered);
g_debug("dialing to number: %s", cm->uri().toUtf8().constData());
if (g_settings_get_boolean(priv->settings, "search-entry-places-call")) {
place_new_call(cm);
place_new_call(cm);
/* move focus away from entry so that DTMF tones can be entered via the keyboard */
gtk_widget_child_focus(GTK_WIDGET(self), GTK_DIR_TAB_FORWARD);
} else {
// if its a new CM, bring it to the top
if (cm->lastUsed() == 0)
cm->setLastUsed(QDateTime::currentDateTime().toTime_t());
/* move focus away from entry so that DTMF tones can be entered via the keyboard */
gtk_widget_child_focus(GTK_WIDGET(win), GTK_DIR_TAB_FORWARD);
/* clear the entry */
gtk_entry_set_text(GTK_ENTRY(priv->search_entry), "");
// select cm
RecentModel::instance().selectionModel()->setCurrentIndex(RecentModel::instance().getIndex(cm), QItemSelectionModel::ClearAndSelect);
}
gtk_entry_set_text(GTK_ENTRY(entry), "");
}
}
......@@ -873,10 +880,19 @@ select_autocompletion(G_GNUC_UNUSED GtkEntryCompletion *widget,
if (idx.isValid()) {
auto cm = priv->q_completion_model->number(idx);
place_new_call(cm);
if (g_settings_get_boolean(priv->settings, "search-entry-places-call")) {
place_new_call(cm);
/* move focus away from entry so that DTMF tones can be entered via the keyboard */
gtk_widget_child_focus(GTK_WIDGET(win), GTK_DIR_TAB_FORWARD);
} else {
// if its a new CM, bring it to the top
if (cm->lastUsed() == 0)
cm->setLastUsed(QDateTime::currentDateTime().toTime_t());
/* move focus away from entry so that DTMF tones can be entered via the keyboard */
gtk_widget_child_focus(GTK_WIDGET(win), GTK_DIR_TAB_FORWARD);
// select cm
RecentModel::instance().selectionModel()->setCurrentIndex(RecentModel::instance().getIndex(cm), QItemSelectionModel::ClearAndSelect);
}
/* clear the entry */
gtk_entry_set_text(GTK_ENTRY(priv->search_entry), "");
......@@ -1092,6 +1108,18 @@ window_size_changed(GtkWidget *win, GdkEventConfigure *event, gpointer)
return GDK_EVENT_PROPAGATE;
}
static void
search_entry_places_call_changed(GSettings *settings, const gchar *key, RingMainWindow *self)
{
auto priv = RING_MAIN_WINDOW_GET_PRIVATE(self);
if (g_settings_get_boolean(settings, key)) {
gtk_widget_set_tooltip_text(priv->button_new_conversation, C_("button next to search entry will place a new call", "place call"));
} else {
gtk_widget_set_tooltip_text(priv->button_new_conversation, C_("button next to search entry will open chat", "open chat"));
}
}
static void
ring_main_window_init(RingMainWindow *win)
{
......@@ -1105,6 +1133,10 @@ ring_main_window_init(RingMainWindow *win)
gtk_window_set_default_size(GTK_WINDOW(win), width, height);
g_signal_connect(win, "configure-event", G_CALLBACK(window_size_changed), nullptr);
/* search-entry-places-call setting */
search_entry_places_call_changed(priv->settings, "search-entry-places-call", win);
g_signal_connect(priv->settings, "changed::search-entry-places-call", G_CALLBACK(search_entry_places_call_changed), win);
/* set window icon */
GError *error = NULL;
GdkPixbuf* icon = gdk_pixbuf_new_from_resource("/cx/ring/RingGnome/ring-symbol-blue", &error);
......@@ -1192,8 +1224,8 @@ ring_main_window_init(RingMainWindow *win)
auto selection_history = gtk_tree_view_get_selection(GTK_TREE_VIEW(priv->treeview_history));
g_signal_connect(selection_history, "changed", G_CALLBACK(history_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);
g_signal_connect(priv->button_new_conversation, "clicked", G_CALLBACK(search_entry_activated), win);
g_signal_connect(priv->search_entry, "activate", G_CALLBACK(search_entry_activated), win);
/* autocompletion */
priv->q_completion_model = new NumberCompletionModel();
......@@ -1338,7 +1370,7 @@ ring_main_window_class_init(RingMainWindowClass *klass)
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, stack_main_view);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, vbox_call_view);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, frame_call);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, button_placecall);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, button_new_conversation );
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, radiobutton_general_settings);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, radiobutton_media_settings);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), RingMainWindow, radiobutton_account_settings);
......
......@@ -38,6 +38,21 @@
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_placecall">
<property name="visible">True</property>
<property name="image">image_place_call</property>
<property name="tooltip-text" translatable="yes">Place call</property>
<child internal-child="accessible">
<object class="AtkObject" id="button_placecall-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Place call</property>
</object>
</child>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="combobox_cm">
<property name="visible">True</property>
......@@ -114,4 +129,8 @@
<property name="visible">True</property>
<property name="icon-name">go-previous-symbolic</property>
</object>
<object class="GtkImage" id="image_place_call">
<property name="visible">True</property>
<property name="icon-name">call-start-symbolic</property>
</object>
</interface>
......@@ -125,6 +125,14 @@
<property name="draw_indicator">True</property>
</object>
</child>
<child>
<object class="GtkCheckButton" id="checkbutton_searchentryplacescall">
<property name="label" translatable="yes">Entering a number in the search entry will place a new call.</property>
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
</child>
<child>
<object class="GtkButtonBox" id="buttonbox_chatposition">
<property name="visible">True</property>
......
......@@ -148,19 +148,12 @@
</packing>
</child>
<child>
<object class="GtkButton" id="button_placecall">
<property name="image">image_call</property>
<object class="GtkButton" id="button_new_conversation">
<property name="image">image_new_conversation</property>
<property name="visible">True</property>
<property name="relief">none</property>
</object>
</child>
<child>
<object class="GtkButton" id="button_addcontact">
<property name="image">image_contact</property>
<!-- TODO: make visible when feature ready -->
<property name="visible">False</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
......@@ -416,9 +409,9 @@
<property name="visible">True</property>
<property name="resource">/cx/ring/RingGnome/users_small</property>
</object>
<object class="GtkImage" id="image_call">
<object class="GtkImage" id="image_new_conversation">
<property name="visible">True</property>
<property name="icon-name">call-start-symbolic</property>
<property name="icon-name">list-add-symbolic</property>
</object>
<object class="GtkImage" id="image_contact">
<property name="visible">True</property>
......
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