header.c 6.04 KB
/*
 * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270  e X3270
 * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
 * aplicativos mainframe. Registro no INPI sob o nome G3270.
 *
 * Copyright (C) <2008> <Banco do Brasil S.A.>
 *
 * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
 * os termos da GPL v.2 - Licença Pública Geral  GNU,  conforme  publicado  pela
 * Free Software Foundation.
 *
 * Este programa é distribuído na expectativa de  ser  útil,  mas  SEM  QUALQUER
 * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou  de  ADEQUAÇÃO
 * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
 * obter mais detalhes.
 *
 * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
 * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
 * St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Este programa está nomeado como - e possui - linhas de código.
 *
 * Contatos:
 *
 * perry.werneck@gmail.com	(Alexandre Perry de Souza Werneck)
 * erico.mendonca@gmail.com	(Erico Mascarenhas Mendonça)
 *
 */

 #include "private.h"
 #include <pw3270.h>
 #include <pw3270/toolbar.h>
 #include <pw3270/application.h>
 #include <pw3270/actions.h>

 void pw3270_window_set_header_action_names(GtkWidget *window, const gchar *action_names) {

	GtkWidget * header = gtk_window_get_titlebar(GTK_WINDOW(window));

	if(!(header && GTK_IS_HEADER_BAR(header)))
		return;

	gtk_container_remove_all(GTK_CONTAINER(header));

	if(action_names && *action_names) {

		size_t ix;
		gchar ** header_blocks = g_strsplit(action_names,":",-1);

		g_autoptr(GtkBuilder) builder = pw3270_application_get_builder("window.xml");

		if(!gtk_application_prefers_app_menu(GTK_APPLICATION(g_application_get_default()))) {

			// No application menu, add view and help sections to open menu.

			g_autoptr(GtkBuilder) app_builder = pw3270_application_get_builder("application.xml");

			g_menu_append_section(
				G_MENU(gtk_builder_get_object(builder,"open-menu")),
				NULL,
				G_MENU_MODEL(gtk_builder_get_object(app_builder,"help-menu-placeholder"))
			);

			g_menu_append_submenu(
				G_MENU(gtk_builder_get_object(builder,"preferences-menu")),
				_("View"),
				G_MENU_MODEL(gtk_builder_get_object(app_builder,"view-menu-placeholder"))
			);

		}

		if(g_strv_length(header_blocks) >= 2) {

			gchar ** elements;
			GtkWidget * button;

			// First the left side actions.
			elements = g_strsplit(header_blocks[0],",",-1);
			for(ix=0;elements[ix];ix++) {
				button = pw3270_header_button_new_from_builder(GTK_WIDGET(window),builder,elements[ix]);
				if(button) {
					g_object_set_data(G_OBJECT(button),"header-position-id",GINT_TO_POINTER(0));
					gtk_header_bar_pack_start(GTK_HEADER_BAR(header), button);
				}
			}
			g_strfreev(elements);

			// And then, the right side actions;
			elements = g_strsplit(header_blocks[1],",",-1);
			for(ix=0;elements[ix];ix++) {
				button = pw3270_header_button_new_from_builder(GTK_WIDGET(window),builder,elements[ix]);
				if(button) {
					g_object_set_data(G_OBJECT(button),"header-position-id",GINT_TO_POINTER(1));
					gtk_header_bar_pack_end(GTK_HEADER_BAR(header), button);
				}
			}
			g_strfreev(elements);

		}

		g_strfreev(header_blocks);

	}

 }

 static void on_sensitive(GtkWidget G_GNUC_UNUSED(*button), GParamSpec G_GNUC_UNUSED(*spec), GtkWidget G_GNUC_UNUSED(*widget)) {

	gboolean sensitive;
	g_object_get(button, "sensitive", &sensitive, NULL);
	gtk_widget_set_visible(button,sensitive);

 }

 GtkWidget * pw3270_header_button_new_from_builder(GtkWidget *widget, GtkBuilder * builder, const gchar *action_name) {

	GtkWidget * button = NULL;

	if(g_str_has_prefix(action_name,"menu.")) {

		// It's a menu
		g_autofree gchar * icon_name = g_strconcat(action_name+5,"-symbolic",NULL);

		button = gtk_menu_button_new();
		gtk_button_set_image(GTK_BUTTON(button),gtk_image_new_from_icon_name(icon_name,GTK_ICON_SIZE_MENU));

		gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(button), G_MENU_MODEL(gtk_builder_get_object(builder, action_name+5)));
		gtk_widget_set_visible(button,TRUE);

	} else if(g_str_has_prefix(action_name,"app.")) {

		// It's an application action

	} else if(g_str_has_prefix(action_name,"win.")) {

		// It's a window action.
		GAction * action = g_action_map_lookup_action(G_ACTION_MAP(widget),action_name+4);

		if(action) {

			button = gtk_button_new_from_action(action,GTK_ICON_SIZE_BUTTON);

			gtk_actionable_set_action_name(GTK_ACTIONABLE(button),action_name);
			gtk_widget_set_visible(button,g_action_get_enabled(action));


		} else {

			g_warning("Can't find action \"%s\"",action_name+4);

		}

	}

	if(button) {

		g_signal_connect(button, "notify::sensitive", G_CALLBACK(on_sensitive), widget);
		gtk_widget_set_focus_on_click(button,FALSE);
		gtk_widget_set_can_focus(button,FALSE);
		gtk_widget_set_can_default(button,FALSE);
		gtk_widget_set_name(button,action_name);

	} else {

		g_warning("Can't create button for action \"%s\"",action_name);

	}

	return button;
 }

 gchar * pw3270_window_get_action_names(GtkWidget *window) {

	GtkWidget * header = gtk_window_get_titlebar(GTK_WINDOW(window));

	if(!(header && GTK_IS_HEADER_BAR(header)))
		return g_strdup("win.disconnect,win.reconnect,win.file.transfer,win.print:menu.open-menu");

	GString * str = g_string_new("");

 	GList * children = gtk_container_get_children(GTK_CONTAINER(header));
 	GList * item;

	int id;
 	for(id = 0; id < 2; id++) {

		gboolean sep = FALSE;

 		for(item = children;item;item = g_list_next(item)) {

			if(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item->data),"header-position-id")) != id)
				continue;

			if(sep)
				g_string_append(str,",");

			if(GTK_IS_MENU_BUTTON(item->data)) {
				g_string_append(str,gtk_widget_get_name(GTK_WIDGET(item->data)));
			} else if(GTK_IS_ACTIONABLE(item->data)) {
				g_string_append(str,gtk_actionable_get_action_name(GTK_ACTIONABLE(item->data)));
			}

			sep = TRUE;
		}

		if(!id)
			g_string_append(str,":");

 	}

 	g_list_free(children);

	return g_string_free(str,FALSE);
 }