Commit a51e9c08 authored by Hugo Lefeuvre's avatar Hugo Lefeuvre

call management: implement let a message view

Change-Id: I3157d745c460fd554d663031db8a170f153e5f55
Reviewed-by: Sébastien Blin's avatarSebastien Blin <sebastien.blin@savoirfairelinux.com>
parent 03eb4e6b
......@@ -308,6 +308,8 @@ SET( SRC_FILES
src/webkitchatcontainer.h
src/webkitchatcontainer.cpp
src/chatview.h
src/messagingwidget.h
src/messagingwidget.cpp
src/chatview.cpp
src/avatarmanipulation.h
src/avatarmanipulation.cpp
......
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg3398"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="baseline-mic-24px.svg">
<metadata
id="metadata3408">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3406" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1855"
inkscape:window-height="1176"
id="namedview3404"
showgrid="false"
inkscape:snap-grids="true"
inkscape:zoom="5.4114583"
inkscape:cx="-1.4303771"
inkscape:cy="8.3244998"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg3398" />
<path
d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z"
id="path3400" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path3402" />
<circle
style="fill:#dc2719"
cx="17.333334"
cy="17.666666"
r="3.3333333"
id="circle3476" />
<ellipse
style="fill:none;stroke-width:0.1;stroke-miterlimit:4;stroke-dasharray:none"
id="path4305"
cx="-8.3156881"
cy="-1.3628489"
rx="3.9268527"
ry="6.0981712" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M6 6h12v12H6z"/>
</svg>
......@@ -12,6 +12,8 @@
<file alias="call_start">ic_video_call_black_24px.svg</file>
<file alias="call_end">ic_call_end_white_24px.svg</file>
<file alias="record">ic_fiber_manual_record_red_24px.svg</file>
<file alias="record_audio">baseline-mic-24px.svg</file>
<file alias="recording_audio">baseline-mic-recording-24px.svg</file>
<file alias="contact">contact.svg</file>
<file alias="accept">accept.svg</file>
<file alias="chat">ic_chat_white_24px.svg</file>
......@@ -20,6 +22,8 @@
<file alias="unmute_video">ic_videocam_off_white_24px.svg</file>
<file alias="mute_video">ic_videocam_white_24px.svg</file>
<file alias="pause">ic_pause_white_24px.svg</file>
<file alias="stop">baseline-stop-24px.svg</file>
<file alias="send">baseline-send-24px.svg</file>
<file alias="play">ic_play_arrow_white_24px.svg</file>
<file alias="quality">ic_high_quality_white_24px.svg</file>
<file alias="contacts_list">ic_people_black_24px.svg</file>
......@@ -28,6 +32,7 @@
<file alias="history_list">ic_history_black_24px.svg</file>
<file alias="add">add.svg</file>
<file alias="reject">reject.svg</file>
<file alias="quit">baseline-exit_to_app-24px.svg</file>
<file alias="block">block.svg</file>
<file alias="block_black">block_black.svg</file>
<file alias="invite">ic_person_add_black_24px.svg</file>
......
......@@ -17,4 +17,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
namespace lrc
{
namespace api
{
namespace account
{
struct Info;
}
}
}
typedef const lrc::api::account::Info* AccountInfoPointer;
......@@ -3,6 +3,7 @@
* Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
* Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
* Author: Hugo Lefeuvre <hugo.lefeuvre@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
......@@ -21,11 +22,19 @@
#include "incomingcallview.h"
// Gtk
/* std */
#include <stdexcept>
// GTK+ related
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
// Qt
#include <QSize>
// Lrc
#include <api/avmodel.h>
#include <api/newcallmodel.h>
#include <api/contactmodel.h>
#include <api/conversationmodel.h>
......@@ -34,6 +43,7 @@
// Client
#include "chatview.h"
#include "messagingwidget.h"
#include "native/pixbufmanipulator.h"
#include "utils/drawing.h"
#include "utils/files.h"
......@@ -61,6 +71,8 @@ struct _IncomingCallViewPrivate
GtkWidget *button_accept_incoming;
GtkWidget *button_reject_incoming;
GtkWidget *frame_chat;
GtkWidget *box_messaging_widget;
GtkWidget *messaging_widget;
// The webkit_chat_container is created once, then reused for all chat views
GtkWidget *webkit_chat_container;
......@@ -101,6 +113,7 @@ incoming_call_view_dispose(GObject *object)
static gboolean
map_boolean_to_orientation(GValue *value, GVariant *variant, G_GNUC_UNUSED gpointer user_data)
{
bool ret = FALSE;
if (g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)) {
if (g_variant_get_boolean(variant)) {
// true, chat should be horizontal (to the right)
......@@ -109,9 +122,9 @@ map_boolean_to_orientation(GValue *value, GVariant *variant, G_GNUC_UNUSED gpoin
// false, chat should be vertical (at the bottom)
g_value_set_enum(value, GTK_ORIENTATION_VERTICAL);
}
return TRUE;
ret = TRUE;
}
return FALSE;
return ret;
}
static void
......@@ -127,8 +140,9 @@ accept_incoming_call(G_GNUC_UNUSED GtkWidget *widget, IncomingCallView *self)
{
g_return_if_fail(IS_INCOMING_CALL_VIEW(self));
auto priv = INCOMING_CALL_VIEW_GET_PRIVATE(self);
auto contactUri = priv->conversation_->participants[0];
try {
auto contactUri = priv->conversation_->participants.at(0);
auto contact = (*priv->accountInfo_)->contactModel->getContact(contactUri);
// If the contact is pending, we should accept its request
if (contact.profileInfo.type == lrc::api::profile::Type::PENDING)
......@@ -140,6 +154,14 @@ accept_incoming_call(G_GNUC_UNUSED GtkWidget *widget, IncomingCallView *self)
}
}
static void
on_leave_action(IncomingCallView *view)
{
g_return_if_fail(IS_INCOMING_CALL_VIEW(view));
auto priv = INCOMING_CALL_VIEW_GET_PRIVATE(view);
(*priv->accountInfo_)->conversationModel->selectConversation(priv->conversation_->uid);
}
static void
incoming_call_view_init(IncomingCallView *view)
{
......@@ -154,6 +176,7 @@ incoming_call_view_init(IncomingCallView *view)
.green-button:hover { background: #219d55; }",
-1, nullptr
);
gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()),
GTK_STYLE_PROVIDER(provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
......@@ -186,9 +209,10 @@ incoming_call_view_class_init(IncomingCallViewClass *klass)
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), IncomingCallView, label_bestId);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), IncomingCallView, spinner_status);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), IncomingCallView, label_status);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), IncomingCallView, button_accept_incoming);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), IncomingCallView, button_reject_incoming);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), IncomingCallView, button_accept_incoming);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), IncomingCallView, frame_chat);
gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), IncomingCallView, box_messaging_widget);
}
static void
......@@ -202,17 +226,21 @@ update_state(IncomingCallView *view)
if (!(*priv->accountInfo_)->callModel->hasCall(callId)) return;
auto call = (*priv->accountInfo_)->callModel->getCall(callId);
gchar *status = g_strdup_printf("%s", lrc::api::call::to_string(call.status).c_str());
gtk_label_set_text(GTK_LABEL(priv->label_status), status);
g_free(status);
gtk_label_set_text(GTK_LABEL(priv->label_status), lrc::api::call::to_string(call.status).c_str());
if (call.status == lrc::api::call::Status::INCOMING_RINGING)
gtk_widget_show(priv->button_accept_incoming);
else
gtk_widget_hide(priv->button_accept_incoming);
gtk_widget_show(priv->button_reject_incoming);
gtk_widget_show(priv->spinner_status);
if (call.status != lrc::api::call::Status::PEER_BUSY &&
call.status != lrc::api::call::Status::ENDED) {
gtk_widget_hide(priv->messaging_widget);
gtk_widget_show(priv->label_status);
gtk_widget_show(priv->spinner_status);
gtk_widget_show(priv->button_reject_incoming);
gtk_widget_show(priv->spinner_status);
}
}
static void
......@@ -275,6 +303,7 @@ set_call_info(IncomingCallView *view) {
GtkWidget *
incoming_call_view_new(WebKitChatContainer* view,
lrc::api::AVModel& avModel,
AccountInfoPointer const & accountInfo,
lrc::api::conversation::Info* conversation)
{
......@@ -285,6 +314,10 @@ incoming_call_view_new(WebKitChatContainer* view,
priv->conversation_ = conversation;
priv->accountInfo_ = &accountInfo;
priv->messaging_widget = messaging_widget_new(avModel, conversation, accountInfo);
gtk_box_pack_start(GTK_BOX(priv->box_messaging_widget), priv->messaging_widget, TRUE, TRUE, 0);
g_signal_connect_swapped(priv->messaging_widget, "leave-action", G_CALLBACK(on_leave_action), self);
set_call_info(INCOMING_CALL_VIEW(self));
return GTK_WIDGET(self);
......@@ -298,3 +331,18 @@ incoming_call_view_get_conversation(IncomingCallView *self)
return *priv->conversation_;
}
void
incoming_call_view_let_a_message(IncomingCallView* view, lrc::api::conversation::Info conv)
{
g_return_if_fail(IS_INCOMING_CALL_VIEW(view));
auto priv = INCOMING_CALL_VIEW_GET_PRIVATE(view);
g_return_if_fail(priv->conversation_->uid == conv.uid);
gtk_widget_hide(priv->label_status);
gtk_widget_hide(priv->spinner_status);
gtk_widget_hide(priv->button_accept_incoming);
gtk_widget_hide(priv->button_reject_incoming);
gtk_widget_show(priv->messaging_widget);
}
......@@ -33,6 +33,7 @@ namespace lrc
{
namespace api
{
class AVModel;
namespace conversation
{
struct Info;
......@@ -54,8 +55,10 @@ typedef struct _IncomingCallViewClass IncomingCallViewClass;
GType incoming_call_view_get_type (void) G_GNUC_CONST;
GtkWidget *incoming_call_view_new (WebKitChatContainer* view,
lrc::api::AVModel& avModel,
AccountInfoPointer const & accountInfo,
lrc::api::conversation::Info* conversation);
void incoming_call_view_let_a_message(IncomingCallView* view, lrc::api::conversation::Info conv);
lrc::api::conversation::Info incoming_call_view_get_conversation (IncomingCallView*);
G_END_DECLS
This diff is collapsed.
/*
* Copyright (C) 2018 Savoir-faire Linux Inc.
* Author: Hugo Lefeuvre <hugo.lefeuvre@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.
*/
#pragma once
// GTK
#include <gtk/gtk.h>
// std
#include <string>
// client
#include "accountinfopointer.h"
namespace lrc
{
namespace api
{
class AVModel;
namespace conversation
{
struct Info;
}
}
}
G_BEGIN_DECLS
#define MESSAGING_WIDGET_TYPE (messaging_widget_get_type ())
#define MESSAGING_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MESSAGING_WIDGET_TYPE, MessagingWidget))
#define MESSAGING_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MESSAGING_WIDGET_TYPE, MessagingWidget))
#define IS_MESSAGING_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MESSAGING_WIDGET_TYPE))
#define IS_MESSAGING_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MESSAGING_WIDGET_TYPE))
typedef struct _MessagingWidget MessagingWidget;
typedef struct _MessagingWidgetClass MessagingWidgetClass;
typedef enum
{
MESSAGING_WIDGET_STATE_INIT,
MESSAGING_WIDGET_REC_AUDIO,
MESSAGING_WIDGET_AUDIO_REC_SUCCESS,
MESSAGING_WIDGET_REC_SENT
} MessagingWidgetState;
GType messaging_widget_get_type (void) G_GNUC_CONST;
GtkWidget* messaging_widget_new (lrc::api::AVModel& avModel,
lrc::api::conversation::Info* conversation,
AccountInfoPointer const & accountInfo);
void messaging_widget_set_peer_name (MessagingWidget *self, std::string name);
G_END_DECLS
......@@ -318,6 +318,7 @@ public:
int contactRequestsPageNum = 0;
QMetaObject::Connection showChatViewConnection_;
QMetaObject::Connection showLeaveMessageViewConnection_;
QMetaObject::Connection showCallViewConnection_;
QMetaObject::Connection showIncomingViewConnection_;
QMetaObject::Connection newTrustRequestNotification_;
......@@ -361,6 +362,7 @@ private:
void slotNewConversation(const std::string& uid);
void slotConversationRemoved(const std::string& uid);
void slotShowChatView(const std::string& id, lrc::api::conversation::Info origin);
void slotShowLeaveMessageView(lrc::api::conversation::Info conv);
void slotShowCallView(const std::string& id, lrc::api::conversation::Info origin);
void slotShowIncomingCallView(const std::string& id, lrc::api::conversation::Info origin);
void slotNewTrustRequest(const std::string& id, const std::string& contactUri);
......@@ -1138,6 +1140,7 @@ CppImpl::init()
CppImpl::~CppImpl()
{
QObject::disconnect(showLeaveMessageViewConnection_);
QObject::disconnect(showChatViewConnection_);
QObject::disconnect(showIncomingViewConnection_);
QObject::disconnect(historyClearedConnection_);
......@@ -1202,7 +1205,7 @@ GtkWidget*
CppImpl::displayIncomingView(lrc::api::conversation::Info conversation)
{
chatViewConversation_.reset(new lrc::api::conversation::Info(conversation));
return incoming_call_view_new(webkitChatContainer(), accountInfo_, chatViewConversation_.get());
return incoming_call_view_new(webkitChatContainer(), lrc_->getAVModel(), accountInfo_, chatViewConversation_.get());
}
GtkWidget*
......@@ -1541,6 +1544,7 @@ void
CppImpl::updateLrc(const std::string& id, const std::string& accountIdToFlagFreeable)
{
// Disconnect old signals.
QObject::disconnect(showLeaveMessageViewConnection_);
QObject::disconnect(showChatViewConnection_);
QObject::disconnect(showIncomingViewConnection_);
QObject::disconnect(changeAccountConnection_);
......@@ -1627,6 +1631,10 @@ CppImpl::updateLrc(const std::string& id, const std::string& accountIdToFlagFree
&lrc::api::BehaviorController::showChatView,
[this] (const std::string& id, lrc::api::conversation::Info origin) { slotShowChatView(id, origin); });
showLeaveMessageViewConnection_ = QObject::connect(&lrc_->getBehaviorController(),
&lrc::api::BehaviorController::showLeaveMessageView,
[this] (const std::string&, lrc::api::conversation::Info conv) { slotShowLeaveMessageView(conv); });
showCallViewConnection_ = QObject::connect(&lrc_->getBehaviorController(),
&lrc::api::BehaviorController::showCallView,
[this] (const std::string& id, lrc::api::conversation::Info origin) { slotShowCallView(id, origin); });
......@@ -1940,6 +1948,15 @@ CppImpl::slotShowChatView(const std::string& id, lrc::api::conversation::Info or
}
}
void
CppImpl::slotShowLeaveMessageView(lrc::api::conversation::Info conv)
{
auto* current_view = gtk_bin_get_child(GTK_BIN(widgets->frame_call));
if (IS_INCOMING_CALL_VIEW(current_view)) {
incoming_call_view_let_a_message(INCOMING_CALL_VIEW(current_view), conv);
}
}
void
CppImpl::slotShowCallView(const std::string& id, lrc::api::conversation::Info origin)
{
......@@ -2071,12 +2088,10 @@ CppImpl::slotShowIncomingCallView(const std::string& id, lrc::api::conversation:
// Change the view if we want a different view.
auto* old_view = gtk_bin_get_child(GTK_BIN(widgets->frame_call));
lrc::api::conversation::Info current_item;
if (IS_INCOMING_CALL_VIEW(old_view))
current_item = incoming_call_view_get_conversation(INCOMING_CALL_VIEW(old_view));
if (current_item.uid != origin.uid)
changeView(INCOMING_CALL_VIEW_TYPE, origin);
/* call changeView even if we are already in an incoming call view, since
the incoming call view holds a copy of the conversation info which has
the be updated */
changeView(INCOMING_CALL_VIEW_TYPE, origin);
}
void
......
......@@ -111,6 +111,23 @@
</child>
<!-- end info vbox -->
<!-- box action bar -->
<child>
<object class="GtkBox" id="box_messaging_widget">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">20</property>
<property name="border_width">20</property>
<property name="valign">center</property>
<property name="halign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<!-- end box messaging widget -->
<!-- hbox action bar -->
<child>
<object class="GtkBox" id="hbox_action_bar">
......
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.10"/>
<template class="MessagingWidget" parent="GtkVBox">
<child>
<object class="GtkLabel" id="label_letmessage">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkBox" id="box_timer">
<property name="visible">False</property>
<property name="halign">center</property>
<property name="margin-top">15px</property>
<property name="margin-bottom">5px</property>
<style>
<class name="timer-box"/>
</style>
<child>
<object class="GtkBox" id="box_red_dot">
<property name="visible">False</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="resource">/cx/ring/RingGnome/record</property>
<child internal-child="accessible">
<object class="AtkObject" id="image_record-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Record</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label">REC</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="label_duration">
<style>
<class name="time-label"/>
</style>
<property name="visible">False</property>
<property name="label">00:00</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox_action_bar">
<property name="visible">True</property>
<property name="orientation">horizontal</property>
<property name="spacing">20</property>
<property name="border_width">20</property>
<property name="valign">center</property>
<property name="halign">center</property>
<child>
<object class="GtkButton" id="button_record_audio">
<style>
<class name="grey-button"/>
<class name="flat-button"/>
</style>
<property name="width-request">48</property>
<property name="height-request">48</property>
<property name="visible">False</property>
<property name="can_focus">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip-text" translatable="yes">Record audio message</property>
<property name="image">image_record_audio</property>
<property name="action-name">app.record-audio</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_end_without_message">
<style>
<class name="grey-button"/>
<class name="flat-button"/>
</style>
<property name="width-request">48</property>
<property name="height-request">48</property>
<property name="visible">False</property>
<property name="can_focus">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip-text" translatable="yes">End without message</property>
<property name="image">image_end_without_message</property>
<property name="action-name">app.end-without-message</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
</child>
</template>
<object class="GtkImage" id="image_record_audio">
<property name="visible">True</property>
<property name="resource">/cx/ring/RingGnome/record_audio</property>
</object>
<object class="GtkImage" id="image_stop">
<property name="visible">True</property>
<property name="resource">/cx/ring/RingGnome/stop</property>
</object>
<object class="GtkImage" id="image_end_without_message">
<property name="visible">True</property>
<property name="resource">/cx/ring/RingGnome/quit</property>
</object>
<object class="GtkImage" id="image_send">
<property name="visible">True</property>
<property name="resource">/cx/ring/RingGnome/send</property>
</object>
</interface>
......@@ -11,6 +11,7 @@
<file preprocess="xml-stripblanks">mediasettingsview.ui</file>
<file preprocess="xml-stripblanks">generalsettingsview.ui</file>
<file preprocess="xml-stripblanks">chatview.ui</file>
<file preprocess="xml-stripblanks">messagingwidget.ui</file>
<file preprocess="xml-stripblanks">avatarmanipulation.ui</file>
<file preprocess="xml-stripblanks">webkitchatcontainer.ui</file>
<file preprocess="xml-stripblanks">usernameregistrationbox.ui</file>
......
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