| 306 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 " |
| 307 "which started at %s?"), time); |
308 "which started at %s?"), time); |
| 308 } |
309 } |
| 309 else { |
310 else { |
| 310 g_free(time); |
311 g_free(time); |
| |
312 g_free(iter); |
| 311 g_return_if_reached(); |
313 g_return_if_reached(); |
| 312 } |
314 } |
| 313 |
315 |
| 314 /* 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 |
| 315 * 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 |
| 316 * 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 |
| 317 * 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 |
| 318 * either way. */ |
320 * either way. */ |
| 319 data2 = g_new(gpointer, 3); |
321 data2 = g_new(gpointer, 3); |
| 320 data2[0] = lv->treestore; |
322 data2[0] = lv->treestore; |
| 321 data2[1] = data[3]; /* iter */ |
323 data2[1] = iter; |
| 322 data2[2] = log; |
324 data2[2] = log; |
| 323 purple_request_action(lv, NULL, _("Delete Log?"), tmp, 0, |
325 purple_request_action(lv, NULL, _("Delete Log?"), tmp, 0, |
| 324 NULL, |
326 NULL, |
| 325 data2, 2, |
327 data2, 2, |
| 326 _("Delete"), delete_log_cb, |
328 _("Delete"), delete_log_cb, |
| 327 _("Cancel"), delete_log_cleanup_cb); |
329 _("Cancel"), delete_log_cleanup_cb); |
| 328 g_free(time); |
330 g_free(time); |
| 329 g_free(tmp); |
331 g_free(tmp); |
| 330 } |
332 } |
| 331 |
333 |
| 332 static void log_show_popup_menu(GtkWidget *treeview, GdkEventButton *event, gpointer *data) |
334 static GtkWidget * |
| 333 { |
335 log_create_popup_menu(GtkWidget *treeview, PidginLogViewer *lv, GtkTreeIter *iter) |
| 334 GtkWidget *menu = gtk_menu_new(); |
336 { |
| 335 GtkWidget *menuitem = gtk_menu_item_new_with_label(_("Delete Log...")); |
337 GValue val; |
| 336 |
338 PurpleLog *log; |
| 337 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 { |
| 338 gtk_widget_set_sensitive(menuitem, FALSE); |
362 gtk_widget_set_sensitive(menuitem, FALSE); |
| 339 |
363 } |
| 340 g_signal_connect(menuitem, "activate", G_CALLBACK(log_delete_log_cb), data); |
|
| 341 g_object_set_data_full(G_OBJECT(menuitem), "log-viewer-data", data, g_free); |
|
| 342 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
364 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
| 343 gtk_widget_show_all(menu); |
365 gtk_widget_show_all(menu); |
| 344 |
366 |
| 345 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, (GtkMenuPositionFunc)data[2], NULL, |
367 return menu; |
| 346 (event != NULL) ? event->button : 0, |
|
| 347 gdk_event_get_time((GdkEvent *)event)); |
|
| 348 } |
368 } |
| 349 |
369 |
| 350 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) |
| 351 { |
371 { |
| 352 if (gdk_event_triggers_context_menu((GdkEvent *)event)) { |
372 if (gdk_event_triggers_context_menu((GdkEvent *)event)) { |
| 353 GtkTreePath *path; |
373 GtkTreePath *path; |
| 354 GtkTreeIter *iter; |
374 GtkTreeIter *iter; |
| 355 GValue val; |
375 GtkWidget *menu; |
| 356 PurpleLog *log; |
|
| 357 gpointer *data; |
|
| 358 |
376 |
| 359 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)) |
| 360 return FALSE; |
378 return FALSE; |
| 361 iter = g_new(GtkTreeIter, 1); |
379 iter = g_new(GtkTreeIter, 1); |
| 362 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); |
| 363 val.g_type = 0; |
|
| 364 gtk_tree_model_get_value(GTK_TREE_MODEL(lv->treestore), iter, 1, &val); |
|
| 365 gtk_tree_path_free(path); |
381 gtk_tree_path_free(path); |
| 366 |
382 |
| 367 log = g_value_get_pointer(&val); |
383 menu = log_create_popup_menu(treeview, lv, iter); |
| 368 |
384 if (menu) { |
| 369 if (log == NULL) |
385 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, |
| 370 { |
386 event->button, gdk_event_get_time((GdkEvent *)event)); |
| 371 g_free(iter); |
387 return TRUE; |
| |
388 } else { |
| 372 return FALSE; |
389 return FALSE; |
| 373 } |
390 } |
| 374 |
|
| 375 data = g_new(gpointer, 4); |
|
| 376 data[0] = lv; |
|
| 377 data[1] = log; |
|
| 378 data[2] = NULL; |
|
| 379 data[3] = iter; |
|
| 380 |
|
| 381 log_show_popup_menu(treeview, event, data); |
|
| 382 return TRUE; |
|
| 383 } |
391 } |
| 384 |
392 |
| 385 return FALSE; |
393 return FALSE; |
| 386 } |
394 } |
| 387 |
395 |
| 388 static gboolean log_popup_menu_cb(GtkWidget *treeview, PidginLogViewer *lv) |
396 static gboolean log_popup_menu_cb(GtkWidget *treeview, PidginLogViewer *lv) |
| 389 { |
397 { |
| 390 GtkTreeSelection *sel; |
398 GtkTreeSelection *sel; |
| 391 GtkTreeIter *iter; |
399 GtkTreeIter *iter; |
| 392 GValue val; |
400 GtkWidget *menu; |
| 393 PurpleLog *log; |
|
| 394 gpointer *data; |
|
| 395 |
401 |
| 396 iter = g_new(GtkTreeIter, 1); |
402 iter = g_new(GtkTreeIter, 1); |
| 397 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview)); |
403 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(lv->treeview)); |
| 398 if (!gtk_tree_selection_get_selected(sel, NULL, iter)) |
404 if (!gtk_tree_selection_get_selected(sel, NULL, iter)) { |
| 399 { |
405 g_free(iter); |
| 400 return FALSE; |
406 return FALSE; |
| 401 } |
407 } |
| 402 |
408 |
| 403 val.g_type = 0; |
409 menu = log_create_popup_menu(treeview, lv, iter); |
| 404 gtk_tree_model_get_value(GTK_TREE_MODEL(lv->treestore), |
410 if (menu) { |
| 405 iter, NODE_COLUMN, &val); |
411 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, |
| 406 |
412 pidgin_treeview_popup_menu_position_func, treeview, |
| 407 log = g_value_get_pointer(&val); |
413 0, GDK_CURRENT_TIME); |
| 408 |
414 return TRUE; |
| 409 if (log == NULL) |
415 } else { |
| 410 return FALSE; |
416 return FALSE; |
| 411 |
417 } |
| 412 data = g_new(gpointer, 4); |
|
| 413 data[0] = lv; |
|
| 414 data[1] = log; |
|
| 415 data[2] = pidgin_treeview_popup_menu_position_func; |
|
| 416 data[3] = iter; |
|
| 417 |
|
| 418 log_show_popup_menu(treeview, NULL, data); |
|
| 419 return TRUE; |
|
| 420 } |
418 } |
| 421 |
419 |
| 422 static gboolean search_find_cb(gpointer data) |
420 static gboolean search_find_cb(gpointer data) |
| 423 { |
421 { |
| 424 PidginLogViewer *viewer = data; |
422 PidginLogViewer *viewer = data; |