| |
1 /* |
| |
2 * Pidgin - Internet Messenger |
| |
3 * Copyright (C) Pidgin Developers <devel@pidgin.im> |
| |
4 * |
| |
5 * Pidgin is the legal property of its developers, whose names are too numerous |
| |
6 * to list here. Please refer to the COPYRIGHT file distributed with this |
| |
7 * source distribution. |
| |
8 * |
| |
9 * This program is free software; you can redistribute it and/or modify |
| |
10 * it under the terms of the GNU General Public License as published by |
| |
11 * the Free Software Foundation; either version 2 of the License, or |
| |
12 * (at your option) any later version. |
| |
13 * |
| |
14 * This program is distributed in the hope that it will be useful, |
| |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| |
17 * GNU General Public License for more details. |
| |
18 * |
| |
19 * You should have received a copy of the GNU General Public License |
| |
20 * along with this program; if not, see <https://www.gnu.org/licenses/>. |
| |
21 */ |
| |
22 |
| |
23 #include <glib/gi18n-lib.h> |
| |
24 |
| |
25 #include <purple.h> |
| |
26 |
| |
27 #include "pidgin/pidginconversation.h" |
| |
28 #include "pidgin/pidgininfopane.h" |
| |
29 #include "pidgin/pidginmessage.h" |
| |
30 |
| |
31 #define PIDGIN_CONVERSATION_DATA ("pidgin-conversation") |
| |
32 |
| |
33 enum { |
| |
34 PROP_0, |
| |
35 PROP_CONVERSATION, |
| |
36 N_PROPERTIES, |
| |
37 }; |
| |
38 static GParamSpec *properties[N_PROPERTIES] = {NULL,}; |
| |
39 |
| |
40 struct _PidginConversation { |
| |
41 GtkBox parent; |
| |
42 |
| |
43 PurpleConversation *conversation; |
| |
44 |
| |
45 GtkWidget *info_pane; |
| |
46 GtkWidget *editor; |
| |
47 GtkWidget *history; |
| |
48 }; |
| |
49 |
| |
50 G_DEFINE_TYPE(PidginConversation, pidgin_conversation, GTK_TYPE_BOX) |
| |
51 |
| |
52 /****************************************************************************** |
| |
53 * Helpers |
| |
54 *****************************************************************************/ |
| |
55 static void |
| |
56 pidgin_conversation_set_conversation(PidginConversation *conversation, |
| |
57 PurpleConversation *purple_conversation) |
| |
58 { |
| |
59 if(g_set_object(&conversation->conversation, purple_conversation)) { |
| |
60 if(PURPLE_IS_CONVERSATION(purple_conversation)) { |
| |
61 g_object_set_data(G_OBJECT(purple_conversation), |
| |
62 PIDGIN_CONVERSATION_DATA, conversation); |
| |
63 } |
| |
64 |
| |
65 pidgin_info_pane_set_conversation(PIDGIN_INFO_PANE(conversation->info_pane), |
| |
66 purple_conversation); |
| |
67 |
| |
68 g_object_notify_by_pspec(G_OBJECT(conversation), |
| |
69 properties[PROP_CONVERSATION]); |
| |
70 } |
| |
71 } |
| |
72 |
| |
73 /****************************************************************************** |
| |
74 * Callbacks |
| |
75 *****************************************************************************/ |
| |
76 static void |
| |
77 pidgin_conversation_send_message_cb(TalkatuInput *input, gpointer data) { |
| |
78 PidginConversation *conversation = data; |
| |
79 const char *contents = NULL; |
| |
80 |
| |
81 contents = talkatu_message_get_contents(TALKATU_MESSAGE(input)); |
| |
82 |
| |
83 purple_conversation_send(conversation->conversation, contents); |
| |
84 |
| |
85 talkatu_message_set_contents(TALKATU_MESSAGE(input), ""); |
| |
86 } |
| |
87 |
| |
88 static void |
| |
89 pidgin_conversation_detach(PidginConversation *conversation) { |
| |
90 if(PURPLE_IS_CONVERSATION(conversation->conversation)) { |
| |
91 gpointer us = NULL; |
| |
92 |
| |
93 us = g_object_get_data(G_OBJECT(conversation->conversation), |
| |
94 PIDGIN_CONVERSATION_DATA); |
| |
95 |
| |
96 if(conversation == us) { |
| |
97 g_object_set_data(G_OBJECT(conversation->conversation), |
| |
98 PIDGIN_CONVERSATION_DATA, NULL); |
| |
99 } |
| |
100 } |
| |
101 } |
| |
102 |
| |
103 /****************************************************************************** |
| |
104 * GObject Implementation |
| |
105 *****************************************************************************/ |
| |
106 static void |
| |
107 pidgin_conversation_dispose(GObject *obj) { |
| |
108 PidginConversation *conversation = PIDGIN_CONVERSATION(obj); |
| |
109 |
| |
110 pidgin_conversation_detach(conversation); |
| |
111 |
| |
112 g_clear_object(&conversation->conversation); |
| |
113 |
| |
114 G_OBJECT_CLASS(pidgin_conversation_parent_class)->dispose(obj); |
| |
115 } |
| |
116 |
| |
117 static void |
| |
118 pidgin_conversation_get_property(GObject *obj, guint param_id, GValue *value, |
| |
119 GParamSpec *pspec) |
| |
120 { |
| |
121 PidginConversation *conversation = PIDGIN_CONVERSATION(obj); |
| |
122 |
| |
123 switch(param_id) { |
| |
124 case PROP_CONVERSATION: |
| |
125 g_value_set_object(value, |
| |
126 pidgin_conversation_get_conversation(conversation)); |
| |
127 break; |
| |
128 default: |
| |
129 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); |
| |
130 break; |
| |
131 } |
| |
132 } |
| |
133 |
| |
134 static void |
| |
135 pidgin_conversation_set_property(GObject *obj, guint param_id, |
| |
136 const GValue *value, GParamSpec *pspec) |
| |
137 { |
| |
138 PidginConversation *conversation = PIDGIN_CONVERSATION(obj); |
| |
139 |
| |
140 switch(param_id) { |
| |
141 case PROP_CONVERSATION: |
| |
142 pidgin_conversation_set_conversation(conversation, |
| |
143 g_value_get_object(value)); |
| |
144 break; |
| |
145 default: |
| |
146 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); |
| |
147 break; |
| |
148 } |
| |
149 } |
| |
150 |
| |
151 static void |
| |
152 pidgin_conversation_init(PidginConversation *conversation) { |
| |
153 gtk_widget_init_template(GTK_WIDGET(conversation)); |
| |
154 } |
| |
155 |
| |
156 static void |
| |
157 pidgin_conversation_class_init(PidginConversationClass *klass) { |
| |
158 GObjectClass *obj_class = G_OBJECT_CLASS(klass); |
| |
159 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); |
| |
160 |
| |
161 obj_class->dispose = pidgin_conversation_dispose; |
| |
162 obj_class->get_property = pidgin_conversation_get_property; |
| |
163 obj_class->set_property = pidgin_conversation_set_property; |
| |
164 |
| |
165 /** |
| |
166 * PidginConversation:conversation: |
| |
167 * |
| |
168 * The [class@Purple.Conversation] that this conversation is displaying. |
| |
169 * |
| |
170 * Since: 3.0.0 |
| |
171 */ |
| |
172 properties[PROP_CONVERSATION] = g_param_spec_object( |
| |
173 "conversation", "conversation", |
| |
174 "The purple conversation this widget is for.", |
| |
175 PURPLE_TYPE_CONVERSATION, |
| |
176 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); |
| |
177 |
| |
178 g_object_class_install_properties(obj_class, N_PROPERTIES, properties); |
| |
179 |
| |
180 /* Template stuff. */ |
| |
181 gtk_widget_class_set_template_from_resource( |
| |
182 widget_class, |
| |
183 "/im/pidgin/Pidgin3/Conversations/conversation.ui" |
| |
184 ); |
| |
185 |
| |
186 gtk_widget_class_bind_template_child(widget_class, PidginConversation, |
| |
187 info_pane); |
| |
188 gtk_widget_class_bind_template_child(widget_class, PidginConversation, |
| |
189 editor); |
| |
190 gtk_widget_class_bind_template_child(widget_class, PidginConversation, |
| |
191 history); |
| |
192 |
| |
193 gtk_widget_class_bind_template_callback(widget_class, |
| |
194 pidgin_conversation_send_message_cb); |
| |
195 } |
| |
196 |
| |
197 /****************************************************************************** |
| |
198 * API |
| |
199 *****************************************************************************/ |
| |
200 GtkWidget * |
| |
201 pidgin_conversation_new(PurpleConversation *conversation) { |
| |
202 g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), NULL); |
| |
203 |
| |
204 return g_object_new( |
| |
205 PIDGIN_TYPE_CONVERSATION, |
| |
206 "conversation", conversation, |
| |
207 NULL); |
| |
208 } |
| |
209 |
| |
210 GtkWidget * |
| |
211 pidgin_conversation_from_purple_conversation(PurpleConversation *conversation) |
| |
212 { |
| |
213 g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), NULL); |
| |
214 |
| |
215 return g_object_get_data(G_OBJECT(conversation), PIDGIN_CONVERSATION_DATA); |
| |
216 } |
| |
217 |
| |
218 PurpleConversation * |
| |
219 pidgin_conversation_get_conversation(PidginConversation *conversation) { |
| |
220 g_return_val_if_fail(PIDGIN_IS_CONVERSATION(conversation), NULL); |
| |
221 |
| |
222 return conversation->conversation; |
| |
223 } |
| |
224 |
| |
225 void |
| |
226 pidgin_conversation_write_message(PidginConversation *conversation, |
| |
227 PurpleMessage *purple_message) |
| |
228 { |
| |
229 PidginMessage *message = NULL; |
| |
230 |
| |
231 g_return_if_fail(PIDGIN_IS_CONVERSATION(conversation)); |
| |
232 g_return_if_fail(PURPLE_IS_MESSAGE(purple_message)); |
| |
233 |
| |
234 message = pidgin_message_new(purple_message); |
| |
235 |
| |
236 talkatu_history_write_message(TALKATU_HISTORY(conversation->history), |
| |
237 TALKATU_MESSAGE(message)); |
| |
238 |
| |
239 g_clear_object(&message); |
| |
240 } |
| |
241 |
| |
242 void |
| |
243 pidgin_conversation_close(PidginConversation *conversation) { |
| |
244 g_return_if_fail(PIDGIN_IS_CONVERSATION(conversation)); |
| |
245 |
| |
246 pidgin_conversation_detach(conversation); |
| |
247 } |