[project @ 2005-04-23 02:58:27 by adrianl]

Query windows, desktop save protocol, confirm abort/quit when downloads in progress

svn path=/import/netsurf/; revision=1679
This commit is contained in:
Adrian Lees 2005-04-23 02:58:27 +00:00
parent 3d067e2fd6
commit 9c1cb7bb2d
7 changed files with 241 additions and 6 deletions

View File

@ -32,7 +32,7 @@ OBJECTS_RISCOS += browser.o netsurf.o selection.o textinput.o version.o # desk
OBJECTS_RISCOS += 401login.o bitmap.o buffer.o debugwin.o \
dialog.o download.o draw.o filetype.o font.o \
global_history.o gui.o help.o history.o hotlist.o image.o \
menus.o mouseactions.o plotters.o plugin.o print.o \
menus.o mouseactions.o plotters.o plugin.o print.o query.o \
save.o save_complete.o save_draw.o save_text.o \
schedule.o search.o sprite.o textselection.o theme.o \
theme_install.o thumbnail.o treeview.o ucstables.o uri.o \

View File

@ -39,7 +39,7 @@
wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br,
dialog_config_prox, dialog_config_th, download_template,
dialog_config_prox, dialog_config_th,
#ifdef WITH_AUTH
dialog_401li,
#endif

View File

