Commit 820c86c26cd7812f410c7a70067b9e7e7d5433c6

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

Small adjustments in the trace window.

src/include/v3270.h
... ... @@ -165,7 +165,6 @@
165 165 #endif // v3270_char
166 166  
167 167 LIB3270_EXPORT GtkWidget * v3270_new(void);
168   - LIB3270_EXPORT GtkWidget * v3270_trace_window_new(GtkWidget *widget, const gchar *header);
169 168 LIB3270_EXPORT GType v3270_get_type(void);
170 169 LIB3270_EXPORT void v3270_reload(GtkWidget * widget);
171 170 LIB3270_EXPORT void v3270_set_font_family(GtkWidget *widget, const gchar *name);
... ...
src/include/v3270/trace.h
... ... @@ -55,6 +55,8 @@
55 55 LIB3270_EXPORT void v3270_trace_save(GtkWidget *widget);
56 56 LIB3270_EXPORT void v3270_trace_select_file(GtkWidget *widget);
57 57  
  58 + LIB3270_EXPORT GtkWidget * v3270_trace_window_new(GtkWidget *widget, const gchar *header);
  59 +
58 60 G_END_DECLS
59 61  
60 62 #endif // V3270_H_INCLUDED
... ...
src/testprogram/testprogram.c
... ... @@ -67,9 +67,12 @@
67 67 }
68 68  
69 69 // Create trace window
  70 + /*
70 71 {
71 72 gtk_notebook_append_page(GTK_NOTEBOOK(notebook),v3270_trace_new(terminal),gtk_label_new("Trace"));
72 73 }
  74 + */
  75 + v3270_trace_window_new(terminal,NULL);
