/*
* Copyright (C) 2013 - 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 .
*/
#include "glade-vn.h"
#include
/*
* Contents of this file:
* definition of the DbModel editor as a property for objects implementing
* the DbModelHolder interface.
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++ DbModel GladeEditorProperty
typedef struct
{
GladeEditorProperty parent;
GtkWidget * button;
GtkWidget * entry;
gboolean connected;
GladeWidget * widget;
}
GladeEPropModel;
GLADE_MAKE_EPROP (GladeEPropModel, glade_eprop_model)
#define GLADE_TYPE_EPROP_MODEL (glade_eprop_model_get_type())
#define GLADE_EPROP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_EPROP_MODEL, GladeEPropModel))
#define GLADE_EPROP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_EPROP_MODEL, GladeEPropModelClass))
#define GLADE_IS_EPROP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EPROP_MODEL))
#define GLADE_IS_EPROP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EPROP_MODEL))
#define GLADE_EPROP_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_EPROP_MODEL, GladeEPropModelClass))
static void glade_eprop_model_name_changed (GladeProject * project,
GladeWidget * widget, GladeEPropModel * obj)
{
if (widget == obj->widget)
gtk_entry_set_text (GTK_ENTRY (obj->entry), glade_widget_get_name (widget));
}
static GladeWidget * glade_model_create (GladeProperty * prop)
{
gboolean use = FALSE;
VnBatch * batch;
GladeWidget * batch_w;
GladeProject * project = glade_widget_get_project (glade_property_get_widget (prop));
const GList * l, * n, * objects = glade_project_get_objects (project);
for (n = objects; n; n = n->next)
if (VN_IS_BATCH (n->data))
{
batch = n->data;
use = TRUE;
for (l = vn_batch_get_objects (batch); l; l = l->next)
if (!DB_IS_MODEL (l->data))
{
use = FALSE;
break;
}
if (use)
break;
}
if (!use)
{
batch_w = glade_command_create
(glade_widget_adaptor_get_by_type (VN_TYPE_BATCH), NULL, NULL, project);
glade_widget_set_name (batch_w,
glade_project_new_widget_name (project, batch_w, "models"));
}
else
batch_w = glade_widget_get_from_gobject (batch);
return glade_command_create
(glade_widget_adaptor_get_by_type (VN_TYPE_MODEL), batch_w, NULL, project);
}
/*
* glade_eprop_model_show_dialog:
* @button:(allow-none): a #GtkButton or @NULL
* @object: a #GladeEditorPropery or a #GladeWidget
*
* Opens a dialog to edit a #DbModel.
* Can be called by a #GladeEditorProperty or by the "edit" action of a
* #GladeWidgetAdaptor directly (in which case @button is %NULL and @obj is a
* #GladeWidget).
**/
static void glade_eprop_model_show_dialog (GtkButton * button, GObject * object)
{
gboolean created = FALSE;
GObject * o;
GtkWidget * box;
GtkDialog * dialog;
GladeWidget * widget;
GladeWidgetAdaptor * adaptor;
GladeEditable * editor;
GladeProperty * p = NULL;
GladeEditorProperty * eprop = NULL;
if (GLADE_IS_EDITOR_PROPERTY (object))
{
eprop = GLADE_EDITOR_PROPERTY (object);
p = glade_editor_property_get_property (eprop);
o = g_value_get_object (glade_property_inline_value (p));
if (o && DB_IS_MODEL (o))
widget = glade_widget_get_from_gobject (o);
else
{
GValue val = G_VALUE_INIT;
glade_command_push_group
(_("Create and set a model for a DbModelHolder"));
widget = glade_model_create (p);
created = TRUE;
g_value_init (&val, DB_TYPE_MODEL);
g_value_set_object (&val, glade_widget_get_object (widget));
glade_command_set_property_value (p, &val);
g_value_unset (&val);
glade_command_pop_group ();
glade_project_selection_set (glade_widget_get_project (widget),
glade_widget_get_object (glade_property_get_widget (p)),
TRUE);
if (!GLADE_EPROP_MODEL (eprop)->connected)
{
g_signal_connect (glade_widget_get_project
(glade_property_get_widget (p)), "widget-name-changed",
G_CALLBACK (glade_eprop_model_name_changed), eprop);
GLADE_EPROP_MODEL (eprop)->connected = TRUE;
}
}
}
else
widget = GLADE_WIDGET (object);
adaptor = glade_widget_get_adaptor (widget);
editor = glade_widget_adaptor_create_editable (adaptor, GLADE_PAGE_GENERAL);
glade_editable_load (editor, widget);
dialog = GTK_DIALOG (gtk_dialog_new_with_buttons
(eprop ? _("Model configuration") : _("Model properties configuration")
,GTK_WINDOW (glade_app_get_window ())
,GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT
,_("OK"), GTK_RESPONSE_OK
,_("Clear"), GTK_RESPONSE_REJECT
,_("Cancel"), GTK_RESPONSE_CANCEL
,NULL
));
gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300);
if (!eprop)
gtk_widget_hide (gtk_dialog_get_widget_for_response
(dialog, GTK_RESPONSE_REJECT));
box = gtk_alignment_new (0,0,1,1);
gtk_alignment_set_padding (GTK_ALIGNMENT (box), 8, 8, 8, 8);
gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (editor));
gtk_widget_show_all (box);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (dialog)),
box, TRUE, TRUE, 0);
switch (gtk_dialog_run (dialog))
{
case GTK_RESPONSE_OK:
{
if (eprop)
{
gtk_entry_set_text (GTK_ENTRY (GLADE_EPROP_MODEL (eprop)->entry),
glade_widget_get_name (widget));
GLADE_EPROP_MODEL (eprop)->widget = widget;
}
break;
}
case GTK_RESPONSE_REJECT:
{
if (eprop)
{
glade_command_set_property (p, NULL);
GLADE_EPROP_MODEL (eprop)->widget = NULL;
}
break;
}
case GTK_RESPONSE_CANCEL:
{
if (created)
{
GList * list = g_list_append (NULL, widget);
GladeWidget * batch = glade_widget_get_parent (widget);
if (vn_batch_get_length
VN_BATCH (glade_widget_get_object (batch)) == 1)
list = g_list_prepend (list, batch);
glade_command_delete (list);
g_list_free (list);
GLADE_EPROP_MODEL (eprop)->widget = NULL;
}
break;
}
default:
break;
}
gtk_widget_destroy (GTK_WIDGET (dialog));
}
static void glade_eprop_model_show_object_dialog (GtkButton * button,
GladeEditorProperty * eprop)
{
GladeProperty * p = glade_editor_property_get_property (eprop);
// Widget to which the property belongs (e.g. Model Holder)
GladeWidget * widget = glade_property_get_widget (p);
GladeProject * project = glade_widget_get_project (widget);
GObject * object = g_value_get_object (glade_property_inline_value (p));
// Widget representing the property itself (i.e. VnModel)
widget = object ? glade_widget_get_from_gobject (object) : NULL;
GLADE_EPROP_MODEL (eprop)->widget = widget;
if (glade_editor_property_show_object_dialog (project,
_("Select a VnModel for the property"), NULL,
DB_TYPE_MODEL, NULL, &widget))
{
if (widget)
{
GValue val = G_VALUE_INIT;
g_value_init (&val, DB_TYPE_MODEL);
g_value_set_object (&val, glade_widget_get_object (widget));
glade_command_set_property_value (p, &val);
g_value_unset (&val);
}
else
glade_command_set_property (p, NULL);
}
}
static GtkWidget * glade_eprop_model_create_input (GladeEditorProperty * eprop)
{
GtkWidget * hbox, * box, * object_button;
GladeEPropModel * obj = GLADE_EPROP_MODEL (eprop);
obj->button = gtk_button_new_with_label (_("New Model"));
g_signal_connect (G_OBJECT (obj->button), "clicked",
G_CALLBACK (glade_eprop_model_show_dialog), eprop);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
obj->entry = gtk_entry_new ();
gtk_editable_set_editable (GTK_EDITABLE (obj->entry), FALSE);
gtk_widget_set_hexpand (obj->entry, TRUE);
gtk_container_add (GTK_CONTAINER (hbox), obj->entry);
object_button = gtk_button_new_with_label ("...");
gtk_container_add (GTK_CONTAINER (hbox), object_button);
g_signal_connect (G_OBJECT (object_button), "clicked",
G_CALLBACK (glade_eprop_model_show_object_dialog), eprop);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (box), hbox);
gtk_container_add (GTK_CONTAINER (box), obj->button);
gtk_widget_show_all (box);
obj->widget = NULL;
/* project = glade_widget_get_project (glade_property_get_widget
(glade_editor_property_get_property (eprop)));
*/
return box;
}
static void glade_eprop_model_load (GladeEditorProperty * eprop, GladeProperty * property)
{
gchar * label;
const gchar * text;
GObject * object;
GladeEditorPropertyClass * parent_class =
g_type_class_peek_parent (GLADE_EDITOR_PROPERTY_GET_CLASS (eprop));
parent_class->load (eprop, property);
if (property == NULL)
return;
if ((object = g_value_get_object (glade_property_inline_value (property))))
{
label = _("Edit Model");
text = glade_widget_get_name (glade_widget_get_from_gobject (object));
}
else
{
label = _("New Model");
text = "";
}
gtk_button_set_label (GTK_BUTTON (GLADE_EPROP_MODEL (eprop)->button), label);
gtk_entry_set_text (GTK_ENTRY (GLADE_EPROP_MODEL (eprop)->entry), text);
}
static void glade_eprop_model_finalize (GObject * object)
{
GObjectClass * parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (object));
G_OBJECT_CLASS (parent_class)->finalize (object);
}
//++++++++++++++++++++++++++++++++++++++++++++ DbModelHolder GladeWidgetAdaptor
GladeEditorProperty * glade_db_model_holder_create_eprop (GladeWidgetAdaptor * adaptor,
GladePropertyClass * klass, gboolean use_command)
{
GladeEditorProperty * eprop;
GParamSpec * pspec = glade_property_class_get_pspec (klass);
if (pspec->value_type == DB_TYPE_MODEL)
{
eprop = g_object_new (GLADE_TYPE_EPROP_MODEL,
"property-class", klass,
"use-command", use_command, NULL);
}
else
eprop = GWA_GET_CLASS (G_TYPE_OBJECT)->create_eprop (adaptor, klass, use_command);
return eprop;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++ DbModel Action Callback
void glade_db_model_action_activate (GladeWidgetAdaptor * adaptor,
DbModel * model, const gchar * path)
{
glade_eprop_model_show_dialog (NULL,
(GObject *) glade_widget_get_from_gobject (model));
}