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