/* 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 #include "sg_convert_dialog.h" #include "sg.h" #include "sg_stock.h" #include "sg_dialogs.h" static GtkWidget *column_entry[3]; static GtkWidget *left_button[3]; static GtkWidget *right_button[3]; static GtkWidget *entries_table = NULL; static gint data_type; static GtkWidget *window = NULL; static GtkWidget *main_table; static GtkWidget *worksheet_combo, *goto_combo; static GtkWidget *columns_list; static GtkWidget* dialog = NULL; static GtkWidget *entries[3]; static GtkWidget *columns_dialog (); static void select_columns (GtkWidget *widget, gpointer data); static void init_columns (GtkWidget *widget); static gint get_column_from_name(gchar *name) { SGworksheet *worksheet; gchar *worksheet_name = NULL; gint n = 0; worksheet_name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(worksheet_combo)->entry)); worksheet = sg_project_get_worksheet(worksheet_name); for(n = 0; n <= GTK_SHEET(worksheet->sheet)->maxcol; n++){ if(strcmp(name, GTK_SHEET(worksheet->sheet)->column[n].name) == 0) return n; } return -1; } static gboolean mw_destroy(GtkWidget *widget) { /* This is needed to get out of gtk_main */ gtk_main_quit (); entries_table = NULL; return FALSE; } static gboolean cancel_pressed(GtkWidget *widget) { gtk_widget_destroy(window); return FALSE; } static gboolean ok_pressed(GtkWidget *widget) { SGworksheet *worksheet, *matrix; GList *selection = NULL; gchar *worksheet_name; gchar default_text[] = ""; gint i, row = 0, narg = 0; gint column[3]; gchar column_text[3][100]; gchar *column_name[3]; for(i = 0; i < 3; i++){ column[i] = -1; column_name[i] = gtk_entry_get_text(GTK_ENTRY(column_entry[i])); column[i] = get_column_from_name(column_name[i]); if(column[i] != -1) narg++; } if(narg < 3) return FALSE; worksheet_name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(worksheet_combo)->entry)); worksheet = sg_project_get_worksheet(worksheet_name); matrix = sg_worksheet_to_matrix_xyz(worksheet, column[0], column[1], column[2]); if(!matrix){ sg_message_dialog("Data does not conform with a quadrilateral mesh", 0); return FALSE; } /* if(worksheet){ SGworksheet *matrix; gboolean error = FALSE; gint begin, end; gdouble xmin, xmax, ymin, ymax; gdouble x, y; gdouble x_step, y_step; gdouble *val_x = NULL, *val_y = NULL; gint nx = 0, ny = 0; gint row, new_row, new_col; gint i; gint nrows, ncols; xmax = xmin = sg_worksheet_cell_get_double(worksheet, 0, column[0], &error); ymax = ymin = sg_worksheet_cell_get_double(worksheet, 0, column[1], &error); begin = MAX(0, worksheet->begin); end = GTK_SHEET(worksheet->sheet)->maxallocrow; if(worksheet->end >= 0) end = MIN(end, worksheet->end); val_x = g_new0(gdouble, 1); val_y = g_new0(gdouble, 1); val_x[0] = xmin; val_y[0] = ymin; nx = ny = 1; for(row = begin; row <= end; row++){ x = sg_worksheet_cell_get_double(worksheet, row, column[0], &error); y = sg_worksheet_cell_get_double(worksheet, row, column[1], &error); if(x < xmin) xmin = x; if(x > xmax) xmax = x; if(y < ymin) ymin = y; if(y > ymax) ymax = y; for(i = 0; i < nx; i++) if(x == val_x[i]) break; if(i == nx){ val_x = (gdouble *)g_realloc(val_x, (nx + 1) * sizeof(gdouble)); val_x[nx] = x; nx++; } for(i = 0; i < ny; i++) if(y == val_y[i]) break; if(i == ny){ val_y = (gdouble *)g_realloc(val_y, (ny + 1) * sizeof(gdouble)); val_y[ny] = y; ny++; } } if(nx < 2 || ny < 2){ gtk_widget_destroy(widget); g_free(val_x); g_free(val_y); sg_message_dialog("Data does not conform with a quadrilateral mesh", 0); return FALSE; } x_step = (xmax - xmin) / (nx - 1); y_step = (ymax - ymin) / (ny - 1); error = FALSE; for(i = 0; i < nx; i++){ gdouble dx; dx = (val_x[i] - xmin) / x_step; if(fabs(dx - (gint)(dx + 0.0001)) > 0.1){ error = TRUE; break; } } for(i = 0; i < ny; i++){ gdouble dy; dy = (val_y[i] - ymin) / y_step; if(fabs(dy - (gint)(dy + 0.0001)) > 0.1){ error = TRUE; break; } } if(error){ gtk_widget_destroy(widget); g_free(val_x); g_free(val_y); sg_message_dialog("Data does not conform with a quadrilateral mesh", 0); return FALSE; } matrix = sg_project_new_matrix(); matrix->xmin = xmin; matrix->xmax = xmax; matrix->ymin = ymin; matrix->ymax = ymax; ncols = nx - gtk_sheet_get_columns_count(GTK_SHEET(matrix->sheet)); nrows = ny - gtk_sheet_get_rows_count(GTK_SHEET(matrix->sheet)); gtk_sheet_freeze(GTK_SHEET(matrix->sheet)); sg_worksheet_add_rows(matrix, nrows); sg_worksheet_add_columns(matrix, ncols); for(row = begin; row <= end; row++){ gchar *text; SGhiddencell *cell, *link; text = sg_worksheet_cell_get_text(worksheet, row, column[2]); link = (SGhiddencell *)gtk_sheet_get_link(GTK_SHEET(worksheet->sheet), row, column[2]); if(text && strlen(text)>0){ if(link){ cell = g_new(SGhiddencell, 1); *cell = *link; if(link->formula) cell->formula = g_strdup(link->formula); }; x = sg_worksheet_cell_get_double(worksheet, row, column[0], &error); y = sg_worksheet_cell_get_double(worksheet, row, column[1], &error); new_col = (x - xmin) / x_step + 0.001; new_row = (y - ymin) / y_step + 0.001; sg_worksheet_cell_set_text(matrix, new_row, new_col, text); if(link) gtk_sheet_link_cell(GTK_SHEET(matrix->sheet), new_row, new_col, cell); } } gtk_sheet_thaw(GTK_SHEET(matrix->sheet)); g_free(val_x); g_free(val_y); sg_worksheet_open(matrix); } */ gtk_widget_destroy(widget); return FALSE; } static void update_columns(GtkEntry *entry) { gint i, nrows; SGworksheet *worksheet = NULL; GList *list; gchar *text; gchar name[100]; nrows = GTK_CLIST(columns_list)->rows; for(i = 0; i <= nrows; i++){ gtk_clist_remove(GTK_CLIST(columns_list), 0); } text = gtk_entry_get_text(entry); list = worksheets; while(list){ worksheet = (SGworksheet *)list->data; if(strcmp(text, worksheet->name) == 0) break; list = list->next; } for(i = 0; i <= GTK_SHEET(worksheet->sheet)->maxcol; i++){ if(!GTK_SHEET(worksheet->sheet)->column[i].name) sprintf(name,"%d",i); else sprintf(name,"%s",GTK_SHEET(worksheet->sheet)->column[i].name); text=g_strdup(name); gtk_clist_append(GTK_CLIST(columns_list), &text); }; } void sg_convert_dialog (void) { GtkWidget *frame; GtkWidget *main_box; GtkWidget *box; GtkWidget *ok_button, *cancel_button; GtkWidget *action_area; GtkWidget *table; GtkWidget *label; GtkWidget *worksheet_combo; GList *list; gint i; window=gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE); gtk_window_set_title (GTK_WINDOW(window),"Convert to XYZ matriz"); gtk_window_set_modal (GTK_WINDOW(window),TRUE); /* Create widgets */ frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_container_add(GTK_CONTAINER (window), frame); /**********************************************************/ main_table = gtk_table_new(3, 1, FALSE); gtk_container_set_border_width(GTK_CONTAINER(main_table), 10); gtk_container_add(GTK_CONTAINER(frame), main_table); gtk_table_set_row_spacings(GTK_TABLE(main_table), 5); gtk_table_set_col_spacings(GTK_TABLE(main_table), 5); main_box = gtk_vbox_new (FALSE, 5); gtk_table_attach_defaults(GTK_TABLE(main_table), main_box, 0, 1, 3, 4); gtk_table_attach_defaults(GTK_TABLE(main_table), columns_dialog(), 0, 1, 1, 2); /**********************************************************/ /* Action Area */ action_area = gtk_hbutton_box_new (); gtk_container_set_border_width(GTK_CONTAINER(action_area), 5); gtk_button_box_set_layout(GTK_BUTTON_BOX(action_area), GTK_BUTTONBOX_SPREAD); gtk_button_box_set_spacing(GTK_BUTTON_BOX(action_area), 5); gtk_box_pack_end (GTK_BOX (main_box), action_area, FALSE, FALSE, 0); gtk_widget_show (action_area); ok_button = sg_stock_button ("Button_Ok"); GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT); gtk_box_pack_start (GTK_BOX (action_area), ok_button, TRUE, TRUE, 0); gtk_widget_grab_default (ok_button); gtk_widget_show (ok_button); cancel_button = sg_stock_button ("Button_Cancel"); GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT); gtk_box_pack_start (GTK_BOX (action_area), cancel_button, TRUE, TRUE, 0); gtk_widget_show (cancel_button); /* connect signals */ gtk_signal_connect_object (GTK_OBJECT (cancel_button), "clicked", GTK_SIGNAL_FUNC (cancel_pressed), GTK_OBJECT (window)); gtk_signal_connect_object (GTK_OBJECT (ok_button), "clicked", GTK_SIGNAL_FUNC (ok_pressed), GTK_OBJECT (window)); gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (mw_destroy),NULL); /* Show widgets */ gtk_widget_show_all (window); /* wait until dialog get destroyed */ gtk_main(); } static GtkWidget * columns_dialog () { GtkWidget *frame, *vbox; GtkWidget *label; GtkWidget *table; GtkWidget *box, *sw; GtkWidget *action_area; GtkWidget *goto_button; GList *list; GtkWidget *item; SGworksheet *worksheet; dialog = vbox = gtk_vbox_new(FALSE, 5); 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_box_pack_start (GTK_BOX (vbox), action_area, FALSE, FALSE, 0); /*********************************************************************/ box = gtk_hbox_new(TRUE, 5); gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 0); label = gtk_label_new("Select Worksheet:"); gtk_misc_set_alignment(GTK_MISC(label), 1., 0.); gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0); worksheet_combo = gtk_combo_new(); gtk_box_pack_end (GTK_BOX (box), worksheet_combo, FALSE, FALSE, 0); gtk_widget_show(box); gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(worksheet_combo)->entry), FALSE); list = worksheets; while(list){ worksheet = (SGworksheet *)list->data; item = gtk_list_item_new_with_label(worksheet->name); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(GTK_COMBO(worksheet_combo)->list), item); list = list->next; } box = gtk_hbox_new(TRUE, 5); gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 0); /*********************************************************************/ frame = gtk_frame_new("Columns"); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); box = gtk_hbox_new(FALSE, 5); gtk_container_set_border_width(GTK_CONTAINER(box), 5); gtk_container_add (GTK_CONTAINER (frame), box); sw = gtk_scrolled_window_new(NULL, NULL); gtk_widget_set_usize(sw, 180, 160); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX (box), sw, FALSE, FALSE, 0); columns_list = gtk_clist_new(1); gtk_container_add(GTK_CONTAINER(sw), columns_list); select_columns(NULL, box); /********************************************************************/ gtk_signal_connect(GTK_OBJECT(GTK_COMBO(worksheet_combo)->entry), "changed", GTK_SIGNAL_FUNC(select_columns), box); return vbox; } static gint set_column(GtkWidget *widget, gpointer data) { GList *selection; gchar *text; gint row; selection = GTK_CLIST(columns_list)->selection; if(!selection) return TRUE; text = gtk_entry_get_text(GTK_ENTRY(data)); if(strlen(text) > 0) return TRUE; row = GPOINTER_TO_INT(selection->data); gtk_clist_get_text(GTK_CLIST(columns_list), row, 0, &text); gtk_entry_set_text(GTK_ENTRY(data), text); gtk_clist_remove(GTK_CLIST(columns_list), row); return TRUE; } static gint restore_column(GtkWidget *widget, gpointer data) { gchar *text; gint col; text = gtk_entry_get_text(GTK_ENTRY(data)); if(strlen(text) == 0) return TRUE; col = get_column_from_name(text); gtk_clist_insert(GTK_CLIST(columns_list), col, &text); gtk_entry_set_text(GTK_ENTRY(data), ""); return TRUE; } static void select_columns(GtkWidget *widget, gpointer data) { GtkWidget *box; GtkWidget *column_label; GtkWidget *button_box; gint i, nrows = 0; gchar *label[3] = {"X:","Y:","Z:"}; box = GTK_WIDGET(data); update_columns(GTK_ENTRY(GTK_COMBO(worksheet_combo)->entry)); if(entries_table && GTK_IS_WIDGET(entries_table)) gtk_container_remove(GTK_CONTAINER(box), entries_table); entries_table = gtk_table_new(3, 3, FALSE); gtk_table_set_col_spacings(GTK_TABLE(entries_table), 5); for(i = 0; i < 3; i++){ button_box = gtk_hbox_new(TRUE, 0); gtk_table_attach_defaults(GTK_TABLE (entries_table), button_box, 0, 1, nrows, nrows + 1); left_button[i] = gtk_button_new(); gtk_container_add(GTK_CONTAINER(left_button[i]), gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_OUT)); gtk_widget_set_usize(left_button[i], 20, 20); gtk_box_pack_start(GTK_BOX(button_box), left_button[i], FALSE, FALSE, 0); right_button[i] = gtk_button_new(); gtk_container_add(GTK_CONTAINER(right_button[i]), gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT)); gtk_widget_set_usize(right_button[i], 20, 20); gtk_box_pack_start(GTK_BOX(button_box), right_button[i], FALSE, FALSE, 0); column_label = gtk_label_new(label[i]); gtk_misc_set_alignment(GTK_MISC(column_label), .5, .5); gtk_table_attach_defaults(GTK_TABLE(entries_table), column_label, 1, 2, nrows, nrows + 1); column_entry[i] = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(column_entry[i]), FALSE); gtk_table_attach_defaults(GTK_TABLE(entries_table), column_entry[i], 2, 3, nrows, nrows + 1); gtk_entry_set_text(GTK_ENTRY(column_entry[i]), ""); gtk_signal_connect(GTK_OBJECT(left_button[i]), "clicked", (GtkSignalFunc) restore_column, column_entry[i]); gtk_signal_connect(GTK_OBJECT(right_button[i]), "clicked", (GtkSignalFunc) set_column, column_entry[i]); nrows++; } gtk_box_pack_start(GTK_BOX(box), entries_table, FALSE, FALSE, 0); gtk_widget_show_all(entries_table); }