[project @ 2004-05-03 22:05:40 by bursa]

Implement dragging files into <input type="file" ...>.

svn path=/import/netsurf/; revision=821
This commit is contained in:
James Bursa 2004-05-03 22:05:40 +00:00
parent 24c57d3215
commit 8da6079f6f
10 changed files with 168 additions and 50 deletions

View File

@ -65,6 +65,10 @@ input[type=image] { background-color: #ddd; color: #000; width: auto;
height: auto; }
input[type=checkbox], input[type=radio] { background-color: transparent;
padding: 0 0.1em; border: 0; width: 1em; height: 1em; }
input[type=file] { background-color: #ddd; color: #000;
border-width: medium; border-color: #aaa #eee #eee #aaa;
border-style: inset; width: 10em; height: 1.5em;
font-style: italic; }
[align=left] { text-align: left; }
[align=center] { text-align: center; }

View File

@ -48,6 +48,7 @@ Form_Submit:Submit
Form_Reset:Reset
Form_None:
Form_Many:(Many)
Form_Drop:Drop file here
Not2xx:Server returned an error

View File

@ -39,6 +39,7 @@ Form_Submit:Soumettre
Form_Reset:Effacer
Form_None:
Form_Many:(Plusieurs)
Form_Drop:Drop file here
Not2xx:Le serveur a renvoyé une erreur

View File