73 76  
74 77 // Setup and show main window
75 78 gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
... ...
src/trace/trace.c 0 → 100644
... ... @@ -0,0 +1,485 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como trace.c e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +/**
  31 + * SECTION:V3270Trace
  32 + * @Short_description: A trace monitor widget.
  33 + * @Title: V3270Trace
  34 + *
  35 + * The #V3270Trace shows a text area with the lib3270 trace output.
  36 + *
  37 + */
  38 +
  39 + #include <gtk/gtk.h>
  40 +
  41 + #define ENABLE_NLS
  42 + #define GETTEXT_PACKAGE PACKAGE_NAME
  43 +
  44 + #include <libintl.h>
  45 + #include <glib/gi18n.h>
  46 +
  47 + #include <v3270.h>
  48 + #include <lib3270.h>
  49 + #include <lib3270/log.h>
  50 + #include <lib3270/trace.h>
  51 + #include <lib3270/properties.h>
  52 + #include <v3270/trace.h>
  53 + #include <internals.h>
  54 +
  55 +#if defined( HAVE_SYSLOG )
  56 + #include <syslog.h>
  57 +#endif // HAVE_SYSLOG
  58 +
  59 +/*--[ Widget definition ]----------------------------------------------------------------------------*/
  60 +
  61 + G_BEGIN_DECLS
  62 +
  63 + struct _V3270TraceClass
  64 + {
  65 + GtkBoxClass parent_class;
  66 +
  67 + };
  68 +
  69 + struct _V3270Trace
  70 + {
  71 + GtkBox parent;
  72 + H3270 * hSession; ///< @brief TN3270 Session.
  73 + GtkWidget * terminal; ///< @brief V3270 Widget.
  74 + GtkScrolledWindow * scroll;
  75 +
  76 + GtkTextView * view; ///< @brief Text view;
  77 + GtkTextBuffer * text; ///< @brief Trace window contents.
  78 + GtkEntry * entry; ///< @brief Command line entry.
  79 + GtkWidget * buttons; ///< @brief Button bar.
  80 +
  81 + gchar * filename; ///< @brief Selected file name.
  82 +
  83 + guint log_handler; ///< @brief GTK Log Handler.
  84 +
  85 + /// @brief lib3270's saved trace handler.
  86 + struct {
  87 + void (*handler)(H3270 *session, void *userdata, const char *fmt, va_list args);
  88 + void *userdata;
  89 + } trace;
  90 +
  91 + };
  92 +
  93 + G_END_DECLS
  94 +
  95 + G_DEFINE_TYPE(V3270Trace, V3270Trace, GTK_TYPE_BOX);
  96 +
  97 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  98 +
  99 + static void trace_handler(H3270 *hSession, void *userdata, const char *fmt, va_list args)
  100 + {
  101 + g_autofree gchar *ptr = g_strdup_vprintf(fmt,args);
  102 + g_autofree gchar * utftext = g_convert_with_fallback(ptr,-1,"UTF-8",lib3270_get_display_charset(hSession),"?",NULL,NULL,NULL);
  103 +
  104 + v3270_trace_append_text(GTK_WIDGET(userdata),utftext);
  105 +
  106 + }
  107 +
  108 + static void set_session(V3270Trace *widget, H3270 *hSession)
  109 + {
  110 + // Return if it's the same session.
  111 + if(widget->hSession == hSession)
  112 + return;
  113 +
  114 + debug("%s: Session changes %p -> %p", __FUNCTION__, widget->hSession, hSession);
  115 +
  116 + if(widget->hSession) {
  117 + lib3270_set_trace_handler(widget->hSession,widget->trace.handler,widget->trace.userdata);
  118 + }
  119 +
  120 + widget->hSession = hSession;
  121 +
  122 + if(hSession) {
  123 + lib3270_get_trace_handler(hSession,&widget->trace.handler,&widget->trace.userdata);
  124 + lib3270_set_trace_handler(hSession,trace_handler,(void *) widget);
  125 + }
  126 +
  127 + }
  128 +
  129 + static void finalize(GObject *object)
  130 + {
  131 + debug("V3270Trace::%s",__FUNCTION__);
  132 +
  133 + V3270Trace *trace = GTK_V3270_TRACE(object);
  134 +
  135 + if(trace->filename)
  136 + {
  137 + g_free(trace->filename);
  138 + trace->filename = NULL;
  139 + }
  140 +
  141 + if(trace->log_handler)
  142 + {
  143 + g_log_remove_handler(NULL,trace->log_handler);
  144 + trace->log_handler = 0;
  145 + }
  146 +
  147 + set_session(trace,NULL);
  148 + g_clear_object(&trace->terminal);
  149 +
  150 + G_OBJECT_CLASS(V3270Trace_parent_class)->finalize(object);
  151 + }
  152 +
  153 + static void V3270Trace_class_init(G_GNUC_UNUSED V3270TraceClass *klass)
  154 + {
  155 + G_OBJECT_CLASS(klass)->finalize = finalize;
  156 + }
  157 +
  158 + static void v3270_trace_execute(GtkWidget *widget, const gchar *cmd)
  159 + {
  160 + if(!*cmd)
  161 + return;
  162 +
  163 + v3270_trace_printf(widget, "%s\n",cmd);
  164 +
  165 + V3270Trace *trace = GTK_V3270_TRACE(widget);
  166 +
  167 + if(trace->terminal)
  168 + {
  169 + int rc = v3270_exec_command(trace->terminal,cmd);
  170 + if(rc)
  171 + v3270_trace_printf(widget, "rc=%d (%s)\n",rc,strerror(rc));
  172 + }
  173 + else
  174 + {
  175 + v3270_trace_append_text(widget, "Can't execute command without an associated terminal");
  176 + }
  177 +
  178 + gtk_entry_set_text(trace->entry, "");
  179 +
  180 + }
  181 +
  182 + static void execute_command(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_pos, G_GNUC_UNUSED GdkEvent *event, GtkWidget *widget)
  183 + {
  184 + v3270_trace_execute(widget, gtk_entry_get_text(entry));
  185 + }
  186 +
  187 + static void entry_activated(GtkEntry *entry, GtkWidget *widget)
  188 + {
  189 + v3270_trace_execute(widget, gtk_entry_get_text(entry));
  190 + }
  191 +
  192 + static void log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, GtkWidget *widget)
  193 + {
  194 + #ifndef LOG_INFO
  195 + #define LOG_INFO 0
  196 + #endif // LOG_INFO
  197 +
  198 + #ifndef LOG_ERR
  199 + #define LOG_ERR 0
  200 + #endif // LOG_ERR
  201 +
  202 + #ifndef LOG_DEBUG
  203 + #define LOG_DEBUG 0
  204 + #endif // LOG_DEBUG
  205 +
  206 + static const struct _logtype
  207 + {
  208 + GLogLevelFlags log_level;
  209 + const gchar * msg;
  210 + } logtype[] =
  211 + {
  212 + { G_LOG_FLAG_RECURSION, "recursion" },
  213 + { G_LOG_FLAG_FATAL, "fatal error" },
  214 +
  215 + /* GLib log levels */
  216 + { G_LOG_LEVEL_ERROR, "error" },
  217 + { G_LOG_LEVEL_CRITICAL, "critical error" },
  218 + { G_LOG_LEVEL_WARNING, "warning" },
  219 + { G_LOG_LEVEL_MESSAGE, "message" },
  220 + { G_LOG_LEVEL_INFO, "info" },
  221 + { G_LOG_LEVEL_DEBUG, "debug" },
  222 + };
  223 +
  224 + size_t f;
  225 +
  226 + for(f=0;f<G_N_ELEMENTS(logtype);f++)
  227 + {
  228 + if(logtype[f].log_level == log_level)
  229 + {
  230 + g_autofree gchar *text = g_strdup_printf("%s: %s %s",logtype[f].msg,log_domain ? log_domain : "",message);
  231 +
  232 + gchar *ptr;
  233 + for(ptr = text;*ptr;ptr++)
  234 + {
  235 + if(*ptr < ' ')
  236 + *ptr = ' ';
  237 + }
  238 +
  239 + v3270_trace_printf(widget,"%s\n",text);
  240 +
  241 + return;
  242 + }
  243 + }
  244 +
  245 + v3270_trace_printf(widget,"%s %s\n",log_domain ? log_domain : "", message);
  246 +
  247 + }
  248 +
  249 + static void V3270Trace_init(V3270Trace *widget)
  250 + {
  251 + gtk_orientable_set_orientation(GTK_ORIENTABLE(widget),GTK_ORIENTATION_VERTICAL);
  252 +
  253 + // Create toolbar
  254 + {
  255 + widget->buttons = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
  256 +
  257 + gtk_button_box_set_layout(GTK_BUTTON_BOX(widget->buttons), GTK_BUTTONBOX_START);
  258 + gtk_box_set_spacing(GTK_BOX(widget->buttons),8);
  259 +
  260 + gtk_widget_set_valign(widget->buttons,GTK_ALIGN_START);
  261 + gtk_box_pack_start(GTK_BOX(widget),widget->buttons,FALSE,FALSE,4);
  262 +
  263 + }
  264 +
  265 + // Create text view
  266 + {
  267 + widget->scroll = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL,NULL));
  268 + gtk_scrolled_window_set_policy(widget->scroll,GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
  269 + gtk_widget_set_vexpand(GTK_WIDGET(widget->scroll),TRUE);
  270 + gtk_widget_set_hexpand(GTK_WIDGET(widget->scroll),TRUE);
  271 +
  272 + gtk_box_pack_start(GTK_BOX(widget),GTK_WIDGET(widget->scroll),TRUE,TRUE,4);
  273 +
  274 + widget->view = GTK_TEXT_VIEW(gtk_text_view_new());
  275 +
  276 +#if GTK_CHECK_VERSION(3,16,0)
  277 + gtk_text_view_set_monospace(widget->view,TRUE);
  278 +#endif // GTK_CHECK_VERSION
  279 +
  280 + widget->text = gtk_text_view_get_buffer(widget->view);
  281 + gtk_text_view_set_editable(widget->view, TRUE);
  282 +
  283 + gtk_container_add(GTK_CONTAINER(widget->scroll),GTK_WIDGET(widget->view));
  284 + gtk_widget_set_can_default(GTK_WIDGET(widget->view),FALSE);
  285 +
  286 + }
  287 +
  288 + // Create command line
  289 + {
  290 + widget->entry = GTK_ENTRY(gtk_entry_new());
  291 +
  292 + gtk_widget_set_can_default(GTK_WIDGET(widget->entry),TRUE);
  293 + gtk_widget_grab_focus(GTK_WIDGET(widget->entry));
  294 +
  295 + gtk_entry_set_activates_default(widget->entry,TRUE);
  296 + gtk_widget_set_vexpand(GTK_WIDGET(widget->entry),FALSE);
  297 + gtk_widget_set_hexpand(GTK_WIDGET(widget->entry),TRUE);
  298 +
  299 + gtk_entry_set_icon_from_icon_name(widget->entry,GTK_ENTRY_ICON_SECONDARY,"system-run");
  300 + gtk_entry_set_placeholder_text(widget->entry,_("Command to execute"));
  301 +
  302 + gtk_box_pack_end(GTK_BOX(widget),GTK_WIDGET(widget->entry),FALSE,FALSE,4);
  303 +
  304 + g_signal_connect(G_OBJECT(widget->entry),"icon-press",G_CALLBACK(execute_command),widget);
  305 + g_signal_connect(G_OBJECT(widget->entry),"activate",G_CALLBACK(entry_activated),widget);
  306 +
  307 + }
  308 +
  309 + // Grab GTK messages.
  310 + widget->log_handler = g_log_set_handler(NULL,G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,(GLogFunc) log_handler, widget);
  311 +
  312 + }
  313 +
  314 +
  315 + LIB3270_EXPORT GtkWidget * v3270_trace_new(GtkWidget *terminal)
  316 + {
  317 + g_return_val_if_fail(GTK_IS_V3270(terminal),NULL);
  318 +
  319 + V3270Trace * widget = GTK_V3270_TRACE(g_object_new(GTK_TYPE_V3270_TRACE, NULL));
  320 +
  321 + // Set terminal widget
  322 + {
  323 + widget->terminal = terminal;
  324 + g_object_ref_sink(G_OBJECT(terminal));
  325 + set_session(widget, v3270_get_session(widget->terminal));
  326 + }
  327 +
  328 + // Create toggle buttons
  329 + {
  330 + size_t ix;
  331 +
  332 + static const LIB3270_TOGGLE toggles[] = { LIB3270_TOGGLE_DS_TRACE, LIB3270_TOGGLE_NETWORK_TRACE, LIB3270_TOGGLE_EVENT_TRACE, LIB3270_TOGGLE_SSL_TRACE, LIB3270_TOGGLE_SCREEN_TRACE};
  333 +
  334 + for(ix = 0; ix < G_N_ELEMENTS(toggles); ix++)
  335 + {
  336 + GtkWidget * item = v3270_toggle_button_new(widget->terminal,toggles[ix]);
  337 +
  338 + gtk_widget_set_can_focus(item,FALSE);
  339 + gtk_widget_set_can_default(item,FALSE);
  340 + gtk_widget_set_focus_on_click(item,FALSE);
  341 +
  342 + gtk_box_pack_start(GTK_BOX(widget->buttons),item,FALSE,FALSE,4);
  343 +
  344 + }
  345 + }
  346 +
  347 +
  348 + return GTK_WIDGET(widget);
  349 + }
  350 +
  351 + struct _append_text
  352 + {
  353 + V3270Trace *widget;
  354 + gchar text[1];
  355 + };
  356 +
  357 + static gboolean bg_append_text(struct _append_text *cfg)
  358 + {
  359 + if(!GTK_IS_TEXT_BUFFER(cfg->widget->text))
  360 + return FALSE;
  361 +
  362 + GtkTextIter itr;
  363 + gtk_text_buffer_get_end_iter(cfg->widget->text,&itr);
  364 +
  365 + if(g_utf8_validate(cfg->text,strlen(cfg->text),NULL))
  366 + {
  367 + gtk_text_buffer_insert(cfg->widget->text,&itr,cfg->text,strlen(cfg->text));
  368 + }
  369 + else
  370 + {
  371 + gtk_text_buffer_insert(cfg->widget->text,&itr,"** Invalid UTF8 String **",-1);
  372 + }
  373 +
  374 + // gtk_text_buffer_get_end_iter(cfg->widget->text,&itr);
  375 + // gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(cfg->widget->view), &itr, 0.0, FALSE, 0.0, 0.0);
  376 +
  377 + GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(cfg->widget->scroll);
  378 + gtk_adjustment_set_value(vadj,gtk_adjustment_get_upper(vadj));
  379 + gtk_scrolled_window_set_vadjustment(cfg->widget->scroll, vadj);
  380 +
  381 + return FALSE;
  382 +
  383 + }
  384 +
  385 + LIB3270_EXPORT void v3270_trace_append_text(GtkWidget *widget, const gchar *text)
  386 + {
  387 + g_return_if_fail(GTK_IS_V3270_TRACE(widget));
  388 +
  389 + // Enqueue update.
  390 + struct _append_text * cfg = g_malloc0(sizeof(struct _append_text)+strlen(text)+1);
  391 + cfg->widget = GTK_V3270_TRACE(widget);
  392 + strcpy(cfg->text,text);
  393 +
  394 + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,(GSourceFunc) bg_append_text, cfg, g_free);
  395 +
  396 + }
  397 +
  398 + LIB3270_EXPORT void v3270_trace_vprintf(GtkWidget *widget, const char *fmt, va_list args)
  399 + {
  400 + g_autofree gchar * text = g_strdup_vprintf(fmt,args);
  401 + v3270_trace_append_text(widget,text);
  402 + }
  403 +
  404 + LIB3270_EXPORT void v3270_trace_printf(GtkWidget *widget, const char *fmt, ... )
  405 + {
  406 + va_list arg_ptr;
  407 + va_start(arg_ptr, fmt);
  408 + v3270_trace_vprintf(widget,fmt,arg_ptr);
  409 + va_end(arg_ptr);
  410 + }
  411 +
  412 + const gchar * v3270_trace_get_filename(GtkWidget *widget)
  413 + {
  414 + g_return_val_if_fail(GTK_IS_V3270_TRACE(widget),NULL);
  415 + return GTK_V3270_TRACE(widget)->filename;
  416 + }
  417 +
  418 + LIB3270_EXPORT void v3270_trace_save(GtkWidget *widget)
  419 + {
  420 + const gchar *filename = v3270_trace_get_filename(widget);
  421 + V3270Trace * trace = GTK_V3270_TRACE(widget);
  422 +
  423 + if(filename)
  424 + {
  425 + GError * error = NULL;
  426 + gchar * text;
  427 + GtkTextIter start;
  428 + GtkTextIter end;
  429 +
  430 + gtk_text_buffer_get_start_iter(trace->text,&start);
  431 + gtk_text_buffer_get_end_iter(trace->text,&end);
  432 + text = gtk_text_buffer_get_text(trace->text,&start,&end,FALSE);
  433 +
  434 + g_file_set_contents(trace->filename,text,-1,&error);
  435 +
  436 + g_free(text);
  437 +
  438 + if(error)
  439 + {
  440 + GtkWidget *popup =
  441 + gtk_message_dialog_new_with_markup(
  442 + GTK_WINDOW(gtk_widget_get_toplevel(widget)),
  443 + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
  444 + GTK_MESSAGE_ERROR,
  445 + GTK_BUTTONS_CLOSE,
  446 + _( "Can't save %s" ),
  447 + filename
  448 + );
  449 +
  450 + gtk_window_set_title(GTK_WINDOW(popup),_("Can't save file"));
  451 +
  452 + gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(popup),"%s",error->message);
  453 + g_error_free(error);
  454 +
  455 + gtk_dialog_run(GTK_DIALOG(popup));
  456 + gtk_widget_destroy(popup);
  457 +
  458 + }
  459 +
  460 + }
  461 +
  462 + }
  463 +
  464 + LIB3270_EXPORT void v3270_trace_select_file(GtkWidget *widget)
  465 + {
  466 + V3270Trace * trace = GTK_V3270_TRACE(widget);
  467 +
  468 + gchar * filename =
  469 + v3270_select_file(
  470 + GTK_WIDGET(trace),
  471 + _("Save trace to file"),
  472 + _("Save"),
  473 + GTK_FILE_CHOOSER_ACTION_SAVE,
  474 + trace->filename,
  475 + N_("Text file"), "*.txt",
  476 + NULL
  477 + );
  478 +
  479 + if(filename) {
  480 + g_free(trace->filename);
  481 + trace->filename = filename;
  482 + v3270_trace_save(widget);
  483 + }
  484 +
  485 + }
