1
0
mirror of https://github.com/netsurf-browser/netsurf synced 2025-01-12 13:59:20 +03:00

[project @ 2004-06-27 23:24:11 by bursa]

Rewritten download window. Now downloads direct to file. New download window gui.

svn path=/import/netsurf/; revision=1020
This commit is contained in:
James Bursa 2004-06-27 23:24:11 +00:00
parent 79a10e41a4
commit a1d73ecd11
12 changed files with 737 additions and 233 deletions

View File

@ -65,7 +65,10 @@ HelpAbout:About NetSurf
Themes:Themes
# Download window
Downloaded:Download complete, %s
Download:%s of %s <20> %s/s <20> %s remaining
DownloadU:%s of unknown <20> %s/s <20> %s total
Downloaded:%s complete <20> average %s/s <20> %s total
Unwritten:Writing data to file failed.
# Forms
Form_Submit:Submit

Binary file not shown.

View File

@ -65,7 +65,10 @@ HelpAbout:
Themes:Thèmes
# Download window
Downloaded:Téléchargement terminé, %s
Download:%s of %s <20> %s/s <20> %s remaining
DownloadU:%s of unknown <20> %s/s <20> %s total
Downloaded:%s complete <20> average %s/s <20> %s total
Unwritten:Writing data to file failed.
# Forms
Form_Submit:Soumettre

Binary file not shown.

View File

@ -824,6 +824,21 @@ bool fetch_can_fetch(const char *url)
}
/**
* Change the callback function for a fetch.
*/
void fetch_change_callback(struct fetch *fetch,
void (*callback)(fetch_msg msg, void *p, const char *data,
unsigned long size),
void *p)
{
assert(fetch);
fetch->callback = callback;
fetch->p = p;
}
/**
* testing framework
*/

View File

@ -53,5 +53,9 @@ void fetch_quit(void);
const char *fetch_filetype(const char *unix_path);
char *fetch_mimetype(const char *ro_path);
bool fetch_can_fetch(const char *url);
void fetch_change_callback(struct fetch *fetch,
void (*callback)(fetch_msg msg, void *p, const char *data,
unsigned long size),
void *p);
#endif

View File

