/* Copyright (C) 2003 by Sean David Fleming sean@ivec.org 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The GNU GPL can also be found at http://www.gnu.org */ #include #include #include #include #include #include #include #include #include #include #include "gdis.h" #include "coords.h" #include "file.h" #include "parse.h" #include "matrix.h" #include "model.h" #include "space.h" #include "zone.h" #include "render.h" #include "select.h" #include "shortcuts.h" #include "interface.h" #include "dialog.h" #include "opengl.h" #define DEBUG_MORE 0 #define MAX_KEYS 15 /* main structures */ extern struct sysenv_pak sysenv; extern struct elem_pak elements[]; /***************************************/ /* setup the recognized file type list */ /***************************************/ #define DEBUG_FILE_INIT 0 void file_init(void) { GSList *rlist=NULL; struct file_pak *file_data; /* NEW - build a recognized image read format list */ /* also used in picture writing as it avoids overlap */ /* problems when getting the file_data structure by extension */ #define PICTURE_SUPPORT 0 #if PICTURE_SUPPORT for (list=gdk_pixbuf_get_formats() ; list ; list=g_slist_next(list)) { gint i; gchar **ext; ext = gdk_pixbuf_format_get_extensions(list->data); i = 0; while (*(ext+i)) { /* if (gdk_pixbuf_format_is_writable(list->data)) wlist = g_slist_prepend(wlist, g_strdup(*(ext+i))); */ rlist = g_slist_prepend(rlist, g_strdup(*(ext+i))); i++; } } #endif #if DEBUG_FILE_INIT printf("read: "); for (list=rlist ; list ; list=g_slist_next(list)) { printf("[%s] ", (gchar *) list->data); } printf("\n"); #endif /* build the recognized file type list */ sysenv.file_list = NULL; /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = DATA; /* unique identifier */ file_data->group = DATA; /* used to group inp/out types */ file_data->menu = TRUE; /* include in menu listing */ file_data->label = g_strdup("All known types"); /* text info for the user */ file_data->ext = NULL; /* extension matching */ file_data->write_file = NULL; /* file creation */ file_data->read_file = NULL; /* file reading */ file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = ABINIT_OUT; file_data->group = ABINIT; file_data->menu = FALSE; file_data->label = g_strdup("ABINIT output"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "about"); file_data->ext = g_slist_prepend(file_data->ext, "abot"); file_data->write_file = NULL; file_data->read_file = read_about; file_data->read_frame = read_about_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = MD_ANALYSIS; file_data->group = MD_ANALYSIS; file_data->menu = FALSE; file_data->label = g_strdup("Analysis"); file_data->ext = NULL; file_data->ext = NULL; /* import/export handled in analysis as a special case */ file_data->write_file = NULL; file_data->read_file = NULL; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = BIOGRAF; file_data->group = BIOGRAF; file_data->menu = TRUE; file_data->label = g_strdup("bgf"); file_data->label = g_strdup("Biograf"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "bgf"); file_data->write_file = write_bgf; file_data->read_file = read_bgf; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = BIOSYM; file_data->group = BIOSYM; file_data->menu = TRUE; file_data->label = g_strdup("Biosym"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "car"); file_data->ext = g_slist_prepend(file_data->ext, "cor"); file_data->ext = g_slist_prepend(file_data->ext, "arc"); file_data->write_file = write_arc; file_data->read_file = read_arc; file_data->read_frame = read_arc_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = CASTEP; file_data->group = CASTEP; file_data->menu = TRUE; file_data->label = g_strdup("CASTEP"); file_data->ext = NULL; file_data->write_file = NULL; file_data->read_file = NULL; file_data->read_frame = NULL; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = CASTEP_OUT; file_data->group = CASTEP; file_data->menu = FALSE; file_data->label = g_strdup("CASTEP output"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "castep"); file_data->write_file = NULL; file_data->read_file = read_castep_out; file_data->read_frame = read_castep_out_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = CIF; file_data->group = CIF; file_data->menu = TRUE; file_data->label = g_strdup("CIF"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "cif"); file_data->write_file = write_cif; file_data->read_file = read_cif; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* NEW: monty crystal graph file format */ /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = CRYSTAL_GRAPH; file_data->group = CRYSTAL_GRAPH; file_data->menu = TRUE; file_data->label = g_strdup("cgf"); file_data->label = g_strdup("Crystal Graph Files"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "cgf"); file_data->write_file = write_cgf; file_data->read_file = read_cgf; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = CSSR; file_data->group = CSSR; file_data->menu = TRUE; file_data->label = g_strdup("CSSR"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "cssr"); file_data->write_file = write_cssr; file_data->read_file = read_cssr; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = DIFFAX_INP; file_data->group = DIFFAX_INP; file_data->menu = FALSE; file_data->label = g_strdup("DIFFaX"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "dfx"); file_data->write_file = write_diffax; file_data->read_file = read_diffax; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = DLP; file_data->group = DLP; file_data->menu = TRUE; file_data->label = g_strdup("DLP"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "dlp"); file_data->write_file = write_dlp; file_data->read_file = read_dlp; file_data->read_frame = NULL; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = DMOL_INPUT; file_data->group = DMOL_INPUT; file_data->menu = TRUE; file_data->label = g_strdup("DMOL"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "dmol"); file_data->write_file = write_dmol; file_data->read_file = read_dmol; file_data->read_frame = NULL; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = DLPOLY; file_data->group = DLPOLY; file_data->menu = TRUE; file_data->label = g_strdup("DL_POLY"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, ""); file_data->ext = g_slist_append(file_data->ext, "dlpoly"); file_data->write_file = write_dlpoly; file_data->read_file = read_dlpoly; file_data->read_frame = read_dlpoly_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = GAMESS; file_data->group = GAMESS; file_data->menu = TRUE; file_data->label = g_strdup("GAMESS"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "inp"); file_data->write_file = write_gms; file_data->read_file = read_gms; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = GAMESS_OUT; file_data->group = GAMESS; file_data->menu = FALSE; file_data->label = g_strdup("GAMESS Output"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "gmout"); file_data->ext = g_slist_prepend(file_data->ext, "gmot"); file_data->write_file = NULL; file_data->read_file = read_gms_out; file_data->read_frame = read_gms_out_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = GAUSS; file_data->group = GAUSS; file_data->menu = TRUE; file_data->label = g_strdup("GAUSSIAN"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "com"); file_data->write_file = write_gauss; file_data->read_file = NULL; file_data->read_frame = NULL; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = GAUSS_OUT; file_data->group = GAUSS; file_data->menu = FALSE; file_data->label = g_strdup("GAUSSIAN output"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "log"); file_data->write_file = NULL; file_data->read_file = read_gauss_out; file_data->read_frame = read_gauss_out_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = MORPH; file_data->group = MORPH; file_data->menu = TRUE; file_data->label = g_strdup("GDIS Morphology"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "gmf"); file_data->write_file = write_gmf; file_data->read_file = read_gmf; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = GEOMVIEW_OFF; file_data->group = GEOMVIEW_OFF; file_data->menu = TRUE; file_data->label = g_strdup("Geomview OFF"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "off"); file_data->write_file = NULL; file_data->read_file = read_off; file_data->read_frame = NULL; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = GULP; file_data->group = GULP; file_data->menu = TRUE; file_data->label = g_strdup("GULP"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "gin"); file_data->ext = g_slist_prepend(file_data->ext, "res"); file_data->write_file = write_gulp; file_data->read_file = read_gulp; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = GULPOUT; file_data->group = GULP; file_data->menu = FALSE; file_data->label = g_strdup("GULP output"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "got"); file_data->ext = g_slist_prepend(file_data->ext, "gout"); file_data->write_file = NULL; file_data->read_file = read_gulp_output; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = MARVIN; file_data->group = MARVIN; file_data->menu = TRUE; file_data->label = g_strdup("MARVIN"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "mar"); file_data->ext = g_slist_prepend(file_data->ext, "mvn"); file_data->ext = g_slist_prepend(file_data->ext, "mvn-r"); file_data->write_file = write_marvin; file_data->read_file = read_marvin; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = MVNOUT; file_data->group = MARVIN; file_data->menu = FALSE; file_data->label = g_strdup("MARVIN output"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "mot"); file_data->ext = g_slist_prepend(file_data->ext, "mvout"); file_data->ext = g_slist_prepend(file_data->ext, "mvnout"); file_data->write_file = NULL; file_data->read_file = read_mvnout; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = NWCHEM; file_data->group = NWCHEM; file_data->menu = TRUE; file_data->label = g_strdup("NWChem"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "nwin"); file_data->write_file = NULL; file_data->read_file = read_nw; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = NWCHEM_OUT; file_data->group = NWCHEM; file_data->menu = FALSE; file_data->label = g_strdup("NWChem output"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "nwout"); file_data->ext = g_slist_prepend(file_data->ext, "nwot"); file_data->write_file = NULL; file_data->read_file = read_nwout; file_data->read_frame = read_nwout_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = PDB; file_data->group = PDB; file_data->menu = TRUE; file_data->label = g_strdup("PDB"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "pdb"); file_data->write_file = write_pdb; file_data->read_file = read_pdb; file_data->read_frame = read_pdb_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = PICTURE; file_data->group = PICTURE; file_data->menu = FALSE; /* TODO - check supported image types with glib - add to string */ file_data->label = g_strdup("Picture (jpg)"); file_data->ext = rlist; file_data->write_file = NULL; file_data->read_file = NULL; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = POVRAY; file_data->group = POVRAY; file_data->menu = FALSE; file_data->label = g_strdup("POVRay"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "pov"); file_data->write_file = write_povray; file_data->read_file = NULL; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = PROJECT; file_data->group = PROJECT; file_data->menu = FALSE; file_data->label = g_strdup("Project"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "pcf"); file_data->write_file = NULL; file_data->read_file = project_read; file_data->read_frame = NULL; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = CEL; file_data->group = CEL; file_data->menu = TRUE; file_data->label = g_strdup("PowderCell"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "cel"); file_data->write_file = NULL; file_data->read_file = read_cel; file_data->read_frame = NULL; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = RIETICA; file_data->group = RIETICA; file_data->menu = TRUE; file_data->label = g_strdup("Rietica"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "inp"); file_data->write_file = NULL; file_data->read_file = read_rietica; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = FDF; file_data->group = FDF; file_data->menu = TRUE; file_data->label = g_strdup("SIESTA"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "fdf"); file_data->write_file = write_fdf; file_data->read_file = read_fdf; file_data->read_frame = NULL; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = SIESTA_OUT; file_data->group = FDF; file_data->menu = FALSE; file_data->label = g_strdup("SIESTA output"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "sout"); file_data->ext = g_slist_prepend(file_data->ext, "sot"); file_data->write_file = NULL; file_data->read_file = read_sout; file_data->read_frame = read_sout_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = XML; file_data->group = XML; file_data->menu = TRUE; file_data->label = g_strdup("XML"); file_data->ext = NULL; file_data->ext = g_slist_prepend(file_data->ext, "xml"); file_data->write_file = write_xml; file_data->read_file = read_xml; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = XTL; file_data->group = XTL; file_data->menu = TRUE; file_data->label = g_strdup("XTL"); file_data->ext = NULL; file_data->ext = g_slist_append(file_data->ext, "xtl"); file_data->write_file = write_xtl; file_data->read_file = read_xtl; file_data->read_frame = NULL; /* frame reading */ sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); /* supported file type */ file_data = g_malloc(sizeof(struct file_pak)); file_data->id = XYZ; file_data->group = XYZ; file_data->menu = TRUE; file_data->label = g_strdup("XYZ"); file_data->ext = NULL; /* file_data->ext = g_slist_append(file_data->ext, "ani"); file_data->ext = g_slist_append(file_data->ext, "xmol"); */ file_data->ext = g_slist_append(file_data->ext, "xyz"); file_data->write_file = write_xyz; file_data->read_file = read_xyz; file_data->read_frame = read_xyz_frame; sysenv.file_list = g_slist_prepend(sysenv.file_list, file_data); sysenv.file_list = g_slist_reverse(sysenv.file_list); } /************************/ /* current version info */ /************************/ void gdis_blurb(FILE *fp) { fprintf(fp, "Created by GDIS version %4.2f.%d\n", VERSION, PATCH); } /*********************************************/ /* alphabetically sort the directory listing */ /*********************************************/ gint alpha_slist_sort(gpointer ptr1, gpointer ptr2) { return(g_ascii_strcasecmp((gchar *) ptr1, (gchar *) ptr2)); } /*********************************************/ /* an all-platform directory listing routine */ /*********************************************/ GSList *get_dir_list(const char *path, gint sort) { const gchar *name; GDir *dir; GSList *files=NULL; /* ensure we can go up a directory */ files = g_slist_prepend(files, g_strdup("..")); /* build the directory list */ dir = g_dir_open(path, 0, NULL); name = g_dir_read_name(dir); while (name) { if (g_ascii_strncasecmp(".", name, 1) != 0) files = g_slist_prepend(files, g_strdup(name)); name = g_dir_read_name(dir); } g_dir_close(dir); if (sort) files = g_slist_sort(files, (gpointer) alpha_slist_sort); return(files); } /*******************************************************/ /* allocate a new string containing the file extension */ /*******************************************************/ gchar *file_extension_get(const gchar *name) { gint i,n; gchar *ext; if (!name) return(NULL); /* search for '.' character in reverse order */ i = n = strlen(name); /* minimum size, avoids troublesome cases (eg "..") */ if (n > 2) { for (i=n-1 ; i-- ; ) { if (name[i] == '.') { ext = g_strndup(name+i+1, n-i-1); /* ignore any .# extension */ if (!str_is_float(ext)) return(ext); g_free(ext); /* mark the .# as the new end */ n = i; } } } return(NULL); } /************************************************/ /* routine to determine if a file is recognized */ /************************************************/ /* returns pointer to file info if found, NULL otherwise */ #define DEBUG_GET_FILE_INFO 0 struct file_pak *get_file_info(gpointer ptr, gint type) { gint code=-1; gchar *text=NULL, *ext; GSList *file, *ext_list; struct file_pak *file_data; /* checks */ g_return_val_if_fail(ptr != NULL, NULL); /* init for search */ switch(type) { case BY_LABEL: text = g_strdup(ptr); #if DEBUG_GET_FILE_INFO printf("Searching for type [%s]\n", text); #endif break; case BY_EXTENSION: /* fix to get around the quotes needed to properly pass win32 filesnames with spaces */ #if __WIN32 { gchar *tmp = g_shell_unquote(ptr, NULL); text = file_extension_get(tmp); g_free(tmp); } #else text = file_extension_get(ptr); #endif if (!text) return(NULL); #if DEBUG_GET_FILE_INFO printf("Searching for extension [%s]\n", text); #endif break; case BY_FILE_ID: code = GPOINTER_TO_INT(ptr); #if DEBUG_GET_FILE_INFO printf("Searching for code [%d]\n", code); #endif break; } /* search */ for (file=sysenv.file_list ; file ; file=g_slist_next(file)) { file_data = file->data; switch (type) { /* compare to all extensions in list */ case BY_EXTENSION: /* go through all extensions listed under this file type */ for (ext_list=file_data->ext ; ext_list ; ext_list=g_slist_next(ext_list)) { ext = ext_list->data; if (strlen(text) == strlen(ext)) { if (g_ascii_strcasecmp(text, ext) == 0) { #if DEBUG_GET_FILE_INFO printf("Matched: %s\n", file_data->label); #endif g_free(text); return(file_data); } } } break; /* compare with label */ case BY_LABEL: if (strlen(text) != strlen(file_data->label)) break; if (g_ascii_strcasecmp(text, file_data->label) == 0) { #if DEBUG_GET_FILE_INFO printf("Matched: %s\n", file_data->label); #endif g_free(text); return(file_data); } break; case BY_FILE_ID: if (code == file_data->id) { #if DEBUG_GET_FILE_INFO printf("Matched: %s\n", file_data->label); #endif return(file_data); } break; default: printf("get_file_info() error: bad search type.\n"); } } if (text) g_free(text); return(NULL); } /**************************/ /* detect valid filetypes */ /**************************/ gint file_extension_valid(const gchar *name) { gchar *ext; GSList *item, *list; struct file_pak *file; /* locate the extension */ /*FIXME: can find_char be replaced by standard strchr()/strrchr() functions? - MW */ ext = find_char(name, '.', LAST); if (ext) ext++; if (sysenv.file_type == DATA) /* compare against all extension types - any match is allowed */ { if (!ext) /* files without extensions are matched only in strict case */ return(FALSE); for (list=sysenv.file_list ; list ; list=g_slist_next(list)) { file = list->data; for (item=file->ext ; item ; item=g_slist_next(item)) if (g_ascii_strcasecmp(item->data, ext) == 0) return(TRUE); } } else /* strict case - file must match the dialog filter */ { for (list=sysenv.file_list ; list ; list=g_slist_next(list)) { file = list->data; if (sysenv.file_type == file->group) for (item=file->ext ; item ; item=g_slist_next(item)) if ((ext && g_ascii_strcasecmp(item->data, ext) == 0) || (!ext && strlen(item->data) == 0)) return(TRUE); } } return(FALSE); } /*******************************************************/ /* get an unused BASENAME (of supplied extension type) */ /*******************************************************/ /* TODO - supply a basename+ext & this inserts _? until new? */ #define DEBUG_GUN 0 gchar *gun(const gchar *ext) { gint i; gchar *name; GString *filename; FILE *fp; /* seek a file name that doesn't exist (avoid background overwriting) */ filename = g_string_new(NULL); i=0; do { g_string_sprintf(filename,"dummy_%d.%s", i, ext); #if DEBUG_GUN printf("testing: %s\n",filename->str); #endif i++; } while (g_file_test(filename->str, G_FILE_TEST_EXISTS)); /* create the file to prevent another process from taking it */ /* b4 the current caller gets around to writing anything to it */ fp = fopen(filename->str, "wt"); if (fp) { fprintf(fp, "locked.\n"); fclose(fp); } else { printf("Fatal error in gun()\n"); return(NULL); } name = g_string_free(filename, FALSE); #if DEBUG_GUN printf("using base: %s\n", name); #endif return(name); } /**************************************************************/ /* correct numbers in binary files with reverse byte ordering */ /**************************************************************/ void swap_bytes(void *ptr, const gint size) { gint i,j; gchar tmp; /* printf("start: "); for (i=0 ; istr, float_val, units); text_str = text->str; g_string_free(format_string, TRUE); g_string_free(text, FALSE); g_strfreev(buff); return (text_str); } /************************************************/ /* read in a raw frame (animation and analysis) */ /************************************************/ #define DEBUG_READ_RAW 0 gint read_raw_frame(FILE *fp, gint n, struct model_pak *model) { gint i, flag=99; gchar *filename; fpos_t *offset; FILE *fp2; struct file_pak *file; g_assert(fp != NULL); g_assert(model != NULL); file = get_file_info(GINT_TO_POINTER(model->id), BY_FILE_ID); #if DEBUG_READ_RAW printf("reading frame: %d\n", n); #endif /* position the file pointer */ if (model->id != GULP) { offset = g_list_nth_data(model->frame_list, n); #if DEBUG_READ_RAW printf("offset = %d\n", offset); #endif if (!offset) return(1); if (fsetpos(fp, offset)) { printf("Error positioning file pointer.\n"); return(2); } /* use supplied routine (if available) */ if (file->read_frame) flag = file->read_frame(fp, model); else gui_text_show(ERROR, "No animation read routine.\n"); } else { /* GULP exception */ if (!n) { /* NEW - 0th frame exception - load original GULP coords */ if (model->cores) g_assert(model->gulp.orig_cores != NULL); if (model->shels) g_assert(model->gulp.orig_shells != NULL); /* free connectivity lists */ free_slist(model->bonds); free_slist(model->moles); model->bonds = NULL; model->moles = NULL; /* restore coords */ free_slist(model->cores); free_slist(model->shels); model->cores = dup_core_list(model->gulp.orig_cores); model->shels = dup_shell_list(model->gulp.orig_shells); /* restore lattice */ /* model->fractional = model->gulp.orig_fractional; */ /* FIXME - I don't know why this works (and the above doesn't)... */ model->fractional = TRUE; model->construct_pbc = model->gulp.orig_construct_pbc; memcpy(model->latmat, model->gulp.orig_latmat, 9*sizeof(gdouble)); memcpy(model->pbc, model->gulp.orig_pbc, 6*sizeof(gdouble)); /* turn space group lookup on */ model->sginfo.lookup = TRUE; flag = 0; } else { /* turn off space group lookup */ /* trg files contain ALL atoms & symmetry may be broken */ model->sginfo.lookup = FALSE; /* FIXME - trj files resist every attempt at random access... why??? */ filename = g_strdup_printf("%s/%s", sysenv.cwd, model->gulp.trj_file); fp2 = fopen(filename, "r"); if (!fp2) { printf("Failed to open: %s\n", filename); g_free(filename); return(3); } /* FIXME - ugly hack to get the nth frame */ read_trj_header(fp2, model); for (i=0 ; ilabel); #endif if (mdata) data = mdata; else { /* get the new model number */ data = model_new(); if (!data) { gui_text_show(ERROR, "Model memory allocation failed.\n"); return; } } data->id = file_data->id; /* read file if exists, else try prepending current working directory */ if (file_data->read_file) { if (g_path_is_absolute(filename)) { status = file_data->read_file(filename, data); } else { fullname = g_build_filename(sysenv.cwd, filename, NULL); status = file_data->read_file(fullname, data); g_free(fullname); } } else gui_text_show(ERROR, "No read routine for this type. "); /* NEW - display error (if any) */ if ((data->error_file_read)->len) { gui_text_show(ERROR, (data->error_file_read)->str); } /* check for successful file load */ if (status) { gui_text_show(ERROR, "Load failed.\n"); printf("Load failed, error code: %d\n", status); model_delete(data); } else { /* we don't know how many new models were loaded so */ /* scan through them all & check for initialization */ for (list=sysenv.mal ; list ; list=g_slist_next(list)) { data = list->data; /* skip if already on the tree */ if (data->grafted) continue; /* NEW - big model display mode exceptions */ /* CURRENT - this doesn't work - something not set up? */ /* TODO - automaticaly choose an appropriate zone size */ /* if (data->num_atoms > 100000) { gpointer za; core_render_mode_set(ZONE, data->cores); za = zone_make(10.0, data); zone_display_init(za, data); zone_free(za); } else */ { if (data->num_atoms > 1000) core_render_mode_set(STICK, data->cores); } /* surfaces are always conv by default */ if (data->periodic == 2) data->gulp.method = CONV; /* not on tree - must have just been loaded */ tree_model_add(data); /* create gulp supercells */ flag=0; for (j=0 ; j<3 ; j++) { if (data->gulp.super[j] > 1) { data->image_limit[2*j+1] = data->gulp.super[j]; data->expected_cores *= data->gulp.super[j]; data->expected_shells *= data->gulp.super[j]; flag++; } } if (flag) { space_make_images(CREATE, data); space_make_supercell(data); model_prep(data); } /* NEW - store initial frame, as trajectory animation will overwrite */ if (data->gulp.trj_file && !data->gulp.orig_cores) { /* FIXME - saving fractional type here instead of at the end of read_gulp() stuffs things up - why? */ /* NB: we need to save the coords here (and not earlier) in case a supercell was created */ memcpy(data->gulp.orig_pbc, data->pbc, 6*sizeof(gdouble)); memcpy(data->gulp.orig_latmat, data->latmat, 9*sizeof(gdouble)); data->gulp.orig_cores = dup_core_list(data->cores); data->gulp.orig_shells = dup_shell_list(data->shels); } sysenv.active_model = data; } } /* finished - only now we destroy the file dialog */ dialog_destroy_type(FILE_SELECT); tree_select_active(); } /****************/ /* load dialog */ /***************/ void file_load_dialog(void) { /* revert to data filetypes for special cases */ switch (sysenv.file_type) { case MD_ANALYSIS: case PICTURE: case PROJECT: case GEOMVIEW_OFF: sysenv.file_type = DATA; } file_dialog("Load file", NULL, FILE_LOAD, (gpointer) file_load, sysenv.file_type); } /**********************************/ /* save file with name */ /**********************************/ gint file_save_as(gchar *filename, struct model_pak *model) { gint id, ret; gchar *name; struct file_pak *file_data; /* setup & checks */ if (!model) model = sysenv.active_model; if (!filename || !model) return(1); file_data = get_file_info((gpointer *) filename, BY_EXTENSION); if (file_data) { /* use extension */ id = file_data->id; strcpy(model->filename, filename); g_free(model->basename); model->basename = strdup_basename(filename); } else { gchar *ext; /* no extension - attempt to use filter type */ file_data = get_file_info(GINT_TO_POINTER(sysenv.file_type), BY_FILE_ID); if (!file_data) return(2); ext = g_slist_nth_data(file_data->ext, 0); if (!ext) return(2); id = file_data->id; g_free(model->basename); model->basename = strdup_basename(filename); name = g_strdup_printf("%s.%s", model->basename, ext); strcpy(model->filename, name); g_free(name); } /* file info indicates routine to call */ if (file_data->write_file == NULL) { printf("No write routine for this type.\n"); return(3); } else { /* build the full name */ name = g_build_filename(sysenv.cwd, model->filename, NULL); ret = file_data->write_file(name, model); g_free(name); } /* update */ if (ret) gui_text_show(ERROR, "Save failed.\n"); else { gui_text_show(STANDARD, "Saved model.\n"); dialog_destroy_type(FILE_SELECT); tree_model_refresh(model); redraw_canvas(SINGLE); } return(ret); } /*************************************/ /* save active model using same name */ /*************************************/ void file_save(void) { gchar *name; struct model_pak *model; model = sysenv.active_model; if (!model) return; /* strip the path, as file_save_as() prepends the cwd */ name = g_path_get_basename(model->filename); file_save_as(name, model); g_free(name); } /******************/ /* save as dialog */ /******************/ void file_save_dialog(void) { gchar *text=NULL; struct model_pak *model; model = sysenv.active_model; if (model) text = model->basename; file_dialog("File save", text, FILE_SAVE, (gpointer) file_save_as, sysenv.file_type); } /*************************************/ /* get the size of a file (in bytes) */ /*************************************/ gint file_byte_size(const gchar *filename) { struct stat buff; stat(filename, &buff); return(buff.st_size); }