1997-11-25 06:05:25 +08:00
/* The GIMP -- an image manipulation program
* Copyright ( C ) 1995 , 1996 , 1997 Spencer Kimball and Peter Mattis
* Copyright ( C ) 1997 Josh MacDonald
*
* 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
1998-04-13 13:44:11 +08:00
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
1997-11-25 06:05:25 +08:00
*/
1999-02-21 07:20:54 +08:00
# include "config.h"
1997-11-25 06:05:25 +08:00
# include <ctype.h>
# include <errno.h>
1998-06-09 08:25:28 +08:00
# include <stdlib.h>
1997-11-25 06:05:25 +08:00
# include <string.h>
# include <sys/types.h>
1999-02-21 07:20:54 +08:00
# ifdef HAVE_SYS_PARAM_H
1997-11-25 06:05:25 +08:00
# include <sys/param.h>
1999-02-21 07:20:54 +08:00
# endif
1997-11-25 06:05:25 +08:00
# include <sys/stat.h>
1999-02-21 07:20:54 +08:00
# ifdef HAVE_UNISTD_H
1997-11-25 06:05:25 +08:00
# include <unistd.h>
1999-02-21 07:20:54 +08:00
# endif
1997-11-25 06:05:25 +08:00
# include <errno.h>
1999-02-21 07:20:54 +08:00
# ifdef _MSC_VER
# include <process.h> /* For _getpid() */
# include <direct.h> /* For _mkdir() */
# define mkdir(path,mode) _mkdir(path)
# endif
1997-11-25 06:05:25 +08:00
# include "appenv.h"
# include "actionarea.h"
1999-02-08 06:13:10 +08:00
# include "cursorutil.h"
1997-11-25 06:05:25 +08:00
# include "gdisplay.h"
# include "general.h"
# include "gimage.h"
# include "fileops.h"
# include "interface.h"
# include "menus.h"
# include "plug_in.h"
# include "procedural_db.h"
# include "gimprc.h"
1998-07-08 17:04:33 +08:00
# include "docindex.h"
1999-03-21 06:58:01 +08:00
# include "undo.h"
1997-11-25 06:05:25 +08:00
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
# include "libgimp/gimpintl.h"
1997-11-25 06:05:25 +08:00
typedef struct _OverwriteBox OverwriteBox ;
struct _OverwriteBox
{
GtkWidget * obox ;
char * full_filename ;
char * raw_filename ;
} ;
static Argument * register_load_handler_invoker ( Argument * args ) ;
static Argument * register_magic_load_handler_invoker ( Argument * args ) ;
static Argument * register_save_handler_invoker ( Argument * args ) ;
static Argument * file_load_invoker ( Argument * args ) ;
static Argument * file_save_invoker ( Argument * args ) ;
static Argument * file_temp_name_invoker ( Argument * args ) ;
static void file_overwrite ( char * filename ,
char * raw_filename ) ;
static void file_overwrite_yes_callback ( GtkWidget * w ,
gpointer client_data ) ;
static void file_overwrite_no_callback ( GtkWidget * w ,
gpointer client_data ) ;
static gint file_overwrite_delete_callback ( GtkWidget * w ,
GdkEvent * e ,
gpointer client_data ) ;
1999-01-12 09:31:49 +08:00
static GimpImage * file_open_image ( char * filename ,
1999-02-23 08:18:24 +08:00
char * raw_filename ,
RunModeType runmode ) ;
1999-01-12 09:31:49 +08:00
1999-02-08 06:13:10 +08:00
static void genbutton_callback ( GtkWidget * w ,
gpointer client_data ) ;
1999-02-04 08:53:35 +08:00
static void file_open_clistrow_callback ( GtkWidget * w ,
int client_data ) ;
1997-11-25 06:05:25 +08:00
static void file_open_ok_callback ( GtkWidget * w ,
gpointer client_data ) ;
static void file_save_ok_callback ( GtkWidget * w ,
gpointer client_data ) ;
static void file_dialog_show ( GtkWidget * filesel ) ;
1998-03-15 10:46:15 +08:00
static int file_dialog_hide ( GtkWidget * filesel ) ;
1997-11-25 06:05:25 +08:00
static void file_update_name ( PlugInProcDef * proc ,
GtkWidget * filesel ) ;
static void file_load_type_callback ( GtkWidget * w ,
gpointer client_data ) ;
static void file_save_type_callback ( GtkWidget * w ,
gpointer client_data ) ;
static void file_convert_string ( char * instr ,
char * outmem ,
int maxmem ,
int * nmem ) ;
static int file_check_single_magic ( char * offset ,
char * type ,
char * value ,
int headsize ,
unsigned char * file_head ,
FILE * ifp ) ;
static int file_check_magic_list ( GSList * magics_list ,
int headsize ,
unsigned char * head ,
FILE * ifp ) ;
static PlugInProcDef * file_proc_find ( GSList * procs ,
char * filename ) ;
static void file_update_menus ( GSList * procs ,
int image_type ) ;
1999-02-08 06:13:10 +08:00
GtkWidget * fileload = NULL ; /* Shared with dialog_handler.c */
static GtkWidget * filesave = NULL ;
static GtkWidget * open_options = NULL ;
static GtkWidget * save_options = NULL ;
1999-02-04 08:53:35 +08:00
/* widgets for the open_options menu */
static GtkPreview * open_options_preview = NULL ;
static GtkWidget * open_options_fixed = NULL ;
static GtkWidget * open_options_label = NULL ;
1999-02-07 23:16:45 +08:00
static GtkWidget * open_options_frame = NULL ;
1999-02-23 08:18:24 +08:00
static GtkWidget * open_options_genbuttonlabel = NULL ;
1999-02-08 06:13:10 +08:00
/* Some state for the thumbnailer */
static gchar * preview_fullname = NULL ;
1997-11-25 06:05:25 +08:00
/* Load by extension.
*/
static ProcArg file_load_args [ ] =
{
1998-12-26 02:22:01 +08:00
{ PDB_INT32 , " run_mode " , " Interactive, non-interactive. " } ,
{ PDB_STRING , " filename " , " The name of the file to load. " } ,
{ PDB_STRING , " raw_filename " , " The name entered. " } ,
1997-11-25 06:05:25 +08:00
} ;
static ProcArg file_load_return_vals [ ] =
{
1998-12-26 02:22:01 +08:00
{ PDB_IMAGE , " image " , " Output image. " } ,
1997-11-25 06:05:25 +08:00
} ;
static ProcRecord file_load_proc =
{
" gimp_file_load " ,
1998-12-26 02:22:01 +08:00
" Loads a file by extension " ,
" This procedure invokes the correct file load handler according to the file's extension and/or prefix. The name of the file to load is typically a full pathname, and the name entered is what the user actually typed before prepending a directory path. The reason for this is that if the user types http://www.xcf/~gimp he wants to fetch a URL, and the full pathname will not look like a URL. " ,
1997-11-25 06:05:25 +08:00
" Josh MacDonald " ,
" Josh MacDonald " ,
" 1997 " ,
PDB_INTERNAL ,
3 ,
file_load_args ,
1 ,
file_load_return_vals ,
{ { file_load_invoker } } ,
} ;
/* Save by extension.
*/
static ProcArg file_save_args [ ] =
{
1998-12-26 02:22:01 +08:00
{ PDB_INT32 , " run_mode " , " Interactive, non-interactive " } ,
{ PDB_IMAGE , " image " , " Input image " } ,
{ PDB_DRAWABLE , " drawable " , " Drawable to save " } ,
{ PDB_STRING , " filename " , " The name of the file to save the image in " } ,
{ PDB_STRING , " raw_filename " , " The name of the file to save the image in " }
1997-11-25 06:05:25 +08:00
} ;
static ProcRecord file_save_proc =
{
" gimp_file_save " ,
1998-12-26 02:22:01 +08:00
" Saves a file by extension " ,
1999-02-23 08:18:24 +08:00
" This procedure invokes the correct file save handler according to the file's extension and/or prefix. The name of the file to save is typically a full pathname, and the name entered is what the user actually typed before prepending a directory path. The reason for this is that if the user types http://www.xcf/~gimp she wants to fetch a URL, and the full pathname will not look like a URL. " ,
1997-11-25 06:05:25 +08:00
" Josh MacDonald " ,
" Josh MacDonald " ,
" 1997 " ,
PDB_INTERNAL ,
5 ,
file_save_args ,
0 ,
NULL ,
{ { file_save_invoker } } ,
} ;
/* Temp name.
*/
static ProcArg file_temp_name_args [ ] =
{
1998-12-26 02:22:01 +08:00
{ PDB_STRING , " extension " , " The extension the file will have. " }
1997-11-25 06:05:25 +08:00
} ;
static ProcArg file_temp_name_values [ ] =
{
1998-12-26 02:22:01 +08:00
{ PDB_STRING , " name " , " The temp name. " }
1997-11-25 06:05:25 +08:00
} ;
static ProcRecord file_temp_name_proc =
{
" gimp_temp_name " ,
1998-12-26 02:22:01 +08:00
" Generates a unique filename. " ,
" Generates a unique filename using the temp path supplied in the user's gimprc. " ,
1997-11-25 06:05:25 +08:00
" Josh MacDonald " ,
" Josh MacDonald " ,
" 1997 " ,
PDB_INTERNAL ,
1 ,
file_temp_name_args ,
1 ,
file_temp_name_values ,
{ { file_temp_name_invoker } } ,
} ;
/* Register magic load handler.
*/
static ProcArg register_magic_load_handler_args [ ] =
{
{ PDB_STRING ,
" procedure_name " ,
1998-12-26 02:22:01 +08:00
" the name of the procedure to be used for loading " } ,
1997-11-25 06:05:25 +08:00
{ PDB_STRING ,
" extensions " ,
1998-12-26 02:22:01 +08:00
" comma separated list of extensions this handler can load (ie. \" jpeg,jpg \" ) " } ,
1997-11-25 06:05:25 +08:00
{ PDB_STRING ,
" prefixes " ,
1998-12-26 02:22:01 +08:00
" comma separated list of prefixes this handler can load (ie. \" http:,ftp: \" ) " } ,
1997-11-25 06:05:25 +08:00
{ PDB_STRING ,
" magics " ,
1998-12-26 02:22:01 +08:00
" comma separated list of magic file information this handler can load (ie. \" 0,string,GIF \" ) " } ,
1997-11-25 06:05:25 +08:00
} ;
static ProcRecord register_magic_load_handler_proc =
{
" gimp_register_magic_load_handler " ,
1998-12-26 02:22:01 +08:00
" Registers a file load handler procedure " ,
" Registers a procedural database procedure to be called to load files of a \
particular file format using magic file information . " ,
1997-11-25 06:05:25 +08:00
" Spencer Kimball & Peter Mattis " ,
" Spencer Kimball & Peter Mattis " ,
" 1995-1996 " ,
PDB_INTERNAL ,
1998-07-24 01:32:32 +08:00
4 ,
1997-11-25 06:05:25 +08:00
register_magic_load_handler_args ,
0 ,
NULL ,
{ { register_magic_load_handler_invoker } } ,
} ;
/* Register load handler.
*/
static ProcArg register_load_handler_args [ ] =
{
{ PDB_STRING ,
" procedure_name " ,
1998-12-26 02:22:01 +08:00
" the name of the procedure to be used for loading " } ,
1997-11-25 06:05:25 +08:00
{ PDB_STRING ,
" extensions " ,
1998-12-26 02:22:01 +08:00
" comma separated list of extensions this handler can load (ie. \" jpeg,jpg \" ) " } ,
1997-11-25 06:05:25 +08:00
{ PDB_STRING ,
" prefixes " ,
1998-12-26 02:22:01 +08:00
" comma separated list of prefixes this handler can load (ie. \" http:,ftp: \" ) " } ,
1997-11-25 06:05:25 +08:00
} ;
static ProcRecord register_load_handler_proc =
{
" gimp_register_load_handler " ,
1998-12-26 02:22:01 +08:00
" Registers a file load handler procedure " ,
" Registers a procedural database procedure to be called to load files of a particular file format. " ,
1997-11-25 06:05:25 +08:00
" Spencer Kimball & Peter Mattis " ,
" Spencer Kimball & Peter Mattis " ,
" 1995-1996 " ,
PDB_INTERNAL ,
3 ,
register_load_handler_args ,
0 ,
NULL ,
{ { register_load_handler_invoker } } ,
} ;
/* Register save handler.
*/
static ProcArg register_save_handler_args [ ] =
{
{ PDB_STRING ,
" procedure_name " ,
1998-12-26 02:22:01 +08:00
" the name of the procedure to be used for saving " } ,
1997-11-25 06:05:25 +08:00
{ PDB_STRING ,
" extensions " ,
1998-12-26 02:22:01 +08:00
" comma separated list of extensions this handler can save (ie. \" jpeg,jpg \" ) " } ,
1997-11-25 06:05:25 +08:00
{ PDB_STRING ,
" prefixes " ,
1998-12-26 02:22:01 +08:00
" comma separated list of prefixes this handler can save (ie. \" http:,ftp: \" ) " } ,
1997-11-25 06:05:25 +08:00
} ;
static ProcRecord register_save_handler_proc =
{
" gimp_register_save_handler " ,
1998-12-26 02:22:01 +08:00
" Registers a file save handler procedure " ,
" Registers a procedural database procedure to be called to save files in a particular file format. " ,
1997-11-25 06:05:25 +08:00
" Spencer Kimball & Peter Mattis " ,
" Spencer Kimball & Peter Mattis " ,
" 1995-1996 " ,
PDB_INTERNAL ,
3 ,
register_save_handler_args ,
0 ,
NULL ,
{ { register_save_handler_invoker } } ,
} ;
static GSList * load_procs = NULL ;
static GSList * save_procs = NULL ;
static PlugInProcDef * load_file_proc = NULL ;
static PlugInProcDef * save_file_proc = NULL ;
1998-08-25 02:48:06 +08:00
static GimpImage * the_gimage = NULL ;
1997-11-25 06:05:25 +08:00
1998-07-29 05:11:47 +08:00
# define FILE_ERR_MESSAGE(str) G_STMT_START{ \
if ( message_handler = = MESSAGE_BOX ) \
message_box ( ( str ) , file_message_box_close_callback , ( void * ) fs ) ; \
else \
g_message ( str ) ; \
gtk_widget_set_sensitive ( GTK_WIDGET ( fs ) , TRUE ) ; } G_STMT_END
1998-05-07 06:20:43 +08:00
static void
file_message_box_close_callback ( GtkWidget * w ,
gpointer client_data )
{
GtkFileSelection * fs ;
fs = ( GtkFileSelection * ) client_data ;
gtk_widget_set_sensitive ( GTK_WIDGET ( fs ) , TRUE ) ;
}
1997-11-25 06:05:25 +08:00
void
file_ops_pre_init ( )
{
procedural_db_register ( & register_magic_load_handler_proc ) ;
procedural_db_register ( & register_load_handler_proc ) ;
procedural_db_register ( & register_save_handler_proc ) ;
procedural_db_register ( & file_load_proc ) ;
procedural_db_register ( & file_save_proc ) ;
procedural_db_register ( & file_temp_name_proc ) ;
}
void
file_ops_post_init ( )
{
GtkMenuEntry entry ;
PlugInProcDef * file_proc ;
GSList * tmp ;
load_procs = g_slist_reverse ( load_procs ) ;
save_procs = g_slist_reverse ( save_procs ) ;
tmp = load_procs ;
while ( tmp )
{
file_proc = tmp - > data ;
tmp = tmp - > next ;
entry . path = file_proc - > menu_path ;
entry . accelerator = NULL ;
entry . callback = file_load_type_callback ;
entry . callback_data = file_proc ;
menus_create ( & entry , 1 ) ;
}
tmp = save_procs ;
while ( tmp )
{
file_proc = tmp - > data ;
tmp = tmp - > next ;
entry . path = file_proc - > menu_path ;
entry . accelerator = NULL ;
entry . callback = file_save_type_callback ;
entry . callback_data = file_proc ;
menus_create ( & entry , 1 ) ;
}
}
static Argument *
register_load_handler_invoker ( Argument * args )
{
Argument fargs [ 4 ] ;
memcpy ( ( char * ) fargs , ( char * ) args , 3 * sizeof ( args [ 0 ] ) ) ;
fargs [ 3 ] . arg_type = PDB_STRING ;
fargs [ 3 ] . value . pdb_pointer = NULL ;
return ( register_magic_load_handler_invoker ( fargs ) ) ;
}
static Argument *
register_magic_load_handler_invoker ( Argument * args )
{
Argument * return_args ;
ProcRecord * proc ;
PlugInProcDef * file_proc ;
int success ;
success = FALSE ;
proc = procedural_db_lookup ( ( char * ) args [ 0 ] . value . pdb_pointer ) ;
if ( proc & & ( ( proc - > num_args < 3 ) | |
( proc - > num_values < 1 ) | |
( proc - > args [ 0 ] . arg_type ! = PDB_INT32 ) | |
( proc - > args [ 1 ] . arg_type ! = PDB_STRING ) | |
( proc - > args [ 2 ] . arg_type ! = PDB_STRING ) | |
( proc - > values [ 0 ] . arg_type ! = PDB_IMAGE ) ) )
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
g_message ( _ ( " load handler \" %s \" does not take the standard load handler args " ) ,
1997-11-25 06:05:25 +08:00
( char * ) args [ 0 ] . value . pdb_pointer ) ;
goto done ;
}
file_proc = plug_in_file_handler ( ( char * ) args [ 0 ] . value . pdb_pointer ,
( char * ) args [ 1 ] . value . pdb_pointer ,
( char * ) args [ 2 ] . value . pdb_pointer ,
( char * ) args [ 3 ] . value . pdb_pointer ) ;
if ( ! file_proc )
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
g_message ( _ ( " attempt to register non-existant load handler \" %s \" " ) ,
1997-11-25 06:05:25 +08:00
( char * ) args [ 0 ] . value . pdb_pointer ) ;
goto done ;
}
load_procs = g_slist_prepend ( load_procs , file_proc ) ;
success = TRUE ;
done :
return_args = procedural_db_return_args ( & register_load_handler_proc , success ) ;
return return_args ;
}
static Argument *
register_save_handler_invoker ( Argument * args )
{
Argument * return_args ;
ProcRecord * proc ;
PlugInProcDef * file_proc ;
int success ;
success = FALSE ;
proc = procedural_db_lookup ( ( char * ) args [ 0 ] . value . pdb_pointer ) ;
if ( proc & & ( ( proc - > num_args < 5 ) | |
( proc - > args [ 0 ] . arg_type ! = PDB_INT32 ) | |
( proc - > args [ 1 ] . arg_type ! = PDB_IMAGE ) | |
( proc - > args [ 2 ] . arg_type ! = PDB_DRAWABLE ) | |
( proc - > args [ 3 ] . arg_type ! = PDB_STRING ) | |
( proc - > args [ 4 ] . arg_type ! = PDB_STRING ) ) )
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
g_message ( _ ( " save handler \" %s \" does not take the standard save handler args " ) ,
1997-11-25 06:05:25 +08:00
( char * ) args [ 0 ] . value . pdb_pointer ) ;
goto done ;
}
file_proc = plug_in_file_handler ( ( char * ) args [ 0 ] . value . pdb_pointer ,
( char * ) args [ 1 ] . value . pdb_pointer ,
( char * ) args [ 2 ] . value . pdb_pointer ,
NULL ) ;
if ( ! file_proc )
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
g_message ( _ ( " attempt to register non-existant save handler \" %s \" " ) ,
1997-11-25 06:05:25 +08:00
( char * ) args [ 0 ] . value . pdb_pointer ) ;
goto done ;
}
save_procs = g_slist_prepend ( save_procs , file_proc ) ;
success = TRUE ;
done :
return_args = procedural_db_return_args ( & register_save_handler_proc , success ) ;
return return_args ;
}
void
file_open_callback ( GtkWidget * w ,
gpointer client_data )
{
GtkWidget * hbox ;
1999-02-04 08:53:35 +08:00
GtkWidget * vbox ;
1997-11-25 06:05:25 +08:00
GtkWidget * label ;
GtkWidget * option_menu ;
GtkWidget * load_menu ;
1999-02-23 08:18:24 +08:00
GtkWidget * open_options_genbutton ;
1997-11-25 06:05:25 +08:00
GDisplay * gdisplay ;
if ( ! fileload )
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
fileload = gtk_file_selection_new ( _ ( " Load Image " ) ) ;
1998-12-04 07:01:44 +08:00
gtk_window_set_position ( GTK_WINDOW ( fileload ) , GTK_WIN_POS_MOUSE ) ;
1998-01-26 06:13:00 +08:00
gtk_window_set_wmclass ( GTK_WINDOW ( fileload ) , " load_image " , " Gimp " ) ;
1998-03-13 06:01:43 +08:00
gtk_signal_connect_object ( GTK_OBJECT ( GTK_FILE_SELECTION ( fileload ) - > cancel_button ) ,
" clicked " ,
1998-03-15 10:46:15 +08:00
GTK_SIGNAL_FUNC ( file_dialog_hide ) ,
1998-03-13 06:01:43 +08:00
GTK_OBJECT ( fileload ) ) ;
gtk_signal_connect ( GTK_OBJECT ( fileload ) ,
" delete_event " ,
1998-03-15 10:46:15 +08:00
GTK_SIGNAL_FUNC ( file_dialog_hide ) ,
1998-03-13 06:01:43 +08:00
NULL ) ;
1997-11-25 06:05:25 +08:00
gtk_signal_connect ( GTK_OBJECT ( GTK_FILE_SELECTION ( fileload ) - > ok_button ) , " clicked " , ( GtkSignalFunc ) file_open_ok_callback , fileload ) ;
1998-03-15 13:41:01 +08:00
gtk_quit_add_destroy ( 1 , GTK_OBJECT ( fileload ) ) ;
1998-07-18 23:25:52 +08:00
gtk_clist_set_selection_mode ( GTK_CLIST
( GTK_FILE_SELECTION ( fileload ) - > file_list ) ,
GTK_SELECTION_EXTENDED ) ;
1999-02-04 08:53:35 +08:00
/* Catch file-clist clicks so we can update the preview thumbnail */
gtk_signal_connect ( GTK_OBJECT ( GTK_FILE_SELECTION ( fileload ) - > file_list ) , " select_row " , ( GtkSignalFunc ) file_open_clistrow_callback , fileload ) ;
1997-11-25 06:05:25 +08:00
}
else
{
1998-05-04 11:21:54 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( fileload ) , TRUE ) ;
1997-11-25 06:05:25 +08:00
if ( GTK_WIDGET_VISIBLE ( fileload ) )
return ;
1999-02-21 07:20:54 +08:00
gtk_file_selection_set_filename ( GTK_FILE_SELECTION ( fileload ) ,
" . " G_DIR_SEPARATOR_S ) ;
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
gtk_window_set_title ( GTK_WINDOW ( fileload ) , _ ( " Load Image " ) ) ;
1997-11-25 06:05:25 +08:00
}
gdisplay = gdisplay_active ( ) ;
if ( ! open_options )
{
1999-02-04 08:53:35 +08:00
GtkWidget * frame ;
1997-11-25 06:05:25 +08:00
1999-02-07 23:16:45 +08:00
open_options = gtk_hbox_new ( TRUE , 1 ) ;
1997-11-25 06:05:25 +08:00
1999-02-04 08:53:35 +08:00
/* format-chooser frame */
frame = gtk_frame_new ( _ ( " Open Options " ) ) ;
{
gtk_frame_set_shadow_type ( GTK_FRAME ( frame ) ,
GTK_SHADOW_ETCHED_IN ) ;
vbox = gtk_vbox_new ( FALSE , 0 ) ;
{
1999-02-23 08:18:24 +08:00
gtk_container_set_border_width ( GTK_CONTAINER ( vbox ) , 2 ) ;
1999-02-04 08:53:35 +08:00
gtk_container_add ( GTK_CONTAINER ( frame ) , vbox ) ;
1997-11-25 06:05:25 +08:00
1999-02-23 08:18:24 +08:00
hbox = gtk_hbox_new ( FALSE , 1 ) ;
1999-02-04 08:53:35 +08:00
{
1999-02-23 08:18:24 +08:00
gtk_container_set_border_width ( GTK_CONTAINER ( hbox ) , 2 ) ;
1999-02-04 08:53:35 +08:00
gtk_box_pack_start ( GTK_BOX ( vbox ) , hbox , FALSE , TRUE , 0 ) ;
label = gtk_label_new ( _ ( " Determine file type: " ) ) ;
1999-02-23 08:18:24 +08:00
gtk_box_pack_start ( GTK_BOX ( hbox ) , label , FALSE , FALSE , 5 ) ;
1999-02-04 08:53:35 +08:00
gtk_widget_show ( label ) ;
option_menu = gtk_option_menu_new ( ) ;
1999-02-23 08:18:24 +08:00
gtk_box_pack_start ( GTK_BOX ( hbox ) , option_menu , FALSE , TRUE , 0 ) ;
1999-02-04 08:53:35 +08:00
gtk_widget_show ( option_menu ) ;
menus_get_load_menu ( & load_menu , NULL ) ;
gtk_option_menu_set_menu ( GTK_OPTION_MENU ( option_menu ) , load_menu ) ;
1999-02-23 08:18:24 +08:00
gtk_box_pack_start ( GTK_BOX ( open_options ) , frame , TRUE , TRUE , 5 ) ;
1999-02-04 08:53:35 +08:00
}
gtk_widget_show ( hbox ) ;
}
gtk_widget_show ( vbox ) ;
}
gtk_widget_show ( frame ) ;
/* Preview frame */
1999-02-07 23:16:45 +08:00
frame = gtk_frame_new ( " " ) ;
open_options_frame = frame ;
1999-02-04 08:53:35 +08:00
{
gtk_frame_set_shadow_type ( GTK_FRAME ( frame ) ,
GTK_SHADOW_ETCHED_IN ) ;
gtk_box_pack_end ( GTK_BOX ( open_options ) , frame , FALSE , TRUE , 5 ) ;
vbox = gtk_vbox_new ( FALSE , 1 ) ;
{
gtk_container_set_border_width ( GTK_CONTAINER ( vbox ) , 5 ) ;
gtk_container_add ( GTK_CONTAINER ( frame ) , vbox ) ;
hbox = gtk_hbox_new ( TRUE , 1 ) ;
{
gtk_container_set_border_width ( GTK_CONTAINER ( hbox ) , 0 ) ;
gtk_box_pack_start ( GTK_BOX ( vbox ) , hbox , FALSE , FALSE , 0 ) ;
1999-02-23 08:18:24 +08:00
open_options_genbutton = gtk_button_new ( ) ;
1999-02-08 06:13:10 +08:00
{
gtk_signal_connect ( GTK_OBJECT ( open_options_genbutton ) ,
" clicked " ,
( GtkSignalFunc ) genbutton_callback ,
open_options_genbutton ) ;
gtk_box_pack_end ( GTK_BOX ( hbox ) , open_options_genbutton ,
1999-02-23 08:18:24 +08:00
TRUE , FALSE , 0 ) ;
1999-02-08 06:13:10 +08:00
}
gtk_widget_show ( open_options_genbutton ) ;
1999-02-04 08:53:35 +08:00
open_options_fixed = gtk_fixed_new ( ) ;
{
1999-02-23 08:18:24 +08:00
GtkWidget * abox ;
GtkWidget * sbox ;
1999-02-08 06:13:10 +08:00
gtk_widget_set_usize ( open_options_fixed , 80 , 60 ) ;
1999-02-23 08:18:24 +08:00
gtk_container_add ( GTK_CONTAINER ( GTK_BIN ( open_options_genbutton ) ) , open_options_fixed ) ;
1999-02-04 08:53:35 +08:00
1999-02-23 08:18:24 +08:00
sbox = gtk_vbox_new ( TRUE , 0 ) ;
1999-02-04 08:53:35 +08:00
{
1999-02-23 08:18:24 +08:00
GtkWidget * align ;
1999-02-04 08:53:35 +08:00
gtk_container_add ( GTK_CONTAINER ( open_options_fixed ) ,
1999-02-23 08:18:24 +08:00
GTK_WIDGET ( sbox ) ) ;
align = gtk_alignment_new ( 0.5 , 0.5 , 0.0 , 0.0 ) ;
{
gtk_widget_set_usize ( align , 80 , 60 ) ;
gtk_box_pack_start ( GTK_BOX ( sbox ) ,
GTK_WIDGET ( align ) ,
FALSE , TRUE , 0 ) ;
abox = gtk_hbox_new ( FALSE , 0 ) ;
{
gtk_container_add ( GTK_CONTAINER ( align ) , abox ) ;
open_options_preview = GTK_PREVIEW ( gtk_preview_new
( GTK_PREVIEW_COLOR ) ) ;
{
gtk_box_pack_start ( GTK_BOX ( abox ) ,
GTK_WIDGET ( open_options_preview ) ,
FALSE , TRUE , 0 ) ;
}
gtk_widget_show ( GTK_WIDGET ( open_options_preview ) ) ;
open_options_genbuttonlabel = gtk_label_new ( " generate \n preview " ) ;
{
gtk_box_pack_start ( GTK_BOX ( abox ) ,
GTK_WIDGET ( open_options_genbuttonlabel ) ,
FALSE , TRUE , 0 ) ;
}
gtk_widget_show ( GTK_WIDGET ( open_options_genbuttonlabel ) ) ;
}
gtk_widget_show ( abox ) ;
}
gtk_widget_show ( align ) ;
1999-02-04 08:53:35 +08:00
}
1999-02-23 08:18:24 +08:00
gtk_widget_show ( sbox ) ;
1999-02-04 08:53:35 +08:00
}
gtk_widget_show ( open_options_fixed ) ;
}
gtk_widget_show ( hbox ) ;
1999-02-07 23:16:45 +08:00
open_options_label = gtk_label_new ( " " ) ;
1999-02-04 08:53:35 +08:00
{
gtk_box_pack_end ( GTK_BOX ( vbox ) , open_options_label ,
FALSE , TRUE , 0 ) ;
}
1999-02-08 06:13:10 +08:00
gtk_widget_show ( open_options_label ) ;
1999-02-04 08:53:35 +08:00
}
gtk_widget_show ( vbox ) ;
}
gtk_widget_show ( frame ) ;
1997-11-25 06:05:25 +08:00
1999-02-04 08:53:35 +08:00
/* pack the containing open_options hbox into the load-dialog */
1997-11-25 06:05:25 +08:00
gtk_box_pack_end ( GTK_BOX ( GTK_FILE_SELECTION ( fileload ) - > main_vbox ) ,
1999-02-23 08:18:24 +08:00
open_options , FALSE , FALSE , 1 ) ;
1997-11-25 06:05:25 +08:00
}
1999-02-07 23:16:45 +08:00
gtk_frame_set_label ( GTK_FRAME ( open_options_frame ) , _ ( " Preview " ) ) ;
1999-02-04 08:53:35 +08:00
gtk_label_set_text ( GTK_LABEL ( open_options_label ) , " No selection. " ) ;
1999-02-23 08:18:24 +08:00
gtk_widget_show ( GTK_WIDGET ( open_options_genbuttonlabel ) ) ;
1999-02-08 06:13:10 +08:00
gtk_widget_hide ( GTK_WIDGET ( open_options_preview ) ) ;
1999-02-23 08:18:24 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( open_options_frame ) , FALSE ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( open_options ) ;
file_dialog_show ( fileload ) ;
}
void
file_save_callback ( GtkWidget * w ,
gpointer client_data )
{
GDisplay * gdisplay ;
gdisplay = gdisplay_active ( ) ;
/* Only save if the gimage has been modified */
if ( gdisplay - > gimage - > dirty ! = 0 )
{
if ( gdisplay - > gimage - > has_filename = = FALSE )
{
popup_shell = gdisplay - > shell ;
file_save_as_callback ( w , client_data ) ;
}
else
1998-06-29 08:24:44 +08:00
file_save ( gdisplay - > gimage , gimage_filename ( gdisplay - > gimage ) ,
1999-02-07 18:45:56 +08:00
g_basename ( gimage_filename ( gdisplay - > gimage ) ) , 2 ) ;
1997-11-25 06:05:25 +08:00
}
}
void
file_save_as_callback ( GtkWidget * w ,
gpointer client_data )
{
GtkWidget * hbox ;
GtkWidget * label ;
GtkWidget * option_menu ;
GtkWidget * save_menu ;
GDisplay * gdisplay ;
if ( ! filesave )
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
filesave = gtk_file_selection_new ( _ ( " Save Image " ) ) ;
1998-01-26 06:13:00 +08:00
gtk_window_set_wmclass ( GTK_WINDOW ( filesave ) , " save_image " , " Gimp " ) ;
1998-12-04 07:01:44 +08:00
gtk_window_set_position ( GTK_WINDOW ( filesave ) , GTK_WIN_POS_MOUSE ) ;
1998-03-16 04:52:24 +08:00
gtk_signal_connect_object ( GTK_OBJECT ( GTK_FILE_SELECTION ( filesave ) - > cancel_button ) ,
1998-03-13 06:01:43 +08:00
" clicked " ,
1998-03-15 10:46:15 +08:00
GTK_SIGNAL_FUNC ( file_dialog_hide ) ,
1998-03-13 06:01:43 +08:00
GTK_OBJECT ( filesave ) ) ;
gtk_signal_connect ( GTK_OBJECT ( filesave ) ,
" delete_event " ,
1998-03-15 10:46:15 +08:00
GTK_SIGNAL_FUNC ( file_dialog_hide ) ,
1998-03-13 06:01:43 +08:00
NULL ) ;
1997-11-25 06:05:25 +08:00
gtk_signal_connect ( GTK_OBJECT ( GTK_FILE_SELECTION ( filesave ) - > ok_button ) , " clicked " , ( GtkSignalFunc ) file_save_ok_callback , filesave ) ;
1998-03-15 13:41:01 +08:00
gtk_quit_add_destroy ( 1 , GTK_OBJECT ( filesave ) ) ;
1997-11-25 06:05:25 +08:00
}
else
{
1998-05-04 11:21:54 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( filesave ) , TRUE ) ;
1997-11-25 06:05:25 +08:00
if ( GTK_WIDGET_VISIBLE ( filesave ) )
return ;
1999-02-21 07:20:54 +08:00
gtk_file_selection_set_filename ( GTK_FILE_SELECTION ( filesave ) ,
" . " G_DIR_SEPARATOR_S ) ;
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
gtk_window_set_title ( GTK_WINDOW ( filesave ) , _ ( " Save Image " ) ) ;
1997-11-25 06:05:25 +08:00
}
gdisplay = gdisplay_active ( ) ;
1998-06-29 08:24:44 +08:00
the_gimage = gdisplay - > gimage ;
1997-11-25 06:05:25 +08:00
if ( ! save_options )
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
save_options = gtk_frame_new ( _ ( " Save Options " ) ) ;
1997-11-25 06:05:25 +08:00
gtk_frame_set_shadow_type ( GTK_FRAME ( save_options ) , GTK_SHADOW_ETCHED_IN ) ;
hbox = gtk_hbox_new ( FALSE , 1 ) ;
1998-12-04 07:01:44 +08:00
gtk_container_set_border_width ( GTK_CONTAINER ( hbox ) , 5 ) ;
1997-11-25 06:05:25 +08:00
gtk_container_add ( GTK_CONTAINER ( save_options ) , hbox ) ;
gtk_widget_show ( hbox ) ;
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
label = gtk_label_new ( _ ( " Determine file type: " ) ) ;
1997-11-25 06:05:25 +08:00
gtk_box_pack_start ( GTK_BOX ( hbox ) , label , FALSE , TRUE , 0 ) ;
gtk_widget_show ( label ) ;
option_menu = gtk_option_menu_new ( ) ;
gtk_box_pack_start ( GTK_BOX ( hbox ) , option_menu , TRUE , TRUE , 0 ) ;
gtk_widget_show ( option_menu ) ;
menus_get_save_menu ( & save_menu , NULL ) ;
gtk_option_menu_set_menu ( GTK_OPTION_MENU ( option_menu ) , save_menu ) ;
gtk_box_pack_end ( GTK_BOX ( GTK_FILE_SELECTION ( filesave ) - > main_vbox ) ,
save_options , FALSE , FALSE , 5 ) ;
}
switch ( gdisplay - > gimage - > base_type )
{
case RGB :
file_update_menus ( save_procs , RGB_IMAGE ) ;
break ;
case GRAY :
file_update_menus ( save_procs , GRAY_IMAGE ) ;
break ;
case INDEXED :
file_update_menus ( save_procs , INDEXED_IMAGE ) ;
break ;
}
gtk_widget_show ( save_options ) ;
file_dialog_show ( filesave ) ;
}
1999-01-12 09:31:49 +08:00
void
file_revert_callback ( GtkWidget * w ,
gpointer client_data )
{
GDisplay * gdisplay ;
GimpImage * gimage ;
char * filename , * raw_filename ;
gdisplay = gdisplay_active ( ) ;
if ( gdisplay - > gimage - > has_filename = = FALSE )
g_message ( _ ( " Can't revert. No filename associated with this image " ) ) ;
else
{
filename = gimage_filename ( gdisplay - > gimage ) ;
1999-02-07 18:45:56 +08:00
raw_filename = g_basename ( filename ) ;
1999-01-12 09:31:49 +08:00
1999-03-21 06:58:01 +08:00
gimage = file_open_image ( filename , raw_filename , RUN_INTERACTIVE ) ;
if ( gimage ! = NULL )
{
undo_free ( gimage ) ;
gdisplay_reconnect ( gdisplay , gimage ) ;
}
1999-01-12 09:31:49 +08:00
else
g_message ( _ ( " Revert failed. " ) ) ;
}
}
1997-11-25 06:05:25 +08:00
void
file_load_by_extension_callback ( GtkWidget * w ,
gpointer client_data )
{
load_file_proc = NULL ;
}
void
file_save_by_extension_callback ( GtkWidget * w ,
gpointer client_data )
{
save_file_proc = NULL ;
}
static void
file_update_name ( PlugInProcDef * proc , GtkWidget * filesel )
{
if ( proc - > extensions_list )
{
char * text = gtk_entry_get_text ( GTK_ENTRY ( GTK_FILE_SELECTION ( filesel ) - > selection_entry ) ) ;
char * last_dot = strrchr ( text , ' . ' ) ;
GString * s ;
if ( last_dot = = text | | ! text [ 0 ] )
return ;
s = g_string_new ( text ) ;
if ( last_dot )
g_string_truncate ( s , last_dot - text ) ;
g_string_append ( s , " . " ) ;
g_string_append ( s , ( char * ) proc - > extensions_list - > data ) ;
gtk_entry_set_text ( GTK_ENTRY ( GTK_FILE_SELECTION ( filesel ) - > selection_entry ) , s - > str ) ;
g_string_free ( s , TRUE ) ;
}
}
static void
file_load_type_callback ( GtkWidget * w ,
gpointer client_data )
{
PlugInProcDef * proc = ( PlugInProcDef * ) client_data ;
file_update_name ( proc , fileload ) ;
load_file_proc = proc ;
}
static void
file_save_type_callback ( GtkWidget * w ,
gpointer client_data )
{
PlugInProcDef * proc = ( PlugInProcDef * ) client_data ;
file_update_name ( proc , filesave ) ;
save_file_proc = proc ;
}
1999-01-12 09:31:49 +08:00
static GimpImage *
1999-02-23 08:18:24 +08:00
file_open_image ( char * filename , char * raw_filename , RunModeType runmode )
1997-11-25 06:05:25 +08:00
{
PlugInProcDef * file_proc ;
ProcRecord * proc ;
Argument * args ;
Argument * return_vals ;
1998-06-29 08:24:44 +08:00
int gimage_id ;
1999-01-12 09:31:49 +08:00
gboolean status ;
1997-11-25 06:05:25 +08:00
int i ;
file_proc = load_file_proc ;
if ( ! file_proc )
file_proc = file_proc_find ( load_procs , filename ) ;
if ( ! file_proc )
{
/* WARNING */
1999-01-12 09:31:49 +08:00
return NULL ;
1997-11-25 06:05:25 +08:00
}
proc = & file_proc - > db_info ;
args = g_new ( Argument , proc - > num_args ) ;
memset ( args , 0 , ( sizeof ( Argument ) * proc - > num_args ) ) ;
for ( i = 0 ; i < proc - > num_args ; i + + )
args [ i ] . arg_type = proc - > args [ i ] . arg_type ;
1999-02-23 08:18:24 +08:00
args [ 0 ] . value . pdb_int = runmode ;
1997-11-25 06:05:25 +08:00
args [ 1 ] . value . pdb_pointer = filename ;
args [ 2 ] . value . pdb_pointer = raw_filename ;
return_vals = procedural_db_execute ( proc - > name , args ) ;
1999-01-12 09:31:49 +08:00
status = ( return_vals [ 0 ] . value . pdb_int = = PDB_SUCCESS ) ;
1998-06-29 08:24:44 +08:00
gimage_id = return_vals [ 1 ] . value . pdb_int ;
1997-11-25 06:05:25 +08:00
procedural_db_destroy_args ( return_vals , proc - > num_values ) ;
g_free ( args ) ;
1999-01-12 09:31:49 +08:00
if ( status )
return pdb_id_to_image ( gimage_id ) ;
else
return NULL ;
}
int
file_open ( char * filename , char * raw_filename )
{
GimpImage * gimage ;
1999-02-23 08:18:24 +08:00
if ( ( gimage = file_open_image ( filename , raw_filename , RUN_INTERACTIVE ) ) ! = NULL )
1997-11-25 06:05:25 +08:00
{
1999-01-12 09:31:49 +08:00
/* enable & clear all undo steps */
1997-11-25 06:05:25 +08:00
gimage_enable_undo ( gimage ) ;
1999-01-12 09:31:49 +08:00
/* set the image to clean */
1997-11-25 06:05:25 +08:00
gimage_clean_all ( gimage ) ;
1999-01-12 09:31:49 +08:00
/* display the image */
1997-11-25 06:05:25 +08:00
gdisplay_new ( gimage , 0x0101 ) ;
1998-07-14 06:31:45 +08:00
idea_add ( filename ) ;
menus_last_opened_add ( filename ) ;
1999-01-12 09:31:49 +08:00
return TRUE ;
1998-07-14 06:31:45 +08:00
}
1998-07-08 17:04:33 +08:00
1999-01-12 09:31:49 +08:00
return FALSE ;
1997-11-25 06:05:25 +08:00
}
1999-02-08 06:13:10 +08:00
1999-02-07 23:16:45 +08:00
static gboolean
file_save_thumbnail ( GimpImage * gimage ,
1999-02-08 06:13:10 +08:00
const char * full_source_filename )
1999-02-07 23:16:45 +08:00
{
TempBuf * tempbuf ;
gint i , j ;
unsigned char * tbd ;
1999-02-08 06:13:10 +08:00
gchar * pathname ;
gchar * filename ;
gchar * xvpathname ;
gchar * thumbnailname ;
1999-02-07 23:16:45 +08:00
gint w , h ;
GimpImageBaseType basetype ;
FILE * fp ;
if ( gimp_image_preview_valid ( gimage , Gray ) )
{
1999-02-08 06:13:10 +08:00
/* just for debugging */
printf ( " (incidentally, gimage already has a valid preview - %dx%d) \n " ,
1999-02-07 23:16:45 +08:00
gimage - > comp_preview - > width ,
gimage - > comp_preview - > height ) ;
}
1999-02-08 06:13:10 +08:00
pathname = g_dirname ( full_source_filename ) ;
filename = g_basename ( full_source_filename ) ; /* Don't free! */
1999-02-07 23:16:45 +08:00
1999-02-08 06:13:10 +08:00
xvpathname = g_strconcat ( pathname , G_DIR_SEPARATOR_S , " .xvpics " ,
NULL ) ;
thumbnailname = g_strconcat ( xvpathname , G_DIR_SEPARATOR_S ,
filename ,
NULL ) ;
1999-02-07 23:16:45 +08:00
if ( gimage - > width < = 80 & & gimage - > height < = 60 )
{
w = gimage - > width ;
h = gimage - > height ;
}
else
{
/* Ratio molesting to fit within .xvpic thumbnail size limits */
if ( 60 * gimage - > width < 80 * gimage - > height )
{
h = 60 ;
w = ( 60 * gimage - > width ) / gimage - > height ;
if ( w = = 0 )
w = 1 ;
}
else
{
w = 80 ;
h = ( 80 * gimage - > height ) / gimage - > width ;
if ( h = = 0 )
h = 1 ;
}
}
1999-02-23 08:18:24 +08:00
/*printf("tn: %d x %d -> ", w, h);fflush(stdout);*/
1999-02-07 23:16:45 +08:00
tempbuf = gimp_image_composite_preview ( gimage , Gray , w , h ) ;
tbd = temp_buf_data ( tempbuf ) ;
w = tempbuf - > width ;
h = tempbuf - > height ;
1999-02-23 08:18:24 +08:00
/*printf("tn: %d x %d\n", w, h);fflush(stdout);*/
1999-02-07 23:16:45 +08:00
1999-02-08 06:13:10 +08:00
mkdir ( xvpathname , 0755 ) ;
1999-02-07 23:16:45 +08:00
1999-02-08 06:13:10 +08:00
fp = fopen ( thumbnailname , " wb " ) ;
g_free ( pathname ) ;
g_free ( xvpathname ) ;
g_free ( thumbnailname ) ;
1999-02-07 23:16:45 +08:00
if ( fp )
{
basetype = gimp_image_base_type ( gimage ) ;
fprintf ( fp ,
" P7 332 \n #IMGINFO:%dx%d %s \n "
" #END_OF_COMMENTS \n %d %d 255 \n " ,
gimage - > width , gimage - > height ,
( basetype = = RGB ) ? " RGB " :
( basetype = = GRAY ) ? " Greyscale " :
( basetype = = INDEXED ) ? " Indexed " :
" (UNKNOWN COLOUR TYPE) " ,
w , h ) ;
switch ( basetype )
{
case INDEXED :
case RGB :
1999-02-08 02:34:16 +08:00
for ( i = 0 ; i < h ; i + + )
1999-02-07 23:16:45 +08:00
{
1999-02-08 02:34:16 +08:00
/* Do a cheap unidirectional error-spread to look better */
gint rerr = 0 , gerr = 0 , berr = 0 ;
for ( j = 0 ; j < w ; j + + )
1999-02-07 23:16:45 +08:00
{
1999-02-08 02:34:16 +08:00
gint32 r , g , b ;
r = * ( tbd + + ) + rerr ;
g = * ( tbd + + ) + gerr ;
b = * ( tbd + + ) + berr ;
1999-02-07 23:16:45 +08:00
tbd + + ;
1999-02-08 02:34:16 +08:00
r = CLAMP0255 ( r ) ;
g = CLAMP0255 ( g ) ;
b = CLAMP0255 ( b ) ;
1999-02-07 23:16:45 +08:00
fputc ( ( ( r > > 5 ) < < 5 ) | ( ( g > > 5 ) < < 2 ) | ( b > > 6 ) , fp ) ;
1999-02-08 02:34:16 +08:00
rerr = r - ( ( r > > 5 ) * 255 ) / 7 ;
gerr = g - ( ( g > > 5 ) * 255 ) / 7 ;
berr = b - ( ( b > > 6 ) * 255 ) / 3 ;
1999-02-07 23:16:45 +08:00
}
}
break ;
case GRAY :
1999-02-08 02:34:16 +08:00
for ( i = 0 ; i < h ; i + + )
1999-02-07 23:16:45 +08:00
{
1999-02-08 02:34:16 +08:00
/* Do a cheap unidirectional error-spread to look better */
gint b3err = 0 , b2err = 0 , v ;
for ( j = 0 ; j < w ; j + + )
1999-02-07 23:16:45 +08:00
{
1999-02-08 02:34:16 +08:00
gint32 b3 , b2 ;
1999-02-07 23:16:45 +08:00
v = * ( tbd + + ) ;
tbd + + ;
1999-02-08 02:34:16 +08:00
b2 = v + b2err ;
b3 = v + b3err ;
b2 = CLAMP0255 ( b2 ) ;
b3 = CLAMP0255 ( b3 ) ;
fputc ( ( ( b3 > > 5 ) < < 5 ) | ( ( b3 > > 5 ) < < 2 ) | ( b2 > > 6 ) , fp ) ;
b2err = b2 - ( ( b2 > > 6 ) * 255 ) / 3 ;
b3err = b3 - ( ( b3 > > 5 ) * 255 ) / 7 ;
1999-02-07 23:16:45 +08:00
}
}
break ;
default :
g_warning ( " UNKNOWN GIMAGE TYPE IN THUMBNAIL SAVE " ) ;
}
fclose ( fp ) ;
}
else /* Error writing thumbnail */
{
return ( FALSE ) ;
}
return ( TRUE ) ;
}
1997-11-25 06:05:25 +08:00
int
1998-06-29 08:24:44 +08:00
file_save ( GimpImage * gimage ,
1997-11-25 06:05:25 +08:00
char * filename ,
1998-10-27 17:26:38 +08:00
char * raw_filename ,
gint mode )
1997-11-25 06:05:25 +08:00
{
PlugInProcDef * file_proc ;
ProcRecord * proc ;
Argument * args ;
Argument * return_vals ;
int return_val ;
int i ;
1998-03-23 07:52:03 +08:00
if ( gimage_active_drawable ( gimage ) = = NULL )
return FALSE ;
1997-11-25 06:05:25 +08:00
1998-10-27 17:26:38 +08:00
file_proc = gimage_get_save_proc ( gimage ) ;
1997-11-25 06:05:25 +08:00
if ( ! file_proc )
file_proc = file_proc_find ( save_procs , raw_filename ) ;
if ( ! file_proc )
return FALSE ;
proc = & file_proc - > db_info ;
args = g_new ( Argument , proc - > num_args ) ;
memset ( args , 0 , ( sizeof ( Argument ) * proc - > num_args ) ) ;
for ( i = 0 ; i < proc - > num_args ; i + + )
args [ i ] . arg_type = proc - > args [ i ] . arg_type ;
1998-10-27 17:26:38 +08:00
args [ 0 ] . value . pdb_int = mode ;
1998-08-22 06:40:17 +08:00
args [ 1 ] . value . pdb_int = pdb_image_to_id ( gimage ) ;
1998-01-22 15:02:57 +08:00
args [ 2 ] . value . pdb_int = drawable_ID ( gimage_active_drawable ( gimage ) ) ;
1997-11-25 06:05:25 +08:00
args [ 3 ] . value . pdb_pointer = filename ;
args [ 4 ] . value . pdb_pointer = raw_filename ;
return_vals = procedural_db_execute ( proc - > name , args ) ;
return_val = ( return_vals [ 0 ] . value . pdb_int = = PDB_SUCCESS ) ;
if ( return_val )
{
/* set this image to clean */
gimage_clean_all ( gimage ) ;
1998-08-25 02:48:06 +08:00
/* these calls must come before the call to gimage_set_filename */
idea_add ( filename ) ;
1998-07-14 06:31:45 +08:00
menus_last_opened_add ( filename ) ;
1998-10-27 17:26:38 +08:00
/* use the same plug-in for this image next time */
1999-02-03 07:34:27 +08:00
/* DISABLED - gets stuck on first saved format... needs
attention - - Adam */
/* gimage_set_save_proc(gimage, file_proc); */
1999-02-08 06:13:10 +08:00
file_save_thumbnail ( gimage , filename ) ;
/* set the image title */
gimp_image_set_filename ( gimage , filename ) ;
/* note: 'filename' may have been free'd by above call! */
1997-11-25 06:05:25 +08:00
}
g_free ( return_vals ) ;
g_free ( args ) ;
1998-07-08 18:29:09 +08:00
1997-11-25 06:05:25 +08:00
return return_val ;
}
1999-02-07 23:16:45 +08:00
/* The readXVThumb function source may be re-used under
the XFree86 - style license . < adam @ gimp . org > */
static guchar *
readXVThumb ( const gchar * fnam ,
gint * w , gint * h ,
gchar * * imginfo /* caller frees if != NULL */ )
1999-02-04 08:53:35 +08:00
{
FILE * fp ;
const gchar * P7_332 = " P7 332 " ;
gchar P7_buf [ 7 ] ;
gchar linebuf [ 200 ] ;
guchar * buf ;
gint twofivefive ;
void * ptr ;
1999-02-07 23:16:45 +08:00
* w = * h = 0 ;
* imginfo = NULL ;
1999-02-04 08:53:35 +08:00
fp = fopen ( fnam , " rb " ) ;
if ( ! fp )
return ( NULL ) ;
fread ( P7_buf , 6 , 1 , fp ) ;
if ( strncmp ( P7_buf , P7_332 , 6 ) ! = 0 )
{
g_warning ( " Thumbnail doesn't have the 'P7 332' header. " ) ;
fclose ( fp ) ;
return ( NULL ) ;
}
/*newline*/
fread ( P7_buf , 1 , 1 , fp ) ;
do
{
ptr = fgets ( linebuf , 199 , fp ) ;
1999-02-07 23:16:45 +08:00
if ( ( strncmp ( linebuf , " #IMGINFO: " , 9 ) = = 0 ) & &
( linebuf [ 9 ] ! = ' \0 ' ) & &
( linebuf [ 9 ] ! = ' \n ' ) )
{
if ( linebuf [ strlen ( linebuf ) - 1 ] = = ' \n ' )
linebuf [ strlen ( linebuf ) - 1 ] = ' \0 ' ;
if ( linebuf [ 9 ] ! = ' \0 ' )
{
if ( * imginfo )
g_free ( * imginfo ) ;
* imginfo = g_strdup ( & linebuf [ 9 ] ) ;
}
}
1999-02-04 08:53:35 +08:00
}
while ( ptr & & linebuf [ 0 ] = = ' # ' ) ; /* keep throwing away comment lines */
1999-02-07 23:16:45 +08:00
if ( ! ptr )
{
/* g_warning("Thumbnail ended - not an image?"); */
fclose ( fp ) ;
return ( NULL ) ;
}
1999-02-04 08:53:35 +08:00
sscanf ( linebuf , " %d %d %d \n " , w , h , & twofivefive ) ;
if ( twofivefive ! = 255 )
{
g_warning ( " Thumbnail is of funky depth. " ) ;
fclose ( fp ) ;
return ( NULL ) ;
}
if ( ( * w ) < 1 | | ( * h ) < 1 | | ( * w ) > 80 | | ( * h ) > 60 )
{
g_warning ( " Thumbnail size bad. Corrupted? " ) ;
fclose ( fp ) ;
return ( NULL ) ;
}
buf = g_malloc ( ( * w ) * ( * h ) ) ;
fread ( buf , ( * w ) * ( * h ) , 1 , fp ) ;
fclose ( fp ) ;
return ( buf ) ;
}
1999-02-23 08:18:24 +08:00
/* don't call with preview_fullname as parameter! will be clobbered! */
1999-02-04 08:53:35 +08:00
static void
1999-02-08 06:13:10 +08:00
set_preview ( const gchar * fullfname )
1999-02-04 08:53:35 +08:00
{
guchar * thumb_rgb ;
guchar * raw_thumb ;
1999-02-07 23:16:45 +08:00
gint tnw , tnh ;
gchar * pname ;
gchar * fname ;
gchar * tname ;
gchar * imginfo ;
struct stat file_stat ;
struct stat thumb_stat ;
gboolean thumb_may_be_outdated = FALSE ;
1999-02-23 08:18:24 +08:00
gboolean show_generate_label = TRUE ;
1999-02-07 23:16:45 +08:00
1999-02-08 06:13:10 +08:00
pname = g_dirname ( fullfname ) ;
fname = g_basename ( fullfname ) ; /* Don't free this! */
1999-02-04 08:53:35 +08:00
tname = g_strconcat ( pname , G_DIR_SEPARATOR_S , " .xvpics " , G_DIR_SEPARATOR_S ,
fname ,
NULL ) ;
g_free ( pname ) ;
1999-02-07 23:16:45 +08:00
/* If the file is newer than its thumbnail, the thumbnail may
be out of date . */
1999-02-08 06:13:10 +08:00
if ( ( stat ( tname , & thumb_stat ) = = 0 ) & &
( stat ( fullfname , & file_stat ) = = 0 ) )
1999-02-07 23:16:45 +08:00
{
if ( ( thumb_stat . st_mtime ) < ( file_stat . st_mtime ) )
{
thumb_may_be_outdated = TRUE ;
}
}
1999-02-04 08:53:35 +08:00
1999-02-07 23:16:45 +08:00
raw_thumb = readXVThumb ( tname , & tnw , & tnh , & imginfo ) ;
1999-02-08 06:13:10 +08:00
1999-02-04 08:53:35 +08:00
g_free ( tname ) ;
1999-02-07 23:16:45 +08:00
gtk_frame_set_label ( GTK_FRAME ( open_options_frame ) ,
fname ) ;
1999-02-23 08:18:24 +08:00
1999-02-08 06:13:10 +08:00
if ( preview_fullname )
1999-02-23 08:18:24 +08:00
{
g_free ( preview_fullname ) ;
}
1999-02-08 06:13:10 +08:00
preview_fullname = g_strdup ( fullfname ) ;
1999-02-07 23:16:45 +08:00
1999-02-04 08:53:35 +08:00
if ( raw_thumb )
{
int i ;
thumb_rgb = g_malloc ( 3 * tnw * tnh ) ;
for ( i = 0 ; i < tnw * tnh ; i + + )
{
thumb_rgb [ i * 3 ] = ( ( raw_thumb [ i ] > > 5 ) * 255 ) / 7 ;
thumb_rgb [ i * 3 + 1 ] = ( ( ( raw_thumb [ i ] > > 2 ) & 7 ) * 255 ) / 7 ;
thumb_rgb [ i * 3 + 2 ] = ( ( ( raw_thumb [ i ] ) & 3 ) * 255 ) / 3 ;
}
gtk_preview_size ( open_options_preview , tnw , tnh ) ;
for ( i = 0 ; i < tnh ; i + + )
{
gtk_preview_draw_row ( open_options_preview , & thumb_rgb [ 3 * i * tnw ] ,
0 , i ,
tnw ) ;
}
1999-02-08 06:13:10 +08:00
gtk_label_set_text ( GTK_LABEL ( open_options_label ) ,
thumb_may_be_outdated ?
" (this thumbnail may be out of date) " :
( imginfo ? imginfo : " (no information) " ) ) ;
gtk_widget_show ( GTK_WIDGET ( open_options_preview ) ) ;
gtk_widget_queue_draw ( GTK_WIDGET ( open_options_preview ) ) ;
1999-02-23 08:18:24 +08:00
show_generate_label = FALSE ;
1999-02-04 08:53:35 +08:00
g_free ( thumb_rgb ) ;
g_free ( raw_thumb ) ;
}
else
{
1999-02-07 23:16:45 +08:00
if ( imginfo )
g_free ( imginfo ) ;
1999-02-08 06:13:10 +08:00
gtk_widget_hide ( GTK_WIDGET ( open_options_preview ) ) ;
1999-02-04 08:53:35 +08:00
gtk_label_set_text ( GTK_LABEL ( open_options_label ) ,
" no preview available " ) ;
}
1999-02-08 06:13:10 +08:00
1999-02-23 08:18:24 +08:00
if ( show_generate_label )
{
gtk_widget_hide ( GTK_WIDGET ( open_options_preview ) ) ;
gtk_widget_show ( GTK_WIDGET ( open_options_genbuttonlabel ) ) ;
}
1999-02-08 06:13:10 +08:00
else
1999-02-23 08:18:24 +08:00
{
gtk_widget_hide ( GTK_WIDGET ( open_options_genbuttonlabel ) ) ;
gtk_widget_show ( GTK_WIDGET ( open_options_preview ) ) ;
}
1999-02-08 06:13:10 +08:00
}
static void
file_open_clistrow_callback ( GtkWidget * w ,
int client_data )
{
gchar * fullfname = NULL ;
fullfname = gtk_file_selection_get_filename ( GTK_FILE_SELECTION ( fileload ) ) ;
1999-02-23 08:18:24 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( open_options_frame ) , TRUE ) ;
1999-02-08 06:13:10 +08:00
set_preview ( fullfname ) ;
}
static void
genbutton_callback ( GtkWidget * w ,
gpointer client_data )
{
GimpImage * gimage_to_be_thumbed ;
1999-02-23 08:18:24 +08:00
gchar * filename ;
1999-02-08 06:13:10 +08:00
if ( ! preview_fullname )
{
g_warning ( " Tried to generate thumbnail for NULL filename. " ) ;
return ;
}
1999-02-23 08:18:24 +08:00
filename = g_strdup ( preview_fullname ) ;
1999-02-08 06:13:10 +08:00
gimp_add_busy_cursors ( ) ;
gtk_widget_set_sensitive ( GTK_WIDGET ( fileload ) , FALSE ) ;
1999-02-23 08:18:24 +08:00
if ( ( gimage_to_be_thumbed = file_open_image ( filename ,
g_basename ( filename ) ,
RUN_NONINTERACTIVE ) ) )
1999-02-08 06:13:10 +08:00
{
1999-02-23 08:18:24 +08:00
file_save_thumbnail ( gimage_to_be_thumbed , filename ) ;
set_preview ( filename ) ;
1999-02-08 06:13:10 +08:00
gimage_delete ( gimage_to_be_thumbed ) ;
}
1999-02-23 08:18:24 +08:00
else
{
gtk_label_set_text ( GTK_LABEL ( open_options_label ) ,
" (could not make preview) " ) ;
}
1999-02-08 06:13:10 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( fileload ) , TRUE ) ;
gimp_remove_busy_cursors ( NULL ) ;
1999-02-23 08:18:24 +08:00
g_free ( filename ) ;
1999-02-04 08:53:35 +08:00
}
1997-11-25 06:05:25 +08:00
static void
file_open_ok_callback ( GtkWidget * w ,
gpointer client_data )
{
GtkFileSelection * fs ;
1998-07-18 23:25:52 +08:00
char * filename , * raw_filename , * mfilename ;
gchar * filedirname ;
1997-11-25 06:05:25 +08:00
struct stat buf ;
int err ;
GString * s ;
fs = GTK_FILE_SELECTION ( client_data ) ;
filename = gtk_file_selection_get_filename ( fs ) ;
raw_filename = gtk_entry_get_text ( GTK_ENTRY ( fs - > selection_entry ) ) ;
g_assert ( filename & & raw_filename ) ;
1997-12-14 15:54:37 +08:00
if ( strlen ( raw_filename ) = = 0 )
return ;
1997-11-25 06:05:25 +08:00
err = stat ( filename , & buf ) ;
if ( err = = 0 & & ( buf . st_mode & S_IFDIR ) )
{
GString * s = g_string_new ( filename ) ;
1999-02-21 07:20:54 +08:00
if ( s - > str [ s - > len - 1 ] ! = G_DIR_SEPARATOR )
1997-11-25 06:05:25 +08:00
{
1999-02-21 07:20:54 +08:00
g_string_append_c ( s , G_DIR_SEPARATOR ) ;
1997-11-25 06:05:25 +08:00
}
gtk_file_selection_set_filename ( fs , s - > str ) ;
g_string_free ( s , TRUE ) ;
return ;
}
1998-05-04 11:21:54 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( fs ) , FALSE ) ;
1998-05-16 14:37:14 +08:00
if ( err )
filename = raw_filename ;
1997-11-25 06:05:25 +08:00
if ( file_open ( filename , raw_filename ) )
{
file_dialog_hide ( client_data ) ;
1998-05-04 11:21:54 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( fs ) , TRUE ) ;
1998-07-18 23:25:52 +08:00
}
else
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
s = g_string_new ( _ ( " Open failed: " ) ) ;
1998-07-18 23:25:52 +08:00
g_string_append ( s , raw_filename ) ;
1998-07-29 05:11:47 +08:00
FILE_ERR_MESSAGE ( s - > str ) ;
1998-07-18 23:25:52 +08:00
g_string_free ( s , TRUE ) ;
1997-11-25 06:05:25 +08:00
}
1998-07-18 23:25:52 +08:00
/*
* Now deal with multiple selections from the filesel clist
*/
/*
* FIXME : cope with cwd ! = fileselcwd ! = dirname ( filename )
1998-07-18 23:49:22 +08:00
*/
1998-07-18 23:25:52 +08:00
/*
{
HistoryCallbackArg * callback_arg ;
GList * row = fs - > history_list ;
while ( row )
{
callback_arg = row - > data ;
printf ( " (%s) \n " , callback_arg - > directory ) ;
row = g_list_next ( row ) ;
}
} */
/* filedirname = fs->history_list->data;*/
filedirname = g_dirname ( filename ) ;
{
GList * row = GTK_CLIST ( fs - > file_list ) - > row_list ;
gint rownum = 0 ;
gchar * temp ;
/*printf("%d\n", GTK_CLIST(fs->file_list)->rows);*/
while ( row )
{
if ( GTK_CLIST_ROW ( row ) - > state = = GTK_STATE_SELECTED )
{
if ( gtk_clist_get_cell_type ( GTK_CLIST ( fs - > file_list ) ,
rownum , 0 ) = = GTK_CELL_TEXT )
{
gtk_clist_get_text ( GTK_CLIST ( fs - > file_list ) ,
rownum , 0 , & temp ) ;
/*printf("%s\n", temp);*/
/* When doing multiple selections, the name
* of the first item touched with the cursor will
* become the text - field default - and we don ' t
* want to load that twice .
*/
/*printf("[%s]{%s}\n", temp, raw_filename);*/
/* fflush(stdout);*/
if ( strcmp ( temp , raw_filename ) = = 0 )
{
goto next_iter ;
}
mfilename = g_strdup ( temp ) ;
err = stat ( mfilename , & buf ) ;
if ( ! ( err = = 0 & & ( buf . st_mode & S_IFDIR ) ) )
{ /* Is not directory. */
if ( err )
{
g_free ( mfilename ) ;
1999-02-08 06:13:10 +08:00
mfilename = g_strconcat ( filedirname ,
G_DIR_SEPARATOR_S ,
temp , NULL ) ;
1998-07-18 23:25:52 +08:00
1998-07-18 23:49:22 +08:00
/*printf(">>> %s\n", mfilename);*/
1998-07-18 23:25:52 +08:00
/*fflush (stdout);*/
}
if ( file_open ( mfilename , temp ) )
{
file_dialog_hide ( client_data ) ;
gtk_widget_set_sensitive ( GTK_WIDGET ( fs ) , TRUE ) ;
}
else
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
s = g_string_new ( _ ( " Open failed: " ) ) ;
1998-07-18 23:25:52 +08:00
g_string_append ( s , temp ) ;
1998-07-29 05:11:47 +08:00
FILE_ERR_MESSAGE ( s - > str ) ;
1998-07-18 23:25:52 +08:00
g_string_free ( s , TRUE ) ;
}
}
if ( mfilename )
{
g_free ( mfilename ) ;
mfilename = NULL ;
}
}
}
next_iter :
rownum + + ;
row = g_list_next ( row ) ;
}
/*fflush(stdout);*/
}
if ( filedirname )
{
g_free ( filedirname ) ;
filedirname = NULL ;
}
1997-11-25 06:05:25 +08:00
}
static void
file_save_ok_callback ( GtkWidget * w ,
gpointer client_data )
{
GtkFileSelection * fs ;
char * filename , * raw_filename ;
GString * s ;
struct stat buf ;
int err ;
fs = GTK_FILE_SELECTION ( client_data ) ;
filename = gtk_file_selection_get_filename ( fs ) ;
raw_filename = gtk_entry_get_text ( GTK_ENTRY ( fs - > selection_entry ) ) ;
err = stat ( filename , & buf ) ;
g_assert ( filename & & raw_filename ) ;
if ( err = = 0 )
{
if ( buf . st_mode & S_IFDIR )
{
GString * s = g_string_new ( filename ) ;
1999-02-21 07:20:54 +08:00
g_string_append_c ( s , G_DIR_SEPARATOR ) ;
1997-11-25 06:05:25 +08:00
gtk_file_selection_set_filename ( fs , s - > str ) ;
g_string_free ( s , TRUE ) ;
return ;
}
else if ( buf . st_mode & S_IFREG )
{
1998-05-07 06:20:43 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( fs ) , FALSE ) ;
1997-11-25 06:05:25 +08:00
file_overwrite ( g_strdup ( filename ) , g_strdup ( raw_filename ) ) ;
return ;
}
else
{
s = g_string_new ( NULL ) ;
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
g_string_sprintf ( s , _ ( " %s is an irregular file (%s) " ) , raw_filename , g_strerror ( errno ) ) ;
1997-11-25 06:05:25 +08:00
}
1998-05-04 11:21:54 +08:00
} else {
1998-05-07 06:20:43 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( fs ) , FALSE ) ;
1998-10-27 17:26:38 +08:00
gimage_set_save_proc ( the_gimage , save_file_proc ) ;
if ( file_save ( the_gimage , filename , raw_filename , 0 ) )
1998-05-04 11:21:54 +08:00
{
file_dialog_hide ( client_data ) ;
gtk_widget_set_sensitive ( GTK_WIDGET ( fs ) , TRUE ) ;
return ;
}
else
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
s = g_string_new ( _ ( " Save failed: " ) ) ;
1998-05-04 11:21:54 +08:00
g_string_append ( s , raw_filename ) ;
}
1997-11-25 06:05:25 +08:00
}
1998-07-29 05:11:47 +08:00
FILE_ERR_MESSAGE ( s - > str ) ;
1997-11-25 06:05:25 +08:00
g_string_free ( s , TRUE ) ;
}
static void
file_dialog_show ( GtkWidget * filesel )
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
menus_set_sensitive ( _ ( " <Toolbox>/File/Open " ) , FALSE ) ;
menus_set_sensitive ( _ ( " <Image>/File/Open " ) , FALSE ) ;
menus_set_sensitive ( _ ( " <Image>/File/Save " ) , FALSE ) ;
menus_set_sensitive ( _ ( " <Image>/File/Save as " ) , FALSE ) ;
1997-11-25 06:05:25 +08:00
gtk_widget_show ( filesel ) ;
}
1998-03-15 10:46:15 +08:00
static int
1997-11-25 06:05:25 +08:00
file_dialog_hide ( GtkWidget * filesel )
{
gtk_widget_hide ( filesel ) ;
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
menus_set_sensitive ( _ ( " <Toolbox>/File/Open " ) , TRUE ) ;
menus_set_sensitive ( _ ( " <Image>/File/Open " ) , TRUE ) ;
menus_set_sensitive ( _ ( " <Image>/File/Save " ) , TRUE ) ;
menus_set_sensitive ( _ ( " <Image>/File/Save as " ) , TRUE ) ;
1998-03-15 10:46:15 +08:00
return TRUE ;
1997-11-25 06:05:25 +08:00
}
static void
file_overwrite ( char * filename , char * raw_filename )
{
static ActionAreaItem obox_action_items [ 2 ] =
{
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
{ N_ ( " Yes " ) , file_overwrite_yes_callback , NULL , NULL } ,
{ N_ ( " No " ) , file_overwrite_no_callback , NULL , NULL }
1997-11-25 06:05:25 +08:00
} ;
OverwriteBox * overwrite_box ;
GtkWidget * vbox ;
GtkWidget * label ;
char * overwrite_text ;
overwrite_box = ( OverwriteBox * ) g_malloc ( sizeof ( OverwriteBox ) ) ;
1998-12-26 02:22:01 +08:00
overwrite_text = g_strdup_printf ( _ ( " %s exists, overwrite? " ) , filename ) ;
1997-11-25 06:05:25 +08:00
overwrite_box - > full_filename = filename ;
overwrite_box - > raw_filename = raw_filename ;
overwrite_box - > obox = gtk_dialog_new ( ) ;
1998-03-25 12:34:43 +08:00
gtk_window_set_wmclass ( GTK_WINDOW ( overwrite_box - > obox ) , " file_exists " , " Gimp " ) ;
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
gtk_window_set_title ( GTK_WINDOW ( overwrite_box - > obox ) , _ ( " File Exists! " ) ) ;
1998-12-04 07:01:44 +08:00
gtk_window_set_position ( GTK_WINDOW ( overwrite_box - > obox ) , GTK_WIN_POS_MOUSE ) ;
1997-11-25 06:05:25 +08:00
1998-03-13 06:01:43 +08:00
gtk_signal_connect ( GTK_OBJECT ( overwrite_box - > obox ) ,
" delete_event " ,
1997-11-25 06:05:25 +08:00
( GtkSignalFunc ) file_overwrite_delete_callback ,
overwrite_box ) ;
vbox = gtk_vbox_new ( FALSE , 1 ) ;
1998-12-04 07:01:44 +08:00
gtk_container_set_border_width ( GTK_CONTAINER ( vbox ) , 1 ) ;
1997-11-25 06:05:25 +08:00
gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG ( overwrite_box - > obox ) - > vbox ) , vbox , TRUE , TRUE , 0 ) ;
label = gtk_label_new ( overwrite_text ) ;
gtk_box_pack_start ( GTK_BOX ( vbox ) , label , TRUE , FALSE , 0 ) ;
obox_action_items [ 0 ] . user_data = overwrite_box ;
obox_action_items [ 1 ] . user_data = overwrite_box ;
build_action_area ( GTK_DIALOG ( overwrite_box - > obox ) , obox_action_items , 2 , 0 ) ;
gtk_widget_show ( label ) ;
gtk_widget_show ( vbox ) ;
gtk_widget_show ( overwrite_box - > obox ) ;
g_free ( overwrite_text ) ;
}
static void
file_overwrite_yes_callback ( GtkWidget * w ,
gpointer client_data )
{
OverwriteBox * overwrite_box ;
GImage * gimage ;
overwrite_box = ( OverwriteBox * ) client_data ;
1998-05-14 12:26:28 +08:00
gtk_widget_destroy ( overwrite_box - > obox ) ;
1998-06-29 08:24:44 +08:00
if ( ( gimage = the_gimage ) ! = NULL & &
1998-10-27 17:26:38 +08:00
file_save ( the_gimage , overwrite_box - > full_filename , overwrite_box - > raw_filename , 0 ) )
1997-11-25 06:05:25 +08:00
{
1998-06-29 08:24:44 +08:00
the_gimage = NULL ;
1997-11-25 06:05:25 +08:00
file_dialog_hide ( filesave ) ;
}
else
{
GString * s ;
1998-07-29 05:11:47 +08:00
GtkWidget * fs ;
1997-11-25 06:05:25 +08:00
1998-07-29 05:11:47 +08:00
fs = filesave ;
Lots of ii8n stuff here and some additions to the de.po. Applied
Wed Oct 14 17:46:15 EDT 1998 Adrian Likins <adrian@gimp.org>
* app/*, po/de.po, de/POTFILES.in, libgimp/gimpintl.h:
Lots of ii8n stuff here and some additions to the de.po.
Applied gimp-egger-981005-1 ,gimp-egger-981006-1,
gimp-egger-981007-1, gimp-egger-981008-1,
gimp-egger-981009-1.patch, gimp-egger-981010-1.patch
* plug-in/guillotine/guillotine.c: added the coordinates
of the split images from the original image to the title.
ie foo.jpg (0,0) for the image in the topleft.
* plug-in/script-fu/scripts/neon-logo.scm,
perspective-shadow.scm, predator.scm,rendermap.scm,
ripply-anim.scm, select_to_image.scm,swirltile.scm,
xach-effect.scm: updated scripts to use new script-fu stuff
wooo boy! a big un!
in testing this, it looks like some of the po files are busted.
but the code stuff seems okay.
-adrian
1998-10-15 07:23:52 +08:00
s = g_string_new ( _ ( " Save failed: " ) ) ;
1997-11-25 06:05:25 +08:00
g_string_append ( s , overwrite_box - > raw_filename ) ;
1998-07-29 05:11:47 +08:00
FILE_ERR_MESSAGE ( s - > str ) ;
1997-11-25 06:05:25 +08:00
g_string_free ( s , TRUE ) ;
}
g_free ( overwrite_box - > full_filename ) ;
g_free ( overwrite_box - > raw_filename ) ;
g_free ( overwrite_box ) ;
}
static gint
file_overwrite_delete_callback ( GtkWidget * w ,
GdkEvent * e ,
gpointer client_data )
{
file_overwrite_no_callback ( w , client_data ) ;
1998-03-13 06:01:43 +08:00
return TRUE ;
1997-11-25 06:05:25 +08:00
}
static void
file_overwrite_no_callback ( GtkWidget * w ,
gpointer client_data )
{
OverwriteBox * overwrite_box ;
overwrite_box = ( OverwriteBox * ) client_data ;
gtk_widget_destroy ( overwrite_box - > obox ) ;
g_free ( overwrite_box - > full_filename ) ;
g_free ( overwrite_box - > raw_filename ) ;
g_free ( overwrite_box ) ;
1998-05-04 19:16:19 +08:00
gtk_widget_set_sensitive ( GTK_WIDGET ( filesave ) , TRUE ) ;
1997-11-25 06:05:25 +08:00
}
static PlugInProcDef *
file_proc_find ( GSList * procs ,
char * filename )
{
PlugInProcDef * file_proc , * size_matched_proc ;
GSList * all_procs = procs ;
GSList * extensions ;
GSList * prefixes ;
char * extension ;
char * p1 , * p2 ;
FILE * ifp = NULL ;
int head_size = - 2 , size_match_count = 0 ;
int match_val ;
unsigned char head [ 256 ] ;
size_matched_proc = NULL ;
extension = strrchr ( filename , ' . ' ) ;
if ( extension )
extension + = 1 ;
/* At first look for magics */
while ( procs )
{
file_proc = procs - > data ;
procs = procs - > next ;
if ( file_proc - > magics_list )
{
if ( head_size = = - 2 )
{
head_size = 0 ;
if ( ( ifp = fopen ( filename , " rb " ) ) ! = NULL )
head_size = fread ( ( char * ) head , 1 , sizeof ( head ) , ifp ) ;
}
if ( head_size > = 4 )
{
match_val = file_check_magic_list ( file_proc - > magics_list ,
head_size , head , ifp ) ;
if ( match_val = = 2 ) /* size match ? */
{ /* Use it only if no other magic matches */
size_match_count + + ;
size_matched_proc = file_proc ;
}
else if ( match_val )
{
fclose ( ifp ) ;
return ( file_proc ) ;
}
}
}
}
if ( ifp ) fclose ( ifp ) ;
if ( size_match_count = = 1 ) return ( size_matched_proc ) ;
procs = all_procs ;
while ( procs )
{
file_proc = procs - > data ;
procs = procs - > next ;
for ( prefixes = file_proc - > prefixes_list ; prefixes ; prefixes = prefixes - > next )
{
p1 = filename ;
p2 = ( char * ) prefixes - > data ;
if ( strncmp ( filename , prefixes - > data , strlen ( prefixes - > data ) ) = = 0 )
return file_proc ;
}
1998-05-16 14:37:14 +08:00
}
procs = all_procs ;
while ( procs )
{
file_proc = procs - > data ;
procs = procs - > next ;
1997-11-25 06:05:25 +08:00
for ( extensions = file_proc - > extensions_list ; extension & & extensions ; extensions = extensions - > next )
{
p1 = extension ;
p2 = ( char * ) extensions - > data ;
while ( * p1 & & * p2 )
{
if ( tolower ( * p1 ) ! = tolower ( * p2 ) )
break ;
p1 + = 1 ;
p2 + = 1 ;
}
if ( ! ( * p1 ) & & ! ( * p2 ) )
return file_proc ;
}
}
return NULL ;
}
static void file_convert_string ( char * instr ,
char * outmem ,
int maxmem ,
int * nmem )
{ /* Convert a string in C-notation to array of char */
unsigned char * uin = ( unsigned char * ) instr ;
unsigned char * uout = ( unsigned char * ) outmem ;
unsigned char tmp [ 5 ] , * tmpptr ;
int k ;
while ( ( * uin ! = ' \0 ' ) & & ( ( ( ( char * ) uout ) - outmem ) < maxmem ) )
{
if ( * uin ! = ' \\ ' ) /* Not an escaped character ? */
{
* ( uout + + ) = * ( uin + + ) ;
continue ;
}
if ( * ( + + uin ) = = ' \0 ' )
{
* ( uout + + ) = ' \\ ' ;
break ;
}
switch ( * uin )
{
case ' 0 ' : case ' 1 ' : case ' 2 ' : case ' 3 ' : /* octal */
for ( tmpptr = tmp ; ( tmpptr - tmp ) < = 3 ; )
{
* ( tmpptr + + ) = * ( uin + + ) ;
if ( ( * uin = = ' \0 ' ) | | ( ! isdigit ( * uin ) )
| | ( * uin = = ' 8 ' ) | | ( * uin = = ' 9 ' ) )
break ;
}
* tmpptr = ' \0 ' ;
1998-03-19 06:35:31 +08:00
sscanf ( ( char * ) tmp , " %o " , & k ) ;
1997-11-25 06:05:25 +08:00
* ( uout + + ) = k ;
break ;
case ' a ' : * ( uout + + ) = ' \a ' ; uin + + ; break ;
case ' b ' : * ( uout + + ) = ' \b ' ; uin + + ; break ;
case ' t ' : * ( uout + + ) = ' \t ' ; uin + + ; break ;
case ' n ' : * ( uout + + ) = ' \n ' ; uin + + ; break ;
case ' v ' : * ( uout + + ) = ' \v ' ; uin + + ; break ;
case ' f ' : * ( uout + + ) = ' \f ' ; uin + + ; break ;
case ' r ' : * ( uout + + ) = ' \r ' ; uin + + ; break ;
default : * ( uout + + ) = * ( uin + + ) ; break ;
}
}
* nmem = ( ( char * ) uout ) - outmem ;
}
static int
file_check_single_magic ( char * offset ,
char * type ,
char * value ,
int headsize ,
unsigned char * file_head ,
FILE * ifp )
{ /* Return values are 0: no match, 1: magic match, 2: size match */
long offs ;
unsigned long num_testval , num_operatorval ;
unsigned long fileval ;
int numbytes , k , c = 0 , found = 0 ;
char * num_operator_ptr , num_operator , num_test ;
unsigned char mem_testval [ 256 ] ;
/* Check offset */
if ( sscanf ( offset , " %ld " , & offs ) ! = 1 ) return ( 0 ) ;
if ( offs < 0 ) return ( 0 ) ;
/* Check type of test */
num_operator_ptr = NULL ;
num_operator = ' \0 ' ;
num_test = ' = ' ;
if ( strncmp ( type , " byte " , 4 ) = = 0 )
{
numbytes = 1 ;
num_operator_ptr = type + 4 ;
}
else if ( strncmp ( type , " short " , 5 ) = = 0 )
{
numbytes = 2 ;
num_operator_ptr = type + 5 ;
}
else if ( strncmp ( type , " long " , 4 ) = = 0 )
{
numbytes = 4 ;
num_operator_ptr = type + 4 ;
}
else if ( strncmp ( type , " size " , 4 ) = = 0 )
{
numbytes = 5 ;
}
else if ( strcmp ( type , " string " ) = = 0 )
{
numbytes = 0 ;
}
else return ( 0 ) ;
/* Check numerical operator value if present */
if ( num_operator_ptr & & ( * num_operator_ptr = = ' & ' ) )
{
if ( isdigit ( num_operator_ptr [ 1 ] ) )
{
if ( num_operator_ptr [ 1 ] ! = ' 0 ' ) /* decimal */
sscanf ( num_operator_ptr + 1 , " %ld " , & num_operatorval ) ;
else if ( num_operator_ptr [ 2 ] = = ' x ' ) /* hexadecimal */
sscanf ( num_operator_ptr + 3 , " %lx " , & num_operatorval ) ;
else /* octal */
sscanf ( num_operator_ptr + 2 , " %lo " , & num_operatorval ) ;
num_operator = * num_operator_ptr ;
}
}
if ( numbytes > 0 ) /* Numerical test ? */
{
/* Check test value */
if ( ( value [ 0 ] = = ' = ' ) | | ( value [ 0 ] = = ' > ' ) | | ( value [ 0 ] = = ' < ' ) )
{
num_test = value [ 0 ] ;
value + + ;
}
if ( ! isdigit ( value [ 0 ] ) ) return ( 0 ) ;
if ( value [ 0 ] ! = ' 0 ' ) /* decimal */
num_testval = strtol ( value , NULL , 10 ) ;
else if ( value [ 1 ] = = ' x ' ) /* hexadecimal */
num_testval = strtol ( value + 2 , NULL , 16 ) ;
else /* octal */
num_testval = strtol ( value + 1 , NULL , 8 ) ;
1998-05-04 11:21:54 +08:00
1997-11-25 06:05:25 +08:00
fileval = 0 ;
if ( numbytes = = 5 ) /* Check for file size ? */
{ struct stat buf ;
if ( fstat ( fileno ( ifp ) , & buf ) < 0 ) return ( 0 ) ;
fileval = buf . st_size ;
}
else if ( offs + numbytes < = headsize ) /* We have it in memory ? */
{
for ( k = 0 ; k < numbytes ; k + + )
fileval = ( fileval < < 8 ) | ( long ) file_head [ offs + k ] ;
}
else /* Read it from file */
{
if ( fseek ( ifp , offs , SEEK_SET ) < 0 ) return ( 0 ) ;
for ( k = 0 ; k < numbytes ; k + + )
fileval = ( fileval < < 8 ) | ( c = getc ( ifp ) ) ;
if ( c = = EOF ) return ( 0 ) ;
}
if ( num_operator = = ' & ' )
fileval & = num_operatorval ;
if ( num_test = = ' < ' )
found = ( fileval < num_testval ) ;
else if ( num_test = = ' > ' )
found = ( fileval > num_testval ) ;
else
found = ( fileval = = num_testval ) ;
if ( found & & ( numbytes = = 5 ) ) found = 2 ;
}
else if ( numbytes = = 0 ) /* String test */
{
file_convert_string ( ( char * ) value , ( char * ) mem_testval ,
sizeof ( mem_testval ) , & numbytes ) ;
if ( numbytes < = 0 ) return ( 0 ) ;
if ( offs + numbytes < = headsize ) /* We have it in memory ? */
{
found = ( memcmp ( mem_testval , file_head + offs , numbytes ) = = 0 ) ;
}
else /* Read it from file */
{
if ( fseek ( ifp , offs , SEEK_SET ) < 0 ) return ( 0 ) ;
found = 1 ;
for ( k = 0 ; found & & ( k < numbytes ) ; k + + )
{
c = getc ( ifp ) ;
found = ( c ! = EOF ) & & ( c = = ( int ) mem_testval [ k ] ) ;
}
}
}
return ( found ) ;
}
static int file_check_magic_list ( GSList * magics_list ,
int headsize ,
unsigned char * head ,
FILE * ifp )
{ /* Return values are 0: no match, 1: magic match, 2: size match */
char * offset , * type , * value ;
int and = 0 ;
int found = 0 , match_val ;
while ( magics_list )
{
if ( ( offset = ( char * ) magics_list - > data ) = = NULL ) break ;
1998-05-04 11:21:54 +08:00
if ( ( magics_list = magics_list - > next ) = = NULL ) break ;
1997-11-25 06:05:25 +08:00
if ( ( type = ( char * ) magics_list - > data ) = = NULL ) break ;
1998-05-04 11:21:54 +08:00
if ( ( magics_list = magics_list - > next ) = = NULL ) break ;
1997-11-25 06:05:25 +08:00
if ( ( value = ( char * ) magics_list - > data ) = = NULL ) break ;
1998-05-04 11:21:54 +08:00
magics_list = magics_list - > next ;
1997-11-25 06:05:25 +08:00
match_val = file_check_single_magic ( offset , type , value ,
headsize , head , ifp ) ;
if ( and )
found = found & & match_val ;
else
found = match_val ;
and = ( strchr ( offset , ' & ' ) ! = NULL ) ;
if ( ( ! and ) & & found ) return ( match_val ) ;
}
return ( 0 ) ;
}
static void
file_update_menus ( GSList * procs ,
int image_type )
{
PlugInProcDef * file_proc ;
while ( procs )
{
file_proc = procs - > data ;
procs = procs - > next ;
if ( file_proc - > db_info . proc_type ! = PDB_EXTENSION )
1998-12-26 02:22:01 +08:00
menus_set_sensitive ( gettext ( file_proc - > menu_path ) , ( file_proc - > image_types_val & image_type ) ) ;
1997-11-25 06:05:25 +08:00
}
}
static Argument *
file_load_invoker ( Argument * args )
{
PlugInProcDef * file_proc ;
ProcRecord * proc ;
file_proc = file_proc_find ( load_procs , args [ 2 ] . value . pdb_pointer ) ;
if ( ! file_proc )
return procedural_db_return_args ( & file_load_proc , FALSE ) ;
proc = & file_proc - > db_info ;
return procedural_db_execute ( proc - > name , args ) ;
}
static Argument *
file_save_invoker ( Argument * args )
{
Argument * new_args ;
Argument * return_vals ;
PlugInProcDef * file_proc ;
ProcRecord * proc ;
int i ;
file_proc = file_proc_find ( save_procs , args [ 4 ] . value . pdb_pointer ) ;
if ( ! file_proc )
return procedural_db_return_args ( & file_save_proc , FALSE ) ;
proc = & file_proc - > db_info ;
new_args = g_new ( Argument , proc - > num_args ) ;
memset ( new_args , 0 , ( sizeof ( Argument ) * proc - > num_args ) ) ;
for ( i = 0 ; i < proc - > num_args ; i + + )
new_args [ i ] . arg_type = proc - > args [ i ] . arg_type ;
memcpy ( new_args , args , ( sizeof ( Argument ) * 5 ) ) ;
return_vals = procedural_db_execute ( proc - > name , new_args ) ;
g_free ( new_args ) ;
1998-05-04 11:21:54 +08:00
return return_vals ;
1997-11-25 06:05:25 +08:00
}
static Argument *
file_temp_name_invoker ( Argument * args )
{
static gint id = 0 ;
static gint pid ;
Argument * return_args ;
GString * s = g_string_new ( NULL ) ;
if ( id = = 0 )
pid = getpid ( ) ;
1999-02-21 07:20:54 +08:00
g_string_sprintf ( s , " %s " G_DIR_SEPARATOR_S " gimp_temp.%d%d.%s " ,
temp_path , pid , id + + , ( char * ) args [ 0 ] . value . pdb_pointer ) ;
1997-11-25 06:05:25 +08:00
return_args = procedural_db_return_args ( & file_temp_name_proc , TRUE ) ;
return_args [ 1 ] . value . pdb_pointer = s - > str ;
g_string_free ( s , FALSE ) ;
return return_args ;
}