Commit 41799dd497c2d614f5c46f8880dd6ee91c7dd276
1 parent
05f44824
Exists in
master
and in
1 other branch
Adding option to save terminal as image.
Showing
4 changed files
with
124 additions
and
54 deletions
Show diff stats
src/dialogs/save/save.c
... | ... | @@ -91,22 +91,6 @@ |
91 | 91 | #ifdef WIN32 |
92 | 92 | static void icon_press(GtkEntry G_GNUC_UNUSED(*entry), G_GNUC_UNUSED GtkEntryIconPosition icon_pos, G_GNUC_UNUSED GdkEvent *event, V3270SaveDialog *widget) |
93 | 93 | { |
94 | - /* | |
95 | - | |
96 | - GtkFileChooserNative * dialog = | |
97 | - gtk_file_chooser_native_new( | |
98 | - _( "Select destination file"), | |
99 | - GTK_WINDOW(widget), | |
100 | - GTK_FILE_CHOOSER_ACTION_SAVE, | |
101 | - _("Select"), | |
102 | - _("Cancel") | |
103 | - ); | |
104 | - | |
105 | - gint rc = gtk_native_dialog_run (GTK_NATIVE_DIALOG(dialog)); | |
106 | - | |
107 | - debug("rc=%d",rc); | |
108 | - */ | |
109 | - | |
110 | 94 | g_autofree gchar *filename = |
111 | 95 | v3270_select_file( |
112 | 96 | GTK_WIDGET(widget), |
... | ... | @@ -125,9 +109,6 @@ static void icon_press(GtkEntry G_GNUC_UNUSED(*entry), G_GNUC_UNUSED GtkEntryIco |
125 | 109 | static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_pos, G_GNUC_UNUSED GdkEvent *event, V3270SaveDialog *widget) |
126 | 110 | { |
127 | 111 | |
128 | - //gint format = gtk_combo_box_get_active(GTK_COMBO_BOX(widget->format)); | |
129 | - //g_autofree gchar * extension = g_strconcat("*",formats[format].extension,NULL); | |
130 | - | |
131 | 112 | GtkWidget * dialog = |
132 | 113 | gtk_file_chooser_dialog_new( |
133 | 114 | _( "Select destination file"), |
... | ... | @@ -195,16 +176,10 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ |
195 | 176 | gtk_grid_attach(grid,widget,0,0,1,1); |
196 | 177 | gtk_label_set_mnemonic_widget(GTK_LABEL(widget),dialog->filename); |
197 | 178 | |
198 | -//#ifdef WIN32 | |
199 | -// widget = gtk_button_new_from_icon_name("document-open",GTK_ICON_SIZE_BUTTON); | |
200 | -// g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(select_file),dialog); | |
201 | -// gtk_grid_attach(grid,widget,4,0,1,1); | |
202 | -//#else | |
203 | - gtk_entry_set_icon_from_icon_name(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,"document-open"); | |
179 | + gtk_entry_set_icon_from_icon_name(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,"document-save-as"); | |
204 | 180 | gtk_entry_set_icon_activatable(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,TRUE); |
205 | 181 | gtk_entry_set_icon_tooltip_text(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,_("Select file")); |
206 | 182 | g_signal_connect(G_OBJECT(dialog->filename),"icon-press",G_CALLBACK(icon_press),dialog); |
207 | -//#endif // WIN32 | |
208 | 183 | |
209 | 184 | gtk_entry_set_width_chars(GTK_ENTRY(dialog->filename),60); |
210 | 185 | gtk_entry_set_max_length(GTK_ENTRY(dialog->filename),PATH_MAX); |
... | ... | @@ -240,7 +215,7 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ |
240 | 215 | { |
241 | 216 | gtk_combo_box_text_insert( |
242 | 217 | GTK_COMBO_BOX_TEXT(dialog->format), |
243 | - ix, | |
218 | + -1, | |
244 | 219 | formats[ix].extension, |
245 | 220 | g_dgettext(GETTEXT_PACKAGE,formats[ix].name) |
246 | 221 | ); |
... | ... | @@ -248,6 +223,26 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ |
248 | 223 | |
249 | 224 | gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->format),0); |
250 | 225 | |
226 | + // Image formats. | |
227 | + GSList *img_formats = gdk_pixbuf_get_formats(); | |
228 | + GSList *img_format; | |
229 | + | |
230 | + for(img_format = img_formats;img_format;img_format = g_slist_next(img_format)) | |
231 | + { | |
232 | + GdkPixbufFormat * pixFormat = (GdkPixbufFormat *) img_format->data; | |
233 | + | |
234 | + if (gdk_pixbuf_format_is_writable(pixFormat)) | |
235 | + { | |
236 | + gtk_combo_box_text_insert( | |
237 | + GTK_COMBO_BOX_TEXT(dialog->format), | |
238 | + -1, | |
239 | + gdk_pixbuf_format_get_name(pixFormat), | |
240 | + gdk_pixbuf_format_get_description(pixFormat) | |
241 | + ); | |
242 | + } | |
243 | + | |
244 | + } | |
245 | + | |
251 | 246 | } |
252 | 247 | |
253 | 248 | |
... | ... | @@ -335,20 +330,38 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ |
335 | 330 | return GTK_WIDGET(dialog); |
336 | 331 | } |
337 | 332 | |
338 | - void v3270_save_dialog_apply(GtkWidget *widget, GError **error) | |
333 | + static const gchar * get_filename(V3270SaveDialog * dialog) | |
339 | 334 | { |
340 | - V3270SaveDialog * dialog = V3270_SAVE_DIALOG(widget); | |
335 | + const gchar * filename = gtk_entry_get_text(GTK_ENTRY(dialog->filename)); | |
336 | + gint response = GTK_RESPONSE_OK; | |
341 | 337 | |
342 | - if(!v3270_is_connected(dialog->terminal)) | |
338 | + if(g_file_test(filename,G_FILE_TEST_EXISTS)) | |
343 | 339 | { |
344 | - *error = g_error_new(g_quark_from_static_string(PACKAGE_NAME),ENOTCONN,"%s",strerror(ENOTCONN)); | |
345 | - return; | |
340 | + GtkWidget * confirmation = | |
341 | + gtk_message_dialog_new_with_markup( | |
342 | + GTK_WINDOW(dialog), | |
343 | + GTK_DIALOG_DESTROY_WITH_PARENT, | |
344 | + GTK_MESSAGE_QUESTION,GTK_BUTTONS_OK_CANCEL, | |
345 | + _("The file \"%s\" already exists. Replace it?"), | |
346 | + filename | |
347 | + ); | |
348 | + | |
349 | + response = gtk_dialog_run(GTK_DIALOG(confirmation)); | |
350 | + gtk_widget_destroy(confirmation); | |
346 | 351 | } |
347 | 352 | |
353 | + return (response == GTK_RESPONSE_OK ? filename : NULL); | |
354 | + | |
355 | + } | |
356 | + | |
357 | + static void save_as_text(V3270SaveDialog * dialog, size_t index, GError **error) | |
358 | + { | |
348 | 359 | // Get selection |
349 | 360 | GList * dynamic = NULL; |
350 | 361 | const GList * selection = NULL; |
351 | 362 | |
363 | + debug("%s",__FUNCTION__); | |
364 | + | |
352 | 365 | switch(dialog->mode) |
353 | 366 | { |
354 | 367 | case LIB3270_CONTENT_ALL: |
... | ... | @@ -382,7 +395,7 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ |
382 | 395 | |
383 | 396 | debug("Encoding: %s",encoding); |
384 | 397 | |
385 | - switch(gtk_combo_box_get_active(GTK_COMBO_BOX(dialog->format))) | |
398 | + switch(index) | |
386 | 399 | { |
387 | 400 | case 0: // "Plain text" |
388 | 401 | text = v3270_get_selection_as_text(GTK_V3270(dialog->terminal), selection, encoding, dialog->mode == LIB3270_CONTENT_ALL); |
... | ... | @@ -402,25 +415,9 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ |
402 | 415 | |
403 | 416 | if(text) |
404 | 417 | { |
405 | - const gchar * filename = gtk_entry_get_text(GTK_ENTRY(dialog->filename)); | |
406 | - gint response = GTK_RESPONSE_OK; | |
407 | - | |
408 | - if(g_file_test(filename,G_FILE_TEST_EXISTS)) | |
409 | - { | |
410 | - GtkWidget * confirmation = | |
411 | - gtk_message_dialog_new_with_markup( | |
412 | - GTK_WINDOW(widget), | |
413 | - GTK_DIALOG_DESTROY_WITH_PARENT, | |
414 | - GTK_MESSAGE_QUESTION,GTK_BUTTONS_OK_CANCEL, | |
415 | - _("The file \"%s\" already exists. Replace it?"), | |
416 | - filename | |
417 | - ); | |
418 | - | |
419 | - response = gtk_dialog_run(GTK_DIALOG(confirmation)); | |
420 | - gtk_widget_destroy(confirmation); | |
421 | - } | |
418 | + const gchar * filename = get_filename(dialog); | |
422 | 419 | |
423 | - if(response == GTK_RESPONSE_OK) | |
420 | + if(filename) | |
424 | 421 | { |
425 | 422 | g_file_set_contents( |
426 | 423 | gtk_entry_get_text(GTK_ENTRY(dialog->filename)), |
... | ... | @@ -445,6 +442,56 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ |
445 | 442 | #pragma GCC diagnostic pop |
446 | 443 | } |
447 | 444 | |
445 | + static void save_as_image(V3270SaveDialog * dialog, const gchar *format, GError **error) | |
446 | + { | |
447 | + debug("%s",__FUNCTION__); | |
448 | + | |
449 | + GdkPixbuf * pixbuf = v3270_get_as_pixbuf(dialog->terminal); | |
450 | + | |
451 | + if(pixbuf) | |
452 | + { | |
453 | + const gchar * filename = get_filename(dialog); | |
454 | + | |
455 | + if(filename) | |
456 | + { | |
457 | + gdk_pixbuf_save(pixbuf,filename,format,error,NULL); | |
458 | + } | |
459 | + | |
460 | + g_object_unref(pixbuf); | |
461 | + } | |
462 | + | |
463 | + } | |
464 | + | |
465 | + void v3270_save_dialog_apply(GtkWidget *widget, GError **error) | |
466 | + { | |
467 | + size_t ix; | |
468 | + V3270SaveDialog * dialog = V3270_SAVE_DIALOG(widget); | |
469 | + | |
470 | + if(!v3270_is_connected(dialog->terminal)) | |
471 | + { | |
472 | + *error = g_error_new(g_quark_from_static_string(PACKAGE_NAME),ENOTCONN,"%s",strerror(ENOTCONN)); | |
473 | + return; | |
474 | + } | |
475 | + | |
476 | + // Get type ID | |
477 | + const gchar * format = gtk_combo_box_get_active_id(GTK_COMBO_BOX(dialog->format)); | |
478 | + | |
479 | + // Check for text formats. | |
480 | + for(ix=0;ix<G_N_ELEMENTS(formats);ix++) | |
481 | + { | |
482 | + if(!strcmp(formats[ix].extension,format)) | |
483 | + { | |
484 | + // Is text format, save it | |
485 | + save_as_text(dialog, ix, error); | |
486 | + return; | |
487 | + } | |
488 | + | |
489 | + } | |
490 | + | |
491 | + save_as_image(dialog, format, error); | |
492 | + | |
493 | + } | |
494 | + | |
448 | 495 | void v3270_save_dialog_run(GtkWidget *widget) |
449 | 496 | { |
450 | 497 | if(gtk_dialog_run(GTK_DIALOG(widget)) == GTK_RESPONSE_APPLY) | ... | ... |
src/include/terminal.h
... | ... | @@ -256,6 +256,7 @@ G_BEGIN_DECLS |
256 | 256 | }; |
257 | 257 | |
258 | 258 | G_GNUC_INTERNAL void v3270_activate(GtkWidget *widget); |
259 | + G_GNUC_INTERNAL GdkPixbuf * v3270_get_as_pixbuf(GtkWidget *widget); | |
259 | 260 | |
260 | 261 | /*--[ Globals ]--------------------------------------------------------------------------------------*/ |
261 | 262 | ... | ... |
src/terminal/drawing/draw.c
... | ... | @@ -524,6 +524,29 @@ LIB3270_EXPORT void v3270_reload(GtkWidget *widget) |
524 | 524 | |
525 | 525 | } |
526 | 526 | |
527 | +GdkPixbuf * v3270_get_as_pixbuf(GtkWidget *widget) | |
528 | +{ | |
529 | + v3270 * terminal = GTK_V3270(widget); | |
530 | + | |
531 | + if(!(gtk_widget_get_realized(widget) && terminal->drawing)) | |
532 | + return NULL; | |
533 | + | |
534 | + gint width = gtk_widget_get_allocated_width(widget); | |
535 | + gint height = gtk_widget_get_allocated_height(widget); | |
536 | + | |
537 | + cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); | |
538 | + | |
539 | + cairo_t *cr = cairo_create(surface); | |
540 | + v3270_redraw(terminal, cr, width, height); | |
541 | + cairo_destroy (cr); | |
542 | + | |
543 | + GdkPixbuf * pixbuf = gdk_pixbuf_get_from_surface(surface,0,0,width,height); | |
544 | + | |
545 | + cairo_surface_destroy (surface); | |
546 | + | |
547 | + return pixbuf; | |
548 | +} | |
549 | + | |
527 | 550 | void v3270_update_char(H3270 *session, int addr, unsigned char chr, unsigned short attr, unsigned char cursor) |
528 | 551 | { |
529 | 552 | v3270 * terminal = GTK_V3270(lib3270_get_user_data(session)); | ... | ... |
v3270.cbp
... | ... | @@ -6,6 +6,7 @@ |
6 | 6 | <Option makefile_is_custom="1" /> |
7 | 7 | <Option pch_mode="2" /> |
8 | 8 | <Option compiler="gcc" /> |
9 | + <Option virtualFolders="src/selection/" /> | |
9 | 10 | <Build> |
10 | 11 | <Target title="Debug"> |
11 | 12 | <Option output=".bin/Debug/libv3270" prefix_auto="1" extension_auto="1" /> |
... | ... | @@ -213,6 +214,7 @@ |
213 | 214 | </Unit> |
214 | 215 | <Unit filename="src/selection/linux/copy.c"> |
215 | 216 | <Option compilerVar="CC" /> |
217 | + <Option virtualFolder="src/selection/" /> | |
216 | 218 | </Unit> |
217 | 219 | <Unit filename="src/selection/linux/paste.c"> |
218 | 220 | <Option compilerVar="CC" /> |
... | ... | @@ -417,9 +419,6 @@ |
417 | 419 | <Option compilerVar="CC" /> |
418 | 420 | </Unit> |
419 | 421 | <Extensions> |
420 | - <code_completion /> | |
421 | - <envvars /> | |
422 | - <debugger /> | |
423 | 422 | <lib_finder disable_auto="1" /> |
424 | 423 | </Extensions> |
425 | 424 | </Project> | ... | ... |