1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

[viewer] New action mark-clipboard. Refs #10

Possibility to mark rectangle for clipboard.
User may bind keys to move-cursor-up, move-cursor-down, move-cursor-left,
move-cursor-right and mark-clipboard.
mark-clipboard is tristate.
First triggerred, it remembers left top corner of rectangle. Now you can move cursor.
Second time triggerred, remembers right bottom corner of rectangle.
Third time, it clears selection.

The copy-clipboard action was changed. Now if the clipboard rectangle is marked,
it copies this rectangle. If not, the current link.
This commit is contained in:
Witold Filipczyk 2020-08-01 23:25:21 +02:00
parent fa27bb0e23
commit 6a960a9fb9
7 changed files with 217 additions and 3 deletions

View File

@ -16,7 +16,7 @@ ACTION_(MAIN, "cache-manager", CACHE_MANAGER, N__("Open cache manager"), 0),
ACTION_(MAIN, "cache-minimize", CACHE_MINIMIZE, N__("Free unused cache entries"), 0),
ACTION_(MAIN, "cookie-manager", COOKIE_MANAGER, N__("Open cookie manager"), 0),
ACTION_(MAIN, "cookies-load", COOKIES_LOAD, N__("Reload cookies file"), ACTION_RESTRICT_ANONYMOUS),
ACTION_(MAIN, "copy-clipboard", COPY_CLIPBOARD, N__("Copy text to clipboard"), ACTION_REQUIRE_VIEW_STATE | ACTION_REQUIRE_LOCATION | ACTION_JUMP_TO_LINK | ACTION_REQUIRE_LINK),
ACTION_(MAIN, "copy-clipboard", COPY_CLIPBOARD, N__("Copy text to clipboard"), ACTION_REQUIRE_VIEW_STATE | ACTION_REQUIRE_LOCATION),
ACTION_(MAIN, "document-info", DOCUMENT_INFO, N__("Show information about the current page"), ACTION_JUMP_TO_LINK),
ACTION_(MAIN, "download-manager", DOWNLOAD_MANAGER, N__("Open download manager"), 0),
ACTION_(MAIN, "exmode", EXMODE, N__("Enter ex-mode (command line)"), 0),
@ -51,6 +51,7 @@ ACTION_(MAIN, "link-info", LINK_INFO, N__("Show information about current link")
ACTION_(MAIN, "link-menu", LINK_MENU, N__("Open the link context menu"), ACTION_REQUIRE_VIEW_STATE | ACTION_JUMP_TO_LINK | ACTION_REQUIRE_LINK),
ACTION_(MAIN, "link-form-menu", LINK_FORM_MENU, N__("Open the form fields menu"), ACTION_REQUIRE_VIEW_STATE | ACTION_JUMP_TO_LINK | ACTION_REQUIRE_LINK | ACTION_REQUIRE_FORM),
ACTION_(MAIN, "lua-console", LUA_CONSOLE, N__("Open a Lua console"), ACTION_RESTRICT_ANONYMOUS),
ACTION_(MAIN, "mark-clipboard", MARK_CLIPBOARD, N__("Mark a corner of the clipboard rectangle"), ACTION_REQUIRE_VIEW_STATE | ACTION_REQUIRE_LOCATION),
ACTION_(MAIN, "mark-goto", MARK_GOTO, N__("Go at a specified mark"), ACTION_REQUIRE_VIEW_STATE),
ACTION_(MAIN, "mark-set", MARK_SET, N__("Set a mark"), ACTION_REQUIRE_VIEW_STATE),
ACTION_(MAIN, "menu", MENU, N__("Activate the menu"), 0),

View File

@ -1284,6 +1284,9 @@ static union option_info config_options_info[] = {
"separator", "brown", "white", "gray", "white",
N_("Tab separator colors.")),
INIT_OPT_COLORS("", N_("Clipboard"),
"clipboard", "lime", "green", "white", "green",
N_("Clipboard highlight colors.")),
INIT_OPT_COLORS("", N_("Searched strings"),
"searched", "black", "lime", "black", "white",

View File

@ -42,6 +42,12 @@ enum cp_status {
CP_STATUS_IGNORED
};
/** Clipboard state */
enum clipboard_status {
CLIPBOARD_NONE,
CLIPBOARD_FIRST_POINT,
CLIPBOARD_SECOND_POINT
};
struct point {
int x, y;
@ -265,6 +271,9 @@ struct document {
enum cp_status cp_status;
unsigned int links_sorted:1; /**< whether links are already sorted */
struct el_box clipboard_box;
enum clipboard_status clipboard_status;
};
#define document_has_frames(document_) ((document_) && (document_)->frame_desc)

View File

@ -166,7 +166,7 @@ do_action(struct session *ses, enum main_action action_id, int verbose)
break;
case ACT_MAIN_COPY_CLIPBOARD:
status = copy_current_link_to_clipboard(ses, doc_view, 0);
status = copy_to_clipboard(ses, doc_view);
break;
case ACT_MAIN_DOCUMENT_INFO:
@ -317,6 +317,10 @@ do_action(struct session *ses, enum main_action action_id, int verbose)
#endif
break;
case ACT_MAIN_MARK_CLIPBOARD:
status = mark_clipboard(ses, doc_view);
break;
case ACT_MAIN_MARK_SET:
#ifdef CONFIG_MARKS
ses->kbdprefix.mark = KP_MARK_SET;

View File

@ -165,6 +165,36 @@ draw_frame_lines(struct terminal *term, struct frameset_desc *frameset_desc,
}
}
static void
draw_clipboard(struct terminal *term, struct document_view *doc_view)
{
struct document *document = doc_view->document;
struct color_pair *color;
int starty, startx, endy, endx, x, y, xoffset, yoffset;
assert(term && doc_view);
if_assert_failed return;
if (!document->clipboard_box.height || !document->clipboard_box.width) {
return;
}
color = get_bfu_color(term, "clipboard");
xoffset = doc_view->box.x - doc_view->vs->x;
yoffset = doc_view->box.y - doc_view->vs->y;
starty = int_max(0, document->clipboard_box.y + yoffset);
endy = int_min(doc_view->box.height, document->clipboard_box.y + document->clipboard_box.height + yoffset);
startx = int_max(0, document->clipboard_box.x + xoffset);
endx = int_min(doc_view->box.width, document->clipboard_box.x + document->clipboard_box.width + xoffset);
for (y = starty; y <= endy; ++y) {
for (x = startx; x <= endx; ++x) {
draw_char_color(term, x, y, color);
}
}
}
static void
draw_view_status(struct session *ses, struct document_view *doc_view, int active)
{
@ -173,6 +203,7 @@ draw_view_status(struct session *ses, struct document_view *doc_view, int active
draw_forms(term, doc_view);
if (active) {
draw_searched(term, doc_view);
draw_clipboard(term, doc_view);
draw_current_link(ses, doc_view);
}
}

View File

@ -60,6 +60,8 @@
#include "viewer/text/view.h"
#include "viewer/text/vs.h"
static enum frame_event_status move_clipboard_pos(struct session *ses, struct document_view *view, enum frame_event_status status);
void
detach_formatted(struct document_view *doc_view)
{
@ -602,15 +604,18 @@ move_cursor(struct session *ses, struct document_view *doc_view, int x, int y)
return status;
}
static enum frame_event_status
move_cursor_rel_count(struct session *ses, struct document_view *view,
int rx, int ry, int count)
{
enum frame_event_status status;
int x, y;
x = ses->tab->x + rx*count;
y = ses->tab->y + ry*count;
return move_cursor(ses, view, x, y);
status = move_cursor(ses, view, x, y);
return move_clipboard_pos(ses, view, status);
}
static enum frame_event_status
@ -949,6 +954,152 @@ move_cursor_line_start(struct session *ses, struct document_view *doc_view)
return move_cursor_rel(ses, doc_view, -x, 0);
}
static enum frame_event_status
move_clipboard_pos(struct session *ses, struct document_view *view, enum frame_event_status status)
{
struct document *document = view->document;
int xoffset, yoffset, x, y;
if (!document || document->clipboard_status != CLIPBOARD_FIRST_POINT) {
return status;
}
xoffset = view->vs->x - view->box.x;
yoffset = view->vs->y - view->box.y;
x = ses->tab->x + xoffset;
y = ses->tab->y + yoffset;
if (document->clipboard_box.x == x && document->clipboard_box.y == y) {
return status;
}
if (document->clipboard_box.x > x || document->clipboard_box.y > y) {
return status;
}
document->clipboard_box.height = y - document->clipboard_box.y;
document->clipboard_box.width = x - document->clipboard_box.x;
return FRAME_EVENT_REFRESH;
}
static enum frame_event_status
copy_to_clipboard2(struct document_view *doc_view)
{
struct document *document = doc_view->document;
struct string data;
int starty, endy, startx, y;
int utf8;
if (!document->clipboard_box.height || !document->clipboard_box.width) {
return FRAME_EVENT_OK;
}
if (!init_string(&data)) {
return FRAME_EVENT_OK;
}
starty = document->clipboard_box.y;
endy = int_min(document->clipboard_box.y + document->clipboard_box.height, document->height - 1);
startx = document->clipboard_box.x;
utf8 = document->options.utf8;
for (y = starty; y <= endy; y++) {
int endx = int_min(document->clipboard_box.x + document->clipboard_box.width, document->data[y].length);
int x;
for (x = startx; x < endx; x++) {
#ifdef CONFIG_UTF8
unicode_val_T c;
#else
unsigned char c;
#endif
c = document->data[y].chars[x].data;
#ifdef CONFIG_UTF8
if (utf8 && c == UCS_NO_CHAR) {
/* This is the second cell of
* a double-cell character. */
continue;
}
#endif
#ifdef CONFIG_UTF8
if (utf8) {
if (!isscreensafe_ucs(c)) c = ' ';
} else {
if (!isscreensafe(c)) c = ' ';
}
#else
if (!isscreensafe(c)) c = ' ';
#endif
#ifdef CONFIG_UTF8
if (utf8) {
add_to_string(&data, encode_utf8(c));
} else {
add_char_to_string(&data, c);
}
#else
add_char_to_string(&data, c);
#endif
}
add_char_to_string(&data, '\n');
}
set_clipboard_text(data.source);
done_string(&data);
return FRAME_EVENT_OK;
}
enum frame_event_status
mark_clipboard(struct session *ses, struct document_view *doc_view)
{
struct document *document = doc_view->document;
int xoffset = doc_view->vs->x - doc_view->box.x;
int yoffset = doc_view->vs->y - doc_view->box.y;
int x = ses->tab->x + xoffset;
int y = ses->tab->y + yoffset;
switch (document->clipboard_status)
{
case CLIPBOARD_NONE:
document->clipboard_box.x = x;
document->clipboard_box.y = y;
document->clipboard_box.height = 0;
document->clipboard_box.width = 0;
document->clipboard_status = CLIPBOARD_FIRST_POINT;
return FRAME_EVENT_OK;
case CLIPBOARD_FIRST_POINT:
if (document->clipboard_box.x == x && document->clipboard_box.y == y) {
return FRAME_EVENT_OK;
}
if (document->clipboard_box.x > x || document->clipboard_box.y > y) {
return FRAME_EVENT_OK;
}
document->clipboard_box.height = y - document->clipboard_box.y;
document->clipboard_box.width = x - document->clipboard_box.x;
document->clipboard_status = CLIPBOARD_SECOND_POINT;
return FRAME_EVENT_REFRESH;
case CLIPBOARD_SECOND_POINT:
document->clipboard_box.x = 0;
document->clipboard_box.y = 0;
document->clipboard_box.height = 0;
document->clipboard_box.width = 0;
document->clipboard_status = CLIPBOARD_NONE;
return FRAME_EVENT_REFRESH;
}
return FRAME_EVENT_OK;
}
enum frame_event_status
copy_current_link_to_clipboard(struct session *ses,
struct document_view *doc_view,
@ -975,6 +1126,17 @@ copy_current_link_to_clipboard(struct session *ses,
return FRAME_EVENT_OK;
}
enum frame_event_status
copy_to_clipboard(struct session *ses, struct document_view *doc_view)
{
if (doc_view && doc_view->document
&& doc_view->document->clipboard_box.height
&& doc_view->document->clipboard_box.width) {
return copy_to_clipboard2(doc_view);
}
return copy_current_link_to_clipboard(ses, doc_view, 0);
}
int
try_jump_to_link_number(struct session *ses, struct document_view *doc_view)

View File

@ -76,6 +76,10 @@ enum frame_event_status copy_current_link_to_clipboard(struct session *ses,
struct document_view *doc_view,
int xxx);
enum frame_event_status copy_to_clipboard(struct session *ses, struct document_view *doc_view);
enum frame_event_status mark_clipboard(struct session *ses, struct document_view *doc_view);
/** If the user has provided a numeric prefix, jump to the link
* with that number as its index. */
int try_jump_to_link_number(struct session *ses,