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 {
19 key_downloadmanager(GtkWidget *widget, GdkEvent *event, gpointer data)
21 if (event->type == GDK_KEY_PRESS) {
22 if (((GdkEventKey *)event)->state & GDK_CONTROL_MASK) {
23 int key = ((GdkEventKey *)event)->keyval;
24 if ((GDK_KEY_q == key) || (GDK_KEY_y == key)) {
25 downloadmanager_delete(dm.win, NULL);
34 changed_download_progress(GObject *obj, GParamSpec *pspec, gpointer data)
36 WebKitDownload *download = WEBKIT_DOWNLOAD(obj);
37 WebKitURIResponse *resp;
38 GtkToolItem *tb = GTK_TOOL_ITEM(data);
41 gchar *t, *filename, *base;
42 p = webkit_download_get_estimated_progress(download);
46 resp = webkit_download_get_response(download);
47 size_mb = webkit_uri_response_get_content_length(resp) / 1e6;
49 uri = webkit_download_get_destination(download);
50 filename = g_filename_from_uri(uri, NULL, NULL);
51 base = g_path_get_basename(filename);
52 t = g_strdup_printf("%s (%.0f%% of %.1f MB)", base, p, size_mb);
55 gtk_tool_button_set_label(GTK_TOOL_BUTTON(tb), t);
60 download_finished(WebKitDownload *download, gpointer data)
62 if (strcmp(gtk_tool_button_get_icon_name(GTK_TOOL_BUTTON(data)),
64 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(data),
70 download_start(WebKitWebView *web_view, WebKitDownload *download, gpointer data)
72 g_signal_connect(G_OBJECT(download), "decide-destination",
73 G_CALLBACK(download_handle), data);
76 download_handle(WebKitDownload *download, gchar *suggested_filename,
82 GtkWidget *chooser = gtk_file_chooser_dialog_new(
83 "Save File", GTK_WINDOW(dm.win), GTK_FILE_CHOOSER_ACTION_SAVE,
84 "Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT,
86 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser),
88 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(chooser),
90 gtk_file_chooser_set_do_overwrite_confirmation(
91 GTK_FILE_CHOOSER(chooser), TRUE);
92 gint res = gtk_dialog_run(GTK_DIALOG(chooser));
94 if (res != GTK_RESPONSE_ACCEPT) {
95 gtk_widget_destroy(chooser);
97 uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(chooser));
98 webkit_download_set_destination(download, uri);
100 remove(uri + 7); // Remove before overwrite
102 gtk_widget_destroy(chooser);
104 tb = gtk_tool_button_new(NULL, NULL);
105 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(tb),
107 gtk_tool_button_set_label(GTK_TOOL_BUTTON(tb), uri);
108 gtk_toolbar_insert(GTK_TOOLBAR(dm.toolbar), tb, 0);
109 gtk_widget_show_all(dm.win);
111 g_signal_connect(G_OBJECT(download),
112 "notify::estimated-progress",
113 G_CALLBACK(changed_download_progress), tb);
116 g_signal_connect(G_OBJECT(download), "finished",
117 G_CALLBACK(download_finished), tb);
119 g_object_ref(download);
121 struct DownloadItem *payload = malloc(sizeof(*payload));
122 payload->tb = (GtkToolButton *)tb;
123 payload->download = download;
124 g_signal_connect(G_OBJECT(tb), "clicked",
125 G_CALLBACK(download_click), payload);
126 g_signal_connect(G_OBJECT(payload->download), "failed",
127 G_CALLBACK(download_cancel), payload);
128 g_signal_connect(G_OBJECT(tb), "destroy_event",
129 G_CALLBACK(g_free), payload);
135 download_cancel(GtkMenuItem *tb, gpointer data)
137 struct DownloadItem *payload = data;
138 gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(payload->tb),
140 webkit_download_cancel(payload->download);
144 download_get_path(struct DownloadItem *payload)
146 const char *path = webkit_download_get_destination(payload->download);
151 download_hide(GtkMenuItem *tb, gpointer data)
153 struct DownloadItem *payload = data;
154 g_object_unref(payload->download);
155 gtk_widget_destroy(GTK_WIDGET(payload->tb));
159 download_delete(GtkMenuItem *tb, gpointer data)
161 remove(download_get_path((struct DownloadItem *)data));
162 download_hide(tb, data);
166 download_copy_url(GtkMenuItem *tb, gpointer data)
168 struct DownloadItem *payload = data;
169 WebKitURIRequest *req = webkit_download_get_request(payload->download);
170 const gchar *uri = webkit_uri_request_get_uri(req);
171 gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), uri,
176 download_copy_path(GtkMenuItem *tb, gpointer data)
178 const char *path = download_get_path((struct DownloadItem *)data);
179 gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), path,
184 download_xdg_open(GtkMenuItem *tb, gpointer data)
186 struct DownloadItem *payload = data;
187 const gchar *path = webkit_download_get_destination(payload->download);
188 char *cmd = malloc(strlen(path) + 9);
189 sprintf(cmd, "xdg-open %s", path);
194 download_click(GtkToolButton *tb, gpointer data)
196 GtkWidget *pmenu = gtk_menu_new();
198 if (strcmp(gtk_tool_button_get_icon_name(GTK_TOOL_BUTTON(tb)),
199 "network-receive") == 0) {
200 option = gtk_menu_item_new_with_label("Cancel download");
201 g_signal_connect(G_OBJECT(option), "activate",
202 G_CALLBACK(download_cancel), data);
203 gtk_widget_show(option);
204 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
207 gtk_menu_item_new_with_label("Hide download from list");
208 g_signal_connect(G_OBJECT(option), "activate",
209 G_CALLBACK(download_hide), data);
210 gtk_widget_show(option);
211 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
213 option = gtk_menu_item_new_with_label("Delete downloaded file");
214 g_signal_connect(G_OBJECT(option), "activate",
215 G_CALLBACK(download_delete), data);
216 gtk_widget_show(option);
217 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
220 gtk_menu_item_new_with_label("Open file with xdg-open");
221 gtk_widget_show(option);
222 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
223 g_signal_connect(G_OBJECT(option), "activate",
224 G_CALLBACK(download_xdg_open), data);
227 option = gtk_menu_item_new_with_label("Copy download URL");
228 gtk_widget_show(option);
229 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
230 g_signal_connect(G_OBJECT(option), "activate",
231 G_CALLBACK(download_copy_url), data);
233 option = gtk_menu_item_new_with_label("Copy local path");
234 gtk_widget_show(option);
235 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), option);
236 g_signal_connect(G_OBJECT(option), "activate",
237 G_CALLBACK(download_copy_path), data);
239 gtk_menu_popup_at_pointer(GTK_MENU(pmenu), NULL);
242 downloadmanager_delete(GtkWidget *obj, gpointer data)
244 if (!quit_if_nothing_active()) gtk_widget_hide(dm.win);
250 downloadmanager_setup(void)
252 dm.win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
253 gtk_window_set_type_hint(GTK_WINDOW(dm.win),
254 GDK_WINDOW_TYPE_HINT_DIALOG);
255 gtk_window_set_default_size(GTK_WINDOW(dm.win), 500, 250);
256 gtk_window_set_title(GTK_WINDOW(dm.win), "chorizo - Download Manager");
257 g_signal_connect(G_OBJECT(dm.win), "delete-event",
258 G_CALLBACK(downloadmanager_delete), NULL);
259 g_signal_connect(G_OBJECT(dm.win), "key-press-event",
260 G_CALLBACK(key_downloadmanager), NULL);
262 dm.toolbar = gtk_toolbar_new();
263 gtk_orientable_set_orientation(GTK_ORIENTABLE(dm.toolbar),
264 GTK_ORIENTATION_VERTICAL);
265 gtk_toolbar_set_style(GTK_TOOLBAR(dm.toolbar), GTK_TOOLBAR_BOTH_HORIZ);
266 gtk_toolbar_set_show_arrow(GTK_TOOLBAR(dm.toolbar), FALSE);
268 dm.scroll = gtk_scrolled_window_new(NULL, NULL);
269 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dm.scroll),
270 GTK_POLICY_AUTOMATIC,
271 GTK_POLICY_AUTOMATIC);
272 gtk_container_add(GTK_CONTAINER(dm.scroll), dm.toolbar);
274 gtk_container_add(GTK_CONTAINER(dm.win), dm.scroll);
278 downloadmanager_show(void)
280 gtk_widget_show_all(dm.win);