summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2011-07-13 13:20:26 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2011-07-13 13:20:26 +0000
commit9c918930289b18dbfd4bb44081891d5780105bfd (patch)
tree372de7dbf3d8393550e46ab1f8de6e9a97cf2140 /render
parent1832155b7c64e0a977541930fc78f47bbd675ab2 (diff)
downloadnetsurf-9c918930289b18dbfd4bb44081891d5780105bfd.tar.gz
netsurf-9c918930289b18dbfd4bb44081891d5780105bfd.tar.bz2
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
Diffstat (limited to 'render')
-rw-r--r--render/html.c25
-rw-r--r--render/html.h1
-rw-r--r--render/html_interaction.c67
-rw-r--r--render/html_internal.h4
-rw-r--r--render/html_redraw.c30
-rw-r--r--render/textinput.c54
-rw-r--r--render/textplain.c68
7 files changed, 160 insertions, 89 deletions
diff --git a/render/html.c b/render/html.c
index 6f76bf6ac..c377b72a5 100644
--- a/render/html.c
+++ b/render/html.c
@@ -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.
diff --git a/render/html.h b/render/html.h
index ba55a6cdd..f137a83f1 100644
--- a/render/html.h
+++ b/render/html.h
@@ -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);
diff --git a/render/html_interaction.c b/render/html_interaction.c
index db68f4629..8f60877e2 100644
--- a/render/html_interaction.c
+++ b/render/html_interaction.c
@@ -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);
}
diff --git a/render/html_internal.h b/render/html_internal.h
index c736be58a..dc852878a 100644
--- a/render/html_internal.h
+++ b/render/html_internal.h
@@ -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;
diff --git a/render/html_redraw.c b/render/html_redraw.c
index 1b762614c..41b78314a 100644
--- a/render/html_redraw.c
+++ b/render/html_redraw.c
@@ -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;
}
diff --git a/render/textinput.c b/render/textinput.c
index 114c1c818..1a205f748 100644
--- a/render/textinput.c
+++ b/render/textinput.c
@@ -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);
diff --git a/render/textplain.c b/render/textplain.c
index 247afc90d..58a94c41d 100644
--- a/render/textplain.c
+++ b/render/textplain.c
@@ -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
*