aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2009-12-16 22:37:19 -0800
committerThomas White <taw@bitwiz.org.uk>2009-12-16 22:37:19 -0800
commit5dc417886b5bb36b43d9354672cfc9e2a2b29512 (patch)
tree2e980b98cd9c3506ab279a2d22680fc9463774f4 /src
parenta372a83f4d1abb6ad6cca90f6ceb108cb4d7664a (diff)
Walk HDF groups to display a menu and switch image
Diffstat (limited to 'src')
-rw-r--r--src/displaywindow.c117
-rw-r--r--src/hdf5-file.c54
-rw-r--r--src/hdf5-file.h2
3 files changed, 173 insertions, 0 deletions
diff --git a/src/displaywindow.c b/src/displaywindow.c
index 52de25d8..b27ca35f 100644
--- a/src/displaywindow.c
+++ b/src/displaywindow.c
@@ -579,6 +579,7 @@ static void displaywindow_addmenubar(DisplayWindow *dw, GtkWidget *vbox)
GtkActionEntry entries[] = {
{ "FileAction", NULL, "_File", NULL, NULL, NULL },
+ { "ImagesAction", NULL, "Images", NULL, NULL, NULL },
{ "CloseAction", GTK_STOCK_CLOSE, "_Close", NULL, NULL,
G_CALLBACK(displaywindow_close) },
@@ -630,11 +631,125 @@ static void displaywindow_addmenubar(DisplayWindow *dw, GtkWidget *vbox)
}
+struct newhdf {
+ DisplayWindow *dw;
+ char name[1024];
+};
+
+static gint displaywindow_newhdf(GtkMenuItem *item, struct newhdf *nh)
+{
+ hdfile_set_image(nh->dw->hdfile, nh->name);
+ displaywindow_update(nh->dw);
+ return 0;
+}
+
+
+static GtkWidget *displaywindow_addhdfgroup(struct hdfile *hdfile,
+ const char *group,
+ DisplayWindow *dw)
+{
+ char **names;
+ int *is_group;
+ int *is_image;
+ GtkWidget *ms;
+ int n, i;
+
+ names = hdfile_walk_tree(hdfile, &n, group, &is_group, &is_image);
+ if ( n == 0 ) return NULL;
+
+ ms = gtk_menu_new();
+
+ for ( i=0; i<n; i++ ) {
+
+ GtkWidget *item;
+ GtkWidget *sub;
+
+ if ( names[i] != NULL ) {
+
+ char subgroup[1024];
+
+ item = gtk_menu_item_new_with_label(names[i]);
+ gtk_menu_shell_append(GTK_MENU_SHELL(ms), item);
+ gtk_widget_show(item);
+
+ if ( is_group[i] ) {
+ snprintf(subgroup, 1023, "%s/%s",
+ group, names[i]);
+ sub = displaywindow_addhdfgroup(hdfile,
+ subgroup, dw);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),
+ sub);
+ } else if ( is_image[i] ) {
+
+ struct newhdf *nh;
+
+ nh = malloc(sizeof(struct newhdf));
+ if ( nh != NULL ) {
+ snprintf(nh->name, 1023, "%s/%s", group,
+ names[i]);
+ nh->dw = dw;
+ g_signal_connect(G_OBJECT(item),
+ "activate",
+ G_CALLBACK(displaywindow_newhdf),
+ nh);
+ }
+ }
+
+ free(names[i]);
+
+ } else {
+ return NULL;
+ }
+
+ }
+
+ free(is_group);
+ free(is_image);
+
+ return ms;
+}
+
+
+static void displaywindow_update_menus(DisplayWindow *dw)
+{
+ GtkWidget *ms;
+ GtkWidget *w;
+
+ ms = displaywindow_addhdfgroup(dw->hdfile, "/", dw);
+
+ if ( ms == NULL ) {
+
+ /* Too bad. You'd better hope that /data/data exists... */
+ ERROR("Couldn't get list of images in HDF file\n");
+ w = gtk_ui_manager_get_widget(dw->ui,
+ "/ui/displaywindow/file/images");
+ gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE);
+
+ /* Add a dummy menu so that the user knows what's going on */
+ ms = gtk_menu_new();
+ w = gtk_ui_manager_get_widget(dw->ui,
+ "/ui/displaywindow/file/images");
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(w), ms);
+
+ return;
+
+ }
+
+ /* Make new menu be the submenu for File->Images */
+ w = gtk_ui_manager_get_widget(dw->ui, "/ui/displaywindow/file/images");
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(w), ms);
+}
+
+
static void displaywindow_disable(DisplayWindow *dw)
{
GtkWidget *w;
w = gtk_ui_manager_get_widget(dw->ui,
+ "/ui/displaywindow/file/images");
+ gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE);
+
+ w = gtk_ui_manager_get_widget(dw->ui,
"/ui/displaywindow/view/binning");
gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE);
@@ -786,5 +901,7 @@ DisplayWindow *displaywindow_open(const char *filename)
g_signal_connect(GTK_OBJECT(dw->drawingarea), "button-release-event",
G_CALLBACK(displaywindow_release), dw);
+ displaywindow_update_menus(dw);
+
return dw;
}
diff --git a/src/hdf5-file.c b/src/hdf5-file.c
index ea3b91f7..0d211998 100644
--- a/src/hdf5-file.c
+++ b/src/hdf5-file.c
@@ -248,3 +248,57 @@ int hdf5_read(struct hdfile *f, struct image *image)
return 0;
}
+
+
+char **hdfile_walk_tree(struct hdfile *f, int *n, const char *parent,
+ int **p_is_group, int **p_is_image)
+{
+ hid_t gh;
+ hsize_t num;
+ char **res;
+ int i;
+ int *is_group;
+ int *is_image;
+
+ gh = H5Gopen(f->fh, parent, H5P_DEFAULT);
+ if ( gh < 0 ) {
+ *n = 0;
+ return NULL;
+ }
+
+ if ( H5Gget_num_objs(gh, &num) < 0 ) {
+ /* Whoopsie */
+ *n = 0;
+ return NULL;
+ }
+ *n = num;
+ if ( num == 0 ) return NULL; /* Bail out now */
+
+ res = malloc(num*sizeof(char *));
+ is_image = malloc(num*sizeof(int));
+ is_group = malloc(num*sizeof(int));
+ *p_is_image = is_image;
+ *p_is_group = is_group;
+
+ for ( i=0; i<num; i++ ) {
+
+ char buf[256];
+ int type;
+
+ H5Gget_objname_by_idx(gh, i, buf, 255);
+ res[i] = strdup(buf);
+
+ type = H5Gget_objtype_by_idx(gh, i);
+ is_image[i] = 0;
+ is_group[i] = 0;
+ if ( type == H5G_GROUP ) {
+ is_group[i] = 1;
+ } else if ( type == H5G_DATASET ) {
+ /* FIXME: Check better */
+ is_image[i] = 1;
+ }
+
+ }
+
+ return res;
+}
diff --git a/src/hdf5-file.h b/src/hdf5-file.h
index 7ad3cd25..a7e0f89e 100644
--- a/src/hdf5-file.h
+++ b/src/hdf5-file.h
@@ -36,6 +36,8 @@ extern int16_t *hdfile_get_image_binned(struct hdfile *hdfile,
int binning, int16_t *maxp);
extern int hdfile_get_unbinned_value(struct hdfile *f, int x, int y,
int16_t *val);
+extern char **hdfile_walk_tree(struct hdfile *f, int *n, const char *parent,
+ int **p_is_group, int **p_is_image);
extern void hdfile_close(struct hdfile *f);
#endif /* HDF5_H */