Commit 41799dd497c2d614f5c46f8880dd6ee91c7dd276

Authored by Perry Werneck
1 parent 05f44824
Exists in master and in 1 other branch develop

Adding option to save terminal as image.

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));
@@ -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>