From d6e1a58bda6ef2dc2d3a6032fea33a19cfd06c73 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Mon, 29 Jul 2019 10:58:50 -0300 Subject: [PATCH] Working in the new "save" dialog. --- src/dialogs/save/private.h | 2 ++ src/dialogs/save/save.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------- src/include/clipboard.h | 13 +++++++++---- src/selection/html.c | 28 ++++++++++++++-------------- src/selection/linux/copy.c | 6 +++--- src/selection/table.c | 32 ++++++++++++++++++-------------- src/selection/text.c | 23 +++++++++++------------ 7 files changed, 220 insertions(+), 81 deletions(-) diff --git a/src/dialogs/save/private.h b/src/dialogs/save/private.h index e2687e2..d7353e6 100644 --- a/src/dialogs/save/private.h +++ b/src/dialogs/save/private.h @@ -41,6 +41,8 @@ GtkWidget * terminal; GtkWidget * filename; + GtkWidget * charset; + GtkWidget * format; LIB3270_CONTENT_OPTION mode; }; diff --git a/src/dialogs/save/save.c b/src/dialogs/save/save.c index 953a6e1..7795777 100644 --- a/src/dialogs/save/save.c +++ b/src/dialogs/save/save.c @@ -35,6 +35,28 @@ G_DEFINE_TYPE(V3270SaveDialog, V3270SaveDialog, GTK_TYPE_DIALOG); +/*--[ Formats ]--------------------------------------------------------------------------------------*/ + + static const struct _formats + { + const gchar *name; + const gchar *extension; + } formats[] = + { + { + N_("Plain text"), + ".txt" + }, + { + N_("Comma-separated values (CSV)"), + ".csv" + }, + { + N_("HyperText Markup Language (HTML)"), + ".html" + } + }; + /*--[ Implement ]------------------------------------------------------------------------------------*/ /* @@ -44,7 +66,7 @@ } */ - static void V3270SaveDialog_class_init(V3270SaveDialogClass *klass) + static void V3270SaveDialog_class_init(V3270SaveDialogClass G_GNUC_UNUSED(*klass)) { debug("%s",__FUNCTION__); @@ -64,6 +86,11 @@ static void V3270SaveDialog_init(V3270SaveDialog *dialog) { + // 0--------1---------------------2-------3------------------ + // 0 - Filename xxxxxxxxx.xxxxxxxxx.xxxxxxxxx.xxxxxxxxx.xxxxxxxxx. + // 1 - Charset xxxxxxxxx.xxxxxxxxx. Format: xxxxxxxxx.xxxxxxxxx. + + dialog->mode = LIB3270_CONTENT_ALL; gtk_window_set_deletable(GTK_WINDOW(dialog),FALSE); @@ -82,57 +109,159 @@ gtk_grid_set_column_spacing(GTK_GRID(grid),12); gtk_box_pack_start(box,GTK_WIDGET(grid),TRUE,TRUE,2); - dialog->filename = gtk_entry_new(); - gtk_widget_set_hexpand(GTK_WIDGET(dialog->filename),TRUE); + // Filename entry + { + dialog->filename = gtk_entry_new(); + gtk_widget_set_hexpand(GTK_WIDGET(dialog->filename),TRUE); - widget = gtk_label_new_with_mnemonic("_Filename:"); - gtk_widget_set_halign(widget,GTK_ALIGN_END); - gtk_widget_set_valign(widget,GTK_ALIGN_CENTER); - gtk_grid_attach(grid,GTK_WIDGET(widget),0,0,1,1); - gtk_label_set_mnemonic_widget(GTK_LABEL(widget),dialog->filename); + widget = gtk_label_new_with_mnemonic(_("_Filename")); + gtk_widget_set_halign(widget,GTK_ALIGN_END); + gtk_widget_set_valign(widget,GTK_ALIGN_CENTER); + gtk_grid_attach(grid,widget,0,0,1,1); + gtk_label_set_mnemonic_widget(GTK_LABEL(widget),dialog->filename); #ifdef WIN32 - widget = gtk_button_new_from_icon_name("document-open",GTK_ICON_SIZE_BUTTON); - //g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(select_local_file),dialog); - gtk_grid_attach(grid,widget,2,0,1,1); + widget = gtk_button_new_from_icon_name("document-open",GTK_ICON_SIZE_BUTTON); + //g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(select_local_file),dialog); + gtk_grid_attach(grid,widget,6,0,1,1); #else - gtk_entry_set_icon_from_icon_name(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,"document-open"); - gtk_entry_set_icon_activatable(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,TRUE); - gtk_entry_set_icon_tooltip_text(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,_("Select file")); - // g_signal_connect(G_OBJECT(dialog->filename),"icon-press",G_CALLBACK(icon_press),dialog); + gtk_entry_set_icon_from_icon_name(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,"document-open"); + gtk_entry_set_icon_activatable(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,TRUE); + gtk_entry_set_icon_tooltip_text(GTK_ENTRY(dialog->filename),GTK_ENTRY_ICON_SECONDARY,_("Select file")); + // g_signal_connect(G_OBJECT(dialog->filename),"icon-press",G_CALLBACK(icon_press),dialog); #endif // WIN32 - gtk_entry_set_width_chars(GTK_ENTRY(dialog->filename),60); - gtk_entry_set_max_length(GTK_ENTRY(dialog->filename),PATH_MAX); - gtk_grid_attach(grid,GTK_WIDGET(dialog->filename),1,0,1,1); + gtk_entry_set_width_chars(GTK_ENTRY(dialog->filename),60); + gtk_entry_set_max_length(GTK_ENTRY(dialog->filename),PATH_MAX); + gtk_grid_attach(grid,GTK_WIDGET(dialog->filename),1,0,3,1); + } + + // Charset drop-down + { + static const struct _charsets + { + const gchar *name; + const gchar *description; + } charsets[] = + { + // http://en.wikipedia.org/wiki/Character_encoding + { "UTF-8", N_( "UTF-8" ) }, + { "ISO-8859-1", N_( "Western Europe (ISO 8859-1)" ) }, + { "CP1252", N_( "Windows Western languages (CP1252)" ) }, + }; + + size_t ix; + const gchar * scharset = NULL; + + widget = gtk_label_new_with_mnemonic (_("C_haracter Coding")); + gtk_widget_set_halign(widget,GTK_ALIGN_END); + gtk_widget_set_valign(widget,GTK_ALIGN_CENTER); + gtk_grid_attach(grid,widget,0,1,1,1); + + dialog->charset = gtk_combo_box_text_new(); + + g_get_charset(&scharset); + + g_autofree gchar * text = g_strdup_printf(_("Current (%s)"),scharset); + gtk_combo_box_text_insert( + GTK_COMBO_BOX_TEXT(dialog->charset), + 0, + scharset, + text + ); + + gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->charset),0); + + gtk_grid_attach(grid,dialog->charset,1,1,1,1); + + for(ix=0;ixcharset), + ix+1, + charsets[ix].name, + gettext(charsets[ix].description) + ); + } + } + + } + + // Format drop-down + { + size_t ix; + + widget = gtk_label_new_with_mnemonic (_("File _Format")); + gtk_widget_set_halign(widget,GTK_ALIGN_END); + gtk_widget_set_valign(widget,GTK_ALIGN_CENTER); + gtk_grid_attach(grid,widget,2,1,1,1); + + dialog->format = gtk_combo_box_text_new(); + gtk_grid_attach(grid,dialog->format,3,1,1,1); + + for(ix=0;ixformat), + ix, + formats[ix].extension, + gettext(formats[ix].name) + ); + } + + gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->format),0); + + } + // Buttons // https://developer.gnome.org/icon-naming-spec/ #if GTK_CHECK_VERSION(3,14,0) - widget = gtk_dialog_get_header_bar(GTK_DIALOG(dialog)); - - button = gtk_button_new_with_mnemonic(_("_Cancel")); - gtk_widget_set_tooltip_markup(button,_("Click to cancel operation")); - gtk_header_bar_pack_start(GTK_HEADER_BAR(widget),button); - g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cancel_operation),dialog); - - button = gtk_button_new_with_mnemonic(_("_Save")); - gtk_widget_set_tooltip_markup(button,_("Click to save file")); - gtk_header_bar_pack_end(GTK_HEADER_BAR(widget),button); - g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(apply_operation),dialog); - #else - - #error TODO! - + widget = NULL; #endif // GTK(3,14,0) + if(widget) + { + // Have header bar + button = gtk_button_new_with_mnemonic(_("_Cancel")); + gtk_widget_set_tooltip_markup(button,_("Click to cancel operation")); + gtk_header_bar_pack_start(GTK_HEADER_BAR(widget),button); + g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cancel_operation),dialog); + + button = gtk_button_new_with_mnemonic(_("_Save")); + gtk_widget_set_tooltip_markup(button,_("Click to save file")); + gtk_header_bar_pack_end(GTK_HEADER_BAR(widget),button); + g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(apply_operation),dialog); + } + else + { + gtk_dialog_add_buttons( + GTK_DIALOG (dialog), + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Save"), GTK_RESPONSE_APPLY, + NULL + ); + } + } GtkWidget * v3270_save_dialog_new(GtkWidget *widget, LIB3270_CONTENT_OPTION mode, const gchar *filename) { - V3270SaveDialog * dialog = V3270_SAVE_DIALOG(g_object_new(GTK_TYPE_V3270SaveDialog,"use-header-bar", (gint) 1, NULL)); + gboolean use_header; + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL); + + // Create dialog + V3270SaveDialog * dialog = V3270_SAVE_DIALOG( + g_object_new( + GTK_TYPE_V3270SaveDialog, + "use-header-bar", (use_header ? 1 : 0), + NULL) + ); + dialog->mode = mode; if(filename) diff --git a/src/include/clipboard.h b/src/include/clipboard.h index 8bd3b4a..203a456 100644 --- a/src/include/clipboard.h +++ b/src/include/clipboard.h @@ -87,12 +87,17 @@ G_GNUC_INTERNAL void v3270_update_system_clipboard(GtkWidget *widget); G_GNUC_INTERNAL const char * v3270_update_selected_text(GtkWidget *widget, gboolean cut); - G_GNUC_INTERNAL GList * v3270_getColumns_from_selection(v3270 * terminal); + G_GNUC_INTERNAL GList * v3270_getColumns_from_selection(v3270 * terminal, const GList *selection); /// @brief Get contents. - G_GNUC_INTERNAL gchar * v3270_get_copy_as_text(v3270 * terminal); - G_GNUC_INTERNAL gchar * v3270_get_copy_as_html(v3270 * terminal); - G_GNUC_INTERNAL gchar * v3270_get_copy_as_table(v3270 * terminal, const gchar *delimiter); + G_GNUC_INTERNAL gchar * v3270_get_selection_as_text(v3270 * terminal, const GList *selection, const gchar *encoding); + G_GNUC_INTERNAL gchar * v3270_get_selection_as_table(v3270 * terminal, const GList *selection, const gchar *delimiter, const gchar *encoding); + + + + G_GNUC_INTERNAL gchar * v3270_get_copy_as_text(v3270 * terminal, const gchar *encoding); + G_GNUC_INTERNAL gchar * v3270_get_copy_as_html(v3270 * terminal, const gchar *encoding); + G_GNUC_INTERNAL gchar * v3270_get_copy_as_table(v3270 * terminal, const gchar *delimiter, const gchar *encoding); G_GNUC_INTERNAL gchar * v3270_get_copy_as_data_block(v3270 * terminal); /// @brief Set contents. diff --git a/src/selection/html.c b/src/selection/html.c index 3e6bcc3..d65f48a 100644 --- a/src/selection/html.c +++ b/src/selection/html.c @@ -49,12 +49,12 @@ static void get_element_colors(v3270 * terminal, unsigned short attr, gchar **fg } /// @brief Get formatted contents as HTML DIV. -static gchar * get_as_div(v3270 * terminal) +static gchar * get_as_div(v3270 * terminal, const GList *selection) { - GList * element = terminal->selection.blocks; - GString * string = g_string_new(""); - gchar * bgColor = gdk_rgba_to_string(terminal->color+V3270_COLOR_BACKGROUND); - gchar * fgColor; + const GList * element = selection; + GString * string = g_string_new(""); + gchar * bgColor = gdk_rgba_to_string(terminal->color+V3270_COLOR_BACKGROUND); + gchar * fgColor; g_string_append_printf( string, @@ -67,7 +67,7 @@ static gchar * get_as_div(v3270 * terminal) while(element) { - lib3270_selection * block = ((lib3270_selection *) element->data); + const lib3270_selection * block = ((const lib3270_selection *) element->data); unsigned int row, col, src = 0; unsigned short flags = block->contents[0].attribute.visual; @@ -144,9 +144,9 @@ static gchar * get_as_div(v3270 * terminal) } /// @brief Get formatted contents as HTML TABLE. -static gchar * get_as_table(v3270 * terminal) +static gchar * get_as_table(v3270 * terminal, const GList *selection) { - GList * element = terminal->selection.blocks; + const GList * element = selection; GString * string = g_string_new(""); unsigned int width = lib3270_get_width(terminal->host); @@ -155,11 +155,11 @@ static gchar * get_as_table(v3270 * terminal) GList * column; // Get contents - GList * columns = v3270_getColumns_from_selection(terminal); + GList * columns = v3270_getColumns_from_selection(terminal, selection); while(element) { - lib3270_selection * block = ((lib3270_selection *) element->data); + const lib3270_selection * block = ((const lib3270_selection *) element->data); unsigned int row, col, src = 0; @@ -214,14 +214,14 @@ static gchar * get_as_table(v3270 * terminal) } -gchar * v3270_get_copy_as_html(v3270 * terminal) +gchar * v3270_get_copy_as_html(v3270 * terminal, const gchar *encoding) { g_autofree char * text = NULL; if(terminal->selection.format == V3270_SELECT_TABLE) - text = get_as_table(terminal); + text = get_as_table(terminal, terminal->selection.blocks); else - text = get_as_div(terminal); + text = get_as_div(terminal, terminal->selection.blocks); - return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL); + return g_convert(text, -1, (encoding ? encoding : "UTF-8"), lib3270_get_display_charset(terminal->host), NULL, NULL, NULL); } diff --git a/src/selection/linux/copy.c b/src/selection/linux/copy.c index 045ee10..c1ee344 100644 --- a/src/selection/linux/copy.c +++ b/src/selection/linux/copy.c @@ -57,14 +57,14 @@ static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionDa { case CLIPBOARD_TYPE_TEXT: // Get clipboard contents as text { - g_autofree gchar *text = v3270_get_copy_as_text(terminal); + g_autofree gchar *text = v3270_get_copy_as_text(terminal,"UTF-8"); gtk_selection_data_set_text(selection,text,-1); } break; case CLIPBOARD_TYPE_CSV: { - g_autofree gchar *text = v3270_get_copy_as_table(terminal,";"); + g_autofree gchar *text = v3270_get_copy_as_table(terminal,";","UTF-8"); debug("Selection:\n%s",text); gtk_selection_data_set( selection, @@ -78,7 +78,7 @@ static void clipboard_get(G_GNUC_UNUSED GtkClipboard *clipboard, GtkSelectionDa case CLIPBOARD_TYPE_HTML: { - g_autofree gchar *text = v3270_get_copy_as_html(terminal); + g_autofree gchar *text = v3270_get_copy_as_html(terminal,"UTF-8"); //debug("Selection:\n%s",text); gtk_selection_data_set( selection, diff --git a/src/selection/table.c b/src/selection/table.c index 59fa874..e133ddc 100644 --- a/src/selection/table.c +++ b/src/selection/table.c @@ -34,13 +34,11 @@ /*--[ Implement ]------------------------------------------------------------------------------------*/ /// @brief Check if column has data. -static gboolean hasDataOnColumn(v3270 * terminal, unsigned int col) +static gboolean hasDataOnColumn(v3270 * terminal, unsigned int col, const GList *selection) { - GList * element = terminal->selection.blocks; - - while(element) + while(selection) { - lib3270_selection * block = ((lib3270_selection *) element->data); + const lib3270_selection * block = ((const lib3270_selection *) selection->data); if( (col >= block->bounds.col) && ( col < (block->bounds.col + block->bounds.width)) ) { @@ -58,14 +56,14 @@ static gboolean hasDataOnColumn(v3270 * terminal, unsigned int col) } - element = g_list_next(element); + selection = g_list_next(selection); } return FALSE; } /// @brief Get column list. -GList * v3270_getColumns_from_selection(v3270 * terminal) +GList * v3270_getColumns_from_selection(v3270 * terminal, const GList *selection) { unsigned int col = 0; GList *rc = NULL; @@ -75,7 +73,7 @@ GList * v3270_getColumns_from_selection(v3270 * terminal) // debug("col(%u): %s", col, hasDataOnColumn(terminal,col) ? "yes" : "no"); // Get first column. - while(!hasDataOnColumn(terminal,col)) { + while(!hasDataOnColumn(terminal,col,selection)) { if(col >= lib3270_get_width(terminal->host)) return rc; col++; @@ -87,7 +85,7 @@ GList * v3270_getColumns_from_selection(v3270 * terminal) rc = g_list_append(rc,columndescription); // Get width. - while(hasDataOnColumn(terminal,col++)) { + while(hasDataOnColumn(terminal,col++,selection)) { columndescription->width++; if(col >= lib3270_get_width(terminal->host)) return rc; @@ -98,12 +96,11 @@ GList * v3270_getColumns_from_selection(v3270 * terminal) } -/// @brief Get formatted contents as single text. -gchar * v3270_get_copy_as_table(v3270 * terminal, const gchar *delimiter) +gchar * v3270_get_selection_as_table(v3270 * terminal, const GList *selection, const gchar *delimiter, const gchar *encoding) { GString * string = g_string_new(""); - GList * columns = v3270_getColumns_from_selection(terminal); + GList * columns = v3270_getColumns_from_selection(terminal, selection); debug("columns=%p",columns); @@ -121,7 +118,7 @@ gchar * v3270_get_copy_as_table(v3270 * terminal, const gchar *delimiter) } #endif // DEBUG - GList * element = terminal->selection.blocks; + GList * element = selection; unsigned int width = lib3270_get_width(terminal->host); g_autofree gchar * line = g_malloc0(width+1); GList * column; @@ -167,5 +164,12 @@ gchar * v3270_get_copy_as_table(v3270 * terminal, const gchar *delimiter) g_list_free_full(columns,g_free); g_autofree char * text = g_string_free(string,FALSE); - return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL); + return g_convert(text, -1, (encoding ? encoding : "UTF-8"), lib3270_get_display_charset(terminal->host), NULL, NULL, NULL); } + +/// @brief Get formatted contents as single text. +gchar * v3270_get_copy_as_table(v3270 * terminal, const gchar *delimiter, const gchar *encoding) +{ + return v3270_get_selection_as_table(terminal, terminal->selection.blocks, delimiter, encoding); +} + diff --git a/src/selection/text.c b/src/selection/text.c index 115211c..b9a1102 100644 --- a/src/selection/text.c +++ b/src/selection/text.c @@ -33,14 +33,13 @@ /*--[ Implement ]------------------------------------------------------------------------------------*/ /// @brief Get formatted contents as single text. -static gchar * get_as_text(v3270 * terminal) +gchar * v3270_get_selection_as_text(v3270 * terminal, const GList *selection, const gchar *encoding) { - GList * element = terminal->selection.blocks; - GString * string = g_string_new(""); + GString * string = g_string_new(""); - while(element) + while(selection) { - lib3270_selection * block = ((lib3270_selection *) element->data); + lib3270_selection * block = ((lib3270_selection *) selection->data); unsigned int row, col, src = 0; for(row=0; row < block->bounds.height; row++) @@ -56,20 +55,20 @@ static gchar * get_as_text(v3270 * terminal) g_string_append_c(string,'\n'); } - element = g_list_next(element); + selection = g_list_next(selection); } g_autofree char * text = g_string_free(string,FALSE); - return g_convert(text, -1, "UTF-8", lib3270_get_display_charset(terminal->host), NULL, NULL, NULL); + + return g_convert(text, -1, (encoding ? encoding : "UTF-8"), lib3270_get_display_charset(terminal->host), NULL, NULL, NULL); } -gchar * v3270_get_copy_as_text(v3270 * terminal) +gchar * v3270_get_copy_as_text(v3270 * terminal, const gchar *encoding) { if(terminal->selection.format == V3270_SELECT_TABLE) - return v3270_get_copy_as_table(terminal,"\t"); - - return get_as_text(terminal); + return v3270_get_copy_as_table(terminal,"\t",encoding); + return v3270_get_selection_as_text(terminal, terminal->selection.blocks, encoding); } LIB3270_EXPORT void v3270_input_text(GtkWidget *widget, const gchar *text, const gchar *encoding) @@ -205,6 +204,6 @@ LIB3270_EXPORT void v3270_input_text(GtkWidget *widget, const gchar *text, const LIB3270_EXPORT gchar * v3270_get_copy(GtkWidget *widget) { g_return_val_if_fail(GTK_IS_V3270(widget),NULL); - return v3270_get_copy_as_text(GTK_V3270(widget)); + return v3270_get_copy_as_text(GTK_V3270(widget),NULL); } -- libgit2 0.21.2