diff options
author | Thomas White <taw@bitwiz.org.uk> | 2009-12-16 22:37:19 -0800 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2009-12-16 22:37:19 -0800 |
commit | 5dc417886b5bb36b43d9354672cfc9e2a2b29512 (patch) | |
tree | 2e980b98cd9c3506ab279a2d22680fc9463774f4 /src | |
parent | a372a83f4d1abb6ad6cca90f6ceb108cb4d7664a (diff) |
Walk HDF groups to display a menu and switch image
Diffstat (limited to 'src')
-rw-r--r-- | src/displaywindow.c | 117 | ||||
-rw-r--r-- | src/hdf5-file.c | 54 | ||||
-rw-r--r-- | src/hdf5-file.h | 2 |
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 */ |