This repository has been archived on 2024-07-15. You can view files and clone it, but cannot push or open issues or pull requests.
hedera/vn/vn-handler.c

552 lines
14 KiB
C
Raw Normal View History

2013-10-11 23:07:35 +00:00
/*
* Copyright (C) 2012 - Juan Ferrer Toribio
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "vn-handler.h"
G_DEFINE_TYPE (VnHandler, vn_handler, GTK_TYPE_HBUTTON_BOX);
/**
* vn_handler_new:
*
* Creates a new handler
*
* Return value: #GtkWidget created.
**/
GtkWidget * vn_handler_new ()
{
return g_object_new (VN_TYPE_HANDLER, NULL);
}
/**
* vn_handler_new_with_form:
* @form: #DbIterator where the handler will be created
*
* Creates a new handler into a iterator gived
*
* Return value: #GtkWidget created.
**/
GtkWidget * vn_handler_new_with_iterator (DbIterator * iterator)
{
return g_object_new (VN_TYPE_HANDLER, "iterator", iterator, NULL);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Private
static void vn_handler_on_add_activated (GtkAction * action, VnHandler * obj)
{
db_iterator_insert (obj->iterator);
}
static void vn_handler_on_remove_activated (GtkAction * action, VnHandler * obj)
{
GtkWidget * toplevel;
GtkWidget * dialog;
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (obj));
dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel)
,GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT
,GTK_MESSAGE_QUESTION
,GTK_BUTTONS_OK_CANCEL
,_("Are you sure you want to delete the selected record?")
);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
db_iterator_delete (obj->iterator);
gtk_widget_destroy (dialog);
}
static void vn_handler_on_save_activated (GtkAction * action, VnHandler * obj)
{
db_iterator_perform_operations (obj->iterator);
}
static void vn_handler_on_undo_activated (GtkAction * action, VnHandler * obj)
{
GtkWidget * toplevel;
GtkWidget * dialog;
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (obj));
dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel)
,GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT
,GTK_MESSAGE_QUESTION
,GTK_BUTTONS_OK_CANCEL
,_("Are you sure that you want to undo all changes?")
);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
db_iterator_reverse_operations (obj->iterator);
gtk_widget_destroy (dialog);
}
static void vn_handler_on_refresh_activated (GtkAction * action, VnHandler * obj)
{
db_iterator_refresh (obj->iterator);
}
static void vn_handler_on_move_activated (GtkAction * action, VnHandler * obj)
{
DbIteratorMove move;
if (action == obj->move_previous)
move = DB_ITERATOR_MOVE_PREVIOUS;
else if (action == obj->move_next)
move = DB_ITERATOR_MOVE_NEXT;
else if (action == obj->move_last)
move = DB_ITERATOR_MOVE_LAST;
else
move = DB_ITERATOR_MOVE_FIRST;
db_iterator_move_to (obj->iterator, move);
}
static void vn_handler_refresh_save_undo_status (VnHandler * obj)
{
gboolean sensitive = obj->iterator
&& db_iterator_has_pending_operations (obj->iterator);
if (obj->show_flags & VN_HANDLER_SHOW_SAVE)
gtk_action_set_sensitive (obj->save, sensitive);
if (obj->show_flags & VN_HANDLER_SHOW_UNDO)
gtk_action_set_sensitive (obj->undo, sensitive);
}
static void vn_handler_refresh_scroll_status (VnHandler * obj)
{
if (obj->show_flags & VN_HANDLER_SHOW_SCROLL)
{
gboolean sensitive;
gint row = db_iterator_get_row (obj->iterator);
sensitive = row > 0;
gtk_action_set_sensitive (obj->move_first, sensitive);
gtk_action_set_sensitive (obj->move_previous, sensitive);
sensitive = row != -1 && row < db_iterator_get_nrows (obj->iterator) - 1;
gtk_action_set_sensitive (obj->move_next, sensitive);
gtk_action_set_sensitive (obj->move_last, sensitive);
}
}
static void vn_handler_on_data_changed (DbIterator * iterator, VnHandler * obj)
{
if (obj->show_flags & VN_HANDLER_SHOW_ADD)
{
gboolean sensitive =
db_iterator_get_update_flags (iterator) & DB_MODEL_INSERT
&& (db_iterator_get_nrows (iterator) < 1 || !obj->simple_record);
gtk_action_set_sensitive (obj->add, sensitive);
}
vn_handler_refresh_save_undo_status (obj);
vn_handler_refresh_scroll_status (obj);
}
static void vn_handler_on_row_num_changed (DbIterator * iterator, VnHandler * obj)
{
if (obj->show_flags & VN_HANDLER_SHOW_REMOVE)
{
gboolean sensitive =
db_iterator_get_update_flags (iterator) & DB_MODEL_DELETE
&& db_iterator_get_row (iterator) != -1;
gtk_action_set_sensitive (obj->remove, sensitive);
}
vn_handler_refresh_scroll_status (obj);
}
static void vn_handler_on_operations_done (DbIterator * iterator, VnHandler * obj)
{
vn_handler_refresh_save_undo_status (obj);
}
static void vn_handler_on_status_changed (DbIterator * iterator, gboolean ready, VnHandler * obj)
{
gtk_action_group_set_sensitive (obj->group, ready);
vn_handler_on_row_num_changed (iterator, obj);
vn_handler_on_data_changed (iterator, obj);
}
static void vn_handler_refresh_status (VnHandler * obj)
{
if (!obj->iterator)
gtk_action_group_set_sensitive (obj->group, FALSE);
else
vn_handler_on_status_changed (obj->iterator,
db_iterator_is_ready (obj->iterator), obj);
}
static VnHandlerShowFlags entries_flags[] =
{
VN_HANDLER_SHOW_UNDO
,VN_HANDLER_SHOW_SAVE
,VN_HANDLER_SHOW_REFRESH
,VN_HANDLER_SHOW_REMOVE
,VN_HANDLER_SHOW_ADD
,VN_HANDLER_SHOW_SCROLL
,VN_HANDLER_SHOW_SCROLL
,VN_HANDLER_SHOW_SCROLL
,VN_HANDLER_SHOW_SCROLL
};
static GtkActionEntry entries[] =
{
{
"undo"
,"edit-undo"
,NULL
,NULL
,N_("Undo changes")
,G_CALLBACK (vn_handler_on_undo_activated)
},{
"save"
,"document-save"
,NULL
,NULL
,N_("Save changes")
,G_CALLBACK (vn_handler_on_save_activated)
},{
"refresh"
,"view-refresh"
,NULL
,NULL
,N_("Refresh data")
,G_CALLBACK (vn_handler_on_refresh_activated)
},{
"remove"
,"list-remove"
,NULL
,NULL
,N_("Remove record")
,G_CALLBACK (vn_handler_on_remove_activated)
},{
"add"
,"list-add"
,NULL
,NULL
,N_("Add record")
,G_CALLBACK (vn_handler_on_add_activated)
},{
"move-first"
,"go-first"
,NULL
,NULL
,N_("Move to the first row")
,G_CALLBACK (vn_handler_on_move_activated)
},{
"move-previous"
,"go-previous"
,NULL
,NULL
,N_("Move to the previous row")
,G_CALLBACK (vn_handler_on_move_activated)
},{
"move-next"
,"go-next"
,NULL
,NULL
,N_("Move to the next row")
,G_CALLBACK (vn_handler_on_move_activated)
},{
"move-last"
,"go-last"
,NULL
,NULL
,N_("Move to the last row")
,G_CALLBACK (vn_handler_on_move_activated)
}
};
static guint n_entries = G_N_ELEMENTS (entries);
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Public
/**
* vn_handler_get_iterator:
* @obj: a #VnHandler
*
* Gets the iterator handled by #VnHandler
*
* Return value: (transfer none) (allow-none): the #DbIterator
**/
DbIterator * vn_handler_get_iterator (VnHandler * obj)
{
return obj->iterator;
}
/**
* vn_handler_set_iterator:
* @obj: a #VnHandler
* @iterator: the iterator to be handled
*
* Sets the iterator handled by #VnHandler
**/
void vn_handler_set_iterator (VnHandler * obj, DbIterator * iterator)
{
g_return_if_fail (VN_IS_HANDLER (obj));
g_return_if_fail (DB_IS_ITERATOR (iterator) || !iterator);
if (obj->iterator)
{
g_object_disconnect (obj->iterator
,"any-signal", vn_handler_on_status_changed, obj
,"any-signal", vn_handler_on_data_changed, obj
,"any-signal", vn_handler_on_row_num_changed, obj
,"any-signal", vn_handler_on_operations_done, obj
,NULL
);
g_clear_object (&obj->iterator);
}
if (iterator)
{
obj->iterator = g_object_ref (iterator);
g_object_connect (iterator
,"signal::status-changed", vn_handler_on_status_changed, obj
,"signal::data-changed", vn_handler_on_data_changed, obj
,"signal::row-num-changed", vn_handler_on_row_num_changed, obj
,"signal::operations-done", vn_handler_on_operations_done, obj
,NULL
);
}
vn_handler_refresh_status (obj);
}
/**
* vn_handler_set_show_flags:
* @obj: a #VnHandler
* @show_flags: the buttons to be shown
*
* Sets the buttons that will be shown on the interface.
**/
void vn_handler_set_show_flags (VnHandler * obj, VnHandlerShowFlags show_flags)
{
gint i;
gint items;
GList * j;
g_return_if_fail (VN_IS_HANDLER (obj));
for (j = gtk_action_group_list_actions (obj->group); j; j = j->next)
gtk_action_group_remove_action (obj->group, j->data);
items = gtk_toolbar_get_n_items (obj->toolbar);
for (i = 0; i < items; i++)
{
GtkToolItem * tool_item = gtk_toolbar_get_nth_item (obj->toolbar, 0);
gtk_container_remove (GTK_CONTAINER (obj->toolbar), GTK_WIDGET (tool_item));
}
obj->show_flags = show_flags;
for (i = 0; i < n_entries; i++)
{
if (obj->show_flags & entries_flags[i])
{
gtk_action_group_add_actions (obj->group, &entries[i], 1, obj);
GtkAction * action = gtk_action_group_get_action (obj->group, entries[i].name);
GtkToolItem * item = GTK_TOOL_ITEM (gtk_action_create_tool_item (action));
gtk_tool_item_set_homogeneous (item, TRUE);
gtk_toolbar_insert (obj->toolbar, item, -1);
}
}
if (obj->show_flags & VN_HANDLER_SHOW_ADD)
obj->add = gtk_action_group_get_action (obj->group, "add");
if (obj->show_flags & VN_HANDLER_SHOW_REMOVE)
obj->remove = gtk_action_group_get_action (obj->group, "remove");
if (obj->show_flags & VN_HANDLER_SHOW_SAVE)
obj->save = gtk_action_group_get_action (obj->group, "save");
if (obj->show_flags & VN_HANDLER_SHOW_UNDO)
obj->undo = gtk_action_group_get_action (obj->group, "undo");
if (obj->show_flags & VN_HANDLER_SHOW_SCROLL)
{
obj->move_first = gtk_action_group_get_action (obj->group, "move-first");
obj->move_previous = gtk_action_group_get_action (obj->group, "move-previous");
obj->move_next = gtk_action_group_get_action (obj->group, "move-next");
obj->move_last = gtk_action_group_get_action (obj->group, "move-last");
}
vn_handler_refresh_status (obj);
}
/**
* vn_handler_set_simple_record:
* @obj: a #VnHandler
* @simple: %FALSE if model allows multiple records, %TRUE otherwise
*
* Sets if it is used to handle a iterator with a single record.
**/
void vn_handler_set_simple_record (VnHandler * obj, gboolean simple)
{
g_return_if_fail (VN_IS_HANDLER (obj));
obj->simple_record = simple;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties
enum
{
PROP_FORM = 1
,PROP_SHOW_FLAGS
,PROP_SIMPLE_RECORD
};
static void vn_handler_set_property (VnHandler * obj, guint id,
const GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_FORM:
vn_handler_set_iterator (obj, g_value_get_object (value));
break;
case PROP_SHOW_FLAGS:
vn_handler_set_show_flags (obj, g_value_get_flags (value));
break;
case PROP_SIMPLE_RECORD:
vn_handler_set_simple_record (obj, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
static void vn_handler_get_property (VnHandler * obj, guint id,
GValue * value, GParamSpec * pspec)
{
switch (id)
{
case PROP_FORM:
g_value_set_object (value, obj->iterator);
break;
case PROP_SHOW_FLAGS:
g_value_set_flags (value, obj->show_flags);
break;
case PROP_SIMPLE_RECORD:
g_value_set_boolean (value, obj->simple_record);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ Class
static void vn_handler_init (VnHandler * obj)
{
GdkRGBA color = {0.0, 0.0, 0.0, 0.0};
obj->add = NULL;
obj->remove = NULL;
obj->move_first = NULL;
obj->move_previous = NULL;
obj->move_next = NULL;
obj->move_last = NULL;
obj->iterator = NULL;
gtk_box_set_spacing (GTK_BOX (obj), 6);
gtk_box_set_homogeneous (GTK_BOX (obj), FALSE);
gtk_button_box_set_layout (GTK_BUTTON_BOX (obj), GTK_BUTTONBOX_END);
obj->group = gtk_action_group_new ("form-handler");
obj->toolbar = GTK_TOOLBAR (g_object_new (GTK_TYPE_TOOLBAR
,"icon-size", GTK_ICON_SIZE_LARGE_TOOLBAR
,"toolbar-style", GTK_TOOLBAR_BOTH_HORIZ
,"show-arrow", FALSE
,NULL
));
gtk_widget_override_background_color (GTK_WIDGET (obj->toolbar),
GTK_STATE_FLAG_NORMAL, &color);
gtk_box_pack_end (GTK_BOX (obj), GTK_WIDGET (obj->toolbar), FALSE, FALSE, 0);
}
static void vn_handler_finalize (VnHandler * obj)
{
vn_handler_set_iterator (obj, NULL);
G_OBJECT_CLASS (vn_handler_parent_class)->finalize (G_OBJECT (obj));
}
static void vn_handler_class_init (VnHandlerClass * klass)
{
GObjectClass * k = G_OBJECT_CLASS (klass);
k->finalize = (GObjectFinalizeFunc) vn_handler_finalize;
k->set_property = (GObjectSetPropertyFunc) vn_handler_set_property;
k->get_property = (GObjectGetPropertyFunc) vn_handler_get_property;
g_object_class_install_property (k, PROP_FORM,
g_param_spec_object ("iterator"
,"Iterator"
,"The handled iterator"
,DB_TYPE_ITERATOR
,G_PARAM_CONSTRUCT | G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_SHOW_FLAGS,
g_param_spec_flags ("show-flags"
,_("Show flags")
,_("Sets the buttons that will be shown on the interface")
,VN_TYPE_HANDLER_SHOW_FLAGS
,VN_HANDLER_SHOW_UNDO | VN_HANDLER_SHOW_SAVE | VN_HANDLER_SHOW_REMOVE | VN_HANDLER_SHOW_ADD
,G_PARAM_CONSTRUCT | G_PARAM_READWRITE
));
g_object_class_install_property (k, PROP_SIMPLE_RECORD,
g_param_spec_boolean ("simple-record"
,_("Simple record")
,_("Sets if it is used to handle a iterator with a single record")
,FALSE
,G_PARAM_CONSTRUCT | G_PARAM_READWRITE
));
}
GType vn_handler_show_flags_get_type ()
{
static GType type = 0;
if (type == 0)
{
static const GFlagsValue values[] =
{
{VN_HANDLER_SHOW_REFRESH, "VN_HANDLER_SHOW_REFRESH", "refresh"}
,{VN_HANDLER_SHOW_UNDO, "VN_HANDLER_SHOW_UNDO", "undo"}
,{VN_HANDLER_SHOW_SAVE, "VN_HANDLER_SHOW_SAVE", "save"}
,{VN_HANDLER_SHOW_REMOVE, "VN_HANDLER_SHOW_REMOVE", "remove"}
,{VN_HANDLER_SHOW_ADD, "VN_HANDLER_SHOW_ADD", "add"}
,{VN_HANDLER_SHOW_SCROLL, "VN_HANDLER_SHOW_SCROLL", "scroll"}
,{0, NULL, NULL}
};
type = g_flags_register_static
(g_intern_static_string ("VnHandlerShowFlags"), values);
}
return type;
}