[project @ 2006-02-07 16:16:23 by adrianl]

Confirmation before overwriting with download files; Interface Choices dialog

svn path=/import/netsurf/; revision=2061
This commit is contained in:
Adrian Lees 2006-02-07 16:16:23 +00:00
parent 6be0b8e60c
commit 57c86c8c0e
15 changed files with 287 additions and 37 deletions

View File

@ -400,7 +400,7 @@ PrintErrorRO2:Der Drucker scheint beschäftigt zu sein.
AbortDownload:Soll das Herunterladen der Datei wirklich abgebrochen werden ?
QuitDownload:Das Herunterladen ein oder mehrerer Dateien wurde noch nicht abgeschlossen. Soll NetSurf trotzdem beendet werden ?
OverwriteFile:A file with that name already exists and would be lost.
# Page fetching
# =============
@ -500,6 +500,10 @@ kBytes: kB
MBytes: MB
GBytes: GB
Yes:Ja
No:Nein
Replace:Replace file
DontReplace:Don't replace
# Interactive help
# ================

Binary file not shown.

View File

@ -399,7 +399,7 @@ AWNotSeen:Please locate the AWViewer application and try again.
AbortDownload:Are you sure you wish to abort this download?
QuitDownload:One or more downloads are still in progress. Are you sure you wish to quit?
OverwriteFile:A file with that name already exists and would be lost.
# Page fetching
# =============
@ -499,6 +499,10 @@ kBytes: kB
MBytes: MB
GBytes: GB
Yes:Yes
No:No
Replace:Replace file
DontReplace:Don't replace
# Interactive help
# ================

Binary file not shown.

View File

@ -400,7 +400,7 @@ PrintErrorRO2:Il semble que l'imprimante soit occupée.
AbortDownload:Étes-vous sûr de vouloir interrompre ce téléchargement ?
QuitDownload:Un ou plusieurs téléchargements sont en cours. Êtes-vous sûr de vouloir quitter ?
OverwriteFile:A file with that name already exists and would be lost.
# Page fetching
# =============
@ -500,6 +500,10 @@ kBytes: KO
MBytes: MO
GBytes: GO
Yes:Oui
No:Non
Replace:Replace file
DontReplace:Don't replace
# Interactive help
# ================

Binary file not shown.

View File

@ -401,6 +401,7 @@ PrintErrorRO2:It appears that the printer is busy.
AbortDownload:Zeker weten dat u deze download af wilt breken?
QuitDownload:Een of meer downloads zijn nog bezig. Toch afbreken?
OverwriteFile:A file with that name already exists and would be lost.
# Page fetching
@ -501,6 +502,10 @@ kBytes: kB
MBytes: MB
GBytes: GB
Yes:Ja
No:Nee
Replace:Replace file
DontReplace:Don't replace
# Interactive help
# ================

Binary file not shown.

View File

