mirror of
https://gitlab.gnome.org/GNOME/glade.git
synced 2025-09-24 00:04:33 -04:00
C Removed chdir code
C * src/glade-app.c: Removed chdir code * src/glade-command.c: Remember original project in paste commands * src/glade-editor-property.c: GladeEPropPixbuf becomes GladeEPropResource, now it interfaces with the glade-project resource control stuff. * src/glade-gtk.c, src/glade-property.c: fixed for new syntax of glade_project_add_object() * src/glade-project-window.c: o Manage project menuitems and "merge-id" outside of glade-project. o New api glade_util_ui_message * src/glade-project.[ch]: Added "resource-update"/"resource-removed" signals and functions: o glade_project_set_resource () o glade_project_list_resources () o glade_project_resource_fullpath () Removed: o glade_project_get_menuitem () o glade_project_get_menuitem_merge_id () Now a new "old_project" parameter to glade_project_add_object () * src/glade-property-class.[ch], src/glade.h: o Added support for "resource" tag in catalogs o Resource file path substituting when generating gvalues (modified glade_property_class_make_gvalue_from_string API). * src/glade-utils.[ch]: o Enhanced version of glade_util_ui_message o glade_util_copy_file () added * src/glade-widget.c: Adjusted for new version of glade_property_class_make_gvalue_from_string * widgets/adding-widgets.txt: Updated manual for resource tag. VS: ----------------------------------------------------------------------
This commit is contained in:
parent
24f10c8f1b
commit
9d924470a9
40
ChangeLog
40
ChangeLog
@ -1,3 +1,43 @@
|
||||
2006-01-22 Tristan Van Berkom <tvb@gnome.org>
|
||||
|
||||
* src/glade-app.c: Removed chdir code
|
||||
|
||||
* src/glade-command.c: Remember original project in paste commands
|
||||
|
||||
* src/glade-editor-property.c: GladeEPropPixbuf becomes GladeEPropResource, now
|
||||
it interfaces with the glade-project resource control stuff.
|
||||
|
||||
* src/glade-gtk.c, src/glade-property.c:
|
||||
fixed for new syntax of glade_project_add_object()
|
||||
|
||||
* src/glade-project-window.c:
|
||||
o Manage project menuitems and "merge-id" outside of glade-project.
|
||||
o New api glade_util_ui_message
|
||||
|
||||
* src/glade-project.[ch]:
|
||||
Added "resource-update"/"resource-removed" signals and functions:
|
||||
o glade_project_set_resource ()
|
||||
o glade_project_list_resources ()
|
||||
o glade_project_resource_fullpath ()
|
||||
Removed:
|
||||
o glade_project_get_menuitem ()
|
||||
o glade_project_get_menuitem_merge_id ()
|
||||
Now a new "old_project" parameter to glade_project_add_object ()
|
||||
|
||||
* src/glade-property-class.[ch], src/glade.h:
|
||||
o Added support for "resource" tag in catalogs
|
||||
o Resource file path substituting when generating gvalues
|
||||
(modified glade_property_class_make_gvalue_from_string API).
|
||||
|
||||
* src/glade-utils.[ch]:
|
||||
o Enhanced version of glade_util_ui_message
|
||||
o glade_util_copy_file () added
|
||||
|
||||
* src/glade-widget.c: Adjusted for new version of
|
||||
glade_property_class_make_gvalue_from_string
|
||||
|
||||
* widgets/adding-widgets.txt: Updated manual for resource tag.
|
||||
|
||||
2006-01-20 Tristan Van Berkom <tvb@gnome.org>
|
||||
|
||||
* src/glade-utils.c: Added glade_util_canonical_path ()
|
||||
|
@ -646,8 +646,6 @@ glade_app_add_project (GladeApp *app, GladeProject *project)
|
||||
void
|
||||
glade_app_remove_project (GladeApp *app, GladeProject *project)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
g_return_if_fail (GLADE_IS_APP (app));
|
||||
g_return_if_fail (GLADE_IS_PROJECT (project));
|
||||
|
||||
@ -690,17 +688,6 @@ glade_app_set_project (GladeApp *app, GladeProject *project)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set current/working directory to project's directory */
|
||||
if (project->path)
|
||||
{
|
||||
gchar *cwd = g_path_get_dirname (project->path);
|
||||
if (cwd)
|
||||
{
|
||||
g_chdir (cwd);
|
||||
g_free (cwd);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear the selection in the previous project */
|
||||
if (app->priv->active_project)
|
||||
glade_project_selection_clear (app->priv->active_project, FALSE);
|
||||
|
@ -46,6 +46,7 @@
|
||||
typedef struct {
|
||||
GladeWidget *widget;
|
||||
GladeWidget *parent;
|
||||
GladeProject *project;
|
||||
GladePlaceholder *placeholder;
|
||||
GList *pack_props;
|
||||
} CommandData;
|
||||
@ -824,7 +825,7 @@ glade_command_create_execute (GladeCommandCreateDelete *me)
|
||||
{
|
||||
glade_project_add_object
|
||||
(GLADE_PROJECT (cdata->widget->project),
|
||||
cdata->widget->object);
|
||||
NULL, cdata->widget->object);
|
||||
glade_default_app_selection_add
|
||||
(cdata->widget->object, TRUE);
|
||||
}
|
||||
@ -979,8 +980,9 @@ glade_command_delete (GList *widgets)
|
||||
widget = list->data;
|
||||
if (widget->internal)
|
||||
{
|
||||
glade_util_ui_warn (glade_default_app_get_window(),
|
||||
_("You cannot delete a widget internal to a composite widget."));
|
||||
glade_util_ui_message (glade_default_app_get_window(),
|
||||
GLADE_UI_WARN,
|
||||
_("You cannot delete a widget internal to a composite widget."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1126,11 +1128,12 @@ GLADE_MAKE_COMMAND (GladeCommandCutCopyPaste, glade_command_cut_copy_paste);
|
||||
static gboolean
|
||||
glade_command_paste_execute (GladeCommandCutCopyPaste *me)
|
||||
{
|
||||
GladeProject *project = glade_default_app_get_active_project ();
|
||||
GladeProject *active_project =
|
||||
glade_default_app_get_active_project ();
|
||||
CommandData *cdata;
|
||||
GList *list, *remove = NULL, *l;
|
||||
|
||||
if (project && me->widgets)
|
||||
if (me->widgets)
|
||||
{
|
||||
glade_default_app_selection_clear (FALSE);
|
||||
|
||||
@ -1201,10 +1204,11 @@ glade_command_paste_execute (GladeCommandCutCopyPaste *me)
|
||||
if (me->from_clipboard &&
|
||||
GTK_WIDGET_TOPLEVEL (cdata->widget->object))
|
||||
glade_project_add_object
|
||||
(project, cdata->widget->object);
|
||||
(active_project, cdata->project,
|
||||
cdata->widget->object);
|
||||
else
|
||||
glade_project_add_object
|
||||
(GLADE_PROJECT (me->project),
|
||||
(me->project, cdata->project,
|
||||
cdata->widget->object);
|
||||
|
||||
glade_default_app_selection_add
|
||||
@ -1406,8 +1410,9 @@ glade_command_cut_copy_paste_common (GList *widgets,
|
||||
widget = list->data;
|
||||
if (widget->internal)
|
||||
{
|
||||
glade_util_ui_warn
|
||||
glade_util_ui_message
|
||||
(glade_default_app_get_window(),
|
||||
GLADE_UI_WARN,
|
||||
_("You cannot copy/cut a widget "
|
||||
"internal to a composite widget."));
|
||||
return;
|
||||
@ -1425,8 +1430,9 @@ glade_command_cut_copy_paste_common (GList *widgets,
|
||||
if (parent == NULL &&
|
||||
GTK_WIDGET_TOPLEVEL (widget->object) == FALSE)
|
||||
{
|
||||
glade_util_ui_warn
|
||||
glade_util_ui_message
|
||||
(glade_default_app_get_window(),
|
||||
GLADE_UI_WARN,
|
||||
_("Only top-level widgets can be "
|
||||
"pasted without a parent."));
|
||||
return;
|
||||
@ -1435,8 +1441,9 @@ glade_command_cut_copy_paste_common (GList *widgets,
|
||||
if (placeholder &&
|
||||
GTK_WIDGET_TOPLEVEL (widget->object))
|
||||
{
|
||||
glade_util_ui_warn
|
||||
glade_util_ui_message
|
||||
(glade_default_app_get_window(),
|
||||
GLADE_UI_WARN,
|
||||
_("You cannot paste a top-level "
|
||||
"to a placeholder."));
|
||||
return;
|
||||
@ -1551,6 +1558,14 @@ glade_command_cut_copy_paste_common (GList *widgets,
|
||||
cdata->widget));
|
||||
}
|
||||
|
||||
/* Save a copy of the original project so we can
|
||||
* forward that to glade-project, who'll copy in
|
||||
* any resource files needed by any properties that
|
||||
* are getting cross-project pasted.
|
||||
*/
|
||||
if (type == GLADE_PASTE)
|
||||
cdata->project = cdata->widget->project;
|
||||
|
||||
me->widgets = g_list_prepend (me->widgets, cdata);
|
||||
}
|
||||
|
||||
|
@ -1631,34 +1631,40 @@ glade_eprop_unichar_create_input (GladeEditorProperty *eprop)
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
GladeEditorPropertyPixbufClass
|
||||
GladeEditorPropertyResourceClass
|
||||
*******************************************************************************/
|
||||
typedef struct {
|
||||
GladeEditorProperty parent_instance;
|
||||
|
||||
GtkWidget *entry, *button;
|
||||
} GladeEPropPixbuf;
|
||||
} GladeEPropResource;
|
||||
|
||||
GLADE_MAKE_EPROP (GladeEPropPixbuf, glade_eprop_pixbuf)
|
||||
#define GLADE_TYPE_EPROP_PIXBUF (glade_eprop_pixbuf_get_type())
|
||||
#define GLADE_EPROP_PIXBUF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_EPROP_PIXBUF, GladeEPropPixbuf))
|
||||
#define GLADE_EPROP_PIXBUF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_EPROP_PIXBUF, GladeEPropPixbufClass))
|
||||
#define GLADE_IS_EPROP_PIXBUF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EPROP_PIXBUF))
|
||||
#define GLADE_IS_EPROP_PIXBUF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EPROP_PIXBUF))
|
||||
#define GLADE_EPROP_PIXBUF_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GLADE_EPROP_PIXBUF, GladeEPropPixbufClass))
|
||||
GLADE_MAKE_EPROP (GladeEPropResource, glade_eprop_resource)
|
||||
#define GLADE_TYPE_EPROP_RESOURCE (glade_eprop_resource_get_type())
|
||||
#define GLADE_EPROP_RESOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_EPROP_RESOURCE, GladeEPropResource))
|
||||
#define GLADE_EPROP_RESOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_EPROP_RESOURCE, GladeEPropResourceClass))
|
||||
#define GLADE_IS_EPROP_RESOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EPROP_RESOURCE))
|
||||
#define GLADE_IS_EPROP_RESOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EPROP_RESOURCE))
|
||||
#define GLADE_EPROP_RESOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GLADE_EPROP_RESOURCE, GladeEPropResourceClass))
|
||||
|
||||
static void
|
||||
glade_eprop_pixbuf_finalize (GObject *object)
|
||||
glade_eprop_resource_finalize (GObject *object)
|
||||
{
|
||||
/* Chain up */
|
||||
G_OBJECT_CLASS (editor_property_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
glade_eprop_pixbuf_entry_activate (GtkEntry *entry, GladeEditorProperty *eprop)
|
||||
glade_eprop_resource_entry_activate (GtkEntry *entry, GladeEditorProperty *eprop)
|
||||
{
|
||||
GValue *value = glade_property_class_make_gvalue_from_string (eprop->class,
|
||||
gtk_entry_get_text(entry));
|
||||
GladeProject *project = glade_widget_get_project (eprop->property->widget);
|
||||
GValue *value = glade_property_class_make_gvalue_from_string
|
||||
(eprop->class, gtk_entry_get_text(entry), project);
|
||||
|
||||
/* Set project resource here where we still have the fullpath.
|
||||
*/
|
||||
glade_project_set_resource (project, eprop->property,
|
||||
gtk_entry_get_text(entry));
|
||||
|
||||
if (eprop->use_command == FALSE)
|
||||
glade_property_set_value (eprop->property, value);
|
||||
@ -1670,12 +1676,13 @@ glade_eprop_pixbuf_entry_activate (GtkEntry *entry, GladeEditorProperty *eprop)
|
||||
}
|
||||
|
||||
static void
|
||||
glade_eprop_pixbuf_select_file (GtkButton *button, GladeEditorProperty *eprop)
|
||||
glade_eprop_resource_select_file (GtkButton *button, GladeEditorProperty *eprop)
|
||||
{
|
||||
GladeEPropPixbuf *eprop_pixbuf = GLADE_EPROP_PIXBUF (eprop);
|
||||
GtkWidget *dialog;
|
||||
GtkFileFilter *filter;
|
||||
gchar *file, *basename;
|
||||
GladeProject *project = glade_widget_get_project (eprop->property->widget);
|
||||
GtkWidget *dialog;
|
||||
GtkFileFilter *filter;
|
||||
GValue *value;
|
||||
gchar *file, *basename;
|
||||
|
||||
if (eprop->loading) return;
|
||||
|
||||
@ -1687,34 +1694,43 @@ glade_eprop_pixbuf_select_file (GtkButton *button, GladeEditorProperty *eprop)
|
||||
NULL);
|
||||
|
||||
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_pixbuf_formats (filter);
|
||||
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
|
||||
|
||||
|
||||
if (eprop->class->pspec->value_type == GDK_TYPE_PIXBUF)
|
||||
{
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_pixbuf_formats (filter);
|
||||
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
|
||||
}
|
||||
|
||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||
|
||||
/*
|
||||
TODO: instead of "basename" we need a relative path to the
|
||||
project's directory.
|
||||
*/
|
||||
|
||||
/* Set project resource here where we still have the fullpath.
|
||||
*/
|
||||
glade_project_set_resource (project, eprop->property, file);
|
||||
basename = g_path_get_basename (file);
|
||||
|
||||
gtk_entry_set_text (GTK_ENTRY(eprop_pixbuf->entry), basename);
|
||||
gtk_widget_activate (eprop_pixbuf->entry);
|
||||
|
||||
value = glade_property_class_make_gvalue_from_string
|
||||
(eprop->class, basename, project);
|
||||
|
||||
if (eprop->use_command == FALSE)
|
||||
glade_property_set_value (eprop->property, value);
|
||||
else
|
||||
glade_command_set_property (eprop->property, value);
|
||||
|
||||
g_value_unset (value);
|
||||
g_free (value);
|
||||
g_free (file);
|
||||
g_free (basename);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
glade_eprop_pixbuf_load (GladeEditorProperty *eprop, GladeProperty *property)
|
||||
glade_eprop_resource_load (GladeEditorProperty *eprop, GladeProperty *property)
|
||||
{
|
||||
GladeEPropPixbuf *eprop_pixbuf = GLADE_EPROP_PIXBUF (eprop);
|
||||
GladeEPropResource *eprop_resource = GLADE_EPROP_RESOURCE (eprop);
|
||||
gchar *file;
|
||||
|
||||
/* Chain up first */
|
||||
@ -1726,37 +1742,37 @@ glade_eprop_pixbuf_load (GladeEditorProperty *eprop, GladeProperty *property)
|
||||
(eprop->class, property->value);
|
||||
if (file)
|
||||
{
|
||||
gtk_entry_set_text (GTK_ENTRY (eprop_pixbuf->entry), file);
|
||||
gtk_entry_set_text (GTK_ENTRY (eprop_resource->entry), file);
|
||||
g_free (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_entry_set_text (GTK_ENTRY (eprop_pixbuf->entry), "");
|
||||
gtk_entry_set_text (GTK_ENTRY (eprop_resource->entry), "");
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
glade_eprop_pixbuf_create_input (GladeEditorProperty *eprop)
|
||||
glade_eprop_resource_create_input (GladeEditorProperty *eprop)
|
||||
{
|
||||
GladeEPropPixbuf *eprop_pixbuf = GLADE_EPROP_PIXBUF (eprop);
|
||||
GladeEPropResource *eprop_resource = GLADE_EPROP_RESOURCE (eprop);
|
||||
GtkWidget *hbox;
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
|
||||
eprop_pixbuf->entry = gtk_entry_new ();
|
||||
gtk_widget_show (eprop_pixbuf->entry);
|
||||
eprop_resource->entry = gtk_entry_new ();
|
||||
gtk_widget_show (eprop_resource->entry);
|
||||
|
||||
eprop_pixbuf->button = gtk_button_new_with_label ("...");
|
||||
gtk_widget_show (eprop_pixbuf->button);
|
||||
eprop_resource->button = gtk_button_new_with_label ("...");
|
||||
gtk_widget_show (eprop_resource->button);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox), eprop_pixbuf->entry, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), eprop_pixbuf->button, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), eprop_resource->entry, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), eprop_resource->button, FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect (G_OBJECT (eprop_pixbuf->entry), "activate",
|
||||
G_CALLBACK (glade_eprop_pixbuf_entry_activate),
|
||||
g_signal_connect (G_OBJECT (eprop_resource->entry), "activate",
|
||||
G_CALLBACK (glade_eprop_resource_entry_activate),
|
||||
eprop);
|
||||
g_signal_connect (G_OBJECT (eprop_pixbuf->button), "clicked",
|
||||
G_CALLBACK (glade_eprop_pixbuf_select_file),
|
||||
g_signal_connect (G_OBJECT (eprop_resource->button), "clicked",
|
||||
G_CALLBACK (glade_eprop_resource_select_file),
|
||||
eprop);
|
||||
|
||||
return hbox;
|
||||
@ -1764,7 +1780,7 @@ glade_eprop_pixbuf_create_input (GladeEditorProperty *eprop)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
GladeEditorPropertyPixbufClass
|
||||
GladeEditorPropertyObjectClass
|
||||
*******************************************************************************/
|
||||
enum {
|
||||
OBJ_COLUMN_WIDGET = 0,
|
||||
@ -2042,8 +2058,11 @@ glade_eprop_object_show_dialog (GtkWidget *dialog_button,
|
||||
GtkWidget *dialog, *parent;
|
||||
GtkWidget *vbox, *label, *sw;
|
||||
GtkWidget *tree_view;
|
||||
GladeProject *project;
|
||||
gint res;
|
||||
|
||||
|
||||
project = glade_widget_get_project (eprop->property->widget);
|
||||
parent = gtk_widget_get_toplevel (GTK_WIDGET (eprop));
|
||||
dialog = gtk_dialog_new_with_buttons (_("Choose an object in this project"),
|
||||
GTK_WINDOW (parent),
|
||||
@ -2098,7 +2117,8 @@ glade_eprop_object_show_dialog (GtkWidget *dialog_button,
|
||||
|
||||
if (selected)
|
||||
{
|
||||
GValue *value = glade_property_class_make_gvalue_from_string (eprop->class, selected->name);
|
||||
GValue *value = glade_property_class_make_gvalue_from_string
|
||||
(eprop->class, selected->name, project);
|
||||
|
||||
if (eprop->use_command == FALSE)
|
||||
glade_property_set_value (eprop->property, value);
|
||||
@ -2108,7 +2128,7 @@ glade_eprop_object_show_dialog (GtkWidget *dialog_button,
|
||||
}
|
||||
else if (res == GLADE_RESPONSE_CLEAR)
|
||||
{
|
||||
GValue *value = glade_property_class_make_gvalue_from_string (eprop->class, NULL);
|
||||
GValue *value = glade_property_class_make_gvalue_from_string (eprop->class, NULL, project);
|
||||
|
||||
if (eprop->use_command == FALSE)
|
||||
glade_property_set_value (eprop->property, value);
|
||||
@ -2206,8 +2226,8 @@ glade_editor_property_type (GParamSpec *pspec)
|
||||
type = GLADE_TYPE_EPROP_UNICHAR;
|
||||
else if (G_IS_PARAM_SPEC_OBJECT(pspec))
|
||||
{
|
||||
if(pspec->value_type == GDK_TYPE_PIXBUF)
|
||||
type = GLADE_TYPE_EPROP_PIXBUF;
|
||||
if (pspec->value_type == GDK_TYPE_PIXBUF)
|
||||
type = GLADE_TYPE_EPROP_RESOURCE;
|
||||
else
|
||||
type = GLADE_TYPE_EPROP_OBJECT;
|
||||
}
|
||||
@ -2242,6 +2262,9 @@ glade_editor_property_new (GladePropertyClass *class,
|
||||
g_error ("%s : type %s not implemented (%s)\n", G_GNUC_FUNCTION,
|
||||
class->name, g_type_name (class->pspec->value_type));
|
||||
|
||||
/* special case for resource specs which are hand specified in the catalog. */
|
||||
if (class->resource) type = GLADE_TYPE_EPROP_RESOURCE;
|
||||
|
||||
/* Create and return the correct type of GladeEditorProperty */
|
||||
eprop = g_object_new (type,
|
||||
"property-class", class,
|
||||
|
@ -699,7 +699,8 @@ glade_gtk_button_ensure_glabel (GtkWidget *button)
|
||||
if (child) gtk_container_remove (GTK_CONTAINER (button), child);
|
||||
gtk_container_add (GTK_CONTAINER (button), GTK_WIDGET (glabel->object));
|
||||
|
||||
glade_project_add_object (GLADE_PROJECT (gbutton->project), glabel->object);
|
||||
glade_project_add_object (GLADE_PROJECT (gbutton->project),
|
||||
NULL, glabel->object);
|
||||
gtk_widget_show (GTK_WIDGET (glabel->object));
|
||||
}
|
||||
|
||||
@ -802,7 +803,8 @@ glade_gtk_image_restore_filename (GladeWidget *gwidget)
|
||||
|
||||
file = g_object_get_data (G_OBJECT (gwidget), "glade-file");
|
||||
p = glade_widget_get_property (gwidget, "pixbuf");
|
||||
value = glade_property_class_make_gvalue_from_string (p->class, file);
|
||||
value = glade_property_class_make_gvalue_from_string
|
||||
(p->class, file, gwidget->project);
|
||||
|
||||
glade_property_set_value (p, value);
|
||||
|
||||
@ -1231,7 +1233,8 @@ glade_gtk_frame_create_idle (gpointer data)
|
||||
g_object_set_data (glabel->object, "special-child-type", "label_item");
|
||||
gtk_frame_set_label_widget (GTK_FRAME (frame), GTK_WIDGET (glabel->object));
|
||||
|
||||
glade_project_add_object (GLADE_PROJECT (gframe->project), glabel->object);
|
||||
glade_project_add_object (GLADE_PROJECT (gframe->project),
|
||||
NULL, glabel->object);
|
||||
gtk_widget_show (GTK_WIDGET (glabel->object));
|
||||
}
|
||||
return FALSE;
|
||||
@ -1260,9 +1263,11 @@ glade_gtk_expander_create_idle (gpointer data)
|
||||
glade_widget_property_set (glabel, "label", "expander");
|
||||
|
||||
g_object_set_data (glabel->object, "special-child-type", "label_item");
|
||||
gtk_expander_set_label_widget (GTK_EXPANDER (expander), GTK_WIDGET (glabel->object));
|
||||
gtk_expander_set_label_widget (GTK_EXPANDER (expander),
|
||||
GTK_WIDGET (glabel->object));
|
||||
|
||||
glade_project_add_object (GLADE_PROJECT (gexpander->project), glabel->object);
|
||||
glade_project_add_object (GLADE_PROJECT (gexpander->project),
|
||||
NULL, glabel->object);
|
||||
gtk_widget_show (GTK_WIDGET (glabel->object));
|
||||
}
|
||||
return FALSE;
|
||||
@ -2179,7 +2184,8 @@ glade_gtk_image_menu_item_set_use_stock (GObject *object, GValue *value)
|
||||
image = gtk_image_new ();
|
||||
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (object), image);
|
||||
gimage = glade_widget_new_for_internal_child (gitem, G_OBJECT (image), "image");
|
||||
glade_project_add_object (glade_widget_get_project (gitem), G_OBJECT (image));
|
||||
glade_project_add_object (glade_widget_get_project (gitem),
|
||||
NULL, G_OBJECT (image));
|
||||
glade_gtk_image_post_create_idle (G_OBJECT (image));
|
||||
glade_widget_property_set_sensitive (gitem, "label", TRUE, NULL);
|
||||
}
|
||||
|
@ -92,6 +92,26 @@ gpw_refresh_title (GladeProjectWindow *gpw)
|
||||
g_free (title);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gpw_menuitem_from_project (GladeProject *project)
|
||||
{
|
||||
GtkUIManager *ui;
|
||||
gchar *path;
|
||||
|
||||
g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
|
||||
|
||||
ui = g_object_get_data (G_OBJECT (project), "ui");
|
||||
path = g_object_get_data (G_OBJECT (project), "menuitem_path");
|
||||
return gtk_ui_manager_get_widget (ui, path);
|
||||
}
|
||||
|
||||
static guint
|
||||
gpw_menuitem_merge_id_from_project (GladeProject *project)
|
||||
{
|
||||
g_return_val_if_fail (GLADE_IS_PROJECT (project), 0);
|
||||
return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (project), "merge_id"));
|
||||
}
|
||||
|
||||
static void
|
||||
gpw_select_project_menu (GladeProjectWindow *gpw)
|
||||
{
|
||||
@ -103,7 +123,7 @@ gpw_select_project_menu (GladeProjectWindow *gpw)
|
||||
projects && projects->data; projects = projects->next)
|
||||
{
|
||||
project = projects->data;
|
||||
palette_item = glade_project_get_menuitem (project);
|
||||
palette_item = gpw_menuitem_from_project (project);
|
||||
|
||||
gtk_check_menu_item_set_draw_as_radio
|
||||
(GTK_CHECK_MENU_ITEM (palette_item), TRUE);
|
||||
@ -117,16 +137,16 @@ gpw_select_project_menu (GladeProjectWindow *gpw)
|
||||
static void
|
||||
gpw_refresh_project_entry (GladeProjectWindow *gpw, GladeProject *project)
|
||||
{
|
||||
GtkAction *action = g_object_get_data (G_OBJECT (project), "action");
|
||||
|
||||
/* Remove menuitem and action */
|
||||
gtk_ui_manager_remove_ui(gpw->priv->ui,
|
||||
glade_project_get_menuitem_merge_id(project));
|
||||
gpw_menuitem_merge_id_from_project (project));
|
||||
|
||||
gtk_action_group_remove_action (gpw->priv->project_actions,
|
||||
GTK_ACTION (project->action));
|
||||
|
||||
g_object_unref (G_OBJECT (project->action));
|
||||
gtk_action_group_remove_action (gpw->priv->project_actions, action);
|
||||
g_object_unref (G_OBJECT (action));
|
||||
|
||||
/* Create project menuiten and action */
|
||||
/* Create project menuitem and action */
|
||||
gpw_project_menuitem_add (gpw, project);
|
||||
|
||||
gpw_select_project_menu (gpw);
|
||||
@ -335,22 +355,22 @@ static void
|
||||
gpw_save (GladeProjectWindow *gpw, GladeProject *project, const gchar *path)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *display_path = g_strdup (path);
|
||||
|
||||
/* Interestingly; we cannot use `path' after glade_project_reset_path
|
||||
* because we are getting called with project->path as an argument.
|
||||
*/
|
||||
if (!glade_project_save (project, path, &error))
|
||||
{
|
||||
/* Reset path so future saves will prompt the file chooser */
|
||||
glade_project_reset_path (project);
|
||||
glade_util_ui_warn (gpw->priv->window, error->message);
|
||||
glade_util_ui_message (gpw->priv->window, GLADE_UI_ERROR,
|
||||
_("Failed to save %s to %s: %s"),
|
||||
project->name, display_path, error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
glade_util_flash_message
|
||||
(gpw->priv->statusbar,
|
||||
gpw->priv->statusbar_actions_context_id,
|
||||
_("Project '%s' saved"),
|
||||
project->name);
|
||||
|
||||
glade_app_update_instance_count (GLADE_APP (gpw), project);
|
||||
|
||||
gpw_recent_project_add (gpw, project->path);
|
||||
@ -375,7 +395,8 @@ gpw_save_as (GladeProjectWindow *gpw, const gchar *dialog_title)
|
||||
|
||||
if ((project = glade_app_get_active_project (GLADE_APP (gpw))) == NULL)
|
||||
{
|
||||
glade_util_ui_warn (gpw->priv->window, _("No open projects to save"));
|
||||
glade_util_ui_message (gpw->priv->window, GLADE_UI_WARN,
|
||||
_("No open projects to save"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -401,11 +422,8 @@ gpw_save_as (GladeProjectWindow *gpw, const gchar *dialog_title)
|
||||
|
||||
if (glade_app_is_project_loaded (GLADE_APP (gpw), real_path))
|
||||
{
|
||||
gchar *message = g_strdup_printf (_("%s is already open"), real_path);
|
||||
|
||||
glade_util_ui_warn (gpw->priv->window, message);
|
||||
|
||||
g_free (message);
|
||||
glade_util_ui_message (gpw->priv->window, GLADE_UI_WARN,
|
||||
_("%s is already open"), real_path);
|
||||
return;
|
||||
}
|
||||
gpw_save (gpw, project, real_path);
|
||||
@ -421,7 +439,9 @@ gpw_save_cb (GtkAction *action, GladeProjectWindow *gpw)
|
||||
|
||||
if ((project = glade_app_get_active_project (GLADE_APP (gpw))) == NULL)
|
||||
{
|
||||
glade_util_ui_warn (gpw->priv->window, _("No open projects to save"));
|
||||
glade_util_ui_message (gpw->priv->window,
|
||||
GLADE_UI_WARN,
|
||||
_("No open projects to save"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -484,7 +504,11 @@ gpw_confirm_close_project (GladeProjectWindow *gpw, GladeProject *project)
|
||||
if ((close = glade_project_save
|
||||
(project, project->path, &error)) == FALSE)
|
||||
{
|
||||
glade_util_ui_warn (gpw->priv->window, error->message);
|
||||
|
||||
glade_util_ui_message
|
||||
(gpw->priv->window, GLADE_UI_ERROR,
|
||||
_("Failed to save %s to %s: %s"),
|
||||
project->name, project->path, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
@ -531,7 +555,7 @@ static void
|
||||
do_close (GladeProjectWindow *gpw, GladeProject *project)
|
||||
{
|
||||
gtk_ui_manager_remove_ui (gpw->priv->ui,
|
||||
glade_project_get_menuitem_merge_id (project));
|
||||
gpw_menuitem_merge_id_from_project (project));
|
||||
|
||||
glade_app_remove_project (GLADE_APP (gpw), project);
|
||||
gpw_select_project_menu (gpw);
|
||||
@ -1027,7 +1051,7 @@ glade_project_window_set_project (GtkAction *action, GladeProject *project)
|
||||
GtkWidget *item;
|
||||
|
||||
gpw = g_object_get_data (G_OBJECT (project), "gpw");
|
||||
item = glade_project_get_menuitem (project);
|
||||
item = gpw_menuitem_from_project (project);
|
||||
|
||||
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)))
|
||||
{
|
||||
@ -1363,6 +1387,7 @@ static void
|
||||
gpw_project_menuitem_add (GladeProjectWindow *gpw, GladeProject *project)
|
||||
{
|
||||
gchar *underscored_name, *action_name, *final_name;
|
||||
GtkWidget *action;
|
||||
guint merge_id;
|
||||
|
||||
/* double the underscores in the project name
|
||||
@ -1378,31 +1403,30 @@ gpw_project_menuitem_add (GladeProjectWindow *gpw, GladeProject *project)
|
||||
|
||||
action_name = g_strdup_printf ("select[%s]", final_name);
|
||||
|
||||
/* What happen if there is two project with the same name in differents
|
||||
* directories?
|
||||
*/
|
||||
project->action = gtk_toggle_action_new (action_name, final_name,
|
||||
project->path, NULL);
|
||||
gtk_toggle_action_set_active (project->action, TRUE);
|
||||
g_signal_connect (G_OBJECT (project->action), "activate",
|
||||
action = (GtkWidget *)gtk_toggle_action_new (action_name, final_name,
|
||||
project->path, NULL);
|
||||
g_object_set_data (G_OBJECT (project), "action", action);
|
||||
|
||||
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
|
||||
g_signal_connect (G_OBJECT (action), "activate",
|
||||
(GCallback) glade_project_window_set_project, project);
|
||||
|
||||
gtk_action_group_add_action_with_accel (gpw->priv->project_actions,
|
||||
GTK_ACTION (project->action), "");
|
||||
GTK_ACTION (action), "");
|
||||
|
||||
/* Add menuitem to menu */
|
||||
merge_id = gtk_ui_manager_new_merge_id(gpw->priv->ui);
|
||||
merge_id = gtk_ui_manager_new_merge_id (gpw->priv->ui);
|
||||
|
||||
gtk_ui_manager_add_ui(gpw->priv->ui, merge_id,
|
||||
"/MenuBar/ProjectMenu", action_name, action_name,
|
||||
GTK_UI_MANAGER_MENUITEM, FALSE);
|
||||
|
||||
/* Set extra data to action */
|
||||
g_object_set_data (G_OBJECT (project->action), "ui", gpw->priv->ui);
|
||||
g_object_set_data_full (G_OBJECT (project->action), "menuitem_path",
|
||||
g_object_set_data (G_OBJECT (project), "ui", gpw->priv->ui);
|
||||
g_object_set_data_full (G_OBJECT (project), "menuitem_path",
|
||||
g_strdup_printf ("/MenuBar/ProjectMenu/%s", action_name),
|
||||
g_free);
|
||||
g_object_set_data (G_OBJECT (project->action), "merge_id", GINT_TO_POINTER (merge_id));
|
||||
g_object_set_data (G_OBJECT (project), "merge_id", GINT_TO_POINTER (merge_id));
|
||||
|
||||
g_free (action_name);
|
||||
g_free (underscored_name);
|
||||
@ -1438,7 +1462,9 @@ glade_project_window_new_project (GladeProjectWindow *gpw)
|
||||
project = glade_project_new (TRUE);
|
||||
if (!project)
|
||||
{
|
||||
glade_util_ui_warn (gpw->priv->window, _("Could not create a new project."));
|
||||
glade_util_ui_message (gpw->priv->window,
|
||||
GLADE_UI_ERROR,
|
||||
_("Could not create a new project."));
|
||||
return;
|
||||
}
|
||||
glade_project_window_add_project (gpw, project);
|
||||
@ -1462,16 +1488,16 @@ glade_project_window_open_project (GladeProjectWindow *gpw, const gchar *path)
|
||||
*/
|
||||
if (glade_app_is_project_loaded (GLADE_APP (gpw), (gchar*)path))
|
||||
{
|
||||
gchar *message = g_strdup_printf (_("%s is already open"), path);
|
||||
glade_util_ui_warn (gpw->priv->window, message);
|
||||
g_free (message);
|
||||
glade_util_ui_message (gpw->priv->window, GLADE_UI_WARN,
|
||||
_("%s is already open"), path);
|
||||
return;
|
||||
}
|
||||
|
||||
project = glade_project_open (path);
|
||||
if (!project)
|
||||
{
|
||||
glade_util_ui_warn (gpw->priv->window, _("Could not open project."));
|
||||
glade_util_ui_message (gpw->priv->window, GLADE_UI_ERROR,
|
||||
_("Could not open project."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,8 @@ enum
|
||||
WIDGET_NAME_CHANGED,
|
||||
SELECTION_CHANGED,
|
||||
CLOSE,
|
||||
RESOURCE_UPDATED,
|
||||
RESOURCE_REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@ -153,6 +155,29 @@ glade_project_class_init (GladeProjectClass *class)
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
glade_project_signals[RESOURCE_UPDATED] =
|
||||
g_signal_new ("resource-updated",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GladeProjectClass, resource_updated),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__STRING,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
glade_project_signals[RESOURCE_REMOVED] =
|
||||
g_signal_new ("resource-removed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GladeProjectClass, resource_removed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__STRING,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
|
||||
object_class->finalize = glade_project_finalize;
|
||||
object_class->dispose = glade_project_dispose;
|
||||
|
||||
@ -161,6 +186,8 @@ glade_project_class_init (GladeProjectClass *class)
|
||||
class->widget_name_changed = NULL;
|
||||
class->selection_changed = NULL;
|
||||
class->close = NULL;
|
||||
class->resource_updated = NULL;
|
||||
class->resource_removed = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -173,10 +200,17 @@ glade_project_init (GladeProject *project)
|
||||
project->selection = NULL;
|
||||
project->undo_stack = NULL;
|
||||
project->prev_redo_item = NULL;
|
||||
project->widget_names_allocator = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) glade_id_allocator_free);
|
||||
project->widget_old_names = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_free);
|
||||
project->widget_names_allocator =
|
||||
g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||
(GDestroyNotify) glade_id_allocator_free);
|
||||
project->widget_old_names =
|
||||
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_free);
|
||||
project->tooltips = gtk_tooltips_new ();
|
||||
project->accel_group = NULL;
|
||||
|
||||
project->resources = g_hash_table_new_full (g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL, g_free);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -255,6 +289,7 @@ glade_project_finalize (GObject *object)
|
||||
|
||||
g_hash_table_destroy (project->widget_names_allocator);
|
||||
g_hash_table_destroy (project->widget_old_names);
|
||||
g_hash_table_destroy (project->resources);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
@ -296,6 +331,92 @@ glade_project_on_widget_notify (GladeWidget *widget, GParamSpec *arg, GladeProje
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gp_sync_resources (GladeProject *project,
|
||||
GladeProject *prev_project,
|
||||
GladeWidget *gwidget)
|
||||
{
|
||||
GList *prop_list, *l;
|
||||
GladeProperty *property;
|
||||
gchar *resource, *full_resource;
|
||||
|
||||
prop_list = g_list_copy (gwidget->properties);
|
||||
prop_list = g_list_concat
|
||||
(prop_list, g_list_copy (gwidget->packing_properties));
|
||||
|
||||
for (l = prop_list; l; l = l->next)
|
||||
{
|
||||
property = l->data;
|
||||
if (property->class->resource)
|
||||
{
|
||||
GValue value = { 0, };
|
||||
glade_property_get_value (property, &value);
|
||||
|
||||
resource = glade_property_class_make_string_from_gvalue
|
||||
(property->class, &value);
|
||||
full_resource = glade_project_resource_fullpath
|
||||
(prev_project ? prev_project : project, resource);
|
||||
|
||||
/* Use a full path here so that the current
|
||||
* working directory isnt used.
|
||||
*/
|
||||
glade_project_set_resource (project,
|
||||
property,
|
||||
full_resource);
|
||||
|
||||
g_free (resource);
|
||||
g_free (full_resource);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
}
|
||||
g_list_free (prop_list);
|
||||
}
|
||||
|
||||
static void
|
||||
glade_project_sync_resources_for_widget (GladeProject *project,
|
||||
GladeProject *prev_project,
|
||||
GladeWidget *gwidget)
|
||||
{
|
||||
GList *children, *l;
|
||||
GladeWidget *gchild;
|
||||
|
||||
children = glade_widget_class_container_get_all_children
|
||||
(gwidget->widget_class, gwidget->object);
|
||||
|
||||
for (l = children; l; l = l->next)
|
||||
if ((gchild =
|
||||
glade_widget_get_from_gobject (l->data)) != NULL)
|
||||
glade_project_sync_resources_for_widget
|
||||
(project, prev_project, gchild);
|
||||
if (children)
|
||||
g_list_free (children);
|
||||
|
||||
gp_sync_resources (project, prev_project, gwidget);
|
||||
}
|
||||
|
||||
static void
|
||||
glade_project_sync_resources (GladeProject *project,
|
||||
GladeProject *old_project)
|
||||
{
|
||||
GList *list;
|
||||
GladeWidget *gwidget;
|
||||
|
||||
g_return_if_fail (GLADE_IS_PROJECT (project));
|
||||
|
||||
for (list = project->objects; list; list = list->next)
|
||||
{
|
||||
if ((gwidget = glade_widget_get_from_gobject (list->data)) != NULL)
|
||||
{
|
||||
gp_sync_resources (project,
|
||||
old_project ? old_project : project,
|
||||
gwidget);
|
||||
}
|
||||
else g_critical ("Project object found without glade widget wrapper");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* glade_project_add_object:
|
||||
* @project: the #GladeProject the widget is added to
|
||||
@ -304,17 +425,20 @@ glade_project_on_widget_notify (GladeWidget *widget, GParamSpec *arg, GladeProje
|
||||
* Adds an object to the project.
|
||||
*/
|
||||
void
|
||||
glade_project_add_object (GladeProject *project, GObject *object)
|
||||
glade_project_add_object (GladeProject *project,
|
||||
GladeProject *old_project,
|
||||
GObject *object)
|
||||
{
|
||||
GladeWidget *gwidget;
|
||||
GList *list, *children;
|
||||
GtkWindow *transient_parent;
|
||||
GladeWidget *gwidget;
|
||||
GList *list, *children;
|
||||
GtkWindow *transient_parent;
|
||||
static gint reentrancy_count = 0;
|
||||
|
||||
g_return_if_fail (GLADE_IS_PROJECT (project));
|
||||
g_return_if_fail (G_IS_OBJECT (object));
|
||||
|
||||
/* We don't list placeholders */
|
||||
if (GLADE_IS_PLACEHOLDER (object))
|
||||
if (GLADE_IS_PLACEHOLDER (object))
|
||||
return;
|
||||
|
||||
/* Only widgets accounted for in the catalog or widgets declared
|
||||
@ -324,11 +448,15 @@ glade_project_add_object (GladeProject *project, GObject *object)
|
||||
if ((gwidget = glade_widget_get_from_gobject (object)) == NULL)
|
||||
return;
|
||||
|
||||
/* Code body starts here */
|
||||
reentrancy_count++;
|
||||
|
||||
if ((children = glade_widget_class_container_get_all_children
|
||||
(gwidget->widget_class, gwidget->object)) != NULL)
|
||||
{
|
||||
for (list = children; list && list->data; list = list->next)
|
||||
glade_project_add_object (project, G_OBJECT (list->data));
|
||||
glade_project_add_object
|
||||
(project, old_project, G_OBJECT (list->data));
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
@ -352,6 +480,11 @@ glade_project_add_object (GladeProject *project, GObject *object)
|
||||
|
||||
/* Notify widget it was added to the project */
|
||||
glade_widget_project_notify (gwidget, project);
|
||||
|
||||
/* Call this once at the end for every recursive call */
|
||||
if (--reentrancy_count == 0)
|
||||
glade_project_sync_resources_for_widget
|
||||
(project, old_project, gwidget);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -436,8 +569,9 @@ glade_project_release_widget_name (GladeProject *project, GladeWidget *glade_wid
|
||||
void
|
||||
glade_project_remove_object (GladeProject *project, GObject *object)
|
||||
{
|
||||
GladeWidget *gwidget;
|
||||
GList *link, *list, *children;
|
||||
GladeWidget *gwidget;
|
||||
GList *link, *list, *children;
|
||||
static gint reentrancy_count = 0;
|
||||
|
||||
g_return_if_fail (GLADE_IS_PROJECT (project));
|
||||
g_return_if_fail (G_IS_OBJECT (object));
|
||||
@ -448,6 +582,9 @@ glade_project_remove_object (GladeProject *project, GObject *object)
|
||||
if ((gwidget = glade_widget_get_from_gobject (object)) == NULL)
|
||||
return;
|
||||
|
||||
/* Code body starts here */
|
||||
reentrancy_count++;
|
||||
|
||||
/* Notify widget is being removed from the project */
|
||||
glade_widget_project_notify (gwidget, NULL);
|
||||
|
||||
@ -474,6 +611,10 @@ glade_project_remove_object (GladeProject *project, GObject *object)
|
||||
glade_project_signals [REMOVE_WIDGET],
|
||||
0,
|
||||
gwidget);
|
||||
|
||||
/* Call this once at the end for every recursive call */
|
||||
if (--reentrancy_count == 0)
|
||||
glade_project_sync_resources (project, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -775,7 +916,6 @@ glade_project_new_from_interface (GladeInterface *interface, const gchar *path)
|
||||
{
|
||||
GladeProject *project;
|
||||
GladeWidget *widget;
|
||||
gchar *cwd;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (interface != NULL, NULL);
|
||||
@ -790,14 +930,6 @@ glade_project_new_from_interface (GladeInterface *interface, const gchar *path)
|
||||
project->selection = NULL;
|
||||
project->objects = NULL;
|
||||
|
||||
/* Set current/working directory to project's directory */
|
||||
cwd = g_path_get_dirname (project->path);
|
||||
if (cwd)
|
||||
{
|
||||
g_chdir (cwd);
|
||||
g_free (cwd);
|
||||
}
|
||||
|
||||
if (interface->n_requires)
|
||||
g_warning ("We currently do not support projects requiring additional libs");
|
||||
|
||||
@ -809,7 +941,7 @@ glade_project_new_from_interface (GladeInterface *interface, const gchar *path)
|
||||
g_warning ("Failed to read a <widget> tag");
|
||||
continue;
|
||||
}
|
||||
glade_project_add_object (project, widget->object);
|
||||
glade_project_add_object (project, NULL, widget->object);
|
||||
}
|
||||
|
||||
/* Set project status after every idle functions */
|
||||
@ -877,13 +1009,46 @@ glade_project_open (const gchar *path)
|
||||
glade_interface_destroy (interface);
|
||||
|
||||
/* Now we have to loop over all the object properties
|
||||
* and fix'em all ('cause they probably weren't found) XXX
|
||||
* and fix'em all ('cause they probably weren't found)
|
||||
*/
|
||||
glade_project_fix_object_props (project);
|
||||
|
||||
/* Resources have to be bookkept after the load.
|
||||
*/
|
||||
glade_project_sync_resources (project, NULL);
|
||||
|
||||
return project;
|
||||
}
|
||||
|
||||
static void
|
||||
glade_project_move_resources (GladeProject *project,
|
||||
const gchar *old_dir,
|
||||
const gchar *new_dir)
|
||||
{
|
||||
GList *list, *resources;
|
||||
gchar *old_name, *new_name;
|
||||
|
||||
if (old_dir == NULL || /* <-- Cant help you :( */
|
||||
new_dir == NULL) /* <-- Unlikely */
|
||||
return;
|
||||
|
||||
if ((resources = /* Nothing to do here */
|
||||
glade_project_list_resources (project)) == NULL)
|
||||
return;
|
||||
|
||||
for (list = resources; list; list = list->next)
|
||||
{
|
||||
old_name = g_build_filename
|
||||
(old_dir, (gchar *)list->data, NULL);
|
||||
new_name = g_build_filename
|
||||
(new_dir, (gchar *)list->data, NULL);
|
||||
glade_util_copy_file (old_name, new_name);
|
||||
g_free (old_name);
|
||||
g_free (new_name);
|
||||
}
|
||||
g_list_free (resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* glade_project_save:
|
||||
* @project: a #GladeProject
|
||||
@ -899,6 +1064,7 @@ glade_project_save (GladeProject *project, const gchar *path, GError **error)
|
||||
{
|
||||
GladeInterface *interface;
|
||||
gboolean ret;
|
||||
gchar *canonical_path;
|
||||
|
||||
g_return_val_if_fail (GLADE_IS_PROJECT (project), FALSE);
|
||||
|
||||
@ -912,14 +1078,32 @@ glade_project_save (GladeProject *project, const gchar *path, GError **error)
|
||||
ret = glade_interface_dump_full (interface, path, error);
|
||||
glade_interface_destroy (interface);
|
||||
|
||||
if (path != project->path)
|
||||
{
|
||||
g_free (project->path);
|
||||
project->path = g_strdup_printf ("%s", path);
|
||||
}
|
||||
g_free (project->name);
|
||||
project->name = g_path_get_basename (project->path);
|
||||
|
||||
canonical_path = glade_util_canonical_path (path);
|
||||
|
||||
if (strcmp (canonical_path, project->path))
|
||||
{
|
||||
gchar *old_dir, *new_dir;
|
||||
|
||||
if (project->path)
|
||||
{
|
||||
old_dir = g_path_get_dirname (project->path);
|
||||
new_dir = g_path_get_dirname (canonical_path);
|
||||
|
||||
glade_project_move_resources (project,
|
||||
old_dir,
|
||||
new_dir);
|
||||
g_free (old_dir);
|
||||
g_free (new_dir);
|
||||
}
|
||||
project->path = (g_free (project->path),
|
||||
g_strdup (canonical_path));
|
||||
|
||||
project->name = (g_free (project->name),
|
||||
g_path_get_basename (project->path));
|
||||
}
|
||||
|
||||
g_free (canonical_path);
|
||||
project->changed = FALSE;
|
||||
|
||||
return ret;
|
||||
@ -954,32 +1138,6 @@ glade_project_get_tooltips (GladeProject *project)
|
||||
}
|
||||
|
||||
/**
|
||||
* glade_project_get_menuitem
|
||||
*/
|
||||
GtkWidget *
|
||||
glade_project_get_menuitem (GladeProject *project)
|
||||
{
|
||||
GtkUIManager *ui;
|
||||
gchar *path;
|
||||
|
||||
g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
|
||||
|
||||
ui = g_object_get_data (G_OBJECT (project->action), "ui");
|
||||
path = g_object_get_data (G_OBJECT (project->action), "menuitem_path");
|
||||
return gtk_ui_manager_get_widget (ui, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* glade_project_get_menuitem_merge_id
|
||||
*/
|
||||
guint
|
||||
glade_project_get_menuitem_merge_id (GladeProject *project)
|
||||
{
|
||||
g_return_val_if_fail (GLADE_IS_PROJECT (project), 0);
|
||||
return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (project->action), "merge_id"));
|
||||
}
|
||||
|
||||
/*
|
||||
* glade_project_set_accel_group:
|
||||
*
|
||||
* Set @accel_group to every top level widget in @project.
|
||||
@ -1007,3 +1165,123 @@ glade_project_set_accel_group (GladeProject *project, GtkAccelGroup *accel_group
|
||||
|
||||
project->accel_group = accel_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* glade_project_resource_fullpath:
|
||||
* @project: The #GladeProject.
|
||||
* @resource: The resource basename
|
||||
*
|
||||
* Returns: A newly allocated string holding the
|
||||
* full path the the project resource.
|
||||
*/
|
||||
gchar *
|
||||
glade_project_resource_fullpath (GladeProject *project,
|
||||
const gchar *resource)
|
||||
{
|
||||
gchar *fullpath, *project_dir;
|
||||
|
||||
g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
|
||||
|
||||
project_dir = g_path_get_dirname (project->path);
|
||||
fullpath = g_build_filename (project_dir, resource, NULL);
|
||||
g_free (project_dir);
|
||||
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* glade_project_set_resource:
|
||||
* @project: A #GladeProject
|
||||
* @property: The #GladeProperty this resource is required by
|
||||
* @resource: The resource file basename to be found in the same
|
||||
* directory as the glade file.
|
||||
*
|
||||
* Adds/Modifies/Removes a resource from a project; any project resources
|
||||
* will be copied when using "Save As...", when moving widgets across projects
|
||||
* and will be copied into the project's directory when selected.
|
||||
*/
|
||||
void
|
||||
glade_project_set_resource (GladeProject *project,
|
||||
GladeProperty *property,
|
||||
const gchar *resource)
|
||||
{
|
||||
gchar *last_resource, *last_resource_dup = NULL, *base_resource = NULL;
|
||||
gchar *fullpath, *dirname;
|
||||
|
||||
g_return_if_fail (GLADE_IS_PROJECT (project));
|
||||
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
||||
|
||||
last_resource = g_hash_table_lookup (project->resources, property);
|
||||
if (resource) base_resource = g_path_get_basename (resource);
|
||||
|
||||
if (last_resource)
|
||||
last_resource_dup = g_strdup (last_resource);
|
||||
|
||||
if (last_resource_dup &&
|
||||
(base_resource == NULL || strcmp (last_resource_dup, base_resource)))
|
||||
{
|
||||
g_hash_table_remove (project->resources, property);
|
||||
|
||||
/* Emit remove signal
|
||||
*/
|
||||
g_signal_emit (G_OBJECT (project),
|
||||
glade_project_signals [RESOURCE_REMOVED],
|
||||
0, last_resource_dup);
|
||||
}
|
||||
|
||||
if (project->path)
|
||||
{
|
||||
dirname = g_path_get_dirname (project->path);
|
||||
fullpath = g_build_filename (dirname, base_resource, NULL);
|
||||
|
||||
if (resource && project->path &&
|
||||
g_file_test (resource, G_FILE_TEST_IS_REGULAR) &&
|
||||
strcmp (fullpath, resource))
|
||||
{
|
||||
glade_util_copy_file (resource, fullpath);
|
||||
}
|
||||
g_free (fullpath);
|
||||
g_free (dirname);
|
||||
}
|
||||
|
||||
g_hash_table_insert (project->resources, property, base_resource);
|
||||
|
||||
/* Emit update signal
|
||||
*/
|
||||
if (base_resource)
|
||||
g_signal_emit (G_OBJECT (project),
|
||||
glade_project_signals [RESOURCE_UPDATED],
|
||||
0, base_resource);
|
||||
}
|
||||
|
||||
static void
|
||||
list_resources_accum (GladeProperty *key,
|
||||
gchar *value,
|
||||
GList **list)
|
||||
{
|
||||
*list = g_list_prepend (*list, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* glade_project_list_resources:
|
||||
* @project: A #GladeProject
|
||||
*
|
||||
* Returns: A newly allocated #GList of file basenames
|
||||
* of resources in this project, note that the
|
||||
* strings are not allocated and are unsafe to
|
||||
* use once the projects state changes.
|
||||
* The returned list should be freed with g_list_free.
|
||||
*/
|
||||
GList *
|
||||
glade_project_list_resources (GladeProject *project)
|
||||
{
|
||||
GList *list = NULL;
|
||||
g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
|
||||
|
||||
g_hash_table_foreach (project->resources,
|
||||
(GHFunc)list_resources_accum, &list);
|
||||
return list;
|
||||
}
|
||||
|
@ -27,8 +27,6 @@ struct _GladeProject
|
||||
gchar *path; /* The full path of the glade file for this project */
|
||||
|
||||
gint instance; /* How many projects with this name */
|
||||
|
||||
GtkToggleAction *action; /* The menu item action */
|
||||
|
||||
gboolean changed; /* A flag that is set when a project has changes
|
||||
* if this flag is not set we don't have to query
|
||||
@ -54,6 +52,8 @@ struct _GladeProject
|
||||
GtkTooltips *tooltips;
|
||||
|
||||
GtkAccelGroup *accel_group;
|
||||
|
||||
GHashTable *resources; /* resource filenames & thier associated properties */
|
||||
};
|
||||
|
||||
struct _GladeProjectClass
|
||||
@ -68,6 +68,11 @@ struct _GladeProjectClass
|
||||
GladeWidget *widget);
|
||||
void (*selection_changed) (GladeProject *project);
|
||||
void (*close) (GladeProject *project);
|
||||
|
||||
void (*resource_updated) (GladeProject *project,
|
||||
const gchar *resource);
|
||||
void (*resource_removed) (GladeProject *project,
|
||||
const gchar *resource);
|
||||
};
|
||||
|
||||
LIBGLADEUI_API GType glade_project_get_type (void);
|
||||
@ -78,7 +83,9 @@ LIBGLADEUI_API gboolean glade_project_save (GladeProject *pr
|
||||
const gchar *path,
|
||||
GError **error);
|
||||
LIBGLADEUI_API void glade_project_reset_path (GladeProject *project);
|
||||
LIBGLADEUI_API void glade_project_add_object (GladeProject *project, GObject *object);
|
||||
LIBGLADEUI_API void glade_project_add_object (GladeProject *project,
|
||||
GladeProject *old_project,
|
||||
GObject *object);
|
||||
LIBGLADEUI_API void glade_project_remove_object (GladeProject *project, GObject *object);
|
||||
LIBGLADEUI_API gboolean glade_project_has_object (GladeProject *project, GObject *object);
|
||||
LIBGLADEUI_API GladeWidget *glade_project_get_widget_by_name (GladeProject *project, const char *name);
|
||||
@ -106,10 +113,18 @@ LIBGLADEUI_API void glade_project_selection_clear (GladeProject *pr
|
||||
LIBGLADEUI_API void glade_project_selection_changed (GladeProject *project);
|
||||
LIBGLADEUI_API GList *glade_project_selection_get (GladeProject *project);
|
||||
|
||||
LIBGLADEUI_API GtkWidget *glade_project_get_menuitem (GladeProject *project);
|
||||
LIBGLADEUI_API guint glade_project_get_menuitem_merge_id (GladeProject *project);
|
||||
LIBGLADEUI_API void glade_project_set_accel_group (GladeProject *project, GtkAccelGroup *new_group);
|
||||
|
||||
LIBGLADEUI_API void glade_project_set_resource (GladeProject *project,
|
||||
GladeProperty *property,
|
||||
const gchar *resource);
|
||||
|
||||
LIBGLADEUI_API GList *glade_project_list_resources (GladeProject *project);
|
||||
|
||||
LIBGLADEUI_API gchar *glade_project_resource_fullpath (GladeProject *project,
|
||||
const gchar *resource);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GLADE_PROJECT_H__ */
|
||||
|
@ -69,8 +69,8 @@ glade_property_class_new (void)
|
||||
property_class->visible = TRUE;
|
||||
property_class->save = TRUE;
|
||||
property_class->ignore = FALSE;
|
||||
property_class->resource = FALSE;
|
||||
property_class->translatable = TRUE;
|
||||
|
||||
return property_class;
|
||||
}
|
||||
|
||||
@ -343,7 +343,13 @@ glade_property_class_make_string_from_gvalue (GladePropertyClass *property_class
|
||||
else if (G_IS_PARAM_SPEC_DOUBLE(property_class->pspec))
|
||||
string = g_strdup_printf ("%g", g_value_get_double (value));
|
||||
else if (G_IS_PARAM_SPEC_STRING(property_class->pspec))
|
||||
string = g_value_dup_string (value);
|
||||
{
|
||||
if (property_class->resource && g_value_get_string (value) != NULL)
|
||||
string = g_path_get_basename
|
||||
(g_value_get_string (value));
|
||||
else
|
||||
string = g_value_dup_string (value);
|
||||
}
|
||||
else if (G_IS_PARAM_SPEC_CHAR(property_class->pspec))
|
||||
string = g_strdup_printf ("%c", g_value_get_char (value));
|
||||
else if (G_IS_PARAM_SPEC_UCHAR(property_class->pspec))
|
||||
@ -367,7 +373,7 @@ glade_property_class_make_string_from_gvalue (GladePropertyClass *property_class
|
||||
|
||||
if (object && (filename = g_object_get_data
|
||||
(object, "GladeFileName")) != NULL)
|
||||
string = g_strdup (filename);
|
||||
string = g_path_get_basename (filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -498,19 +504,21 @@ glade_property_class_make_enum_from_string (GType type, const char *string)
|
||||
|
||||
/**
|
||||
* glade_property_class_make_gvalue_from_string:
|
||||
* @property_class:
|
||||
* @string:
|
||||
* @property_class: A #GladePropertyClass
|
||||
* @string: a string representation of this property
|
||||
* @project: the glade project that the associated property
|
||||
* belongs to.
|
||||
*
|
||||
* TODO: write me
|
||||
*
|
||||
* Returns:
|
||||
* Returns: A #GValue created based on the @property_class
|
||||
* and @string criteria.
|
||||
*/
|
||||
GValue *
|
||||
glade_property_class_make_gvalue_from_string (GladePropertyClass *property_class,
|
||||
const gchar *string)
|
||||
const gchar *string,
|
||||
GladeProject *project)
|
||||
{
|
||||
GValue *value = g_new0 (GValue, 1);
|
||||
gchar **strv;
|
||||
gchar **strv, *fullpath;
|
||||
GdkColor color = { 0, };
|
||||
|
||||
g_value_init (value, property_class->pspec->value_type);
|
||||
@ -565,7 +573,20 @@ glade_property_class_make_gvalue_from_string (GladePropertyClass *property_class
|
||||
else if (G_IS_PARAM_SPEC_DOUBLE(property_class->pspec))
|
||||
g_value_set_double (value, (float) atof (string));
|
||||
else if (G_IS_PARAM_SPEC_STRING(property_class->pspec))
|
||||
g_value_set_string (value, string);
|
||||
{
|
||||
/* This can be called when loading defaults from
|
||||
* catalog files... it wont happen and we cant do
|
||||
* anything for it.
|
||||
*/
|
||||
if (property_class->resource && project)
|
||||
{
|
||||
fullpath = g_build_filename
|
||||
(project->path, string, NULL);
|
||||
g_value_set_string (value, fullpath);
|
||||
g_free (fullpath);
|
||||
}
|
||||
else g_value_set_string (value, string);
|
||||
}
|
||||
else if (G_IS_PARAM_SPEC_CHAR(property_class->pspec))
|
||||
g_value_set_char (value, string[0]);
|
||||
else if (G_IS_PARAM_SPEC_UCHAR(property_class->pspec))
|
||||
@ -581,26 +602,35 @@ glade_property_class_make_gvalue_from_string (GladePropertyClass *property_class
|
||||
}
|
||||
else if (G_IS_PARAM_SPEC_OBJECT(property_class->pspec))
|
||||
{
|
||||
if (property_class->pspec->value_type == GDK_TYPE_PIXBUF)
|
||||
if (property_class->pspec->value_type == GDK_TYPE_PIXBUF && project)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
if (string != NULL &&
|
||||
(pixbuf = gdk_pixbuf_new_from_file (string, NULL)) != NULL)
|
||||
if (string)
|
||||
{
|
||||
g_object_set_data_full (G_OBJECT(pixbuf),
|
||||
"GladeFileName",
|
||||
g_strdup (string),
|
||||
g_free);
|
||||
g_value_take_object (value, G_OBJECT(pixbuf));
|
||||
fullpath = g_build_filename
|
||||
(project->path, string, NULL);
|
||||
|
||||
if ((pixbuf = gdk_pixbuf_new_from_file
|
||||
(string, NULL)) != NULL)
|
||||
{
|
||||
g_object_set_data_full (G_OBJECT(pixbuf),
|
||||
"GladeFileName",
|
||||
g_strdup (string),
|
||||
g_free);
|
||||
g_value_take_object (value, G_OBJECT(pixbuf));
|
||||
}
|
||||
|
||||
g_free (fullpath);
|
||||
}
|
||||
else
|
||||
g_value_set_object (value, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
GladeWidget *gwidget;
|
||||
if (glade_default_app_get_active_project () && string &&
|
||||
(gwidget = glade_project_get_widget_by_name
|
||||
(glade_default_app_get_active_project (), string)) != NULL)
|
||||
if (string && (gwidget = glade_project_get_widget_by_name
|
||||
(project, string)) != NULL)
|
||||
g_value_set_object (value, gwidget->object);
|
||||
else
|
||||
g_value_set_object (value, NULL);
|
||||
@ -1063,7 +1093,7 @@ glade_property_class_update_from_node (GladeXmlNode *node,
|
||||
g_value_unset (class->def);
|
||||
g_free (class->def);
|
||||
}
|
||||
class->def = glade_property_class_make_gvalue_from_string (class, buff);
|
||||
class->def = glade_property_class_make_gvalue_from_string (class, buff, NULL);
|
||||
g_free (buff);
|
||||
}
|
||||
|
||||
@ -1124,12 +1154,18 @@ glade_property_class_update_from_node (GladeXmlNode *node,
|
||||
class->translatable = glade_xml_get_property_boolean (node, GLADE_TAG_TRANSLATABLE, TRUE);
|
||||
|
||||
/* common, optional, etc */
|
||||
class->common = glade_xml_get_property_boolean (node, GLADE_TAG_COMMON, class->common);
|
||||
class->optional = glade_xml_get_property_boolean (node, GLADE_TAG_OPTIONAL, class->optional);
|
||||
class->query = glade_xml_get_property_boolean (node, GLADE_TAG_QUERY, class->query);
|
||||
class->save = glade_xml_get_property_boolean (node, GLADE_TAG_SAVE, class->save);
|
||||
class->visible = glade_xml_get_property_boolean (node, GLADE_TAG_VISIBLE, class->visible);
|
||||
class->ignore = glade_xml_get_property_boolean (node, GLADE_TAG_IGNORE, class->ignore);
|
||||
class->common = glade_xml_get_property_boolean (node, GLADE_TAG_COMMON, class->common);
|
||||
class->optional = glade_xml_get_property_boolean (node, GLADE_TAG_OPTIONAL, class->optional);
|
||||
class->query = glade_xml_get_property_boolean (node, GLADE_TAG_QUERY, class->query);
|
||||
class->save = glade_xml_get_property_boolean (node, GLADE_TAG_SAVE, class->save);
|
||||
class->visible = glade_xml_get_property_boolean (node, GLADE_TAG_VISIBLE, class->visible);
|
||||
class->ignore = glade_xml_get_property_boolean (node, GLADE_TAG_IGNORE, class->ignore);
|
||||
class->resource = glade_xml_get_property_boolean (node, GLADE_TAG_RESOURCE, class->resource);
|
||||
|
||||
/* Special case pixbuf here.
|
||||
*/
|
||||
if (class->pspec->value_type == GDK_TYPE_PIXBUF)
|
||||
class->resource = TRUE;
|
||||
|
||||
if (class->optional)
|
||||
class->optional_default =
|
||||
|
@ -37,10 +37,9 @@ struct _GladePropertyClass
|
||||
GList *parameters; /* list of GladeParameter objects. This list
|
||||
* provides with an extra set of key-value
|
||||
* pairs to specify aspects of this property.
|
||||
* Like the number of "VisibleLines" of a text
|
||||
* property. Or the range and default values of
|
||||
* a spin button entry. Also the default choice
|
||||
* for a type == CHOICE
|
||||
*
|
||||
* This is unused by glade and only maintained
|
||||
* to be of possible use in plugin code.
|
||||
*/
|
||||
|
||||
GArray *displayable_values; /* If this property's value is an enumeration/flags and
|
||||
@ -61,6 +60,7 @@ struct _GladePropertyClass
|
||||
*/
|
||||
|
||||
gboolean optional_default; /* For optional values, what the default is */
|
||||
|
||||
gboolean construct_only; /* Whether this property is G_PARAM_CONSTRUCT_ONLY or not */
|
||||
|
||||
gboolean common; /* Common properties go in the common tab */
|
||||
@ -91,6 +91,13 @@ struct _GladePropertyClass
|
||||
gboolean is_modified; /* If true, this property_class has been "modified" from the
|
||||
* the standard property by a xml file. */
|
||||
|
||||
gboolean resource; /* Some property types; such as some file specifying
|
||||
* string properties or GDK_TYPE_PIXBUF properties; are
|
||||
* resource files and are treated specialy (a filechooser
|
||||
* popup is used and the resource is copied to the project
|
||||
* directory).
|
||||
*/
|
||||
|
||||
/* Delagate to verify if this is a valid value for this property,
|
||||
* if this function exists and returns FALSE, then glade_property_set
|
||||
* will abort before making any changes
|
||||
@ -129,7 +136,8 @@ LIBGLADEUI_API void glade_property_class_free
|
||||
LIBGLADEUI_API gboolean glade_property_class_is_visible (GladePropertyClass *property_class);
|
||||
LIBGLADEUI_API gboolean glade_property_class_is_object (GladePropertyClass *property_class);
|
||||
LIBGLADEUI_API GValue *glade_property_class_make_gvalue_from_string (GladePropertyClass *property_class,
|
||||
const gchar *string);
|
||||
const gchar *string,
|
||||
GladeProject *project);
|
||||
LIBGLADEUI_API gchar *glade_property_class_make_string_from_gvalue (GladePropertyClass *property_class,
|
||||
const GValue *value);
|
||||
LIBGLADEUI_API GValue *glade_property_class_make_gvalue_from_vl (GladePropertyClass *property_class,
|
||||
|
@ -269,7 +269,7 @@ glade_property_sync_impl (GladeProperty *property)
|
||||
|
||||
if (inproject)
|
||||
{
|
||||
glade_project_add_object (property->widget->project,
|
||||
glade_project_add_object (property->widget->project, NULL,
|
||||
glade_widget_get_object (property->widget));
|
||||
if (reselect)
|
||||
glade_project_selection_add
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "glade-clipboard.h"
|
||||
|
||||
#define GLADE_UTIL_SELECTION_NODE_SIZE 7
|
||||
#define GLADE_UTIL_COPY_BUFFSIZE 1024
|
||||
|
||||
/* List of widgets that have selection
|
||||
*/
|
||||
@ -187,28 +188,88 @@ glade_utils_get_pspec_from_funcname (const gchar *funcname)
|
||||
}
|
||||
|
||||
/**
|
||||
* glade_util_ui_warn:
|
||||
* glade_util_ui_message:
|
||||
* @parent: a #GtkWindow cast as a #GtkWidget
|
||||
* @warning: a string
|
||||
* @format: a printf style format string
|
||||
* @type: a #GladeUIMessageType
|
||||
* @...: args for the format.
|
||||
*
|
||||
* Creates a new warning dialog window as a child of @parent containing
|
||||
* the text of @warning, runs it, then destroys it on close.
|
||||
* the text of @format, runs it, then destroys it on close. Depending
|
||||
* on @type, a cancel button may apear or the icon may change.
|
||||
*
|
||||
* Returns: True if the @type was GLADE_UI_ARE_YOU_SURE and the user
|
||||
* selected "OK", True if the @type was GLADE_UI_YES_OR_NO and
|
||||
* the user selected "YES"; False otherwise.
|
||||
*/
|
||||
void
|
||||
glade_util_ui_warn (GtkWidget *parent, const gchar *warning)
|
||||
gboolean
|
||||
glade_util_ui_message (GtkWidget *parent,
|
||||
GladeUIMessageType type,
|
||||
const gchar *format,
|
||||
...)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *dialog;
|
||||
GtkMessageType message_type = GTK_MESSAGE_INFO;
|
||||
GtkButtonsType buttons_type = GTK_BUTTONS_OK;
|
||||
va_list args;
|
||||
gchar *string;
|
||||
gint response;
|
||||
|
||||
va_start (args, format);
|
||||
string = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
|
||||
/* Get message_type */
|
||||
switch (type)
|
||||
{
|
||||
case GLADE_UI_INFO: message_type = GTK_MESSAGE_INFO; break;
|
||||
case GLADE_UI_WARN:
|
||||
case GLADE_UI_ARE_YOU_SURE:
|
||||
message_type = GTK_MESSAGE_WARNING;
|
||||
break;
|
||||
case GLADE_UI_ERROR: message_type = GTK_MESSAGE_ERROR; break;
|
||||
case GLADE_UI_YES_OR_NO: message_type = GTK_MESSAGE_QUESTION; break;
|
||||
break;
|
||||
default:
|
||||
g_critical ("Bad arg for glade_util_ui_message");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Get buttons_type */
|
||||
switch (type)
|
||||
{
|
||||
case GLADE_UI_INFO:
|
||||
case GLADE_UI_WARN:
|
||||
case GLADE_UI_ERROR:
|
||||
buttons_type = GTK_BUTTONS_OK;
|
||||
break;
|
||||
case GLADE_UI_ARE_YOU_SURE: buttons_type = GTK_BUTTONS_OK_CANCEL; break;
|
||||
case GLADE_UI_YES_OR_NO: buttons_type = GTK_BUTTONS_YES_NO; break;
|
||||
break;
|
||||
default:
|
||||
g_critical ("Bad arg for glade_util_ui_message");
|
||||
break;
|
||||
}
|
||||
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_WARNING,
|
||||
GTK_BUTTONS_OK,
|
||||
warning);
|
||||
message_type,
|
||||
buttons_type,
|
||||
string);
|
||||
|
||||
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
g_free (string);
|
||||
|
||||
return (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_YES);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
GtkStatusbar *statusbar;
|
||||
guint context_id;
|
||||
@ -1061,16 +1122,16 @@ glade_util_paste_clipboard (GladePlaceholder *placeholder,
|
||||
if (placeholder == NULL &&
|
||||
g_list_length (list) != 1)
|
||||
{
|
||||
glade_util_ui_warn
|
||||
(glade_default_app_get_window(),
|
||||
_("Unable to paste to multiple widgets"));
|
||||
glade_util_ui_message (glade_default_app_get_window(),
|
||||
GLADE_UI_WARN,
|
||||
_("Unable to paste to multiple widgets"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_list_length (clipboard->selection) == 0)
|
||||
{
|
||||
glade_util_ui_warn (glade_default_app_get_window (),
|
||||
glade_util_ui_message (glade_default_app_get_window (), GLADE_UI_WARN,
|
||||
_("No widget selected on the clipboard"));
|
||||
return;
|
||||
}
|
||||
@ -1086,11 +1147,10 @@ glade_util_paste_clipboard (GladePlaceholder *placeholder,
|
||||
*/
|
||||
if (glade_util_widget_pastable (widget, parent) == FALSE)
|
||||
{
|
||||
gchar *message = g_strdup_printf
|
||||
(_("Unable to paste widget %s to parent %s"),
|
||||
widget->name, parent->name);
|
||||
glade_util_ui_warn (glade_default_app_get_window (), message);
|
||||
g_free (message);
|
||||
glade_util_ui_message (glade_default_app_get_window (),
|
||||
GLADE_UI_ERROR,
|
||||
_("Unable to paste widget %s to parent %s"),
|
||||
widget->name, parent->name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1108,18 +1168,20 @@ glade_util_paste_clipboard (GladePlaceholder *placeholder,
|
||||
parent && parent->manager != NULL &&
|
||||
gtkcontainer_relations != 1)
|
||||
{
|
||||
glade_util_ui_warn (glade_default_app_get_window (),
|
||||
_("Only one widget can be pasted at a "
|
||||
"time to this container"));
|
||||
glade_util_ui_message (glade_default_app_get_window (),
|
||||
GLADE_UI_WARN,
|
||||
_("Only one widget can be pasted at a "
|
||||
"time to this container"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent && parent->manager == NULL &&
|
||||
glade_util_count_placeholders (parent) < gtkcontainer_relations)
|
||||
{
|
||||
glade_util_ui_warn (glade_default_app_get_window (),
|
||||
_("Insufficient amount of placeholders in "
|
||||
"target container"));
|
||||
glade_util_ui_message (glade_default_app_get_window (),
|
||||
GLADE_UI_WARN,
|
||||
_("Insufficient amount of placeholders in "
|
||||
"target container"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1165,8 +1227,8 @@ glade_util_cut_selection (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
glade_util_ui_warn (glade_default_app_get_window (),
|
||||
_("No widget selected!"));
|
||||
glade_util_ui_message (glade_default_app_get_window (),
|
||||
GLADE_UI_WARN, _("No widget selected!"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1196,8 +1258,9 @@ glade_util_copy_selection (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
glade_util_ui_warn (glade_default_app_get_window(),
|
||||
_("No widget selected!"));
|
||||
glade_util_ui_message (glade_default_app_get_window(),
|
||||
GLADE_UI_WARN,
|
||||
_("No widget selected!"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1226,8 +1289,9 @@ glade_util_delete_selection (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
glade_util_ui_warn (glade_default_app_get_window(),
|
||||
_("No widget selected!"));
|
||||
glade_util_ui_message (glade_default_app_get_window(),
|
||||
GLADE_UI_WARN,
|
||||
_("No widget selected!"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1363,6 +1427,8 @@ glade_util_canonical_path (const gchar *path)
|
||||
{
|
||||
gchar *orig_dir, *dirname, *basename, *direct_dir, *direct_name = NULL;
|
||||
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
|
||||
basename = g_path_get_basename (path);
|
||||
|
||||
if ((orig_dir = g_get_current_dir ()) != NULL)
|
||||
@ -1393,3 +1459,146 @@ glade_util_canonical_path (const gchar *path)
|
||||
|
||||
return direct_name;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glade_util_canonical_match (const gchar *src_path,
|
||||
const gchar *dest_path)
|
||||
{
|
||||
gchar *canonical_src, *canonical_dest;
|
||||
gboolean match;
|
||||
canonical_src = glade_util_canonical_path (src_path);
|
||||
canonical_dest = glade_util_canonical_path (dest_path);
|
||||
|
||||
match = (strcmp (canonical_src, canonical_dest) == 0);
|
||||
|
||||
g_free (canonical_src);
|
||||
g_free (canonical_dest);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
/**
|
||||
* glade_util_copy_file:
|
||||
* @src_path: the path to the source file
|
||||
* @dest_path: the path to the destination file to create or overwrite.
|
||||
*
|
||||
* Copies a file from @src to @dest, queries the user
|
||||
* if it involves overwriting the target and displays an
|
||||
* error message upon failure.
|
||||
*
|
||||
* Returns: True if the copy was successfull.
|
||||
*/
|
||||
gboolean
|
||||
glade_util_copy_file (const gchar *src_path,
|
||||
const gchar *dest_path)
|
||||
{
|
||||
GIOChannel *src, *dest;
|
||||
GError *error = NULL;
|
||||
GIOStatus read_status, write_status;
|
||||
gchar buffer[GLADE_UTIL_COPY_BUFFSIZE];
|
||||
gsize bytes_read, bytes_written, written;
|
||||
gboolean success = FALSE;
|
||||
|
||||
/* FIXME: This may break if src_path & dest_path are actually
|
||||
* the same file, right now the canonical comparison is the
|
||||
* best check I have.
|
||||
*/
|
||||
if (glade_util_canonical_match (src_path, dest_path))
|
||||
return FALSE;
|
||||
|
||||
if (g_file_test (dest_path, G_FILE_TEST_IS_REGULAR) == TRUE)
|
||||
if (glade_util_ui_message
|
||||
(glade_default_app_get_window(), GLADE_UI_YES_OR_NO,
|
||||
_("%s exists. Do you want to replace it ?"), dest_path) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
|
||||
if ((src = g_io_channel_new_file (src_path, "r", &error)) != NULL)
|
||||
{
|
||||
g_io_channel_set_encoding (src, NULL, NULL);
|
||||
|
||||
if ((dest = g_io_channel_new_file (dest_path, "w", &error)) != NULL)
|
||||
{
|
||||
g_io_channel_set_encoding (dest, NULL, NULL);
|
||||
|
||||
while ((read_status = g_io_channel_read_chars
|
||||
(src, buffer, GLADE_UTIL_COPY_BUFFSIZE,
|
||||
&bytes_read, &error)) != G_IO_STATUS_ERROR)
|
||||
{
|
||||
bytes_written = 0;
|
||||
while ((write_status = g_io_channel_write_chars
|
||||
(dest, buffer + bytes_written,
|
||||
bytes_read - bytes_written,
|
||||
&written, &error)) != G_IO_STATUS_ERROR &&
|
||||
(bytes_written < bytes_read))
|
||||
bytes_written += written;
|
||||
|
||||
if (write_status == G_IO_STATUS_ERROR)
|
||||
{
|
||||
glade_util_ui_message (glade_default_app_get_window(),
|
||||
GLADE_UI_ERROR,
|
||||
_("Error writing to %s: %s"),
|
||||
dest_path, error->message);
|
||||
error = (g_error_free (error), NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Break on EOF & ERROR but not AGAIN and not NORMAL */
|
||||
if (read_status == G_IO_STATUS_EOF) break;
|
||||
}
|
||||
|
||||
if (read_status == G_IO_STATUS_ERROR)
|
||||
{
|
||||
glade_util_ui_message (glade_default_app_get_window(),
|
||||
GLADE_UI_ERROR,
|
||||
_("Error reading %s: %s"),
|
||||
src_path, error->message);
|
||||
error = (g_error_free (error), NULL);
|
||||
}
|
||||
|
||||
|
||||
/* From here on, unless we have problems shutting down, succuss ! */
|
||||
success = (read_status == G_IO_STATUS_EOF &&
|
||||
write_status == G_IO_STATUS_NORMAL);
|
||||
|
||||
if (g_io_channel_shutdown (dest, TRUE, &error) != G_IO_STATUS_NORMAL)
|
||||
{
|
||||
glade_util_ui_message
|
||||
(glade_default_app_get_window(),
|
||||
GLADE_UI_ERROR,
|
||||
_("Error shutting down io channel %s: %s"),
|
||||
dest_path, error->message);
|
||||
error = (g_error_free (error), NULL);
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glade_util_ui_message (glade_default_app_get_window(),
|
||||
GLADE_UI_ERROR,
|
||||
_("Failed to open %s for writing: %s"),
|
||||
dest_path, error->message);
|
||||
error = (g_error_free (error), NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (g_io_channel_shutdown (src, TRUE, &error) != G_IO_STATUS_NORMAL)
|
||||
{
|
||||
glade_util_ui_message (glade_default_app_get_window(),
|
||||
GLADE_UI_ERROR,
|
||||
_("Error shutting down io channel %s: %s"),
|
||||
src_path, error->message);
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glade_util_ui_message (glade_default_app_get_window(),
|
||||
GLADE_UI_ERROR,
|
||||
_("Failed to open %s for reading: %s"),
|
||||
src_path, error->message);
|
||||
error = (g_error_free (error), NULL);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ G_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef enum _GladeUtilFileDialogType GladeUtilFileDialogType;
|
||||
typedef enum _GladeUIMessageType GladeUIMessageType;
|
||||
|
||||
enum _GladeUtilFileDialogType
|
||||
{
|
||||
@ -14,13 +15,24 @@ enum _GladeUtilFileDialogType
|
||||
GLADE_FILE_DIALOG_ACTION_SAVE
|
||||
};
|
||||
|
||||
enum _GladeUIMessageType {
|
||||
GLADE_UI_INFO,
|
||||
GLADE_UI_WARN,
|
||||
GLADE_UI_ERROR,
|
||||
GLADE_UI_ARE_YOU_SURE,
|
||||
GLADE_UI_YES_OR_NO
|
||||
};
|
||||
|
||||
|
||||
#define glade_implement_me() g_print ("Implement me : %s %d %s\n", __FILE__, __LINE__, G_GNUC_FUNCTION);
|
||||
|
||||
|
||||
LIBGLADEUI_API void glade_util_widget_set_tooltip (GtkWidget *widget, const gchar *str);
|
||||
LIBGLADEUI_API GType glade_util_get_type_from_name (const gchar *name);
|
||||
LIBGLADEUI_API GParamSpec *glade_utils_get_pspec_from_funcname (const gchar *funcname);
|
||||
LIBGLADEUI_API void glade_util_ui_warn (GtkWidget *parent, const gchar *warning);
|
||||
LIBGLADEUI_API gboolean glade_util_ui_message (GtkWidget *parent,
|
||||
GladeUIMessageType type,
|
||||
const gchar *format, ...);
|
||||
LIBGLADEUI_API void glade_util_flash_message (GtkWidget *statusbar,
|
||||
guint context_id,
|
||||
gchar *format, ...);
|
||||
@ -78,8 +90,12 @@ LIBGLADEUI_API gboolean glade_util_basenames_match (const gchar
|
||||
const gchar *path2);
|
||||
|
||||
LIBGLADEUI_API GList *glade_util_purify_list (GList *list);
|
||||
LIBGLADEUI_API gchar *glade_util_canonical_path (const gchar *path);
|
||||
|
||||
LIBGLADEUI_API gboolean glade_util_copy_file (const gchar *src,
|
||||
const gchar *dest);
|
||||
|
||||
|
||||
LIBGLADEUI_API gchar *glade_util_direct_path (const gchar *path);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -92,6 +92,13 @@ enum
|
||||
static guint glade_widget_signals[LAST_SIGNAL] = {0};
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
/* Sometimes we need to use the project deep in the loading code,
|
||||
* this is just a shortcut way to get the project.
|
||||
*/
|
||||
static GladeProject *loading_project = NULL;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* glade_widget_get_type:
|
||||
*
|
||||
@ -603,7 +610,8 @@ glade_widget_set_default_packing_properties (GladeWidget *container,
|
||||
|
||||
/* Check value type */
|
||||
value = glade_property_class_make_gvalue_from_string (property_class,
|
||||
def->value);
|
||||
def->value,
|
||||
child->project);
|
||||
|
||||
glade_widget_class_container_set_property (container->widget_class,
|
||||
container->object,
|
||||
@ -2518,7 +2526,8 @@ glade_widget_value_from_prop_info (GladePropInfo *info,
|
||||
if (info->name && info->value &&
|
||||
(pclass = glade_widget_class_get_property_class (class, id)) != NULL)
|
||||
gvalue = glade_property_class_make_gvalue_from_string (pclass,
|
||||
info->value);
|
||||
info->value,
|
||||
loading_project);
|
||||
|
||||
g_free (id);
|
||||
|
||||
@ -2696,7 +2705,7 @@ glade_widget_properties_from_widget_info (GladeWidgetClass *class,
|
||||
GladeProperty *property;
|
||||
gboolean translatable;
|
||||
gboolean has_context;
|
||||
gchar *comment = NULL;
|
||||
gchar *comment = NULL, *string;
|
||||
const gchar *obj_name;
|
||||
|
||||
/* If there is a value in the XML, initialize property with it,
|
||||
@ -3006,6 +3015,8 @@ GladeWidget *
|
||||
glade_widget_read (GladeProject *project, GladeWidgetInfo *info)
|
||||
{
|
||||
GladeWidget *widget;
|
||||
|
||||
loading_project = project;
|
||||
|
||||
if ((widget = glade_widget_new_from_widget_info
|
||||
(info, project, NULL)) != NULL)
|
||||
@ -3013,5 +3024,8 @@ glade_widget_read (GladeProject *project, GladeWidgetInfo *info)
|
||||
if (glade_verbose)
|
||||
glade_widget_debug (widget);
|
||||
}
|
||||
|
||||
loading_project = NULL;
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
@ -131,6 +131,7 @@ typedef struct _GladeProject GladeProject;
|
||||
#define GLADE_TAG_EDITABLE "editable"
|
||||
#define GLADE_TAG_IGNORE "ignore"
|
||||
#define GLADE_TAG_VISIBLE_LINES "visible-lines"
|
||||
#define GLADE_TAG_RESOURCE "resource"
|
||||
|
||||
#define GLADE_NUMERICAL_STEP_INCREMENT 1
|
||||
#define GLADE_FLOATING_STEP_INCREMENT 0.01F
|
||||
|
@ -202,9 +202,17 @@ things you can do with properties.
|
||||
plugin override functions) when it changes in the editor (the value in the
|
||||
editor is the value saved).
|
||||
|
||||
- resource: This is for string properties that represent filenames that are packaged with
|
||||
the glade file (like pixbufs); you can set this to true and the string
|
||||
property will be treated like a resource.
|
||||
|
||||
`property' tag values:
|
||||
|
||||
|
||||
- spec: Specifies a function to be used to return a GParamSpec for this property;
|
||||
this is used to add virtual properties to an object (like the "size" property
|
||||
on GtkBox).
|
||||
|
||||
- tooltip: The tooltip to be displayed in the property editor for this property, this
|
||||
is also translated. The tooltip defaults to the blurb of the associated
|
||||
GParamSpec.
|
||||
@ -229,9 +237,6 @@ things you can do with properties.
|
||||
|
||||
gboolean verify_function (GObject *object, GValue *value);
|
||||
|
||||
- spec: Specifies a function to be used to return a GParamSpec for this property;
|
||||
this is used to add virtual properties to an object (like the "size" property
|
||||
on GtkBox).
|
||||
|
||||
Displayable values
|
||||
------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user