diff options
author | Andrés <andmarti@gmail.com> | 2023-08-21 13:39:17 -0300 |
---|---|---|
committer | Andrés <andmarti@gmail.com> | 2023-08-21 13:39:17 -0300 |
commit | 7ff262c4e455c708f8a6925f017b5da0b99adbda (patch) | |
tree | bde5db11ee92d0f279ccab191a469630bd455e08 | |
parent | 538c6a332a94e49ff2c695216b8ec08088b7489a (diff) | |
parent | 41270c42aca84fef96fd4b8dadf96fb67e4201ff (diff) |
Merge branch 'pr-832' into dev
-rw-r--r-- | src/clipboard.c | 76 | ||||
-rw-r--r-- | src/cmds/cmds.c | 14 | ||||
-rw-r--r-- | src/conf.c | 1 | ||||
-rwxr-xr-x | src/doc | 12 | ||||
-rwxr-xr-x | src/gram.y | 8 |
5 files changed, 95 insertions, 16 deletions
diff --git a/src/clipboard.c b/src/clipboard.c index 2ca7fc9..35d5159 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_delimited_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,19 +319,23 @@ int save_plain(FILE * fout, int r0, int c0, int rn, int cn) { else { emptyfield++; } - if(emptyfield){ - fwprintf(fout, L"\t"); - } + if (! conf_clipboard_delimited_tab) { - pad_and_align(text, num, roman->cur_sh->fwidth[col], align, 0, out, roman->cur_sh->row_format[row]); - fwprintf(fout, L"%ls", out); + if (emptyfield) { + fwprintf(fout, L"%*s", out_widths[col-c0], " "); + } else { + 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){ + fwprintf(fout, L"\t"); } else if ( (*pp)->flags & is_valid) { fwprintf(fout, L"%s\t", num); } else if ( (*pp)->label) { 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"); } diff --git a/src/cmds/cmds.c b/src/cmds/cmds.c index a865de5..c3a9ef3 100644 --- a/src/cmds/cmds.c +++ b/src/cmds/cmds.c @@ -2730,18 +2730,21 @@ void pad_and_align (char * str_value, char * numeric_value, int col_width, int a str_len = wcswidth(wcs_value, wcslen(wcs_value)); if (str_len == 2 && str_in[0] == '\\') { - wmemset(str_out + wcslen(str_out), str_in[1], col_width); + wmemset(str_out, str_in[1], col_width); + str_out[col_width] = L'\0'; free(str_in); return; } else if (str_len == 3 && str_in[0] == '\\' && str_in[1] == '\\') { - wmemset(str_out + wcslen(str_out), str_in[2], col_width); + wmemset(str_out, str_in[2], col_width); + str_out[col_width] = L'\0'; free(str_in); return; } // If padding exceedes column width, returns n number of '-' needed to fill column width if (padding >= col_width ) { - wmemset(str_out + wcslen(str_out), L' ', col_width); + wmemset(str_out, L' ', col_width); + str_out[col_width] = L'\0'; free(str_in); return; } @@ -2749,8 +2752,9 @@ void pad_and_align (char * str_value, char * numeric_value, int col_width, int a // If content exceedes column width, outputs n number of '*' needed to fill column width if (str_len + num_len + padding > col_width * rowfmt && ! get_conf_int("truncate") && ! get_conf_int("overlap") && ! get_conf_int("autowrap")) { - if (padding) wmemset(str_out + wcslen(str_out), L' ', padding); - wmemset(str_out + wcslen(str_out), L'*', col_width - padding); + if (padding) wmemset(str_out, L' ', padding); + wmemset(str_out + padding, L'*', col_width - padding); + str_out[col_width] = L'\0'; free(str_in); return; } @@ -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" @@ -509,9 +509,12 @@ Commands for handling cell content: runtime, using the :set command. This process will export content as plain text. It will not delimit columns with '\t' chars. - 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 delimit columns with tabs in order to paste + content directly into other spreadsheet programs rather than + an editor, set "copy_to_clipboard_delimited_tab" 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 @@ -290,6 +290,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 @@ -1703,7 +1705,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; |