summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrés <andmarti@gmail.com>2023-08-21 13:39:17 -0300
committerAndrés <andmarti@gmail.com>2023-08-21 13:39:17 -0300
commit7ff262c4e455c708f8a6925f017b5da0b99adbda (patch)
treebde5db11ee92d0f279ccab191a469630bd455e08
parent538c6a332a94e49ff2c695216b8ec08088b7489a (diff)
parent41270c42aca84fef96fd4b8dadf96fb67e4201ff (diff)
Merge branch 'pr-832' into dev
-rw-r--r--src/clipboard.c76
-rw-r--r--src/cmds/cmds.c14
-rw-r--r--src/conf.c1
-rwxr-xr-xsrc/doc12
-rwxr-xr-xsrc/gram.y8
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;
}
diff --git a/src/conf.c b/src/conf.c
index 6a0ea39..8d2cf95 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -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"
diff --git a/src/doc b/src/doc
index 04f5c3a..cd9228b 100755
--- a/src/doc
+++ b/src/doc
@@ -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
diff --git a/src/gram.y b/src/gram.y
index ca51a86..37ee19e 100755
--- a/src/gram.y
+++ b/src/gram.y
@@ -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;