1 #include <webkit2/webkit2.h>
5 gboolean download_handle(WebKitDownload *, gchar *, gpointer);
6 void download_click(GtkToolButton *, gpointer);
7 void download_cancel(GtkMenuItem *, gpointer);
8 gboolean downloadmanager_delete(GtkWidget *, gpointer);
10 struct DownloadManager {
20 WebKitDownload *download;
23 key_downloadmanager(GtkWidget *widget, GdkEvent *event, gpointer data)
25 if (event->type == GDK_KEY_PRESS) {
26 if (((GdkEventKey *)event)->state & GDK_CONTROL_MASK) {
27 int key = ((GdkEventKey *)event)->keyval;
28 if ((GDK_KEY_q == key) || (GDK_KEY_y == key)) {
29 downloadmanager_delete(dm.win, NULL);
38 changed_download_progress(GObject *obj, GParamSpec *pspec, gpointer data)
40 WebKitDownload *download = WEBKIT_DOWNLOAD(obj);
41 WebKitURIResponse *resp;
42 GtkToolItem *tb = GTK_TOOL_ITEM(data);
45 gchar *t, *filename, *base;
46 p = webkit_download_get_estimated_progress(download);
50 resp = webkit_download_get_response(download);
51 size_mb = webkit_uri_response_get_content_length(resp) / 1e6;
53 uri = webkit_download_get_destination(download);
54 filename = g_filename_from_uri(uri, NULL, NULL);
55 base = g_path_get_basename(filename);
56 t = g_strdup_printf("%s (%.0f%% of %.1f MB)", base, p, size_mb);
59 gtk_tool_button_set_label(GTK_TOOL_BUTTON(tb), t);
64 download_finished(WebKitDownload *download, gpointer data)
66 if (strcmp(gtk_tool_button_get_icon_name(GTK_TOOL_BUTTON(data)),
68 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(data),
74 download_start(WebKitWebView *web_view, WebKitDownload *download, gpointer data)
76 g_signal_connect(G_OBJECT(download), "decide-destination",
77 G_CALLBACK(download_handle), data);
80 download_handle(WebKitDownload *download, gchar *suggested_filename,
86 GtkWidget *chooser = gtk_file_chooser_dialog_new(
87 "Choose download location", GTK_WINDOW(dm.win),
88 GTK_FILE_CHOOSER_ACTION_SAVE, "Save file", GTK_RESPONSE_ACCEPT,
89 "Cancel", GTK_RESPONSE_CANCEL, NULL);
90 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser),
92 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(chooser),
94 gtk_file_chooser_set_do_overwrite_confirmation(
95 GTK_FILE_CHOOSER(chooser), TRUE);
96 gint res = gtk_dialog_run(GTK_DIALOG(chooser));
98 case GTK_RESPONSE_ACCEPT:
99 uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(chooser));
100 webkit_download_set_destination(
102 gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(chooser)));
104 case GTK_RESPONSE_CANCEL:
110 gtk_widget_destroy(chooser);
113 tb = gtk_tool_button_new(NULL, NULL);
114 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(tb), "network-receive");
115 gtk_tool_button_set_label(GTK_TOOL_BUTTON(tb), uri);
116 gtk_toolbar_insert(GTK_TOOLBAR(dm.toolbar), tb, 0);
117 gtk_widget_show_all(dm.win);
119 g_signal_connect(G_OBJECT(download), "notify::estimated-progress",
120 G_CALLBACK(changed_download_progress), tb);
123 g_signal_connect(G_OBJECT(download), "finished",
124 G_CALLBACK(download_finished), tb);
126 g_object_ref(download);
128 struct DownloadItem *payload = malloc(sizeof(*payload));
129 payload->tb = (GtkToolButton *)tb;
130 payload->download = download;
131 g_signal_connect(G_OBJECT(tb), "clicked", G_CALLBACK(download_click),
133 g_signal_connect(G_OBJECT(tb), "failed", G_CALLBACK(download_cancel),
135 g_signal_connect(G_OBJECT(tb), "destroy_event", G_CALLBACK(g_free),
138 //Propagate-- to whom it may concern.
143 download_cancel(GtkMenuItem *tb, gpointer data)
145 struct DownloadItem *payload = data;
146 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(payload->tb),
148 webkit_download_cancel(payload->download);
152 download_remove(GtkMenuItem *tb, gpointer data)
154 struct DownloadItem *payload = data;
155 g_object_unref(payload->download);
156 gtk_widget_destroy(GTK_WIDGET(payload->tb));
160 download_copy_url(GtkMenuItem *tb, gpointer data)
162 struct DownloadItem *payload = data;
163 WebKitURIRequest *req = webkit_download_get_request(payload->download);
164 const gchar *uri = webkit_uri_request_get_uri(req);
165 gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), uri,
170 download_copy_path(GtkMenuItem *tb, gpointer data)
172 struct DownloadItem *payload = data;
173 const gchar *path = webkit_download_get_destination(payload->download);
174 gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
175 path + 7, strlen(path) - 7);
176 //Offset by 7 to remove "file://"
180 download_xdg_open(GtkMenuItem *tb, gpointer data)
182 struct DownloadItem *payload = data;
183 const gchar *path = webkit_download_get_destination(payload->download);
184 char *cmd = malloc(strlen(path) + 9);
185 sprintf(cmd, "xdg-open %s", path);
190 download_click(GtkToolButton *tb, gpointer data)
192 GtkWidget *pmenu = gtk_menu_new();
194 if (strcmp(gtk_tool_button_get_icon_name(GTK_TOOL_BUTTON(tb)),
195 "network-receive") == 0) {
196 option = gtk_menu_item_new_with_label("Cancel download");
197 g_signal_connect(G_OBJECT(option), "activate",
198 G_CALLBACK(download_cancel), data);
199 gtk_widget_show(option);
200 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
202 option = gtk_menu_item_new_with_label("Remove download");
203 g_signal_connect(G_OBJECT(option), "activate",
204 G_CALLBACK(download_remove), data);
205 gtk_widget_show(option);
206 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
209 gtk_menu_item_new_with_label("Open file with xdg-open");
210 gtk_widget_show(option);
211 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
212 g_signal_connect(G_OBJECT(option), "activate",
213 G_CALLBACK(download_xdg_open), data);
216 option = gtk_menu_item_new_with_label("Copy download URL");
217 gtk_widget_show(option);
218 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
219 g_signal_connect(G_OBJECT(option), "activate",
220 G_CALLBACK(download_copy_url), data);
222 option = gtk_menu_item_new_with_label("Copy local path");
223 gtk_widget_show(option);
224 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
225 g_signal_connect(G_OBJECT(option), "activate",
226 G_CALLBACK(download_copy_path), data);
228 gtk_menu_popup_at_pointer(GTK_MENU(pmenu), NULL);
231 downloadmanager_delete(GtkWidget *obj, gpointer data)
233 if (!quit_if_nothing_active())
234 gtk_widget_hide(dm.win);
240 downloadmanager_setup(void)
242 dm.win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
243 gtk_window_set_type_hint(GTK_WINDOW(dm.win),
244 GDK_WINDOW_TYPE_HINT_DIALOG);
245 gtk_window_set_default_size(GTK_WINDOW(dm.win), 500, 250);
246 gtk_window_set_title(GTK_WINDOW(dm.win), "chorizo - Download Manager");
247 g_signal_connect(G_OBJECT(dm.win), "delete-event",
248 G_CALLBACK(downloadmanager_delete), NULL);
249 g_signal_connect(G_OBJECT(dm.win), "key-press-event",
250 G_CALLBACK(key_downloadmanager), NULL);
252 dm.toolbar = gtk_toolbar_new();
253 gtk_orientable_set_orientation(GTK_ORIENTABLE(dm.toolbar),
254 GTK_ORIENTATION_VERTICAL);
255 gtk_toolbar_set_style(GTK_TOOLBAR(dm.toolbar), GTK_TOOLBAR_BOTH_HORIZ);
256 gtk_toolbar_set_show_arrow(GTK_TOOLBAR(dm.toolbar), FALSE);
258 dm.scroll = gtk_scrolled_window_new(NULL, NULL);
259 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dm.scroll),
260 GTK_POLICY_AUTOMATIC,
261 GTK_POLICY_AUTOMATIC);
262 gtk_container_add(GTK_CONTAINER(dm.scroll), dm.toolbar);
264 gtk_container_add(GTK_CONTAINER(dm.win), dm.scroll);
268 downloadmanager_show(void)
270 gtk_widget_show_all(dm.win);