... ...
src/trace/tracewindow.c 0 → 100644
... ... @@ -0,0 +1,142 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como trace.c e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +/**
  31 + * SECTION:V3270TraceWindow
  32 + * @Short_description: Window containing a trace monitor widget.
  33 + * @Title: V3270Trace
  34 + *
  35 + * The #V3270TraceWindow shows a window with the lib3270 trace output.
  36 + *
  37 + */
  38 +
  39 + #include <gtk/gtk.h>
  40 +
  41 + #define ENABLE_NLS
  42 + #define GETTEXT_PACKAGE PACKAGE_NAME
  43 +
  44 + #include <libintl.h>
  45 + #include <glib/gi18n.h>
  46 +
  47 + #include <v3270.h>
  48 + #include <lib3270.h>
  49 + #include <lib3270/log.h>
  50 + #include <lib3270/trace.h>
  51 + #include <lib3270/properties.h>
  52 + #include <v3270/trace.h>
  53 + #include <internals.h>
  54 +
  55 +#if defined( HAVE_SYSLOG )
  56 + #include <syslog.h>
  57 +#endif // HAVE_SYSLOG
  58 +
  59 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  60 +
  61 + static void menu_item_new(GtkWidget *menu, const gchar *label, GCallback callback, gpointer data)
  62 + {
  63 + GtkWidget *widget = gtk_menu_item_new_with_mnemonic(label);
  64 + gtk_menu_shell_append(GTK_MENU_SHELL(menu),widget);
  65 + g_signal_connect(G_OBJECT(widget), "activate", callback, data);
  66 + }
  67 +
  68 + static void menu_save(G_GNUC_UNUSED GtkWidget *button, GtkWidget *trace)
  69 + {
  70 + v3270_trace_save(trace);
  71 + }
  72 +
  73 + static void menu_save_as(G_GNUC_UNUSED GtkWidget *button, GtkWidget *trace)
  74 + {
  75 + v3270_trace_select_file(trace);
  76 + }
  77 +
  78 + static void menu_close(G_GNUC_UNUSED GtkWidget *button, GtkWidget *window)
  79 + {
  80 + debug("%s",__FUNCTION__);
  81 + gtk_widget_destroy(window);
  82 + }
  83 +
  84 + LIB3270_EXPORT GtkWidget * v3270_trace_window_new(GtkWidget *widget, const gchar *header)
  85 + {
  86 + g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
  87 +
  88 + GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  89 + GtkWidget * vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
  90 + GtkWidget * trace = v3270_trace_new(widget);
  91 +
  92 + gtk_window_set_transient_for(GTK_WINDOW(window),GTK_WINDOW(gtk_widget_get_toplevel(widget)));
  93 + gtk_window_set_destroy_with_parent(GTK_WINDOW(window),TRUE);
  94 +
  95 + // Set window title and default size
  96 + {
  97 + const gchar * url = lib3270_get_url(v3270_get_session(widget));
  98 + g_autofree gchar * title = NULL;
  99 +
  100 + if(url)
  101 + title = g_strdup_printf("%s - %s - Trace", v3270_get_session_name(widget), url);
  102 + else
  103 + title = g_strdup_printf("%s - Trace", v3270_get_session_name(widget));
  104 +
  105 + gtk_window_set_title(GTK_WINDOW(window), title);
  106 + gtk_window_set_default_size(GTK_WINDOW(window),590,430);
  107 + }
  108 +
  109 + // Top menu
  110 + {
  111 + GtkWidget * menubar = gtk_menu_bar_new();
  112 + GtkWidget * topitem;
  113 + GtkWidget * submenu;
  114 +
  115 + {
  116 + // File menu
  117 + topitem = gtk_menu_item_new_with_mnemonic(_("_File"));
  118 + submenu = gtk_menu_new();
  119 +
  120 + gtk_menu_item_set_submenu(GTK_MENU_ITEM(topitem), submenu);
  121 + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), topitem);
  122 +
  123 + menu_item_new(submenu,_("_Save"),G_CALLBACK(menu_save),trace);
  124 + menu_item_new(submenu,_("Save _As"),G_CALLBACK(menu_save_as),trace);
  125 + menu_item_new(submenu,_("_Close"),G_CALLBACK(menu_close),window);
  126 + }
  127 +
  128 + gtk_box_pack_start(GTK_BOX(vbox),menubar,FALSE,TRUE,0);
  129 + }
  130 +
  131 + // Trace window
  132 + gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(trace),TRUE,TRUE,0);
  133 +
  134 + gtk_container_add(GTK_CONTAINER(window),vbox);
  135 + gtk_widget_show_all(window);
  136 +
  137 + if(header)
  138 + v3270_trace_append_text(trace,header);
  139 +
  140 + return window;
  141 + }
  142 +
