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 | ... | ... |