mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 04:02:34 +03:00
Fix selection for non-gui browser windows (iframes).
Selection no longer uses current_redraw_browser. Fix long-standing selection bugs on platforms that use action on release behaviour. svn path=/trunk/netsurf/; revision=12598
This commit is contained in:
parent
1832155b7c
commit
9c91893028
@ -676,6 +676,22 @@ void content_close(hlcache_handle *h)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find this content's selection context, if it has one.
|
||||
*/
|
||||
|
||||
struct selection *content_get_selection(hlcache_handle *h)
|
||||
{
|
||||
struct content *c = hlcache_handle_get_content(h);
|
||||
assert(c != 0);
|
||||
|
||||
if (c->handler->get_selection != NULL)
|
||||
return c->handler->get_selection(c);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void content_add_error(struct content *c, const char *token,
|
||||
unsigned int line)
|
||||
{
|
||||
|
@ -157,6 +157,7 @@ void content_open(struct hlcache_handle *h, struct browser_window *bw,
|
||||
struct content *page, struct box *box,
|
||||
struct object_params *params);
|
||||
void content_close(struct hlcache_handle *h);
|
||||
struct selection *content_get_selection(struct hlcache_handle *h);
|
||||
|
||||
/* Member accessors */
|
||||
content_type content_get_type(struct hlcache_handle *c);
|
||||
|
@ -64,6 +64,7 @@ struct content_handler {
|
||||
struct box *box,
|
||||
struct object_params *params);
|
||||
void (*close)(struct content *c);
|
||||
struct selection * (*get_selection)(struct content *c);
|
||||
nserror (*clone)(const struct content *old, struct content **newc);
|
||||
bool (*matches_quirks)(const struct content *c, bool quirks);
|
||||
content_type (*type)(lwc_string *mime_type);
|
||||
|
@ -344,16 +344,40 @@ bool browser_window_has_selection(struct browser_window *bw)
|
||||
{
|
||||
assert(bw->window);
|
||||
|
||||
/* TODO: handle selections in (i)frames */
|
||||
|
||||
if (bw->current_content != NULL && bw->sel != NULL &&
|
||||
selection_defined(bw->sel)) {
|
||||
if (bw->cur_sel != NULL && selection_defined(bw->cur_sel)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* exported interface, documented in browser.h */
|
||||
void browser_window_set_selection(struct browser_window *bw,
|
||||
struct selection *s)
|
||||
{
|
||||
assert(bw->window);
|
||||
|
||||
if (bw->cur_sel != s && bw->cur_sel != NULL) {
|
||||
/* Clear any existing selection */
|
||||
selection_clear(bw->cur_sel, true);
|
||||
}
|
||||
|
||||
/* Replace current selection pointer */
|
||||
if (s == NULL && bw->current_content != NULL) {
|
||||
bw->cur_sel = content_get_selection(bw->current_content);
|
||||
} else {
|
||||
bw->cur_sel = s;
|
||||
}
|
||||
}
|
||||
|
||||
/* exported interface, documented in browser.h */
|
||||
struct selection *browser_window_get_selection(struct browser_window *bw)
|
||||
{
|
||||
assert(bw->window);
|
||||
|
||||
return bw->cur_sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set scroll offsets for a browser window.
|
||||
*
|
||||
@ -407,8 +431,6 @@ struct browser_window *browser_window_create(const char *url,
|
||||
bw->last_action = wallclock();
|
||||
bw->focus = bw;
|
||||
|
||||
bw->sel = selection_create();
|
||||
|
||||
/* gui window */
|
||||
/* from the front end's pov, it clones the top level browser window,
|
||||
* so find that. */
|
||||
@ -446,7 +468,7 @@ void browser_window_initialise_common(struct browser_window *bw,
|
||||
bw->history = history_clone(clone->history);
|
||||
|
||||
/* window characteristics */
|
||||
bw->sel = NULL;
|
||||
bw->cur_sel = NULL;
|
||||
bw->refresh_interval = -1;
|
||||
|
||||
bw->reformat_pending = false;
|
||||
@ -799,13 +821,11 @@ nserror browser_window_callback(hlcache_handle *c,
|
||||
global_history_add(urldb_get_url(url));
|
||||
}
|
||||
}
|
||||
|
||||
/* text selection */
|
||||
if (content_get_type(c) == CONTENT_HTML)
|
||||
selection_init(bw->sel,
|
||||
html_get_box_tree(bw->current_content));
|
||||
if (content_get_type(c) == CONTENT_TEXTPLAIN)
|
||||
selection_init(bw->sel, NULL);
|
||||
|
||||
if (bw->window != NULL) {
|
||||
browser_window_set_selection(bw,
|
||||
content_get_selection(c));
|
||||
}
|
||||
|
||||
/* frames */
|
||||
if (content_get_type(c) == CONTENT_HTML &&
|
||||
@ -854,7 +874,6 @@ nserror browser_window_callback(hlcache_handle *c,
|
||||
else if (c == bw->current_content) {
|
||||
bw->current_content = NULL;
|
||||
browser_window_remove_caret(bw);
|
||||
selection_init(bw->sel, NULL);
|
||||
}
|
||||
|
||||
hlcache_handle_release(c);
|
||||
@ -875,8 +894,6 @@ nserror browser_window_callback(hlcache_handle *c,
|
||||
/* reflow iframe positions */
|
||||
if (html_get_iframe(c) != NULL)
|
||||
browser_window_recalculate_iframes(bw);
|
||||
/* box tree may have changed, need to relabel */
|
||||
selection_reinit(bw->sel, html_get_box_tree(c));
|
||||
}
|
||||
|
||||
if (bw->move_callback)
|
||||
@ -1439,6 +1456,12 @@ void browser_window_destroy_internal(struct browser_window *bw)
|
||||
|
||||
if (top->focus == bw)
|
||||
top->focus = top;
|
||||
|
||||
if (bw->current_content != NULL &&
|
||||
top->cur_sel == content_get_selection(
|
||||
bw->current_content)) {
|
||||
browser_window_set_selection(top, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Destruction order is important: we must ensure that the frontend
|
||||
@ -1471,12 +1494,6 @@ void browser_window_destroy_internal(struct browser_window *bw)
|
||||
bw->box = NULL;
|
||||
}
|
||||
|
||||
/* TODO: After core FRAMES are done, should be
|
||||
* if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) */
|
||||
if (bw->browser_window_type != BROWSER_WINDOW_IFRAME) {
|
||||
selection_destroy(bw->sel);
|
||||
}
|
||||
|
||||
/* These simply free memory, so are safe here */
|
||||
history_destroy(bw->history);
|
||||
|
||||
@ -1831,6 +1848,7 @@ void browser_window_mouse_track(struct browser_window *bw,
|
||||
browser_window_mouse_drag_end(bw, mouse, x, y);
|
||||
}
|
||||
|
||||
/* Browser window's horizontal scrollbar */
|
||||
if (bw->scroll_x != NULL) {
|
||||
int scr_x, scr_y;
|
||||
browser_window_get_scrollbar_pos(bw, true, &scr_x, &scr_y);
|
||||
@ -1853,6 +1871,7 @@ void browser_window_mouse_track(struct browser_window *bw,
|
||||
}
|
||||
}
|
||||
|
||||
/* Browser window's vertical scrollbar */
|
||||
if (bw->scroll_y != NULL) {
|
||||
int scr_x, scr_y;
|
||||
browser_window_get_scrollbar_pos(bw, false, &scr_x, &scr_y);
|
||||
@ -2002,31 +2021,7 @@ void browser_window_mouse_drag_end(struct browser_window *bw,
|
||||
|
||||
switch (bw->drag_type) {
|
||||
case DRAGGING_SELECTION:
|
||||
{
|
||||
hlcache_handle *h = bw->current_content;
|
||||
if (h) {
|
||||
int dir = -1;
|
||||
size_t idx;
|
||||
|
||||
if (selection_dragging_start(bw->sel))
|
||||
dir = 1;
|
||||
|
||||
if (content_get_type(h) == CONTENT_HTML) {
|
||||
idx = html_selection_drag_end(h, mouse, x, y,
|
||||
dir);
|
||||
if (idx != 0)
|
||||
selection_track(bw->sel, mouse, idx);
|
||||
} else {
|
||||
assert(content_get_type(h) ==
|
||||
CONTENT_TEXTPLAIN);
|
||||
idx = textplain_offset_from_coords(h, x, y,
|
||||
dir);
|
||||
selection_track(bw->sel, mouse, idx);
|
||||
}
|
||||
}
|
||||
selection_drag_end(bw->sel);
|
||||
}
|
||||
bw->drag_type = DRAGGING_NONE;
|
||||
/* Drag handled by content handler */
|
||||
break;
|
||||
|
||||
case DRAGGING_OTHER:
|
||||
|
@ -78,9 +78,6 @@ struct browser_window {
|
||||
/** Window history structure. */
|
||||
struct history *history;
|
||||
|
||||
/** Selection state */
|
||||
struct selection *sel;
|
||||
|
||||
/** Handler for keyboard input, or 0. */
|
||||
browser_caret_callback caret_callback;
|
||||
/** Handler for pasting text, or 0. */
|
||||
@ -193,6 +190,9 @@ struct browser_window {
|
||||
/** search context for free text search */
|
||||
struct search_context *search_context;
|
||||
|
||||
/** Content with current selection, or NULL if none */
|
||||
struct selection *cur_sel;
|
||||
|
||||
/** cache of the currently displayed status text. */
|
||||
char *status_text; /**< Current status bar text. */
|
||||
int status_text_len; /**< Length of the ::status_text buffer. */
|
||||
@ -365,6 +365,23 @@ struct browser_window * browser_window_get_root(struct browser_window *bw);
|
||||
*/
|
||||
bool browser_window_has_selection(struct browser_window *bw);
|
||||
|
||||
/**
|
||||
* Set pointer to current selection. Clears any existing selection.
|
||||
*
|
||||
* \param bw The browser window
|
||||
* \param s The new selection
|
||||
*/
|
||||
void browser_window_set_selection(struct browser_window *bw,
|
||||
struct selection *s);
|
||||
|
||||
/**
|
||||
* Get the current selection context from a root browser window
|
||||
*
|
||||
* \param bw The browser window
|
||||
* \return the selection context, or NULL
|
||||
*/
|
||||
struct selection *browser_window_get_selection(struct browser_window *bw);
|
||||
|
||||
|
||||
/* In platform specific hotlist.c. */
|
||||
void hotlist_visited(struct hlcache_handle *c);
|
||||
|
@ -201,7 +201,7 @@ void browser_window_create_iframes(struct browser_window *bw,
|
||||
window->no_resize = true;
|
||||
window->margin_width = cur->margin_width;
|
||||
window->margin_height = cur->margin_height;
|
||||
window->sel = bw->sel;
|
||||
window->cur_sel = bw->cur_sel;
|
||||
window->scale = bw->scale;
|
||||
if (cur->name) {
|
||||
window->name = strdup(cur->name);
|
||||
@ -315,9 +315,8 @@ void browser_window_create_frameset(struct browser_window *bw,
|
||||
warn_user("NoMemory", 0);
|
||||
}
|
||||
|
||||
/* TODO: when framesets are handled in the core, remove
|
||||
* the following line. */
|
||||
window->sel = selection_create();
|
||||
/* TODO: When frames are handled in core:
|
||||
* window->cur_sel = bw->cur_sel; */
|
||||
|
||||
/* linking */
|
||||
window->parent = bw;
|
||||
|
@ -90,20 +90,34 @@ static struct box *get_box(struct box *b, unsigned offset, size_t *pidx);
|
||||
/**
|
||||
* Creates a new selection object associated with a browser window.
|
||||
*
|
||||
* \param s selection object
|
||||
* \param bw browser window
|
||||
* \return new selection context
|
||||
*/
|
||||
|
||||
struct selection *selection_create(void)
|
||||
{
|
||||
struct selection *s = calloc(1, sizeof(struct selection));
|
||||
if (s) {
|
||||
selection_prepare(s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a newly created selection object for use.
|
||||
*
|
||||
* \param s selection object
|
||||
* \param bw browser window
|
||||
*/
|
||||
|
||||
void selection_prepare(struct selection *s)
|
||||
{
|
||||
if (s) {
|
||||
s->bw = NULL;
|
||||
s->root = NULL;
|
||||
s->drag_state = DRAG_NONE;
|
||||
s->max_idx = 0;
|
||||
selection_clear(s, false);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -304,12 +318,16 @@ bool selection_click(struct selection *s, browser_mouse_state mouse,
|
||||
gui_drag_save_selection(s, top->window);
|
||||
}
|
||||
else if (!modkeys) {
|
||||
if (pos && (mouse & BROWSER_MOUSE_PRESS_1))
|
||||
if (pos && (mouse & BROWSER_MOUSE_PRESS_1)) {
|
||||
/* Clear the selection if mouse is pressed outside the selection,
|
||||
* Otherwise clear on release (to allow for drags) */
|
||||
browser_window_set_selection(top, s);
|
||||
|
||||
selection_clear(s, true);
|
||||
else if (mouse & BROWSER_MOUSE_DRAG_1) {
|
||||
} else if (mouse & BROWSER_MOUSE_DRAG_1) {
|
||||
/* start new selection drag */
|
||||
browser_window_set_selection(top, s);
|
||||
|
||||
selection_clear(s, true);
|
||||
|
||||
selection_set_start(s, idx);
|
||||
@ -325,6 +343,8 @@ bool selection_click(struct selection *s, browser_mouse_state mouse,
|
||||
if (!selection_defined(s))
|
||||
return false; /* ignore Adjust drags */
|
||||
|
||||
browser_window_set_selection(top, s);
|
||||
|
||||
if (pos >= 0) {
|
||||
selection_set_end(s, idx);
|
||||
|
||||
@ -385,6 +405,10 @@ void selection_track(struct selection *s, browser_mouse_state mouse,
|
||||
if (!SAME_SPACE(s, idx))
|
||||
return;
|
||||
|
||||
if (!mouse) {
|
||||
s->drag_state = DRAG_NONE;
|
||||
}
|
||||
|
||||
switch (s->drag_state) {
|
||||
|
||||
case DRAG_START:
|
||||
@ -902,7 +926,8 @@ struct box *selection_get_end(struct selection *s, size_t *pidx)
|
||||
* \return true iff part of the given box lies within the selection
|
||||
*/
|
||||
|
||||
bool selection_highlighted(struct selection *s, unsigned start, unsigned end,
|
||||
bool selection_highlighted(const struct selection *s,
|
||||
unsigned start, unsigned end,
|
||||
unsigned *start_idx, unsigned *end_idx)
|
||||
{
|
||||
/* caller should have checked first for efficiency */
|
||||
|
@ -60,6 +60,7 @@ typedef bool (*seln_traverse_handler)(const char *text, size_t length,
|
||||
|
||||
|
||||
struct selection *selection_create(void);
|
||||
void selection_prepare(struct selection *s);
|
||||
void selection_destroy(struct selection *s);
|
||||
|
||||
void selection_init(struct selection *s, struct box *root);
|
||||
@ -103,7 +104,8 @@ void selection_track(struct selection *s, browser_mouse_state mouse,
|
||||
bool selection_traverse(struct selection *s, seln_traverse_handler handler,
|
||||
void *handle);
|
||||
|
||||
bool selection_highlighted(struct selection *s, unsigned start, unsigned end,
|
||||
bool selection_highlighted(const struct selection *s,
|
||||
unsigned start, unsigned end,
|
||||
unsigned *start_idx, unsigned *end_idx);
|
||||
|
||||
bool selection_save_text(struct selection *s, const char *path);
|
||||
|
@ -100,11 +100,7 @@ void browser_window_remove_caret(struct browser_window *bw)
|
||||
{
|
||||
struct browser_window *root_bw;
|
||||
|
||||
/* Find top level browser window */
|
||||
root_bw = bw;
|
||||
while (root_bw && !root_bw->window && root_bw->parent) {
|
||||
root_bw = root_bw->parent;
|
||||
}
|
||||
root_bw = browser_window_get_root(bw);
|
||||
|
||||
gui_window_remove_caret(root_bw->window);
|
||||
|
||||
@ -113,8 +109,6 @@ void browser_window_remove_caret(struct browser_window *bw)
|
||||
bw->move_callback = NULL;
|
||||
bw->caret_p1 = NULL;
|
||||
bw->caret_p2 = NULL;
|
||||
|
||||
selection_clear(bw->sel, true);
|
||||
}
|
||||
|
||||
|
||||
@ -129,23 +123,25 @@ bool browser_window_key_press(struct browser_window *bw, uint32_t key)
|
||||
{
|
||||
struct browser_window *focus = bw->focus;
|
||||
|
||||
assert(bw->window != NULL);
|
||||
|
||||
/* keys that take effect wherever the caret is positioned */
|
||||
switch (key) {
|
||||
case KEY_SELECT_ALL:
|
||||
selection_select_all(focus->sel);
|
||||
selection_select_all(bw->cur_sel);
|
||||
return true;
|
||||
|
||||
case KEY_COPY_SELECTION:
|
||||
gui_copy_to_clipboard(focus->sel);
|
||||
gui_copy_to_clipboard(bw->cur_sel);
|
||||
return true;
|
||||
|
||||
case KEY_CLEAR_SELECTION:
|
||||
selection_clear(focus->sel, true);
|
||||
selection_clear(bw->cur_sel, true);
|
||||
return true;
|
||||
|
||||
case KEY_ESCAPE:
|
||||
if (selection_defined(focus->sel)) {
|
||||
selection_clear(focus->sel, true);
|
||||
if (selection_defined(bw->cur_sel)) {
|
||||
selection_clear(bw->cur_sel, true);
|
||||
return true;
|
||||
}
|
||||
/* if there's no selection,
|
||||
|
@ -381,7 +381,7 @@ static guint nsgtk_scaffolding_update_edit_actions_sensitivity(
|
||||
} else {
|
||||
struct browser_window *bw =
|
||||
gui_window_get_browser_window(g->top_level);
|
||||
has_selection = bw->sel->defined;
|
||||
has_selection = browser_window_has_selection(bw);
|
||||
|
||||
g->buttons[COPY_BUTTON]->sensitivity = has_selection;
|
||||
g->buttons[CUT_BUTTON]->sensitivity = (has_selection &&
|
||||
@ -959,7 +959,7 @@ MULTIHANDLER(copy)
|
||||
if (GTK_IS_EDITABLE (focused))
|
||||
gtk_editable_copy_clipboard(GTK_EDITABLE(g->url_bar));
|
||||
else
|
||||
gui_copy_to_clipboard(bw->sel);
|
||||
gui_copy_to_clipboard(browser_window_get_selection(bw));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -999,7 +999,7 @@ MULTIHANDLER(selectall)
|
||||
gtk_editable_select_region(GTK_EDITABLE(g->url_bar), 0, -1);
|
||||
} else {
|
||||
LOG(("Selecting all document text"));
|
||||
selection_select_all(bw->sel);
|
||||
selection_select_all(browser_window_get_selection(bw));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -74,6 +74,7 @@ static void html_open(struct content *c, struct browser_window *bw,
|
||||
struct content *page, struct box *box,
|
||||
struct object_params *params);
|
||||
static void html_close(struct content *c);
|
||||
struct selection *html_get_selection(struct content *c);
|
||||
static nserror html_clone(const struct content *old, struct content **newc);
|
||||
static content_type html_content_type(lwc_string *mime_type);
|
||||
|
||||
@ -114,6 +115,7 @@ static const content_handler html_content_handler = {
|
||||
.redraw = html_redraw,
|
||||
.open = html_open,
|
||||
.close = html_close,
|
||||
.get_selection = html_get_selection,
|
||||
.clone = html_clone,
|
||||
.type = html_content_type,
|
||||
.no_share = true,
|
||||
@ -255,6 +257,8 @@ nserror html_create_html_data(html_content *c, const http_parameter *params)
|
||||
c->font_func = &nsfont;
|
||||
c->scrollbar = NULL;
|
||||
|
||||
selection_prepare(&c->sel);
|
||||
|
||||
nerror = http_parameter_list_find_item(params, html_charset, &charset);
|
||||
if (nerror == NSERROR_OK) {
|
||||
c->encoding = talloc_strdup(c, lwc_string_data(charset));
|
||||
@ -1754,6 +1758,8 @@ void html_reformat(struct content *c, int width, int height)
|
||||
if (c->height < layout->y + layout->descendant_y1)
|
||||
c->height = layout->y + layout->descendant_y1;
|
||||
|
||||
selection_reinit(&htmlc->sel, htmlc->layout);
|
||||
|
||||
time_taken = wallclock() - time_before;
|
||||
c->reformat_time = wallclock() +
|
||||
((time_taken * 3 < option_min_reflow_period ?
|
||||
@ -1962,7 +1968,9 @@ void html_open(struct content *c, struct browser_window *bw,
|
||||
html->page = (html_content *) page;
|
||||
html->box = box;
|
||||
|
||||
selection_set_browser_window(bw->sel, bw);
|
||||
/* text selection */
|
||||
selection_init(&html->sel, html->layout);
|
||||
selection_set_browser_window(&html->sel, bw);
|
||||
|
||||
for (object = html->object_list; object != NULL; object = next) {
|
||||
next = object->next;
|
||||
@ -1990,8 +1998,7 @@ void html_close(struct content *c)
|
||||
html_content *html = (html_content *) c;
|
||||
struct content_html_object *object, *next;
|
||||
|
||||
if (html->bw && html->bw->sel)
|
||||
selection_set_browser_window(html->bw->sel, NULL);
|
||||
selection_set_browser_window(&html->sel, NULL);
|
||||
|
||||
html->bw = NULL;
|
||||
|
||||
@ -2011,6 +2018,18 @@ void html_close(struct content *c)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an HTML content's selection context
|
||||
*/
|
||||
|
||||
struct selection *html_get_selection(struct content *c)
|
||||
{
|
||||
html_content *html = (html_content *) c;
|
||||
|
||||
return &html->sel;
|
||||
}
|
||||
|
||||
#if ALWAYS_DUMP_FRAMESET
|
||||
/**
|
||||
* Print a frameset tree to stderr.
|
||||
|
@ -159,6 +159,7 @@ bool text_redraw(const char *utf8_text, size_t utf8_len,
|
||||
int height,
|
||||
float scale,
|
||||
bool excluded,
|
||||
const struct selection *sel,
|
||||
const struct redraw_context *ctx);
|
||||
|
||||
xmlDoc *html_get_document(struct hlcache_handle *h);
|
||||
|
@ -61,18 +61,35 @@ static void html_box_drag_start(struct box *box, int x, int y);
|
||||
void html_mouse_track(struct content *c, struct browser_window *bw,
|
||||
browser_mouse_state mouse, int x, int y)
|
||||
{
|
||||
html_content *html = (html_content*) c;
|
||||
hlcache_handle *h = bw->current_content;
|
||||
|
||||
if (bw->drag_type == DRAGGING_SELECTION && !mouse) {
|
||||
int dir = -1;
|
||||
size_t idx;
|
||||
|
||||
if (selection_dragging_start(&html->sel))
|
||||
dir = 1;
|
||||
|
||||
idx = html_selection_drag_end(h, mouse, x, y, dir);
|
||||
|
||||
if (idx != 0)
|
||||
selection_track(&html->sel, mouse, idx);
|
||||
|
||||
browser_window_set_drag_type(bw, DRAGGING_NONE);
|
||||
}
|
||||
|
||||
switch (bw->drag_type) {
|
||||
case DRAGGING_SELECTION: {
|
||||
struct box *box;
|
||||
int dir = -1;
|
||||
int dx, dy;
|
||||
|
||||
if (selection_dragging_start(bw->sel)) dir = 1;
|
||||
if (selection_dragging_start(&html->sel))
|
||||
dir = 1;
|
||||
|
||||
box = box_pick_text_box(h, x, y, dir, &dx, &dy);
|
||||
|
||||
box = box_pick_text_box(h, x, y, dir,
|
||||
&dx, &dy);
|
||||
if (box) {
|
||||
int pixel_offset;
|
||||
size_t idx;
|
||||
@ -84,7 +101,7 @@ void html_mouse_track(struct content *c, struct browser_window *bw,
|
||||
box->text, box->length,
|
||||
dx, &idx, &pixel_offset);
|
||||
|
||||
selection_track(bw->sel, mouse,
|
||||
selection_track(&html->sel, mouse,
|
||||
box->byte_offset + idx);
|
||||
}
|
||||
}
|
||||
@ -116,6 +133,7 @@ void html_mouse_track(struct content *c, struct browser_window *bw,
|
||||
void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
browser_mouse_state mouse, int x, int y)
|
||||
{
|
||||
html_content *html = (html_content *) c;
|
||||
enum { ACTION_NONE, ACTION_SUBMIT, ACTION_GO } action = ACTION_NONE;
|
||||
char *title = 0;
|
||||
const char *url = 0;
|
||||
@ -143,8 +161,6 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
plot_font_style_t fstyle;
|
||||
int scroll_mouse_x = 0, scroll_mouse_y = 0;
|
||||
int padding_left, padding_right, padding_top, padding_bottom;
|
||||
html_content *html = (html_content *) c;
|
||||
|
||||
|
||||
if (bw->drag_type != DRAGGING_NONE && !mouse &&
|
||||
html->visible_select_menu != NULL) {
|
||||
@ -376,12 +392,11 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
|
||||
if (mouse & (BROWSER_MOUSE_PRESS_1 |
|
||||
BROWSER_MOUSE_PRESS_2)) {
|
||||
if (text_box && selection_root(bw->sel) !=
|
||||
if (text_box && selection_root(&html->sel) !=
|
||||
gadget_box)
|
||||
selection_init(bw->sel, gadget_box);
|
||||
selection_init(&html->sel, gadget_box);
|
||||
|
||||
textinput_textarea_click(c,
|
||||
mouse,
|
||||
textinput_textarea_click(c, mouse,
|
||||
gadget_box,
|
||||
gadget_box_x,
|
||||
gadget_box_y,
|
||||
@ -403,17 +418,17 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
&idx,
|
||||
&pixel_offset);
|
||||
|
||||
selection_click(bw->sel, mouse,
|
||||
selection_click(&html->sel, mouse,
|
||||
text_box->byte_offset + idx);
|
||||
|
||||
if (selection_dragging(bw->sel)) {
|
||||
if (selection_dragging(&html->sel)) {
|
||||
bw->drag_type = DRAGGING_SELECTION;
|
||||
status = messages_get("Selecting");
|
||||
} else
|
||||
status = content_get_status_message(h);
|
||||
}
|
||||
else if (mouse & BROWSER_MOUSE_PRESS_1)
|
||||
selection_clear(bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
break;
|
||||
case GADGET_TEXTBOX:
|
||||
case GADGET_PASSWORD:
|
||||
@ -436,7 +451,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
|
||||
if (mouse & (BROWSER_MOUSE_DRAG_1 |
|
||||
BROWSER_MOUSE_DRAG_2))
|
||||
selection_init(bw->sel, gadget_box);
|
||||
selection_init(&html->sel, gadget_box);
|
||||
|
||||
font_plot_style_from_css(text_box->style,
|
||||
&fstyle);
|
||||
@ -448,14 +463,14 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
&idx,
|
||||
&pixel_offset);
|
||||
|
||||
selection_click(bw->sel, mouse,
|
||||
selection_click(&html->sel, mouse,
|
||||
text_box->byte_offset + idx);
|
||||
|
||||
if (selection_dragging(bw->sel))
|
||||
if (selection_dragging(&html->sel))
|
||||
bw->drag_type = DRAGGING_SELECTION;
|
||||
}
|
||||
else if (mouse & BROWSER_MOUSE_PRESS_1)
|
||||
selection_clear(bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
break;
|
||||
case GADGET_HIDDEN:
|
||||
/* not possible: no box generated */
|
||||
@ -538,11 +553,10 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
if (!done) {
|
||||
struct box *layout = html_get_box_tree(h);
|
||||
|
||||
if (text_box &&
|
||||
(mouse & (BROWSER_MOUSE_CLICK_1 |
|
||||
BROWSER_MOUSE_CLICK_2)) &&
|
||||
selection_root(bw->sel) != layout)
|
||||
selection_init(bw->sel, layout);
|
||||
if (mouse && (mouse < BROWSER_MOUSE_MOD_1) &&
|
||||
selection_root(&html->sel) != layout) {
|
||||
selection_init(&html->sel, layout);
|
||||
}
|
||||
|
||||
if (text_box) {
|
||||
int pixel_offset;
|
||||
@ -558,13 +572,13 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
&idx,
|
||||
&pixel_offset);
|
||||
|
||||
if (selection_click(bw->sel, mouse,
|
||||
if (selection_click(&html->sel, mouse,
|
||||
text_box->byte_offset + idx)) {
|
||||
/* key presses must be directed at the
|
||||
* main browser window, paste text
|
||||
* operations ignored */
|
||||
|
||||
if (selection_dragging(bw->sel)) {
|
||||
if (selection_dragging(&html->sel)) {
|
||||
bw->drag_type =
|
||||
DRAGGING_SELECTION;
|
||||
status =
|
||||
@ -576,7 +590,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
}
|
||||
}
|
||||
else if (mouse & BROWSER_MOUSE_PRESS_1)
|
||||
selection_clear(bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
@ -621,8 +635,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((mouse & BROWSER_MOUSE_CLICK_1) &&
|
||||
!selection_defined(bw->sel)) {
|
||||
if (mouse && mouse < BROWSER_MOUSE_MOD_1) {
|
||||
/* ensure key presses still act on the browser window */
|
||||
browser_window_remove_caret(bw);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define NETSURF_RENDER_HTML_INTERNAL_H_
|
||||
|
||||
#include "content/content_protected.h"
|
||||
#include "desktop/selection.h"
|
||||
#include "render/html.h"
|
||||
|
||||
/** Data specific to CONTENT_HTML. */
|
||||
@ -92,6 +93,9 @@ typedef struct html_content {
|
||||
/** Open core-handled form SELECT menu,
|
||||
* or NULL if none currently open. */
|
||||
struct form_control *visible_select_menu;
|
||||
|
||||
/** Selection state */
|
||||
struct selection sel;
|
||||
} html_content;
|
||||
|
||||
|
||||
|
@ -52,16 +52,16 @@
|
||||
#include "utils/utils.h"
|
||||
|
||||
|
||||
static bool html_redraw_box(html_content *html, struct box *box, int x, int y,
|
||||
const struct rect *clip, float scale,
|
||||
static bool html_redraw_box(const html_content *html, struct box *box,
|
||||
int x, int y, const struct rect *clip, float scale,
|
||||
colour current_background_color,
|
||||
const struct redraw_context *ctx);
|
||||
static bool html_redraw_box_children(html_content *html, struct box *box,
|
||||
static bool html_redraw_box_children(const html_content *html, struct box *box,
|
||||
int x_parent, int y_parent, const struct rect *clip,
|
||||
float scale, colour current_background_color,
|
||||
const struct redraw_context *ctx);
|
||||
static bool html_redraw_text_box(struct box *box, int x, int y,
|
||||
const struct rect *clip, float scale,
|
||||
static bool html_redraw_text_box(const html_content *html, struct box *box,
|
||||
int x, int y, const struct rect *clip, float scale,
|
||||
colour current_background_color,
|
||||
const struct redraw_context *ctx);
|
||||
static bool html_redraw_borders(struct box *box, int x_parent, int y_parent,
|
||||
@ -253,7 +253,7 @@ static struct box *html_redraw_find_bg_box(struct box *box)
|
||||
* x, y, clip_[xy][01] are in target coordinates.
|
||||
*/
|
||||
|
||||
bool html_redraw_box(html_content *html, struct box *box,
|
||||
bool html_redraw_box(const html_content *html, struct box *box,
|
||||
int x_parent, int y_parent,
|
||||
const struct rect *clip, float scale,
|
||||
colour current_background_color,
|
||||
@ -692,7 +692,7 @@ bool html_redraw_box(html_content *html, struct box *box,
|
||||
return false;
|
||||
|
||||
} else if (box->text) {
|
||||
if (!html_redraw_text_box(box, x, y, &r, scale,
|
||||
if (!html_redraw_text_box(html, box, x, y, &r, scale,
|
||||
current_background_color, ctx))
|
||||
return false;
|
||||
|
||||
@ -770,7 +770,7 @@ bool html_redraw_box(html_content *html, struct box *box,
|
||||
* \return true if successful, false otherwise
|
||||
*/
|
||||
|
||||
bool html_redraw_box_children(html_content *html, struct box *box,
|
||||
bool html_redraw_box_children(const html_content *html, struct box *box,
|
||||
int x_parent, int y_parent,
|
||||
const struct rect *clip, float scale,
|
||||
colour current_background_color,
|
||||
@ -818,8 +818,8 @@ bool html_redraw_box_children(html_content *html, struct box *box,
|
||||
* \return true iff successful and redraw should proceed
|
||||
*/
|
||||
|
||||
bool html_redraw_text_box(struct box *box, int x, int y,
|
||||
const struct rect *clip, float scale,
|
||||
bool html_redraw_text_box(const html_content *html, struct box *box,
|
||||
int x, int y, const struct rect *clip, float scale,
|
||||
colour current_background_color,
|
||||
const struct redraw_context *ctx)
|
||||
{
|
||||
@ -831,7 +831,7 @@ bool html_redraw_text_box(struct box *box, int x, int y,
|
||||
|
||||
if (!text_redraw(box->text, box->length, box->byte_offset,
|
||||
box->space, &fstyle, x, y,
|
||||
clip, box->height, scale, excluded, ctx))
|
||||
clip, box->height, scale, excluded, &html->sel, ctx))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -859,7 +859,7 @@ bool html_redraw_text_box(struct box *box, int x, int y,
|
||||
bool text_redraw(const char *utf8_text, size_t utf8_len,
|
||||
size_t offset, int space, const plot_font_style_t *fstyle,
|
||||
int x, int y, const struct rect *clip, int height,
|
||||
float scale, bool excluded,
|
||||
float scale, bool excluded, const struct selection *sel,
|
||||
const struct redraw_context *ctx)
|
||||
{
|
||||
const struct plotter_table *plot = ctx->plot;
|
||||
@ -876,9 +876,9 @@ bool text_redraw(const char *utf8_text, size_t utf8_len,
|
||||
unsigned end_idx;
|
||||
|
||||
/* first try the browser window's current selection */
|
||||
if (selection_defined(current_redraw_browser->sel) &&
|
||||
selection_highlighted(current_redraw_browser->sel,
|
||||
offset, offset + len, &start_idx, &end_idx)) {
|
||||
if (selection_defined(sel) && selection_highlighted(sel,
|
||||
offset, offset + len,
|
||||
&start_idx, &end_idx)) {
|
||||
highlighted = true;
|
||||
}
|
||||
|
||||
|
@ -258,8 +258,8 @@ static bool textinput_textbox_insert(struct content *c,
|
||||
struct box *input = text_box->parent->parent;
|
||||
bool hide;
|
||||
|
||||
if (html->bw && html->bw->sel->defined)
|
||||
textinput_delete_selection(c, html->bw->sel);
|
||||
if (html->bw && html->sel.defined)
|
||||
textinput_delete_selection(c, &html->sel);
|
||||
|
||||
/* insert into form gadget (text and password inputs only) */
|
||||
if (input->gadget && (input->gadget->type == GADGET_TEXTBOX ||
|
||||
@ -402,8 +402,8 @@ bool textinput_textbox_delete(struct content *c, struct box *text_box,
|
||||
unsigned next_offset = char_offset + utf8_len;
|
||||
struct box *form = text_box->parent->parent;
|
||||
|
||||
if (html->bw && html->bw->sel->defined) {
|
||||
textinput_delete_selection(c, html->bw->sel);
|
||||
if (html->bw && html->sel.defined) {
|
||||
textinput_delete_selection(c, &html->sel);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1113,7 +1113,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
char utf8[6];
|
||||
unsigned int utf8_len;
|
||||
bool scrolled, reflow = false;
|
||||
bool selection_exists = html->bw->sel->defined;
|
||||
bool selection_exists = html->sel.defined;
|
||||
plot_font_style_t fstyle;
|
||||
|
||||
/* box_dump(textarea, 0); */
|
||||
@ -1192,7 +1192,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
|
||||
/* Clear the selection, if one exists */
|
||||
if (selection_exists)
|
||||
selection_clear(html->bw->sel, false);
|
||||
selection_clear(&html->sel, false);
|
||||
|
||||
textinput_textarea_cut(c, start_box, 0, text_box,
|
||||
char_offset, false);
|
||||
@ -1208,7 +1208,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
|
||||
/* Clear the selection, if one exists */
|
||||
if (selection_exists)
|
||||
selection_clear(html->bw->sel, false);
|
||||
selection_clear(&html->sel, false);
|
||||
|
||||
if (end_box != text_box ||
|
||||
char_offset < text_box->length + SPACE_LEN(text_box)) {
|
||||
@ -1293,7 +1293,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
|
||||
/* Clear the selection, if one exists */
|
||||
if (selection_exists)
|
||||
selection_clear(html->bw->sel, false);
|
||||
selection_clear(&html->sel, false);
|
||||
|
||||
textinput_textarea_cut(c, start_box, 0, end_box,
|
||||
end_box->length, false);
|
||||
@ -1317,11 +1317,11 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
{
|
||||
size_t start_idx, end_idx;
|
||||
struct box *start_box =
|
||||
selection_get_start(html->bw->sel, &start_idx);
|
||||
struct box *end_box = selection_get_end(html->bw->sel, &end_idx);
|
||||
selection_get_start(&html->sel, &start_idx);
|
||||
struct box *end_box = selection_get_end(&html->sel, &end_idx);
|
||||
|
||||
if (start_box && end_box) {
|
||||
selection_clear(html->bw->sel, false);
|
||||
selection_clear(&html->sel, false);
|
||||
textinput_textarea_cut(c, start_box, start_idx,
|
||||
end_box, end_idx, true);
|
||||
text_box = start_box;
|
||||
@ -1334,7 +1334,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
case KEY_RIGHT:
|
||||
if (selection_exists) {
|
||||
/* In selection, move caret to end */
|
||||
text_box = selection_get_end(html->bw->sel, &char_offset);
|
||||
text_box = selection_get_end(&html->sel, &char_offset);
|
||||
} else if (char_offset < text_box->length) {
|
||||
/* Within-box movement */
|
||||
char_offset = utf8_next(text_box->text,
|
||||
@ -1355,7 +1355,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
case KEY_LEFT:
|
||||
if (selection_exists) {
|
||||
/* In selection, move caret to start */
|
||||
text_box = selection_get_start(html->bw->sel, &char_offset);
|
||||
text_box = selection_get_start(&html->sel, &char_offset);
|
||||
} else if (char_offset > 0) {
|
||||
/* Within-box movement */
|
||||
char_offset = utf8_prev(text_box->text, char_offset);
|
||||
@ -1373,7 +1373,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
break;
|
||||
|
||||
case KEY_UP:
|
||||
selection_clear(html->bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
textinput_textarea_click(c, BROWSER_MOUSE_CLICK_1,
|
||||
textarea,
|
||||
box_x, box_y,
|
||||
@ -1382,7 +1382,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
return true;
|
||||
|
||||
case KEY_DOWN:
|
||||
selection_clear(html->bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
textinput_textarea_click(c, BROWSER_MOUSE_CLICK_1,
|
||||
textarea,
|
||||
box_x, box_y,
|
||||
@ -1458,7 +1458,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
bool in_word;
|
||||
/* if there is a selection, caret should move to the end */
|
||||
if (selection_exists) {
|
||||
text_box = selection_get_end(html->bw->sel, &char_offset);
|
||||
text_box = selection_get_end(&html->sel, &char_offset);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1572,7 +1572,7 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
|
||||
|
||||
nsfont.font_width(&fstyle, text_box->text, char_offset, &pixel_offset);
|
||||
|
||||
selection_clear(html->bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
|
||||
textarea->gadget->caret_inline_container = inline_container;
|
||||
textarea->gadget->caret_text_box = text_box;
|
||||
@ -1804,7 +1804,7 @@ bool textinput_input_callback(struct browser_window *bw, uint32_t key,
|
||||
char utf8[6];
|
||||
unsigned int utf8_len;
|
||||
bool to_textarea = false;
|
||||
bool selection_exists = html->bw->sel->defined;
|
||||
bool selection_exists = html->sel.defined;
|
||||
|
||||
input->gadget->caret_form_offset =
|
||||
textinput_get_form_offset(input, text_box, box_offset);
|
||||
@ -1813,7 +1813,7 @@ bool textinput_input_callback(struct browser_window *bw, uint32_t key,
|
||||
input->gadget->caret_form_offset =
|
||||
textinput_get_form_offset(input, text_box, box_offset);
|
||||
|
||||
selection_get_end(html->bw->sel, &end_offset);
|
||||
selection_get_end(&html->sel, &end_offset);
|
||||
|
||||
box_coords(input, &box_x, &box_y);
|
||||
|
||||
@ -1905,7 +1905,7 @@ bool textinput_input_callback(struct browser_window *bw, uint32_t key,
|
||||
|
||||
case KEY_NL:
|
||||
case KEY_CR: /* Return/Enter hit */
|
||||
selection_clear(html->bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
|
||||
if (form)
|
||||
form_submit(bw->current_content, bw, form, 0);
|
||||
@ -1936,7 +1936,7 @@ bool textinput_input_callback(struct browser_window *bw, uint32_t key,
|
||||
case KEY_CUT_LINE:
|
||||
/* Clear the selection, if one exists */
|
||||
if (selection_exists)
|
||||
selection_clear(html->bw->sel, false);
|
||||
selection_clear(&html->sel, false);
|
||||
|
||||
textinput_textarea_cut(c, text_box, 0, text_box,
|
||||
text_box->length, false);
|
||||
@ -1957,11 +1957,11 @@ bool textinput_input_callback(struct browser_window *bw, uint32_t key,
|
||||
{
|
||||
size_t start_idx, end_idx;
|
||||
struct box *start_box =
|
||||
selection_get_start(html->bw->sel, &start_idx);
|
||||
struct box *end_box = selection_get_end(html->bw->sel, &end_idx);
|
||||
selection_get_start(&html->sel, &start_idx);
|
||||
struct box *end_box = selection_get_end(&html->sel, &end_idx);
|
||||
|
||||
if (start_box && end_box) {
|
||||
selection_clear(html->bw->sel, false);
|
||||
selection_clear(&html->sel, false);
|
||||
textinput_textarea_cut(c, start_box, start_idx,
|
||||
end_box, end_idx, true);
|
||||
|
||||
@ -2026,7 +2026,7 @@ bool textinput_input_callback(struct browser_window *bw, uint32_t key,
|
||||
|
||||
case KEY_DELETE_LINE_START:
|
||||
if (selection_exists)
|
||||
selection_clear(html->bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
|
||||
if (box_offset == 0)
|
||||
return true;
|
||||
@ -2040,7 +2040,7 @@ bool textinput_input_callback(struct browser_window *bw, uint32_t key,
|
||||
|
||||
case KEY_DELETE_LINE_END:
|
||||
if (selection_exists)
|
||||
selection_clear(html->bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
|
||||
if (box_offset >= text_box->length)
|
||||
return true;
|
||||
@ -2055,7 +2055,7 @@ bool textinput_input_callback(struct browser_window *bw, uint32_t key,
|
||||
return false;
|
||||
}
|
||||
|
||||
selection_clear(html->bw->sel, true);
|
||||
selection_clear(&html->sel, true);
|
||||
textinput_input_update_display(c, input, box_offset,
|
||||
to_textarea, changed);
|
||||
|
||||
|
@ -67,6 +67,8 @@ typedef struct textplain_content {
|
||||
struct textplain_line *physical_line;
|
||||
int formatted_width;
|
||||
struct browser_window *bw;
|
||||
|
||||
struct selection sel; /** Selection state */
|
||||
} textplain_content;
|
||||
|
||||
|
||||
@ -109,6 +111,7 @@ static void textplain_open(struct content *c, struct browser_window *bw,
|
||||
struct content *page, struct box *box,
|
||||
struct object_params *params);
|
||||
void textplain_close(struct content *c);
|
||||
struct selection *textplain_get_selection(struct content *c);
|
||||
static nserror textplain_clone(const struct content *old,
|
||||
struct content **newc);
|
||||
static content_type textplain_content_type(lwc_string *mime_type);
|
||||
@ -134,6 +137,7 @@ static const content_handler textplain_content_handler = {
|
||||
.redraw = textplain_redraw,
|
||||
.open = textplain_open,
|
||||
.close = textplain_close,
|
||||
.get_selection = textplain_get_selection,
|
||||
.clone = textplain_clone,
|
||||
.type = textplain_content_type,
|
||||
.no_share = true,
|
||||
@ -288,6 +292,8 @@ nserror textplain_create_internal(textplain_content *c, lwc_string *encoding)
|
||||
c->formatted_width = 0;
|
||||
c->bw = NULL;
|
||||
|
||||
selection_prepare(&c->sel);
|
||||
|
||||
return NSERROR_OK;
|
||||
|
||||
no_memory:
|
||||
@ -616,6 +622,22 @@ content_type textplain_content_type(lwc_string *mime_type)
|
||||
void textplain_mouse_track(struct content *c, struct browser_window *bw,
|
||||
browser_mouse_state mouse, int x, int y)
|
||||
{
|
||||
textplain_content *text = (textplain_content *) c;
|
||||
hlcache_handle *h = bw->current_content;
|
||||
|
||||
if (bw->drag_type == DRAGGING_SELECTION && !mouse) {
|
||||
int dir = -1;
|
||||
size_t idx;
|
||||
|
||||
if (selection_dragging_start(&text->sel))
|
||||
dir = 1;
|
||||
|
||||
idx = textplain_offset_from_coords(h, x, y, dir);
|
||||
selection_track(&text->sel, mouse, idx);
|
||||
|
||||
browser_window_set_drag_type(bw, DRAGGING_NONE);
|
||||
}
|
||||
|
||||
switch (bw->drag_type) {
|
||||
|
||||
case DRAGGING_SELECTION: {
|
||||
@ -623,10 +645,10 @@ void textplain_mouse_track(struct content *c, struct browser_window *bw,
|
||||
int dir = -1;
|
||||
size_t idx;
|
||||
|
||||
if (selection_dragging_start(bw->sel)) dir = 1;
|
||||
if (selection_dragging_start(&text->sel)) dir = 1;
|
||||
|
||||
idx = textplain_offset_from_coords(h, x, y, dir);
|
||||
selection_track(bw->sel, mouse, idx);
|
||||
selection_track(&text->sel, mouse, idx);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -650,20 +672,19 @@ void textplain_mouse_track(struct content *c, struct browser_window *bw,
|
||||
void textplain_mouse_action(struct content *c, struct browser_window *bw,
|
||||
browser_mouse_state mouse, int x, int y)
|
||||
{
|
||||
textplain_content *text = (textplain_content *) c;
|
||||
hlcache_handle *h = bw->current_content;
|
||||
gui_pointer_shape pointer = GUI_POINTER_DEFAULT;
|
||||
const char *status = 0;
|
||||
size_t idx;
|
||||
int dir = 0;
|
||||
|
||||
bw->drag_type = DRAGGING_NONE;
|
||||
|
||||
if (!bw->sel) return;
|
||||
browser_window_set_drag_type(bw, DRAGGING_NONE);
|
||||
|
||||
idx = textplain_offset_from_coords(h, x, y, dir);
|
||||
if (selection_click(bw->sel, mouse, idx)) {
|
||||
if (selection_click(&text->sel, mouse, idx)) {
|
||||
|
||||
if (selection_dragging(bw->sel)) {
|
||||
if (selection_dragging(&text->sel)) {
|
||||
bw->drag_type = DRAGGING_SELECTION;
|
||||
status = messages_get("Selecting");
|
||||
}
|
||||
@ -751,7 +772,7 @@ bool textplain_redraw(struct content *c, struct content_redraw_data *data,
|
||||
x = (x + MARGIN) * data->scale;
|
||||
y = (y + MARGIN) * data->scale;
|
||||
for (lineno = line0; lineno != line1; lineno++) {
|
||||
const char *text = utf8_data + line[lineno].start;
|
||||
const char *text_d = utf8_data + line[lineno].start;
|
||||
int tab_width = textplain_tab_width * data->scale;
|
||||
size_t offset = 0;
|
||||
int tx = x;
|
||||
@ -767,22 +788,22 @@ bool textplain_redraw(struct content *c, struct content_redraw_data *data,
|
||||
int width;
|
||||
int ntx;
|
||||
|
||||
while (next_offset < length && text[next_offset] != '\t')
|
||||
next_offset = utf8_next(text, length, next_offset);
|
||||
while (next_offset < length && text_d[next_offset] != '\t')
|
||||
next_offset = utf8_next(text_d, length, next_offset);
|
||||
|
||||
if (!text_redraw(text + offset, next_offset - offset,
|
||||
if (!text_redraw(text_d + offset, next_offset - offset,
|
||||
line[lineno].start + offset, 0,
|
||||
&textplain_style,
|
||||
tx, y + (lineno * scaled_line_height),
|
||||
clip, line_height, data->scale, false,
|
||||
ctx))
|
||||
&text->sel, ctx))
|
||||
return false;
|
||||
|
||||
if (next_offset >= length)
|
||||
break;
|
||||
|
||||
/* locate end of string and align to next tab position */
|
||||
if (nsfont.font_width(&textplain_style, &text[offset],
|
||||
if (nsfont.font_width(&textplain_style, &text_d[offset],
|
||||
next_offset - offset, &width))
|
||||
tx += (int)(width * data->scale);
|
||||
|
||||
@ -794,7 +815,7 @@ bool textplain_redraw(struct content *c, struct content_redraw_data *data,
|
||||
|
||||
if (bw) {
|
||||
unsigned tab_ofst = line[lineno].start + next_offset;
|
||||
struct selection *sel = bw->sel;
|
||||
struct selection *sel = &text->sel;
|
||||
bool highlighted = false;
|
||||
|
||||
if (selection_defined(sel)) {
|
||||
@ -845,7 +866,9 @@ void textplain_open(struct content *c, struct browser_window *bw,
|
||||
|
||||
text->bw = bw;
|
||||
|
||||
selection_set_browser_window(bw->sel, bw);
|
||||
/* text selection */
|
||||
selection_set_browser_window(&text->sel, bw);
|
||||
selection_init(&text->sel, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -857,12 +880,23 @@ void textplain_close(struct content *c)
|
||||
{
|
||||
textplain_content *text = (textplain_content *) c;
|
||||
|
||||
if (text->bw && text->bw->sel)
|
||||
selection_set_browser_window(text->bw->sel, NULL);
|
||||
selection_set_browser_window(&text->sel, NULL);
|
||||
|
||||
text->bw = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an textplain content's selection context
|
||||
*/
|
||||
|
||||
struct selection *textplain_get_selection(struct content *c)
|
||||
{
|
||||
textplain_content *text = (textplain_content *) c;
|
||||
|
||||
return &text->sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve number of lines in content
|
||||
*
|
||||
|
@ -2580,7 +2580,7 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
|
||||
|
||||
ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_CUT,
|
||||
!browser_window_has_selection(bw) ||
|
||||
selection_read_only(bw->sel));
|
||||
selection_read_only(browser_window_get_selection(bw)));
|
||||
|
||||
ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_PASTE,
|
||||
h == NULL || bw->paste_callback == NULL);
|
||||
@ -2726,7 +2726,8 @@ void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
|
||||
case BROWSER_SELECTION_SAVE:
|
||||
if (browser_window_has_selection(bw))
|
||||
ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
|
||||
bw->sel, NULL, NULL);
|
||||
browser_window_get_selection(bw),
|
||||
NULL, NULL);
|
||||
break;
|
||||
|
||||
case BROWSER_SAVE_URL_URI:
|
||||
@ -3069,7 +3070,8 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
|
||||
case BROWSER_SELECTION_SAVE:
|
||||
if (h != NULL) {
|
||||
ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
|
||||
bw->sel, NULL, NULL);
|
||||
browser_window_get_selection(bw),
|
||||
NULL, NULL);
|
||||
ro_gui_dialog_open_persistent(g->window, dialog_saveas,
|
||||
false);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user