Commit 34e5473bc58351951c10c4e4a0705796c5b0565a
1 parent
0098cc85
Exists in
master
and in
5 other branches
Incluindo opcao "copy as table"
Showing
7 changed files
with
165 additions
and
27 deletions
Show diff stats
src/gtk/actions.c
| ... | ... | @@ -97,8 +97,35 @@ static void reload_action(GtkAction *action, GtkWidget *widget) |
| 97 | 97 | |
| 98 | 98 | static void copy_action(GtkAction *action, GtkWidget *widget) |
| 99 | 99 | { |
| 100 | - trace("Action %s activated on widget %p",gtk_action_get_name(action),widget); | |
| 101 | - v3270_copy(widget); | |
| 100 | + V3270_SELECT_FORMAT mode = V3270_SELECT_TEXT; | |
| 101 | + const gchar * str = (const gchar *) g_object_get_data(G_OBJECT(action),"format"); | |
| 102 | + | |
| 103 | + if(str) | |
| 104 | + { | |
| 105 | + static const struct _format | |
| 106 | + { | |
| 107 | + V3270_SELECT_FORMAT mode; | |
| 108 | + const gchar * name; | |
| 109 | + } format[] = | |
| 110 | + { | |
| 111 | + { V3270_SELECT_TEXT, "text" }, | |
| 112 | + { V3270_SELECT_TABLE, "table" }, | |
| 113 | + }; | |
| 114 | + | |
| 115 | + int f; | |
| 116 | + | |
| 117 | + for(f=0;f<G_N_ELEMENTS(format);f++) | |
| 118 | + { | |
| 119 | + if(!g_strcasecmp(format[f].name,str)) | |
| 120 | + { | |
| 121 | + mode = format[f].mode; | |
| 122 | + break; | |
| 123 | + } | |
| 124 | + } | |
| 125 | + } | |
| 126 | + | |
| 127 | + trace("Action %s activated on widget %p mode=%d",gtk_action_get_name(action),widget,(int) mode); | |
| 128 | + v3270_copy(widget,mode); | |
| 102 | 129 | } |
| 103 | 130 | |
| 104 | 131 | static void append_action(GtkAction *action, GtkWidget *widget) |
| ... | ... | @@ -455,23 +482,13 @@ GtkAction * ui_get_action(GtkWidget *widget, const gchar *name, GHashTable *hash |
| 455 | 482 | } |
| 456 | 483 | else if(!g_strcasecmp(name,"copy")) |
| 457 | 484 | { |
| 458 | - static const gchar * src[] = { "begin", | |
| 459 | - "table", | |
| 460 | - "image", | |
| 461 | - "append", | |
| 462 | - NULL | |
| 463 | - }; | |
| 464 | - | |
| 465 | 485 | static const GCallback cbk[] = { G_CALLBACK(copy_action), |
| 466 | - G_CALLBACK(nop_action), | |
| 467 | - G_CALLBACK(nop_action), | |
| 468 | 486 | G_CALLBACK(append_action) |
| 469 | 487 | }; |
| 470 | 488 | callback = cbk; |
| 471 | 489 | action_type = ACTION_TYPE_TABLE; |
| 472 | - id = get_attribute_id(name,"mode",&nm,src,names,values,error); | |
| 473 | - if(id < 0) | |
| 474 | - return NULL; | |
| 490 | + id = ui_get_bool_attribute("append",names,values,FALSE) ? 1 : 0; | |
| 491 | + nm = g_strconcat(id == 0 ? "copy" : "append",ui_get_attribute("format",names,values),NULL); | |
| 475 | 492 | } |
| 476 | 493 | else if(!g_strcasecmp(name,"select")) |
| 477 | 494 | { | ... | ... |
src/gtk/v3270/clipboard.c
| ... | ... | @@ -96,6 +96,18 @@ gchar * v3270_get_text(GtkWidget *widget, int offset, int len) |
| 96 | 96 | return text; |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | +static gchar * v3270_get_selected(v3270 *widget) | |
| 100 | +{ | |
| 101 | + gchar *text = lib3270_get_selected(widget->host); | |
| 102 | + if(text) | |
| 103 | + { | |
| 104 | + gchar *str = g_strdup(text); | |
| 105 | + free(text); | |
| 106 | + return str; | |
| 107 | + } | |
| 108 | + return NULL; | |
| 109 | +} | |
| 110 | + | |
| 99 | 111 | const gchar * v3270_get_selected_text(GtkWidget *widget) |
| 100 | 112 | { |
| 101 | 113 | v3270 *terminal; |
| ... | ... | @@ -111,7 +123,7 @@ const gchar * v3270_get_selected_text(GtkWidget *widget) |
| 111 | 123 | terminal->clipboard = NULL; |
| 112 | 124 | } |
| 113 | 125 | |
| 114 | - text = lib3270_get_selected(terminal->host); | |
| 126 | + text = v3270_get_selected(terminal); | |
| 115 | 127 | |
| 116 | 128 | if(!text) |
| 117 | 129 | { |
| ... | ... | @@ -120,9 +132,85 @@ const gchar * v3270_get_selected_text(GtkWidget *widget) |
| 120 | 132 | return NULL; |
| 121 | 133 | } |
| 122 | 134 | |
| 135 | + if(terminal->table) | |
| 136 | + { | |
| 137 | + // Convert text to table | |
| 138 | + gchar **ln = g_strsplit(text,"\n",-1); | |
| 139 | + int width = lib3270_get_width(terminal->host); | |
| 140 | + gboolean cols[width]; | |
| 141 | + int l; | |
| 142 | + GString * buffer; | |
| 143 | + | |
| 144 | + memset(cols,0,sizeof(gboolean)*width); | |
| 145 | + | |
| 146 | + // Find column delimiters | |
| 147 | + for(l=0;ln[l];l++) | |
| 148 | + { | |
| 149 | + int c; | |
| 150 | + gchar * ptr = ln[l]; | |
| 151 | + GString * buffer; | |
| 152 | + | |
| 153 | + for(c=0;c<width && *ptr;c++) | |
| 154 | + { | |
| 155 | + if(!g_ascii_isspace(*ptr)) | |
| 156 | + cols[c] = TRUE; | |
| 157 | + | |
| 158 | + ptr++; | |
| 159 | + } | |
| 160 | + | |
| 161 | + } | |
| 162 | + | |
| 163 | + // Read screen contents | |
| 164 | + buffer = g_string_sized_new(strlen(text)); | |
| 165 | + for(l=0;ln[l];l++) | |
| 166 | + { | |
| 167 | + int col = 0; | |
| 168 | + gchar * src = ln[l]; | |
| 169 | + | |
| 170 | + while(col < width && *src) | |
| 171 | + { | |
| 172 | + if(col) | |
| 173 | + g_string_append_c(buffer,'\t'); | |
| 174 | + | |
| 175 | + // Find column start | |
| 176 | + while(!cols[col] && col < width && *src) | |
| 177 | + { | |
| 178 | + col++; | |
| 179 | + src++; | |
| 180 | + } | |
| 181 | + | |
| 182 | + if(col < width && *src) | |
| 183 | + { | |
| 184 | + gchar tmp[width+1]; | |
| 185 | + gchar * dst = tmp; | |
| 186 | + | |
| 187 | + // Copy column content | |
| 188 | + while(cols[col] && col < width && *src) | |
| 189 | + { | |
| 190 | + *dst = *src; | |
| 191 | + col++; | |
| 192 | + dst++; | |
| 193 | + src++; | |
| 194 | + } | |
| 195 | + *dst = 0; | |
| 196 | + g_string_append(buffer,g_strstrip(tmp)); | |
| 197 | + } | |
| 198 | + | |
| 199 | + } | |
| 200 | + g_string_append_c(buffer,'\n'); | |
| 201 | + | |
| 202 | + } | |
| 203 | + | |
| 204 | + g_strfreev(ln); | |
| 205 | + g_free(text); | |
| 206 | + | |
| 207 | + text = g_string_free(buffer,FALSE); | |
| 208 | + } | |
| 209 | + | |
| 123 | 210 | terminal->clipboard = g_convert(text, -1, "UTF-8", lib3270_get_charset(terminal->host), NULL, NULL, NULL); |
| 124 | 211 | |
| 125 | - free(text); | |
| 212 | + g_free(text); | |
| 213 | + | |
| 126 | 214 | |
| 127 | 215 | return terminal->clipboard; |
| 128 | 216 | } |
| ... | ... | @@ -175,11 +263,17 @@ const gchar * v3270_copy_append(GtkWidget *widget) |
| 175 | 263 | return terminal->clipboard; |
| 176 | 264 | } |
| 177 | 265 | |
| 178 | -const gchar * v3270_copy(GtkWidget *widget) | |
| 266 | +const gchar * v3270_copy(GtkWidget *widget, V3270_SELECT_FORMAT mode) | |
| 179 | 267 | { |
| 180 | - const gchar * text = v3270_get_selected_text(widget); | |
| 268 | + const gchar * text; | |
| 181 | 269 | GtkClipboard * clipboard = gtk_widget_get_clipboard(widget,GDK_SELECTION_CLIPBOARD); |
| 182 | 270 | |
| 271 | + g_return_val_if_fail(GTK_IS_V3270(widget),NULL); | |
| 272 | + | |
| 273 | + GTK_V3270(widget)->table = (mode == V3270_SELECT_TABLE ? 1 : 0); | |
| 274 | + | |
| 275 | + text = v3270_get_selected_text(widget); | |
| 276 | + | |
| 183 | 277 | if(text) |
| 184 | 278 | { |
| 185 | 279 | if(gtk_clipboard_set_with_owner( clipboard, | ... | ... |
src/gtk/v3270/private.h
| ... | ... | @@ -121,10 +121,11 @@ G_BEGIN_DECLS |
| 121 | 121 | { |
| 122 | 122 | GtkWidget parent; |
| 123 | 123 | |
| 124 | - // private | |
| 124 | + // flags | |
| 125 | 125 | int selecting : 1; /**< Selecting region */ |
| 126 | 126 | int moving : 1; /**< Moving selected region */ |
| 127 | 127 | int resizing : 1; /**< Resizing selected region */ |
| 128 | + int table : 1; /**< Copy mode is table */ | |
| 128 | 129 | |
| 129 | 130 | #if GTK_CHECK_VERSION(3,0,0) |
| 130 | 131 | ... | ... |
src/gtk/v3270/v3270.h
| ... | ... | @@ -142,11 +142,20 @@ |
| 142 | 142 | void v3270_disconnect(GtkWidget *widget); |
| 143 | 143 | |
| 144 | 144 | // Clipboard |
| 145 | + typedef enum _v3270_select_format | |
| 146 | + { | |
| 147 | + V3270_SELECT_TEXT, | |
| 148 | + V3270_SELECT_TABLE, | |
| 149 | + | |
| 150 | + V3270_SELECT_MAX | |
| 151 | + } V3270_SELECT_FORMAT; | |
| 152 | + | |
| 153 | + const gchar * v3270_copy(GtkWidget *widget, V3270_SELECT_FORMAT mode); | |
| 154 | + const gchar * v3270_copy_append(GtkWidget *widget); | |
| 155 | + | |
| 145 | 156 | const gchar * v3270_get_selected_text(GtkWidget *widget); |
| 146 | 157 | const gchar * v3270_get_copy(GtkWidget *widget); |
| 147 | 158 | gchar * v3270_get_text(GtkWidget *widget,int offset, int len); |
| 148 | - const gchar * v3270_copy(GtkWidget *widget); | |
| 149 | - const gchar * v3270_copy_append(GtkWidget *widget); | |
| 150 | 159 | |
| 151 | 160 | void v3270_paste(GtkWidget *widget); |
| 152 | 161 | void v3270_paste_string(GtkWidget *widget, const gchar *text, const gchar *encoding); | ... | ... |
src/include/lib3270.h
| ... | ... | @@ -267,6 +267,17 @@ |
| 267 | 267 | */ |
| 268 | 268 | LIB3270_EXPORT void lib3270_get_screen_size(H3270 *h, int *r, int *c); |
| 269 | 269 | |
| 270 | + | |
| 271 | + /** | |
| 272 | + * Get current screen width in columns. | |
| 273 | + * | |
| 274 | + * @param h Handle of the desired session. | |
| 275 | + * | |
| 276 | + * @return screen width. | |
| 277 | + * | |
| 278 | + */ | |
| 279 | + LIB3270_EXPORT int lib3270_get_width(H3270 *h); | |
| 280 | + | |
| 270 | 281 | LIB3270_EXPORT unsigned int lib3270_get_length(H3270 *h); |
| 271 | 282 | |
| 272 | 283 | /** | ... | ... |
src/lib3270/screen.c
| ... | ... | @@ -244,6 +244,12 @@ LIB3270_EXPORT void lib3270_get_screen_size(H3270 *h, int *r, int *c) |
| 244 | 244 | *c = h->cols; |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | +LIB3270_EXPORT int lib3270_get_width(H3270 *h) | |
| 248 | +{ | |
| 249 | + CHECK_SESSION_HANDLE(h); | |
| 250 | + return h->cols; | |
| 251 | +} | |
| 252 | + | |
| 247 | 253 | void update_model_info(H3270 *session, int model, int cols, int rows) |
| 248 | 254 | { |
| 249 | 255 | if(model == session->model_num && session->maxROWS == rows && session->maxCOLS == cols) | ... | ... |
ui/00default.xml
| ... | ... | @@ -57,10 +57,10 @@ |
| 57 | 57 | </menu> |
| 58 | 58 | |
| 59 | 59 | <menu name='EditMenu' label='_Edit' > |
| 60 | - <menuitem action='copy' mode='begin' key='<ctrl>c' icon='copy' group='selection' label='Copy' /> | |
| 61 | - <!-- menuitem action='copy' mode='table' key='<ctrl><alt>c' group='selection' label='Copy as table' /--> | |
| 60 | + <menuitem action='copy' append='no' format='text' key='<ctrl>c' icon='copy' group='selection' label='Copy' /> | |
| 61 | + <menuitem action='copy' append='no' format='table' key='<ctrl><alt>c' group='selection' label='Copy as table' /> | |
| 62 | 62 | <!-- menuitem action='copy' mode='image' group='selection' label='Copy as image' /--> |
| 63 | - <menuitem action='copy' mode='append' key='<shift><ctrl>c' group='selection' label='Add to copy' /> | |
| 63 | + <menuitem action='copy' append='yes' key='<shift><ctrl>c' group='selection' label='Add to copy' /> | |
| 64 | 64 | <menuitem action='paste' src='clipboard' key='<ctrl>v' icon='paste' group='paste' label='Paste' /> |
| 65 | 65 | <menuitem action='paste' src='next' key='<shift><ctrl>v' label='Paste next' /> |
| 66 | 66 | |
| ... | ... | @@ -144,7 +144,7 @@ |
| 144 | 144 | |
| 145 | 145 | <toolbar name='toolbar.default' label='Toolbar' key='<alt>t' > |
| 146 | 146 | <toolitem action='selectall' /> |
| 147 | - <toolitem action='copy' mode='begin' /> | |
| 147 | + <toolitem action='copy' append='no' format='text' /> | |
| 148 | 148 | <toolitem action='paste' src='clipboard' /> |
| 149 | 149 | <toolitem action='EraseInput' /> |
| 150 | 150 | |
| ... | ... | @@ -161,8 +161,8 @@ |
| 161 | 161 | </toolbar> |
| 162 | 162 | |
| 163 | 163 | <popup name='selectionpopup' type='selection'> |
| 164 | - <menuitem action='copy' mode='begin' /> | |
| 165 | - <menuitem action='copy' mode='append' /> | |
| 164 | + <menuitem action='copy' append='no' format='text' /> | |
| 165 | + <menuitem action='copy' append='yes' /> | |
| 166 | 166 | <menuitem action='select' target='none'/> |
| 167 | 167 | <menuitem action='select' target='all'/> |
| 168 | 168 | ... | ... |