@ -663,7 +663,6 @@ int browser_window_gadget_click(struct browser_window* bw, unsigned long click_x
break;
case GADGET_TEXTBOX:
case GADGET_PASSWORD:
case GADGET_FILE:
browser_window_input_click(bw,
(unsigned int)click_boxes[i].actual_x,
(unsigned int)click_boxes[i].actual_y,
@ -682,6 +681,8 @@ int browser_window_gadget_click(struct browser_window* bw, unsigned long click_x
break;
case GADGET_RESET:
break;
case GADGET_FILE:
break;
}
xfree(click_boxes);
@ -1188,8 +1189,7 @@ void browser_window_input_callback(struct browser_window *bw, char key, void *p)
for (next_input = input->gadget->next;
next_input != 0 && next_input->type != GADGET_TEXTBOX &&
next_input->type != GADGET_TEXTAREA &&
next_input->type != GADGET_PASSWORD &&
next_input->type != GADGET_FILE;
next_input->type != GADGET_PASSWORD;
next_input = next_input->next)
;
if (!next_input) return;
@ -1216,8 +1216,7 @@ void browser_window_input_callback(struct browser_window *bw, char key, void *p)
for (prev_input = input->gadget->prev;
prev_input != 0 && prev_input->type != GADGET_TEXTBOX &&
prev_input->type != GADGET_TEXTAREA &&
prev_input->type != GADGET_PASSWORD &&
prev_input->type != GADGET_FILE;
prev_input->type != GADGET_PASSWORD;
prev_input = prev_input->prev)
;
if (!prev_input) return;
@ -1548,8 +1547,7 @@ void browser_window_follow_link(struct browser_window *bw,
if (click_type == 0 && click_boxes[i].box->gadget != NULL) {
if (click_boxes[i].box->gadget->type == GADGET_TEXTBOX ||
click_boxes[i].box->gadget->type == GADGET_TEXTAREA ||
click_boxes[i].box->gadget->type == GADGET_PASSWORD ||
click_boxes[i].box->gadget->type == GADGET_FILE) {
click_boxes[i].box->gadget->type == GADGET_PASSWORD) {
pointer = GUI_POINTER_CARET;
done = 1;
break;

View File

@ -76,7 +76,7 @@ static struct result box_select(xmlNode *n, struct status *status,
static struct result box_input(xmlNode *n, struct status *status,
struct css_style *style);
static struct box *box_input_text(xmlNode *n, struct status *status,
struct css_style *style, bool password, bool file);
struct css_style *style, bool password);
static struct result box_button(xmlNode *n, struct status *status,
struct css_style *style);
static struct result box_frameset(xmlNode *n, struct status *status,
@ -607,8 +607,8 @@ struct css_style * box_get_style(struct content ** stylesheet,
if (0 < size) {
char *type = (char *) xmlGetProp(n, (const xmlChar *) "type");
style->width.width = CSS_WIDTH_LENGTH;
if (!type || stricmp(type, "text") == 0 ||
stricmp(type, "password") == 0)
if (!type || strcasecmp(type, "text") == 0 ||
strcasecmp(type, "password") == 0)
/* in characters for text or password */
style->width.value.length.unit = CSS_UNIT_EX;
else
@ -1050,36 +1050,30 @@ struct result box_input(xmlNode *n, struct status *status,
type = (char *) xmlGetProp(n, (const xmlChar *) "type");
/* the default type is "text" */
if (type == 0 || stricmp(type, "text") == 0)
{
box = box_input_text(n, status, style, false, false);
if (type && strcasecmp(type, "password") == 0) {
box = box_input_text(n, status, style, true);
gadget = box->gadget;
gadget->box = box;
}
else if (stricmp(type, "password") == 0)
{
box = box_input_text(n, status, style, true, false);
gadget = box->gadget;
} else if (type && strcasecmp(type, "file") == 0) {
box = box_create(style, NULL, 0,
status->content->data.html.box_pool);
box->type = BOX_INLINE_BLOCK;
box->gadget = gadget = xcalloc(1, sizeof(struct form_control));
gadget->box = box;
}
else if (stricmp(type, "file") == 0)
{
box = box_input_text(n, status, style, false, true);
gadget = box->gadget;
gadget->box = box;
}
else if (stricmp(type, "hidden") == 0)
{
gadget->type = GADGET_FILE;
box->font = font_open(status->content->data.html.fonts, style);
} else if (type && strcasecmp(type, "hidden") == 0) {
/* no box for hidden inputs */
gadget = xcalloc(1, sizeof(struct form_control));
gadget->type = GADGET_HIDDEN;
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value")))
gadget->value = s;
}
else if (stricmp(type, "checkbox") == 0 || stricmp(type, "radio") == 0)
{
} else if (type && (strcasecmp(type, "checkbox") == 0 ||
strcasecmp(type, "radio") == 0)) {
box = box_create(style, NULL, 0,
status->content->data.html.box_pool);
box->gadget = gadget = xcalloc(1, sizeof(struct form_control));
@ -1099,9 +1093,9 @@ struct result box_input(xmlNode *n, struct status *status,
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "value")))
gadget->value = s;
}
else if (stricmp(type, "submit") == 0 || stricmp(type, "reset") == 0)
{
} else if (type && (strcasecmp(type, "submit") == 0 ||
strcasecmp(type, "reset") == 0)) {
struct result result = box_button(n, status, style);
struct box *inline_container, *inline_box;
box = result.box;
@ -1122,9 +1116,8 @@ struct result box_input(xmlNode *n, struct status *status,
inline_box->font = font_open(status->content->data.html.fonts, style);
box_add_child(inline_container, inline_box);
box_add_child(box, inline_container);
}
else if (stricmp(type, "button") == 0)
{
} else if (type && strcasecmp(type, "button") == 0) {
struct result result = box_button(n, status, style);
struct box *inline_container, *inline_box;
box = result.box;
@ -1145,9 +1138,8 @@ struct result box_input(xmlNode *n, struct status *status,
inline_box->font = font_open(status->content->data.html.fonts, style);
box_add_child(inline_container, inline_box);
box_add_child(box, inline_container);
}
else if (stricmp(type, "image") == 0)
{
} else if (type && strcasecmp(type, "image") == 0) {
box = box_create(style, NULL, 0,
status->content->data.html.box_pool);
box->gadget = gadget = xcalloc(1, sizeof(struct form_control));
@ -1160,6 +1152,12 @@ struct result box_input(xmlNode *n, struct status *status,
image_types);
xmlFree(s);
}
} else {
/* the default type is "text" */
box = box_input_text(n, status, style, false);
gadget = box->gadget;
gadget->box = box;
}
if (type != 0)
@ -1177,7 +1175,7 @@ struct result box_input(xmlNode *n, struct status *status,
}
struct box *box_input_text(xmlNode *n, struct status *status,
struct css_style *style, bool password, bool file)
struct css_style *style, bool password)
{
char *s;
unsigned int i;
@ -1214,9 +1212,6 @@ struct box *box_input_text(xmlNode *n, struct status *status,
inline_box->text = xcalloc(inline_box->length + 1, 1);
for (i = 0; i != inline_box->length; i++)
inline_box->text[i] = '*';
} else if (file) {
box->gadget->type = GADGET_FILE;
inline_box->text = xcalloc(inline_box->length + 1, 1);
} else {
box->gadget->type = GADGET_TEXTBOX;
inline_box->text = xstrdup(box->gadget->value);
@ -2243,7 +2238,7 @@ bool plugin_decode(struct content* content, char* url, struct box* box,
/* The java plugin doesn't need the .class extension
* so we strip it.
*/
if(stricmp((&po->classid[strlen(po->classid)-6]),
if(strcasecmp((&po->classid[strlen(po->classid)-6]),
".class") == 0)
po->classid[strlen(po->classid)-6] = 0;
}

View File

@ -135,7 +135,7 @@ struct form_successful_control *form_successful_controls(struct form *form,
continue;
/* file */
if (control->type == GADGET_FILE) {
if (control->type == GADGET_FILE && control->value) {
success_new = xcalloc(1, sizeof(*success_new));
success_new->file = true;
success_new->name = xstrdup(control->name);

View File

@ -989,11 +989,13 @@ void ro_msg_datasave(wimp_message* block)
void ro_msg_dataload(wimp_message *message)
{
char *url = 0;
gui_window *gui = 0;
gui_window *gui;
if (message->data.data_xfer.w != wimp_ICON_BAR &&
(gui = ro_lookup_gui_from_w(message->data.data_xfer.w)) == NULL) {
return;
gui = ro_lookup_gui_from_w(message->data.data_xfer.w);
if (gui) {
if (ro_gui_window_dataload(gui, message))
return;
}
if (message->data.data_xfer.file_type != 0xfaf &&

View File

@ -147,6 +147,7 @@ bool ro_gui_window_keypress(gui_window *g, int key, bool toolbar);
void ro_gui_scroll_request(wimp_scroll *scroll);
int window_x_units(int x, wimp_window_state *state);
int window_y_units(int y, wimp_window_state *state);
bool ro_gui_window_dataload(gui_window *g, wimp_message *message);
/* in history.c */
void ro_gui_history_init(void);

View File

@ -18,6 +18,7 @@
#include "netsurf/render/html.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/messages.h"
#include "netsurf/utils/utils.h"
@ -42,6 +43,8 @@ static void html_redraw_checkbox(int x, int y, int width, int height,
bool selected);
static void html_redraw_radio(int x, int y, int width, int height,
bool selected);
static void html_redraw_file(int x, int y, int width, int height,
struct box *box, float scale);
bool gui_redraw_debug = false;
@ -231,6 +234,13 @@ void html_redraw_box(struct content *content, struct box * box,
width, height,
box->gadget->data.radio.selected);
} else if (box->gadget && box->gadget->type == GADGET_FILE) {
colourtrans_set_font_colours(box->font->handle,
current_background_color << 8,
box->style->color << 8, 14, 0, 0, 0);
html_redraw_file(x + padding_left, y - padding_top,
width, height, box, scale);
} else if (box->text && box->font) {
if (content->data.html.text_selection.selected == 1) {
@ -499,3 +509,38 @@ void html_redraw_radio(int x, int y, int width, int height,
html_redraw_circle(x + width * 0.5, y - height * 0.5,
width * 0.3 - 1, os_COLOUR_RED);
}
/**
* Plot a file upload input.
*/
void html_redraw_file(int x, int y, int width, int height,
struct box *box, float scale)
{
int text_width;
const char *text;
const char *sprite;
if (box->gadget->value) {
text = box->gadget->value;
sprite = "file_fff";
} else {
text = messages_get("Form_Drop");
sprite = "drophere";
}
text_width = font_width(box->font, text, strlen(text)) * 2 * scale;
if (width < text_width + 8)
x = x + width - text_width - 4;
else
x = x + 4;
font_paint(box->font->handle, text,
font_OS_UNITS | font_GIVEN_FONT |
font_KERN | font_GIVEN_TRFM,
x, y - height * 0.75, 0, &trfm, 0);
/* xwimpspriteop_put_sprite_user_coords(sprite, x + 4, */
/* y - height / 2 - 17, os_ACTION_OVERWRITE); */
}

View File

@ -27,6 +27,7 @@
#include "netsurf/riscos/save_draw.h"
#include "netsurf/riscos/theme.h"
#include "netsurf/riscos/thumbnail.h"
#include "netsurf/render/form.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/url.h"
#include "netsurf/utils/utils.h"
@ -1003,3 +1004,73 @@ int window_y_units(int y, wimp_window_state *state)
{
return y - (state->visible.y1 - state->yscroll);
}
/**
* Handle Message_DataLoad (file dragged in) for a window.
*
* \param g window
* \param message Message_DataLoad block
* \return true if the load was processed
*
* If the file was dragged into a form file input, it is used as the value.
*/
bool ro_gui_window_dataload(gui_window *g, wimp_message *message)
{
struct browser_window *bw = g->data.browser.bw;
struct box_selection *click_boxes = 0;
int x, y;
int i;
int found = 0;
int plot_index = 0;
wimp_window_state state;
/* HTML content only. */
if (!bw->current_content || bw->current_content->type != CONTENT_HTML)
return false;
/* Ignore directories etc. */
if (0x1000 <= message->data.data_xfer.file_type)
return false;
/* Search for a file input at the drop point. */
state.w = message->data.data_xfer.w;
wimp_get_window_state(&state);
x = window_x_units(message->data.data_xfer.pos.x, &state) / 2;
y = -window_y_units(message->data.data_xfer.pos.y, &state) / 2;
box_under_area(bw->current_content,
bw->current_content->data.html.layout->children,
x, y, 0, 0, &click_boxes, &found, &plot_index);
if (found == 0)
return false;
for (i = 0; i != found; i++) {
if (click_boxes[i].box->gadget &&
click_boxes[i].box->gadget->type ==
GADGET_FILE)
break;
}
if (i == found) {
free(click_boxes);
return false;
}
/* Found: update form input. */
free(click_boxes[i].box->gadget->value);
click_boxes[i].box->gadget->value =
strdup(message->data.data_xfer.file_name);
/* Redraw box. */
box_coords(click_boxes[i].box, &x, &y);
gui_window_redraw(bw->window, x, y,
x + click_boxes[i].box->width,
y + click_boxes[i].box->height);
/* send DataLoadAck */
message->action = message_DATA_LOAD_ACK;
message->your_ref = message->my_ref;
wimp_send_message(wimp_USER_MESSAGE, message, message->sender);
return true;
}