/* SciGraphica - Scientific graphics and data manipulation
* Copyright (C) 2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
*
* 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 <math.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gtkextra/gtkextra.h>
#include <gdk/gdkkeysyms.h>
#include <stdio.h>
#include <string.h>
#include "sg_matrix_convert.h"
#include "sg.h"
SGworksheet *
sg_worksheet_to_matrix_xyz(SGworksheet *worksheet, gint colx, gint coly, gint colz)
{
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;
gint column[3];
column[0] = colx;
column[1] = coly;
column[2] = colz;
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){
g_free(val_x);
g_free(val_y);
return NULL;
}
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){
g_free(val_x);
g_free(val_y);
return NULL;
}
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);
gtk_widget_show(GTK_WIDGET(matrix));
return matrix;
}
SGworksheet *
sg_worksheet_to_matrix(SGworksheet *worksheet)
{
SGworksheet *matrix;
gboolean error = FALSE;
gint begin, end;
gint nx = 0, ny = 0;
gint row, col;
gint i;
gint nrows, ncols;
begin = MAX(0, worksheet->begin);
end = GTK_SHEET(worksheet->sheet)->maxallocrow;
if(worksheet->end >= 0)
end = MIN(end, worksheet->end);
matrix = sg_project_new_matrix();
ny = end - begin + 1;
nx = GTK_SHEET(worksheet->sheet)->maxalloccol;
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++)
for(col = 0; col <= nx; col++){
gchar *text;
SGhiddencell *cell, *link;
text = sg_worksheet_cell_get_text(worksheet, row, col);
link = (SGhiddencell *)gtk_sheet_get_link(GTK_SHEET(worksheet->sheet),
row, col);
if(text && strlen(text)>0){
if(link){
cell = g_new(SGhiddencell, 1);
*cell = *link;
if(link->formula) cell->formula = g_strdup(link->formula);
};
sg_worksheet_cell_set_text(matrix, row, col, text);
if(link)
gtk_sheet_link_cell(GTK_SHEET(matrix->sheet), row, col, cell);
}
}
gtk_sheet_thaw(GTK_SHEET(matrix->sheet));
gtk_widget_show(GTK_WIDGET(matrix));
return matrix;
}
SGworksheet *
sg_matrix_transpose(SGworksheet *worksheet)
{
SGworksheet *matrix;
gboolean error = FALSE;
gint begin, end;
gint nx = 0, ny = 0;
gint row, col;
gint i;
gint nrows, ncols;
begin = MAX(0, worksheet->begin);
end = GTK_SHEET(worksheet->sheet)->maxallocrow;
if(worksheet->end >= 0)
end = MIN(end, worksheet->end);
matrix = sg_project_new_matrix();
nx = end - begin + 1;
ny = GTK_SHEET(worksheet->sheet)->maxalloccol;
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++)
for(col = 0; col <= nx; col++){
gchar *text;
SGhiddencell *cell, *link;
text = sg_worksheet_cell_get_text(worksheet, row, col);
link = (SGhiddencell *)gtk_sheet_get_link(GTK_SHEET(worksheet->sheet),
row, col);
if(text && strlen(text)>0){
if(link){
cell = g_new(SGhiddencell, 1);
*cell = *link;
if(link->formula) cell->formula = g_strdup(link->formula);
};
sg_worksheet_cell_set_text(matrix, col, row, text);
if(link)
gtk_sheet_link_cell(GTK_SHEET(matrix->sheet), row, col, cell);
}
}
gtk_sheet_thaw(GTK_SHEET(matrix->sheet));
gtk_widget_show(GTK_WIDGET(matrix));
return matrix;
}
SGworksheet *
sg_matrix_to_worksheet(SGworksheet *matrix)
{
SGworksheet *worksheet;
gboolean error = FALSE;
gint nx = 0, ny = 0;
gint row, col;
gint i;
gint nrows, ncols;
worksheet = sg_project_new_worksheet();
nx = gtk_sheet_get_columns_count(GTK_SHEET(matrix->sheet));
ny = gtk_sheet_get_rows_count(GTK_SHEET(matrix->sheet));
nrows = ny*nx - gtk_sheet_get_rows_count(GTK_SHEET(worksheet->sheet));
gtk_sheet_freeze(GTK_SHEET(worksheet->sheet));
sg_worksheet_add_rows(worksheet, nrows);
for(row = 0; row <= ny; row++)
for(col = 0; col <= nx; col++){
gchar *text;
gchar label[100];
SGhiddencell *cell, *link;
text = sg_worksheet_cell_get_text(matrix, row, col);
link = (SGhiddencell *)gtk_sheet_get_link(GTK_SHEET(worksheet->sheet),
row, col);
g_snprintf(label, 100, "%f\n",
matrix->xmin+col*(matrix->xmax-matrix->xmin)/nx);
sg_worksheet_cell_set(worksheet, row*nx+col, 0, label, TRUE, TRUE);
g_snprintf(label, 100, "%f\n",
matrix->ymin+row*(matrix->ymax-matrix->ymin)/ny);
sg_worksheet_cell_set(worksheet, row*nx+col, 1, label, TRUE, TRUE);
if(text && strlen(text)>0){
if(link){
cell = g_new(SGhiddencell, 1);
*cell = *link;
if(link->formula) cell->formula = g_strdup(link->formula);
};
sg_worksheet_cell_set_text(worksheet, row*nx+col, 2, text);
if(link)
gtk_sheet_link_cell(GTK_SHEET(worksheet->sheet), row*nx+col, 2, cell);
}
}
gtk_sheet_thaw(GTK_SHEET(worksheet->sheet));
gtk_widget_show(GTK_WIDGET(worksheet));
return matrix;
}
syntax highlighted by Code2HTML, v. 0.9.1