Mercurial > pidgin
comparison gtk/gtkft.c @ 14191:009db0b357b5
This is a hand-crafted commit to migrate across subversion revisions
16854:16861, due to some vagaries of the way the original renames were
done. Witness that monotone can do in one revision what svn had to
spread across several.
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Sat, 16 Dec 2006 04:59:55 +0000 |
parents | |
children | 2620e491c8f1 |
comparison
equal
deleted
inserted
replaced
14190:366be2ce35a7 | 14191:009db0b357b5 |
---|---|
1 /** | |
2 * @file gtkft.c GTK+ File Transfer UI | |
3 * @ingroup gtkui | |
4 * | |
5 * gaim | |
6 * | |
7 * Gaim is the legal property of its developers, whose names are too numerous | |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
10 * | |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
25 #include "internal.h" | |
26 #include "gtkgaim.h" | |
27 | |
28 #include "debug.h" | |
29 #include "notify.h" | |
30 #include "ft.h" | |
31 #include "prpl.h" | |
32 #include "util.h" | |
33 | |
34 #include "gtkcellrendererprogress.h" | |
35 #include "gtkft.h" | |
36 #include "prefs.h" | |
37 #include "gtkexpander.h" | |
38 #include "gaimstock.h" | |
39 #include "gtkutils.h" | |
40 | |
41 #define GAIM_GTKXFER(xfer) \ | |
42 (GaimGtkXferUiData *)(xfer)->ui_data | |
43 | |
44 struct _GaimGtkXferDialog | |
45 { | |
46 gboolean keep_open; | |
47 gboolean auto_clear; | |
48 | |
49 gint num_transfers; | |
50 | |
51 GaimXfer *selected_xfer; | |
52 | |
53 GtkWidget *window; | |
54 GtkWidget *tree; | |
55 GtkListStore *model; | |
56 | |
57 GtkWidget *expander; | |
58 | |
59 GtkWidget *table; | |
60 | |
61 GtkWidget *local_user_desc_label; | |
62 GtkWidget *local_user_label; | |
63 GtkWidget *remote_user_desc_label; | |
64 GtkWidget *remote_user_label; | |
65 GtkWidget *protocol_label; | |
66 GtkWidget *filename_label; | |
67 GtkWidget *localfile_label; | |
68 GtkWidget *status_label; | |
69 GtkWidget *speed_label; | |
70 GtkWidget *time_elapsed_label; | |
71 GtkWidget *time_remaining_label; | |
72 | |
73 GtkWidget *progress; | |
74 | |
75 /* Buttons */ | |
76 GtkWidget *open_button; | |
77 GtkWidget *pause_button; | |
78 GtkWidget *resume_button; | |
79 GtkWidget *remove_button; | |
80 GtkWidget *stop_button; | |
81 GtkWidget *close_button; | |
82 }; | |
83 | |
84 typedef struct | |
85 { | |
86 GtkTreeIter iter; | |
87 time_t last_updated_time; | |
88 gboolean in_list; | |
89 | |
90 char *name; | |
91 | |
92 } GaimGtkXferUiData; | |
93 | |
94 static GaimGtkXferDialog *xfer_dialog = NULL; | |
95 | |
96 enum | |
97 { | |
98 COLUMN_STATUS = 0, | |
99 COLUMN_PROGRESS, | |
100 COLUMN_FILENAME, | |
101 COLUMN_SIZE, | |
102 COLUMN_REMAINING, | |
103 COLUMN_DATA, | |
104 NUM_COLUMNS | |
105 }; | |
106 | |
107 | |
108 /************************************************************************** | |
109 * Utility Functions | |
110 **************************************************************************/ | |
111 static void | |
112 get_xfer_info_strings(GaimXfer *xfer, char **kbsec, char **time_elapsed, | |
113 char **time_remaining) | |
114 { | |
115 GaimGtkXferUiData *data; | |
116 double kb_sent, kb_rem; | |
117 double kbps = 0.0; | |
118 time_t elapsed, now; | |
119 | |
120 data = GAIM_GTKXFER(xfer); | |
121 | |
122 if (xfer->end_time != 0) | |
123 now = xfer->end_time; | |
124 else | |
125 now = time(NULL); | |
126 | |
127 kb_sent = gaim_xfer_get_bytes_sent(xfer) / 1024.0; | |
128 kb_rem = gaim_xfer_get_bytes_remaining(xfer) / 1024.0; | |
129 elapsed = (xfer->start_time > 0 ? now - xfer->start_time : 0); | |
130 kbps = (elapsed > 0 ? (kb_sent / elapsed) : 0); | |
131 | |
132 if (kbsec != NULL) { | |
133 *kbsec = g_strdup_printf(_("%.2f KB/s"), kbps); | |
134 } | |
135 | |
136 if (time_elapsed != NULL) | |
137 { | |
138 int h, m, s; | |
139 int secs_elapsed; | |
140 | |
141 if (xfer->start_time > 0) | |
142 { | |
143 secs_elapsed = now - xfer->start_time; | |
144 | |
145 h = secs_elapsed / 3600; | |
146 m = (secs_elapsed % 3600) / 60; | |
147 s = secs_elapsed % 60; | |
148 | |
149 *time_elapsed = g_strdup_printf("%d:%02d:%02d", h, m, s); | |
150 } | |
151 else | |
152 { | |
153 *time_elapsed = g_strdup(_("Not started")); | |
154 } | |
155 } | |
156 | |
157 if (time_remaining != NULL) { | |
158 if (gaim_xfer_get_size(xfer) == 0) { | |
159 *time_remaining = g_strdup(_("Unknown")); | |
160 } | |
161 else if (gaim_xfer_is_completed(xfer)) { | |
162 *time_remaining = g_strdup(_("Finished")); | |
163 } | |
164 else if (gaim_xfer_is_canceled(xfer)) { | |
165 *time_remaining = g_strdup(_("Canceled")); | |
166 } | |
167 else if (kb_sent <= 0) { | |
168 *time_remaining = g_strdup(_("Waiting for transfer to begin")); | |
169 } | |
170 else { | |
171 int h, m, s; | |
172 int secs_remaining; | |
173 | |
174 secs_remaining = (int)(kb_rem / kbps); | |
175 | |
176 h = secs_remaining / 3600; | |
177 m = (secs_remaining % 3600) / 60; | |
178 s = secs_remaining % 60; | |
179 | |
180 *time_remaining = g_strdup_printf("%d:%02d:%02d", h, m, s); | |
181 } | |
182 } | |
183 } | |
184 | |
185 static void | |
186 update_detailed_info(GaimGtkXferDialog *dialog, GaimXfer *xfer) | |
187 { | |
188 GaimGtkXferUiData *data; | |
189 char *kbsec, *time_elapsed, *time_remaining; | |
190 char *status, *utf8; | |
191 | |
192 if (dialog == NULL || xfer == NULL) | |
193 return; | |
194 | |
195 data = GAIM_GTKXFER(xfer); | |
196 | |
197 get_xfer_info_strings(xfer, &kbsec, &time_elapsed, &time_remaining); | |
198 | |
199 status = g_strdup_printf("%ld%% (%ld of %ld bytes)", | |
200 (unsigned long)(gaim_xfer_get_progress(xfer)*100), | |
201 (unsigned long)gaim_xfer_get_bytes_sent(xfer), | |
202 (unsigned long)gaim_xfer_get_size(xfer)); | |
203 | |
204 if (gaim_xfer_is_completed(xfer)) { | |
205 | |
206 GdkPixbuf *pixbuf = NULL; | |
207 | |
208 pixbuf = gtk_widget_render_icon(xfer_dialog->window, | |
209 GAIM_STOCK_FILE_DONE, | |
210 GTK_ICON_SIZE_MENU, NULL); | |
211 | |
212 gtk_list_store_set(GTK_LIST_STORE(xfer_dialog->model), &data->iter, | |
213 COLUMN_STATUS, pixbuf, | |
214 -1); | |
215 | |
216 g_object_unref(pixbuf); | |
217 } | |
218 | |
219 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
220 gtk_label_set_markup(GTK_LABEL(dialog->local_user_desc_label), | |
221 _("<b>Receiving As:</b>")); | |
222 gtk_label_set_markup(GTK_LABEL(dialog->remote_user_desc_label), | |
223 _("<b>Receiving From:</b>")); | |
224 } | |
225 else { | |
226 gtk_label_set_markup(GTK_LABEL(dialog->remote_user_desc_label), | |
227 _("<b>Sending To:</b>")); | |
228 gtk_label_set_markup(GTK_LABEL(dialog->local_user_desc_label), | |
229 _("<b>Sending As:</b>")); | |
230 } | |
231 | |
232 gtk_label_set_text(GTK_LABEL(dialog->local_user_label), | |
233 gaim_account_get_username(xfer->account)); | |
234 gtk_label_set_text(GTK_LABEL(dialog->remote_user_label), xfer->who); | |
235 gtk_label_set_text(GTK_LABEL(dialog->protocol_label), | |
236 gaim_account_get_protocol_name(xfer->account)); | |
237 | |
238 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
239 gtk_label_set_text(GTK_LABEL(dialog->filename_label), | |
240 gaim_xfer_get_filename(xfer)); | |
241 } else { | |
242 char *tmp; | |
243 | |
244 tmp = g_path_get_basename(gaim_xfer_get_local_filename(xfer)); | |
245 utf8 = g_filename_to_utf8(tmp, -1, NULL, NULL, NULL); | |
246 g_free(tmp); | |
247 | |
248 gtk_label_set_text(GTK_LABEL(dialog->filename_label), utf8); | |
249 g_free(utf8); | |
250 } | |
251 | |
252 utf8 = g_filename_to_utf8((gaim_xfer_get_local_filename(xfer)), -1, NULL, NULL, NULL); | |
253 gtk_label_set_text(GTK_LABEL(dialog->localfile_label), utf8); | |
254 g_free(utf8); | |
255 | |
256 gtk_label_set_text(GTK_LABEL(dialog->status_label), status); | |
257 | |
258 gtk_label_set_text(GTK_LABEL(dialog->speed_label), kbsec); | |
259 gtk_label_set_text(GTK_LABEL(dialog->time_elapsed_label), time_elapsed); | |
260 gtk_label_set_text(GTK_LABEL(dialog->time_remaining_label), | |
261 time_remaining); | |
262 | |
263 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(dialog->progress), | |
264 gaim_xfer_get_progress(xfer)); | |
265 | |
266 g_free(kbsec); | |
267 g_free(time_elapsed); | |
268 g_free(time_remaining); | |
269 g_free(status); | |
270 } | |
271 | |
272 static void | |
273 update_buttons(GaimGtkXferDialog *dialog, GaimXfer *xfer) | |
274 { | |
275 if (dialog->selected_xfer == NULL) { | |
276 gtk_widget_set_sensitive(dialog->expander, FALSE); | |
277 gtk_widget_set_sensitive(dialog->open_button, FALSE); | |
278 gtk_widget_set_sensitive(dialog->pause_button, FALSE); | |
279 gtk_widget_set_sensitive(dialog->resume_button, FALSE); | |
280 gtk_widget_set_sensitive(dialog->stop_button, FALSE); | |
281 | |
282 gtk_widget_show(dialog->stop_button); | |
283 gtk_widget_hide(dialog->remove_button); | |
284 | |
285 return; | |
286 } | |
287 | |
288 if (dialog->selected_xfer != xfer) | |
289 return; | |
290 | |
291 if (gaim_xfer_is_completed(xfer)) { | |
292 gtk_widget_hide(dialog->stop_button); | |
293 gtk_widget_show(dialog->remove_button); | |
294 | |
295 #ifdef _WIN32 | |
296 /* If using Win32... */ | |
297 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
298 gtk_widget_set_sensitive(dialog->open_button, TRUE); | |
299 } else { | |
300 gtk_widget_set_sensitive(dialog->open_button, FALSE); | |
301 } | |
302 #else | |
303 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
304 gtk_widget_set_sensitive(dialog->open_button, TRUE); | |
305 } else { | |
306 gtk_widget_set_sensitive (dialog->open_button, FALSE); | |
307 } | |
308 #endif | |
309 gtk_widget_set_sensitive(dialog->pause_button, FALSE); | |
310 gtk_widget_set_sensitive(dialog->resume_button, FALSE); | |
311 | |
312 gtk_widget_set_sensitive(dialog->remove_button, TRUE); | |
313 } else if (gaim_xfer_is_canceled(xfer)) { | |
314 gtk_widget_hide(dialog->stop_button); | |
315 gtk_widget_show(dialog->remove_button); | |
316 | |
317 gtk_widget_set_sensitive(dialog->open_button, FALSE); | |
318 gtk_widget_set_sensitive(dialog->pause_button, FALSE); | |
319 gtk_widget_set_sensitive(dialog->resume_button, FALSE); | |
320 | |
321 gtk_widget_set_sensitive(dialog->remove_button, TRUE); | |
322 } else { | |
323 gtk_widget_show(dialog->stop_button); | |
324 gtk_widget_hide(dialog->remove_button); | |
325 | |
326 gtk_widget_set_sensitive(dialog->open_button, FALSE); | |
327 | |
328 /* TODO: If the transfer can pause, blah blah */ | |
329 gtk_widget_set_sensitive(dialog->pause_button, FALSE); | |
330 gtk_widget_set_sensitive(dialog->resume_button, FALSE); | |
331 gtk_widget_set_sensitive(dialog->stop_button, TRUE); | |
332 } | |
333 } | |
334 | |
335 static void | |
336 ensure_row_selected(GaimGtkXferDialog *dialog) | |
337 { | |
338 GtkTreeIter iter; | |
339 GtkTreeSelection *selection; | |
340 | |
341 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->tree)); | |
342 | |
343 if (gtk_tree_selection_get_selected(selection, NULL, &iter)) | |
344 return; | |
345 | |
346 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(dialog->model), &iter)) | |
347 gtk_tree_selection_select_iter(selection, &iter); | |
348 } | |
349 | |
350 /************************************************************************** | |
351 * Callbacks | |
352 **************************************************************************/ | |
353 static gint | |
354 delete_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d) | |
355 { | |
356 GaimGtkXferDialog *dialog; | |
357 | |
358 dialog = (GaimGtkXferDialog *)d; | |
359 | |
360 gaim_gtkxfer_dialog_hide(dialog); | |
361 | |
362 return TRUE; | |
363 } | |
364 | |
365 static void | |
366 toggle_keep_open_cb(GtkWidget *w, GaimGtkXferDialog *dialog) | |
367 { | |
368 dialog->keep_open = !dialog->keep_open; | |
369 gaim_prefs_set_bool("/gaim/gtk/filetransfer/keep_open", | |
370 dialog->keep_open); | |
371 } | |
372 | |
373 static void | |
374 toggle_clear_finished_cb(GtkWidget *w, GaimGtkXferDialog *dialog) | |
375 { | |
376 dialog->auto_clear = !dialog->auto_clear; | |
377 gaim_prefs_set_bool("/gaim/gtk/filetransfer/clear_finished", | |
378 dialog->auto_clear); | |
379 } | |
380 | |
381 static void | |
382 selection_changed_cb(GtkTreeSelection *selection, GaimGtkXferDialog *dialog) | |
383 { | |
384 GtkTreeIter iter; | |
385 GaimXfer *xfer = NULL; | |
386 | |
387 if (gtk_tree_selection_get_selected(selection, NULL, &iter)) { | |
388 GValue val; | |
389 | |
390 gtk_widget_set_sensitive(dialog->expander, TRUE); | |
391 | |
392 val.g_type = 0; | |
393 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), | |
394 &iter, COLUMN_DATA, &val); | |
395 | |
396 xfer = g_value_get_pointer(&val); | |
397 | |
398 update_detailed_info(dialog, xfer); | |
399 | |
400 dialog->selected_xfer = xfer; | |
401 } | |
402 else { | |
403 gtk_expander_set_expanded(GTK_EXPANDER(dialog->expander), | |
404 FALSE); | |
405 | |
406 gtk_widget_set_sensitive(dialog->expander, FALSE); | |
407 | |
408 dialog->selected_xfer = NULL; | |
409 } | |
410 | |
411 update_buttons(dialog, xfer); | |
412 } | |
413 | |
414 static void | |
415 open_button_cb(GtkButton *button, GaimGtkXferDialog *dialog) | |
416 { | |
417 #ifdef _WIN32 | |
418 /* If using Win32... */ | |
419 int code; | |
420 if (G_WIN32_HAVE_WIDECHAR_API ()) { | |
421 wchar_t *wc_filename = g_utf8_to_utf16( | |
422 gaim_xfer_get_local_filename( | |
423 dialog->selected_xfer), | |
424 -1, NULL, NULL, NULL); | |
425 | |
426 code = (int) ShellExecuteW(NULL, NULL, wc_filename, NULL, NULL, | |
427 SW_SHOW); | |
428 | |
429 g_free(wc_filename); | |
430 } else { | |
431 char *l_filename = g_locale_from_utf8( | |
432 gaim_xfer_get_local_filename( | |
433 dialog->selected_xfer), | |
434 -1, NULL, NULL, NULL); | |
435 | |
436 code = (int) ShellExecuteA(NULL, NULL, l_filename, NULL, NULL, | |
437 SW_SHOW); | |
438 | |
439 g_free(l_filename); | |
440 } | |
441 | |
442 if (code == SE_ERR_ASSOCINCOMPLETE || code == SE_ERR_NOASSOC) | |
443 { | |
444 gaim_notify_error(dialog, NULL, | |
445 _("There is no application configured to open this type of file."), NULL); | |
446 } | |
447 else if (code < 32) | |
448 { | |
449 gaim_notify_error(dialog, NULL, | |
450 _("An error occurred while opening the file."), NULL); | |
451 gaim_debug_warning("ft", "filename: %s; code: %d\n", | |
452 gaim_xfer_get_local_filename(dialog->selected_xfer), code); | |
453 } | |
454 #else | |
455 const char *filename = gaim_xfer_get_local_filename(dialog->selected_xfer); | |
456 char *command = NULL; | |
457 char *tmp = NULL; | |
458 GError *error = NULL; | |
459 | |
460 if (gaim_running_gnome()) | |
461 { | |
462 char *escaped = g_shell_quote(filename); | |
463 command = g_strdup_printf("gnome-open %s", escaped); | |
464 g_free(escaped); | |
465 } | |
466 else if (gaim_running_kde()) | |
467 { | |
468 char *escaped = g_shell_quote(filename); | |
469 | |
470 if (gaim_str_has_suffix(filename, ".desktop")) | |
471 command = g_strdup_printf("kfmclient openURL %s 'text/plain'", escaped); | |
472 else | |
473 command = g_strdup_printf("kfmclient openURL %s", escaped); | |
474 g_free(escaped); | |
475 } | |
476 else | |
477 { | |
478 gaim_notify_uri(NULL, filename); | |
479 return; | |
480 } | |
481 | |
482 if (gaim_program_is_valid(command)) | |
483 { | |
484 gint exit_status; | |
485 if (!g_spawn_command_line_sync(command, NULL, NULL, &exit_status, &error)) | |
486 { | |
487 tmp = g_strdup_printf(_("Error launching %s: %s"), | |
488 gaim_xfer_get_local_filename(dialog->selected_xfer), | |
489 error->message); | |
490 gaim_notify_error(dialog, NULL, _("Unable to open file."), tmp); | |
491 g_free(tmp); | |
492 g_error_free(error); | |
493 } | |
494 if (exit_status != 0) | |
495 { | |
496 char *primary = g_strdup_printf(_("Error running %s"), command); | |
497 char *secondary = g_strdup_printf(_("Process returned error code %d"), | |
498 exit_status); | |
499 gaim_notify_error(dialog, NULL, primary, secondary); | |
500 g_free(tmp); | |
501 } | |
502 } | |
503 #endif | |
504 } | |
505 | |
506 static void | |
507 pause_button_cb(GtkButton *button, GaimGtkXferDialog *dialog) | |
508 { | |
509 } | |
510 | |
511 static void | |
512 resume_button_cb(GtkButton *button, GaimGtkXferDialog *dialog) | |
513 { | |
514 } | |
515 | |
516 static void | |
517 remove_button_cb(GtkButton *button, GaimGtkXferDialog *dialog) | |
518 { | |
519 gaim_gtkxfer_dialog_remove_xfer(dialog, dialog->selected_xfer); | |
520 } | |
521 | |
522 static void | |
523 stop_button_cb(GtkButton *button, GaimGtkXferDialog *dialog) | |
524 { | |
525 gaim_xfer_cancel_local(dialog->selected_xfer); | |
526 } | |
527 | |
528 static void | |
529 close_button_cb(GtkButton *button, GaimGtkXferDialog *dialog) | |
530 { | |
531 gaim_gtkxfer_dialog_hide(dialog); | |
532 } | |
533 | |
534 /************************************************************************** | |
535 * Dialog Building Functions | |
536 **************************************************************************/ | |
537 static GtkWidget * | |
538 setup_tree(GaimGtkXferDialog *dialog) | |
539 { | |
540 GtkWidget *sw; | |
541 GtkWidget *tree; | |
542 GtkListStore *model; | |
543 GtkCellRenderer *renderer; | |
544 GtkTreeViewColumn *column; | |
545 GtkTreeSelection *selection; | |
546 | |
547 /* Create the scrolled window. */ | |
548 sw = gtk_scrolled_window_new(0, 0); | |
549 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
550 GTK_SHADOW_IN); | |
551 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
552 GTK_POLICY_AUTOMATIC, | |
553 GTK_POLICY_AUTOMATIC); | |
554 gtk_widget_show(sw); | |
555 | |
556 /* Build the tree model */ | |
557 /* Transfer type, Progress Bar, Filename, Size, Remaining */ | |
558 model = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_DOUBLE, | |
559 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, | |
560 G_TYPE_POINTER); | |
561 dialog->model = model; | |
562 | |
563 /* Create the treeview */ | |
564 dialog->tree = tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); | |
565 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE); | |
566 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); | |
567 /* gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); */ | |
568 | |
569 gtk_widget_show(tree); | |
570 | |
571 g_signal_connect(G_OBJECT(selection), "changed", | |
572 G_CALLBACK(selection_changed_cb), dialog); | |
573 | |
574 g_object_unref(G_OBJECT(model)); | |
575 | |
576 | |
577 /* Columns */ | |
578 | |
579 /* Transfer Type column */ | |
580 renderer = gtk_cell_renderer_pixbuf_new(); | |
581 column = gtk_tree_view_column_new_with_attributes(NULL, renderer, | |
582 "pixbuf", COLUMN_STATUS, NULL); | |
583 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column), | |
584 GTK_TREE_VIEW_COLUMN_FIXED); | |
585 gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column), 25); | |
586 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); | |
587 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); | |
588 | |
589 /* Progress bar column */ | |
590 renderer = gaim_gtk_cell_renderer_progress_new(); | |
591 column = gtk_tree_view_column_new_with_attributes(_("Progress"), renderer, | |
592 "percentage", COLUMN_PROGRESS, NULL); | |
593 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); | |
594 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); | |
595 | |
596 /* Filename column */ | |
597 renderer = gtk_cell_renderer_text_new(); | |
598 column = gtk_tree_view_column_new_with_attributes(_("Filename"), renderer, | |
599 "text", COLUMN_FILENAME, NULL); | |
600 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); | |
601 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); | |
602 | |
603 /* File Size column */ | |
604 renderer = gtk_cell_renderer_text_new(); | |
605 column = gtk_tree_view_column_new_with_attributes(_("Size"), renderer, | |
606 "text", COLUMN_SIZE, NULL); | |
607 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); | |
608 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); | |
609 | |
610 /* Bytes Remaining column */ | |
611 renderer = gtk_cell_renderer_text_new(); | |
612 column = gtk_tree_view_column_new_with_attributes(_("Remaining"), | |
613 renderer, "text", COLUMN_REMAINING, NULL); | |
614 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); | |
615 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); | |
616 | |
617 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(tree)); | |
618 | |
619 gtk_container_add(GTK_CONTAINER(sw), tree); | |
620 gtk_widget_show(tree); | |
621 | |
622 return sw; | |
623 } | |
624 | |
625 static GtkWidget * | |
626 make_info_table(GaimGtkXferDialog *dialog) | |
627 { | |
628 GtkWidget *table; | |
629 GtkWidget *label; | |
630 int i; | |
631 | |
632 struct | |
633 { | |
634 GtkWidget **desc_label; | |
635 GtkWidget **val_label; | |
636 const char *desc; | |
637 | |
638 } labels[] = | |
639 { | |
640 { &dialog->local_user_desc_label, &dialog->local_user_label, NULL }, | |
641 { &dialog->remote_user_desc_label, &dialog->remote_user_label, NULL }, | |
642 { &label, &dialog->protocol_label, _("Protocol:") }, | |
643 { &label, &dialog->filename_label, _("Filename:") }, | |
644 { &label, &dialog->localfile_label, _("Local File:") }, | |
645 { &label, &dialog->status_label, _("Status:") }, | |
646 { &label, &dialog->speed_label, _("Speed:") }, | |
647 { &label, &dialog->time_elapsed_label, _("Time Elapsed:") }, | |
648 { &label, &dialog->time_remaining_label, _("Time Remaining:") } | |
649 }; | |
650 | |
651 /* Setup the initial table */ | |
652 dialog->table = table = gtk_table_new(9, 2, FALSE); | |
653 gtk_table_set_row_spacings(GTK_TABLE(table), GAIM_HIG_BOX_SPACE); | |
654 gtk_table_set_col_spacings(GTK_TABLE(table), GAIM_HIG_BOX_SPACE); | |
655 | |
656 /* Setup the labels */ | |
657 for (i = 0; i < sizeof(labels) / sizeof(*labels); i++) { | |
658 GtkWidget *label; | |
659 char buf[256]; | |
660 | |
661 g_snprintf(buf, sizeof(buf), "<b>%s</b>", | |
662 labels[i].desc != NULL ? labels[i].desc : ""); | |
663 | |
664 *labels[i].desc_label = label = gtk_label_new(NULL); | |
665 gtk_label_set_markup(GTK_LABEL(label), buf); | |
666 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT); | |
667 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
668 gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i + 1, | |
669 GTK_FILL, 0, 0, 0); | |
670 gtk_widget_show(label); | |
671 | |
672 *labels[i].val_label = label = gtk_label_new(NULL); | |
673 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
674 gtk_table_attach(GTK_TABLE(table), label, 1, 2, i, i + 1, | |
675 GTK_FILL | GTK_EXPAND, 0, 0, 0); | |
676 gtk_widget_show(label); | |
677 } | |
678 | |
679 /* Setup the progress bar */ | |
680 dialog->progress = gtk_progress_bar_new(); | |
681 gtk_table_attach(GTK_TABLE(table), dialog->progress, 0, 2, 8, 9, | |
682 GTK_FILL, GTK_FILL, 0, 0); | |
683 gtk_widget_show(dialog->progress); | |
684 | |
685 return table; | |
686 } | |
687 | |
688 GaimGtkXferDialog * | |
689 gaim_gtkxfer_dialog_new(void) | |
690 { | |
691 GaimGtkXferDialog *dialog; | |
692 GtkWidget *window; | |
693 GtkWidget *vbox1, *vbox2; | |
694 GtkWidget *bbox; | |
695 GtkWidget *sw; | |
696 GtkWidget *button; | |
697 GtkWidget *expander; | |
698 GtkWidget *table; | |
699 GtkWidget *checkbox; | |
700 | |
701 dialog = g_new0(GaimGtkXferDialog, 1); | |
702 dialog->keep_open = | |
703 gaim_prefs_get_bool("/gaim/gtk/filetransfer/keep_open"); | |
704 dialog->auto_clear = | |
705 gaim_prefs_get_bool("/gaim/gtk/filetransfer/clear_finished"); | |
706 | |
707 /* Create the window. */ | |
708 dialog->window = window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
709 gtk_window_set_role(GTK_WINDOW(window), "file transfer"); | |
710 gtk_window_set_title(GTK_WINDOW(window), _("File Transfers")); | |
711 gtk_container_set_border_width(GTK_CONTAINER(window), GAIM_HIG_BORDER); | |
712 | |
713 g_signal_connect(G_OBJECT(window), "delete_event", | |
714 G_CALLBACK(delete_win_cb), dialog); | |
715 | |
716 /* Create the parent vbox for everything. */ | |
717 vbox1 = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
718 gtk_container_add(GTK_CONTAINER(window), vbox1); | |
719 gtk_widget_show(vbox1); | |
720 | |
721 /* Create the main vbox for top half of the window. */ | |
722 vbox2 = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
723 gtk_box_pack_start(GTK_BOX(vbox1), vbox2, TRUE, TRUE, 0); | |
724 gtk_widget_show(vbox2); | |
725 | |
726 /* Setup the listbox */ | |
727 sw = setup_tree(dialog); | |
728 gtk_box_pack_start(GTK_BOX(vbox2), sw, TRUE, TRUE, 0); | |
729 gtk_widget_set_size_request(sw,-1, 140); | |
730 | |
731 /* "Close this window when all transfers finish" */ | |
732 checkbox = gtk_check_button_new_with_mnemonic( | |
733 _("Close this window when all transfers _finish")); | |
734 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), | |
735 !dialog->keep_open); | |
736 g_signal_connect(G_OBJECT(checkbox), "toggled", | |
737 G_CALLBACK(toggle_keep_open_cb), dialog); | |
738 gtk_box_pack_start(GTK_BOX(vbox2), checkbox, FALSE, FALSE, 0); | |
739 gtk_widget_show(checkbox); | |
740 | |
741 /* "Clear finished transfers" */ | |
742 checkbox = gtk_check_button_new_with_mnemonic( | |
743 _("C_lear finished transfers")); | |
744 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), | |
745 dialog->auto_clear); | |
746 g_signal_connect(G_OBJECT(checkbox), "toggled", | |
747 G_CALLBACK(toggle_clear_finished_cb), dialog); | |
748 gtk_box_pack_start(GTK_BOX(vbox2), checkbox, FALSE, FALSE, 0); | |
749 gtk_widget_show(checkbox); | |
750 | |
751 /* "Download Details" arrow */ | |
752 expander = gtk_expander_new_with_mnemonic(_("File transfer _details")); | |
753 dialog->expander = expander; | |
754 gtk_box_pack_start(GTK_BOX(vbox2), expander, FALSE, FALSE, 0); | |
755 gtk_widget_show(expander); | |
756 | |
757 gtk_widget_set_sensitive(expander, FALSE); | |
758 | |
759 /* The table of information. */ | |
760 table = make_info_table(dialog); | |
761 gtk_container_add(GTK_CONTAINER(expander), table); | |
762 gtk_widget_show(table); | |
763 | |
764 /* Now the button box for the buttons */ | |
765 bbox = gtk_hbutton_box_new(); | |
766 gtk_box_set_spacing(GTK_BOX(bbox), GAIM_HIG_BOX_SPACE); | |
767 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
768 gtk_box_pack_end(GTK_BOX(vbox1), bbox, FALSE, TRUE, 0); | |
769 gtk_widget_show(bbox); | |
770 | |
771 /* Open button */ | |
772 button = gtk_button_new_from_stock(GTK_STOCK_OPEN); | |
773 gtk_widget_set_sensitive(button, FALSE); | |
774 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
775 gtk_widget_show(button); | |
776 dialog->open_button = button; | |
777 | |
778 g_signal_connect(G_OBJECT(button), "clicked", | |
779 G_CALLBACK(open_button_cb), dialog); | |
780 | |
781 /* Pause button */ | |
782 button = gtk_button_new_with_mnemonic(_("_Pause")); | |
783 gtk_widget_set_sensitive(button, FALSE); | |
784 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
785 gtk_widget_show(button); | |
786 dialog->pause_button = button; | |
787 | |
788 g_signal_connect(G_OBJECT(button), "clicked", | |
789 G_CALLBACK(pause_button_cb), dialog); | |
790 | |
791 /* Resume button */ | |
792 button = gtk_button_new_with_mnemonic(_("_Resume")); | |
793 gtk_widget_set_sensitive(button, FALSE); | |
794 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
795 gtk_widget_show(button); | |
796 dialog->resume_button = button; | |
797 | |
798 g_signal_connect(G_OBJECT(button), "clicked", | |
799 G_CALLBACK(resume_button_cb), dialog); | |
800 | |
801 /* Remove button */ | |
802 button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); | |
803 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
804 gtk_widget_hide(button); | |
805 dialog->remove_button = button; | |
806 | |
807 g_signal_connect(G_OBJECT(button), "clicked", | |
808 G_CALLBACK(remove_button_cb), dialog); | |
809 | |
810 /* Stop button */ | |
811 button = gtk_button_new_from_stock(GTK_STOCK_STOP); | |
812 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
813 gtk_widget_show(button); | |
814 gtk_widget_set_sensitive(button, FALSE); | |
815 dialog->stop_button = button; | |
816 | |
817 g_signal_connect(G_OBJECT(button), "clicked", | |
818 G_CALLBACK(stop_button_cb), dialog); | |
819 | |
820 /* Close button */ | |
821 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); | |
822 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
823 gtk_widget_show(button); | |
824 dialog->close_button = button; | |
825 | |
826 g_signal_connect(G_OBJECT(button), "clicked", | |
827 G_CALLBACK(close_button_cb), dialog); | |
828 | |
829 return dialog; | |
830 } | |
831 | |
832 void | |
833 gaim_gtkxfer_dialog_destroy(GaimGtkXferDialog *dialog) | |
834 { | |
835 g_return_if_fail(dialog != NULL); | |
836 | |
837 gaim_notify_close_with_handle(dialog); | |
838 | |
839 gtk_widget_destroy(dialog->window); | |
840 | |
841 g_free(dialog); | |
842 } | |
843 | |
844 void | |
845 gaim_gtkxfer_dialog_show(GaimGtkXferDialog *dialog) | |
846 { | |
847 g_return_if_fail(dialog != NULL); | |
848 | |
849 gtk_widget_show(dialog->window); | |
850 } | |
851 | |
852 void | |
853 gaim_gtkxfer_dialog_hide(GaimGtkXferDialog *dialog) | |
854 { | |
855 g_return_if_fail(dialog != NULL); | |
856 | |
857 gaim_notify_close_with_handle(dialog); | |
858 | |
859 gtk_widget_hide(dialog->window); | |
860 } | |
861 | |
862 void | |
863 gaim_show_xfer_dialog() | |
864 { | |
865 GaimGtkXferDialog *dialog; | |
866 | |
867 dialog = gaim_get_gtkxfer_dialog(); | |
868 | |
869 if (dialog == NULL) { | |
870 dialog = gaim_gtkxfer_dialog_new(); | |
871 | |
872 gaim_set_gtkxfer_dialog(dialog); | |
873 } | |
874 | |
875 gaim_gtkxfer_dialog_show(dialog); | |
876 } | |
877 | |
878 void | |
879 gaim_gtkxfer_dialog_add_xfer(GaimGtkXferDialog *dialog, GaimXfer *xfer) | |
880 { | |
881 GaimGtkXferUiData *data; | |
882 GaimXferType type; | |
883 GdkPixbuf *pixbuf; | |
884 char *size_str, *remaining_str; | |
885 char *lfilename, *utf8; | |
886 | |
887 g_return_if_fail(dialog != NULL); | |
888 g_return_if_fail(xfer != NULL); | |
889 | |
890 gaim_xfer_ref(xfer); | |
891 | |
892 data = GAIM_GTKXFER(xfer); | |
893 data->in_list = TRUE; | |
894 | |
895 gaim_gtkxfer_dialog_show(dialog); | |
896 | |
897 data->last_updated_time = 0; | |
898 | |
899 type = gaim_xfer_get_type(xfer); | |
900 | |
901 size_str = gaim_str_size_to_units(gaim_xfer_get_size(xfer)); | |
902 remaining_str = gaim_str_size_to_units(gaim_xfer_get_bytes_remaining(xfer)); | |
903 | |
904 pixbuf = gtk_widget_render_icon(dialog->window, | |
905 (type == GAIM_XFER_RECEIVE | |
906 ? GAIM_STOCK_DOWNLOAD | |
907 : GAIM_STOCK_UPLOAD), | |
908 GTK_ICON_SIZE_MENU, NULL); | |
909 | |
910 gtk_list_store_append(dialog->model, &data->iter); | |
911 lfilename = g_path_get_basename(gaim_xfer_get_local_filename(xfer)); | |
912 utf8 = g_filename_to_utf8(lfilename, -1, NULL, NULL, NULL); | |
913 g_free(lfilename); | |
914 lfilename = utf8; | |
915 gtk_list_store_set(dialog->model, &data->iter, | |
916 COLUMN_STATUS, pixbuf, | |
917 COLUMN_PROGRESS, 0.0, | |
918 COLUMN_FILENAME, (type == GAIM_XFER_RECEIVE) | |
919 ? gaim_xfer_get_filename(xfer) | |
920 : lfilename, | |
921 COLUMN_SIZE, size_str, | |
922 COLUMN_REMAINING, _("Waiting for transfer to begin"), | |
923 COLUMN_DATA, xfer, | |
924 -1); | |
925 g_free(lfilename); | |
926 | |
927 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(dialog->tree)); | |
928 | |
929 g_object_unref(pixbuf); | |
930 | |
931 g_free(size_str); | |
932 g_free(remaining_str); | |
933 | |
934 dialog->num_transfers++; | |
935 | |
936 ensure_row_selected(dialog); | |
937 } | |
938 | |
939 void | |
940 gaim_gtkxfer_dialog_remove_xfer(GaimGtkXferDialog *dialog, | |
941 GaimXfer *xfer) | |
942 { | |
943 GaimGtkXferUiData *data; | |
944 | |
945 g_return_if_fail(dialog != NULL); | |
946 g_return_if_fail(xfer != NULL); | |
947 | |
948 data = GAIM_GTKXFER(xfer); | |
949 | |
950 if (data == NULL) | |
951 return; | |
952 | |
953 if (!data->in_list) | |
954 return; | |
955 | |
956 data->in_list = FALSE; | |
957 | |
958 gtk_list_store_remove(GTK_LIST_STORE(dialog->model), &data->iter); | |
959 | |
960 dialog->num_transfers--; | |
961 | |
962 if (dialog->num_transfers == 0 && !dialog->keep_open) | |
963 gaim_gtkxfer_dialog_hide(dialog); | |
964 else | |
965 ensure_row_selected(dialog); | |
966 | |
967 gaim_xfer_unref(xfer); | |
968 } | |
969 | |
970 void | |
971 gaim_gtkxfer_dialog_cancel_xfer(GaimGtkXferDialog *dialog, | |
972 GaimXfer *xfer) | |
973 { | |
974 GaimGtkXferUiData *data; | |
975 GdkPixbuf *pixbuf; | |
976 const gchar *status; | |
977 | |
978 g_return_if_fail(dialog != NULL); | |
979 g_return_if_fail(xfer != NULL); | |
980 | |
981 data = GAIM_GTKXFER(xfer); | |
982 | |
983 if (data == NULL) | |
984 return; | |
985 | |
986 if (!data->in_list) | |
987 return; | |
988 | |
989 if ((gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) && (dialog->auto_clear)) { | |
990 gaim_gtkxfer_dialog_remove_xfer(dialog, xfer); | |
991 return; | |
992 } | |
993 | |
994 data = GAIM_GTKXFER(xfer); | |
995 | |
996 update_detailed_info(dialog, xfer); | |
997 | |
998 pixbuf = gtk_widget_render_icon(dialog->window, | |
999 GAIM_STOCK_FILE_CANCELED, | |
1000 GTK_ICON_SIZE_MENU, NULL); | |
1001 | |
1002 if (gaim_xfer_is_canceled(xfer)) | |
1003 status = _("Canceled"); | |
1004 else | |
1005 status = _("Failed"); | |
1006 | |
1007 gtk_list_store_set(dialog->model, &data->iter, | |
1008 COLUMN_STATUS, pixbuf, | |
1009 COLUMN_REMAINING, status, | |
1010 -1); | |
1011 | |
1012 g_object_unref(pixbuf); | |
1013 | |
1014 update_buttons(dialog, xfer); | |
1015 } | |
1016 | |
1017 void | |
1018 gaim_gtkxfer_dialog_update_xfer(GaimGtkXferDialog *dialog, | |
1019 GaimXfer *xfer) | |
1020 { | |
1021 GaimGtkXferUiData *data; | |
1022 char *size_str, *remaining_str; | |
1023 GtkTreeSelection *selection; | |
1024 time_t current_time; | |
1025 | |
1026 g_return_if_fail(dialog != NULL); | |
1027 g_return_if_fail(xfer != NULL); | |
1028 | |
1029 if ((data = GAIM_GTKXFER(xfer)) == NULL) | |
1030 return; | |
1031 | |
1032 if (data->in_list == FALSE) | |
1033 return; | |
1034 | |
1035 current_time = time(NULL); | |
1036 if (((current_time - data->last_updated_time) == 0) && | |
1037 (!gaim_xfer_is_completed(xfer))) | |
1038 { | |
1039 /* Don't update the window more than once per second */ | |
1040 return; | |
1041 } | |
1042 data->last_updated_time = current_time; | |
1043 | |
1044 size_str = gaim_str_size_to_units(gaim_xfer_get_size(xfer)); | |
1045 remaining_str = gaim_str_size_to_units(gaim_xfer_get_bytes_remaining(xfer)); | |
1046 | |
1047 gtk_list_store_set(xfer_dialog->model, &data->iter, | |
1048 COLUMN_PROGRESS, gaim_xfer_get_progress(xfer), | |
1049 COLUMN_SIZE, size_str, | |
1050 COLUMN_REMAINING, remaining_str, | |
1051 -1); | |
1052 | |
1053 if (gaim_xfer_is_completed(xfer)) | |
1054 { | |
1055 GdkPixbuf *pixbuf; | |
1056 | |
1057 pixbuf = gtk_widget_render_icon(dialog->window, | |
1058 GAIM_STOCK_FILE_DONE, | |
1059 GTK_ICON_SIZE_MENU, NULL); | |
1060 | |
1061 gtk_list_store_set(GTK_LIST_STORE(xfer_dialog->model), &data->iter, | |
1062 COLUMN_STATUS, pixbuf, | |
1063 COLUMN_REMAINING, _("Finished"), | |
1064 -1); | |
1065 | |
1066 g_object_unref(pixbuf); | |
1067 } | |
1068 | |
1069 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(xfer_dialog->tree)); | |
1070 | |
1071 if (xfer == dialog->selected_xfer) | |
1072 update_detailed_info(xfer_dialog, xfer); | |
1073 | |
1074 if (gaim_xfer_is_completed(xfer) && dialog->auto_clear) | |
1075 gaim_gtkxfer_dialog_remove_xfer(dialog, xfer); | |
1076 else | |
1077 update_buttons(dialog, xfer); | |
1078 } | |
1079 | |
1080 /************************************************************************** | |
1081 * File Transfer UI Ops | |
1082 **************************************************************************/ | |
1083 static void | |
1084 gaim_gtkxfer_new_xfer(GaimXfer *xfer) | |
1085 { | |
1086 GaimGtkXferUiData *data; | |
1087 | |
1088 /* This is where we're setting xfer->ui_data for the first time. */ | |
1089 data = g_new0(GaimGtkXferUiData, 1); | |
1090 xfer->ui_data = data; | |
1091 } | |
1092 | |
1093 static void | |
1094 gaim_gtkxfer_destroy(GaimXfer *xfer) | |
1095 { | |
1096 GaimGtkXferUiData *data; | |
1097 | |
1098 data = GAIM_GTKXFER(xfer); | |
1099 if (data) { | |
1100 g_free(data->name); | |
1101 g_free(data); | |
1102 xfer->ui_data = NULL; | |
1103 } | |
1104 } | |
1105 | |
1106 static void | |
1107 gaim_gtkxfer_add_xfer(GaimXfer *xfer) | |
1108 { | |
1109 if (xfer_dialog == NULL) | |
1110 xfer_dialog = gaim_gtkxfer_dialog_new(); | |
1111 | |
1112 gaim_gtkxfer_dialog_add_xfer(xfer_dialog, xfer); | |
1113 } | |
1114 | |
1115 static void | |
1116 gaim_gtkxfer_update_progress(GaimXfer *xfer, double percent) | |
1117 { | |
1118 gaim_gtkxfer_dialog_update_xfer(xfer_dialog, xfer); | |
1119 } | |
1120 | |
1121 static void | |
1122 gaim_gtkxfer_cancel_local(GaimXfer *xfer) | |
1123 { | |
1124 if (xfer_dialog) | |
1125 gaim_gtkxfer_dialog_cancel_xfer(xfer_dialog, xfer); | |
1126 } | |
1127 | |
1128 static void | |
1129 gaim_gtkxfer_cancel_remote(GaimXfer *xfer) | |
1130 { | |
1131 if (xfer_dialog) | |
1132 gaim_gtkxfer_dialog_cancel_xfer(xfer_dialog, xfer); | |
1133 } | |
1134 | |
1135 static GaimXferUiOps ops = | |
1136 { | |
1137 gaim_gtkxfer_new_xfer, | |
1138 gaim_gtkxfer_destroy, | |
1139 gaim_gtkxfer_add_xfer, | |
1140 gaim_gtkxfer_update_progress, | |
1141 gaim_gtkxfer_cancel_local, | |
1142 gaim_gtkxfer_cancel_remote | |
1143 }; | |
1144 | |
1145 /************************************************************************** | |
1146 * GTK+ File Transfer API | |
1147 **************************************************************************/ | |
1148 void | |
1149 gaim_gtk_xfers_init(void) | |
1150 { | |
1151 gaim_prefs_add_none("/gaim/gtk/filetransfer"); | |
1152 gaim_prefs_add_bool("/gaim/gtk/filetransfer/clear_finished", TRUE); | |
1153 gaim_prefs_add_bool("/gaim/gtk/filetransfer/keep_open", FALSE); | |
1154 } | |
1155 | |
1156 void | |
1157 gaim_gtk_xfers_uninit(void) | |
1158 { | |
1159 if (xfer_dialog != NULL) | |
1160 gaim_gtkxfer_dialog_destroy(xfer_dialog); | |
1161 } | |
1162 | |
1163 void | |
1164 gaim_set_gtkxfer_dialog(GaimGtkXferDialog *dialog) | |
1165 { | |
1166 xfer_dialog = dialog; | |
1167 } | |
1168 | |
1169 GaimGtkXferDialog * | |
1170 gaim_get_gtkxfer_dialog(void) | |
1171 { | |
1172 return xfer_dialog; | |
1173 } | |
1174 | |
1175 GaimXferUiOps * | |
1176 gaim_gtk_xfers_get_ui_ops(void) | |
1177 { | |
1178 return &ops; | |
1179 } |