@ -83,6 +83,9 @@ void ro_gui_configure_initialise(void) {
ro_gui_configure_register("con_language",
ro_gui_options_language_initialise,
ro_gui_wimp_event_finalise);
ro_gui_configure_register("con_inter",
ro_gui_options_interface_initialise,
ro_gui_wimp_event_finalise);
}
void ro_gui_configure_show(void) {

View File

@ -0,0 +1,64 @@
/*
* This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license
* Copyright 2006 Adrian Lees <adrianl@users.sourceforge.net>
*/
#include "netsurf/riscos/dialog.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/options.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/riscos/wimp_event.h"
#include "netsurf/riscos/configure.h"
#include "netsurf/riscos/configure/configure.h"
#define INTERFACE_OK_BUTTON 0
#define INTERFACE_CANCEL_BUTTON 1
#define INTERFACE_DEFAULT_BUTTON 2
#define INTERFACE_STRIP_EXTNS_OPTION 4
#define INTERFACE_CONFIRM_OVWR_OPTION 5
static void ro_gui_options_interface_default(wimp_pointer *pointer);
static bool ro_gui_options_interface_ok(wimp_w w);
bool ro_gui_options_interface_initialise(wimp_w w) {
/* set the current values */
ro_gui_set_icon_selected_state(w, INTERFACE_STRIP_EXTNS_OPTION,
option_strip_extensions);
ro_gui_set_icon_selected_state(w, INTERFACE_CONFIRM_OVWR_OPTION,
option_confirm_overwrite);
/* initialise all functions for a newly created window */
ro_gui_wimp_event_register_button(w, INTERFACE_DEFAULT_BUTTON,
ro_gui_options_interface_default);
ro_gui_wimp_event_register_cancel(w, INTERFACE_CANCEL_BUTTON);
ro_gui_wimp_event_register_ok(w, INTERFACE_OK_BUTTON,
ro_gui_options_interface_ok);
ro_gui_wimp_event_set_help_prefix(w, "HelpInterfaceConfig");
ro_gui_wimp_event_memorise(w);
return true;
}
void ro_gui_options_interface_default(wimp_pointer *pointer) {
ro_gui_set_icon_selected_state(pointer->w,
INTERFACE_STRIP_EXTNS_OPTION, true);
ro_gui_set_icon_selected_state(pointer->w,
INTERFACE_CONFIRM_OVWR_OPTION, true);
}
bool ro_gui_options_interface_ok(wimp_w w) {
option_strip_extensions = ro_gui_get_icon_selected_state(w,
INTERFACE_STRIP_EXTNS_OPTION);
option_confirm_overwrite = ro_gui_get_icon_selected_state(w,
INTERFACE_CONFIRM_OVWR_OPTION);
ro_gui_save_options();
return true;
}

View File

@ -20,6 +20,7 @@ bool ro_gui_options_fonts_initialise(wimp_w w);
bool ro_gui_options_home_initialise(wimp_w w);
bool ro_gui_options_image_initialise(wimp_w w);
void ro_gui_options_image_finalise(wimp_w w);
bool ro_gui_options_interface_initialise(wimp_w w);
bool ro_gui_options_language_initialise(wimp_w w);
bool ro_gui_options_memory_initialise(wimp_w w);
bool ro_gui_options_theme_initialise(wimp_w w);

View File

@ -43,6 +43,14 @@
#include "netsurf/utils/utils.h"
typedef enum
{
QueryRsn_Quit,
QueryRsn_Abort,
QueryRsn_Overwrite
} query_reason;
/** Data for a download window. */
struct gui_download_window {
/** Associated fetch, or 0 if the fetch has completed or aborted. */
@ -62,12 +70,13 @@ struct gui_download_window {
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;
query_reason query_rsn;
struct timeval start_time; /**< Time download started. */
struct timeval last_time; /**< Time status was last updated. */
@ -97,6 +106,7 @@ static int download_progress_y0;
static int download_progress_y1;
static const char *ro_gui_download_temp_name(struct gui_download_window *dw);
static void ro_gui_download_update_status(struct gui_download_window *dw);
static void ro_gui_download_update_status_wrapper(void *p);
@ -106,11 +116,14 @@ static bool ro_gui_download_check_space(struct gui_download_window *dw,
const char *dest_file, const char *orig_file);
static os_error *ro_gui_download_move(struct gui_download_window *dw,
const char *dest_file, const char *src_file);
static bool ro_gui_download_save(struct gui_download_window *dw, const char *file_name);
static bool ro_gui_download_save(struct gui_download_window *dw,
const char *file_name, bool force_overwrite);
static void ro_gui_download_send_dataload(struct gui_download_window *dw);
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 void ro_gui_download_overwrite_confirmed(query_id, enum query_response res, void *p);
static void ro_gui_download_overwrite_cancelled(query_id, enum query_response res, void *p);
static const query_callback close_funcs =
{
@ -119,6 +132,13 @@ static const query_callback close_funcs =
ro_gui_download_close_cancelled
};
static const query_callback overwrite_funcs =
{
ro_gui_download_overwrite_confirmed,
ro_gui_download_overwrite_cancelled,
ro_gui_download_overwrite_cancelled
};
/**
* Load the download window template.
@ -736,23 +756,24 @@ bool ro_gui_download_window_keypress(struct gui_download_window *dw, wimp_key *k
return true;
case wimp_KEY_RETURN: {
char *name = ro_gui_get_icon_string(dw->window, ICON_DOWNLOAD_PATH);
if (!strrchr(name, '.'))
{
warn_user("NoPathError", NULL);
return true;
}
ro_gui_convert_save_path(dw->path, sizeof dw->path, name);
dw->send_dataload = false;
if (ro_gui_download_save(dw, dw->path) && !dw->fetch)
{
/* finished already */
schedule(200, ro_gui_download_window_destroy_wrapper, dw);
}
char *name = ro_gui_get_icon_string(dw->window, ICON_DOWNLOAD_PATH);
if (!strrchr(name, '.'))
{
warn_user("NoPathError", NULL);
return true;
}
break;
ro_gui_convert_save_path(dw->path, sizeof dw->path, name);
dw->send_dataload = false;
if (ro_gui_download_save(dw, dw->path,
!option_confirm_overwrite) && !dw->fetch)
{
/* finished already */
schedule(200, ro_gui_download_window_destroy_wrapper, dw);
}
return true;
}
break;
}
/* ignore all other keypresses (F12 etc) */
@ -830,11 +851,11 @@ void ro_gui_download_datasave_ack(wimp_message *message)
dw->send_dataload = true;
memcpy(&dw->save_message, message, sizeof(wimp_message));
if (!ro_gui_download_save(dw, message->data.data_xfer.file_name))
if (!ro_gui_download_save(dw, message->data.data_xfer.file_name,
!option_confirm_overwrite))
return;
if (!dw->fetch)
{
if (!dw->fetch) {
/* Ack successful completed save with message_DATA_LOAD immediately
to reduce the chance of the target app getting confused by it
being delayed */
@ -1076,13 +1097,16 @@ os_error *ro_gui_download_move(struct gui_download_window *dw,
/**
* Start of save operation, user has specified where the file should be saved.
*
* \param dw download window
* \param file_name pathname of destination file
* \param dw download window
* \param file_name pathname of destination file
& \param force_overwrite true iff required to overwrite without prompting
* \return true iff save successfully initiated
*/
bool ro_gui_download_save(struct gui_download_window *dw, const char *file_name)
bool ro_gui_download_save(struct gui_download_window *dw,
const char *file_name, bool force_overwrite)
{
fileswitch_object_type obj_type;
const char *temp_name;
os_error *error;
@ -1091,6 +1115,34 @@ bool ro_gui_download_save(struct gui_download_window *dw, const char *file_name)
temp_name = ro_gui_download_temp_name(dw);
/* does the user want to check for collisions when saving? */
if (true && !force_overwrite) {
/* check whether the destination file/dir already exists */
error = xosfile_read_stamped(file_name, &obj_type,
NULL, NULL, NULL, NULL, NULL);
if (error) {
LOG(("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess));
return false;
}
switch (obj_type) {
case osfile_NOT_FOUND:
break;
case osfile_IS_FILE:
dw->query = query_user("OverwriteFile", NULL, &overwrite_funcs, dw,
messages_get("Replace"), messages_get("DontReplace"));
dw->query_rsn = QueryRsn_Overwrite;
return false;
default:
error = xosfile_make_error(file_name, obj_type);
assert(error);
warn_user("SaveError", error->errmess);
return false;
}
}
if (!ro_gui_download_check_space(dw, file_name, temp_name)) {
warn_user("SaveError", messages_get("NoDiscSpace"));
return false;
@ -1222,17 +1274,34 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit)
if (!safe && !dw->close_confirmed)
{
if (dw->query != QUERY_INVALID && dw->query_quit != quit) {
query_reason rsn = quit ? QueryRsn_Quit : QueryRsn_Abort;
if (dw->query != QUERY_INVALID) {
/* can we just reuse the existing query? */
if (rsn == dw->query_rsn) {
ro_gui_query_window_bring_to_front(dw->query);
return false;
}
query_close(dw->query);
dw->query = QUERY_INVALID;
}
dw->query_quit = quit;
if (dw->query == QUERY_INVALID)
dw->query = query_user(quit ? "QuitDownload" : "AbortDownload",
NULL, &close_funcs, dw);
else
ro_gui_query_window_bring_to_front(dw->query);
if (quit) {
/* bring all download windows to the front of the desktop as
a convenience if there are lots of windows open */
struct gui_download_window *d = download_window_list;
while (d) {
ro_gui_open_window_at_front(d->window);
d = d->next;
}
}
dw->query_rsn = rsn;
dw->query = query_user(quit ? "QuitDownload" : "AbortDownload",
NULL, &close_funcs, dw, NULL, NULL);
return false;
}
@ -1319,10 +1388,10 @@ void ro_gui_download_close_cancelled(query_id id, enum query_response res, void
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;
struct gui_download_window *dw = p;
dw->query = QUERY_INVALID;
dw->close_confirmed = true;
if (dw->query_quit) {
if (dw->query_rsn == QueryRsn_Quit) {
/* destroy all our downloads */
while (download_window_list)
@ -1337,6 +1406,41 @@ void ro_gui_download_close_confirmed(query_id id, enum query_response res, void
}
/**
* User has opted not to overwrite the existing file.
*/
void ro_gui_download_overwrite_cancelled(query_id id, enum query_response res, void *p)
{
struct gui_download_window *dw = p;
dw->query = QUERY_INVALID;
}
/**
* Overwrite of existing file confirmed, proceed with the save.
*/
void ro_gui_download_overwrite_confirmed(query_id id, enum query_response res, void *p)
{
struct gui_download_window *dw = p;
dw->query = QUERY_INVALID;
if (!ro_gui_download_save(dw, dw->save_message.data.data_xfer.file_name, true))
return;
if (!dw->fetch) {
/* Ack successful completed save with message_DATA_LOAD immediately
to reduce the chance of the target app getting confused by it
being delayed */
ro_gui_download_send_dataload(dw);
schedule(200, ro_gui_download_window_destroy_wrapper, dw);
}
}
/**
* Respond to PreQuit message, displaying a prompt message if we need
* the user to confirm the shutdown.

View File

@ -57,6 +57,7 @@ extern bool option_url_suggestion;
extern int option_image_memory_direct; /* -1 means auto-detect */
extern int option_image_memory_compressed; /* -1 means auto-detect */
extern bool option_strip_extensions;
extern bool option_confirm_overwrite;
extern char *option_url_path;
extern char *option_url_save;
extern char *option_hotlist_path;
@ -107,6 +108,7 @@ bool option_url_suggestion = true; \
int option_image_memory_direct = -1; \
int option_image_memory_compressed = -1; \
bool option_strip_extensions = true; \
bool option_confirm_overwrite = true; \
char *option_url_path = 0; \
char *option_url_save = 0; \
char *option_hotlist_path = 0; \
@ -157,6 +159,7 @@ char *option_theme_save = 0;
{ "image_memory_direct", OPTION_INTEGER, &option_image_memory_direct }, \
{ "image_memory_compressed",OPTION_INTEGER, &option_image_memory_compressed }, \
{ "strip_extensions", OPTION_BOOL, &option_strip_extensions }, \
{ "confirm_overwrite", OPTION_BOOL, &option_confirm_overwrite }, \
{ "url_path", OPTION_STRING, &option_url_path }, \
{ "url_save", OPTION_STRING, &option_url_save }, \
{ "hotlist_path", OPTION_STRING, &option_hotlist_path }, \

View File

@ -6,6 +6,7 @@
*/
#include <stdlib.h>
#include <string.h>
#include "netsurf/riscos/dialog.h"
#include "netsurf/riscos/query.h"
@ -40,6 +41,10 @@ static struct gui_query_window *gui_query_window_list = 0;
/** Template for a query window. */
static struct wimp_window *query_template;
/** Widths of Yes and No buttons */
static int query_yes_width = 0;
static int query_no_width = 0;
static void ro_gui_query_window_destroy(struct gui_query_window *qw);
static struct gui_query_window *ro_gui_query_window_lookup_id(query_id id);
@ -89,14 +94,22 @@ struct gui_query_window *ro_gui_query_window_lookup_id(query_id id)
* \param detail parameter used in expanding tokenised message
* \param cb table of callback functions to be called when user responds
* \param pw handle to be passed to callback functions
* \param yes text to use for 'Yes' button' (or NULL for default)
* \param no text to use for 'No' button (or NULL for default)
* \return id number of the query (or QUERY_INVALID if it failed)
*/
query_id query_user(const char *query, const char *detail, const query_callback *cb, void *pw)
query_id query_user(const char *query, const char *detail,
const query_callback *cb, void *pw,
const char *yes, const char *no)
{
struct gui_query_window *qw;
char query_buffer[300];
os_error *error;
wimp_icon *icn;
int width;
int len;
int x;
qw = malloc(sizeof(struct gui_query_window));
if (!qw) {
@ -112,9 +125,53 @@ query_id query_user(const char *query, const char *detail, const query_callback
if (next_id == QUERY_INVALID)
next_id++;
if (!yes) yes = messages_get("Yes");
if (!no) no = messages_get("No");
/* set the text of the 'No' button and size accordingly */
icn = &query_template->icons[ICON_QUERY_NO];
len = strnlen(no, icn->data.indirected_text.size - 1);
memcpy(icn->data.indirected_text.text, no, len);
icn->data.indirected_text.text[len] = '\0';
error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width);
if (error) {
LOG(("xwimptextop_string_width: 0x%x:%s",
error->errnum, error->errmess));
width = len * 16;
}
if (!query_no_width) query_no_width = icn->extent.x1 - icn->extent.x0;
if (width < query_no_width)
width = query_no_width;
else
width += 44;
icn->extent.x0 = x = icn->extent.x1 - width;
/* set the text of the 'Yes' button and size accordingly */
icn = &query_template->icons[ICON_QUERY_YES];
len = strnlen(yes, icn->data.indirected_text.size - 1);
memcpy(icn->data.indirected_text.text, yes, len);
icn->data.indirected_text.text[len] = '\0';
if (!query_yes_width) query_yes_width = icn->extent.x1 - icn->extent.x0;
icn->extent.x1 = x - 16;
error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width);
if (error) {
LOG(("xwimptextop_string_width: 0x%x:%s",
error->errnum, error->errmess));
width = len * 16;
}
if (width < query_yes_width)
width = query_yes_width;
else
width += 28;
icn->extent.x0 = icn->extent.x1 - width;
error = xwimp_create_window(query_template, &qw->window);
if (error) {
warn_user("WimpError", error->errmess);
free(qw);
return QUERY_INVALID;
}
snprintf(query_buffer, sizeof query_buffer, "%s %s",

View File

@ -61,7 +61,8 @@ const char *rfc1123_date(time_t t);
/* 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);
query_id query_user(const char *query, const char *detail,
const query_callback *cb, void *pw, const char *yes, const char *no);
void query_close(query_id);
#endif