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