Añadida GtkHeaderBar

This commit is contained in:
Alejandro T. Colombini Gómez 2014-05-20 17:45:13 +02:00
parent 986e748a82
commit c9d6d0ddf8
14 changed files with 389 additions and 562 deletions

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.2 -->
<interface> <interface>
<!-- interface-requires vn 0.0 --> <requires lib="gtk+" version="3.0"/>
<!-- interface-requires gtk+ 3.0 --> <requires lib="vn" version="0.0"/>
<!-- interface-local-resource-path ../image --> <!-- interface-local-resource-path ../image -->
<object class="GtkActionGroup" id="actions"> <object class="GtkActionGroup" id="actions">
<child> <child>
@ -66,8 +67,6 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="has_entry">True</property> <property name="has_entry">True</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
<child internal-child="entry"> <child internal-child="entry">
<object class="GtkEntry" id="combo-entry"> <object class="GtkEntry" id="combo-entry">
<property name="can_focus">True</property> <property name="can_focus">True</property>
@ -85,6 +84,7 @@
</child> </child>
<child> <child>
<object class="GtkButton" id="button-send"> <object class="GtkButton" id="button-send">
<property name="use_action_appearance">True</property>
<property name="related_action">send</property> <property name="related_action">send</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
@ -98,6 +98,7 @@
</child> </child>
<child> <child>
<object class="GtkButton" id="button-clean"> <object class="GtkButton" id="button-clean">
<property name="use_action_appearance">True</property>
<property name="related_action">clean</property> <property name="related_action">clean</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>

View File

@ -7,12 +7,4 @@
</menu> </menu>
</placeholder> </placeholder>
</menubar> </menubar>
<toolbar name="Toolbar">
<placeholder name="ModuleTools">
<separator/>
<toolitem name="Send" action="send"/>
<toolitem name="Clean" action="clean"/>
<separator/>
</placeholder>
</toolbar>
</ui> </ui>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module> <module>
<library translatable="yes" name="example">Example</library> <library translatable="yes" name="example">Example</library>
<action-group> <!-- <action-group>-->
<action <!-- <action-->
translatable="yes" <!-- translatable="yes"-->
name="action-menu-example">Example</action> <!-- name="action-menu-example">Example</action>-->
</action-group> <!-- </action-group>-->
<form-group> <form-group>
<form <form
translatable="yes" translatable="yes"
@ -13,14 +13,6 @@
icon="system-run" icon="system-run"
action-name="open-consulter" action-name="open-consulter"
accel="F1">Consulter</form> accel="F1">Consulter</form>
<!-- <form
translatable="yes"
name="customer"
icon="x-office-address-book"
action-name="open-customer"
accel="F5">
Customer
</form>
-->
</form-group> </form-group>
</module> </module>

View File

