On 2011-11-03 16:30, Peter John Hartman wrote:
>
> Second of all, and instead, it just prints to stdout (a) the fact that the
> Download has started, together with the filename, and (b) the fact that it
> has finished/cancelled/errored, together with the filename.

Not much more to add a progress bar to that patch.


Patrick
diff -urN surf-tip/surf.c surf-dl/surf.c
--- surf-tip/surf.c     2011-11-04 22:21:52.077749801 +0800
+++ surf-dl/surf.c      2011-11-04 23:35:55.630343708 +0800
@@ -42,6 +42,15 @@
        gboolean zoomed;
 } Client;
 
+typedef struct Download {
+       WebKitDownload *download;
+       Client *client;
+       gboolean is_done;
+       char *filename;
+       char *filename_partial;
+       struct Download *next;
+} Download;
+
 typedef struct {
        char *label;
        void (*func)(Client *c, const Arg *arg);
@@ -58,6 +67,7 @@
 static Display *dpy;
 static Atom atoms[AtomLast];
 static Client *clients = NULL;
+static Download *downloads = NULL;
 static GdkNativeWindow embed = 0;
 static gboolean showxid = FALSE;
 static char winid[64];
@@ -340,14 +350,82 @@
        soup_cookies_free(l);
 }
 
+int 
+downloadstatus(WebKitDownload *download, GParamSpec *pspec, gpointer 
user_data) {
+       WebKitDownloadStatus status;
+       Download *d;
+
+       for (d = downloads; d != NULL && d->download != download ; d = d->next )
+               ;
+       if (d == NULL)
+               return fprintf(stderr, "lost download?\n"), -1;
+
+       g_object_get(download, "status", &status, NULL);
+
+       switch(status) {
+               case WEBKIT_DOWNLOAD_STATUS_CREATED:
+                       d->client->progress = 0;
+                       update(d->client);
+                       break;
+               case WEBKIT_DOWNLOAD_STATUS_STARTED:
+               case WEBKIT_DOWNLOAD_STATUS_ERROR:
+               case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
+                       break; /* these are irrelevant */
+               case WEBKIT_DOWNLOAD_STATUS_FINISHED: {
+                       unlink(d->filename);
+                       rename(d->filename_partial, d->filename);
+                       g_free(d->filename_partial);
+                       g_free(d->filename);
+                       d->is_done = TRUE;
+                       d->client->progress = 100;
+                       update(d->client);
+               }
+       }
+       return 0;
+}
+
+void
+downloadprogress(WebKitDownload *download, GParamSpec *pspec, gpointer 
user_data) {
+       Download *d;
+       gdouble progress;
+
+       g_object_get(download, "progress", &progress, NULL);
+       for (d = downloads; d != NULL && d->download != download ; d = d->next )
+               ;
+       if (d == NULL)
+               return;
+       if ( (d->client->progress = (int)(progress * 100)) == 0)
+               d->client->progress = 1;
+       update(d->client);
+}
+
 gboolean
 initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) {
-       Arg arg;
+       char *f;
+       Download *d;
 
-       updatewinid(c);
-       arg = (Arg)DOWNLOAD((char *)webkit_download_get_uri(o));
-       spawn(c, &arg);
-       return FALSE;
+       if (!(d = malloc(sizeof(Download))))
+               die("Cannot malloc!\n");
+       d->next = downloads;
+       d->client = c;
+       d->download = o;
+       d->is_done = FALSE;
+       downloads = d;
+       d->client->progress = 1;
+       update(d->client);
+       g_signal_connect(o, "notify::status", G_CALLBACK(downloadstatus), NULL);
+       g_signal_connect(o, "notify::progress", G_CALLBACK(downloadprogress), 
NULL);
+       d->filename = g_strconcat(downloaddir, "/",
+               (char *)webkit_download_get_suggested_filename(o), NULL
+       );
+       d->filename_partial = g_strconcat(d->filename, ".part", NULL);
+       unlink(d->filename_partial);
+
+       f = g_strconcat("file://", d->filename_partial, NULL);
+       webkit_download_set_destination_uri(o, f);
+       webkit_download_start(o);
+       g_free(f);
+       return TRUE;
 }
 
 gboolean

Reply via email to