/* SciGraphica - Scientific graphics and data manipulation * Copyright (C) 2001 Adrian E. Feiguin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "sg_dataset_dialog.h" #include "sg.h" #include "sg_dataset.h" #include "sg_layer.h" #include "sg_dialogs.h" #include "../pixmaps/pixmaps.h" static gchar **data_pixmaps[13]; static SGdataset *dataset = NULL; static GtkWidget *worksheet_combo; static GtkWidget *datasets_list; static GtkWidget *project_list; static SGplot *plot; static GList *old_datasets = NULL; static GtkWidget *dialog = NULL; static SGlayer *the_layer; static void clist_fill_datasets(GtkWidget *clist, GList *datasets, gint col); static void clist_add_dataset(GtkWidget *clist, SGdataset *dataset, gint col); static void set_autostyle(SGdataset *dataset) { if(dataset->real_data->symbol.symbol_type != GTK_PLOT_SYMBOL_NONE){ dataset->real_data->symbol.symbol_type = (GtkPlotSymbolType)the_layer->symbol; dataset->real_data->symbol.symbol_style = (GtkPlotSymbolStyle)the_layer->symbol_style; the_layer->symbol++; if(the_layer->symbol >= NUM_SYMBOLS){ the_layer->symbol = 1; the_layer->symbol_style++; if(the_layer->symbol_style >= NUM_SYMBOL_STYLES) the_layer->symbol_style = 0; } } if(dataset->real_data->line.line_style != GTK_PLOT_LINE_NONE){ dataset->real_data->line.line_style = (GtkPlotLineStyle)the_layer->line_style; the_layer->line_style++; if(the_layer->line_style >= NUM_LINE_STYLES) the_layer->line_style = 1; } } static gboolean edit_project_dataset(GtkWidget *widget, gpointer data) { SGdataset *row_dataset = NULL; gchar *text[1]; gint i = 0; gint nrows; GList *selection; gint row; GdkColormap *colormap; GdkPixmap *pixmap; GdkBitmap *mask; SGdataset *link; colormap = gdk_colormap_get_system(); selection = GTK_CLIST(project_list)->selection; if(!selection) return TRUE; row = GPOINTER_TO_INT(selection->data); row_dataset = (SGdataset *)gtk_clist_get_row_data(GTK_CLIST(project_list), row); active_dataset = row_dataset; if(!active_dataset) return TRUE; sg_edit_data_dialog(row_dataset, the_layer->type); switch(row_dataset->type){ case SG_DATA_PYTHON: pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &mask, NULL, g_python_xpm); break; case SG_DATA_FUNCTION: pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &mask, NULL, g_function_xpm); break; case SG_DATA_COLUMNS: case SG_DATA_MATRIX: default: pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &mask, NULL, data_pixmaps[row_dataset->style]); break; } link = (SGdataset *)gtk_plot_data_get_link(row_dataset->real_data); text[0] = GTK_PLOT_DATA(link->real_data)->name; gtk_clist_set_pixtext(GTK_CLIST(project_list), row, 0, text[0], 5, pixmap, mask); gdk_pixmap_unref(pixmap); gdk_bitmap_unref(mask); return TRUE; } static gboolean edit_layer_dataset(GtkWidget *widget, gpointer data) { SGdataset *row_dataset = NULL; gchar *text[1]; gint i = 0; gint nrows; GList *selection; gint row; GdkColormap *colormap; GdkPixmap *pixmap; GdkBitmap *mask; SGdataset *link; gint dataset_style; GtkPlotSymbol symbol; GtkPlotLine line; GtkPlotConnector connector; colormap = gdk_colormap_get_system(); selection = GTK_CLIST(datasets_list)->selection; if(!selection) return TRUE; row = GPOINTER_TO_INT(selection->data); row_dataset = (SGdataset *)gtk_clist_get_row_data(GTK_CLIST(datasets_list), row); active_dataset = row_dataset; if(!active_dataset) return TRUE; dataset_style = row_dataset->style; symbol = row_dataset->real_data->symbol; line = row_dataset->real_data->line; connector = row_dataset->real_data->line_connector; sg_edit_data_dialog(row_dataset, the_layer->type); switch(row_dataset->type){ case SG_DATA_PYTHON: pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &mask, NULL, g_python_xpm); break; case SG_DATA_FUNCTION: pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &mask, NULL, g_function_xpm); break; case SG_DATA_COLUMNS: case SG_DATA_MATRIX: default: pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &mask, NULL, data_pixmaps[row_dataset->style]); break; } if(dataset_style == row_dataset->style){ row_dataset->real_data->symbol = symbol; row_dataset->real_data->line = line; row_dataset->real_data->line_connector = connector; } link = (SGdataset *)gtk_plot_data_get_link(row_dataset->real_data); text[0] = GTK_PLOT_DATA(link->real_data)->name; gtk_clist_set_pixtext(GTK_CLIST(datasets_list), row, 1, text[0], 5, pixmap, mask); gdk_pixmap_unref(pixmap); gdk_bitmap_unref(mask); return TRUE; } static gint show_dataset(GtkWidget *widget, gpointer data) { SGdataset *aux_dataset; GdkColormap *colormap; GdkPixmap *eye_pixmap; GdkBitmap *eye_mask; GList *selection; gint row; colormap = gdk_colormap_get_system(); selection = GTK_CLIST(datasets_list)->selection; if(!selection) return TRUE; row = GPOINTER_TO_INT(selection->data); aux_dataset = (SGdataset *)gtk_clist_get_row_data(GTK_CLIST(datasets_list), row); if(aux_dataset){ if(GTK_WIDGET_VISIBLE(aux_dataset->real_data)){ gtk_widget_hide(GTK_WIDGET(aux_dataset->real_data)); gtk_clist_set_text(GTK_CLIST(datasets_list), row, 0, NULL); }else{ gtk_widget_show(GTK_WIDGET(aux_dataset->real_data)); eye_pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &eye_mask, NULL, eye_xpm); gtk_clist_set_pixmap(GTK_CLIST(datasets_list), row, 0, eye_pixmap, eye_mask); gdk_pixmap_unref(eye_pixmap); gdk_bitmap_unref(eye_mask); } gtk_plot_canvas_paint(GTK_PLOT_CANVAS(plot->real_canvas)); gtk_plot_canvas_refresh(GTK_PLOT_CANVAS(plot->real_canvas)); } return TRUE; } static gint free_auxiliary_list(GList **aux_list) { GList *list; GList *old_list = *aux_list; while(old_list){ SGdataset *aux_data; aux_data = (SGdataset *)old_list->data; gtk_object_destroy(GTK_OBJECT(aux_data)); *aux_list = g_list_remove_link(*aux_list, old_list); g_list_free_1(old_list); old_list = *aux_list; } *aux_list = NULL; return TRUE; } void sg_data_dialog_update_plot(GtkWidget *widget) { GList *list = NULL; gint i; old_datasets = the_layer->datasets; /* REMOVE OLD DATASETS */ the_layer->datasets = NULL; list = GTK_PLOT(the_layer->real_plot)->data_sets; while(list){ gtk_plot_remove_data(GTK_PLOT(the_layer->real_plot), GTK_PLOT_DATA(list->data)); list = GTK_PLOT(the_layer->real_plot)->data_sets; } GTK_PLOT(the_layer->real_plot)->data_sets = NULL; /* ADD NEW DATASETS */ for(i = 0; i < GTK_CLIST(datasets_list)->rows; i++){ SGdataset *row_dataset, *link; gboolean visible; row_dataset = (SGdataset *)gtk_clist_get_row_data(GTK_CLIST(datasets_list), i); visible = GTK_WIDGET_VISIBLE(GTK_WIDGET(row_dataset->real_data)); link = (SGdataset *)gtk_plot_data_get_link(GTK_PLOT_DATA(row_dataset->real_data)); if(link && link != row_dataset){ GList *old_link; /* This dataset was originally there, we restore exactly how it was */ old_link = g_list_find(old_datasets, row_dataset); old_datasets = g_list_remove_link(old_datasets, old_link); g_list_free_1(old_link); sg_layer_add_dataset(the_layer, row_dataset); }else{ SGdataset *copy; /* This dataset was not there, we place a copy of the original */ copy = sg_dataset_clone(link); set_autostyle(copy); sg_layer_add_dataset(the_layer, copy); gtk_clist_set_row_data(GTK_CLIST(datasets_list), i, copy); } if(!visible) gtk_widget_hide(GTK_WIDGET(row_dataset->real_data)); } /* FREE AUXILIARY LISTS */ free_auxiliary_list(&old_datasets); sg_plot_refresh_datasets(plot); gtk_plot_canvas_paint(GTK_PLOT_CANVAS(plot->real_canvas)); gtk_plot_canvas_refresh(GTK_PLOT_CANVAS(plot->real_canvas)); } static gint create_dataset(GtkWidget *widget, gpointer data) { GList *list; active_dataset = dataset = sg_new_data_dialog(the_layer); if(!dataset) return FALSE; clist_add_dataset(project_list, dataset, 0); /* list = datasets; while(list){ printf("%d %s\n",SG_DATASET(list->data)->id, GTK_PLOT_DATA(SG_DATASET(list->data)->real_data)->name); list = list->next; } */ return TRUE; } static gint delete_dataset(GtkWidget *widget, gpointer data) { GList *selection = NULL; SGdataset *dataset = NULL; SGdataset *parent = NULL; gchar *text = NULL; gint row; gboolean veto; selection = GTK_CLIST(project_list)->selection; if(!selection) return TRUE; row = GPOINTER_TO_INT(selection->data); dataset = (SGdataset *)gtk_clist_get_row_data(GTK_CLIST(project_list), row); parent = (SGdataset *)gtk_plot_data_get_link(GTK_PLOT_DATA(dataset->real_data)); veto = sg_project_remove_dataset(parent, FALSE); if(veto) gtk_clist_remove(GTK_CLIST(project_list), row); } static gint add_dataset(GtkWidget *widget, gpointer data) { GList *selection = NULL; SGdataset *dataset = NULL; gchar *text = NULL; gint row; selection = GTK_CLIST(project_list)->selection; if(!selection) return TRUE; row = GPOINTER_TO_INT(selection->data); dataset = (SGdataset *)gtk_clist_get_row_data(GTK_CLIST(project_list), row); gtk_clist_remove(GTK_CLIST(project_list), row); gtk_widget_show(GTK_WIDGET(dataset->real_data)); clist_add_dataset(datasets_list, dataset, 1); return TRUE; } static gint restore_dataset(GtkWidget *widget, gpointer data) { GList *selection = NULL; SGdataset *dataset = NULL; SGdataset *link = NULL; gchar *text = NULL; gint row; selection = GTK_CLIST(datasets_list)->selection; if(!selection) return TRUE; row = GPOINTER_TO_INT(selection->data); dataset = SG_DATASET(gtk_clist_get_row_data(GTK_CLIST(datasets_list), row)); link = SG_DATASET(gtk_plot_data_get_link(GTK_PLOT_DATA(dataset->real_data))); gtk_clist_remove(GTK_CLIST(datasets_list), row); clist_add_dataset(project_list, link, 0); return TRUE; } static gint destroy_dialog(GtkWidget *widget, gpointer data) { GList *list; return TRUE; } static gint refresh_dataset(GtkWidget *widget, gpointer data) { SGdataset *aux_dataset; GList *selection; gint row; selection = GTK_CLIST(datasets_list)->selection; if(!selection) return TRUE; row = GPOINTER_TO_INT(selection->data); aux_dataset = (SGdataset *)gtk_clist_get_row_data(GTK_CLIST(datasets_list), row); if(aux_dataset){ sg_dataset_refresh(aux_dataset); gtk_plot_canvas_paint(GTK_PLOT_CANVAS(plot->real_canvas)); gtk_plot_canvas_refresh(GTK_PLOT_CANVAS(plot->real_canvas)); } return TRUE; } GtkWidget * sg_data_dialog_new (SGlayer *layer) { GtkWidget *frame; GtkWidget *main_box; GtkWidget *main_table; GtkWidget *button_box, *button_box2; GtkWidget *sw; GtkWidget *action_area; GtkWidget *new_button, *delete_button, *refresh_button, *show_button; GtkWidget *edit_project_button, *edit_layer_button; GtkWidget *left_button, *right_button; GdkColormap *colormap; GList *list; gchar *text[1]; gchar *titles1[] = {"Datasets", ""}; gchar *titles2[] = {"","Layer", ""}; colormap = gdk_colormap_get_system(); data_pixmaps[0] = g_python_xpm; data_pixmaps[1] = g_function_xpm; data_pixmaps[0] = g_lpoints_xpm; data_pixmaps[1] = g_bars_xpm; data_pixmaps[2] = g_hbars_xpm; data_pixmaps[3] = g_boxes_xpm; data_pixmaps[4] = g_hbox_xpm; data_pixmaps[5] = g_bubbles_xpm; data_pixmaps[6] = g_vectors_xpm; data_pixmaps[7] = g_colors_xpm; data_pixmaps[8] = g_density_xpm; data_pixmaps[9] = g_contour_xpm; data_pixmaps[10] = g_csurface_xpm; data_pixmaps[11] = g_surface_xpm; if(layer->type == SG_LAYER_3D){ data_pixmaps[0] = g_scatter3d_xpm; data_pixmaps[5] = g_bubbles3d_xpm; data_pixmaps[6] = g_flux3d_xpm; data_pixmaps[7] = g_colors3d_xpm; } plot = (SGplot *)layer->parent; the_layer = layer; active_dataset = NULL; /* Create widgets */ main_box = gtk_vbox_new (FALSE,5); gtk_container_set_border_width(GTK_CONTAINER(main_box), 10); main_table = gtk_table_new(2, 3, FALSE); gtk_table_set_col_spacings(GTK_TABLE(main_table), 5); gtk_box_pack_start(GTK_BOX(main_box), main_table, TRUE, TRUE, 0); /********************************************************************/ action_area = gtk_hbutton_box_new (); gtk_button_box_set_layout(GTK_BUTTON_BOX(action_area), GTK_BUTTONBOX_START); gtk_button_box_set_spacing(GTK_BUTTON_BOX(action_area), 5); gtk_table_attach_defaults(GTK_TABLE (main_table), action_area, 0, 1, 0, 1); new_button = gtk_button_new_with_label ("New"); gtk_box_pack_start (GTK_BOX (action_area), new_button, TRUE, TRUE, 0); gtk_widget_show (new_button); delete_button = gtk_button_new_with_label ("Delete"); gtk_box_pack_start (GTK_BOX (action_area), delete_button, TRUE, TRUE, 0); gtk_widget_show (delete_button); edit_project_button = gtk_button_new_with_label ("Edit"); gtk_box_pack_start (GTK_BOX (action_area), edit_project_button, TRUE, TRUE, 0); gtk_widget_show (edit_project_button); gtk_table_attach_defaults(GTK_TABLE (main_table), gtk_vseparator_new(), 1, 2, 0, 1); action_area = gtk_hbutton_box_new (); gtk_button_box_set_layout(GTK_BUTTON_BOX(action_area), GTK_BUTTONBOX_START); gtk_button_box_set_spacing(GTK_BUTTON_BOX(action_area), 5); gtk_table_attach_defaults(GTK_TABLE (main_table), action_area, 2, 3, 0, 1); /* refresh_button = gtk_button_new_with_label ("Refresh"); gtk_box_pack_start (GTK_BOX (action_area), refresh_button, TRUE, TRUE, 0); gtk_widget_show (refresh_button); */ show_button = gtk_button_new_with_label ("Show/Hide"); gtk_box_pack_start (GTK_BOX (action_area), show_button, TRUE, TRUE, 0); gtk_widget_show (show_button); edit_layer_button = gtk_button_new_with_label ("Edit"); gtk_box_pack_start (GTK_BOX (action_area), edit_layer_button, TRUE, TRUE, 0); gtk_widget_show (edit_layer_button); /********************************************************************/ button_box2 = gtk_vbox_new(FALSE, 0); gtk_table_attach(GTK_TABLE (main_table), button_box2, 1, 2, 1, 2, (GtkAttachOptions)0, GTK_SHRINK, 5, 5); button_box = gtk_hbox_new(TRUE, 0); gtk_box_pack_start(GTK_BOX(button_box2), button_box, FALSE, FALSE, 0); left_button = gtk_button_new(); gtk_container_add(GTK_CONTAINER(left_button), gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_OUT)); gtk_widget_set_usize(left_button, 20, 20); gtk_box_pack_start(GTK_BOX(button_box), left_button, FALSE, FALSE, 0); right_button = gtk_button_new(); gtk_container_add(GTK_CONTAINER(right_button), gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT)); gtk_widget_set_usize(right_button, 20, 20); gtk_box_pack_start(GTK_BOX(button_box), right_button, FALSE, FALSE, 0); gtk_signal_connect(GTK_OBJECT(left_button), "clicked", (GtkSignalFunc) restore_dataset, NULL); gtk_signal_connect(GTK_OBJECT(right_button), "clicked", (GtkSignalFunc) add_dataset, NULL); /********************************************************************/ sw = gtk_scrolled_window_new(NULL, NULL); gtk_container_set_border_width(GTK_CONTAINER(sw), 5); gtk_widget_set_usize(sw, 300, 160); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_ALWAYS, GTK_POLICY_AUTOMATIC); gtk_table_attach(GTK_TABLE (main_table), sw, 0, 1, 1, 2, (GtkAttachOptions)(GTK_FILL|GTK_EXPAND), (GtkAttachOptions)(GTK_FILL|GTK_EXPAND), 0, 0); project_list = gtk_clist_new_with_titles(1, titles1); gtk_clist_set_row_height(GTK_CLIST(project_list), 20); gtk_clist_set_column_min_width(GTK_CLIST(project_list), 0, 400); gtk_container_add(GTK_CONTAINER(sw), project_list); /********************************************************************/ sw = gtk_scrolled_window_new(NULL, NULL); gtk_container_set_border_width(GTK_CONTAINER(sw), 5); gtk_widget_set_usize(sw, 300, 160); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_ALWAYS, GTK_POLICY_AUTOMATIC); gtk_table_attach(GTK_TABLE (main_table), sw, 2, 3, 1, 2, (GtkAttachOptions)(GTK_FILL|GTK_EXPAND), (GtkAttachOptions)(GTK_FILL|GTK_EXPAND), 0, 0); datasets_list = gtk_clist_new_with_titles(2, titles2); gtk_clist_set_row_height(GTK_CLIST(datasets_list), 20); gtk_clist_set_column_min_width(GTK_CLIST(datasets_list), 0, 20); gtk_clist_set_column_min_width(GTK_CLIST(datasets_list), 1, 400); gtk_container_add(GTK_CONTAINER(sw), datasets_list); /* connect signals */ gtk_signal_connect(GTK_OBJECT(new_button), "clicked", (GtkSignalFunc) create_dataset, NULL); gtk_signal_connect(GTK_OBJECT(delete_button), "clicked", (GtkSignalFunc) delete_dataset, NULL); gtk_signal_connect(GTK_OBJECT(edit_project_button), "clicked", (GtkSignalFunc) edit_project_dataset, NULL); gtk_signal_connect(GTK_OBJECT(edit_layer_button), "clicked", (GtkSignalFunc) edit_layer_dataset, NULL); /* gtk_signal_connect(GTK_OBJECT(refresh_button), "clicked", (GtkSignalFunc) refresh_dataset, NULL); */ gtk_signal_connect(GTK_OBJECT(show_button), "clicked", (GtkSignalFunc) show_dataset, NULL); gtk_signal_connect(GTK_OBJECT(main_box), "destroy", (GtkSignalFunc) destroy_dialog, NULL); /* Show widgets */ /* Datasets */ clist_fill_datasets(project_list, datasets, 0); clist_fill_datasets(project_list, functions, 0); clist_fill_datasets(project_list, expressions, 0); clist_fill_datasets(datasets_list, layer->datasets, 1); return main_box; } static void clist_fill_datasets(GtkWidget *clist, GList *data, gint col) { GList *list; SGdataset *dataset; list = data; while(list){ dataset = (SGdataset *)list->data; if(col == 0 && ((the_layer->type != SG_LAYER_3D && (dataset->style == SG_STYLE_SURFACE || dataset->style == SG_STYLE_CSURFACE)) || (the_layer->type == SG_LAYER_3D && (dataset->style != SG_STYLE_SURFACE && dataset->style != SG_STYLE_CSURFACE && dataset->style != SG_STYLE_LPOINTS)))) { ; } else { clist_add_dataset(clist, dataset, col); if(col == 1){ /* Remove from project list */ gint nrows = 0; gint i; nrows = GTK_CLIST(project_list)->rows; for(i = 0; i real_data))){ gtk_clist_remove(GTK_CLIST(project_list), i); break; } } } } list = list->next; } } static void clist_add_dataset(GtkWidget *clist, SGdataset *dataset, gint col) { gchar *text[1]; GdkColormap *colormap; GdkPixmap *eye_pixmap; GdkBitmap *eye_mask; GdkPixmap *pixmap; GdkBitmap *mask; SGdataset *link = NULL; gint nrows; colormap = gdk_colormap_get_system(); eye_pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &eye_mask, NULL, eye_xpm); switch(dataset->type){ case SG_DATA_PYTHON: pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &mask, NULL, g_python_xpm); break; case SG_DATA_FUNCTION: pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &mask, NULL, g_function_xpm); break; case SG_DATA_COLUMNS: case SG_DATA_MATRIX: default: pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, colormap, &mask, NULL, data_pixmaps[dataset->style]); break; } nrows = GTK_CLIST(clist)->rows; text[0] = NULL; gtk_clist_append(GTK_CLIST(clist), text); link = SG_DATASET(gtk_plot_data_get_link(dataset->real_data)); if(link){ text[0] = GTK_PLOT_DATA(link->real_data)->name; } gtk_clist_set_pixtext(GTK_CLIST(clist), nrows, col, text[0], 5, pixmap, mask); gtk_clist_set_row_data(GTK_CLIST(clist), nrows, dataset); if(col != 0 && GTK_WIDGET_VISIBLE(dataset->real_data)) gtk_clist_set_pixmap(GTK_CLIST(datasets_list), nrows, 0, eye_pixmap, eye_mask); gdk_pixmap_unref(pixmap); gdk_bitmap_unref(mask); gdk_pixmap_unref(eye_pixmap); gdk_bitmap_unref(eye_mask); }