@ -18,10 +18,10 @@
#include "vn-consulter.h" #include "vn-consulter.h"
#include "stdlib.h" #include "stdlib.h"
G_DEFINE_TYPE (VnConsulter, vn_consulter, VN_TYPE_FORM);
#define FILE_KW "sql://" #define FILE_KW "sql://"
G_DEFINE_TYPE (VnConsulter, vn_consulter, VN_TYPE_FORM);
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
void vn_consulter_clean_clicked (GtkButton * button, VnConsulter * obj) void vn_consulter_clean_clicked (GtkButton * button, VnConsulter * obj)
@ -126,7 +126,7 @@ if (format)
else if (type == G_TYPE_FLOAT || type == G_TYPE_DOUBLE) else if (type == G_TYPE_FLOAT || type == G_TYPE_DOUBLE)
g_object_set (column, g_object_set (column,
"digits", 2, "digits", 2,
"lower", 0.0, "lower", -1000.0,
"upper", 1000.0, "upper", 1000.0,
"step-increment", 0.1, "step-increment", 0.1,
// "editable", FALSE, // "editable", FALSE,
@ -240,6 +240,30 @@ static void vn_consulter_open (VnConsulter * obj)
gtk_combo_box_text_prepend_text (obj->combo, queries[i]); gtk_combo_box_text_prepend_text (obj->combo, queries[i]);
} }
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Actions
void vn_consulter_on_send_activated (GSimpleAction * a, GVariant * p, gpointer obj)
{
vn_consulter_send (NULL, VN_CONSULTER (obj));
}
void vn_consulter_on_clean_activated (GSimpleAction * a, GVariant * p, gpointer obj)
{
vn_consulter_clean_clicked (NULL, VN_CONSULTER (obj));
}
static const GActionEntry actions[] =
{
{"send", vn_consulter_on_send_activated}
,{"clean", vn_consulter_on_clean_activated}
};
const GActionEntry * vn_consulter_get_actions (VnForm * obj, gint * size)
{
*size = G_N_ELEMENTS (actions);
return actions;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void vn_consulter_init (VnConsulter * obj) static void vn_consulter_init (VnConsulter * obj)
@ -257,4 +281,5 @@ static void vn_consulter_class_init (VnConsulterClass * k)
{ {
G_OBJECT_CLASS (k)->finalize = (GObjectFinalizeFunc) vn_consulter_finalize; G_OBJECT_CLASS (k)->finalize = (GObjectFinalizeFunc) vn_consulter_finalize;
VN_FORM_CLASS (k)->open = (VnFormOpenFunc) vn_consulter_open; VN_FORM_CLASS (k)->open = (VnFormOpenFunc) vn_consulter_open;
VN_FORM_CLASS (k)->get_actions = vn_consulter_get_actions;
} }

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.2 -->
<interface> <interface>
<!-- interface-requires gtk+ 3.0 --> <requires lib="gtk+" version="3.0"/>
<object class="GtkActionGroup" id="main-actions"> <object class="GtkActionGroup" id="main-actions">
<child> <child>
<object class="GtkAction" id="logout"> <object class="GtkAction" id="logout">
@ -57,27 +58,5 @@
</object> </object>
<accelerator key="w" modifiers="GDK_CONTROL_MASK"/> <accelerator key="w" modifiers="GDK_CONTROL_MASK"/>
</child> </child>
<child>
<object class="GtkAction" id="menu-view">
<property name="label" translatable="yes">_View</property>
</object>
</child>
<child>
<object class="GtkToggleAction" id="menu-view-tabs">
<property name="label" translatable="yes" context="View menu option">Dynamic _Tabs</property>
<property name="tooltip" translatable="yes">Don't show tabs if there is only one tab open</property>
<property name="active">True</property>
<signal name="toggled" handler="vn_gui_on_dynamic_tabs_activated" swapped="no"/>
</object>
<accelerator key="t" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
<object class="GtkToggleAction" id="menu-view-toolbar">
<property name="label" translatable="yes" context="View menu option">Tool_bar</property>
<property name="active">True</property>
<signal name="toggled" handler="vn_gui_on_view_toolbar_activated" swapped="no"/>
</object>
<accelerator key="b" modifiers="GDK_CONTROL_MASK"/>
</child>
</object> </object>
</interface> </interface>

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.2 -->
<interface> <interface>
<!-- interface-requires gtk+ 3.0 --> <requires lib="gtk+" version="3.0"/>
<!-- interface-local-resource-path ../image --> <!-- interface-local-resource-path ../image -->
<object class="GtkWindow" id="child"> <object class="GtkApplicationWindow" id="child">
<property name="width_request">400</property> <property name="width_request">400</property>
<property name="height_request">300</property> <property name="height_request">300</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
@ -24,12 +25,11 @@
<object class="GtkNotebook" id="notebook"> <object class="GtkNotebook" id="notebook">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="show_tabs">False</property>
<property name="scrollable">True</property> <property name="scrollable">True</property>
<signal name="page-removed" handler="vn_gui_on_page_removed" swapped="no"/>
<signal name="switch-page" handler="vn_gui_on_switch_page" swapped="no"/>
<signal name="create-window" handler="vn_gui_on_page_detached" swapped="no"/> <signal name="create-window" handler="vn_gui_on_page_detached" swapped="no"/>
<signal name="page-added" handler="vn_gui_on_page_added" swapped="no"/> <signal name="page-added" handler="vn_gui_on_page_added" swapped="no"/>
<signal name="page-removed" handler="vn_gui_on_page_removed" swapped="no"/>
<signal name="switch-page" handler="vn_gui_on_switch_page" swapped="no"/>
</object> </object>
</child> </child>
</object> </object>

View File

@ -1,69 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.2 -->
<interface> <interface>
<!-- interface-requires gtk+ 3.0 --> <requires lib="gtk+" version="3.0"/>
<!-- interface-local-resource-path ../image --> <!-- interface-local-resource-path ../image -->
<object class="GtkAboutDialog" id="about"> <object class="GtkApplicationWindow" id="window">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="destroy_with_parent">True</property>
<property name="icon">../image/icon.svg</property>
<property name="type_hint">dialog</property>
<property name="transient_for">window</property>
<property name="program_name">Hedera</property>
<property name="version">Versión 1.0</property>
<property name="copyright" translatable="yes">Copyright - Verdnatura Levante S. L.</property>
<property name="comments" translatable="yes">Management and administration of companies</property>
<property name="website">http://www.verdnatura.es</property>
<property name="website_label" translatable="yes">www.verdnatura.es</property>
<property name="license" translatable="yes">This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.</property>
<property name="authors">Juan Ferrer Toribio
Alejandro Colombini Gómez
Javier Gallego Ferris</property>
<property name="documenters">Juan Ferrer Toribio
Alejandro Colombini Gómez
Javier Gallego Ferris</property>
<property name="artists">Jordi Cuquerella
Juan Ferrer Toribio</property>
<property name="logo">../image/icon.svg</property>
<property name="license_type">gpl-3-0</property>
<signal name="response" handler="gtk_widget_hide" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="aboutdialog-vbox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="aboutdialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="window">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="title" translatable="yes">Hedera</property> <property name="title" translatable="yes">Hedera</property>
<property name="window_position">center</property> <property name="window_position">center</property>
@ -85,13 +25,12 @@ Juan Ferrer Toribio</property>
<object class="GtkNotebook" id="notebook"> <object class="GtkNotebook" id="notebook">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="show_tabs">False</property>
<property name="scrollable">True</property> <property name="scrollable">True</property>
<property name="group_name">vn-notebook</property> <property name="group_name">vn-notebook</property>
<signal name="page-removed" handler="vn_gui_on_main_page_removed" swapped="no"/>
<signal name="switch-page" handler="vn_gui_on_switch_page" swapped="no"/>
<signal name="create-window" handler="vn_gui_on_page_detached" swapped="no"/> <signal name="create-window" handler="vn_gui_on_page_detached" swapped="no"/>
<signal name="page-added" handler="vn_gui_on_page_added" swapped="no"/> <signal name="page-added" handler="vn_gui_on_page_added" swapped="no"/>
<signal name="page-removed" handler="vn_gui_on_main_page_removed" swapped="no"/>
<signal name="switch-page" handler="vn_gui_on_switch_page" swapped="no"/>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>
@ -177,4 +116,65 @@ Juan Ferrer Toribio</property>
</object> </object>
</child> </child>
</object> </object>
<object class="GtkAboutDialog" id="about">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="destroy_with_parent">True</property>
<property name="icon">../image/icon.svg</property>
<property name="type_hint">dialog</property>
<property name="transient_for">window</property>
<property name="program_name">Hedera</property>
<property name="version">Versión 1.0</property>
<property name="copyright" translatable="yes">Copyright - Verdnatura Levante S. L.</property>
<property name="comments" translatable="yes">Management and administration of companies</property>
<property name="website">http://www.verdnatura.es</property>
<property name="website_label" translatable="yes">www.verdnatura.es</property>
<property name="license" translatable="yes">This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.</property>
<property name="authors">Juan Ferrer Toribio
Alejandro Colombini Gómez
Javier Gallego Ferris</property>
<property name="documenters">Juan Ferrer Toribio
Alejandro Colombini Gómez
Javier Gallego Ferris</property>
<property name="artists">Jordi Cuquerella
Juan Ferrer Toribio</property>
<property name="logo">../image/icon.svg</property>
<property name="license_type">gpl-3-0</property>
<signal name="response" handler="gtk_widget_hide" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="aboutdialog-vbox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="aboutdialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface> </interface>

View File

@ -1,32 +0,0 @@
<ui>
<menubar name="MenuBar">
<menu name="FileMenu" action="menu-file">
<menuitem name="Connect" action="connect"/>
<menuitem name="Logout" action="logout"/>
<separator/>
<placeholder name="ModuleFileMenu"/>
<separator/>
<menuitem name="Close" action="close-tab"/>
<menuitem name="Exit" action="exit"/>
</menu>
<menu name="ViewMenu" action="menu-view">
<menuitem name="Toolbar" action="menu-view-toolbar"/>
<separator/>
<menuitem name="Tabs" action="menu-view-tabs"/>
</menu>
<placeholder name="ModuleMenu"/>
<menu name="HelpMenu" action="menu-help">
<menuitem name="About" action="about"/>
</menu>
</menubar>
<toolbar name="Toolbar">
<toolitem name="Connect" action="connect"/>
<toolitem name="Logout" action="logout"/>
<separator/>
<placeholder name="ModuleTools"/>
<!--
<separator expand="true"/>
<toolitem name="Close" action="close-tab"/>
-->
</toolbar>
</ui>

View File

@ -55,22 +55,21 @@ void vn_form_open (VnForm * obj)
gtk_container_add (GTK_CONTAINER (obj), vn_form_get (obj, "main")); gtk_container_add (GTK_CONTAINER (obj), vn_form_get (obj, "main"));
gtk_widget_show_all (GTK_WIDGET (obj)); gtk_widget_show_all (GTK_WIDGET (obj));
// Loading actions from the .glade and the GtkUIManager definition // Loading menu
if ((obj->actions = vn_form_get (obj, "actions"))) g_free (file);
file = g_strdup_printf ("%s/%s-menu.glade", dir, obj->name);
if (gtk_builder_add_from_file (obj->builder, file, &err))
{ {
gchar * buffer; obj->menu = vn_form_get (obj, "menu");
gchar * ui_file = g_strdup_printf ("%s/%s.ui", dir, obj->name); }
else
{
// if (err && err->code != G_FILE_ERROR_NOENT)
g_warning ("VnForm: %s", err->message);
if (g_file_get_contents (ui_file, &buffer, NULL, NULL)) g_error_free (err);
{
obj->ui = buffer;
g_object_ref (obj->actions);
}
else
obj->actions = NULL;
g_free (ui_file);
} }
} }
else else
@ -111,36 +110,34 @@ const gchar * vn_form_get_name (VnForm * obj)
} }
/** /**
* vn_form_get_ui_manager: * vn_form_get_actions:
* @obj: the #VnForm * @obj: the #VnForm
* *
* Returns the string containing the path of the #GtkUIManager UI definition * Returns the actions implemented by @obj.
* file for the form @obj.
* *
* Return value: a string * Return value: (transfer none): a #GActionEntry array
**/ **/
const gchar * vn_form_get_ui_manager (VnForm * obj) const GActionEntry * vn_form_get_actions (VnForm * obj, gint * size)
{ {
g_return_val_if_fail (VN_IS_FORM (obj), NULL); g_return_val_if_fail (VN_IS_FORM (obj), NULL);
return obj->ui; return VN_FORM_GET_CLASS (obj)->get_actions (obj, size);
} }
/** /**
* vn_form_get_action_group: * vn_form_get_menu_model:
* @obj: the #VnForm * @obj: the #VnForm
* *
* Returns the group actions implemented by @obj. * Returns the #GMenuModel of the form.
* *
* Return value: (transfer none): a #GtkActionGroup * Return value: (transfer full): a #GMenuModel or #NULL
**/ **/
GtkActionGroup * vn_form_get_action_group (VnForm * obj) GMenuModel * vn_form_get_menu_model (VnForm * obj)
{ {
g_return_val_if_fail (VN_IS_FORM (obj), NULL); g_return_val_if_fail (VN_IS_FORM (obj), NULL);
return obj->actions; return obj->menu;
} }
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum enum
@ -202,18 +199,16 @@ static void vn_form_init (VnForm * obj)
obj->conn = NULL; obj->conn = NULL;
obj->builder = NULL; obj->builder = NULL;
obj->mod = NULL; obj->mod = NULL;
obj->actions = NULL; obj->menu = NULL;
obj->ui = NULL;
} }
static void vn_form_finalize (VnForm * obj) static void vn_form_finalize (VnForm * obj)
{ {
g_free (obj->name); g_free (obj->name);
g_free (obj->ui);
g_clear_object (&obj->gui); g_clear_object (&obj->gui);
g_clear_object (&obj->builder); g_clear_object (&obj->builder);
g_clear_object (&obj->mod); g_clear_object (&obj->mod);
g_clear_object (&obj->actions); g_clear_object (&obj->menu);
G_OBJECT_CLASS (vn_form_parent_class)->finalize (G_OBJECT (obj)); G_OBJECT_CLASS (vn_form_parent_class)->finalize (G_OBJECT (obj));
} }

