mirror of
https://github.com/netsurf-browser/netsurf
synced 2025-01-03 17:54:33 +03:00
[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:
parent
a01210941b
commit
31c659a2ea
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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
|
||||
|
@ -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;
|
||||
|
30
render/box.c
30
render/box.c
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
148
riscos/window.c
148
riscos/window.c
@ -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 */;
|
||||
@ -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,13 +2096,29 @@ 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)
|
||||
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;
|
||||
|
||||
if (file_box) {
|
||||
|
||||
/* Found: update form input. */
|
||||
free(file_box->gadget->value);
|
||||
file_box->gadget->value =
|
||||
@ -2060,6 +2129,16 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user