Commit e7854ba0 authored by Sébastien Blin's avatar Sébastien Blin Committed by Ming Rui Zhang

chatview: fix crash when adding SIP contacts

A regression occured with the patch to fix the creation of the
chatview (when reparenting). This patch fix it.

Change-Id: I26a97812e65311619964898d646052d7f8482669
parent 15d170e8
...@@ -315,6 +315,9 @@ SET( SRC_FILES ...@@ -315,6 +315,9 @@ SET( SRC_FILES
src/accountinfopointer.h src/accountinfopointer.h
src/profileview.h src/profileview.h
src/profileview.cpp src/profileview.cpp
# Generated marshals
src/marshals.h
src/marshals.cpp
) )
# compile glib resource files to c code # compile glib resource files to c code
......
...@@ -90,3 +90,10 @@ For now, the build type of the client is "Debug" by default, however it is ...@@ -90,3 +90,10 @@ For now, the build type of the client is "Debug" by default, however it is
useful to also have the debug symbols of libRingClient. To do this, specify this useful to also have the debug symbols of libRingClient. To do this, specify this
when compiling libRingClient with `-DCMAKE_BUILD_TYPE=Debug` in the cmake when compiling libRingClient with `-DCMAKE_BUILD_TYPE=Debug` in the cmake
options. options.
## Generating marshals.*
```
glib-genmarshal --header marshals.list > marshals.h
glib-genmarshal --include-header=marshals.h --body marshals.list > marshals.cpp
```
\ No newline at end of file
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
// Client // Client
#include "utils/files.h" #include "utils/files.h"
#include "marshals.h"
struct CppImpl { struct CppImpl {
struct Interaction { struct Interaction {
...@@ -93,6 +94,8 @@ enum { ...@@ -93,6 +94,8 @@ enum {
HIDE_VIEW_CLICKED, HIDE_VIEW_CLICKED,
PLACE_CALL_CLICKED, PLACE_CALL_CLICKED,
PLACE_AUDIO_CALL_CLICKED, PLACE_AUDIO_CALL_CLICKED,
ADD_CONVERSATION_CLICKED,
SEND_TEXT_CLICKED,
LAST_SIGNAL LAST_SIGNAL
}; };
...@@ -168,11 +171,19 @@ place_audio_call_clicked(ChatView *self) ...@@ -168,11 +171,19 @@ place_audio_call_clicked(ChatView *self)
} }
static void static void
button_add_to_conversations_clicked(ChatView *self) add_to_conversations_clicked(ChatView *self)
{ {
auto priv = CHAT_VIEW_GET_PRIVATE(self); auto priv = CHAT_VIEW_GET_PRIVATE(self);
if (!priv->conversation_) return; if (!priv->conversation_) return;
(*priv->accountInfo_)->conversationModel->makePermanent(priv->conversation_->uid); g_signal_emit(G_OBJECT(self), chat_view_signals[ADD_CONVERSATION_CLICKED], 0, priv->conversation_->uid.c_str());
}
static void
send_text_clicked(ChatView *self, const std::string& body)
{
auto priv = CHAT_VIEW_GET_PRIVATE(self);
if (!priv->conversation_) return;
g_signal_emit(G_OBJECT(self), chat_view_signals[SEND_TEXT_CLICKED], 0, priv->conversation_->uid.c_str(), body.c_str());
} }
static gchar* static gchar*
...@@ -232,9 +243,13 @@ webkit_chat_container_script_dialog(GtkWidget* webview, gchar *interaction, Chat ...@@ -232,9 +243,13 @@ webkit_chat_container_script_dialog(GtkWidget* webview, gchar *interaction, Chat
} else if (order.find("CLOSE_CHATVIEW") == 0) { } else if (order.find("CLOSE_CHATVIEW") == 0) {
hide_chat_view(webview, self); hide_chat_view(webview, self);
} else if (order.find("SEND:") == 0) { } else if (order.find("SEND:") == 0) {
// Get text body
auto toSend = order.substr(std::string("SEND:").size()); auto toSend = order.substr(std::string("SEND:").size());
(*priv->accountInfo_)->conversationModel->sendMessage(priv->conversation_->uid, toSend); if ((*priv->accountInfo_)->profileInfo.type == lrc::api::profile::Type::RING) {
(*priv->accountInfo_)->conversationModel->sendMessage(priv->conversation_->uid, toSend);
} else {
// For SIP accounts, we need to wait that the conversation is created to send text
send_text_clicked(self, toSend);
}
} else if (order.find("SEND_FILE") == 0) { } else if (order.find("SEND_FILE") == 0) {
if (auto model = (*priv->accountInfo_)->conversationModel.get()) { if (auto model = (*priv->accountInfo_)->conversationModel.get()) {
if (auto filename = file_to_manipulate(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(self))), true)) if (auto filename = file_to_manipulate(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(self))), true))
...@@ -295,7 +310,7 @@ webkit_chat_container_script_dialog(GtkWidget* webview, gchar *interaction, Chat ...@@ -295,7 +310,7 @@ webkit_chat_container_script_dialog(GtkWidget* webview, gchar *interaction, Chat
g_error_free(error); g_error_free(error);
} }
} else if (order.find("ADD_TO_CONVERSATIONS") == 0) { } else if (order.find("ADD_TO_CONVERSATIONS") == 0) {
button_add_to_conversations_clicked(self); add_to_conversations_clicked(self);
} else if (order.find("DELETE_INTERACTION:") == 0) { } else if (order.find("DELETE_INTERACTION:") == 0) {
try { try {
auto interactionId = std::stoull(order.substr(std::string("DELETE_INTERACTION:").size())); auto interactionId = std::stoull(order.substr(std::string("DELETE_INTERACTION:").size()));
...@@ -373,6 +388,26 @@ chat_view_class_init(ChatViewClass *klass) ...@@ -373,6 +388,26 @@ chat_view_class_init(ChatViewClass *klass)
nullptr, nullptr,
g_cclosure_marshal_VOID__STRING, g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING); G_TYPE_NONE, 1, G_TYPE_STRING);
chat_view_signals[ADD_CONVERSATION_CLICKED] = g_signal_new (
"add-conversation-clicked",
G_TYPE_FROM_CLASS(klass),
(GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
0,
nullptr,
nullptr,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
chat_view_signals[SEND_TEXT_CLICKED] = g_signal_new (
"send-text-clicked",
G_TYPE_FROM_CLASS(klass),
(GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
0,
nullptr,
nullptr,
g_cclosure_user_marshal_VOID__STRING_STRING,
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
} }
static void static void
......
/* This file is generated by glib-genmarshal, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */
#include "marshals.h"
#include <glib-object.h>
#ifdef G_ENABLE_DEBUG
#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
#define g_marshal_value_peek_char(v) g_value_get_schar (v)
#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
#define g_marshal_value_peek_int(v) g_value_get_int (v)
#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
#define g_marshal_value_peek_long(v) g_value_get_long (v)
#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
#define g_marshal_value_peek_float(v) g_value_get_float (v)
#define g_marshal_value_peek_double(v) g_value_get_double (v)
#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
#define g_marshal_value_peek_param(v) g_value_get_param (v)
#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
#define g_marshal_value_peek_object(v) g_value_get_object (v)
#define g_marshal_value_peek_variant(v) g_value_get_variant (v)
#else /* !G_ENABLE_DEBUG */
/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
* Do not access GValues directly in your code. Instead, use the
* g_value_get_*() functions
*/
#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
#define g_marshal_value_peek_char(v) (v)->data[0].v_int
#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
#define g_marshal_value_peek_int(v) (v)->data[0].v_int
#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
#define g_marshal_value_peek_long(v) (v)->data[0].v_long
#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_float(v) (v)->data[0].v_float
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer
#endif /* !G_ENABLE_DEBUG */
/* VOID:STRING,STRING (marshals.list:1) */
void
g_cclosure_user_marshal_VOID__STRING_STRING (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer data1,
gpointer arg1,
gpointer arg2,
gpointer data2);
GCClosure *cc = (GCClosure *) closure;
gpointer data1, data2;
GMarshalFunc_VOID__STRING_STRING callback;
g_return_if_fail (n_param_values == 3);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback);
callback (data1,
g_marshal_value_peek_string (param_values + 1),
g_marshal_value_peek_string (param_values + 2),
data2);
}
/* This file is generated by glib-genmarshal, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */
#ifndef __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__
#define __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__
#include <glib-object.h>
G_BEGIN_DECLS
/* VOID:STRING,STRING (marshallers.list:1) */
extern
void g_cclosure_user_marshal_VOID__STRING_STRING (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data);
G_END_DECLS
#endif /* __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__ */
VOID:STRING,STRING
\ No newline at end of file
...@@ -368,6 +368,7 @@ public: ...@@ -368,6 +368,7 @@ public:
QMetaObject::Connection profileUpdatedConnection_; QMetaObject::Connection profileUpdatedConnection_;
std::string eventUid_; std::string eventUid_;
std::string eventBody_;
private: private:
CppImpl() = delete; CppImpl() = delete;
CppImpl(const CppImpl&) = delete; CppImpl(const CppImpl&) = delete;
...@@ -444,6 +445,51 @@ on_place_call_clicked(G_GNUC_UNUSED GtkWidget*, gchar *uid, RingMainWindow* self ...@@ -444,6 +445,51 @@ on_place_call_clicked(G_GNUC_UNUSED GtkWidget*, gchar *uid, RingMainWindow* self
g_idle_add((GSourceFunc)place_call_event, self); g_idle_add((GSourceFunc)place_call_event, self);
} }
static gboolean
add_conversation_event(RingMainWindow* self)
{
g_return_val_if_fail(IS_RING_MAIN_WINDOW(self), G_SOURCE_REMOVE);
auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
if (!priv->cpp->eventUid_.empty())
priv->cpp->accountInfo_->conversationModel->makePermanent(priv->cpp->eventUid_);
return G_SOURCE_REMOVE;
}
static void
on_add_conversation_clicked(G_GNUC_UNUSED GtkWidget*, gchar *uid, RingMainWindow* self)
{
g_return_if_fail(IS_RING_MAIN_WINDOW(self) && uid);
auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
priv->cpp->eventUid_ = uid;
g_idle_add((GSourceFunc)add_conversation_event, self);
}
static gboolean
send_text_event(RingMainWindow* self)
{
g_return_val_if_fail(IS_RING_MAIN_WINDOW(self), G_SOURCE_REMOVE);
auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
if (!priv->cpp->eventUid_.empty())
priv->cpp->accountInfo_->conversationModel->sendMessage(priv->cpp->eventUid_, priv->cpp->eventBody_);
return G_SOURCE_REMOVE;
}
static void
on_send_text_clicked(G_GNUC_UNUSED GtkWidget*, gchar* uid, gchar* body, RingMainWindow* self)
{
g_return_if_fail(IS_RING_MAIN_WINDOW(self) && uid);
auto* priv = RING_MAIN_WINDOW_GET_PRIVATE(RING_MAIN_WINDOW(self));
priv->cpp->eventUid_ = uid;
priv->cpp->eventBody_ = body;
g_idle_add((GSourceFunc)send_text_event, self);
}
static gboolean static gboolean
place_audio_call_event(RingMainWindow* self) place_audio_call_event(RingMainWindow* self)
{ {
...@@ -1395,8 +1441,10 @@ CppImpl::displayChatView(lrc::api::conversation::Info conversation, bool redraw_ ...@@ -1395,8 +1441,10 @@ CppImpl::displayChatView(lrc::api::conversation::Info conversation, bool redraw_
chatViewConversation_.reset(new lrc::api::conversation::Info(conversation)); chatViewConversation_.reset(new lrc::api::conversation::Info(conversation));
auto* new_view = chat_view_new(webkitChatContainer(redraw_webview), accountInfo_, chatViewConversation_.get()); auto* new_view = chat_view_new(webkitChatContainer(redraw_webview), accountInfo_, chatViewConversation_.get());
g_signal_connect_swapped(new_view, "hide-view-clicked", G_CALLBACK(on_hide_view_clicked), self); g_signal_connect_swapped(new_view, "hide-view-clicked", G_CALLBACK(on_hide_view_clicked), self);
g_signal_connect(new_view, "place-call-clicked", G_CALLBACK(on_place_call_clicked), self); g_signal_connect(new_view, "add-conversation-clicked", G_CALLBACK(on_add_conversation_clicked), self);
g_signal_connect(new_view, "place-audio-call-clicked", G_CALLBACK(on_place_audio_call_clicked), self); g_signal_connect(new_view, "place-audio-call-clicked", G_CALLBACK(on_place_audio_call_clicked), self);
g_signal_connect(new_view, "place-call-clicked", G_CALLBACK(on_place_call_clicked), self);
g_signal_connect(new_view, "send-text-clicked", G_CALLBACK(on_send_text_clicked), self);
try { try {
auto contactUri = chatViewConversation_->participants.front(); auto contactUri = chatViewConversation_->participants.front();
auto contactInfo = accountInfo_->contactModel->getContact(contactUri); auto contactInfo = accountInfo_->contactModel->getContact(contactUri);
......
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