View File

@ -43,23 +43,23 @@ struct _VnForm
DbConn * conn; DbConn * conn;
GtkBuilder * builder; GtkBuilder * builder;
VnMod * mod; VnMod * mod;
GtkActionGroup * actions; GMenuModel * menu;
gchar * ui;
}; };
struct _VnFormClass struct _VnFormClass
{ {
GtkAlignmentClass parent; GtkAlignmentClass parent;
void (* open) (VnForm * obj, GtkBuilder * builder, gpointer user_data); void (* open) (VnForm * obj, GtkBuilder * builder, gpointer user_data);
void (* activate) (VnForm * obj); const GActionEntry * (* get_actions) (VnForm * obj, int * size);
void (* deactivate) (VnForm * obj); void (* activate) (VnForm * obj);
void (* deactivate) (VnForm * obj);
}; };
GType vn_form_get_type (); GType vn_form_get_type ();
void vn_form_open (VnForm * obj); void vn_form_open (VnForm * obj);
gpointer vn_form_get (VnForm * obj, const gchar * name); gpointer vn_form_get (VnForm * obj, const gchar * name);
const gchar * vn_form_get_name (VnForm * obj); const gchar * vn_form_get_name (VnForm * obj);
const gchar * vn_form_get_ui_manager (VnForm * obj); GMenuModel * vn_form_get_menu_model (VnForm * obj);
GtkActionGroup * vn_form_get_action_group (VnForm * obj); const GActionEntry * vn_form_get_actions (VnForm * obj, int * size);
#endif #endif

View File

