summaryrefslogtreecommitdiff
path: root/frontends/amiga/download.c
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/amiga/download.c')
-rw-r--r--frontends/amiga/download.c451
1 files changed, 451 insertions, 0 deletions
diff --git a/frontends/amiga/download.c b/frontends/amiga/download.c
new file mode 100644
index 000000000..a0bc5c47b
--- /dev/null
+++ b/frontends/amiga/download.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2008-2010 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+#include <proto/wb.h>
+#include <proto/asl.h>
+#include <proto/exec.h>
+#include <proto/dos.h>
+#include <proto/intuition.h>
+#include <proto/utility.h>
+#include <proto/icon.h>
+#ifdef __amigaos4__
+#include <proto/application.h>
+#endif
+
+#include <workbench/icon.h>
+
+#include <proto/window.h>
+#include <proto/layout.h>
+
+#include <proto/fuelgauge.h>
+#include <classes/window.h>
+#include <gadgets/fuelgauge.h>
+#include <gadgets/layout.h>
+
+#include <reaction/reaction_macros.h>
+
+#include "utils/errors.h"
+#include "utils/nsurl.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/utils.h"
+#include "utils/nsoption.h"
+#include "utils/string.h"
+#include "desktop/download.h"
+#include "desktop/save_complete.h"
+#include "desktop/browser.h"
+#include "desktop/mouse.h"
+#include "desktop/gui_window.h"
+#include "desktop/gui_download.h"
+#include "image/ico.h"
+
+#include "amiga/gui.h"
+#include "amiga/download.h"
+#include "amiga/object.h"
+#include "amiga/bitmap.h"
+#include "amiga/icon.h"
+#include "amiga/file.h"
+#include "amiga/drag.h"
+#include "amiga/iff_dr2d.h"
+#include "amiga/libs.h"
+#include "amiga/misc.h"
+#include "amiga/theme.h"
+#include "amiga/utf8.h"
+
+struct gui_download_window {
+ struct nsObject *node;
+ struct Window *win;
+ Object *objects[GID_LAST];
+ BPTR fh;
+ uint32 size;
+ uint32 downloaded;
+ struct dlnode *dln;
+ struct browser_window *bw;
+ struct download_context *ctx;
+ const char *url;
+ char fname[1024];
+ int result;
+};
+
+enum {
+ AMINS_DLOAD_OK = 0,
+ AMINS_DLOAD_ERROR,
+ AMINS_DLOAD_ABORT,
+};
+
+int downloads_in_progress = 0;
+
+static struct gui_download_window *gui_download_window_create(download_context *ctx,
+ struct gui_window *gui)
+{
+ const char *url = nsurl_access(download_context_get_url(ctx));
+ unsigned long total_size = download_context_get_total_length(ctx);
+ struct gui_download_window *dw;
+ char *dl_filename = ami_utf8_easy(download_context_get_filename(ctx));
+ APTR va[3];
+
+ dw = ami_misc_allocvec_clear(sizeof(struct gui_download_window), 0);
+
+ if(gui && (!IsListEmpty(&gui->dllist)) && (dw->dln = (struct dlnode *)FindName(&gui->dllist,url)))
+ {
+ strcpy(dw->fname, dw->dln->filename);
+ free(dw->dln->node.ln_Name);
+ dw->dln->node.ln_Name = NULL;
+ }
+ else
+ {
+ if(AslRequestTags(savereq,
+ ASLFR_Window, gui->shared->win,
+ ASLFR_SleepWindow, TRUE,
+ ASLFR_TitleText, messages_get("NetSurf"),
+ ASLFR_Screen, scrn,
+ ASLFR_InitialFile, dl_filename,
+ TAG_DONE))
+ {
+ strlcpy(dw->fname, savereq->fr_Drawer, 1024);
+ AddPart((STRPTR)&dw->fname,savereq->fr_File,1024);
+ if(!ami_download_check_overwrite(dw->fname, gui->shared->win, total_size))
+ {
+ FreeVec(dw);
+ return NULL;
+ }
+ }
+ else
+ {
+ FreeVec(dw);
+ return NULL;
+ }
+ }
+
+ if(dl_filename) ami_utf8_free(dl_filename);
+ dw->size = total_size;
+ dw->downloaded = 0;
+ if(gui) dw->bw = gui->bw;
+ dw->url = url;
+
+ va[0] = (APTR)dw->downloaded;
+ va[1] = (APTR)dw->size;
+ va[2] = 0;
+
+ if(!(dw->fh = FOpen((STRPTR)&dw->fname,MODE_NEWFILE,0)))
+ {
+ FreeVec(dw);
+ return NULL;
+ }
+
+ dw->objects[OID_MAIN] = WindowObj,
+ WA_ScreenTitle, ami_gui_get_screen_title(),
+ WA_Title, dw->url,
+ WA_Activate, TRUE,
+ WA_DepthGadget, TRUE,
+ WA_DragBar, TRUE,
+ WA_CloseGadget, FALSE,
+ WA_SizeGadget, TRUE,
+ WA_PubScreen,scrn,
+ WINDOW_SharedPort,sport,
+ WINDOW_UserData,dw,
+ WINDOW_IconifyGadget, FALSE,
+ WINDOW_LockHeight,TRUE,
+ WINDOW_Position, WPOS_CENTERSCREEN,
+ WINDOW_ParentGroup, dw->objects[GID_MAIN] = LayoutVObj,
+ LAYOUT_AddChild, dw->objects[GID_STATUS] = FuelGaugeObj,
+ GA_ID,GID_STATUS,
+ GA_Text,messages_get("amiDownload"),
+ FUELGAUGE_Min,0,
+ FUELGAUGE_Max,total_size,
+ FUELGAUGE_Level,0,
+ FUELGAUGE_Ticks,11,
+ FUELGAUGE_ShortTicks,TRUE,
+ FUELGAUGE_VarArgs,va,
+ FUELGAUGE_Percent,FALSE,
+ FUELGAUGE_Justification,FGJ_CENTER,
+ FuelGaugeEnd,
+ CHILD_NominalSize,TRUE,
+ CHILD_WeightedHeight,0,
+ LAYOUT_AddChild, dw->objects[GID_CANCEL] = ButtonObj,
+ GA_ID,GID_CANCEL,
+ GA_RelVerify,TRUE,
+ GA_Text,messages_get("Abort"),
+ GA_TabCycle,TRUE,
+ ButtonEnd,
+ EndGroup,
+ EndWindow;
+
+ dw->win = (struct Window *)RA_OpenWindow(dw->objects[OID_MAIN]);
+ dw->ctx = ctx;
+
+ dw->node = AddObject(window_list,AMINS_DLWINDOW);
+ dw->node->objstruct = dw;
+
+ downloads_in_progress++;
+
+ return dw;
+}
+
+static nserror gui_download_window_data(struct gui_download_window *dw,
+ const char *data, unsigned int size)
+{
+ APTR va[3];
+ if(!dw) return NSERROR_SAVE_FAILED;
+
+ FWrite(dw->fh,data,1,size);
+
+ dw->downloaded = dw->downloaded + size;
+
+ va[0] = (APTR)dw->downloaded;
+ va[1] = (APTR)dw->size;
+ va[2] = 0;
+
+ if(dw->size)
+ {
+ RefreshSetGadgetAttrs((struct Gadget *)dw->objects[GID_STATUS], dw->win, NULL,
+ FUELGAUGE_Level, dw->downloaded,
+ GA_Text, messages_get("amiDownload"),
+ FUELGAUGE_VarArgs, va,
+ TAG_DONE);
+ }
+ else
+ {
+ RefreshSetGadgetAttrs((struct Gadget *)dw->objects[GID_STATUS], dw->win, NULL,
+ FUELGAUGE_Level, dw->downloaded,
+ GA_Text, messages_get("amiDownloadU"),
+ FUELGAUGE_VarArgs, va,
+ TAG_DONE);
+ }
+
+ return NSERROR_OK;
+}
+
+static void gui_download_window_done(struct gui_download_window *dw)
+{
+ struct dlnode *dln,*dln2 = NULL;
+ struct browser_window *bw;
+ bool queuedl = false;
+
+ if(!dw) return;
+ bw = dw->bw;
+
+ if((nsoption_bool(download_notify)) && (dw->result == AMINS_DLOAD_OK))
+ {
+ Notify(ami_gui_get_app_id(), APPNOTIFY_Title, messages_get("amiDownloadComplete"),
+ APPNOTIFY_PubScreenName, "FRONT",
+ APPNOTIFY_BackMsg, dw->fname,
+ APPNOTIFY_CloseOnDC, TRUE,
+ APPNOTIFY_Text, dw->fname,
+ TAG_DONE);
+ }
+
+ download_context_destroy(dw->ctx);
+
+ if((dln = dw->dln))
+ {
+ dln2 = (struct dlnode *)GetSucc((struct Node *)dln);
+ if((dln!=dln2) && (dln2)) queuedl = true;
+
+ free(dln->filename);
+ Remove((struct Node *)dln);
+ FreeVec(dln);
+ }
+
+ FClose(dw->fh);
+ SetComment(dw->fname, dw->url);
+
+ downloads_in_progress--;
+
+ DisposeObject(dw->objects[OID_MAIN]);
+ DelObject(dw->node);
+ if(queuedl) {
+ nsurl *url;
+ if (nsurl_create(dln2->node.ln_Name, &url) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", 0);
+ } else {
+ browser_window_navigate(bw,
+ url,
+ NULL,
+ BW_NAVIGATE_DOWNLOAD,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
+ }
+ }
+ ami_try_quit(); /* In case the only window open was this download */
+}
+
+static void gui_download_window_error(struct gui_download_window *dw,
+ const char *error_msg)
+{
+ amiga_warn_user("Unwritten","");
+ dw->result = AMINS_DLOAD_ERROR;
+ gui_download_window_done(dw);
+}
+
+void ami_download_window_abort(struct gui_download_window *dw)
+{
+ download_context_abort(dw->ctx);
+ dw->result = AMINS_DLOAD_ABORT;
+ gui_download_window_done(dw);
+}
+
+BOOL ami_download_window_event(struct gui_download_window *dw)
+{
+ /* return TRUE if window destroyed */
+ ULONG result;
+ uint16 code;
+
+ while((result = RA_HandleInput(dw->objects[OID_MAIN], &code)) != WMHI_LASTMSG)
+ {
+ switch(result & WMHI_CLASSMASK) // class
+ {
+ case WMHI_GADGETUP:
+ switch(result & WMHI_GADGETMASK)
+ {
+ case GID_CANCEL:
+ ami_download_window_abort(dw);
+ return TRUE;
+ break;
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+void ami_free_download_list(struct List *dllist)
+{
+ struct dlnode *node;
+ struct dlnode *nnode;
+
+ if(!dllist) return;
+ if(IsListEmpty(dllist)) return;
+
+ node = (struct dlnode *)GetHead((struct List *)dllist);
+
+ do
+ {
+ nnode=(struct dlnode *)GetSucc((struct Node *)node);
+ free(node->node.ln_Name);
+ free(node->filename);
+ Remove((struct Node *)node);
+ FreeVec((struct Node *)node);
+ }while((node=nnode));
+}
+
+nserror
+gui_window_save_link(struct gui_window *g, nsurl *url, const char *title)
+{
+ char fname[1024];
+ STRPTR openurlstring,linkname;
+ struct DiskObject *dobj = NULL;
+
+ linkname = ASPrintf("Link_to_%s",FilePart(nsurl_access(url)));
+
+ if(AslRequestTags(savereq,
+ ASLFR_Window, g->shared->win,
+ ASLFR_SleepWindow, TRUE,
+ ASLFR_TitleText,messages_get("NetSurf"),
+ ASLFR_Screen,scrn,
+ ASLFR_InitialFile,linkname,
+ TAG_DONE))
+ {
+ strlcpy(fname, savereq->fr_Drawer, 1024);
+ AddPart(fname,savereq->fr_File,1024);
+
+ ami_set_pointer(g->shared, GUI_POINTER_WAIT, false);
+
+ if(ami_download_check_overwrite(fname, g->shared->win, 0))
+ {
+ BPTR fh;
+
+ if((fh = FOpen(fname,MODE_NEWFILE,0)))
+ {
+ /* \todo Should be URLOpen on OS4.1 */
+ openurlstring = ASPrintf("openurl \"%s\"\n",nsurl_access(url));
+ FWrite(fh,openurlstring,1,strlen(openurlstring));
+ FClose(fh);
+ FreeVec(openurlstring);
+ SetComment(fname, nsurl_access(url));
+
+ dobj = GetIconTags(NULL,ICONGETA_GetDefaultName,"url",
+ ICONGETA_GetDefaultType,WBPROJECT,
+ TAG_DONE);
+
+ dobj->do_DefaultTool = "IconX";
+
+ PutIconTags(fname,dobj,
+ ICONPUTA_NotifyWorkbench,TRUE,
+ TAG_DONE);
+
+ FreeDiskObject(dobj);
+ }
+ FreeVec(linkname);
+ }
+ ami_reset_pointer(g->shared);
+ }
+ return NSERROR_OK;
+}
+
+BOOL ami_download_check_overwrite(const char *file, struct Window *win, ULONG size)
+{
+ /* Return TRUE if file can be (over-)written */
+ int32 res = 0;
+ BPTR lock = 0;
+ char *overwritetext;
+
+ if(nsoption_bool(ask_overwrite) == false) return TRUE;
+
+ lock = Lock(file, ACCESS_READ);
+
+ if(lock)
+ {
+ if(size) {
+ BPTR fh;
+ int64 oldsize = 0;
+
+ if((fh = OpenFromLock(lock))) {
+ oldsize = GetFileSize(fh);
+ Close(fh);
+ }
+ overwritetext = ASPrintf("%s\n\n%s %s\n%s %s",
+ messages_get("OverwriteFile"),
+ messages_get("amiSizeExisting"), human_friendly_bytesize((ULONG)oldsize),
+ messages_get("amiSizeNew"), human_friendly_bytesize(size));
+ } else {
+ UnLock(lock);
+ overwritetext = ASPrintf(messages_get("OverwriteFile"));
+ }
+
+ res = amiga_warn_user_multi(overwritetext, "Replace", "DontReplace", win);
+ FreeVec(overwritetext);
+ }
+ else return TRUE;
+
+ if(res == 1) return TRUE;
+ else return FALSE;
+}
+
+static struct gui_download_table download_table = {
+ .create = gui_download_window_create,
+ .data = gui_download_window_data,
+ .error = gui_download_window_error,
+ .done = gui_download_window_done,
+};
+
+struct gui_download_table *amiga_download_table = &download_table;