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,22 +91,6 @@ | ||
| 91 | #ifdef WIN32 | 91 | #ifdef WIN32 |
| 92 | static void icon_press(GtkEntry G_GNUC_UNUSED(*entry), G_GNUC_UNUSED GtkEntryIconPosition icon_pos, G_GNUC_UNUSED GdkEvent *event, V3270SaveDialog *widget) | 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 | g_autofree gchar *filename = | 94 | g_autofree gchar *filename = |
| 111 | v3270_select_file( | 95 | v3270_select_file( |
| 112 | GTK_WIDGET(widget), | 96 | GTK_WIDGET(widget), |
| @@ -125,9 +109,6 @@ static void icon_press(GtkEntry G_GNUC_UNUSED(*entry), G_GNUC_UNUSED GtkEntryIco | @@ -125,9 +109,6 @@ static void icon_press(GtkEntry G_GNUC_UNUSED(*entry), G_GNUC_UNUSED GtkEntryIco | ||
| 125 | static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_pos, G_GNUC_UNUSED GdkEvent *event, V3270SaveDialog *widget) | 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 | GtkWidget * dialog = | 112 | GtkWidget * dialog = |
| 132 | gtk_file_chooser_dialog_new( | 113 | gtk_file_chooser_dialog_new( |
| 133 | _( "Select destination file"), | 114 | _( "Select destination file"), |
| @@ -195,16 +176,10 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ | @@ -195,16 +176,10 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ | ||
| 195 | gtk_grid_attach(grid,widget,0,0,1,1); | 176 | gtk_grid_attach(grid,widget,0,0,1,1); |
| 196 | gtk_label_set_mnemonic_widget(GTK_LABEL(widget),dialog->filename); | 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 | gtk_entry_set_icon_activatable(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,TRUE); | 180 | gtk_entry_set_icon_activatable(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,TRUE); |
| 205 | gtk_entry_set_icon_tooltip_text(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,_("Select file")); | 181 | gtk_entry_set_icon_tooltip_text(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,_("Select file")); |
| 206 | g_signal_connect(G_OBJECT(dialog->filename),"icon-press",G_CALLBACK(icon_press),dialog); | 182 | g_signal_connect(G_OBJECT(dialog->filename),"icon-press",G_CALLBACK(icon_press),dialog); |
| 207 | -//#endif // WIN32 | ||
| 208 | 183 | ||
| 209 | gtk_entry_set_width_chars(GTK_ENTRY(dialog->filename),60); | 184 | gtk_entry_set_width_chars(GTK_ENTRY(dialog->filename),60); |
| 210 | gtk_entry_set_max_length(GTK_ENTRY(dialog->filename),PATH_MAX); | 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,7 +215,7 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ | ||
| 240 | { | 215 | { |
| 241 | gtk_combo_box_text_insert( | 216 | gtk_combo_box_text_insert( |
| 242 | GTK_COMBO_BOX_TEXT(dialog->format), | 217 | GTK_COMBO_BOX_TEXT(dialog->format), |
| 243 | - ix, | 218 | + -1, |
| 244 | formats[ix].extension, | 219 | formats[ix].extension, |
| 245 | g_dgettext(GETTEXT_PACKAGE,formats[ix].name) | 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,6 +223,26 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ | ||
| 248 | 223 | ||
| 249 | gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->format),0); | 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,20 +330,38 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ | ||
| 335 | return GTK_WIDGET(dialog); | 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 | // Get selection | 359 | // Get selection |
| 349 | GList * dynamic = NULL; | 360 | GList * dynamic = NULL; |
| 350 | const GList * selection = NULL; | 361 | const GList * selection = NULL; |
| 351 | 362 | ||
| 363 | + debug("%s",__FUNCTION__); | ||
| 364 | + | ||
| 352 | switch(dialog->mode) | 365 | switch(dialog->mode) |
| 353 | { | 366 | { |
| 354 | case LIB3270_CONTENT_ALL: | 367 | case LIB3270_CONTENT_ALL: |
| @@ -382,7 +395,7 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ | @@ -382,7 +395,7 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ | ||
| 382 | 395 | ||
| 383 | debug("Encoding: %s",encoding); | 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 | case 0: // "Plain text" | 400 | case 0: // "Plain text" |
| 388 | text = v3270_get_selection_as_text(GTK_V3270(dialog->terminal), selection, encoding, dialog->mode == LIB3270_CONTENT_ALL); | 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,25 +415,9 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ | ||
| 402 | 415 | ||
| 403 | if(text) | 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 | g_file_set_contents( | 422 | g_file_set_contents( |
| 426 | gtk_entry_get_text(GTK_ENTRY(dialog->filename)), | 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,6 +442,56 @@ static void icon_press(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_ | ||
| 445 | #pragma GCC diagnostic pop | 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 | void v3270_save_dialog_run(GtkWidget *widget) | 495 | void v3270_save_dialog_run(GtkWidget *widget) |
| 449 | { | 496 | { |
| 450 | if(gtk_dialog_run(GTK_DIALOG(widget)) == GTK_RESPONSE_APPLY) | 497 | if(gtk_dialog_run(GTK_DIALOG(widget)) == GTK_RESPONSE_APPLY) |
src/include/terminal.h
| @@ -256,6 +256,7 @@ G_BEGIN_DECLS | @@ -256,6 +256,7 @@ G_BEGIN_DECLS | ||
| 256 | }; | 256 | }; |
| 257 | 257 | ||
| 258 | G_GNUC_INTERNAL void v3270_activate(GtkWidget *widget); | 258 | G_GNUC_INTERNAL void v3270_activate(GtkWidget *widget); |
| 259 | + G_GNUC_INTERNAL GdkPixbuf * v3270_get_as_pixbuf(GtkWidget *widget); | ||
| 259 | 260 | ||
| 260 | /*--[ Globals ]--------------------------------------------------------------------------------------*/ | 261 | /*--[ Globals ]--------------------------------------------------------------------------------------*/ |
| 261 | 262 |
src/terminal/drawing/draw.c
| @@ -524,6 +524,29 @@ LIB3270_EXPORT void v3270_reload(GtkWidget *widget) | @@ -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 | void v3270_update_char(H3270 *session, int addr, unsigned char chr, unsigned short attr, unsigned char cursor) | 550 | void v3270_update_char(H3270 *session, int addr, unsigned char chr, unsigned short attr, unsigned char cursor) |
| 528 | { | 551 | { |
| 529 | v3270 * terminal = GTK_V3270(lib3270_get_user_data(session)); | 552 | v3270 * terminal = GTK_V3270(lib3270_get_user_data(session)); |
v3270.cbp
| @@ -6,6 +6,7 @@ | @@ -6,6 +6,7 @@ | ||
| 6 | <Option makefile_is_custom="1" /> | 6 | <Option makefile_is_custom="1" /> |
| 7 | <Option pch_mode="2" /> | 7 | <Option pch_mode="2" /> |
| 8 | <Option compiler="gcc" /> | 8 | <Option compiler="gcc" /> |
| 9 | + <Option virtualFolders="src/selection/" /> | ||
| 9 | <Build> | 10 | <Build> |
| 10 | <Target title="Debug"> | 11 | <Target title="Debug"> |
| 11 | <Option output=".bin/Debug/libv3270" prefix_auto="1" extension_auto="1" /> | 12 | <Option output=".bin/Debug/libv3270" prefix_auto="1" extension_auto="1" /> |
| @@ -213,6 +214,7 @@ | @@ -213,6 +214,7 @@ | ||
| 213 | </Unit> | 214 | </Unit> |
| 214 | <Unit filename="src/selection/linux/copy.c"> | 215 | <Unit filename="src/selection/linux/copy.c"> |
| 215 | <Option compilerVar="CC" /> | 216 | <Option compilerVar="CC" /> |
| 217 | + <Option virtualFolder="src/selection/" /> | ||
| 216 | </Unit> | 218 | </Unit> |
| 217 | <Unit filename="src/selection/linux/paste.c"> | 219 | <Unit filename="src/selection/linux/paste.c"> |
| 218 | <Option compilerVar="CC" /> | 220 | <Option compilerVar="CC" /> |
| @@ -417,9 +419,6 @@ | @@ -417,9 +419,6 @@ | ||
| 417 | <Option compilerVar="CC" /> | 419 | <Option compilerVar="CC" /> |
| 418 | </Unit> | 420 | </Unit> |
| 419 | <Extensions> | 421 | <Extensions> |
| 420 | - <code_completion /> | ||
| 421 | - <envvars /> | ||
| 422 | - <debugger /> | ||
| 423 | <lib_finder disable_auto="1" /> | 422 | <lib_finder disable_auto="1" /> |
| 424 | </Extensions> | 423 | </Extensions> |
| 425 | </Project> | 424 | </Project> |