On Tue, Jan 14, 2003 at 09:08:44AM -0200, Ricardo Caesar Lenzi wrote:
> All my pixmaps are in the 'pixmaps' diretory and all glade files are in
> the 'glade' directory. While design with glade thats all ok, but when I
> start my application I got the error:
> 
> Gdk-CRITICAL **: file gdkdraw.c: line 380 (gdk_draw_pixmap): assertion
> `src != NULL' failed.
> 
> and the pixmaps don't appear. It seems that libglade does not follow the
> glade pixmap directory. 
> 
> The question is: Can I indicate the pixmap directory in libglade?

Heh. Coincidences. We decided to look into this last week because it was
a serious problem to us. The issue is as follows:

    - Glade saves only the pixmap filename in the XML file. It *does*
      allow specifying a pixmap directory (configurable through the
      project options dialog) which is included in the top of the file,
      but that section is never parsed by libglade.

    - Glade copies the pixmaps you indicate from the original directory
      to the directory specified in the pixmaps directory option.

    - libglade, since all it knows is the pixmap filename, tries to load
      all pixmaps from the same directory as it loads the glade file.
      Since your pixmaps are not in there, it doesn't find them, and
      they are never loaded.

There are a couple of solutions to this problem:

    - Make links from the pixmap directory XPMs to the glade directory.
      This works, but CVS doesn't create links and you will need to run
      a script to generate this upon checkout/update.

    - Hack libglade to support the pixmap directory. This is only a
      problem if you consider the issue of relative paths (you would
      need to configure the pixmap path relative to the glade file, and
      in my case, I have:

        App1/
        App1/glade/*.glade
        App2/
        App2/glade/*.glade
        components/dialog1/
        components/dialog1/glade/*.glade
        components/dialog2/
        components/dialog2/glade/*.glade
        data/
        data/pixmaps/*.xpm

      which would force me to use ../data/pixmaps/ in the parameter, and
      since I have multiple glade files, I would need to use a different
      path per gladefile) This is not difficult to implement if you
      decide to, and it might be a clean solution.

    - Hack libglade and glade to support a GLADE_PIXMAP_PATH environment
      variable, which indicates where the pixmap is to be found. Johan
      hacked this for us last week and I have the diffs here. I am
      hoping James will comment on this approach and let me know if it
      is acceptable for integration with CVS libglade (nothing was
      changed beyond looking in this environment variable). Glade was
      changed to also look in the path for pixmaps.

We didn't implement option b. because I thought it was less clean, and
also because I thought James was less likely to accept the patch, but if
he does it should be easy to change these patches to do it. 

HTH!

Take care,
--
Christian Reis, Senior Engineer, Async Open Source, Brazil.
http://async.com.br/~kiko/ | [+55 16] 261 2331 | NMFL
diff -ur libglade-0.17/glade/glade-gtk.c libglade-0.17-new/glade/glade-gtk.c
--- libglade-0.17/glade/glade-gtk.c     2001-09-04 23:01:32.000000000 -0300
+++ libglade-0.17-new/glade/glade-gtk.c 2003-01-08 19:38:25.000000000 -0200
@@ -25,6 +25,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <glade/glade-build.h>
 #include <glade/glade-private.h>
 #include <gmodule.h>
@@ -37,6 +38,35 @@
 #undef _
 #define _(msgid) (glade_xml_gettext(xml, msgid))
 
+char *
+find_in_glade_pixmap_path (const char *filename)
+{
+       gchar *env, *pixmap;
+       gchar **parts;
+       gint i;
+
+       env = g_getenv("GLADE_PIXMAP_PATH");
+       if (env == NULL) {
+               return NULL;
+       }
+       
+       parts = g_strsplit(env, ":", 255);
+       for (i = 0; parts[i] != NULL; i++) {
+               pixmap = g_strdup_printf("%s/%s", parts[i],
+                                       g_basename(filename));
+              
+               /* Check if the pixmap exist and is readable */
+               if (!access(pixmap, R_OK)) {
+                       return pixmap;
+               }
+               
+               g_free(parts[i]);
+               g_free(pixmap);
+       }
+       g_free(parts);
+       return NULL;
+}
+
 /* functions to actually build the widgets */
 
 static void
@@ -580,6 +610,7 @@
        g_free (vboxname);
 }
 
+
 static void
 toolbar_build_children (GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
                        const char *longname)
@@ -628,6 +659,13 @@
                        if (icon) {
                                GdkPixmap *pix;
                                GdkBitmap *mask = NULL;
+                               gchar *full_path;
+                               
+                               full_path = find_in_glade_pixmap_path(icon);
+                               if (full_path != NULL) {
+                                       icon = full_path;
+                               }
+
                                pix = gdk_pixmap_colormap_create_from_xpm(NULL,
                                        gtk_widget_get_colormap(w), &mask,
                                        NULL, icon);
@@ -1778,7 +1816,8 @@
        GdkPixmap *pixmap;
        GdkBitmap *bitmap = NULL;
        char *filename = NULL;
-  
+       char *full_path;
+       
        for (tmp = info->attributes; tmp; tmp = tmp->next) {
                GladeAttribute *attr = tmp->data;
 
@@ -1788,6 +1827,12 @@
                        break;
                }
        }
+
+       full_path = find_in_glade_pixmap_path(filename);
+       if (full_path != NULL) {
+               filename = full_path;
+       }
+
        pixmap = gdk_pixmap_colormap_create_from_xpm(NULL,
                gtk_widget_get_default_colormap(), &bitmap, NULL, filename);
        if (filename)
diff -ur glade-0.6.4/glade/glade_project.c glade-0.6.4-new/glade/glade_project.c
--- glade-0.6.4/glade/glade_project.c   2000-09-17 19:49:16.000000000 -0300
+++ glade-0.6.4-new/glade/glade_project.c       2003-01-08 15:49:22.000000000 -0200
@@ -836,7 +836,12 @@
   GList *element;
   GladeError *error = NULL;
   gboolean checked_pixmaps_dir = FALSE;
-
+  
+  if (g_getenv("GLADE_PIXMAP_PATH") != NULL)
+    {
+      return NULL;
+    }
+        
   pixmaps_dir = glade_project_get_pixmaps_directory (project);
   if (!pixmaps_dir || pixmaps_dir[0] == '\0')
     {
diff -ur glade-0.6.4/glade/load.c glade-0.6.4-new/glade/load.c
--- glade-0.6.4/glade/load.c    2001-02-15 01:42:33.000000000 -0200
+++ glade-0.6.4-new/glade/load.c        2003-01-08 19:40:56.000000000 -0200
@@ -20,6 +20,7 @@
 #include <string.h>
 #include <locale.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include "gladeconfig.h"
 
@@ -810,6 +811,34 @@
   return value ? value : "";
 }
 
+char *
+find_in_glade_pixmap_path (const char *filename)
+{
+       gchar *env, *pixmap;
+       gchar **parts;
+       gint i;
+
+       env = g_getenv("GLADE_PIXMAP_PATH");
+       if (env == NULL) {
+               return NULL;
+       }
+
+       parts = g_strsplit(env, ":", 255);
+       for (i = 0; parts[i] != NULL; i++) {
+               pixmap = glade_util_make_absolute_path(parts[i],
+                                                     g_basename(filename));
+
+               /* Check if the pixmap exist and is readable */
+               if (!access(pixmap, R_OK)) {
+                       return pixmap;
+               }
+              
+              g_free(parts[i]);
+               g_free(pixmap);
+       }
+       g_free(parts);
+       return NULL;
+}
 
 /* If we are loading the XML file, we convert any relative filenames to
    absolute ones, based on the project directory and/or pixmaps directory
@@ -819,11 +848,18 @@
                      const gchar * property_name)
 {
   gchar *value = load_get_value (data, property_name);
+  gchar *pixmap;
   gchar *pixmaps_dir;
 
   if (value == NULL)
     return NULL;
 
+  pixmap = find_in_glade_pixmap_path(value);
+  if (pixmap != NULL) 
+     {
+            return pixmap;
+     }
+
   if (data->xml_buffer == NULL)
     {
       pixmaps_dir = glade_project_get_pixmaps_directory (data->project);

Reply via email to