pidgin/pidginconversationwindow.c

changeset 41696
35f8ce475b21
parent 41582
4ee4a8ddc190
child 41701
43f994f7f9f2
equal deleted inserted replaced
41695:6032b86cb76b 41696:35f8ce475b21
28 #include "gtkdialogs.h" 28 #include "gtkdialogs.h"
29 #include "gtkutils.h" 29 #include "gtkutils.h"
30 #include "pidgininvitedialog.h" 30 #include "pidgininvitedialog.h"
31 31
32 enum { 32 enum {
33 PIDGIN_CONVERSATION_WINDOW_COLUMN_OBJECT, 33 PIDGIN_DISPLAY_WINDOW_COLUMN_OBJECT,
34 PIDGIN_CONVERSATION_WINDOW_COLUMN_NAME, 34 PIDGIN_DISPLAY_WINDOW_COLUMN_NAME,
35 PIDGIN_CONVERSATION_WINDOW_COLUMN_ICON, 35 PIDGIN_DISPLAY_WINDOW_COLUMN_ICON,
36 PIDGIN_CONVERSATION_WINDOW_COLUMN_MARKUP, 36 PIDGIN_DISPLAY_WINDOW_COLUMN_MARKUP,
37 }; 37 };
38 38
39 enum { 39 enum {
40 SIG_CONVERSATION_SWITCHED, 40 SIG_CONVERSATION_SWITCHED,
41 N_SIGNALS, 41 N_SIGNALS,
42 }; 42 };
43 static guint signals[N_SIGNALS] = {0, }; 43 static guint signals[N_SIGNALS] = {0, };
44 44
45 struct _PidginConversationWindow { 45 struct _PidginDisplayWindow {
46 GtkApplicationWindow parent; 46 GtkApplicationWindow parent;
47 47
48 GtkWidget *vbox; 48 GtkWidget *vbox;
49 49
50 GtkWidget *view; 50 GtkWidget *view;
56 GtkWidget *notification_list; 56 GtkWidget *notification_list;
57 57
58 GtkTreePath *conversation_path; 58 GtkTreePath *conversation_path;
59 }; 59 };
60 60
61 G_DEFINE_TYPE(PidginConversationWindow, pidgin_conversation_window, 61 G_DEFINE_TYPE(PidginDisplayWindow, pidgin_display_window,
62 GTK_TYPE_APPLICATION_WINDOW) 62 GTK_TYPE_APPLICATION_WINDOW)
63 63
64 static GtkWidget *default_window = NULL; 64 static GtkWidget *default_window = NULL;
65 65
66 /****************************************************************************** 66 /******************************************************************************
67 * Helpers 67 * Helpers
68 *****************************************************************************/ 68 *****************************************************************************/
69 static void 69 static void
70 pidgin_conversation_window_actions_set_enabled(GActionMap *map, 70 pidgin_display_window_actions_set_enabled(GActionMap *map,
71 const gchar **actions, 71 const gchar **actions,
72 gboolean enabled) 72 gboolean enabled)
73 { 73 {
74 gint i = 0; 74 gint i = 0;
75 75
76 for(i = 0; actions[i] != NULL; i++) { 76 for(i = 0; actions[i] != NULL; i++) {
77 GAction *action = NULL; 77 GAction *action = NULL;
88 88
89 /****************************************************************************** 89 /******************************************************************************
90 * Callbacks 90 * Callbacks
91 *****************************************************************************/ 91 *****************************************************************************/
92 static void 92 static void
93 pidgin_conversation_window_invite_cb(GtkDialog *dialog, gint response_id, 93 pidgin_display_window_invite_cb(GtkDialog *dialog, gint response_id,
94 G_GNUC_UNUSED gpointer data) 94 G_GNUC_UNUSED gpointer data)
95 { 95 {
96 PidginInviteDialog *invite_dialog = PIDGIN_INVITE_DIALOG(dialog); 96 PidginInviteDialog *invite_dialog = PIDGIN_INVITE_DIALOG(dialog);
97 PurpleChatConversation *chat = NULL; 97 PurpleChatConversation *chat = NULL;
98 98
99 chat = pidgin_invite_dialog_get_conversation(invite_dialog); 99 chat = pidgin_invite_dialog_get_conversation(invite_dialog);
121 121
122 /****************************************************************************** 122 /******************************************************************************
123 * Actions 123 * Actions
124 *****************************************************************************/ 124 *****************************************************************************/
125 static void 125 static void
126 pidgin_conversation_window_alias(G_GNUC_UNUSED GSimpleAction *simple, 126 pidgin_display_window_alias(G_GNUC_UNUSED GSimpleAction *simple,
127 G_GNUC_UNUSED GVariant *parameter, 127 G_GNUC_UNUSED GVariant *parameter,
128 gpointer data) 128 gpointer data)
129 { 129 {
130 PidginConversationWindow *window = data; 130 PidginDisplayWindow *window = data;
131 PurpleConversation *selected = NULL; 131 PurpleConversation *selected = NULL;
132 132
133 selected = pidgin_conversation_window_get_selected(window); 133 selected = pidgin_display_window_get_selected(window);
134 if(PURPLE_IS_CONVERSATION(selected)) { 134 if(PURPLE_IS_CONVERSATION(selected)) {
135 PurpleAccount *account; 135 PurpleAccount *account;
136 const gchar *name; 136 const gchar *name;
137 137
138 account = purple_conversation_get_account(selected); 138 account = purple_conversation_get_account(selected);
153 } 153 }
154 } 154 }
155 } 155 }
156 156
157 static void 157 static void
158 pidgin_conversation_window_close_conversation(G_GNUC_UNUSED GSimpleAction *simple, 158 pidgin_display_window_close_conversation(G_GNUC_UNUSED GSimpleAction *simple,
159 G_GNUC_UNUSED GVariant *parameter, 159 G_GNUC_UNUSED GVariant *parameter,
160 gpointer data) 160 gpointer data)
161 { 161 {
162 PidginConversationWindow *window = data; 162 PidginDisplayWindow *window = data;
163 PurpleConversation *selected = NULL; 163 PurpleConversation *selected = NULL;
164 164
165 selected = pidgin_conversation_window_get_selected(window); 165 selected = pidgin_display_window_get_selected(window);
166 if(PURPLE_IS_CONVERSATION(selected)) { 166 if(PURPLE_IS_CONVERSATION(selected)) {
167 pidgin_conversation_window_remove(window, selected); 167 pidgin_display_window_remove(window, selected);
168 pidgin_conversation_detach(selected); 168 pidgin_conversation_detach(selected);
169 } 169 }
170 } 170 }
171 171
172 static void 172 static void
173 pidgin_conversation_window_get_info(G_GNUC_UNUSED GSimpleAction *simple, 173 pidgin_display_window_get_info(G_GNUC_UNUSED GSimpleAction *simple,
174 G_GNUC_UNUSED GVariant *parameter, 174 G_GNUC_UNUSED GVariant *parameter,
175 gpointer data) 175 gpointer data)
176 { 176 {
177 PidginConversationWindow *window = data; 177 PidginDisplayWindow *window = data;
178 PurpleConversation *selected = NULL; 178 PurpleConversation *selected = NULL;
179 179
180 selected = pidgin_conversation_window_get_selected(window); 180 selected = pidgin_display_window_get_selected(window);
181 if(PURPLE_IS_CONVERSATION(selected)) { 181 if(PURPLE_IS_CONVERSATION(selected)) {
182 if(PURPLE_IS_IM_CONVERSATION(selected)) { 182 if(PURPLE_IS_IM_CONVERSATION(selected)) {
183 PurpleConnection *connection = NULL; 183 PurpleConnection *connection = NULL;
184 184
185 connection = purple_conversation_get_connection(selected); 185 connection = purple_conversation_get_connection(selected);
188 } 188 }
189 } 189 }
190 } 190 }
191 191
192 static void 192 static void
193 pidgin_conversation_window_invite(G_GNUC_UNUSED GSimpleAction *simple, 193 pidgin_display_window_invite(G_GNUC_UNUSED GSimpleAction *simple,
194 G_GNUC_UNUSED GVariant *parameter, 194 G_GNUC_UNUSED GVariant *parameter,
195 gpointer data) 195 gpointer data)
196 { 196 {
197 PidginConversationWindow *window = data; 197 PidginDisplayWindow *window = data;
198 PurpleConversation *selected = NULL; 198 PurpleConversation *selected = NULL;
199 199
200 selected = pidgin_conversation_window_get_selected(window); 200 selected = pidgin_display_window_get_selected(window);
201 if(PURPLE_IS_CHAT_CONVERSATION(selected)) { 201 if(PURPLE_IS_CHAT_CONVERSATION(selected)) {
202 GtkWidget *invite_dialog = NULL; 202 GtkWidget *invite_dialog = NULL;
203 203
204 invite_dialog = g_object_get_data(G_OBJECT(selected), 204 invite_dialog = g_object_get_data(G_OBJECT(selected),
205 "pidgin-invite-dialog"); 205 "pidgin-invite-dialog");
212 gtk_window_set_transient_for(GTK_WINDOW(invite_dialog), 212 gtk_window_set_transient_for(GTK_WINDOW(invite_dialog),
213 GTK_WINDOW(window)); 213 GTK_WINDOW(window));
214 gtk_window_set_destroy_with_parent(GTK_WINDOW(invite_dialog), TRUE); 214 gtk_window_set_destroy_with_parent(GTK_WINDOW(invite_dialog), TRUE);
215 215
216 g_signal_connect(invite_dialog, "response", 216 g_signal_connect(invite_dialog, "response",
217 G_CALLBACK(pidgin_conversation_window_invite_cb), 217 G_CALLBACK(pidgin_display_window_invite_cb),
218 NULL); 218 NULL);
219 } 219 }
220 220
221 gtk_widget_show(invite_dialog); 221 gtk_widget_show(invite_dialog);
222 } 222 }
223 } 223 }
224 224
225 static void 225 static void
226 pidgin_conversation_window_send_file(G_GNUC_UNUSED GSimpleAction *simple, 226 pidgin_display_window_send_file(G_GNUC_UNUSED GSimpleAction *simple,
227 G_GNUC_UNUSED GVariant *parameter, 227 G_GNUC_UNUSED GVariant *parameter,
228 gpointer data) 228 gpointer data)
229 { 229 {
230 PidginConversationWindow *window = data; 230 PidginDisplayWindow *window = data;
231 PurpleConversation *selected = NULL; 231 PurpleConversation *selected = NULL;
232 232
233 selected = pidgin_conversation_window_get_selected(window); 233 selected = pidgin_display_window_get_selected(window);
234 if(PURPLE_IS_IM_CONVERSATION(selected)) { 234 if(PURPLE_IS_IM_CONVERSATION(selected)) {
235 PurpleConnection *connection = NULL; 235 PurpleConnection *connection = NULL;
236 236
237 connection = purple_conversation_get_connection(selected); 237 connection = purple_conversation_get_connection(selected);
238 purple_serv_send_file(connection, 238 purple_serv_send_file(connection,
242 } 242 }
243 243
244 static GActionEntry win_entries[] = { 244 static GActionEntry win_entries[] = {
245 { 245 {
246 .name = "alias", 246 .name = "alias",
247 .activate = pidgin_conversation_window_alias 247 .activate = pidgin_display_window_alias
248 }, { 248 }, {
249 .name = "close", 249 .name = "close",
250 .activate = pidgin_conversation_window_close_conversation 250 .activate = pidgin_display_window_close_conversation
251 }, { 251 }, {
252 .name = "get-info", 252 .name = "get-info",
253 .activate = pidgin_conversation_window_get_info 253 .activate = pidgin_display_window_get_info
254 }, { 254 }, {
255 .name = "invite", 255 .name = "invite",
256 .activate = pidgin_conversation_window_invite 256 .activate = pidgin_display_window_invite
257 }, { 257 }, {
258 .name = "send-file", 258 .name = "send-file",
259 .activate = pidgin_conversation_window_send_file 259 .activate = pidgin_display_window_send_file
260 } 260 }
261 }; 261 };
262 262
263 /*<private> 263 /*<private>
264 * pidgin_conversation_window_conversation_actions: 264 * pidgin_display_window_conversation_actions:
265 * 265 *
266 * A list of action names that are only valid if a conversation is selected. 266 * A list of action names that are only valid if a conversation is selected.
267 */ 267 */
268 static const gchar *pidgin_conversation_window_conversation_actions[] = { 268 static const gchar *pidgin_display_window_conversation_actions[] = {
269 "alias", 269 "alias",
270 "close", 270 "close",
271 "get-info", 271 "get-info",
272 NULL 272 NULL
273 }; 273 };
274 274
275 static const gchar *pidgin_conversation_window_im_conversation_actions[] = { 275 static const gchar *pidgin_display_window_im_conversation_actions[] = {
276 "send-file", 276 "send-file",
277 NULL 277 NULL
278 }; 278 };
279 279
280 static const gchar *pidgin_conversation_window_chat_conversation_actions[] = { 280 static const gchar *pidgin_display_window_chat_conversation_actions[] = {
281 "invite", 281 "invite",
282 NULL 282 NULL
283 }; 283 };
284 284
285 /****************************************************************************** 285 /******************************************************************************
286 * Callbacks 286 * Callbacks
287 *****************************************************************************/ 287 *****************************************************************************/
288 static void 288 static void
289 pidgin_conversation_window_selection_changed(GtkTreeSelection *selection, 289 pidgin_display_window_selection_changed(GtkTreeSelection *selection,
290 gpointer data) 290 gpointer data)
291 { 291 {
292 PidginConversationWindow *window = PIDGIN_CONVERSATION_WINDOW(data); 292 PidginDisplayWindow *window = PIDGIN_DISPLAY_WINDOW(data);
293 GtkTreeModel *model = NULL; 293 GtkTreeModel *model = NULL;
294 GtkTreeIter iter; 294 GtkTreeIter iter;
295 gboolean changed = FALSE; 295 gboolean changed = FALSE;
296 296
297 if(gtk_tree_selection_get_selected(selection, &model, &iter)) { 297 if(gtk_tree_selection_get_selected(selection, &model, &iter)) {
299 gboolean is_conversation = FALSE; 299 gboolean is_conversation = FALSE;
300 gboolean im_selected = FALSE, chat_selected = FALSE; 300 gboolean im_selected = FALSE, chat_selected = FALSE;
301 gchar *name = NULL; 301 gchar *name = NULL;
302 302
303 gtk_tree_model_get(model, &iter, 303 gtk_tree_model_get(model, &iter,
304 PIDGIN_CONVERSATION_WINDOW_COLUMN_NAME, &name, 304 PIDGIN_DISPLAY_WINDOW_COLUMN_NAME, &name,
305 PIDGIN_CONVERSATION_WINDOW_COLUMN_OBJECT, &obj, 305 PIDGIN_DISPLAY_WINDOW_COLUMN_OBJECT, &obj,
306 -1); 306 -1);
307 307
308 gtk_stack_set_visible_child_name(GTK_STACK(window->stack), name); 308 gtk_stack_set_visible_child_name(GTK_STACK(window->stack), name);
309 g_free(name); 309 g_free(name);
310 310
312 312
313 /* If a conversation is selected, enable the generic conversation 313 /* If a conversation is selected, enable the generic conversation
314 * actions. 314 * actions.
315 */ 315 */
316 is_conversation = PURPLE_IS_CONVERSATION(obj); 316 is_conversation = PURPLE_IS_CONVERSATION(obj);
317 pidgin_conversation_window_actions_set_enabled(G_ACTION_MAP(window), 317 pidgin_display_window_actions_set_enabled(G_ACTION_MAP(window),
318 pidgin_conversation_window_conversation_actions, 318 pidgin_display_window_conversation_actions,
319 is_conversation); 319 is_conversation);
320 320
321 /* If an IM is selected, enable the IM-specific actions otherwise 321 /* If an IM is selected, enable the IM-specific actions otherwise
322 * disable them. 322 * disable them.
323 */ 323 */
324 im_selected = PURPLE_IS_IM_CONVERSATION(obj); 324 im_selected = PURPLE_IS_IM_CONVERSATION(obj);
325 pidgin_conversation_window_actions_set_enabled(G_ACTION_MAP(window), 325 pidgin_display_window_actions_set_enabled(G_ACTION_MAP(window),
326 pidgin_conversation_window_im_conversation_actions, 326 pidgin_display_window_im_conversation_actions,
327 im_selected); 327 im_selected);
328 328
329 /* If a chat is selected, enable the chat-specific actions otherwise 329 /* If a chat is selected, enable the chat-specific actions otherwise
330 * disable them. 330 * disable them.
331 */ 331 */
332 chat_selected = PURPLE_IS_CHAT_CONVERSATION(obj); 332 chat_selected = PURPLE_IS_CHAT_CONVERSATION(obj);
333 pidgin_conversation_window_actions_set_enabled(G_ACTION_MAP(window), 333 pidgin_display_window_actions_set_enabled(G_ACTION_MAP(window),
334 pidgin_conversation_window_chat_conversation_actions, 334 pidgin_display_window_chat_conversation_actions,
335 chat_selected); 335 chat_selected);
336 336
337 g_clear_object(&obj); 337 g_clear_object(&obj);
338 } 338 }
339 339
341 gtk_stack_set_visible_child_name(GTK_STACK(window->stack), "__conversations__"); 341 gtk_stack_set_visible_child_name(GTK_STACK(window->stack), "__conversations__");
342 } 342 }
343 } 343 }
344 344
345 static gboolean 345 static gboolean
346 pidgin_conversation_window_key_pressed_cb(GtkEventControllerKey *controller, 346 pidgin_display_window_key_pressed_cb(GtkEventControllerKey *controller,
347 guint keyval, 347 guint keyval,
348 G_GNUC_UNUSED guint keycode, 348 G_GNUC_UNUSED guint keycode,
349 GdkModifierType state, 349 GdkModifierType state,
350 gpointer data) 350 gpointer data)
351 { 351 {
352 PidginConversationWindow *window = data; 352 PidginDisplayWindow *window = data;
353 353
354 /* If CTRL was held down... */ 354 /* If CTRL was held down... */
355 if (state & GDK_CONTROL_MASK) { 355 if (state & GDK_CONTROL_MASK) {
356 switch (keyval) { 356 switch (keyval) {
357 case GDK_KEY_Page_Down: 357 case GDK_KEY_Page_Down:
358 case GDK_KEY_KP_Page_Down: 358 case GDK_KEY_KP_Page_Down:
359 case ']': 359 case ']':
360 pidgin_conversation_window_select_next(window); 360 pidgin_display_window_select_next(window);
361 return TRUE; 361 return TRUE;
362 break; 362 break;
363 363
364 case GDK_KEY_Page_Up: 364 case GDK_KEY_Page_Up:
365 case GDK_KEY_KP_Page_Up: 365 case GDK_KEY_KP_Page_Up:
366 case '[': 366 case '[':
367 pidgin_conversation_window_select_previous(window); 367 pidgin_display_window_select_previous(window);
368 return TRUE; 368 return TRUE;
369 break; 369 break;
370 } /* End of switch */ 370 } /* End of switch */
371 } 371 }
372 372
373 /* If ALT (or whatever) was held down... */ 373 /* If ALT (or whatever) was held down... */
374 else if (state & GDK_ALT_MASK) { 374 else if (state & GDK_ALT_MASK) {
375 if ('1' <= keyval && keyval <= '9') { 375 if ('1' <= keyval && keyval <= '9') {
376 guint switchto = keyval - '1'; 376 guint switchto = keyval - '1';
377 pidgin_conversation_window_select_nth(window, switchto); 377 pidgin_display_window_select_nth(window, switchto);
378 378
379 return TRUE; 379 return TRUE;
380 } 380 }
381 } 381 }
382 382
385 385
386 /****************************************************************************** 386 /******************************************************************************
387 * GObjectImplementation 387 * GObjectImplementation
388 *****************************************************************************/ 388 *****************************************************************************/
389 static void 389 static void
390 pidgin_conversation_window_dispose(GObject *obj) { 390 pidgin_display_window_dispose(GObject *obj) {
391 PidginConversationWindow *window = PIDGIN_CONVERSATION_WINDOW(obj); 391 PidginDisplayWindow *window = PIDGIN_DISPLAY_WINDOW(obj);
392 392
393 if(GTK_IS_TREE_MODEL(window->model)) { 393 if(GTK_IS_TREE_MODEL(window->model)) {
394 GtkTreeModel *model = GTK_TREE_MODEL(window->model); 394 GtkTreeModel *model = GTK_TREE_MODEL(window->model);
395 GtkTreeIter parent, iter; 395 GtkTreeIter parent, iter;
396 396
403 */ 403 */
404 do { 404 do {
405 PurpleConversation *conversation = NULL; 405 PurpleConversation *conversation = NULL;
406 406
407 gtk_tree_model_get(model, &iter, 407 gtk_tree_model_get(model, &iter,
408 PIDGIN_CONVERSATION_WINDOW_COLUMN_OBJECT, &conversation, 408 PIDGIN_DISPLAY_WINDOW_COLUMN_OBJECT, &conversation,
409 -1); 409 -1);
410 410
411 if(PURPLE_IS_CONVERSATION(conversation)) { 411 if(PURPLE_IS_CONVERSATION(conversation)) {
412 pidgin_conversation_detach(conversation); 412 pidgin_conversation_detach(conversation);
413 413
417 } 417 }
418 418
419 g_clear_pointer(&window->conversation_path, gtk_tree_path_free); 419 g_clear_pointer(&window->conversation_path, gtk_tree_path_free);
420 } 420 }
421 421
422 G_OBJECT_CLASS(pidgin_conversation_window_parent_class)->dispose(obj); 422 G_OBJECT_CLASS(pidgin_display_window_parent_class)->dispose(obj);
423 } 423 }
424 424
425 static void 425 static void
426 pidgin_conversation_window_init(PidginConversationWindow *window) { 426 pidgin_display_window_init(PidginDisplayWindow *window) {
427 GtkEventController *key = NULL; 427 GtkEventController *key = NULL;
428 GtkTreeIter iter; 428 GtkTreeIter iter;
429 429
430 gtk_widget_init_template(GTK_WIDGET(window)); 430 gtk_widget_init_template(GTK_WIDGET(window));
431 431
436 G_N_ELEMENTS(win_entries), window); 436 G_N_ELEMENTS(win_entries), window);
437 437
438 key = gtk_event_controller_key_new(); 438 key = gtk_event_controller_key_new();
439 gtk_event_controller_set_propagation_phase(key, GTK_PHASE_CAPTURE); 439 gtk_event_controller_set_propagation_phase(key, GTK_PHASE_CAPTURE);
440 g_signal_connect(G_OBJECT(key), "key-pressed", 440 g_signal_connect(G_OBJECT(key), "key-pressed",
441 G_CALLBACK(pidgin_conversation_window_key_pressed_cb), 441 G_CALLBACK(pidgin_display_window_key_pressed_cb),
442 window); 442 window);
443 gtk_widget_add_controller(GTK_WIDGET(window), key); 443 gtk_widget_add_controller(GTK_WIDGET(window), key);
444 444
445 /* Add our toplevels to the tree store. */ 445 /* Add our toplevels to the tree store. */
446 gtk_tree_store_append(window->model, &iter, NULL); 446 gtk_tree_store_append(window->model, &iter, NULL);
447 gtk_tree_store_set(window->model, &iter, 447 gtk_tree_store_set(window->model, &iter,
448 PIDGIN_CONVERSATION_WINDOW_COLUMN_OBJECT, window->notification_list, 448 PIDGIN_DISPLAY_WINDOW_COLUMN_OBJECT, window->notification_list,
449 PIDGIN_CONVERSATION_WINDOW_COLUMN_NAME, "__notifications__", 449 PIDGIN_DISPLAY_WINDOW_COLUMN_NAME, "__notifications__",
450 PIDGIN_CONVERSATION_WINDOW_COLUMN_MARKUP, _("Notifications"), 450 PIDGIN_DISPLAY_WINDOW_COLUMN_MARKUP, _("Notifications"),
451 -1); 451 -1);
452 452
453 gtk_tree_store_append(window->model, &iter, NULL); 453 gtk_tree_store_append(window->model, &iter, NULL);
454 gtk_tree_store_set(window->model, &iter, 454 gtk_tree_store_set(window->model, &iter,
455 PIDGIN_CONVERSATION_WINDOW_COLUMN_MARKUP, _("Conversations"), 455 PIDGIN_DISPLAY_WINDOW_COLUMN_MARKUP, _("Conversations"),
456 PIDGIN_CONVERSATION_WINDOW_COLUMN_NAME, "__conversations__", 456 PIDGIN_DISPLAY_WINDOW_COLUMN_NAME, "__conversations__",
457 -1); 457 -1);
458 gtk_tree_selection_select_iter(window->selection, &iter); 458 gtk_tree_selection_select_iter(window->selection, &iter);
459 window->conversation_path = gtk_tree_model_get_path(GTK_TREE_MODEL(window->model), 459 window->conversation_path = gtk_tree_model_get_path(GTK_TREE_MODEL(window->model),
460 &iter); 460 &iter);
461 } 461 }
462 462
463 static void 463 static void
464 pidgin_conversation_window_class_init(PidginConversationWindowClass *klass) { 464 pidgin_display_window_class_init(PidginDisplayWindowClass *klass) {
465 GObjectClass *obj_class = G_OBJECT_CLASS(klass); 465 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
466 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); 466 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
467 467
468 obj_class->dispose = pidgin_conversation_window_dispose; 468 obj_class->dispose = pidgin_display_window_dispose;
469 469
470 /** 470 /**
471 * PidginConversationWindow::conversation-switched: 471 * PidginDisplayWindow::conversation-switched:
472 * @window: The conversation window. 472 * @window: The conversation window.
473 * @new_conv: The now active conversation. 473 * @new_conv: The now active conversation.
474 * 474 *
475 * Emitted when a window switched from one conversation to another. 475 * Emitted when a window switched from one conversation to another.
476 */ 476 */
490 gtk_widget_class_set_template_from_resource( 490 gtk_widget_class_set_template_from_resource(
491 widget_class, 491 widget_class,
492 "/im/pidgin/Pidgin3/Conversations/window.ui" 492 "/im/pidgin/Pidgin3/Conversations/window.ui"
493 ); 493 );
494 494
495 gtk_widget_class_bind_template_child(widget_class, PidginConversationWindow, 495 gtk_widget_class_bind_template_child(widget_class, PidginDisplayWindow,
496 vbox); 496 vbox);
497 497
498 gtk_widget_class_bind_template_child(widget_class, PidginConversationWindow, 498 gtk_widget_class_bind_template_child(widget_class, PidginDisplayWindow,
499 model); 499 model);
500 gtk_widget_class_bind_template_child(widget_class, PidginConversationWindow, 500 gtk_widget_class_bind_template_child(widget_class, PidginDisplayWindow,
501 view); 501 view);
502 gtk_widget_class_bind_template_child(widget_class, PidginConversationWindow, 502 gtk_widget_class_bind_template_child(widget_class, PidginDisplayWindow,
503 selection); 503 selection);
504 504
505 gtk_widget_class_bind_template_child(widget_class, PidginConversationWindow, 505 gtk_widget_class_bind_template_child(widget_class, PidginDisplayWindow,
506 stack); 506 stack);
507 gtk_widget_class_bind_template_child(widget_class, PidginConversationWindow, 507 gtk_widget_class_bind_template_child(widget_class, PidginDisplayWindow,
508 notification_list); 508 notification_list);
509 509
510 gtk_widget_class_bind_template_callback(widget_class, 510 gtk_widget_class_bind_template_callback(widget_class,
511 pidgin_conversation_window_selection_changed); 511 pidgin_display_window_selection_changed);
512 512
513 gtk_widget_class_bind_template_callback(widget_class, 513 gtk_widget_class_bind_template_callback(widget_class,
514 pidgin_conversation_window_key_pressed_cb); 514 pidgin_display_window_key_pressed_cb);
515 } 515 }
516 516
517 /****************************************************************************** 517 /******************************************************************************
518 * API 518 * API
519 *****************************************************************************/ 519 *****************************************************************************/
520 GtkWidget * 520 GtkWidget *
521 pidgin_conversation_window_get_default(void) { 521 pidgin_display_window_get_default(void) {
522 if(!GTK_IS_WIDGET(default_window)) { 522 if(!GTK_IS_WIDGET(default_window)) {
523 default_window = pidgin_conversation_window_new(); 523 default_window = pidgin_display_window_new();
524 g_object_add_weak_pointer(G_OBJECT(default_window), 524 g_object_add_weak_pointer(G_OBJECT(default_window),
525 (gpointer)&default_window); 525 (gpointer)&default_window);
526 } 526 }
527 527
528 return default_window; 528 return default_window;
529 } 529 }
530 530
531 GtkWidget * 531 GtkWidget *
532 pidgin_conversation_window_new(void) { 532 pidgin_display_window_new(void) {
533 return g_object_new( 533 return g_object_new(
534 PIDGIN_TYPE_CONVERSATION_WINDOW, 534 PIDGIN_TYPE_DISPLAY_WINDOW,
535 "show-menubar", TRUE, 535 "show-menubar", TRUE,
536 NULL); 536 NULL);
537 } 537 }
538 538
539 void 539 void
540 pidgin_conversation_window_add(PidginConversationWindow *window, 540 pidgin_display_window_add(PidginDisplayWindow *window,
541 PurpleConversation *conversation) 541 PurpleConversation *conversation)
542 { 542 {
543 PidginConversation *gtkconv = NULL; 543 PidginConversation *gtkconv = NULL;
544 GtkTreeIter parent, iter; 544 GtkTreeIter parent, iter;
545 GtkTreeModel *model = NULL; 545 GtkTreeModel *model = NULL;
546 const gchar *markup = NULL; 546 const gchar *markup = NULL;
547 gboolean expand = FALSE; 547 gboolean expand = FALSE;
548 548
549 g_return_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window)); 549 g_return_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window));
550 g_return_if_fail(PURPLE_IS_CONVERSATION(conversation)); 550 g_return_if_fail(PURPLE_IS_CONVERSATION(conversation));
551 551
552 model = GTK_TREE_MODEL(window->model); 552 model = GTK_TREE_MODEL(window->model);
553 if(!gtk_tree_model_get_iter(model, &parent, window->conversation_path)) { 553 if(!gtk_tree_model_get_iter(model, &parent, window->conversation_path)) {
554 /* If we can't find the conversation_path we have to bail. */ 554 /* If we can't find the conversation_path we have to bail. */
580 } 580 }
581 } 581 }
582 582
583 gtk_tree_store_prepend(window->model, &iter, &parent); 583 gtk_tree_store_prepend(window->model, &iter, &parent);
584 gtk_tree_store_set(window->model, &iter, 584 gtk_tree_store_set(window->model, &iter,
585 PIDGIN_CONVERSATION_WINDOW_COLUMN_OBJECT, conversation, 585 PIDGIN_DISPLAY_WINDOW_COLUMN_OBJECT, conversation,
586 PIDGIN_CONVERSATION_WINDOW_COLUMN_NAME, markup, 586 PIDGIN_DISPLAY_WINDOW_COLUMN_NAME, markup,
587 PIDGIN_CONVERSATION_WINDOW_COLUMN_MARKUP, markup, 587 PIDGIN_DISPLAY_WINDOW_COLUMN_MARKUP, markup,
588 -1); 588 -1);
589 589
590 /* If we just added the first child, expand the parent. */ 590 /* If we just added the first child, expand the parent. */
591 if(expand) { 591 if(expand) {
592 gtk_tree_view_expand_row(GTK_TREE_VIEW(window->view), 592 gtk_tree_view_expand_row(GTK_TREE_VIEW(window->view),
598 gtk_widget_show(GTK_WIDGET(window)); 598 gtk_widget_show(GTK_WIDGET(window));
599 } 599 }
600 } 600 }
601 601
602 void 602 void
603 pidgin_conversation_window_remove(PidginConversationWindow *window, 603 pidgin_display_window_remove(PidginDisplayWindow *window,
604 PurpleConversation *conversation) 604 PurpleConversation *conversation)
605 { 605 {
606 GtkTreeIter parent, iter; 606 GtkTreeIter parent, iter;
607 GtkTreeModel *model = NULL; 607 GtkTreeModel *model = NULL;
608 GObject *obj = NULL; 608 GObject *obj = NULL;
609 609
610 g_return_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window)); 610 g_return_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window));
611 g_return_if_fail(PURPLE_IS_CONVERSATION(conversation)); 611 g_return_if_fail(PURPLE_IS_CONVERSATION(conversation));
612 612
613 model = GTK_TREE_MODEL(window->model); 613 model = GTK_TREE_MODEL(window->model);
614 614
615 if(!gtk_tree_model_get_iter(model, &parent, window->conversation_path)) { 615 if(!gtk_tree_model_get_iter(model, &parent, window->conversation_path)) {
622 return; 622 return;
623 } 623 }
624 624
625 do { 625 do {
626 gtk_tree_model_get(model, &iter, 626 gtk_tree_model_get(model, &iter,
627 PIDGIN_CONVERSATION_WINDOW_COLUMN_OBJECT, &obj, 627 PIDGIN_DISPLAY_WINDOW_COLUMN_OBJECT, &obj,
628 -1); 628 -1);
629 629
630 if(PURPLE_CONVERSATION(obj) == conversation) { 630 if(PURPLE_CONVERSATION(obj) == conversation) {
631 GtkWidget *child = NULL; 631 GtkWidget *child = NULL;
632 const gchar *name = NULL; 632 const gchar *name = NULL;
648 g_clear_object(&obj); 648 g_clear_object(&obj);
649 } while(gtk_tree_model_iter_next(model, &iter)); 649 } while(gtk_tree_model_iter_next(model, &iter));
650 } 650 }
651 651
652 guint 652 guint
653 pidgin_conversation_window_get_count(PidginConversationWindow *window) { 653 pidgin_display_window_get_count(PidginDisplayWindow *window) {
654 GtkSelectionModel *model = NULL; 654 GtkSelectionModel *model = NULL;
655 guint count = 0; 655 guint count = 0;
656 656
657 g_return_val_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window), 0); 657 g_return_val_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window), 0);
658 658
659 model = gtk_stack_get_pages(GTK_STACK(window->stack)); 659 model = gtk_stack_get_pages(GTK_STACK(window->stack));
660 660
661 count = g_list_model_get_n_items(G_LIST_MODEL(model)); 661 count = g_list_model_get_n_items(G_LIST_MODEL(model));
662 662
664 664
665 return count; 665 return count;
666 } 666 }
667 667
668 PurpleConversation * 668 PurpleConversation *
669 pidgin_conversation_window_get_selected(PidginConversationWindow *window) { 669 pidgin_display_window_get_selected(PidginDisplayWindow *window) {
670 PurpleConversation *conversation = NULL; 670 PurpleConversation *conversation = NULL;
671 GtkTreeSelection *selection = NULL; 671 GtkTreeSelection *selection = NULL;
672 GtkTreeIter iter; 672 GtkTreeIter iter;
673 673
674 g_return_val_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window), NULL); 674 g_return_val_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window), NULL);
675 675
676 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(window->view)); 676 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(window->view));
677 if(gtk_tree_selection_get_selected(selection, NULL, &iter)) { 677 if(gtk_tree_selection_get_selected(selection, NULL, &iter)) {
678 678
679 gtk_tree_model_get(GTK_TREE_MODEL(window->model), &iter, 679 gtk_tree_model_get(GTK_TREE_MODEL(window->model), &iter,
680 PIDGIN_CONVERSATION_WINDOW_COLUMN_OBJECT, &conversation, 680 PIDGIN_DISPLAY_WINDOW_COLUMN_OBJECT, &conversation,
681 -1); 681 -1);
682 } 682 }
683 683
684 return conversation; 684 return conversation;
685 } 685 }
686 686
687 void 687 void
688 pidgin_conversation_window_select(PidginConversationWindow *window, 688 pidgin_display_window_select(PidginDisplayWindow *window,
689 PurpleConversation *conversation) 689 PurpleConversation *conversation)
690 { 690 {
691 const gchar *name = NULL; 691 const gchar *name = NULL;
692 692
693 g_return_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window)); 693 g_return_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window));
694 g_return_if_fail(PURPLE_IS_CONVERSATION(conversation)); 694 g_return_if_fail(PURPLE_IS_CONVERSATION(conversation));
695 695
696 name = purple_conversation_get_name(conversation); 696 name = purple_conversation_get_name(conversation);
697 gtk_stack_set_visible_child_name(GTK_STACK(window->stack), name); 697 gtk_stack_set_visible_child_name(GTK_STACK(window->stack), name);
698 } 698 }
699 699
700 void 700 void
701 pidgin_conversation_window_select_previous(PidginConversationWindow *window) { 701 pidgin_display_window_select_previous(PidginDisplayWindow *window) {
702 GtkTreeIter iter; 702 GtkTreeIter iter;
703 GtkTreeModel *model = NULL; 703 GtkTreeModel *model = NULL;
704 GtkTreeSelection *selection = NULL; 704 GtkTreeSelection *selection = NULL;
705 gboolean set = FALSE; 705 gboolean set = FALSE;
706 706
707 g_return_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window)); 707 g_return_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window));
708 708
709 model = GTK_TREE_MODEL(window->model); 709 model = GTK_TREE_MODEL(window->model);
710 710
711 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(window->view)); 711 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(window->view));
712 if(gtk_tree_selection_get_selected(selection, NULL, &iter)) { 712 if(gtk_tree_selection_get_selected(selection, NULL, &iter)) {
715 set = TRUE; 715 set = TRUE;
716 } 716 }
717 } 717 }
718 718
719 if(!set) { 719 if(!set) {
720 pidgin_conversation_window_select_last(window); 720 pidgin_display_window_select_last(window);
721 } 721 }
722 } 722 }
723 723
724 724
725 void 725 void
726 pidgin_conversation_window_select_next(PidginConversationWindow *window) { 726 pidgin_display_window_select_next(PidginDisplayWindow *window) {
727 GtkTreeIter iter; 727 GtkTreeIter iter;
728 GtkTreeModel *model = NULL; 728 GtkTreeModel *model = NULL;
729 GtkTreeSelection *selection = NULL; 729 GtkTreeSelection *selection = NULL;
730 gboolean set = FALSE; 730 gboolean set = FALSE;
731 731
732 g_return_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window)); 732 g_return_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window));
733 733
734 model = GTK_TREE_MODEL(window->model); 734 model = GTK_TREE_MODEL(window->model);
735 735
736 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(window->view)); 736 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(window->view));
737 if(gtk_tree_selection_get_selected(selection, NULL, &iter)) { 737 if(gtk_tree_selection_get_selected(selection, NULL, &iter)) {
740 set = TRUE; 740 set = TRUE;
741 } 741 }
742 } 742 }
743 743
744 if(!set) { 744 if(!set) {
745 pidgin_conversation_window_select_first(window); 745 pidgin_display_window_select_first(window);
746 } 746 }
747 } 747 }
748 748
749 void 749 void
750 pidgin_conversation_window_select_first(PidginConversationWindow *window) { 750 pidgin_display_window_select_first(PidginDisplayWindow *window) {
751 GtkTreeIter iter; 751 GtkTreeIter iter;
752 GtkTreeModel *model = NULL; 752 GtkTreeModel *model = NULL;
753 753
754 g_return_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window)); 754 g_return_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window));
755 755
756 model = GTK_TREE_MODEL(window->model); 756 model = GTK_TREE_MODEL(window->model);
757 757
758 if(gtk_tree_model_get_iter_first(model, &iter)) { 758 if(gtk_tree_model_get_iter_first(model, &iter)) {
759 GtkTreeSelection *selection = NULL; 759 GtkTreeSelection *selection = NULL;
762 gtk_tree_selection_select_iter(selection, &iter); 762 gtk_tree_selection_select_iter(selection, &iter);
763 } 763 }
764 } 764 }
765 765
766 void 766 void
767 pidgin_conversation_window_select_last(PidginConversationWindow *window) { 767 pidgin_display_window_select_last(PidginDisplayWindow *window) {
768 GtkTreeIter iter; 768 GtkTreeIter iter;
769 GtkTreeModel *model = NULL; 769 GtkTreeModel *model = NULL;
770 gint count = 0; 770 gint count = 0;
771 771
772 g_return_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window)); 772 g_return_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window));
773 773
774 model = GTK_TREE_MODEL(window->model); 774 model = GTK_TREE_MODEL(window->model);
775 count = gtk_tree_model_iter_n_children(model, NULL); 775 count = gtk_tree_model_iter_n_children(model, NULL);
776 776
777 if(gtk_tree_model_iter_nth_child(model, &iter, NULL, count - 1)) { 777 if(gtk_tree_model_iter_nth_child(model, &iter, NULL, count - 1)) {
781 gtk_tree_selection_select_iter(selection, &iter); 781 gtk_tree_selection_select_iter(selection, &iter);
782 } 782 }
783 } 783 }
784 784
785 void 785 void
786 pidgin_conversation_window_select_nth(PidginConversationWindow *window, 786 pidgin_display_window_select_nth(PidginDisplayWindow *window,
787 guint nth) 787 guint nth)
788 { 788 {
789 GtkTreeIter iter; 789 GtkTreeIter iter;
790 GtkTreeModel *model = NULL; 790 GtkTreeModel *model = NULL;
791 791
792 g_return_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window)); 792 g_return_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window));
793 793
794 model = GTK_TREE_MODEL(window->model); 794 model = GTK_TREE_MODEL(window->model);
795 795
796 if(gtk_tree_model_iter_nth_child(model, &iter, NULL, nth)) { 796 if(gtk_tree_model_iter_nth_child(model, &iter, NULL, nth)) {
797 GtkTreeSelection *selection = NULL; 797 GtkTreeSelection *selection = NULL;
800 gtk_tree_selection_select_iter(selection, &iter); 800 gtk_tree_selection_select_iter(selection, &iter);
801 } 801 }
802 } 802 }
803 803
804 gboolean 804 gboolean
805 pidgin_conversation_window_conversation_is_selected(PidginConversationWindow *window, 805 pidgin_display_window_conversation_is_selected(PidginDisplayWindow *window,
806 PurpleConversation *conversation) 806 PurpleConversation *conversation)
807 { 807 {
808 const gchar *name = NULL, *visible = NULL; 808 const gchar *name = NULL, *visible = NULL;
809 809
810 g_return_val_if_fail(PIDGIN_IS_CONVERSATION_WINDOW(window), FALSE); 810 g_return_val_if_fail(PIDGIN_IS_DISPLAY_WINDOW(window), FALSE);
811 g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), FALSE); 811 g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), FALSE);
812 812
813 name = purple_conversation_get_name(conversation); 813 name = purple_conversation_get_name(conversation);
814 visible = gtk_stack_get_visible_child_name(GTK_STACK(window->stack)); 814 visible = gtk_stack_get_visible_child_name(GTK_STACK(window->stack));
815 815

mercurial