diff options
author | Nicholas Todoroff <nd.todoroff@gmail.com> | 2023-08-17 18:35:55 -0600 |
---|---|---|
committer | Nicholas Todoroff <nd.todoroff@gmail.com> | 2023-08-17 18:35:55 -0600 |
commit | e1fdb425b63cb121c6e7c332f621941b81dcf74a (patch) | |
tree | ff94825ca65f6e1241caf00158ac873334b4d9ab | |
parent | 61ac2051c82c9d6f0e67e6efdfcb66b5a8d98070 (diff) |
Allow :ccopy to copy full representation of cells
Adds a configuration variable "copy_to_clipboard_wysiwyg" which defaults
to 1. When this variable is nonzero, :ccopy copies the selected range as
it's displayed. When set to zero, :ccopy copies a full string
representation of the cells.
-rw-r--r-- | src/clipboard.c | 67 | ||||
-rw-r--r-- | src/conf.c | 1 | ||||
-rwxr-xr-x | src/doc | 6 | ||||
-rwxr-xr-x | src/gram.y | 8 |
4 files changed, 77 insertions, 5 deletions
diff --git a/src/clipboard.c b/src/clipboard.c index 94d8636..e08c74d 100644 --- a/src/clipboard.c +++ b/src/clipboard.c @@ -204,16 +204,74 @@ int save_plain(FILE * fout, int r0, int c0, int rn, int cn) { if (fout == NULL) return -1; struct roman * roman = session->cur_doc; int conf_clipboard_delimited_tab = get_conf_int("copy_to_clipboard_delimited_tab"); - int row, col; + int conf_clipboard_wysiwyg = get_conf_int("copy_to_clipboard_wysiwyg"); + int row, col, test_width; + struct ent * p; register struct ent ** pp; + mbstate_t state; wchar_t out[FBUFLEN] = L""; + const char *label = NULL; char num [FBUFLEN] = ""; char text[FBUFLEN] = ""; char formated_s[FBUFLEN] = ""; int res = -1; int align = 1; int emptyfield=-1; + int out_widths[cn - c0 + 1]; + // Calculates the column widths necessary to output. + // If copy_to_clipboard_delimited_tab != 0 then we don't need any of this. + // If copy_to_clipboard_wysiwyg != 0 + // then just use roman->cur_sh->fwidths[col]. + // Otherwise, if the data already fits inside roman->cur_sh->fwidths[col] + // then that is the width used. + // If it doesn't + // then we use the largest data width found in the column and add 1. + if (!conf_clipboard_delimted_tab) { + for (col = c0; col <= cn; ++col) { + out_widths[col-c0] = roman->cur_sh->fwidth[col]; + if (!conf_clipboard_wysiwyg) { + for (row = r0; row <= rn; ++row) { + p = *ATBL(roman->cur_sh, roman->cur_sh->tbl, row, col); + if (!p || p->flags & is_deleted) continue; + if (p->flags & is_valid) { + num[0] = '\0'; + formated_s[0] = '\0'; + res = ui_get_formated_value(&p, col, formated_s); + // res = 0, indicates that in num we store a date + // res = 1, indicates a format is applied in num + if (res == 0 || res == 1) { + strcpy(num, formated_s); + } else if (res == -1) { + sprintf(num, "%.*f", roman->cur_sh->precision[col], p->v); + } + test_width = strlen(num); + } + else if (p->label) { + // Calculate the display width of p->label. + memset(&state, '\0', sizeof state); + label = p->label; + res = mbsrtowcs(out, &label, FBUFLEN, &state); + if (res != (size_t)-1) + test_width = wcswidth(out, wcslen(out)); + else { + test_width = 0; + sc_error("Failed to convert cell label to wide string"); + } + } + else { + test_width = 0; + } + + if (test_width >= out_widths[col-c0]) { + out_widths[col-c0] = test_width + 1; + } + } + } + } + } + + res = -1; for (row = r0; row <= rn; row++) { // ignore hidden rows //if (row_hidden[row]) continue; @@ -261,11 +319,12 @@ int save_plain(FILE * fout, int r0, int c0, int rn, int cn) { else { emptyfield++; } + if (! conf_clipboard_delimited_tab) { if (emptyfield) { - fwprintf(fout, L"%*s", roman->cur_sh->fwidth[col], " "); + fwprintf(fout, L"%*s", out_widths[col-c0], " "); } else { - pad_and_align(text, num, roman->cur_sh->fwidth[col], align, 0, out, roman->cur_sh->row_format[row]); + pad_and_align(text, num, out_widths[col-c0], align, 0, out, roman->cur_sh->row_format[row]); fwprintf(fout, L"%ls", out); } } else if (emptyfield){ @@ -276,7 +335,7 @@ int save_plain(FILE * fout, int r0, int c0, int rn, int cn) { fwprintf(fout, L"%s\t", text); } } else if (! conf_clipboard_delimited_tab) { - fwprintf(fout, L"%*s", roman->cur_sh->fwidth[col], " "); + fwprintf(fout, L"%*s", out_widths[col-c0], " "); } else { fwprintf(fout, L"\t"); } @@ -93,6 +93,7 @@ const char default_config[] = #endif "copy_to_clipboard_delimited_tab=0\n" + "copy_to_clipboard_wysiwyg=1\n" #ifdef DEFAULT_PASTE_FROM_CLIPBOARD_CMD "default_paste_from_clipboard_cmd=" DEFAULT_PASTE_FROM_CLIPBOARD_CMD "\n" @@ -512,6 +512,9 @@ Commands for handling cell content: If you wish to delimit columns with tabs, to paste content directly to other spreadsheet programs, rather than an editor, set "copy_to_clipboard_delimited_tab" variable to "1". + If you wish to copy a full string representation of the range + instead of how its currently displayed in Sc-im, set + "copy_to_clipboard_wysiwyg" to "0". :cpaste Paste clipboard content to Sc-im. When 'cpaste' command is executed, the default value of macro @@ -2206,6 +2209,9 @@ Commands for handling cell content: COPY_TO_CLIPBOARD_DELIMITED_TAB COPY_TO_CLIPBOARD_DELIMITED_TAB = {NUMBER} NOCOPY_TO_CLIPBOARD_DELIMITED_TAB + COPY_TO_CLIPBOARD_WYSIWYG + COPY_TO_CLIPBOARD_WYSIWYG = {NUMBER} + NOCOPY_TO_CLIPBOARD_WYSIWYG DEFAULT_OPEN_FILE_UNDER_CURSOR_CMD = {strarg} NEWLINE_ACTION = {NUMBER} TM_GMTOFF @@ -289,6 +289,8 @@ token S_YANKCOL %token K_DEFAULT_PASTE_FROM_CLIPBOARD_CMD %token K_COPY_TO_CLIPBOARD_DELIMITED_TAB %token K_NOCOPY_TO_CLIPBOARD_DELIMITED_TAB +%token K_COPY_TO_CLIPBOARD_WYSIWYG +%token K_NOCOPY_TO_CLIPBOARD_WYSIWYG %token K_DEFAULT_OPEN_FILE_UNDER_CURSOR_CMD %token K_IMPORT_DELIMITED_TO_TEXT %token K_IGNORECASE @@ -1702,7 +1704,11 @@ setitem : { if ($3 == 0) parse_str(user_conf_d, "copy_to_clipboard_delimited_tab=0", TRUE); else parse_str(user_conf_d, "copy_to_clipboard_delimited_tab=1", TRUE); } | K_NOCOPY_TO_CLIPBOARD_DELIMITED_TAB { parse_str(user_conf_d, "copy_to_clipboard_delimited_tab=0", TRUE); } - + | K_COPY_TO_CLIPBOARD_WYSIWYG { parse_str(user_conf_d, "copy_to_clipboard_wysiwyg=1", TRUE); } + | K_COPY_TO_CLIPBOARD_WYSIWYG '=' NUMBER + { if ($3 == 0) parse_str(user_conf_d, "copy_to_clipboard_wysiwyg=0", TRUE); + else parse_str(user_conf_d, "copy_to_clipboard_wysiwyg=1", TRUE); } + | K_NOCOPY_TO_CLIPBOARD_WYSIWYG { parse_str(user_conf_d, "copy_to_clipboard_wysiwyg=0", TRUE); } | K_DEFAULT_OPEN_FILE_UNDER_CURSOR_CMD '=' strarg { char cmd[MAXCMD]; char * s = (char *) $3; |