... ...
src/trace/widget.c
... ... @@ -1,553 +0,0 @@
1   -/*
2   - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
3   - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
4   - * aplicativos mainframe. Registro no INPI sob o nome G3270.
5   - *
6   - * Copyright (C) <2008> <Banco do Brasil S.A.>
7   - *
8   - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
9   - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
10   - * Free Software Foundation.
11   - *
12   - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
13   - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
14   - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
15   - * obter mais detalhes.
16   - *
17   - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
18   - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
19   - * St, Fifth Floor, Boston, MA 02110-1301 USA
20   - *
21   - * Este programa está nomeado como trace.c e possui - linhas de código.
22   - *
23   - * Contatos:
24   - *
25   - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
26   - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
27   - *
28   - */
29   -
30   -/**
31   - * SECTION:V3270Trace
32   - * @Short_description: A trace monitor widget.
33   - * @Title: V3270Trace
34   - *
35   - * The #V3270Trace shows a text area with the lib3270 trace output.
36   - *
37   - */
38   -
39   - #include <gtk/gtk.h>
40   -
41   - #define ENABLE_NLS
42   - #define GETTEXT_PACKAGE PACKAGE_NAME
43   -
44   - #include <libintl.h>
45   - #include <glib/gi18n.h>
46   -
47   - #include <v3270.h>
48   - #include <lib3270.h>
49   - #include <lib3270/log.h>
50   - #include <lib3270/trace.h>
51   - #include <lib3270/properties.h>
52   - #include <v3270/trace.h>
53   - #include <internals.h>
54   -
55   -#if defined( HAVE_SYSLOG )
56   - #include <syslog.h>
57   -#endif // HAVE_SYSLOG
58   -
59   -/*--[ Widget definition ]----------------------------------------------------------------------------*/
60   -
61   - G_BEGIN_DECLS
62   -
63   - struct _V3270TraceClass
64   - {
65   - GtkBoxClass parent_class;
66   -
67   - };
68   -
69   - struct _V3270Trace
70   - {
71   - GtkBox parent;
72   - H3270 * hSession; ///< @brief TN3270 Session.
73   - GtkWidget * terminal; ///< @brief V3270 Widget.
74   - GtkScrolledWindow * scroll;
75   -
76   - GtkTextView * view; ///< @brief Text view;
77   - GtkTextBuffer * text; ///< @brief Trace window contents.
78   - GtkEntry * entry; ///< @brief Command line entry.
79   - GtkWidget * buttons; ///< @brief Button bar.
80   -
81   - gchar * filename; ///< @brief Selected file name.
82   -
83   - guint log_handler; ///< @brief GTK Log Handler.
84   -
85   - /// @brief lib3270's saved trace handler.
86   - struct {
87   - void (*handler)(H3270 *session, void *userdata, const char *fmt, va_list args);
88   - void *userdata;
89   - } trace;
90   -
91   - };
92   -
93   - G_END_DECLS
94   -
95   - G_DEFINE_TYPE(V3270Trace, V3270Trace, GTK_TYPE_BOX);
96   -
97   -/*--[ Implement ]------------------------------------------------------------------------------------*/
98   -
99   - static void trace_handler(H3270 *hSession, void *userdata, const char *fmt, va_list args)
100   - {
101   - g_autofree gchar *ptr = g_strdup_vprintf(fmt,args);
102   - g_autofree gchar * utftext = g_convert_with_fallback(ptr,-1,"UTF-8",lib3270_get_display_charset(hSession),"?",NULL,NULL,NULL);
103   -
104   - v3270_trace_append_text(GTK_WIDGET(userdata),utftext);
105   -
106   - }
107   -
108   - static void set_session(V3270Trace *widget, H3270 *hSession)
109   - {
110   - // Return if it's the same session.
111   - if(widget->hSession == hSession)
112   - return;
113   -
114   - debug("%s: Session changes %p -> %p", __FUNCTION__, widget->hSession, hSession);
115   -
116   - if(widget->hSession) {
117   - lib3270_set_trace_handler(widget->hSession,widget->trace.handler,widget->trace.userdata);
118   - }
119   -
120   - widget->hSession = hSession;
121   -
122   - if(hSession) {
123   - lib3270_get_trace_handler(hSession,&widget->trace.handler,&widget->trace.userdata);
124   - lib3270_set_trace_handler(hSession,trace_handler,(void *) widget);
125   - }
126   -
127   - }
128   -
129   - static void finalize(GObject *object)
130   - {
131   - debug("V3270Trace::%s",__FUNCTION__);
132   -
133   - V3270Trace *trace = GTK_V3270_TRACE(object);
134   -
135   - if(trace->filename)
136   - {
137   - g_free(trace->filename);
138   - trace->filename = NULL;
139   - }
140   -
141   - if(trace->log_handler)
142   - {
143   - g_log_remove_handler(NULL,trace->log_handler);
144   - trace->log_handler = 0;
145   - }
146   -
147   - set_session(trace,NULL);
148   - g_clear_object(&trace->terminal);
149   -
150   - G_OBJECT_CLASS(V3270Trace_parent_class)->finalize(object);
151   - }
152   -
153   - static void V3270Trace_class_init(G_GNUC_UNUSED V3270TraceClass *klass)
154   - {
155   - G_OBJECT_CLASS(klass)->finalize = finalize;
156   - }
157   -
158   - static void v3270_trace_execute(GtkWidget *widget, const gchar *cmd)
159   - {
160   - if(!*cmd)
161   - return;
162   -
163   - v3270_trace_printf(widget, "%s\n",cmd);
164   -
165   - V3270Trace *trace = GTK_V3270_TRACE(widget);
166   -
167   - if(trace->terminal)
168   - {
169   - int rc = v3270_exec_command(trace->terminal,cmd);
170   - if(rc)
171   - v3270_trace_printf(widget, "rc=%d (%s)\n",rc,strerror(rc));
172   - }
173   - else
174   - {
175   - v3270_trace_append_text(widget, "Can't execute command without an associated terminal");
176   - }
177   -
178   - gtk_entry_set_text(trace->entry, "");
179   -
180   - }
181   -
182   - static void execute_command(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_pos, G_GNUC_UNUSED GdkEvent *event, GtkWidget *widget)
183   - {
184   - v3270_trace_execute(widget, gtk_entry_get_text(entry));
185   - }
186   -
187   - static void entry_activated(GtkEntry *entry, GtkWidget *widget)
188   - {
189   - v3270_trace_execute(widget, gtk_entry_get_text(entry));
190   - }
191   -
192   - static void log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, GtkWidget *widget)
193   - {
194   - #ifndef LOG_INFO
195   - #define LOG_INFO 0
196   - #endif // LOG_INFO
197   -
198   - #ifndef LOG_ERR
199   - #define LOG_ERR 0
200   - #endif // LOG_ERR
201   -
202   - #ifndef LOG_DEBUG
203   - #define LOG_DEBUG 0
204   - #endif // LOG_DEBUG
205   -
206   - static const struct _logtype
207   - {
208   - GLogLevelFlags log_level;
209   - const gchar * msg;
210   - } logtype[] =
211   - {
212   - { G_LOG_FLAG_RECURSION, "recursion" },
213   - { G_LOG_FLAG_FATAL, "fatal error" },
214   -
215   - /* GLib log levels */
216   - { G_LOG_LEVEL_ERROR, "error" },
217   - { G_LOG_LEVEL_CRITICAL, "critical error" },
218   - { G_LOG_LEVEL_WARNING, "warning" },
219   - { G_LOG_LEVEL_MESSAGE, "message" },
220   - { G_LOG_LEVEL_INFO, "info" },
221   - { G_LOG_LEVEL_DEBUG, "debug" },
222   - };
223   -
224   - size_t f;
225   -
226   - for(f=0;f<G_N_ELEMENTS(logtype);f++)
227   - {
228   - if(logtype[f].log_level == log_level)
229   - {
230   - g_autofree gchar *text = g_strdup_printf("%s: %s %s",logtype[f].msg,log_domain ? log_domain : "",message);
231   -
232   - gchar *ptr;
233   - for(ptr = text;*ptr;ptr++)
234   - {
235   - if(*ptr < ' ')
236   - *ptr = ' ';
237   - }
238   -
239   - v3270_trace_printf(widget,"%s\n",text);
240   -
241   - return;
242   - }
243   - }
244   -
245   - v3270_trace_printf(widget,"%s %s\n",log_domain ? log_domain : "", message);
246   -
247   - }
248   -
249   - static void V3270Trace_init(V3270Trace *widget)
250   - {
251   - gtk_orientable_set_orientation(GTK_ORIENTABLE(widget),GTK_ORIENTATION_VERTICAL);
252   -
253   - // Create toolbar
254   - {
255   - widget->buttons = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
256   -
257   - gtk_button_box_set_layout(GTK_BUTTON_BOX(widget->buttons), GTK_BUTTONBOX_START);
258   - gtk_box_set_spacing(GTK_BOX(widget->buttons),8);
259   -
260   - gtk_widget_set_valign(widget->buttons,GTK_ALIGN_START);
261   - gtk_box_pack_start(GTK_BOX(widget),widget->buttons,FALSE,FALSE,4);
262   -
263   - }
264   -
265   - // Create text view
266   - {
267   - widget->scroll = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL,NULL));
268   - gtk_scrolled_window_set_policy(widget->scroll,GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
269   - gtk_widget_set_vexpand(GTK_WIDGET(widget->scroll),TRUE);
270   - gtk_widget_set_hexpand(GTK_WIDGET(widget->scroll),TRUE);
271   -
272   - gtk_box_pack_start(GTK_BOX(widget),GTK_WIDGET(widget->scroll),TRUE,TRUE,4);
273   -
274   - widget->view = GTK_TEXT_VIEW(gtk_text_view_new());
275   -
276   -#if GTK_CHECK_VERSION(3,16,0)
277   - gtk_text_view_set_monospace(widget->view,TRUE);
278   -#endif // GTK_CHECK_VERSION
279   -
280   - widget->text = gtk_text_view_get_buffer(widget->view);
281   - gtk_text_view_set_editable(widget->view, TRUE);
282   -
283   - gtk_container_add(GTK_CONTAINER(widget->scroll),GTK_WIDGET(widget->view));
284   - gtk_widget_set_can_default(GTK_WIDGET(widget->view),FALSE);
285   -
286   - }
287   -
288   - // Create command line
289   - {
290   - widget->entry = GTK_ENTRY(gtk_entry_new());
291   -
292   - gtk_widget_set_can_default(GTK_WIDGET(widget->entry),TRUE);
293   - gtk_widget_grab_focus(GTK_WIDGET(widget->entry));
294   -
295   - gtk_entry_set_activates_default(widget->entry,TRUE);
296   - gtk_widget_set_sensitive(GTK_WIDGET(widget->entry),FALSE);
297   - gtk_widget_set_vexpand(GTK_WIDGET(widget->entry),FALSE);
298   - gtk_widget_set_hexpand(GTK_WIDGET(widget->entry),TRUE);
299   -
300   - gtk_entry_set_icon_from_icon_name(widget->entry,GTK_ENTRY_ICON_SECONDARY,"system-run");
301   - gtk_entry_set_placeholder_text(widget->entry,_("Command to execute"));
302   -
303   - gtk_box_pack_end(GTK_BOX(widget),GTK_WIDGET(widget->entry),FALSE,FALSE,4);
304   -
305   - g_signal_connect(G_OBJECT(widget->entry),"icon-press",G_CALLBACK(execute_command),widget);
306   - g_signal_connect(G_OBJECT(widget->entry),"activate",G_CALLBACK(entry_activated),widget);
307   -
308   - }
309   -
310   - // Grab GTK messages.
311   - widget->log_handler = g_log_set_handler(NULL,G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,(GLogFunc) log_handler, widget);
312   -
313   - }
314   -
315   -
316   - LIB3270_EXPORT GtkWidget * v3270_trace_new(GtkWidget *terminal)
317   - {
318   - g_return_val_if_fail(GTK_IS_V3270(terminal),NULL);
319   -
320   - V3270Trace * widget = GTK_V3270_TRACE(g_object_new(GTK_TYPE_V3270_TRACE, NULL));
321   -
322   - // Set terminal widget
323   - {
324   - widget->terminal = terminal;
325   - g_object_ref_sink(G_OBJECT(terminal));
326   - set_session(widget, v3270_get_session(widget->terminal));
327   - }
328   -
329   - // Create toggle buttons
330   - {
331   - size_t ix;
332   -
333   - static const LIB3270_TOGGLE toggles[] = { LIB3270_TOGGLE_DS_TRACE, LIB3270_TOGGLE_NETWORK_TRACE, LIB3270_TOGGLE_EVENT_TRACE, LIB3270_TOGGLE_SSL_TRACE, LIB3270_TOGGLE_SCREEN_TRACE};
334   -
335   - for(ix = 0; ix < G_N_ELEMENTS(toggles); ix++)
336   - {
337   - GtkWidget * item = v3270_toggle_button_new(widget->terminal,toggles[ix]);
338   -
339   - gtk_widget_set_can_focus(item,FALSE);
340   - gtk_widget_set_can_default(item,FALSE);
341   - gtk_widget_set_focus_on_click(item,FALSE);
342   -
343   - gtk_box_pack_start(GTK_BOX(widget->buttons),item,FALSE,FALSE,4);
344   -
345   - }
346   - }
347   -
348   -
349   - return GTK_WIDGET(widget);
350   - }
351   -
352   - struct _append_text
353   - {
354   - V3270Trace *widget;
355   - gchar text[1];
356   - };
357   -
358   - static gboolean bg_append_text(struct _append_text *cfg)
359   - {
360   - if(!GTK_IS_TEXT_BUFFER(cfg->widget->text))
361   - return FALSE;
362   -
363   - GtkTextIter itr;
364   - gtk_text_buffer_get_end_iter(cfg->widget->text,&itr);
365   -
366   - if(g_utf8_validate(cfg->text,strlen(cfg->text),NULL))
367   - {
368   - gtk_text_buffer_insert(cfg->widget->text,&itr,cfg->text,strlen(cfg->text));
369   - }
370   - else
371   - {
372   - gtk_text_buffer_insert(cfg->widget->text,&itr,"** Invalid UTF8 String **",-1);
373   - }
374   -
375   - // gtk_text_buffer_get_end_iter(cfg->widget->text,&itr);
376   - // gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(cfg->widget->view), &itr, 0.0, FALSE, 0.0, 0.0);
377   -
378   - GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment(cfg->widget->scroll);
379   - gtk_adjustment_set_value(vadj,gtk_adjustment_get_upper(vadj));
380   - gtk_scrolled_window_set_vadjustment(cfg->widget->scroll, vadj);
381   -
382   - return FALSE;
383   -
384   - }
385   -
386   - LIB3270_EXPORT void v3270_trace_append_text(GtkWidget *widget, const gchar *text)
387   - {
388   - g_return_if_fail(GTK_IS_V3270_TRACE(widget));
389   -
390   - // Enqueue update.
391   - struct _append_text * cfg = g_malloc0(sizeof(struct _append_text)+strlen(text)+1);
392   - cfg->widget = GTK_V3270_TRACE(widget);
393   - strcpy(cfg->text,text);
394   -
395   - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,(GSourceFunc) bg_append_text, cfg, g_free);
396   -
397   - }
398   -
399   - LIB3270_EXPORT void v3270_trace_vprintf(GtkWidget *widget, const char *fmt, va_list args)
400   - {
401   - g_autofree gchar * text = g_strdup_vprintf(fmt,args);
402   - v3270_trace_append_text(widget,text);
403   - }
404   -
405   - LIB3270_EXPORT void v3270_trace_printf(GtkWidget *widget, const char *fmt, ... )
406   - {
407   - va_list arg_ptr;
408   - va_start(arg_ptr, fmt);
409   - v3270_trace_vprintf(widget,fmt,arg_ptr);
410   - va_end(arg_ptr);
411   - }
412   -
413   - static void menu_item_new(GtkWidget *menu, const gchar *label, GCallback callback, gpointer data)
414   - {
415   - GtkWidget *widget = gtk_menu_item_new_with_mnemonic(label);
416   - gtk_menu_shell_append(GTK_MENU_SHELL(menu),widget);
417   - g_signal_connect(G_OBJECT(widget), "activate", callback, data);
418   - }
419   -
420   - static void menu_save(G_GNUC_UNUSED GtkWidget *button, GtkWidget *trace)
421   - {
422   - v3270_trace_save(trace);
423   - }
424   -
425   - static void menu_save_as(G_GNUC_UNUSED GtkWidget *button, GtkWidget *trace)
426   - {
427   - v3270_trace_select_file(trace);
428   - }
429   -
430   - static void menu_close(G_GNUC_UNUSED GtkWidget *button, GtkWidget *window)
431   - {
432   - debug("%s",__FUNCTION__);
433   - gtk_widget_destroy(window);
434   - }
435   -
436   - LIB3270_EXPORT GtkWidget * v3270_trace_window_new(GtkWidget *widget, const gchar *header)
437   - {
438   - g_return_val_if_fail(GTK_IS_V3270(widget),NULL);
439   -
440   - GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
441   - GtkWidget * vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
442   - GtkWidget * trace = v3270_trace_new(widget);
443   -
444   - // Set window title and default size
445   - {
446   - const gchar * url = lib3270_get_url(v3270_get_session(widget));
447   - g_autofree gchar * title = NULL;
448   -
449   - if(url)
450   - title = g_strdup_printf("%s - %s - Trace", v3270_get_session_name(widget), url);
451   - else
452   - title = g_strdup_printf("%s - Trace", v3270_get_session_name(widget));
453   -
454   - gtk_window_set_title(GTK_WINDOW(window), title);
455   - gtk_window_set_default_size(GTK_WINDOW(window),590,430);
456   - }
457   -
458   - // Top menu
459   - {
460   - GtkWidget * menubar = gtk_menu_bar_new();
461   - GtkWidget * topitem = gtk_menu_item_new_with_mnemonic(_("_File"));
462   - GtkWidget * submenu = gtk_menu_new();
463   -
464   - gtk_menu_item_set_submenu(GTK_MENU_ITEM(topitem), submenu);
465   - gtk_menu_shell_append(GTK_MENU_SHELL(menubar), topitem);
466   -
467   - menu_item_new(submenu,_("_Save"),G_CALLBACK(menu_save),trace);
468   - menu_item_new(submenu,_("Save _As"),G_CALLBACK(menu_save_as),trace);
469   - menu_item_new(submenu,_("_Close"),G_CALLBACK(menu_close),window);
470   -
471   - gtk_box_pack_start(GTK_BOX(vbox),menubar,FALSE,TRUE,0);
472   - }
473   -
474   - // Trace window
475   - gtk_box_pack_start(GTK_BOX(vbox),GTK_WIDGET(trace),TRUE,TRUE,0);
476   -
477   - gtk_container_add(GTK_CONTAINER(window),vbox);
478   - gtk_widget_show_all(window);
479   -
480   - if(header)
481   - v3270_trace_append_text(trace,header);
482   -
483   - return window;
484   - }
485   -
486   - LIB3270_EXPORT void v3270_trace_save(GtkWidget *widget)
487   - {
488   - V3270Trace * trace = GTK_V3270_TRACE(widget);
489   -
490   - if(trace && trace->filename)
491   - {
492   - GError * error = NULL;
493   - gchar * text;
494   - GtkTextIter start;
495   - GtkTextIter end;
496   -
497   - gtk_text_buffer_get_start_iter(trace->text,&start);
498   - gtk_text_buffer_get_end_iter(trace->text,&end);
499   - text = gtk_text_buffer_get_text(trace->text,&start,&end,FALSE);
500   -
501   - g_file_set_contents(trace->filename,text,-1,&error);
502   -
503   - g_free(text);
504   -
505   - if(error)
506   - {
507   - GtkWidget *popup =
508   - gtk_message_dialog_new_with_markup(
509   - GTK_WINDOW(gtk_widget_get_toplevel(widget)),
510   - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
511   - GTK_MESSAGE_ERROR,
512   - GTK_BUTTONS_CLOSE,
513   - _( "Can't save %s" ),
514   - trace->filename
515   - );
516   -
517   - gtk_window_set_title(GTK_WINDOW(popup),_("Can't save file"));
518   -
519   - gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(popup),"%s",error->message);
520   - g_error_free(error);
521   -
522   - gtk_dialog_run(GTK_DIALOG(popup));
523   - gtk_widget_destroy(popup);
524   -
525   - }
526   -
527   - }
528   -
529   - }
530   -
531   - LIB3270_EXPORT void v3270_trace_select_file(GtkWidget *widget)
532   - {
533   - V3270Trace * trace = GTK_V3270_TRACE(widget);
534   -
535   - gchar * filename =
536   - v3270_select_file(
537   - GTK_WIDGET(trace),
538   - _("Save trace to file"),
539   - _("Save"),
540   - GTK_FILE_CHOOSER_ACTION_SAVE,
541   - trace->filename,
542   - N_("Text file"), "*.txt",
543   - NULL
544   - );
545   -
546   - if(filename) {
547   - g_free(trace->filename);
548   - trace->filename = filename;
549   - v3270_trace_save(widget);
550   - }
551   -
552   - }
553   -
v3270.cbp
... ... @@ -260,7 +260,10 @@
260 260 <Unit filename="src/trace/exec.c">
261 261 <Option compilerVar="CC" />
262 262 </Unit>
263   - <Unit filename="src/trace/widget.c">
  263 + <Unit filename="src/trace/trace.c">
  264 + <Option compilerVar="CC" />
  265 + </Unit>
  266 + <Unit filename="src/trace/tracewindow.c">
264 267 <Option compilerVar="CC" />
265 268 </Unit>
266 269 <Extensions>
... ...