pidgin/gtklog.c

changeset 38897
6db89a0010ae
parent 38888
8bcae3a0b165
parent 38709
6c80734ca3b4
equal deleted inserted replaced
38889:5f88ba22172b 38897:6db89a0010ae
106 gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview)), path); 106 gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview)), path);
107 107
108 gtk_tree_path_free(path); 108 gtk_tree_path_free(path);
109 } 109 }
110 110
111 static const char *log_get_date(PurpleLog *log) 111 static gchar *log_get_date(PurpleLog *log)
112 { 112 {
113 if (log->tm) 113 GDateTime *dt;
114 return purple_date_format_full(log->tm); 114 gchar *ret;
115 else 115 dt = g_date_time_to_local(log->time);
116 return purple_date_format_full(localtime(&log->time)); 116 ret = g_date_time_format(dt, "%c");
117 g_date_time_unref(dt);
118 return ret;
117 } 119 }
118 120
119 static void search_cb(GtkWidget *button, PidginLogViewer *lv) 121 static void search_cb(GtkWidget *button, PidginLogViewer *lv)
120 { 122 {
121 const char *search_term = gtk_entry_get_text(GTK_ENTRY(lv->entry)); 123 const char *search_term = gtk_entry_get_text(GTK_ENTRY(lv->entry));
150 for (logs = lv->logs; logs != NULL; logs = logs->next) { 152 for (logs = lv->logs; logs != NULL; logs = logs->next) {
151 char *read = purple_log_read((PurpleLog*)logs->data, NULL); 153 char *read = purple_log_read((PurpleLog*)logs->data, NULL);
152 if (read && *read && purple_strcasestr(read, search_term)) { 154 if (read && *read && purple_strcasestr(read, search_term)) {
153 GtkTreeIter iter; 155 GtkTreeIter iter;
154 PurpleLog *log = logs->data; 156 PurpleLog *log = logs->data;
157 gchar *log_date = log_get_date(log);
155 158
156 gtk_tree_store_append (lv->treestore, &iter, NULL); 159 gtk_tree_store_append (lv->treestore, &iter, NULL);
157 gtk_tree_store_set(lv->treestore, &iter, 160 gtk_tree_store_set(lv->treestore, &iter,
158 0, log_get_date(log), 161 0, log_date,
159 1, log, -1); 162 1, log, -1);
163 g_free(log_date);
160 } 164 }
161 g_free(read); 165 g_free(read);
162 } 166 }
163 167
164 select_first_log(lv); 168 select_first_log(lv);
268 272
269 static void log_delete_log_cb(GtkWidget *menuitem, gpointer *data) 273 static void log_delete_log_cb(GtkWidget *menuitem, gpointer *data)
270 { 274 {
271 PidginLogViewer *lv = data[0]; 275 PidginLogViewer *lv = data[0];
272 PurpleLog *log = data[1]; 276 PurpleLog *log = data[1];
273 const char *time = log_get_date(log); 277 GtkTreeIter *iter = data[2];
278 gchar *time = log_get_date(log);
274 const char *name; 279 const char *name;
275 char *tmp; 280 char *tmp;
276 gpointer *data2; 281 gpointer *data2;
277 282
278 if (log->type == PURPLE_LOG_IM) 283 if (log->type == PURPLE_LOG_IM)
300 else if (log->type == PURPLE_LOG_SYSTEM) 305 else if (log->type == PURPLE_LOG_SYSTEM)
301 { 306 {
302 tmp = g_strdup_printf(_("Are you sure you want to permanently delete the system log " 307 tmp = g_strdup_printf(_("Are you sure you want to permanently delete the system log "
303 "which started at %s?"), time); 308 "which started at %s?"), time);
304 } 309 }
305 else 310 else {
311 g_free(time);
312 g_free(iter);
306 g_return_if_reached(); 313 g_return_if_reached();
314 }
307 315
308 /* The only way to free data in all cases is to tie it to the menuitem with 316 /* The only way to free data in all cases is to tie it to the menuitem with
309 * g_object_set_data_full(). But, since we need to get some data down to 317 * g_object_set_data_full(). But, since we need to get some data down to
310 * delete_log_cb() to delete the log from the log viewer after the file is 318 * delete_log_cb() to delete the log from the log viewer after the file is
311 * deleted, we have to allocate a new data array and make sure it gets freed 319 * deleted, we have to allocate a new data array and make sure it gets freed
312 * either way. */ 320 * either way. */
313 data2 = g_new(gpointer, 3); 321 data2 = g_new(gpointer, 3);
314 data2[0] = lv->treestore; 322 data2[0] = lv->treestore;
315 data2[1] = data[3]; /* iter */ 323 data2[1] = iter;
316 data2[2] = log; 324 data2[2] = log;
317 purple_request_action(lv, NULL, _("Delete Log?"), tmp, 0, 325 purple_request_action(lv, NULL, _("Delete Log?"), tmp, 0,
318 NULL, 326 NULL,
319 data2, 2, 327 data2, 2,
320 _("Delete"), delete_log_cb, 328 _("Delete"), delete_log_cb,
321 _("Cancel"), delete_log_cleanup_cb); 329 _("Cancel"), delete_log_cleanup_cb);
330 g_free(time);
322 g_free(tmp); 331 g_free(tmp);
323 } 332 }
324 333
325 static void log_show_popup_menu(GtkWidget *treeview, GdkEventButton *event, gpointer *data) 334 static GtkWidget *
326 { 335 log_create_popup_menu(GtkWidget *treeview, PidginLogViewer *lv, GtkTreeIter *iter)
327 GtkWidget *menu = gtk_menu_new(); 336 {
328 GtkWidget *menuitem = gtk_menu_item_new_with_label(_("Delete Log...")); 337 GValue val;
329 338 PurpleLog *log;
330 if (!purple_log_is_deletable((PurpleLog *)data[1])) 339 GtkWidget *menu;
340 GtkWidget *menuitem;
341
342 val.g_type = 0;
343 gtk_tree_model_get_value(GTK_TREE_MODEL(lv->treestore), iter, 1, &val);
344 log = g_value_get_pointer(&val);
345 if (log == NULL) {
346 g_free(iter);
347 return NULL;
348 }
349
350 menu = gtk_menu_new();
351 menuitem = gtk_menu_item_new_with_label(_("Delete Log..."));
352
353 if (purple_log_is_deletable(log)) {
354 gpointer *data = g_new(gpointer, 3);
355 data[0] = lv;
356 data[1] = log;
357 data[2] = iter;
358
359 g_signal_connect(menuitem, "activate", G_CALLBACK(log_delete_log_cb), data);
360 g_object_set_data_full(G_OBJECT(menuitem), "log-viewer-data", data, g_free);
361 } else {
331 gtk_widget_set_sensitive(menuitem, FALSE); 362 gtk_widget_set_sensitive(menuitem, FALSE);
332 363 }
333 g_signal_connect(menuitem, "activate", G_CALLBACK(log_delete_log_cb), data);
334 g_object_set_data_full(G_OBJECT(menuitem), "log-viewer-data", data, g_free);
335 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 364 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
336 gtk_widget_show_all(menu); 365 gtk_widget_show_all(menu);
337 366
338 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, (GtkMenuPositionFunc)data[2], NULL, 367 return menu;
339 (event != NULL) ? event->button : 0,
340 gdk_event_get_time((GdkEvent *)event));
341 } 368 }
342 369
343 static gboolean log_button_press_cb(GtkWidget *treeview, GdkEventButton *event, PidginLogViewer *lv) 370 static gboolean log_button_press_cb(GtkWidget *treeview, GdkEventButton *event, PidginLogViewer *lv)
344 { 371 {
345 if (event->type == GDK_BUTTON_PRESS && event->button == 3) 372 if (gdk_event_triggers_context_menu((GdkEvent *)event)) {
346 {
347 GtkTreePath *path; 373 GtkTreePath *path;
348 GtkTreeIter *iter; 374 GtkTreeIter *iter;
349 GValue val; 375 GtkWidget *menu;
350 PurpleLog *log;
351 gpointer *data;
352 376
353 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), event->x, event->y, &path, NULL, NULL, NULL)) 377 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), event->x, event->y, &path, NULL, NULL, NULL))
354 return FALSE; 378 return FALSE;
355 iter = g_new(GtkTreeIter, 1); 379 iter = g_new(GtkTreeIter, 1);
356 gtk_tree_model_get_iter(GTK_TREE_MODEL(lv->treestore), iter, path); 380 gtk_tree_model_get_iter(GTK_TREE_MODEL(lv->treestore), iter, path);
357 val.g_type = 0;
358 gtk_tree_model_get_value(GTK_TREE_MODEL(lv->treestore), iter, 1, &val);
359 gtk_tree_path_free(path); 381 gtk_tree_path_free(path);
360 382
361 log = g_value_get_pointer(&val); 383 menu = log_create_popup_menu(treeview, lv, iter);
362 384 if (menu) {
363 if (log == NULL) 385 gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event);
364 { 386 return TRUE;
365 g_free(iter); 387 } else {
366 return FALSE; 388 return FALSE;
367 } 389 }
368
369 data = g_new(gpointer, 4);
370 data[0] = lv;
371 data[1] = log;
372 data[2] = NULL;
373 data[3] = iter;
374
375 log_show_popup_menu(treeview, event, data);
376 return TRUE;
377 } 390 }
378 391
379 return FALSE; 392 return FALSE;
380 } 393 }
381 394
382 static gboolean log_popup_menu_cb(GtkWidget *treeview, PidginLogViewer *lv) 395 static gboolean log_popup_menu_cb(GtkWidget *treeview, PidginLogViewer *lv)
383 { 396 {
384 GtkTreeSelection *sel; 397 GtkTreeSelection *sel;
385 GtkTreeIter *iter; 398 GtkTreeIter *iter;
386 GValue val; 399 GtkWidget *menu;
387 PurpleLog *log;
388 gpointer *data;
389 400
390 iter = g_new(GtkTreeIter, 1); 401 iter = g_new(GtkTreeIter, 1);
391 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview)); 402 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview));
392 if (!gtk_tree_selection_get_selected(sel, NULL, iter)) 403 if (!gtk_tree_selection_get_selected(sel, NULL, iter)) {
393 { 404 g_free(iter);
394 return FALSE; 405 return FALSE;
395 } 406 }
396 407
397 val.g_type = 0; 408 menu = log_create_popup_menu(treeview, lv, iter);
398 gtk_tree_model_get_value(GTK_TREE_MODEL(lv->treestore), 409 if (menu) {
399 iter, NODE_COLUMN, &val); 410 pidgin_menu_popup_at_treeview_selection(menu, treeview);
400 411 return TRUE;
401 log = g_value_get_pointer(&val); 412 } else {
402
403 if (log == NULL)
404 return FALSE; 413 return FALSE;
405 414 }
406 data = g_new(gpointer, 4);
407 data[0] = lv;
408 data[1] = log;
409 data[2] = pidgin_treeview_popup_menu_position_func;
410 data[3] = iter;
411
412 log_show_popup_menu(treeview, NULL, data);
413 return TRUE;
414 } 415 }
415 416
416 static gboolean search_find_cb(gpointer data) 417 static gboolean search_find_cb(gpointer data)
417 { 418 {
418 PidginLogViewer *viewer = data; 419 PidginLogViewer *viewer = data;
442 return; 443 return;
443 444
444 pidgin_set_cursor(viewer->window, GDK_WATCH); 445 pidgin_set_cursor(viewer->window, GDK_WATCH);
445 446
446 if (log->type != PURPLE_LOG_SYSTEM) { 447 if (log->type != PURPLE_LOG_SYSTEM) {
448 gchar *log_date = log_get_date(log);
447 char *title; 449 char *title;
448 if (log->type == PURPLE_LOG_CHAT) 450 if (log->type == PURPLE_LOG_CHAT)
449 title = g_strdup_printf(_("<span size='larger' weight='bold'>Conversation in %s on %s</span>"), 451 title = g_strdup_printf(_("<span size='larger' weight='bold'>Conversation in %s on %s</span>"),
450 log->name, log_get_date(log)); 452 log->name, log_date);
451 else 453 else
452 title = g_strdup_printf(_("<span size='larger' weight='bold'>Conversation with %s on %s</span>"), 454 title = g_strdup_printf(_("<span size='larger' weight='bold'>Conversation with %s on %s</span>"),
453 log->name, log_get_date(log)); 455 log->name, log_date);
454 456
455 gtk_label_set_markup(viewer->label, title); 457 gtk_label_set_markup(viewer->label, title);
458 g_free(log_date);
456 g_free(title); 459 g_free(title);
457 } 460 }
458 461
459 read = purple_log_read(log, &flags); 462 read = purple_log_read(log, &flags);
460 viewer->flags = flags; 463 viewer->flags = flags;
490 */ 493 */
491 static void populate_log_tree(PidginLogViewer *lv) 494 static void populate_log_tree(PidginLogViewer *lv)
492 /* Logs are made from trees in real life. 495 /* Logs are made from trees in real life.
493 This is a tree made from logs */ 496 This is a tree made from logs */
494 { 497 {
495 const char *month; 498 gchar *month;
496 char prev_top_month[30] = ""; 499 char prev_top_month[30] = "";
497 GtkTreeIter toplevel, child; 500 GtkTreeIter toplevel, child;
498 GList *logs = lv->logs; 501 GList *logs = lv->logs;
499 502
500 while (logs != NULL) { 503 while (logs != NULL) {
501 PurpleLog *log = logs->data; 504 PurpleLog *log = logs->data;
502 505 GDateTime *dt;
503 month = purple_utf8_strftime(_("%B %Y"), 506 gchar *log_date;
504 log->tm ? log->tm : localtime(&log->time)); 507
505 508 dt = g_date_time_to_local(log->time);
506 if (!purple_strequal(month, prev_top_month)) 509 month = g_date_time_format(dt, _("%B %Y"));
507 { 510
511 if (!purple_strequal(month, prev_top_month)) {
508 /* top level */ 512 /* top level */
509 gtk_tree_store_append(lv->treestore, &toplevel, NULL); 513 gtk_tree_store_append(lv->treestore, &toplevel, NULL);
510 gtk_tree_store_set(lv->treestore, &toplevel, 0, month, 1, NULL, -1); 514 gtk_tree_store_set(lv->treestore, &toplevel, 0, month, 1, NULL, -1);
511 515
512 g_strlcpy(prev_top_month, month, sizeof(prev_top_month)); 516 g_strlcpy(prev_top_month, month, sizeof(prev_top_month));
513 } 517 }
514 518
515 /* sub */ 519 /* sub */
520 log_date = g_date_time_format(dt, "%c");
516 gtk_tree_store_append(lv->treestore, &child, &toplevel); 521 gtk_tree_store_append(lv->treestore, &child, &toplevel);
517 gtk_tree_store_set(lv->treestore, &child, 522 gtk_tree_store_set(lv->treestore, &child,
518 0, log_get_date(log), 523 0, log_date,
519 1, log, 524 1, log,
520 -1); 525 -1);
521 526
527 g_free(log_date);
528 g_free(month);
529 g_date_time_unref(dt);
522 logs = logs->next; 530 logs = logs->next;
523 } 531 }
524 } 532 }
525 533
526 static PidginLogViewer *display_log_viewer(struct log_viewer_hash_t *ht, GList *logs, 534 static PidginLogViewer *display_log_viewer(struct log_viewer_hash_t *ht, GList *logs,

mercurial