summaryrefslogtreecommitdiff
path: root/desktop/selection.c
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2013-01-08 16:54:46 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2013-01-08 16:54:46 +0000
commitde63a64b5034900c6673421d4f66e41d68834cb5 (patch)
tree1cc5bf40412760d78ddf06939e6df485dedc94a0 /desktop/selection.c
parent147f2bd08aa48ba6a4f945e28db05b378ab85a13 (diff)
downloadnetsurf-de63a64b5034900c6673421d4f66e41d68834cb5.tar.gz
netsurf-de63a64b5034900c6673421d4f66e41d68834cb5.tar.bz2
Update to use new front end clipboard functions. Now we build the buffer from each individual text box in the core, instead of in each front end. Styles for text runs are generated in the HTML case.
Diffstat (limited to 'desktop/selection.c')
-rw-r--r--desktop/selection.c159
1 files changed, 88 insertions, 71 deletions
diff --git a/desktop/selection.c b/desktop/selection.c
index f4f44e117..ae9df5ec6 100644
--- a/desktop/selection.c
+++ b/desktop/selection.c
@@ -77,6 +77,9 @@ struct selection_string {
char *buffer;
size_t buffer_len;
size_t length;
+
+ int n_styles;
+ nsclipboard_styles *styles;
};
@@ -743,69 +746,6 @@ void selection_redraw(struct selection *s, unsigned start_idx, unsigned end_idx)
/**
- * Selection traversal routine for appending text to the current contents
- * of the clipboard.
- *
- * \param text pointer to text being added, or NULL for newline
- * \param length length of text to be appended (bytes)
- * \param box pointer to text box, or NULL if from textplain
- * \param handle unused handle, we don't need one
- * \param whitespace_text whitespace to place before text for formatting
- * may be NULL
- * \param whitespace_length length of whitespace_text
- * \return true iff successful and traversal should continue
- */
-
-static bool selection_copy_clip_handler(const char *text, size_t length,
- struct box *box, void *handle, const char *whitespace_text,
- size_t whitespace_length)
-{
- bool add_space = false;
- plot_font_style_t style = *plot_style_font;
-
- /* add any whitespace which precedes the text from this box */
- if (whitespace_text != NULL && whitespace_length > 0) {
- if (!gui_add_to_clipboard(whitespace_text,
- whitespace_length, false, &style)) {
- return false;
- }
- }
-
- if (box != NULL) {
- /* HTML */
- add_space = (box->space != 0);
-
- if (box->style != NULL) {
- /* Override default font style */
- font_plot_style_from_css(box->style, &style);
- } else {
- /* If there's no style, there must be no text */
- assert(box->text == NULL);
- }
- }
-
- /* add the text from this box */
- if (!gui_add_to_clipboard(text, length, add_space, &style))
- return false;
-
- return true;
-}
-
-
-/**
- * Copy the selected contents to the clipboard
- *
- * \param s selection
- * \return true iff successful, ie. cut operation can proceed without losing data
- */
-
-bool selection_copy_to_clipboard(struct selection *s)
-{
- return selection_traverse(s, selection_copy_clip_handler, NULL);
-}
-
-
-/**
* Append text to selection string.
*
* \param text text to be added
@@ -816,11 +756,34 @@ bool selection_copy_to_clipboard(struct selection *s)
*/
static bool selection_string_append(const char *text, size_t length, bool space,
- struct selection_string *sel_string)
+ plot_font_style_t *style, struct selection_string *sel_string)
{
size_t new_length = sel_string->length + length + (space ? 1 : 0) + 1;
+ if (style != NULL) {
+ /* Add text run style */
+ nsclipboard_styles *new_styles;
+
+ if (sel_string->n_styles == 0)
+ assert(sel_string->length == 0);
+
+ new_styles = realloc(sel_string->styles,
+ (sel_string->n_styles + 1) *
+ sizeof(nsclipboard_styles));
+ if (new_styles == NULL)
+ return false;
+
+ sel_string->styles = new_styles;
+
+ sel_string->styles[sel_string->n_styles].style = *style;
+ sel_string->styles[sel_string->n_styles].start =
+ sel_string->length;
+
+ sel_string->n_styles++;
+ }
+
if (new_length > sel_string->buffer_len) {
+ /* Need to extend buffer */
size_t new_alloc = new_length + (new_length / 4);
char *new_buff;
@@ -832,12 +795,14 @@ static bool selection_string_append(const char *text, size_t length, bool space,
sel_string->buffer_len = new_alloc;
}
+ /* Copy text onto end of existing text in buffer */
memcpy(sel_string->buffer + sel_string->length, text, length);
sel_string->length += length;
if (space)
sel_string->buffer[sel_string->length++] = ' ';
+ /* Ensure NULL termination */
sel_string->buffer[sel_string->length] = '\0';
return true;
@@ -862,11 +827,13 @@ static bool selection_copy_handler(const char *text, size_t length,
size_t whitespace_length)
{
bool add_space = false;
+ plot_font_style_t style;
+ plot_font_style_t *pstyle = NULL;
/* add any whitespace which precedes the text from this box */
if (whitespace_text != NULL && whitespace_length > 0) {
if (!selection_string_append(whitespace_text,
- whitespace_length, false, handle)) {
+ whitespace_length, false, pstyle, handle)) {
return false;
}
}
@@ -874,10 +841,19 @@ static bool selection_copy_handler(const char *text, size_t length,
if (box != NULL) {
/* HTML */
add_space = (box->space != 0);
+
+ if (box->style != NULL) {
+ /* Override default font style */
+ font_plot_style_from_css(box->style, &style);
+ pstyle = &style;
+ } else {
+ /* If there's no style, there must be no text */
+ assert(box->text == NULL);
+ }
}
/* add the text from this box */
- if (!selection_string_append(text, length, add_space, handle))
+ if (!selection_string_append(text, length, add_space, pstyle, handle))
return false;
return true;
@@ -891,28 +867,69 @@ static bool selection_copy_handler(const char *text, size_t length,
* \return string of selected text, or NULL. Ownership passed to caller.
*/
-char * selection_get_copy(struct selection *s)
+char *selection_get_copy(struct selection *s)
{
struct selection_string sel_string = {
.buffer = NULL,
.buffer_len = 0,
- .length = 0
+ .length = 0,
+
+ .n_styles = 0,
+ .styles = NULL
};
if (s == NULL || !s->defined)
return NULL;
if (!selection_traverse(s, selection_copy_handler, &sel_string)) {
- if (sel_string.buffer != NULL) {
- free(sel_string.buffer);
- }
+ free(sel_string.buffer);
+ free(sel_string.styles);
return NULL;
}
+ free(sel_string.styles);
+
return sel_string.buffer;
}
+
+/**
+ * Copy the selected contents to the clipboard
+ *
+ * \param s selection
+ * \return true iff successful
+ */
+bool selection_copy_to_clipboard(struct selection *s)
+{
+ struct selection_string sel_string = {
+ .buffer = NULL,
+ .buffer_len = 0,
+ .length = 0,
+
+ .n_styles = 0,
+ .styles = NULL
+ };
+
+ if (s == NULL || !s->defined)
+ return false;
+
+ if (!selection_traverse(s, selection_copy_handler, &sel_string)) {
+ free(sel_string.buffer);
+ free(sel_string.styles);
+ return false;
+ }
+
+ gui_set_clipboard(sel_string.buffer, sel_string.length,
+ sel_string.styles, sel_string.n_styles);
+
+ free(sel_string.buffer);
+ free(sel_string.styles);
+
+ return true;
+}
+
+
/**
* Clears the current selection, optionally causing the screen to be updated.
*