@ -39,8 +39,7 @@
static void browser_window_callback(content_msg msg, struct content *c,
void *p1, void *p2, union content_msg_data data);
static void browser_window_convert_to_download(struct browser_window *bw,
content_msg msg);
static void browser_window_convert_to_download(struct browser_window *bw);
static void browser_window_start_throbber(struct browser_window *bw);
static void browser_window_stop_throbber(struct browser_window *bw);
static void browser_window_update(struct browser_window *bw,
@ -48,8 +47,8 @@ static void browser_window_update(struct browser_window *bw,
static void browser_window_set_status(struct browser_window *bw,
const char *text);
static void browser_window_set_pointer(gui_pointer_shape shape);
static void download_window_callback(content_msg msg, struct content *c,
void *p1, void *p2, union content_msg_data data);
static void download_window_callback(fetch_msg msg, void *p, const char *data,
unsigned long size);
static void browser_window_text_selection(struct browser_window* bw,
unsigned long click_x, unsigned long click_y, int click_type);
@ -194,13 +193,12 @@ void browser_window_callback(content_msg msg, struct content *c,
struct browser_window *bw = p1;
char status[40];
if (c->type == CONTENT_OTHER) {
browser_window_convert_to_download(bw, msg);
return;
}
switch (msg) {
case CONTENT_MSG_LOADING:
assert(bw->loading_content == c);
if (c->type == CONTENT_OTHER)
browser_window_convert_to_download(bw);
break;
case CONTENT_MSG_READY:
@ -294,21 +292,32 @@ void browser_window_callback(content_msg msg, struct content *c,
* Transfer the loading_content to a new download window.
*/
void browser_window_convert_to_download(struct browser_window *bw,
content_msg msg)
void browser_window_convert_to_download(struct browser_window *bw)
{
gui_window *download_window;
struct gui_download_window *download_window;
struct content *c = bw->loading_content;
union content_msg_data data;
struct fetch *fetch;
assert(c);
/* create download window and add content to it */
download_window = gui_create_download_window(c);
content_add_user(c, download_window_callback, download_window, 0);
fetch = c->fetch;
if (msg == CONTENT_MSG_DONE)
download_window_callback(CONTENT_MSG_DONE, c, download_window,
0, data);
if (fetch) {
/* create download window */
download_window = gui_download_window_create(c->url,
c->mime_type, fetch, c->total_size);
if (download_window) {
/* extract fetch from content */
c->fetch = 0;
c->fresh = false;
fetch_change_callback(fetch, download_window_callback,
download_window);
}
} else {
/* must already be a download window for this fetch */
/** \todo open it at top of stack */
}
/* remove content from browser window */
bw->loading_content = 0;
@ -466,50 +475,38 @@ void browser_window_destroy(struct browser_window *bw)
/**
* Callback for fetchcache() for download window fetches.
* Callback for fetch for download window fetches.
*/
void download_window_callback(content_msg msg, struct content *c,
void *p1, void *p2, union content_msg_data data)
void download_window_callback(fetch_msg msg, void *p, const char *data,
unsigned long size)
{
gui_window *download_window = p1;
struct gui_download_window *download_window = p;
switch (msg) {
case CONTENT_MSG_STATUS:
gui_download_window_update_status(download_window);
case FETCH_DATA:
gui_download_window_data(download_window, data, size);
break;
case CONTENT_MSG_DONE:
case FETCH_FINISHED:
gui_download_window_done(download_window);
break;
case CONTENT_MSG_ERROR:
gui_download_window_error(download_window, data.error);
case FETCH_ERROR:
gui_download_window_error(download_window, data);
break;
case CONTENT_MSG_READY:
break;
case CONTENT_MSG_LOADING:
case CONTENT_MSG_REDIRECT:
/* not possible at this point, handled in
browser_window_callback() */
case FETCH_TYPE:
case FETCH_REDIRECT:
case FETCH_AUTH:
default:
/* not possible */
assert(0);
break;
case CONTENT_MSG_REFORMAT:
break;
case CONTENT_MSG_REDRAW:
break;
#ifdef WITH_AUTH
case CONTENT_MSG_AUTH:
break;
#endif
}
}
}
void clear_radio_gadgets(struct browser_window *bw, struct box *box,
struct form_control *group)
{

View File

@ -14,6 +14,7 @@
#define _NETSURF_DESKTOP_GUI_H_
struct gui_window;
struct gui_download_window;
typedef struct gui_window gui_window;
typedef enum { GUI_POINTER_DEFAULT, GUI_POINTER_POINT, GUI_POINTER_CARET,
GUI_POINTER_MENU, GUI_POINTER_UD, GUI_POINTER_LR,
@ -26,7 +27,6 @@ typedef enum { GUI_POINTER_DEFAULT, GUI_POINTER_POINT, GUI_POINTER_CARET,
gui_window *gui_create_browser_window(struct browser_window *bw,
struct browser_window *clone);
gui_window *gui_create_download_window(struct content *content);
void gui_window_destroy(gui_window* g);
void gui_window_redraw(gui_window* g, unsigned long x0, unsigned long y0,
unsigned long x1, unsigned long y1);
@ -40,9 +40,14 @@ void gui_window_set_pointer(gui_pointer_shape shape);
void gui_window_set_title(gui_window* g, char* title);
void gui_window_set_url(gui_window *g, char *url);
void gui_download_window_update_status(gui_window *g);
void gui_download_window_done(gui_window *g);
void gui_download_window_error(gui_window *g, const char *error);
struct gui_download_window *gui_download_window_create(const char *url,
const char *mime_type, struct fetch *fetch,
unsigned int total_size);
void gui_download_window_data(struct gui_download_window *dw, const char *data,
unsigned int size);
void gui_download_window_error(struct gui_download_window *dw,
const char *error_msg);
void gui_download_window_done(struct gui_download_window *dw);
void gui_init(int argc, char** argv);
void gui_window_clone_options(struct browser_window *new_bw, struct browser_window *old_bw);

View File

@ -6,10 +6,26 @@
* Copyright 2003 Rob Jackson <jacko@xms.ms>
*/
/** \file
* Download windows (RISC OS implementation).
*
* This file implements the interface given by desktop/gui.h for download
* windows. Each download window has an associated fetch. Downloads start by
* writing received data to a temporary file. At some point the user chooses
* a destination (by drag & drop), and the temporary file is then moved to the
* destination and the download continues until complete.
*/
#include <assert.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "oslib/mimemap.h"
#include "oslib/osargs.h"
#include "oslib/osfile.h"
#include "oslib/osfind.h"
#include "oslib/osfscontrol.h"
#include "oslib/osgbpb.h"
#include "oslib/wimp.h"
#include "oslib/wimpspriteop.h"
#include "netsurf/content/fetch.h"
@ -21,8 +37,57 @@
#include "netsurf/utils/utils.h"
/** Data for a download window. */
struct gui_download_window {
/** Associated fetch, or 0 if the fetch has completed or aborted. */
struct fetch *fetch;
unsigned int received; /**< Amount of data received so far. */
unsigned int total_size; /**< Size of resource, or 0 if unknown. */
wimp_w window; /**< RISC OS window handle. */
bits file_type; /**< RISC OS file type. */
char url[256]; /**< Buffer for URL icon. */
char sprite_name[20]; /**< Buffer for sprite icon. */
char path[256]; /**< Buffer for pathname icon. */
char status[256]; /**< Buffer for status icon. */
/** User has chosen the destination, and it is being written. */
bool saved;
bool error; /**< Error occurred, aborted. */
/** RISC OS file handle, of temporary file when !saved, and of
* destination when saved. */
os_fw file;
struct timeval start_time; /**< Time download started. */
struct timeval last_time; /**< Time status was last updated. */
unsigned int last_received; /**< Value of received at last_time. */
struct gui_download_window *prev; /**< Previous in linked list. */
struct gui_download_window *next; /**< Next in linked list. */
};
/** List of all download windows. */
static struct gui_download_window *download_window_list = 0;
/** Download window with current save operation. */
static struct gui_download_window *download_window_current = 0;
/** Template for a download window. */
static wimp_window *download_template;
/** Width of progress bar at 100%. */
static int download_progress_width;
/** Coordinates of progress bar. */
static int download_progress_x0;
static int download_progress_y0;
static int download_progress_y1;
static void ro_gui_download_update_status(struct gui_download_window *dw);
static void ro_gui_download_update_status_wrapper(void *p);
static void ro_gui_download_window_destroy_wrapper(void *p);
/**
* Load the download window template.
@ -31,164 +96,427 @@ static wimp_window *download_template;
void ro_gui_download_init(void)
{
download_template = ro_gui_dialog_load_template("download");
download_progress_width =
download_template->icons[ICON_DOWNLOAD_STATUS].extent.x1 -
download_template->icons[ICON_DOWNLOAD_STATUS].extent.x0;
download_progress_x0 =
download_template->icons[ICON_DOWNLOAD_PROGRESS].extent.x0;
download_progress_y0 =
download_template->icons[ICON_DOWNLOAD_PROGRESS].extent.y0;
download_progress_y1 =
download_template->icons[ICON_DOWNLOAD_PROGRESS].extent.y1;
}
/**
* Create and open a download progress window.
*
* \param url URL of download
* \param mime_type MIME type sent by server
* \param fetch fetch structure
* \param total_size size of resource, or 0 if unknown
* \return a new gui_download_window structure, or 0 on error and error
* reported
*/
gui_window *gui_create_download_window(struct content *content)
struct gui_download_window *gui_download_window_create(const char *url,
const char *mime_type, struct fetch *fetch,
unsigned int total_size)
{
char *nice;
gui_window *g = xcalloc(1, sizeof(gui_window));
os_error *e;
char temp_name[40];
struct gui_download_window *dw;
os_error *error;
assert(content->type == CONTENT_OTHER);
dw = malloc(sizeof *dw);
if (!dw) {
warn_user("NoMemory", 0);
return 0;
}
g->type = GUI_DOWNLOAD_WINDOW;
g->data.download.content = content;
dw->fetch = fetch;
dw->saved = false;
dw->error = false;
dw->received = 0;
dw->total_size = total_size;
strncpy(dw->url, url, sizeof dw->url);
dw->url[sizeof dw->url - 1] = 0;
dw->status[0] = 0;
gettimeofday(&dw->start_time, 0);
dw->last_time = dw->start_time;
dw->last_received = 0;
/* convert MIME type to RISC OS file type */
e = xmimemaptranslate_mime_type_to_filetype(content->mime_type,
&(g->data.download.file_type));
if (e)
g->data.download.file_type = 0xffd;
error = xmimemaptranslate_mime_type_to_filetype(mime_type,
&(dw->file_type));
if (error) {
LOG(("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s",
error->errnum, error->errmess));
warn_user("MiscError", error->errmess);
dw->file_type = 0xffd;
}
/* open temporary output file */
snprintf(temp_name, sizeof temp_name, "<Wimp$ScrapDir>.ns%x",
(unsigned int) dw);
error = xosfind_openoutw(osfind_NO_PATH | osfind_ERROR_IF_DIR,
temp_name, 0, &dw->file);
if (error) {
LOG(("xosfind_openoutw: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
free(dw);
return 0;
}
/* fill in download window icons */
download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.text =
content->url;
dw->url;
download_template->icons[ICON_DOWNLOAD_URL].data.indirected_text.size =
strlen(content->url) + 1;
strncpy(g->status, content->status_message, 256);
download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text.text =
g->status;
download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text.size =
256;
sprintf(g->data.download.sprite_name, "file_%.3x",
g->data.download.file_type);
e = xwimpspriteop_select_sprite(g->data.download.sprite_name, 0);
if (e)
strcpy(g->data.download.sprite_name, "file_xxx");
sizeof dw->url;
download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text.
text = dw->status;
download_template->icons[ICON_DOWNLOAD_STATUS].data.indirected_text.
size = sizeof dw->status;
sprintf(dw->sprite_name, "file_%.3x", dw->file_type);
error = xwimpspriteop_select_sprite(dw->sprite_name, 0);
if (error) {
if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) {
LOG(("xwimpspriteop_select_sprite: 0x%x: %s",
error->errnum, error->errmess));
warn_user("MiscError", error->errmess);
}
strcpy(dw->sprite_name, "file_xxx");
}
download_template->icons[ICON_DOWNLOAD_ICON].data.indirected_sprite.id =
(osspriteop_id) g->data.download.sprite_name;
strcpy(g->data.download.path, messages_get("SaveObject"));
if ((nice = url_nice(content->url))) {
strcpy(g->data.download.path, nice);
(osspriteop_id) dw->sprite_name;
strcpy(dw->path, messages_get("SaveObject"));
if ((nice = url_nice(url))) {
strcpy(dw->path, nice);
free(nice);
}
download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.text =
g->data.download.path;
dw->path;
download_template->icons[ICON_DOWNLOAD_PATH].data.indirected_text.size =
256;
sizeof dw->path;
download_template->icons[ICON_DOWNLOAD_DESTINATION].data.
indirected_text.text = dw->path;
download_template->icons[ICON_DOWNLOAD_DESTINATION].data.
indirected_text.size = sizeof dw->path;
download_template->icons[ICON_DOWNLOAD_DESTINATION].flags |=
wimp_ICON_DELETED;
/* create and open the download window */
g->window = wimp_create_window(download_template);
ro_gui_dialog_open(g->window);
error = xwimp_create_window(download_template, &dw->window);
if (error) {
LOG(("xwimp_create_window: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
free(dw);
return 0;
}
g->data.download.download_status = download_INCOMPLETE;
dw->prev = 0;
dw->next = download_window_list;
download_window_list = dw;
g->next = window_list;
window_list = g;
return g;
ro_gui_download_update_status(dw);
ro_gui_dialog_open(dw->window);
return dw;
}
/**
* Refresh the status icon in the download window.
* Handle received download data.
*
* \param dw download window
* \param data pointer to block of data received
* \param size size of data
*/
void gui_download_window_update_status(gui_window *g)
void gui_download_window_data(struct gui_download_window *dw, const char *data,
unsigned int size)
{
strncpy(g->status, g->data.download.content->status_message, 256);
wimp_set_icon_state(g->window,
ICON_DOWNLOAD_STATUS, 0, 0);
int unwritten;
os_error *error;
error = xosgbpb_writew(dw->file, data, size, &unwritten);
if (error) {
LOG(("xosgbpb_writew: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
fetch_abort(dw->fetch);
gui_download_window_error(dw, error->errmess);
return;
}
if (unwritten) {
LOG(("xosgbpb_writew: unwritten %i", unwritten));
warn_user("SaveError", messages_get("Unwritten"));
fetch_abort(dw->fetch);
gui_download_window_error(dw, messages_get("Unwritten"));
return;
}
dw->received += size;
}
/**
* Update the status text and progress bar.
*
* \param dw download window
*/
void ro_gui_download_update_status(struct gui_download_window *dw)
{
char *received;
char *total_size;
char *speed;
char time[20] = "?";
float f = 0;
struct timeval t;
float dt;
unsigned int left;
float rate;
os_error *error;
gettimeofday(&t, 0);
dt = (t.tv_sec + 0.000001 * t.tv_usec) - (dw->last_time.tv_sec +
0.000001 * dw->last_time.tv_usec);
if (dt == 0)
dt = 0.001;
total_size = human_friendly_bytesize(dw->total_size);
if (dw->fetch) {
rate = (dw->received - dw->last_received) / dt;
received = human_friendly_bytesize(dw->received);
speed = human_friendly_bytesize(rate);
if (dw->total_size) {
if (rate) {
left = (dw->total_size - dw->received) / rate;
sprintf(time, "%u:%.2u", left / 60, left % 60);
}
snprintf(dw->status, sizeof dw->status,
messages_get("Download"),
received, total_size, speed, time);
} else {
left = t.tv_sec - dw->start_time.tv_sec;
sprintf(time, "%u:%.2u", left / 60, left % 60);
snprintf(dw->status, sizeof dw->status,
messages_get("DownloadU"),
received, speed, time);
}
} else {
left = dw->last_time.tv_sec - dw->start_time.tv_sec;
rate = (float) dw->received / (float) left;
sprintf(time, "%u:%.2u", left / 60, left % 60);
speed = human_friendly_bytesize(rate);
snprintf(dw->status, sizeof dw->status,
messages_get("Downloaded"),
total_size, speed, time);
}
dw->last_time = t;
dw->last_received = dw->received;
if (dw->total_size)
f = (float) dw->received /
(float) dw->total_size;
error = xwimp_resize_icon(dw->window, ICON_DOWNLOAD_PROGRESS,
download_progress_x0,
download_progress_y0,
download_progress_x0 + download_progress_width * f,
download_progress_y1);
if (error) {
LOG(("xwimp_resize_icon: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_STATUS, 0, 0);
if (error) {
LOG(("xwimp_set_icon_state: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
if (dw->fetch)
schedule(100, ro_gui_download_update_status_wrapper, dw);
else
schedule_remove(ro_gui_download_update_status_wrapper, dw);
}
/**
* Wrapper for ro_gui_download_update_status(), suitable for schedule().
*/
void ro_gui_download_update_status_wrapper(void *p)
{
ro_gui_download_update_status((struct gui_download_window *) p);
}
/**
* Handle failed downloads.
*
* \param dw download window
* \param error_msg error message
*/
void gui_download_window_error(gui_window *g, const char *error)
void gui_download_window_error(struct gui_download_window *dw,
const char *error_msg)
{
g->data.download.content = 0;
os_error *error;
dw->fetch = 0;
dw->error = true;
schedule_remove(ro_gui_download_update_status_wrapper, dw);
/* place error message in status icon in red */
strncpy(g->status, error, 256);
wimp_set_icon_state(g->window,
strncpy(dw->status, error_msg, sizeof dw->status);
error = xwimp_set_icon_state(dw->window,
ICON_DOWNLOAD_STATUS,
wimp_COLOUR_RED << wimp_ICON_FG_COLOUR_SHIFT,
wimp_ICON_FG_COLOUR);
if (error) {
LOG(("xwimp_set_icon_state: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
/* grey out file and pathname icons */
wimp_set_icon_state(g->window,
ICON_DOWNLOAD_ICON, wimp_ICON_SHADED, 0);
wimp_set_icon_state(g->window,
ICON_DOWNLOAD_PATH, wimp_ICON_SHADED, 0);
g->data.download.download_status = download_ERROR;
/* grey out pathname icon */
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH,
wimp_ICON_SHADED, 0);
if (error) {
LOG(("xwimp_set_icon_state: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
}
/**
* Handle completed downloads.
*
* \param dw download window
*/
void gui_download_window_done(gui_window *g)
void gui_download_window_done(struct gui_download_window *dw)
{
snprintf(g->status, 256, messages_get("Downloaded"),
human_friendly_bytesize(g->data.download.content->source_size));
wimp_set_icon_state(g->window,
ICON_DOWNLOAD_STATUS, 0, 0);
os_error *error;
// clear shaded path and icon icons
wimp_set_icon_state(g->window,
ICON_DOWNLOAD_ICON, 0, wimp_ICON_SHADED);
wimp_set_icon_state(g->window,
ICON_DOWNLOAD_PATH, 0, wimp_ICON_SHADED);
dw->fetch = 0;
ro_gui_download_update_status(dw);
g->data.download.download_status = download_COMPLETE;
error = xosfind_closew(dw->file);
if (error) {
LOG(("xosfind_closew: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
}
dw->file = 0;
if (dw->saved) {
error = xosfile_set_type(dw->path,
dw->file_type);
if (error) {
LOG(("xosfile_set_type: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
}
schedule(200, ro_gui_download_window_destroy_wrapper, dw);
}
}
/**
* Handle clicks in a download window.
* Convert a RISC OS window handle to a gui_download_window.
*
* \param w RISC OS window handle
* \return pointer to a structure if found, 0 otherwise
*/
void ro_download_window_click(struct gui_window *g, wimp_pointer *pointer)
struct gui_download_window * ro_gui_download_window_lookup(wimp_w w)
{
switch (pointer->i) {
case ICON_DOWNLOAD_ABORT:
if (g->data.download.download_status ==
download_INCOMPLETE)
fetch_abort(g->data.download.content->fetch);
struct gui_download_window *dw;
for (dw = download_window_list; dw; dw = dw->next)
if (dw->window == w)
return dw;
return 0;
}
ro_download_window_close(g);
break;
case ICON_DOWNLOAD_ICON:
if (g->data.download.download_status ==
download_COMPLETE) {
gui_current_drag_type = GUI_DRAG_DOWNLOAD_SAVE;
current_gui = g;
ro_gui_drag_icon(pointer);
/**
* Handle Mouse_Click events in a download window.
*
* \param dw download window
* \param pointer block returned by Wimp_Poll
*/
void ro_gui_download_window_click(struct gui_download_window *dw,
wimp_pointer *pointer)
{
char command[256] = "Filer_OpenDir ";
char *dot;
os_error *error;
if (pointer->i == ICON_DOWNLOAD_ICON && !dw->error &&
!dw->saved) {
gui_current_drag_type = GUI_DRAG_DOWNLOAD_SAVE;
download_window_current = dw;
ro_gui_drag_icon(pointer);
} else if (pointer->i == ICON_DOWNLOAD_DESTINATION) {
strncpy(command + 14, dw->path, 242);
command[255] = 0;
dot = strrchr(command, '.');
if (dot) {
*dot = 0;
error = xos_cli(command);
if (error) {
LOG(("xos_cli: 0x%x: %s",
error->errnum, error->errmess));
warn_user("MiscError", error->errmess);
}
break;
}
}
}
/**
* Handle User_Drag_Box event for a drag from a download window.
*
* \param drag block returned by Wimp_Poll
*/
void ro_download_drag_end(wimp_dragged *drag)
void ro_gui_download_drag_end(wimp_dragged *drag)
{
wimp_pointer pointer;
wimp_message message;
struct gui_download_window *dw = download_window_current;
os_error *error;
wimp_get_pointer_info(&pointer);
if (dw->saved || dw->error)
return;
error = xwimp_get_pointer_info(&pointer);
if (error) {
LOG(("xwimp_get_pointer_info: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
return;
}
message.your_ref = 0;
message.action = message_DATA_SAVE;
@ -196,71 +524,230 @@ void ro_download_drag_end(wimp_dragged *drag)
message.data.data_xfer.i = pointer.i;
message.data.data_xfer.pos.x = pointer.pos.x;
message.data.data_xfer.pos.y = pointer.pos.y;
message.data.data_xfer.est_size = (int)
current_gui->data.download.content->source_size;
message.data.data_xfer.file_type = current_gui->data.download.file_type;
strncpy(message.data.data_xfer.file_name,
current_gui->data.download.path, 212);
message.data.data_xfer.est_size = dw->total_size ? dw->total_size :
dw->received;
message.data.data_xfer.file_type = dw->file_type;
strncpy(message.data.data_xfer.file_name, dw->path, 212);
message.size = 44 + ((strlen(message.data.data_xfer.file_name) + 4) &
(~3u));
wimp_send_message_to_window(wimp_USER_MESSAGE, &message,
pointer.w, pointer.i);
error = xwimp_send_message_to_window(wimp_USER_MESSAGE, &message,
pointer.w, pointer.i, 0);
if (error) {
LOG(("xwimp_send_message_to_window: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
}
/**
* Handle Message_DataSaveAck for a drag from a download window.
*
* \param message block returned by Wimp_Poll
*/
void ro_download_datasave_ack(wimp_message *message)
void ro_gui_download_datasave_ack(wimp_message *message)
{
char *data;
char *data_end;
char temp_name[40];
char *file_name;
struct gui_download_window *dw = download_window_current;
os_error *error;
assert(current_gui->data.download.download_status == download_COMPLETE);
data = current_gui->data.download.content->source_data;
data_end = data + current_gui->data.download.content->source_size;
error = xosfile_save_stamped(message->data.data_xfer.file_name,
current_gui->data.download.file_type,
data, data_end);
if (error) {
LOG(("0x%x: %s\n", error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
if (dw->saved || dw->error)
return;
file_name = message->data.data_xfer.file_name;
snprintf(temp_name, sizeof temp_name, "<Wimp$ScrapDir>.ns%x",
(unsigned int) dw);
/* close temporary file */
if (dw->file) {
error = xosfind_closew(dw->file);
dw->file = 0;
if (error) {
LOG(("xosfind_closew: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
if (dw->fetch)
fetch_abort(dw->fetch);
gui_download_window_error(dw, error->errmess);
return;
}
}
/* move or copy temporary file to destination file */
error = xosfscontrol_rename(temp_name, file_name);
if (error && error->errnum == error_BAD_RENAME) {
/* rename failed: copy with delete */
error = xosfscontrol_copy(temp_name, file_name,
osfscontrol_COPY_FORCE |
osfscontrol_COPY_DELETE |
osfscontrol_COPY_LOOK,
0, 0, 0, 0, 0);
if (error) {
LOG(("xosfscontrol_copy: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
if (dw->fetch)
fetch_abort(dw->fetch);
gui_download_window_error(dw, error->errmess);
return;
}
} else if (error) {
LOG(("xosfscontrol_rename: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
if (dw->fetch)
fetch_abort(dw->fetch);
gui_download_window_error(dw, error->errmess);
return;
}
if (dw->fetch) {
/* open new destination file if still fetching */
error = xosfile_write(file_name, 0xdeaddead, 0xdeaddead,
fileswitch_ATTR_OWNER_READ |
fileswitch_ATTR_OWNER_WRITE);
if (error) {
LOG(("xosfile_write: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
}
error = xosfind_openupw(osfind_NO_PATH | osfind_ERROR_IF_DIR,
file_name, 0, &dw->file);
if (error) {
LOG(("xosfind_openupw: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
if (dw->fetch)
fetch_abort(dw->fetch);
gui_download_window_error(dw, error->errmess);
return;
}
error = xosargs_set_ptrw(dw->file, dw->received);
if (error) {
LOG(("xosargs_set_ptrw: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
if (dw->fetch)
fetch_abort(dw->fetch);
gui_download_window_error(dw, error->errmess);
return;
}
} else {
/* otherwise just set the file type */
error = xosfile_set_type(file_name,
dw->file_type);
if (error) {
LOG(("xosfile_set_type: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
}
}
dw->saved = true;
strncpy(dw->path, file_name, sizeof dw->path);
/* hide writeable path icon and show destination icon */
error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH,
wimp_ICON_DELETED, wimp_ICON_DELETED);
if (error) {
LOG(("xwimp_set_icon_state: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
error = xwimp_set_icon_state(dw->window,
ICON_DOWNLOAD_DESTINATION, 0, wimp_ICON_DELETED);
if (error) {
LOG(("xwimp_set_icon_state: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
/* Ack successful save with message_DATA_LOAD */
message->action = message_DATA_LOAD;
message->your_ref = message->my_ref;
wimp_send_message_to_window(wimp_USER_MESSAGE, message, message->data.data_xfer.w, message->data.data_xfer.i);
error = xwimp_send_message_to_window(wimp_USER_MESSAGE, message,
message->data.data_xfer.w,
message->data.data_xfer.i, 0);
if (error) {
LOG(("xwimp_set_icon_state: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
ro_download_window_close(current_gui);
if (!dw->fetch)
schedule(200, ro_gui_download_window_destroy_wrapper, dw);
}
struct gui_window * ro_lookup_download_window_from_w(wimp_w window)
/**
* Close a download window and free any related resources.
*
* \param dw download window
*/
void ro_gui_download_window_destroy(struct gui_download_window *dw)
{
gui_window* g;
for (g = window_list; g != NULL; g = g->next)
{
if (g->type == GUI_DOWNLOAD_WINDOW)
{
if (g->window == window)
{
return g;
}
}
}
return NULL;
char temp_name[40];
os_error *error;
schedule_remove(ro_gui_download_update_status_wrapper, dw);
/* remove from list */
if (dw->prev)
dw->prev->next = dw->next;
else
download_window_list = dw->next;
if (dw->next)
dw->next->prev = dw->prev;
/* delete window */
error = xwimp_delete_window(dw->window);
if (error) {
LOG(("xwimp_delete_window: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
/* close download file */
if (dw->file) {
error = xosfind_closew(dw->file);
if (error) {
LOG(("xosfind_closew: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
}
}
/* delete temporary file */
if (!dw->saved) {
snprintf(temp_name, sizeof temp_name, "<Wimp$ScrapDir>.ns%x",
(unsigned int) dw);
error = xosfile_delete(temp_name, 0, 0, 0, 0, 0);
if (error) {
LOG(("xosfile_delete: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
}
}
if (dw->fetch)
fetch_abort(dw->fetch);
free(dw);
}
void ro_download_window_close(struct gui_window *g)
/**
* Wrapper for ro_gui_download_window_destroy(), suitable for schedule().
*/
void ro_gui_download_window_destroy_wrapper(void *p)
{
// free contexts etc???
wimp_close_window(g->window);
ro_gui_download_window_destroy((struct gui_download_window *) p);
}

View File

@ -660,17 +660,15 @@ void ro_gui_open_window_request(wimp_open *open)
void ro_gui_close_window_request(wimp_close *close)
{
gui_window *g;
struct gui_download_window *dw;
if (close->w == dialog_debug) {
if (close->w == dialog_debug)
ro_gui_debugwin_close();
return;
}
g = ro_lookup_gui_from_w(close->w);
if (g) {
else if ((g = ro_gui_window_lookup(close->w)))
browser_window_destroy(g->data.browser.bw);
} else
else if ((dw = ro_gui_download_window_lookup(close->w)))
ro_gui_download_window_destroy(dw);
else
ro_gui_dialog_close(close->w);
}
@ -682,6 +680,7 @@ void ro_gui_close_window_request(wimp_close *close)
void ro_gui_mouse_click(wimp_pointer *pointer)
{
gui_window *g = ro_gui_window_lookup(pointer->w);
struct gui_download_window *dw;
if (pointer->w == wimp_ICON_BAR)
ro_gui_icon_bar_click(pointer);
@ -695,8 +694,8 @@ void ro_gui_mouse_click(wimp_pointer *pointer)
else if (g && g->type == GUI_BROWSER_WINDOW &&
g->data.browser.toolbar->status_handle == pointer->w)
ro_gui_status_click(g, pointer);
else if (g && g->type == GUI_DOWNLOAD_WINDOW)
ro_download_window_click(g, pointer);
else if ((dw = ro_gui_download_window_lookup(pointer->w)))
ro_gui_download_window_click(dw, pointer);
else if (pointer->w == dialog_saveas)
ro_gui_save_click(pointer);
else
@ -739,7 +738,7 @@ void ro_gui_drag_end(wimp_dragged *drag)
break;
case GUI_DRAG_DOWNLOAD_SAVE:
ro_download_drag_end(drag);
ro_gui_download_drag_end(drag);
break;
case GUI_DRAG_SAVE:
@ -774,9 +773,6 @@ void ro_gui_keypress(wimp_key *key)
handled = ro_gui_window_keypress(g, key->c,
(bool) (g->data.browser.toolbar->toolbar_handle == key->w));
break;
case GUI_DOWNLOAD_WINDOW:
break;
}
if (!handled)
@ -1140,7 +1136,7 @@ void ro_msg_datasave_ack(wimp_message *message)
{
switch (gui_current_drag_type) {
case GUI_DRAG_DOWNLOAD_SAVE:
ro_download_datasave_ack(message);
ro_gui_download_datasave_ack(message);
break;
case GUI_DRAG_SAVE:

View File

@ -37,7 +37,7 @@ extern gui_window *current_gui;
extern gui_window *ro_gui_current_redraw_gui;
extern osspriteop_area *gui_pointers;
typedef enum { GUI_BROWSER_WINDOW, GUI_DOWNLOAD_WINDOW } gui_window_type;
typedef enum { GUI_BROWSER_WINDOW } gui_window_type;
typedef enum { GUI_SAVE_SOURCE, GUI_SAVE_DRAW, GUI_SAVE_TEXT,
GUI_SAVE_COMPLETE,
GUI_SAVE_OBJECT_ORIG, GUI_SAVE_OBJECT_NATIVE,
@ -48,44 +48,33 @@ typedef enum { GUI_DRAG_SELECTION, GUI_DRAG_DOWNLOAD_SAVE,
GUI_DRAG_SAVE, GUI_DRAG_STATUS_RESIZE } gui_drag_type;
extern gui_drag_type gui_current_drag_type;
struct gui_window
{
gui_window_type type;
struct gui_window {
gui_window_type type;
wimp_w window;
wimp_w window;
union {
struct {
struct toolbar *toolbar;
int toolbar_width;
struct browser_window* bw;
bool reformat_pending;
int old_width;
int old_height;
} browser;
struct {
struct content *content;
bits file_type;
char sprite_name[20];
char path[256];
enum {
download_COMPLETE,
download_INCOMPLETE,
download_ERROR
} download_status;
} download;
} data;
union {
struct {
struct toolbar *toolbar;
int toolbar_width;
struct browser_window* bw;
bool reformat_pending;
int old_width;
int old_height;
} browser;
} data;
char status[256];
char title[256];
char url[256];
gui_window* next;
char status[256];
char title[256];
char url[256];
gui_window *next;
int throbber;
char throb_buf[12];
float throbtime;
int throbber;
char throb_buf[12];
float throbtime;
enum { drag_NONE, drag_UNKNOWN, drag_BROWSER_TEXT_SELECTION } drag_status;
enum { drag_NONE, drag_UNKNOWN, drag_BROWSER_TEXT_SELECTION }
drag_status;
/* Options
*/
@ -132,11 +121,12 @@ void ro_gui_redraw_config_th_pane(wimp_draw *redraw);
/* in download.c */
void ro_gui_download_init(void);
void ro_download_window_close(struct gui_window *g);
struct gui_window * ro_lookup_download_window_from_w(wimp_w window);
void ro_download_window_click(struct gui_window *g, wimp_pointer *pointer);
void ro_download_drag_end(wimp_dragged *drag);
void ro_download_datasave_ack(wimp_message *message);
struct gui_download_window * ro_gui_download_window_lookup(wimp_w w);
void ro_gui_download_window_click(struct gui_download_window *dw,
wimp_pointer *pointer);
void ro_gui_download_drag_end(wimp_dragged *drag);
void ro_gui_download_datasave_ack(wimp_message *message);
void ro_gui_download_window_destroy(struct gui_download_window *dw);
/* in mouseactions.c */
void ro_gui_mouse_action(gui_window* g);
@ -253,11 +243,12 @@ void ro_gui_debugwin_redraw(wimp_draw *redraw);
#define ICON_CONFIG_TH_GET 2
#define ICON_CONFIG_TH_MANAGE 3
#define ICON_DOWNLOAD_URL 0
#define ICON_DOWNLOAD_STATUS 1
#define ICON_DOWNLOAD_ICON 2
#define ICON_DOWNLOAD_PATH 3
#define ICON_DOWNLOAD_ABORT 4
#define ICON_DOWNLOAD_ICON 0
#define ICON_DOWNLOAD_URL 1
#define ICON_DOWNLOAD_PATH 2
#define ICON_DOWNLOAD_DESTINATION 3
#define ICON_DOWNLOAD_PROGRESS 5
#define ICON_DOWNLOAD_STATUS 6
#define ICON_401LOGIN_LOGIN 0
#define ICON_401LOGIN_CANCEL 1

View File

@ -308,7 +308,7 @@ void clean_cookiejar(void) {
/**
* Does a simple conversion which assumes the user speaks English. The buffer
* returned is one of two static ones so may change each time this call is
* returned is one of three static ones so may change each time this call is
* made. Don't store the buffer for later use. It's done this way for
* convenience and to fight possible memory leaks, it is not necessarily pretty.
**/
@ -316,12 +316,15 @@ void clean_cookiejar(void) {
char *human_friendly_bytesize(unsigned long bsize) {
static char buffer1[BYTESIZE_BUFFER_SIZE];
static char buffer2[BYTESIZE_BUFFER_SIZE];
static char *curbuffer = buffer2;
static char buffer3[BYTESIZE_BUFFER_SIZE];
static char *curbuffer = buffer3;
float bytesize = (float)bsize;
if (curbuffer == buffer1)
curbuffer = buffer2;
else if (curbuffer == buffer2)
curbuffer = buffer3;
else
curbuffer = buffer1;