@ -26,8 +26,7 @@
#define MAIN_UI _GUI_DIR"/main.glade" #define MAIN_UI _GUI_DIR"/main.glade"
#define CHILD_WINDOW_UI _GUI_DIR"/child-window.glade" #define CHILD_WINDOW_UI _GUI_DIR"/child-window.glade"
#define ACTIONS_UI _GUI_DIR"/actions.glade" #define MENU_UI _GUI_DIR"/menu.glade"
#define MENUBAR_XML _GUI_DIR"/menubar.ui"
#define MODULE_DTD _DTD_DIR"/module.dtd" #define MODULE_DTD _DTD_DIR"/module.dtd"
#define S(string) (gdome_str_mkref (string)) #define S(string) (gdome_str_mkref (string))
@ -42,41 +41,39 @@
**/ **/
G_DEFINE_TYPE (VnGui, vn_gui, G_TYPE_OBJECT); G_DEFINE_TYPE (VnGui, vn_gui, G_TYPE_OBJECT);
// TODO global en vn-actions.h?
void vn_gui_on_logout_activated (GSimpleAction * a, GVariant * v, gpointer obj);
void vn_gui_on_open_activated (GSimpleAction * a, GVariant * v, gpointer obj);
void vn_gui_on_about_activated (GSimpleAction * a, GVariant * v, gpointer obj);
void vn_gui_on_exit_activated (GSimpleAction * a, GVariant * v, gpointer obj);
static const GActionEntry app_entries[] =
{
{"logout", vn_gui_on_logout_activated}
,{"connect", vn_gui_on_open_activated}
,{"about", vn_gui_on_about_activated}
,{"quit", vn_gui_on_exit_activated}
};
void vn_gui_on_close_tab_activated (GSimpleAction * a, GVariant * v, gpointer obj);
static const GActionEntry win_entries[] =
{
{"close", vn_gui_on_close_tab_activated}
};
struct _VnWindow struct _VnWindow
{ {
VnGui * obj; VnGui * obj;
GtkWindow * widget; GtkWindow * widget;
GtkHeaderBar * header;
GtkWidget * menu_button;
GtkNotebook * notebook; GtkNotebook * notebook;
GtkUIManager * manager;
GtkWidget * toolbar;
VnForm * active_form; VnForm * active_form;
GtkToggleAction * dynamic_tabs;
GtkToggleAction * view_toolbar;
guint merge_id; guint merge_id;
gboolean maximized; gboolean maximized;
}; };
typedef struct
{
VnGui * gui;
gchar * name;
}
FormData;
typedef struct
{
GtkActionEntry * entry;
FormData * form;
}
ActionData;
typedef struct
{
GSList * action_data;
VnMod * mod;
}
ModData;
enum { enum {
COL_ICON COL_ICON
,COL_NAME ,COL_NAME
@ -104,7 +101,7 @@ GuiData;
static void vn_gui_reconnect (VnGui * obj); static void vn_gui_reconnect (VnGui * obj);
static void vn_gui_on_conn_error (DbConn * conn, const GError * error, VnGui * obj); static void vn_gui_on_conn_error (DbConn * conn, const GError * error, VnGui * obj);
static void vn_gui_on_conn_status_changed (DbConn * conn, DbConnStatus status, VnGui * obj); static void vn_gui_on_conn_status_changed (DbConn * conn, DbConnStatus status, VnGui * obj);
void vn_gui_on_open_form_activated (GtkAction * action, FormData * form_data); void vn_gui_on_open_form_activated (GSimpleAction * action, GVariant * v, gpointer obj);
void vn_gui_on_child_destroyed (GtkWindow * widget, VnWindow * window); void vn_gui_on_child_destroyed (GtkWindow * widget, VnWindow * window);
void vn_gui_on_page_removed (GtkNotebook * notebook, GtkWidget * page, guint num, VnWindow * window); void vn_gui_on_page_removed (GtkNotebook * notebook, GtkWidget * page, guint num, VnWindow * window);
void vn_gui_on_main_page_removed (GtkNotebook * notebook, GtkWidget * page, guint num, VnWindow * window); void vn_gui_on_main_page_removed (GtkNotebook * notebook, GtkWidget * page, guint num, VnWindow * window);
@ -127,39 +124,6 @@ VnGui * vn_gui_new (GtkApplication * app, DbConn * conn)
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void vn_gui_free_action_data (ActionData * data)
{
if (data)
{
if (data->form)
g_free (data->form->name);
g_free (data->form);
if (data->entry)
{
g_free ((gchar *) data->entry->name);
g_free ((gchar *) data->entry->stock_id);
g_free ((gchar *) data->entry->label);
g_free ((gchar *) data->entry->accelerator);
g_free ((gchar *) data->entry->tooltip);
}
g_free (data->entry);
}
g_free (data);
}
static void vn_gui_free_mod_data (ModData * data)
{
if (data->action_data)
g_slist_free_full (data->action_data,
(GDestroyNotify) vn_gui_free_action_data);
g_free (data);
}
/* /*
* Frees the #GuiData struct. * Frees the #GuiData struct.
*/ */
@ -183,7 +147,6 @@ static void vn_gui_free_window (VnGui * obj, VnWindow * window)
vn_gui_on_main_page_removed, window); vn_gui_on_main_page_removed, window);
gtk_widget_destroy (GTK_WIDGET (window->widget)); gtk_widget_destroy (GTK_WIDGET (window->widget));
g_object_unref (window->manager);
g_free (window); g_free (window);
} }
@ -241,7 +204,7 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
GdomeException e; GdomeException e;
GdomeDocument * doc; GdomeDocument * doc;
GdomeDOMImplementation * di; GdomeDOMImplementation * di;
GdomeNodeList * nl, * action_nl; GdomeNodeList * nl;
GdomeElement * el; GdomeElement * el;
GdomeNode * node; GdomeNode * node;
GdomeDOMString * mod_title; GdomeDOMString * mod_title;
@ -270,8 +233,7 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
if (doc) if (doc)
{ {
GdomeDOMString * library_str = S("library"), GdomeDOMString * library_str = S("library"),
* form_str = S("form"), * form_str = S("form");
* action_str = S("action");
nl = gdome_doc_getElementsByTagName (doc, library_str, &e); nl = gdome_doc_getElementsByTagName (doc, library_str, &e);
el = (GdomeElement *) gdome_nl_item (nl, 0, &e); el = (GdomeElement *) gdome_nl_item (nl, 0, &e);
@ -285,10 +247,8 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
mod_title = gdome_n_nodeValue (node, &e); mod_title = gdome_n_nodeValue (node, &e);
mod_title_strip = g_strstrip (g_strdup (mod_title->str)); mod_title_strip = g_strstrip (g_strdup (mod_title->str));
nl = gdome_doc_getElementsByTagName (doc, form_str, &e); nl = gdome_doc_getElementsByTagName (doc, form_str, &e);
action_nl = gdome_doc_getElementsByTagName (doc, action_str, &e);
gdome_str_unref (form_str); gdome_str_unref (form_str);
gdome_str_unref (action_str);
gdome_str_unref (library); gdome_str_unref (library);
gdome_doc_unref (doc, &e); gdome_doc_unref (doc, &e);
gdome_n_unref (node, &e); gdome_n_unref (node, &e);
@ -321,37 +281,27 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
); );
} }
else else
g_warning ("VnGui: Can't load module %s: %s" g_warning ("VnGui: Can't load module %s: %s", mod_name, g_module_error ());
,mod_name
,g_module_error ()
);
// If successful, load forms, actions and UI // If successful, load forms, actions and UI
if (mod) if (mod)
{ {
GType type; GType type;
gulong len, n; gulong len, n;
gchar * c_name; gchar * c_name;
gchar * title_strip; gchar * title_strip;
gchar * ui_file;
gchar * buffer;
GdomeDOMString * name; GdomeDOMString * name;
GdomeDOMString * icon; GdomeDOMString * icon;
GdomeDOMString * action_name; GdomeDOMString * action_name;
GdomeDOMString * accel;
GdomeDOMString * title; GdomeDOMString * title;
gchar * symbol_name; gchar * symbol_name;
GtkTreeIter parent_iter; GtkTreeIter parent_iter;
GtkTreeIter * iter; GtkTreeIter * iter;
VnFormGetTypeFunc mod_get_type_func; VnFormGetTypeFunc mod_get_type_func;
GError * err = NULL; GActionEntry * mod_actions;
GSList * mod_actions = NULL;
ActionData * action_data;
GtkActionGroup * actions = gtk_action_group_new (mod_name);
GdomeDOMString * icon_str = S("icon"), GdomeDOMString * icon_str = S("icon"),
* action_name_str = S("action-name"), * action_name_str = S("action-name");
* accel_str = S("accel");
// Creating folder to put forms inside // Creating folder to put forms inside
@ -366,6 +316,7 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
); );
len = gdome_nl_length (nl, &e); len = gdome_nl_length (nl, &e);
mod_actions = g_new0 (GActionEntry, len + 1);
for (n = 0; n < len; n++) for (n = 0; n < len; n++)
{ {
@ -374,7 +325,6 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
el = (GdomeElement *) gdome_nl_item (nl, n, &e); el = (GdomeElement *) gdome_nl_item (nl, n, &e);
icon = gdome_el_getAttribute (el, icon_str, &e); icon = gdome_el_getAttribute (el, icon_str, &e);
action_name = gdome_el_getAttribute (el, action_name_str, &e); action_name = gdome_el_getAttribute (el, action_name_str, &e);
accel = gdome_el_getAttribute (el, accel_str, &e);
name = gdome_el_getAttribute (el, name_str, &e); name = gdome_el_getAttribute (el, name_str, &e);
c_name = g_strdelimit (g_strdup (name->str), "-. ", '_'); c_name = g_strdelimit (g_strdup (name->str), "-. ", '_');
@ -386,10 +336,10 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
gdome_n_unref (node, &e); gdome_n_unref (node, &e);
gdome_el_unref (el, &e); gdome_el_unref (el, &e);
// Loading form // Loading form action entries
symbol_name = g_strdup_printf ("vn_%s_get_type", c_name); symbol_name = g_strdup_printf ("vn_%s_get_type", c_name);
if (g_module_symbol (module, symbol_name, (gpointer) &mod_get_type_func)) if (g_module_symbol (module, symbol_name, (gpointer) &mod_get_type_func))
{ {
type = mod_get_type_func (); type = mod_get_type_func ();
@ -409,27 +359,10 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
g_hash_table_replace (obj->forms, g_strdup (name->str), iter); g_hash_table_replace (obj->forms, g_strdup (name->str), iter);
if (g_strcmp0 ("", action_name->str)) if (g_strcmp0 ("", action_name->str))
{ {//TODO Free this somewhere!
action_data = g_new (ActionData, 1); mod_actions[n].name = g_strdup (action_name->str);
action_data->entry = g_new (GtkActionEntry, 1); mod_actions[n].activate = vn_gui_on_open_form_activated;
action_data->entry->name = g_strdup (action_name->str); mod_actions[n].state = g_strconcat ("\"", name->str, "\"", NULL);
action_data->entry->stock_id = g_strdup (icon->str);
action_data->entry->label = g_strdup (title_strip);
action_data->entry->accelerator = g_strdup (accel->str);
action_data->entry->tooltip = NULL;
action_data->entry->callback =
(GCallback) vn_gui_on_open_form_activated;
action_data->form = g_new (FormData, 1);
action_data->form->name = g_strdup (name->str);
action_data->form->gui = obj;
mod_actions = g_slist_prepend (mod_actions, action_data);
gtk_action_group_add_actions (actions
,action_data->entry, 1
,action_data->form
);
} }
} }
else else
@ -439,70 +372,19 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
g_warning ("VnGui: Error loading form: %s", g_module_error ()); g_warning ("VnGui: Error loading form: %s", g_module_error ());
g_free (c_name); g_free (c_name);
g_free (title_strip);
g_free (symbol_name);
gdome_str_unref (name); gdome_str_unref (name);
gdome_str_unref (icon); gdome_str_unref (icon);
gdome_str_unref (action_name); gdome_str_unref (action_name);
gdome_str_unref (accel);
gdome_str_unref (title); gdome_str_unref (title);
g_free (title_strip);
g_free (symbol_name);
} }
obj->mod_actions = g_slist_prepend (obj->mod_actions, mod_actions);
obj->modules = g_slist_prepend (obj->modules, g_object_ref (mod));
gdome_str_unref (icon_str); gdome_str_unref (icon_str);
gdome_str_unref (action_name_str); gdome_str_unref (action_name_str);
gdome_str_unref (accel_str);
len = gdome_nl_length (action_nl, &e);
for (n = 0; n < len; n++)
{
el = (GdomeElement *) gdome_nl_item (action_nl, n, &e);
name = gdome_el_getAttribute (el, name_str, &e);
node = gdome_el_firstChild (el, &e);
title = gdome_n_nodeValue (node, &e);
title_strip = g_strstrip (g_strdup (g_dgettext (text_dom, title->str)));
gdome_el_unref (el, &e);
gdome_n_unref (node, &e);
gdome_str_unref (title);
action_data = g_new (ActionData, 1);
action_data->entry = g_new0 (GtkActionEntry, 1);
action_data->entry->name = g_strdup (name->str);
action_data->entry->label = g_strdup (title_strip);
action_data->form = NULL;
mod_actions = g_slist_prepend (mod_actions, action_data);
gtk_action_group_add_actions (actions, action_data->entry, 1, NULL);
gdome_str_unref (name);
g_free (title_strip);
}
ui_file = g_strdup_printf ("%s/%s.ui", dir, mod_name);
if (g_file_get_contents (ui_file, &buffer, NULL, &err))
{
ModData * mod_data = g_new (ModData, 1);
mod_data->action_data = mod_actions;
mod_data->mod = mod;
vn_mod_set_ui (mod, buffer);
obj->modules = g_slist_prepend (obj->modules, mod_data);
}
else
{
g_warning ("VnGui: %s", err->message);
g_error_free (err);
g_slist_free_full (mod_actions,
(GDestroyNotify) vn_gui_free_action_data);
}
g_free (ui_file);
// g_object_unref (mod);
g_object_unref (actions);
} }
g_free (mod_title_strip); g_free (mod_title_strip);
@ -510,22 +392,18 @@ static void vn_gui_load_module (VnGui * obj, const gchar * dir, const gchar * fi
gdome_str_unref (name_str); gdome_str_unref (name_str);
gdome_str_unref (mod_title); gdome_str_unref (mod_title);
gdome_nl_unref (nl, &e); gdome_nl_unref (nl, &e);
gdome_nl_unref (action_nl, &e); // gdome_nl_unref (action_nl, &e);
} }
static VnWindow * vn_gui_add_window (VnGui * obj, GtkWindow * widget, GtkNotebook * notebook) static VnWindow * vn_gui_add_window (VnGui * obj, GtkWindow * widget, GtkNotebook * notebook)
{ {
GSList * n, * m; GSList * n;
GError * err = NULL; GtkWidget * button;
GtkActionGroup * actions = NULL; VnWindow * window = g_new (VnWindow, 1);
GtkBuilder * builder;
VnWindow * window;
window = g_new (VnWindow, 1);
window->obj = obj; window->obj = obj;
window->widget = widget; window->widget = widget;
window->notebook = notebook; window->notebook = notebook;
window->manager = gtk_ui_manager_new ();
window->active_form = NULL; window->active_form = NULL;
window->merge_id = 0; window->merge_id = 0;
@ -534,87 +412,40 @@ static VnWindow * vn_gui_add_window (VnGui * obj, GtkWindow * widget, GtkNoteboo
gtk_notebook_set_group_name (notebook, gtk_notebook_set_group_name (notebook,
g_application_get_application_id (G_APPLICATION (obj->app))); g_application_get_application_id (G_APPLICATION (obj->app)));
gtk_widget_show_all (GTK_WIDGET (widget)); // Setting header and window menu
// Loading the bars and associated actions window->header = g_object_new (GTK_TYPE_HEADER_BAR
,"show-close-button", TRUE
,"has-subtitle", TRUE
,"title", gtk_window_get_title (widget)
,NULL);
gtk_window_set_titlebar (widget,
GTK_WIDGET (window->header));
builder = gtk_builder_new (); button = gtk_menu_button_new ();
g_action_map_add_action_entries (G_ACTION_MAP (window->widget),
win_entries, G_N_ELEMENTS (win_entries), window);
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), obj->main_menu);
gtk_button_set_image (GTK_BUTTON (button),
gtk_image_new_from_icon_name ("preferences-system-symbolic",
GTK_ICON_SIZE_BUTTON));
gtk_header_bar_pack_end (window->header, button);
if (gtk_builder_add_from_file (builder, ACTIONS_UI, &err)) button = gtk_menu_button_new ();
{ gtk_widget_set_no_show_all (button, TRUE);
actions = gtk_builder_get (builder, "main-actions"); gtk_header_bar_pack_start (window->header, button);
gtk_builder_connect_signals (builder, window); window->menu_button = button;
gtk_ui_manager_insert_action_group (window->manager, actions, -1);
}
else
{
g_warning ("VnGui: %s", err->message);
g_clear_error (&err);
}
if (gtk_ui_manager_add_ui_from_file (window->manager, MENUBAR_XML, &err))
{
GtkBox * box = GTK_BOX (gtk_bin_get_child (GTK_BIN (widget)));
GtkWidget * menubar = gtk_ui_manager_get_widget (window->manager, "/MenuBar");
GtkWidget * toolbar = gtk_ui_manager_get_widget (window->manager, "/Toolbar");
gtk_box_pack_start (box, menubar, FALSE, FALSE, 0);
gtk_box_pack_start (box, toolbar, FALSE, FALSE, 0);
gtk_style_context_add_class (gtk_widget_get_style_context (toolbar),
GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
gtk_window_add_accel_group (widget,
gtk_ui_manager_get_accel_group (window->manager));
window->toolbar = toolbar;
}
else
{
window->toolbar = NULL;
g_warning ("VnGui: %s", err->message);
g_error_free (err);
}
if (actions)
{
// TODO: Load from config file the default value for toggle actions.
window->dynamic_tabs = gtk_builder_get (builder, "menu-view-tabs");
gtk_toggle_action_set_active (window->dynamic_tabs, TRUE);
window->view_toolbar = gtk_builder_get (builder, "menu-view-toolbar");
gtk_toggle_action_set_active (window->view_toolbar, TRUE);
}
g_object_unref (builder);
// Loading the modules actions // Loading the modules actions
for (n = obj->modules; n; n = n->next) for (n = obj->mod_actions; n; n = n->next)
{ {
ModData * mod_data = n->data; GActionEntry * entries = n->data;
GtkActionGroup * mod_actions = gtk_action_group_new (vn_mod_get_name (mod_data->mod)); g_action_map_add_action_entries (G_ACTION_MAP (window->widget),
entries, -1, window);
for (m = mod_data->action_data; m; m = m->next)
{
ActionData * action_data = m->data;
gtk_action_group_add_actions (mod_actions
,action_data->entry, 1
,action_data->form
);
}
gtk_ui_manager_insert_action_group (window->manager, mod_actions, -1);
g_object_unref (mod_actions);
if (!gtk_ui_manager_add_ui_from_string (window->manager,
vn_mod_get_ui (mod_data->mod), -1, &err))
{
g_warning ("VnGui: %s", err->message);
g_error_free (err);
}
} }
gtk_ui_manager_ensure_update (window->manager); gtk_widget_show_all (GTK_WIDGET (widget));
return window; return window;
} }
@ -757,27 +588,31 @@ void vn_gui_logout (VnGui * obj, gboolean exit)
static void vn_gui_hide_form (VnWindow * window) static void vn_gui_hide_form (VnWindow * window)
{ {
if (window->active_form) VnForm * form = window->active_form;
{
GtkActionGroup * actions =
vn_form_get_action_group (window->active_form);
if (actions) if (form)
{
/* gint i = 0;
gint size;
const GActionEntry * actions = vn_form_get_actions (form, &size);
//quitar acciones y ocultar menu
while (&actions[i].name)
{ {
gtk_ui_manager_remove_ui (window->manager, window->merge_id); g_action_map_remove_action (G_ACTION_MAP (window->widget),
gtk_ui_manager_remove_action_group (window->manager, actions); actions[i].name);
i++;
} }
window->active_form = NULL; gtk_widget_hide (window->menu_button);
window->active_form = NULL;*/
} }
} }
static void vn_gui_set_show_tabs (VnWindow * window) static void vn_gui_set_show_tabs (VnWindow * window)
{ {
gboolean show_tabs = gtk_notebook_get_n_pages (window->notebook) > 1 gtk_notebook_set_show_tabs (window->notebook,
|| !gtk_toggle_action_get_active (window->dynamic_tabs); gtk_notebook_get_n_pages (window->notebook) > 1);
gtk_notebook_set_show_tabs (window->notebook, show_tabs);
} }
//--------------------------------------------------- Window handlers //--------------------------------------------------- Window handlers
@ -822,57 +657,39 @@ GtkNotebook * vn_gui_on_page_detached (GtkNotebook * old_notebook,
*/ */
void vn_gui_on_switch_page (GtkNotebook * notebook, VnForm * form, guint num, VnWindow * window) void vn_gui_on_switch_page (GtkNotebook * notebook, VnForm * form, guint num, VnWindow * window)
{ {
GError * err = NULL;
GtkTreeIter * iter; GtkTreeIter * iter;
GtkActionGroup * actions; GMenuModel * menu;
VnGui * obj = window->obj; VnGui * obj = window->obj;
vn_gui_hide_form (window); vn_gui_hide_form (window);
// Merge form UI with the window UI
window->active_form = form; window->active_form = form;
if ((iter = g_hash_table_lookup (obj->forms, vn_form_get_name (form)))) if ((iter = g_hash_table_lookup (obj->forms, vn_form_get_name (form))))
{ {
gchar * window_title, * form_title; gchar * form_title;
gtk_tree_model_get (GTK_TREE_MODEL (obj->tree), gtk_tree_model_get (GTK_TREE_MODEL (obj->tree),
iter, COL_TITLE, &form_title, -1); iter, COL_TITLE, &form_title, -1);
gtk_header_bar_set_subtitle (window->header, form_title);
window_title = g_strdup_printf ("%s - %s", form_title, obj->app_title);
gtk_window_set_title (window->widget, window_title);
g_free (form_title); g_free (form_title);
g_free (window_title);
} }
if ((actions = vn_form_get_action_group (form))) // Set active form Menu
menu = vn_form_get_menu_model (form);
if (menu)
{ {
guint merge_id; gint size;
const gchar * form_ui = vn_form_get_ui_manager (form); const GActionEntry * actions = vn_form_get_actions (form, &size);
gtk_ui_manager_insert_action_group (window->manager, actions, -1); g_action_map_add_action_entries (G_ACTION_MAP (window->widget),
actions, size, form);
if ((merge_id = gtk_ui_manager_add_ui_from_string (window->manager, gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (window->menu_button), menu);
form_ui, -1, &err))) gtk_widget_show (window->menu_button);
{
window->merge_id = merge_id;
}
else
{
g_warning ("VnGui: %s", err->message);
g_error_free (err);
}
} }
gtk_ui_manager_ensure_update (window->manager);
}
void vn_gui_on_page_added (GtkNotebook * notebook,
GtkWidget * page, guint num, VnWindow * window)
{
vn_gui_set_show_tabs (window);
} }
/* /*
@ -881,13 +698,13 @@ void vn_gui_on_page_added (GtkNotebook * notebook,
void vn_gui_on_main_page_removed (GtkNotebook * notebook, void vn_gui_on_main_page_removed (GtkNotebook * notebook,
GtkWidget * page, guint num, VnWindow * window) GtkWidget * page, guint num, VnWindow * window)
{ {
vn_gui_set_show_tabs (window);
if (gtk_notebook_get_n_pages (notebook) < 1) if (gtk_notebook_get_n_pages (notebook) < 1)
{ {
vn_gui_hide_form (window); vn_gui_hide_form (window);
gtk_window_set_title (window->widget, window->obj->app_title); gtk_header_bar_set_subtitle (window->header, window->obj->app_title);
} }
vn_gui_set_show_tabs (window);
} }
/* /*
@ -897,10 +714,19 @@ void vn_gui_on_main_page_removed (GtkNotebook * notebook,
void vn_gui_on_page_removed (GtkNotebook * notebook, void vn_gui_on_page_removed (GtkNotebook * notebook,
GtkWidget * page, guint num, VnWindow * window) GtkWidget * page, guint num, VnWindow * window)
{ {
vn_gui_set_show_tabs (window);
if (gtk_notebook_get_n_pages (notebook) < 1) if (gtk_notebook_get_n_pages (notebook) < 1)
gtk_widget_destroy (GTK_WIDGET (window->widget)); gtk_widget_destroy (GTK_WIDGET (window->widget));
vn_gui_set_show_tabs (window);
}
/*
* Called each time a page is added to a notebook.
*/
void vn_gui_on_page_added (GtkNotebook * notebook, GtkWidget * page, guint num,
VnWindow * window)
{
vn_gui_set_show_tabs (window);
} }
//--------------------------------------------------- Action handlers //--------------------------------------------------- Action handlers
@ -908,66 +734,54 @@ void vn_gui_on_page_removed (GtkNotebook * notebook,
/* /*
* Opens a form when the action associated to it is activated. * Opens a form when the action associated to it is activated.
*/ */
void vn_gui_on_open_form_activated (GtkAction * action, FormData * form_data) void vn_gui_on_open_form_activated (GSimpleAction * a, GVariant * p, gpointer obj)
{ {
vn_gui_open_form (form_data->gui, form_data->name); VnWindow * window = obj;
} vn_gui_open_form_at_window (window->obj,
g_variant_get_string (g_action_get_state (G_ACTION (a)), NULL), window);
/*
* Reconnects to database.
*/
void vn_gui_on_open_activated (GtkAction * action, VnWindow * window)
{
vn_gui_reconnect (window->obj);
} }
/* /*
* Logout action handler. * Logout action handler.
*/ */
void vn_gui_on_logout_activated (GtkAction * action, VnWindow * window) void vn_gui_on_logout_activated (GSimpleAction * a, GVariant * v, gpointer obj)
{ {
vn_gui_logout (window->obj, FALSE); vn_gui_logout (obj, FALSE);
} }
/* /*
* Exit action handler. * Reconnects to database.
*/ */
void vn_gui_on_exit_activated (GtkAction * action, VnWindow * window) void vn_gui_on_open_activated (GSimpleAction * a, GVariant * v, gpointer obj)
{ {
vn_gui_logout (window->obj, TRUE); vn_gui_reconnect (obj);
}
/*
* Closes the current tab when the close-tab action is activated.
*/
void vn_gui_on_close_tab_activated (GtkAction * action, VnWindow * window)
{
if (window->active_form)
vn_gui_close_form (window->obj, window->active_form);
}
/*
* Shows/hides the tabs when the view-tabs action is activated
*/
void vn_gui_on_dynamic_tabs_activated (GtkToggleAction * action, VnWindow * window)
{
vn_gui_set_show_tabs (window);
}
/*
* Shows/hides the toolbar when the view-toolbar action is activated
*/
void vn_gui_on_view_toolbar_activated (GtkToggleAction * action, VnWindow * window)
{
gtk_widget_set_visible (window->toolbar, gtk_toggle_action_get_active (action));
} }
/* /*
* Shows a window with program information. * Shows a window with program information.
*/ */
void vn_gui_on_about_activated (GtkAction * action, VnWindow * window) void vn_gui_on_about_activated (GSimpleAction * a, GVariant * v, gpointer obj)
{ {
gtk_dialog_run (window->obj->about); gtk_dialog_run (VN_GUI (obj)->about);
}
/*
* Exit action handler.
*/
void vn_gui_on_exit_activated (GSimpleAction * a, GVariant * v, gpointer obj)
{
vn_gui_logout (obj, TRUE);
}
/*
* Closes the current tab when the close-tab action is activated.
*/
void vn_gui_on_close_tab_activated (GSimpleAction * a, GVariant * v, gpointer obj)
{
VnWindow * window = obj;
if (window->active_form)
vn_gui_close_form (window->obj, window->active_form);
} }
//--------------------------------------------------- Connection handlers //--------------------------------------------------- Connection handlers
@ -1034,6 +848,47 @@ void vn_gui_open (VnGui * obj)
builder = gtk_builder_new (); builder = gtk_builder_new ();
// Loading Application Menu
if (gtk_builder_add_from_file (builder, MENU_UI, &err))
{
GSList * n;
GMenu * section;
GMenuModel * menu = G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu"));
g_action_map_add_action_entries (G_ACTION_MAP (obj->app), app_entries,
G_N_ELEMENTS (app_entries), obj);
gtk_application_set_app_menu (obj->app, menu);
obj->main_menu = gtk_builder_get (builder, "win-menu");
section = gtk_builder_get (builder, "modules");
obj->modules = g_slist_reverse (obj->modules);
for (n = obj->modules; n; n = n->next)
{
VnMod * mod = VN_MOD (n->data);
GMenuModel * mod_menu = vn_mod_get_menu_model (mod);
if (mod_menu)
{//FIXME coger etiqueta del elemento en lugar del nombre!!
gchar * label = g_strdup (vn_mod_get_name (mod));
if (label && label[0] != '\0')
label[0] = g_ascii_toupper (label[0]);
g_menu_append_submenu (section, label, mod_menu);
g_object_unref (mod_menu);
g_free (label);
}
}
}
else if (err)
{
g_warning ("VnGui: %s", err->message);
g_clear_error (&err);
}
if (gtk_builder_add_from_file (builder, MAIN_UI, &err)) if (gtk_builder_add_from_file (builder, MAIN_UI, &err))
{ {
gchar * user; gchar * user;
@ -1046,21 +901,22 @@ void vn_gui_open (VnGui * obj)
obj->about = gtk_builder_get (builder, "about"); obj->about = gtk_builder_get (builder, "about");
obj->menu = gtk_builder_get (builder, "menu"); obj->menu = gtk_builder_get (builder, "menu");
obj->status_label = gtk_builder_get (builder, "status-label"); obj->status_label = gtk_builder_get (builder, "status-label");
user = db_conn_get_user (obj->conn); user = db_conn_get_user (obj->conn);
label = gtk_builder_get (builder, "user-name"); label = gtk_builder_get (builder, "user-name");
gtk_label_set_text (label, user); gtk_label_set_text (label, user);
g_free (user); g_free (user);
widget = gtk_builder_get (builder, "window"); widget = gtk_builder_get (builder, "window");
notebook = gtk_builder_get (builder, "notebook"); notebook = gtk_builder_get (builder, "notebook");
obj->main_window = vn_gui_add_window (obj, widget, notebook); obj->main_window = vn_gui_add_window (obj, widget, notebook);
gtk_builder_connect_signals (GTK_BUILDER (builder), obj->main_window); gtk_builder_connect_signals (GTK_BUILDER (builder), obj->main_window);
// Restoring interface // Restoring interface
config = g_key_file_new (); config = g_key_file_new ();
if (g_key_file_load_from_file (config, obj->config_file, 0, NULL)) if (g_key_file_load_from_file (config, obj->config_file, 0, NULL))
{ {
gsize m, n; gsize m, n;
@ -1073,7 +929,7 @@ void vn_gui_open (VnGui * obj)
VnWindow * window; VnWindow * window;
windows = g_key_file_get_groups (config, &len); windows = g_key_file_get_groups (config, &len);
for (m = 0; m < len; m++) for (m = 0; m < len; m++)
{ {
x = g_key_file_get_integer (config, windows[m], "x", NULL); x = g_key_file_get_integer (config, windows[m], "x", NULL);
@ -1210,7 +1066,7 @@ VnWindow * vn_gui_create_window (VnGui * obj, gint x, gint y)
GtkBuilder * builder; GtkBuilder * builder;
VnWindow * window = NULL; VnWindow * window = NULL;
GError * err = NULL; GError * err = NULL;
g_return_val_if_fail (VN_IS_GUI (obj), NULL); g_return_val_if_fail (VN_IS_GUI (obj), NULL);
g_return_val_if_fail (obj->main_window, NULL); g_return_val_if_fail (obj->main_window, NULL);
@ -1220,7 +1076,7 @@ VnWindow * vn_gui_create_window (VnGui * obj, gint x, gint y)
{ {
GtkWindow * widget; GtkWindow * widget;
GtkNotebook * notebook; GtkNotebook * notebook;
widget = gtk_builder_get (builder, "child"); widget = gtk_builder_get (builder, "child");
notebook = gtk_builder_get (builder, "notebook"); notebook = gtk_builder_get (builder, "notebook");
gtk_window_move (widget, x, y); gtk_window_move (widget, x, y);
@ -1260,12 +1116,12 @@ VnForm * vn_gui_open_form_at_window (VnGui * obj, const gchar * form_name, VnWin
GtkWidget * button; GtkWidget * button;
GtkTreeIter * iter; GtkTreeIter * iter;
GtkNotebook * notebook = NULL; GtkNotebook * notebook = NULL;
g_return_val_if_fail (VN_IS_GUI (obj), NULL); g_return_val_if_fail (VN_IS_GUI (obj), NULL);
g_return_val_if_fail (obj->main_window, NULL); g_return_val_if_fail (obj->main_window, NULL);
iter = g_hash_table_lookup (obj->forms, form_name); iter = g_hash_table_lookup (obj->forms, form_name);
if (!iter) if (!iter)
{ {
g_warning ("VnGui: Form %s doesn't exist", form_name); g_warning ("VnGui: Form %s doesn't exist", form_name);
@ -1313,6 +1169,8 @@ VnForm * vn_gui_open_form_at_window (VnGui * obj, const gchar * form_name, VnWin
gtk_notebook_append_page (notebook, form, GTK_WIDGET (hbox))); gtk_notebook_append_page (notebook, form, GTK_WIDGET (hbox)));
gtk_notebook_set_tab_detachable (notebook, form, TRUE); gtk_notebook_set_tab_detachable (notebook, form, TRUE);
gtk_notebook_set_tab_reorderable (notebook, form, TRUE); gtk_notebook_set_tab_reorderable (notebook, form, TRUE);
gtk_container_child_set (GTK_CONTAINER (notebook), form,
"tab-expand", TRUE, NULL);
gtk_widget_show_all (GTK_WIDGET (hbox)); gtk_widget_show_all (GTK_WIDGET (hbox));
gtk_widget_show (form); gtk_widget_show (form);
@ -1408,9 +1266,9 @@ static void vn_gui_set_property (VnGui * obj, guint id,
gchar * app_name; gchar * app_name;
gchar * config_dir; gchar * config_dir;
gchar * lib_path, * data_path; gchar * lib_path, * data_path;
obj->app = g_value_dup_object (value); obj->app = g_value_dup_object (value);
app_id = g_application_get_application_id (G_APPLICATION (obj->app)); app_id = g_application_get_application_id (G_APPLICATION (obj->app));
app_name = g_strrstr (app_id, ".") + 1; app_name = g_strrstr (app_id, ".") + 1;
@ -1439,7 +1297,7 @@ static void vn_gui_set_property (VnGui * obj, guint id,
g_free (data_path); g_free (data_path);
g_free (lib_path); g_free (lib_path);
// Initializing modules // Initializing modules
for (n = 0; obj->data_dirs[n]; n++) for (n = 0; obj->data_dirs[n]; n++)
@ -1447,7 +1305,7 @@ static void vn_gui_set_property (VnGui * obj, guint id,
const gchar * file; const gchar * file;
GError * err = NULL; GError * err = NULL;
GDir * dir = g_dir_open (obj->data_dirs[n], 0, &err); GDir * dir = g_dir_open (obj->data_dirs[n], 0, &err);
if (dir) if (dir)
{ {
while ((file = g_dir_read_name (dir))) while ((file = g_dir_read_name (dir)))
@ -1502,6 +1360,9 @@ static void vn_gui_init (VnGui * obj)
obj->lib_dirs = NULL; obj->lib_dirs = NULL;
obj->data_dirs = NULL; obj->data_dirs = NULL;
obj->config_file = NULL; obj->config_file = NULL;
obj->main_menu = NULL;
obj->mod_actions = NULL;
obj->modules = NULL;
obj->forms = g_hash_table_new_full ( obj->forms = g_hash_table_new_full (
(GHashFunc) g_str_hash (GHashFunc) g_str_hash
@ -1524,7 +1385,8 @@ static void vn_gui_finalize (VnGui * obj)
db_conn_close (obj->conn, FALSE); db_conn_close (obj->conn, FALSE);
g_hash_table_unref (obj->forms); g_hash_table_unref (obj->forms);
g_slist_free_full (obj->modules, (GDestroyNotify) vn_gui_free_mod_data); g_slist_free_full (obj->mod_actions, g_free);
g_slist_free_full (obj->modules, g_object_unref);
g_clear_object (&obj->conn); g_clear_object (&obj->conn);
g_clear_object (&obj->tree); g_clear_object (&obj->tree);
g_clear_object (&obj->app); g_clear_object (&obj->app);

View File

@ -53,6 +53,9 @@ struct _VnGui
GtkSpinner * spinner; GtkSpinner * spinner;
GtkDialog * about; GtkDialog * about;
GtkLabel * status_label; GtkLabel * status_label;
GtkHeaderBar * header;
GMenuModel * main_menu;
GSList * mod_actions;
GHashTable * forms; GHashTable * forms;
GSList * windows; GSList * windows;

View File

@ -22,9 +22,7 @@ struct _VnModPrivate
gchar * name; gchar * name;
gchar * data_dir; gchar * data_dir;
gchar * text_domain; gchar * text_domain;
gchar * ui;
GModule * module; GModule * module;
GtkActionGroup * actions;
}; };
G_DEFINE_TYPE (VnMod, vn_mod, G_TYPE_OBJECT); G_DEFINE_TYPE (VnMod, vn_mod, G_TYPE_OBJECT);
@ -65,19 +63,36 @@ const gchar * vn_mod_get_data_dir (VnMod * obj)
return obj->priv->data_dir; return obj->priv->data_dir;
} }
const gchar * vn_mod_get_ui (VnMod * obj) /**
* vn_mod_get_menu_model:
* Returns: (transfer full):
**/
GMenuModel * vn_mod_get_menu_model (VnMod * obj)
{ {
gchar * menu_file;
GMenuModel * menu = NULL;
GtkBuilder * builder;
GError * err = NULL;
g_return_val_if_fail (VN_IS_MOD (obj), NULL); g_return_val_if_fail (VN_IS_MOD (obj), NULL);
return obj->priv->ui; menu_file = g_strdup_printf ("%s/%s-menu.glade",
} obj->priv->data_dir, obj->priv->name);
builder = gtk_builder_new ();
void vn_mod_set_ui (VnMod * obj, gchar * ui) if (gtk_builder_add_from_file (builder, menu_file, &err))
{ menu = g_object_ref (G_MENU_MODEL (gtk_builder_get_object (builder, "menu")));
g_return_if_fail (VN_IS_MOD (obj)); else if (err)
{
if (err->code != G_FILE_ERROR_NOENT)
g_warning (err->message);
g_free (obj->priv->ui); g_clear_error (&err);
obj->priv->ui = ui; }
g_free (menu_file);
g_object_unref (builder);
return menu;
} }
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
@ -148,8 +163,6 @@ static void vn_mod_init (VnMod * obj)
obj->priv->data_dir = NULL; obj->priv->data_dir = NULL;
obj->priv->module = NULL; obj->priv->module = NULL;
obj->priv->text_domain = NULL; obj->priv->text_domain = NULL;
obj->priv->ui = NULL;
obj->priv->actions = NULL;
} }
static void vn_mod_finalize (VnMod * obj) static void vn_mod_finalize (VnMod * obj)
@ -157,8 +170,6 @@ static void vn_mod_finalize (VnMod * obj)
g_free (obj->priv->name); g_free (obj->priv->name);
g_free (obj->priv->data_dir); g_free (obj->priv->data_dir);
g_free (obj->priv->text_domain); g_free (obj->priv->text_domain);
g_free (obj->priv->ui);
g_object_unref (obj->priv->actions);
G_OBJECT_CLASS (vn_mod_parent_class)->finalize (G_OBJECT (obj)); G_OBJECT_CLASS (vn_mod_parent_class)->finalize (G_OBJECT (obj));
} }

View File

@ -47,12 +47,11 @@ struct _VnModClass
void (* activate) (VnMod * obj); void (* activate) (VnMod * obj);
}; };
GType vn_mod_get_type (); GType vn_mod_get_type ();
void vn_mod_activate (VnMod * obj); void vn_mod_activate (VnMod * obj);
const gchar * vn_mod_get_name (VnMod * obj); const gchar * vn_mod_get_name (VnMod * obj);
const gchar * vn_mod_get_text_domain (VnMod * obj); const gchar * vn_mod_get_text_domain (VnMod * obj);
const gchar * vn_mod_get_data_dir (VnMod * obj); const gchar * vn_mod_get_data_dir (VnMod * obj);
const gchar * vn_mod_get_ui (VnMod * obj); GMenuModel * vn_mod_get_menu_model (VnMod * obj);
void vn_mod_set_ui (VnMod * obj, gchar * ui);
#endif #endif