/* * 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)); }