[project @ 2005-04-20 12:24:41 by adrianl]

text import from global clipboard, other apps & files and additional keys for editing text in textareas

svn path=/import/netsurf/; revision=1673
This commit is contained in:
Adrian Lees 2005-04-20 12:24:41 +00:00
parent a01210941b
commit 31c659a2ea
12 changed files with 975 additions and 205 deletions

View File

@ -97,6 +97,7 @@ void browser_window_create(const char *url, struct browser_window *clone,
bw->sel = selection_create(bw);
bw->throbbing = false;
bw->caret_callback = NULL;
bw->paste_callback = NULL;
bw->frag_id = NULL;
bw->drag_type = DRAGGING_NONE;
bw->scrolling_box = NULL;
@ -292,6 +293,7 @@ void browser_window_callback(content_msg msg, struct content *c,
bw->current_content = c;
bw->loading_content = NULL;
bw->caret_callback = NULL;
bw->paste_callback = NULL;
bw->scrolling_box = NULL;
gui_window_new_content(bw->window);
if (bw->frag_id)
@ -335,6 +337,7 @@ void browser_window_callback(content_msg msg, struct content *c,
else if (c == bw->current_content) {
bw->current_content = 0;
bw->caret_callback = NULL;
bw->paste_callback = NULL;
bw->scrolling_box = NULL;
selection_init(bw->sel, NULL);
}
@ -384,6 +387,7 @@ void browser_window_callback(content_msg msg, struct content *c,
else if (c == bw->current_content) {
bw->current_content = 0;
bw->caret_callback = NULL;
bw->paste_callback = NULL;
bw->scrolling_box = NULL;
selection_init(bw->sel, NULL);
}
@ -936,6 +940,11 @@ void browser_window_mouse_action_html(struct browser_window *bw,
if (text_box && selection_click(bw->sel, text_box, mouse, x - box_x, y - box_y)) {
/* key presses must be directed at the main browser window,
paste text operations ignored */
if (bw->caret_callback) bw->caret_callback = NULL;
if (bw->paste_callback) bw->paste_callback = NULL;
if (selection_dragging(bw->sel)) {
bw->drag_type = DRAGGING_SELECTION;
status = messages_get("Selecting");

View File

@ -25,6 +25,13 @@ struct form_successful_control;
struct gui_window;
struct history;
struct selection;
struct browser_window;
typedef void (*browser_caret_callback)(struct browser_window *bw,
wchar_t key, void *p);
typedef bool (*browser_paste_callback)(struct browser_window *bw,
const char *utf8, unsigned utf8_len, bool last, void *p);
/** Browser window data. */
struct browser_window {
@ -40,9 +47,11 @@ struct browser_window {
struct selection *sel;
/** Handler for keyboard input, or 0. */
void (*caret_callback)(struct browser_window *bw,
wchar_t key, void *p);
/** User parameter for caret_callback. */
browser_caret_callback caret_callback;
/** Handler for pasting text, or 0. */
browser_paste_callback paste_callback;
/** User parameter for caret_callback and paste_callback */
void *caret_p;
/** Platform specific window data. */
@ -125,6 +134,8 @@ void browser_window_mouse_drag_end(struct browser_window *bw,
browser_mouse_state mouse, int x, int y);
bool browser_window_key_press(struct browser_window *bw, wchar_t key);
bool browser_window_paste_text(struct browser_window *bw, const char *utf8,
unsigned utf8_len, bool last);
void browser_window_form_select(struct browser_window *bw,
struct form_control *control, int item);
void browser_redraw_box(struct content *c, struct box *box);

View File

@ -85,6 +85,7 @@ void gui_drag_save_object(gui_save_type type, struct content *c,
void gui_drag_save_selection(struct selection *s, struct gui_window *g);
void gui_start_selection(struct gui_window *g);
void gui_paste_from_clipboard(struct gui_window *g, int x, int y);
bool gui_copy_to_clipboard(struct selection *s);
void gui_create_form_select_menu(struct browser_window *bw,

File diff suppressed because it is too large Load Diff

View File

@ -12,16 +12,51 @@
* Textual input handling (interface)
*/
#ifndef _NETSURF_DESKTOP_TEXTINPUT_H_
#define _NETSURF_DESKTOP_TEXTINPUT_H_
#include <stdbool.h>
struct browser_window;
struct box;
enum input_key {
KEY_DELETE_LEFT = 8,
/* cursor movement keys */
KEY_LEFT = 28,
KEY_RIGHT,
KEY_UP,
KEY_DOWN,
KEY_DELETE_RIGHT = 127,
KEY_LINE_START = 128,
KEY_LINE_END,
KEY_TEXT_START,
KEY_TEXT_END,
KEY_WORD_LEFT,
KEY_WORD_RIGHT,
KEY_PAGE_UP,
KEY_PAGE_DOWN,
KEY_DELETE_LINE_END,
KEY_DELETE_LINE_START,
};
void browser_window_textarea_click(struct browser_window *bw,
browser_mouse_state mouse,
struct box *textarea,
int box_x, int box_y,
int x, int y);
//bool browser_window_textarea_paste(struct browser_window *bw,
void browser_window_input_click(struct browser_window* bw,
struct box *input,
int box_x, int box_y,
int x, int y);
void browser_window_remove_caret(struct browser_window *bw);
#endif

View File

@ -380,6 +380,11 @@ void gui_start_selection(struct gui_window *g)
}
void gui_paste_from_clipboard(struct browser_window *bw, int x, int y)
{
}
bool gui_copy_to_clipboard(struct selection *s)
{
return false;

View File

@ -133,7 +133,35 @@ void box_insert_sibling(struct box *box, struct box *new_box)
/**
* Free the a box tree recursively.
* Unlink a box from the box tree and then free it recursively.
*
* \param box box to unlink and free recursively.
*/
void box_unlink_and_free(struct box *box)
{
struct box *parent = box->parent;
struct box *next = box->next;
struct box *prev = box->prev;
if (parent) {
if (parent->children == box)
parent->children = next;
if (parent->last == box)
parent->last = next ? next : prev;
}
if (prev)
prev->next = next;
if (next)
next->prev = prev;
box_free(box);
}
/**
* Free a box tree recursively.
*
* \param box box to free recursively
*

View File

@ -234,6 +234,7 @@ struct box * box_create(struct css_style *style,
char *id, void *context);
void box_add_child(struct box *parent, struct box *child);
void box_insert_sibling(struct box *box, struct box *new_box);
void box_unlink_and_free(struct box *box);
void box_free(struct box *box);
void box_free_box(struct box *box);
void box_free_object_params(struct object_params *op);

View File

@ -161,6 +161,7 @@ void ro_gui_scroll_request(wimp_scroll *scroll);
//#define window_y_units(y, state) (y - (state->visible.y1 - state->yscroll))
int window_x_units(int x, wimp_window_state *state);
int window_y_units(int y, wimp_window_state *state);
bool window_screen_pos(struct gui_window *g, int x, int y, os_coord *pos);
bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message);
void ro_gui_window_process_reformats(void);
void ro_gui_window_default_options(struct browser_window *bw);

View File

@ -3,6 +3,7 @@
* Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license
* Copyright 2004 James Bursa <bursa@users.sourceforge.net>
* Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net>
*/
/** \file

View File

@ -258,6 +258,53 @@ bool gui_copy_to_clipboard(struct selection *s)
}
/**
* Request to paste the clipboard contents into a textarea/input field
* at a given position. Note that the actual operation may take place
* straight away (local clipboard) or in a number of chunks at some
* later time (clipboard owned by another app).
*
* \param g gui window
* \param x x ordinate at which to paste text
* \param y y ordinate at which to paste text
*/
void gui_paste_from_clipboard(struct gui_window *g, int x, int y)
{
if (owns_clipboard) {
if (clip_length > 0)
browser_window_paste_text(g->bw, clipboard, clip_length, true);
}
else {
wimp_full_message_data_request msg;
os_error *error;
os_coord pos;
if (!window_screen_pos(g, x, y, &pos))
return;
msg.size = sizeof(msg);
msg.your_ref = 0;
msg.action = message_DATA_REQUEST;
msg.w = g->window;
msg.i = -1;
msg.pos.x = pos.x;
msg.pos.y = pos.y;
msg.flags = wimp_DATA_REQUEST_CLIPBOARD;
msg.file_types[0] = osfile_TYPE_TEXT;
msg.file_types[1] = ~0;
error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)&msg,
wimp_BROADCAST);
if (error) {
LOG(("xwimp_send_message: 0x%x : %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
}
}
}
/**
* Discard the current contents of the clipboard, if any, releasing the
* memory it uses.
@ -306,8 +353,6 @@ void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim)
void ro_gui_selection_data_request(wimp_full_message_data_request *req)
{
LOG(("%x owns %d size %d", req->flags, owns_clipboard, req->size));
if (owns_clipboard && clip_length > 0 &&
(req->flags & wimp_DATA_REQUEST_CLIPBOARD)) {
wimp_full_message_data_xfer message;

View File

@ -20,6 +20,7 @@
#include <string.h>
#include "oslib/colourtrans.h"
#include "oslib/osbyte.h"
#include "oslib/osfile.h"
#include "oslib/osspriteop.h"
#include "oslib/serviceinternational.h"
#include "oslib/wimp.h"
@ -28,7 +29,9 @@
#include "netsurf/content/content.h"
#include "netsurf/content/url_store.h"
#include "netsurf/css/css.h"
#include "netsurf/desktop/browser.h"
#include "netsurf/desktop/plotters.h"
#include "netsurf/desktop/textinput.h"
#include "netsurf/render/box.h"
#include "netsurf/render/form.h"
#include "netsurf/riscos/buffer.h"
@ -48,6 +51,10 @@
#include "netsurf/utils/utils.h"
#include "netsurf/utils/messages.h"
#ifndef wimp_KEY_END
#define wimp_KEY_END wimp_KEY_COPY
#endif
/** List of all browser windows. */
static struct gui_window *window_list = 0;
@ -62,6 +69,7 @@ static float scale_snap_to[] = {0.10, 0.125, 0.25, 0.333, 0.5, 0.75,
static void ro_gui_window_clone_options(struct browser_window *new_bw,
struct browser_window *old_bw);
static browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons);
static bool ro_gui_window_import_text(struct gui_window *g, const char *filename);
@ -1616,14 +1624,29 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar)
/* We can't map onto 1->26 (reserved for ctrl+<qwerty>
That leaves 27->31 and 128->159 */
if (c == 394) c = 9; /* Tab */
else if (c == 410) c = 11; /* Shift+Tab */
else if (c == 428) c = 128; /* Ctrl+Left */
else if (c == 429) c = 129; /* Ctrl+Right*/
else if (c == 396) c = 29; /* Left */
else if (c == 397) c = 28; /* Right */
else if (c == 398) c = 31; /* Down */
else if (c == 399) c = 30; /* Up */
switch (key) {
case wimp_KEY_TAB: c = 9; break;
case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break;
/* cursor movement keys */
case wimp_KEY_CONTROL | wimp_KEY_LEFT: c = KEY_LINE_START; break;
case wimp_KEY_END:
case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = KEY_LINE_END; break;
case wimp_KEY_CONTROL | wimp_KEY_UP: c = KEY_TEXT_START; break;
case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = KEY_TEXT_END; break;
case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = KEY_WORD_LEFT ; break;
case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = KEY_WORD_RIGHT; break;
case wimp_KEY_SHIFT | wimp_KEY_UP: c = KEY_PAGE_UP; break;
case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = KEY_PAGE_DOWN; break;
case wimp_KEY_LEFT: c = KEY_LEFT; break;
case wimp_KEY_RIGHT: c = KEY_RIGHT; break;
case wimp_KEY_UP: c = KEY_UP; break;
case wimp_KEY_DOWN: c = KEY_DOWN; break;
/* editing */
case wimp_KEY_CONTROL | wimp_KEY_END: c = 136; break;
}
if (c < 256) {
if ((wchar_t)key > 256)
/* do nothing */;
@ -1685,7 +1708,7 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar)
"%x (ignoring)", c));
return true;
}
/* Continuation of UTF8 character */
wc |= ((c & 0x3F) << (6 * --shift));
if (shift > 0)
@ -1992,6 +2015,35 @@ int window_y_units(int y, wimp_window_state *state) {
}
/**
* Convert x,y window co-ordinates into screen co-ordinates.
*
* \param g gui window
* \param x x ordinate
* \param y y ordinate
* \param pos receives position in screen co-ordinatates
* \return true iff conversion successful
*/
bool window_screen_pos(struct gui_window *g, int x, int y, os_coord *pos)
{
wimp_window_state state;
os_error *error;
state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
LOG(("xwimp_get_window_state: 0x%x:%s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
return false;
}
pos->x = state.visible.x0 + ((x * 2 * g->option.scale) - state.xscroll);
pos->y = state.visible.y1 + ((-y * 2 * g->option.scale) - state.yscroll);
return true;
}
/**
* Handle Message_DataLoad (file dragged in) for a window.
*
@ -2008,6 +2060,7 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
int x, y;
struct box *box;
struct box *file_box = 0;
struct box *text_box = 0;
struct browser_window *bw = g->bw;
struct content *content;
wimp_window_state state;
@ -2021,7 +2074,7 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
if (0x1000 <= message->data.data_xfer.file_type)
return false;
/* Search for a file input at the drop point. */
/* Search for a file input or text area at the drop point. */
state.w = message->data.data_xfer.w;
error = xwimp_get_window_state(&state);
if (error) {
@ -2043,23 +2096,49 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
box->style->visibility == CSS_VISIBILITY_HIDDEN)
continue;
if (box->gadget && box->gadget->type == GADGET_FILE)
file_box = box;
if (box->gadget) {
switch (box->gadget->type) {
case GADGET_FILE:
file_box = box;
break;
case GADGET_TEXTBOX:
case GADGET_TEXTAREA:
case GADGET_PASSWORD:
text_box = box;
break;
default: /* appease compiler */
break;
}
}
}
if (!file_box)
if (!file_box && !text_box)
return false;
/* Found: update form input. */
free(file_box->gadget->value);
file_box->gadget->value =
strdup(message->data.data_xfer.file_name);
if (file_box) {
/* Redraw box. */
box_coords(file_box, &x, &y);
gui_window_redraw(bw->window, x, y,
x + file_box->width,
y + file_box->height);
/* Found: update form input. */
free(file_box->gadget->value);
file_box->gadget->value =
strdup(message->data.data_xfer.file_name);
/* Redraw box. */
box_coords(file_box, &x, &y);
gui_window_redraw(bw->window, x, y,
x + file_box->width,
y + file_box->height);
}
else {
const char *filename = message->data.data_xfer.file_name;
browser_window_mouse_click(g->bw, BROWSER_MOUSE_CLICK_1, x, y);
if (!ro_gui_window_import_text(g, filename))
return true; /* it was for us, it just didn't work! */
}
/* send DataLoadAck */
message->action = message_DATA_LOAD_ACK;
@ -2470,3 +2549,50 @@ void ro_gui_window_set_scale(struct gui_window *g, float scale)
browser_window_update(g->bw, false);
gui_reformat_pending = true;
}
/**
* Import text file into textarea at caret position
*
* \param g gui window containing textarea
* \param filename pathname of file to be imported
* \return true iff successful
*/
bool ro_gui_window_import_text(struct gui_window *g, const char *filename)
{
fileswitch_object_type obj_type;
os_error *error;
char *buf;
int size;
error = xosfile_read_stamped(filename, &obj_type, NULL, NULL,
&size, NULL, NULL);
if (error) {
LOG(("xosfile_read_stamped: 0x%x:%s",
error->errnum, error->errmess));
warn_user("FileError", error->errmess);
return true; /* was for us, but it didn't work! */
}
buf = malloc(size);
if (!buf) {
warn_user("NoMemory", NULL);
return true;
}
error = xosfile_load_stamped(filename, (byte*)buf,
NULL, NULL, NULL, NULL, NULL);
if (error) {
LOG(("xosfile_load_stamped: 0x%x:%s",
error->errnum, error->errmess));
warn_user("LoadError", error->errmess);
free(buf);
return true;
}
browser_window_paste_text(g->bw, buf, size, true);
free(buf);
return true;
}