@ -31,6 +31,7 @@
#include "netsurf/content/fetch.h"
#include "netsurf/desktop/gui.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/query.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/messages.h"
@ -55,11 +56,15 @@ struct gui_download_window {
/** User has chosen the destination, and it is being written. */
bool saved;
bool close_confirmed;
bool error; /**< Error occurred, aborted. */
/** RISC OS file handle, of temporary file when !saved, and of
* destination when saved. */
os_fw file;
query_id query;
bool query_quit;
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. */
@ -88,6 +93,15 @@ 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);
static void ro_gui_download_close_confirmed(query_id, enum query_response res, void *p);
static void ro_gui_download_close_cancelled(query_id, enum query_response res, void *p);
static const query_callback close_funcs =
{
ro_gui_download_close_confirmed,
ro_gui_download_close_cancelled,
ro_gui_download_close_cancelled
};
/**
@ -138,7 +152,9 @@ struct gui_download_window *gui_download_window_create(const char *url,
dw->fetch = fetch;
dw->saved = false;
dw->close_confirmed = false;
dw->error = false;
dw->query = QUERY_INVALID;
dw->received = 0;
dw->total_size = total_size;
strncpy(dw->url, url, sizeof dw->url);
@ -557,6 +573,7 @@ void ro_gui_download_datasave_ack(wimp_message *message)
char *file_name;
struct gui_download_window *dw = download_window_current;
os_error *error;
wimp_caret caret;
if (dw->saved || dw->error)
return;
@ -675,6 +692,22 @@ void ro_gui_download_datasave_ack(wimp_message *message)
warn_user("WimpError", error->errmess);
}
/* hide the caret but preserve input focus */
error = xwimp_get_caret_position(&caret);
if (error) {
LOG(("xwimp_get_caret_position: 0x%x : %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
else if (caret.w == dw->window) {
error = xwimp_set_caret_position(dw->window, (wimp_i)-1, 0, 0, 1 << 25, -1);
if (error) {
LOG(("xwimp_get_caret_position: 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;
@ -703,6 +736,21 @@ void ro_gui_download_window_destroy(struct gui_download_window *dw)
char temp_name[40];
os_error *error;
if (!dw->saved && !dw->close_confirmed)
{
if (dw->query != QUERY_INVALID && dw->query_quit) {
query_close(dw->query);
dw->query = QUERY_INVALID;
}
dw->query_quit = false;
if (dw->query == QUERY_INVALID)
dw->query = query_user("AbortDownload", NULL, &close_funcs, dw);
else
ro_gui_query_window_bring_to_front(dw->query);
return;
}
schedule_remove(ro_gui_download_update_status_wrapper, dw);
schedule_remove(ro_gui_download_window_destroy_wrapper, dw);
@ -757,5 +805,72 @@ void ro_gui_download_window_destroy(struct gui_download_window *dw)
void ro_gui_download_window_destroy_wrapper(void *p)
{
ro_gui_download_window_destroy((struct gui_download_window *) p);
struct gui_download_window *dw = p;
if (dw->query != QUERY_INVALID)
query_close(dw->query);
dw->query = QUERY_INVALID;
ro_gui_download_window_destroy(dw);
}
/**
* User has opted to cancel the close, leaving the download to continue.
*/
void ro_gui_download_close_cancelled(query_id id, enum query_response res, void *p)
{
struct gui_download_window *dw = p;
dw->query = QUERY_INVALID;
}
/**
* Download aborted, close window and tidy up.
*/
void ro_gui_download_close_confirmed(query_id id, enum query_response res, void *p)
{
struct gui_download_window *dw = (struct gui_download_window *)p;
dw->query = QUERY_INVALID;
dw->close_confirmed = true;
if (dw->query_quit) {
/* destroy all our downloads */
while (download_window_list)
ro_gui_download_window_destroy_wrapper(download_window_list);
/* and restart the shutdown */
if (ro_gui_prequit())
netsurf_quit = true;
}
else
ro_gui_download_window_destroy(dw);
}
/**
* Respond to PreQuit message, displaying a prompt message if we need
* the user to confirm the shutdown.
*
* \return true iff we can shutdown straightaway
*/
bool ro_gui_download_prequit(void)
{
if (download_window_list) {
struct gui_download_window *dw = download_window_list;
if (dw->query != QUERY_INVALID && !dw->query_quit) {
query_close(dw->query);
dw->query = QUERY_INVALID;
}
dw->query_quit = true;
if (dw->query == QUERY_INVALID)
dw->query = query_user("QuitDownload", NULL, &close_funcs, dw);
else
ro_gui_query_window_bring_to_front(dw->query);
return false;
}
return true;
}

View File

@ -27,6 +27,7 @@
#include "oslib/osbyte.h"
#include "oslib/osfile.h"
#include "oslib/osfscontrol.h"
#include "oslib/osgbpb.h"
#include "oslib/osspriteop.h"
#include "oslib/pdriver.h"
#include "oslib/plugin.h"
@ -56,6 +57,7 @@
#ifdef WITH_PRINT
#include "netsurf/riscos/print.h"
#endif
#include "netsurf/riscos/query.h"
#include "netsurf/riscos/save_complete.h"
#include "netsurf/riscos/theme.h"
#include "netsurf/riscos/treeview.h"
@ -135,13 +137,15 @@ static clock_t gui_last_poll; /**< Time of last wimp_poll. */
osspriteop_area *gui_sprites; /**< Sprite area containing pointer and hotlist sprites */
/** Accepted wimp user messages. */
static wimp_MESSAGE_LIST(36) task_messages = { {
static wimp_MESSAGE_LIST(38) task_messages = { {
message_HELP_REQUEST,
message_DATA_SAVE,
message_DATA_SAVE_ACK,
message_DATA_LOAD,
message_DATA_LOAD_ACK,
message_DATA_OPEN,
message_PRE_QUIT,
message_SAVE_DESKTOP,
message_MENU_WARNING,
message_MENUS_DELETED,
message_MODE_CHANGE,
@ -215,6 +219,8 @@ static char *ro_gui_ieurl_file_parse(const char *file_name);
static void ro_msg_datasave(wimp_message *message);
static void ro_msg_datasave_ack(wimp_message *message);
static void ro_msg_dataopen(wimp_message *block);
static void ro_msg_prequit(wimp_message *message);
static void ro_msg_save_desktop(wimp_message *message);
static char *ro_path_to_url(const char *path);
@ -329,6 +335,7 @@ void gui_init(int argc, char** argv)
ro_gui_dialog_init();
ro_gui_download_init();
ro_gui_menu_init();
ro_gui_query_init();
#ifdef WITH_AUTH
ro_gui_401login_init();
#endif
@ -1011,6 +1018,7 @@ void ro_gui_mouse_click(wimp_pointer *pointer)
{
struct gui_window *g;
struct gui_download_window *dw;
struct gui_query_window *qw;
if (pointer->w == wimp_ICON_BAR)
ro_gui_icon_bar_click(pointer);
@ -1046,6 +1054,8 @@ void ro_gui_mouse_click(wimp_pointer *pointer)
ro_gui_status_click(g, pointer);
else if ((dw = ro_gui_download_window_lookup(pointer->w)) != NULL)
ro_gui_download_window_click(dw, pointer);
else if ((qw = ro_gui_query_window_lookup(pointer->w)) != NULL)
ro_gui_query_window_click(qw, pointer);
else
ro_gui_dialog_click(pointer);
}
@ -1136,6 +1146,7 @@ void ro_gui_drag_end(wimp_dragged *drag)
void ro_gui_keypress(wimp_key *key)
{
struct gui_query_window *qw;
bool handled = false;
struct gui_window *g;
os_error *error;
@ -1148,6 +1159,8 @@ void ro_gui_keypress(wimp_key *key)
handled = ro_gui_window_keypress(g, key->c, false);
else if ((g = ro_gui_toolbar_lookup(key->w)) != NULL)
handled = ro_gui_window_keypress(g, key->c, true);
else if ((qw = ro_gui_query_window_lookup(key->w)) != NULL)
handled = ro_gui_query_window_keypress(qw, key);
else
handled = ro_gui_dialog_keypress(key);
@ -1203,6 +1216,14 @@ void ro_gui_user_message(wimp_event_no event, wimp_message *message)
ro_msg_dataopen(message);
break;
case message_PRE_QUIT:
ro_msg_prequit(message);
break;
case message_SAVE_DESKTOP:
ro_msg_save_desktop(message);
break;
case message_MENU_WARNING:
ro_gui_menu_warning((wimp_message_menu_warning *)
&message->data);
@ -1754,6 +1775,64 @@ void ro_msg_dataopen(wimp_message *message)
}
/**
* Handle PreQuit message
*
* \param message PreQuit message from Wimp
*/
void ro_msg_prequit(wimp_message *message)
{
if (!ro_gui_prequit()) {
os_error *error;
/* we're objecting to the close down */
message->your_ref = message->my_ref;
error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE,
message, message->sender);
if (error) {
LOG(("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
}
}
/**
* Handle SaveDesktop message
*
* \param message SaveDesktop message from Wimp
*/
void ro_msg_save_desktop(wimp_message *message)
{
os_error *error;
error = xosgbpb_writew(message->data.save_desktopw.file,
(const byte*)"Run ", 4, NULL);
if (!error) {
error = xosgbpb_writew(message->data.save_desktopw.file,
(const byte*)NETSURF_DIR, strlen(NETSURF_DIR), NULL);
if (!error)
error = xos_bputw('\n', message->data.save_desktopw.file);
}
if (error) {
LOG(("xosgbpb_writew/xos_bputw: 0x%x:%s", error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
/* we must cancel the save by acknowledging the message */
message->your_ref = message->my_ref;
error = xwimp_send_message(wimp_USER_MESSAGE_ACKNOWLEDGE,
message, message->sender);
if (error) {
LOG(("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
}
}
/**
* Convert a RISC OS pathname to a file: URL.
*
@ -1879,7 +1958,7 @@ void gui_launch_url(const char *url)
void warn_user(const char *warning, const char *detail)
{
static char warn_buffer[300];
char warn_buffer[300];
LOG(("%s %s", warning, detail));
snprintf(warn_buffer, sizeof warn_buffer, "%s %s",
@ -1918,3 +1997,15 @@ void die(const char *error)
(osspriteop_area *) 1, 0, 0);
exit(EXIT_FAILURE);
}
/**
* Test whether it's okay to shutdown, prompting the user if not.
*
* \return true iff it's okay to shutdown immediately
*/
bool ro_gui_prequit(void)
{
return ro_gui_download_prequit();
}

View File

@ -97,6 +97,7 @@ void ro_gui_open_help_page(const char *page);
void ro_gui_screen_size(int *width, int *height);
void ro_gui_view_source(struct content *content);
void ro_gui_drag_box_start(wimp_pointer *pointer);
bool ro_gui_prequit(void);
/* in dialog.c */
void ro_gui_dialog_init(void);
@ -126,6 +127,7 @@ void ro_gui_download_window_click(struct gui_download_window *dw,
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);
bool ro_gui_download_prequit(void);
/* in mouseactions.c */
void ro_gui_mouse_action(struct gui_window *g);
@ -379,6 +381,11 @@ void ro_gui_theme_install_click(wimp_pointer *pointer);
#define ICON_WARNING_CONTINUE 1
#define ICON_WARNING_HELP 2
#define ICON_QUERY_MESSAGE 0
#define ICON_QUERY_YES 1
#define ICON_QUERY_NO 2
#define ICON_QUERY_HELP 3
#define ICON_SEARCH_TEXT 0
#define ICON_SEARCH_START 1
#define ICON_SEARCH_CASE_SENSITIVE 2

View File

@ -1547,7 +1547,8 @@ bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
/* misc actions */
case APPLICATION_QUIT:
netsurf_quit = true;
if (ro_gui_prequit())
netsurf_quit = true;
return true;
case CHOICES_SHOW:
ro_gui_dialog_open_config();

View File

@ -29,6 +29,25 @@
#define max(x,y) (((x)>(y))?(x):(y))
#endif
enum query_response {
QUERY_CONTINUE,
QUERY_YES,
QUERY_NO,
QUERY_ESCAPE
};
typedef int query_id;
#define QUERY_INVALID ((query_id)-1)
typedef struct
{
void (*confirm)(query_id id, enum query_response res, void *pw);
void (*cancel)(query_id, enum query_response res, void *pw);
void (*escape)(query_id, enum query_response res, void *pw);
} query_callback;
char * strip(char * const s);
int whitespace(const char * str);
char * squash_whitespace(const char * s);
@ -45,6 +64,8 @@ char *human_friendly_bytesize(unsigned long bytesize);
/* Platform specific functions */
void die(const char * const error);
void warn_user(const char *warning, const char *detail);
query_id query_user(const char *query, const char *detail, const query_callback *cb, void *pw);
void query_close(query_id);
const char *local_encoding_name(void);
#endif