1 
2 /*
3  *  Ump - Unnamed Math Program
4  *  Copyright (c) 2003-2006 by Mattias Hultgren <mattias_hultgren@tele2.se>
5  *
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; version 2 of the License.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public
17  *   License along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  */
20 
21 #include "main.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26 #include "utf8_string.h"
27 #include "math2.h"
28 #include "vector.h"
29 #include "addon_functions.h"
30 #ifndef NO_GTK
31 	#include <locale.h>
32 #endif
33 #include "ump_3d_viewer.h"
34 
35 
36 extern "C"
37 {
38 	extern char *translation_svenska;
39 }
40 
41 #define GET_BOOLEAN_KEY( KEY, DEST )    if((str = setup_file.get_key( KEY )) != 0) \
42                                         { \
43                                           if( *str == "True" ) \
44                                             DEST = true; \
45                                           else if( *str == "False" ) \
46                                             DEST = false; \
47                                           else \
48                                           { \
49                                             char tmp_err[ERROR_OBJ_MSG_LEN]; \
50                                             snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Invalid format in file %s"), "<Configure file>" ); \
51                                             THROW_ERROR( ErrorType_File_IO, tmp_err ); \
52                                           } \
53                                         }
54 
55 
56 
57 void (*TEXTVIEW_FUNCTION)(const utf8_string &string) = 0;
58 void (*QUIT_FUNCTION)(void) = 0;
59 
60 void term_quit(void);
61 void term_showtext(const utf8_string &string);
62 
63 Format format;
64 math::CodeBlock calc_function;
65 
66 
67 keyfile setup_file;
68 utf8_string language_filename("English");
69 #ifndef NO_GTK
70 	utf8_string default_start_window("");
71 
72 
73 	#include <gtk/gtk.h>
74 	#include "picture2gtk.h"
75 
76 	#include "ump_advancedwin.h"
77 	#include "ump_editor.h"
78 	#include "ump_simplewin.h"
79 	#include "ump_picturewin.h"
80 	#include "ump_graphwin.h"
81 	#include "ump_prefwin.h"
82 	#include "matrix_editor.h"
83 
84 	void build_std_names(void);
85 
86 	uint32 open_windows = 0;
87 
88 	const char *dialog_title_save_as, *dialog_title_open_file;
89 
90 	const char *menu_file, *menu_file_new, *menu_file_open, *menu_file_save,
91 	           *menu_file_save_as, *menu_file_close, *menu_file_quit;
92 	const char *menu_tools, *menu_tools_advanced, *menu_tools_editor, *menu_tools_simple,
93 	           *menu_tools_graphtool, *menu_tools_matrixedit;
94 	const char *menu_about, *menu_pref;
95 
96 	const char *button_ok, *button_cancel, *button_close;
97 
98 	const char *main_file_load, *main_file_clear;
99 	const char *main_options, *main_opt_radian, *main_opt_degree;
100 
101 	const char *edit_edit, *edit_edit_cut, *edit_edit_copy, *edit_edit_paste, *edit_edit_delete,
102 	           *edit_edit_select_all;
103 
104 	const char *filter_ump_files, *filter_all_files, *filter_picture_files, *filter_pcx_files,
105                *filter_ppm_files;
106 
107 	uint32 start_window = ADVANCED_WIN;
108 #endif
109 
110 void save_keyfile(void);
111 void read_keyfile(void);
112 void text_setup_functions( void );
113 
114 void degfix_needs_updating( math::Variable *var );
115 
116 
117 void show_versions(void);
118 
119 
main(int argc,char ** argv)120 int main(int argc, char **argv)
121 {
122 	math::intern_format = &format;
123 
124 	translation.replace_escape_sequences = true;
125 
126 	try
127 	{
128 		math::init();
129 		{
130 			Variable tmpvar;
131 			tmpvar.set_complex( Complex( 0 ) );
132 			tmpvar.set_name( "ans" );
133 			math::global_varlist.create(tmpvar, false, false, true);
134 		}
135 
136 		read_keyfile();
137 		if( math::autoload_directories.get_size() == 0 )
138 		{
139 			utf8_string dir( DATA_DIR "/ump-files" );
140 			math::autoload_directories.append( dir );
141 		}
142 	}
143 	catch(error_obj error)
144 	{
145 		fprintf( stderr, "\n\nFATAL ERROR: %s\n\n", error.msg );
146 		exit(-1);
147 	}
148 
149 
150 	if(argv[1] != 0)
151 	{
152 		if(strcmp(argv[1],"--version") == 0)
153 		{
154 			show_versions();
155 			exit(0);
156 		}
157 		else if(strcmp(argv[1],"--text") == 0)
158 			goto terminal_only;
159 #ifndef NO_GTK
160 		else if(strcmp(argv[1],"--simple") == 0)
161 			start_window = SIMPLE_WIN;
162 		else if(strcmp(argv[1],"--advanced") == 0)
163 			start_window = ADVANCED_WIN;
164 		else if(strcmp(argv[1],"--editor") == 0)
165 			start_window = EDITOR_WIN;
166 		else if(strcmp(argv[1],"--graphtool") == 0)
167 			start_window = GRAPHTOOL_WIN;
168 		else if(strcmp(argv[1],"--matrix-editor") == 0)
169 			start_window = MATRIX_EDITOR_WIN;
170 #endif
171 		else
172 		{ // let's check if it's a ump-filename
173 			char *name_ext = strstr( argv[1], ".ump" );
174 			if( name_ext != 0 )
175 			{
176 				text_setup_functions(); // load add on functions
177 
178 				math::CodeBlock code;
179 				utf8_string str;
180 				Variable res;
181 				try
182 				{
183 					code.set_code_from_file( argv[1] );
184 				}
185 				catch(error_obj error)
186 				{
187 					(*TEXTVIEW_FUNCTION)(error.msg);
188 					(*TEXTVIEW_FUNCTION)("\n");
189 					exit( -1 );
190 				}
191 
192 // Let's get the name of the funtion to call
193 				{
194 					int start, stop;
195 					char tmp[2];
196 					tmp[1] = '\0';
197 
198 					stop = strlen(argv[1]) - 4;
199 
200 					for( start = stop; start != 0 ; start-- )
201 					{
202 						if( argv[1][start] == '/' )
203 						{
204 							start++;
205 							break;
206 						}
207 						if( start == 0 )
208 							break;
209 					}
210 
211 					for( ; start<stop; start++ )
212 					{
213 						tmp[0] = argv[1][start];
214 						str.append( tmp );
215 					}
216 				}
217 // Name lies nice and easy in str
218 
219 				if( argv[2] != 0 )
220 				{
221 					str.append( "(" );
222 
223 					for( int i=2; argv[i] != 0; i++ )
224 					{
225 						if( i != 2 )
226 							str.append( "," );
227 
228 						str.append( argv[i] );
229 					}
230 
231 					str.append( ")" );
232 				}
233 
234 				try
235 				{
236 					code.set_code( str.c_str() );
237 					code.calc( &res );
238 				}
239 				catch( error_obj error )
240 				{
241 					(*TEXTVIEW_FUNCTION)(error.msg);
242 					(*TEXTVIEW_FUNCTION)("\n");
243 					exit( -1 );
244 				}
245 
246 				exit( 0 );
247 			}
248 		}
249 	}
250 
251 
252 #ifndef NO_GTK
253 
254 	if( gtk_init_check( &argc, &argv ) == TRUE )
255 	{
256 		setlocale( LC_NUMERIC, "C" ); // gtk+ changes this...which I don't want
257 		TEXTVIEW_FUNCTION = advancedwin_showtext;
258 		QUIT_FUNCTION = UMP_gtk_quit;
259 
260 		try
261 		{
262 			math::add_function( "quit", addon_quit, false, false );
263 			math::add_function( "exit", addon_quit, false, false );
264 			math::add_function( "view", addon_view, false, true );
265 			math::add_function( "viewall", addon_viewall, false, false );
266 			math::add_function( "show", addon_show, false, true );
267 			math::add_function( "print", addon_print, false,true );
268 			math::add_function( "message", addon_message, false, true );
269 			math::add_function( "menu", addon_menu, false, true );
270 			math::add_function( "input", addon_input, false, true );
271 			math::add_function( "load", addon_load, false, true );
272 			math::add_function( "load_picture", addon_load_picture, false, true );
273 			math::add_function( "save_picture", addon_save_picture, false, true );
274 
275 
276 			_3d_viewer_init();
277 
278 			{
279 				Variable tmpvar;
280 				math::Picture pic;
281 				Matrix matr;
282 
283 				tmpvar.set_picture(&pic);
284 				tmpvar.set_name( "plot_picture" );
285 				math::global_varlist.create( tmpvar, false, false, false );
286 
287 
288 				tmpvar.set_matrix(&matr);
289 				tmpvar.set_name( "plot_x_matrix" );
290 				math::global_varlist.create( tmpvar, false, false, false );
291 				tmpvar.set_name( "plot_y_matrix" );
292 				math::global_varlist.create( tmpvar, false, false, false );
293 #ifdef PLOT_3D
294 				tmpvar.set_name( "plot_z_matrix" );
295 				math::global_varlist.create( tmpvar, false, false, false );
296 #endif
297 
298 				tmpvar.set_complex( Complex( 1 ) );
299 				tmpvar.set_name( "degfix" );
300 				math::global_varlist.create( tmpvar , false, false, false ); // default is radians
301 				tmpvar.set_name( "radian" );
302 				math::global_varlist.create( tmpvar , true, false, false ); // constant
303 				tmpvar.set_complex( Complex( PI/180.0 ) );
304 				tmpvar.set_name( "degree" );
305 				math::global_varlist.create( tmpvar , true, false, false ); // constant
306 
307 				math::global_varlist.get_pointer_rw( math::global_varlist.get_id( "degfix" ) )->
308 				                          set_change_func( degfix_needs_updating );
309 			}
310 		}
311 		catch(error_obj error)
312 		{
313 			fprintf( stderr, "\n\nFATAL ERROR: %s\n\n", error.msg );
314 			exit(-1);
315 		}
316 
317 		switch(start_window)
318 		{
319 		case EDITOR_WIN:
320 			editor_showwin();
321 			break;
322 		case SIMPLE_WIN:
323 			simplewin_show();
324 			break;
325 		case GRAPHTOOL_WIN:
326 			graphwin_show();
327 			break;
328 		case MATRIX_EDITOR_WIN:
329 			matrix_editor_show();
330 			break;
331 		case ADVANCED_WIN:
332 		default:
333 			advancedwin_show();
334 		}
335 
336 		gtk_main();
337 	}
338 	else // gtk failed to start
339 	{
340 #endif
341 terminal_only:
342 		char line[2000];
343 #ifndef NO_GTK
344 		setlocale( LC_NUMERIC, "C" ); // gtk+ changes this...which I don't want
345 #endif
346 
347 		_3d_viewer_init();
348 		text_setup_functions();
349 		{
350 			math::Variable tmpvar;
351 
352 			tmpvar.set_complex( Complex( 1 ) );
353 			tmpvar.set_name( "degfix" );
354 			math::global_varlist.create( tmpvar , false,false,false); // default is radians
355 			tmpvar.set_name( "radian" );
356 			math::global_varlist.create( tmpvar , true,false,false); // constant
357 			tmpvar.set_complex( Complex( PI/180.0 ) );
358 			tmpvar.set_name( "degree" );
359 			math::global_varlist.create( tmpvar , true,false,false); // constant
360 
361 			math::global_varlist.get_pointer_rw( math::global_varlist.get_id( "degfix" ) )->
362 			                         set_change_func( degfix_needs_updating );
363 		}
364 
365 		printf( "\n" PRG_NAME " " PRG_VERSION "\n\n  Copyright (c) " PRG_DATE " Mattias Hultgren\n%s",
366 		        get_start_message() );
367 
368 		{
369 			utf8_string output;
370 
371 			for(;;)
372 			{
373 				printf( "\n> " );
374 				fgets( line, 2000, stdin );
375 				for( int i=0; ; i++ )
376 				{
377 					if( line[i] == 0 )
378 					{
379 						if( i >= 2 )
380 						{
381 							if( line[i-2] == '\n'  ||  line[i-2] == '\r' )
382 								line[i-2] = 0;
383 						}
384 						if( i >= 1 )
385 						{
386 							if( line[i-1] == '\n'  ||  line[i-1] == '\r' )
387 								line[i-1] = 0;
388 						}
389 						break;
390 					}
391 				}
392 				{
393 					int i;
394 					for( i=0; line[i] != '\0'; i++ )
395 					{
396 						if( line[i] != ' '  &&  line[i] != '\t' )
397 							break;
398 					}
399 					if( line[i] == '\0' )
400 						continue;
401 				}
402 				try
403 				{
404 					Variable *varpointer;
405 
406 					varpointer = math::global_varlist.get_pointer_rw( math::global_varlist.get_id("ans") );
407 
408 					calc_function.set_code( line );
409 					calc_function.calc( varpointer );
410 					calc_function.clear();
411 
412 					if( !varpointer->is_void() )
413 					{
414 						output = "";
415 						varpointer->append_to_string( output, format );
416 						printf( "%s\n", output.c_str() );
417 					}
418 				}
419 				catch( error_obj error )
420 				{
421 					printf( "\n  %s\n\n", error.msg );
422 				}
423 			}
424 		}
425 #ifndef NO_GTK
426 	}
427 #endif
428 
429 	{
430 		Variable *tmpvar;
431 		tmpvar = math::global_varlist.get_pointer_rw( math::global_varlist.get_id( "degfix" ) );
432 		tmpvar->set_change_func( 0 );
433 	}
434 	return 0;
435 }
436 
degfix_needs_updating(math::Variable * var)437 void degfix_needs_updating( math::Variable *var )
438 {
439 	math::degfix = *( math::global_varlist.get_pointer_rw(
440 	                    math::global_varlist.get_id( "degfix" ) )->get_complex()
441 	                );
442 #ifndef NO_GTK
443 	degfix_changed();
444 #endif
445 }
446 
text_setup_functions(void)447 void text_setup_functions( void )
448 {
449 	TEXTVIEW_FUNCTION = term_showtext;
450 	QUIT_FUNCTION = term_quit;
451 	try
452 	{
453 		math::add_function( "quit", addon_quit, false, false);
454 		math::add_function( "exit", addon_quit, false, false);
455 		math::add_function( "view", addon_view, false, true);
456 		math::add_function( "viewall", addon_viewall, false, false);
457 		math::add_function( "print", addon_print, false, true);
458 		math::add_function( "message", addon_text_message, false, true);
459 		math::add_function( "menu", addon_text_menu, false, true);
460 		math::add_function( "input", addon_text_input, false, true);
461 		math::add_function( "load", addon_load, false, true);
462 		math::add_function( "load_picture", addon_load_picture, false, true);
463 		math::add_function( "save_picture", addon_save_picture, false, true);
464 	}
465 	catch( error_obj error )
466 	{
467 		fprintf( stderr, "\n\nFATAL ERROR: %s\n\n", error.msg );
468 		exit(-1);
469 	}
470 }
471 
472 
get_start_message(void)473 const char * get_start_message(void)
474 {
475 	const char *trans;
476 
477 	if( (trans = translation.get_key_c_str("START_MESSAGE")) == 0 )
478 		trans = "  Ump comes with ABSOLUTELY NO WARRANTY; for details see LICENSE.\n"
479 		        "  This is free software, and you are welcome to redistribute it\n"
480 		        "  under certain conditions; see LICENSE for details.\n\n";
481 	return trans;
482 }
483 
484 
show_versions(void)485 void show_versions(void)
486 {
487 	printf( "\n\n" PRG_NAME " " PRG_VERSION " " PRG_DATE "\nCompiled " __DATE__ " " __TIME__ "\nwith " FLAGS "\n" );
488 
489 	printf( "\nutf8_string.h  %-3s  " UTF8_STRING_H_DATE, UTF8_STRING_H_VERSION );
490 	printf( "\ninteger.h      %-3s  " INTEGER_H_DATE, INTEGER_H_VERSION );
491 	printf( "\nreal.h         %-3s  " REAL_H_DATE, REAL_H_VERSION );
492 	printf( "\ncomplex.h      %-3s  " COMPLEX_H_DATE, COMPLEX_H_VERSION );
493 	printf( "\nmatrix.h       %-3s  " MATRIX_H_DATE, MATRIX_H_VERSION );
494 	printf( "\nmath2.h        %-3s  " MATH2_H_DATE, MATH2_H_VERSION );
495 	printf( "\nvartypes.h     %-3s  " VARTYPES_H_DATE, VARTYPES_H_VERSION );
496 	printf( "\npicture.h      %-3s  " PICTURE_H_DATE, PICTURE_H_VERSION );
497 	printf( "\nvector.h       %-3s  " VECTOR_H_DATE, VECTOR_H_VERSION );
498 #ifndef NO_GTK
499 	printf( "\npicture2gtk.h  %-3s  " PICTURE2GTK_H_DATE "\n\n", PICTURE2GTK_H_VERSION );
500 #else
501 	printf( "\n\n" );
502 #endif
503 }
504 
save_keyfile(void)505 void save_keyfile(void)
506 {
507 	try
508 	{
509 		char str[100];
510 
511 		setup_file.set_key( "PROGRAM", PRG_NAME );
512 		setup_file.set_key( "VERSION", PRG_VERSION );
513 
514 		snprintf( str, 100, "%lu", format.get_max_decimals() );
515 		setup_file.set_key( "FORMAT_MAX_DECIMALS", str );
516 
517 		if(strlen(language_filename.c_str()) > 0)
518 			setup_file.set_key( "LANGUAGE", language_filename );
519 		else
520 			setup_file.remove_key( "LANGUAGE" );
521 
522 #ifndef NO_GTK
523 		if(strlen(default_start_window.c_str()) > 0)
524 			setup_file.set_key( "DEFAULT_START_WINDOW", default_start_window );
525 		else
526 			setup_file.remove_key( "DEFAULT_START_WINDOW" );
527 #endif
528 
529 		setup_file.set_key( "FORMAT_SHOW_TRAILING", (format.show_trailingzeros) ? "True" : "False" );
530 
531 		switch( FormatType( format.get_type() ) )
532 		{
533 		case FormatType_Normal:
534 			setup_file.set_key( "FORMAT_TYPE", "Normal" );
535 			break;
536 		case FormatType_Mixed:
537 			setup_file.set_key( "FORMAT_TYPE", "Mixed" );
538 			break;
539 		case FormatType_Science:
540 			setup_file.set_key( "FORMAT_TYPE", "Science" );
541 			break;
542 		}
543 
544 		switch( FormatFractionType( format.get_fraction_type() ) )
545 		{
546 		case FormatFractionType_Fractions:
547 			setup_file.set_key( "FORMAT_FRACTION_TYPE", "Fractions" );
548 			break;
549 		case FormatFractionType_Integer_plus_fraction:
550 			setup_file.set_key( "FORMAT_FRACTION_TYPE", "Integer + fraction" );
551 			break;
552 		case FormatFractionType_Decimals:
553 			setup_file.set_key( "FORMAT_FRACTION_TYPE", "Decimals" );
554 			break;
555 		}
556 
557 		{
558 			utf8_string base("AUTOLOAD_PATH_"), keyname;
559 			const utf8_string *tmp;
560 			char number[10];
561 
562 			for( int i=0;; i++ ) // removes all old AUTOLOAD_PATH's
563 			{
564 				snprintf( number, 10, "%ld", i );
565 				keyname = base;
566 				keyname.append( number );
567 				tmp = setup_file.get_key( keyname );
568 				if( tmp == 0 )
569 					break;
570 				setup_file.remove_key( keyname );
571 			}
572 			for( int i=0; i<math::autoload_directories.get_size(); i++ )
573 			{
574 				snprintf( number, 10, "%ld", i );
575 				keyname = base;
576 				keyname.append( number );
577 
578 				setup_file.set_key( keyname, *math::autoload_directories[i] );
579 			}
580 		}
581 #ifndef NO_GTK
582 		{
583 			utf8_string base("HISTORY_LIST_"), keyname;
584 			const utf8_string *tmp;
585 			char number[10];
586 
587 			for( int i=0;; i++ ) // removes all old HISTORY_LIST
588 			{
589 				snprintf( number, 10, "%ld", i );
590 				keyname = base;
591 				keyname.append( number );
592 				tmp = setup_file.get_key( keyname );
593 				if( tmp == 0 )
594 					break;
595 				setup_file.remove_key( keyname );
596 			}
597 			for( int i=0; i<advanced_history.get_size(); i++ )
598 			{
599 				snprintf( number, 10, "%ld", i );
600 				keyname = base;
601 				keyname.append( number );
602 
603 				setup_file.set_key( keyname, *advanced_history[i] );
604 			}
605 		}
606 
607 		snprintf( str, 100, "%lu", SNAP_SIZE );
608 		setup_file.set_key( "SNAP_SIZE", str );
609 #endif
610 
611 		snprintf(str,100,"%s/.ump",getenv("HOME"));
612 
613 		setup_file.write( str );
614 	}
615 	catch(error_obj error)
616 	{
617 		printf("\n\nKey file error: %s\n\n",error.msg);
618 	}
619 }
hexstring_to_colorrgb(const char * str,picture_h::colorrgb & color)620 void hexstring_to_colorrgb(const char *str, picture_h::colorrgb &color) throw(error_obj)
621 {
622 	static char hex_code[] = "0123456789abcdefABCDEF";
623 	static char hex_value[] = "\0\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\12\13\14\15\16\17";
624 	int i;
625 	char value;
626 
627 	for(int c=0;c<3;c++)
628 	{
629 		if( str[c*2] == '\0'  ||  str[c*2+1] == '\0' )
630 			THROW_ERROR( ErrorType_General, _("Unknown format") );
631 
632 		for(i=0;;i++)
633 		{
634 			if(hex_code[i] == '\0')
635 				THROW_ERROR( ErrorType_General, _("Unknown format") );
636 
637 			if(hex_code[i] == str[c*2])
638 			{
639 				value = 16 * hex_value[i];
640 				break;
641 			}
642 		}
643 
644 		for(i=0;;i++)
645 		{
646 			if(hex_code[i] == '\0')
647 				THROW_ERROR( ErrorType_General, _("Unknown format") );
648 
649 			if(hex_code[i] == str[c*2+1])
650 			{
651 				value += hex_value[i];
652 				break;
653 			}
654 		}
655 		color.red   = (c == 0) ? value : color.red;
656 		color.green = (c == 1) ? value : color.green;
657 		color.blue  = (c == 2) ? value : color.blue;
658 	}
659 }
hexstring_to_colorrgbs(const char * str,Vector<picture_h::colorrgb> & colors)660 void hexstring_to_colorrgbs(const char *str, Vector<picture_h::colorrgb> &colors) throw(error_obj)
661 {
662 	int i;
663 	picture_h::colorrgb color;
664 
665 	colors.clear();
666 
667 	for( i=0;; i += 6 )
668 	{
669 		if( i == 0 )
670 			hexstring_to_colorrgb( str, color );
671 		else
672 		{
673 			if( str[i] == ' ' )
674 			{
675 				i++;
676 				try{ hexstring_to_colorrgb( &str[i], color ); }
677 				catch( ... ) { return; }
678 			}
679 			else if( str[i] == '\0' )
680 				return;
681 			else
682 				THROW_ERROR( ErrorType_General, _("Unknown format") );
683 		}
684 		colors.append( color );
685 	}
686 }
read_keyfile(void)687 void read_keyfile(void)
688 {
689 	try
690 	{
691 		char filename[100],tmpstr[50];
692 		const char *tmp;
693 		const utf8_string *str;
694 		bool std_settings = true;
695 
696 		setup_file.replace_escape_sequences = true;
697 
698 		try{  setup_file.read( "/usr/local/etc/ump.conf" );  }
699 		catch(...) { std_settings = false; }
700 
701 		snprintf(filename,100,"%s/.ump",getenv("HOME"));
702 
703 		try{ setup_file.read( filename ); }
704 		catch(...) { if( !std_settings ) return; }
705 
706 		{
707 			utf8_string base("AUTOLOAD_PATH_"), keyname;
708 			const utf8_string *tmp;
709 
710 			for( int i=0;; i++ ) // loads all AUTOLOAD_PATH's
711 			{
712 				snprintf( tmpstr, 50, "%ld", i );
713 				keyname = base;
714 				keyname.append( tmpstr );
715 				tmp = setup_file.get_key( keyname );
716 				if( tmp == 0 )
717 					break;
718 				math::autoload_directories.append( *tmp );
719 			}
720 		}
721 
722 #ifndef NO_GTK
723 		{
724 			utf8_string base("HISTORY_LIST_"), keyname;
725 			const utf8_string *tmp;
726 
727 			for( int i=0;; i++ ) // loads whole HISTORY_LIST
728 			{
729 				snprintf( tmpstr, 50, "%ld", i );
730 				keyname = base;
731 				keyname.append( tmpstr );
732 				tmp = setup_file.get_key( keyname );
733 				if( tmp == 0 )
734 					break;
735 				advanced_history.append( *tmp );
736 			}
737 		}
738 
739 		if((str = setup_file.get_key("DEFAULT_START_WINDOW")) != 0)
740 		{
741 			if( *str == "Advanced" )
742 			{
743 				default_start_window = *str;
744 				start_window = ADVANCED_WIN;
745 			}
746 			else if( *str == "Simple" )
747 			{
748 				default_start_window = *str;
749 				start_window = SIMPLE_WIN;
750 			}
751 			else if( *str == "Editor" )
752 			{
753 				default_start_window = *str;
754 				start_window = EDITOR_WIN;
755 			}
756 			else if( *str == "Graphtool" )
757 			{
758 				default_start_window = *str;
759 				start_window = GRAPHTOOL_WIN;
760 			}
761 			else if( *str == "MatrixEditor" )
762 			{
763 				default_start_window = *str;
764 				start_window = MATRIX_EDITOR_WIN;
765 			}
766 			else
767 				printf("\n\nUnknown DEFAULT_START_WINDOW in '%s'\n\n", filename);
768 		}
769 		if( (tmp = setup_file.get_key_c_str("SNAP_SIZE")) != 0 )
770 		{
771 			uint32 tmp_int;
772 
773 			if(sscanf( tmp, "%lu", &tmp_int ) == 0)
774 			{
775 
776 				char tmp_err[ERROR_OBJ_MSG_LEN];
777 				snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Invalid format in file %s"), filename );
778 				THROW_ERROR( ErrorType_File_IO, tmp_err );
779 			}
780 			if(tmp_int > 100)
781 			{
782 
783 				char tmp_err[ERROR_OBJ_MSG_LEN];
784 				snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Invalid format in file %s"), filename );
785 				THROW_ERROR( ErrorType_File_IO, tmp_err );
786 			}
787 			SNAP_SIZE = tmp_int;
788 		}
789 #endif
790 
791 		if((tmp = setup_file.get_key_c_str("LANGUAGE")) != 0)
792 			update_translation( tmp );
793 
794 		if((str = setup_file.get_key("FORMAT_TYPE")) != 0)
795 		{
796 			if(*str == "Normal")
797 				format.set_type( FormatType_Normal );
798 			else if(*str == "Mixed")
799 				format.set_type( FormatType_Mixed );
800 			else if(*str == "Science")
801 				format.set_type( FormatType_Science );
802 			else
803 			{
804 
805 				char tmp_err[ERROR_OBJ_MSG_LEN];
806 				snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Invalid format in file %s"), filename );
807 				THROW_ERROR( ErrorType_File_IO, tmp_err );
808 			}
809 		}
810 
811 		if((str = setup_file.get_key("FORMAT_FRACTION_TYPE")) != 0)
812 		{
813 			if(*str == "Fractions")
814 				format.set_fraction_type( FormatFractionType_Fractions );
815 			else if(*str == "Integer + fraction")
816 				format.set_fraction_type( FormatFractionType_Integer_plus_fraction );
817 			else if(*str == "Decimals")
818 				format.set_fraction_type( FormatFractionType_Decimals );
819 			else
820 			{
821 
822 				char tmp_err[ERROR_OBJ_MSG_LEN];
823 				snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Invalid format in file %s"), filename );
824 				THROW_ERROR( ErrorType_File_IO, tmp_err );
825 			}
826 		}
827 
828 		if((tmp = setup_file.get_key_c_str("FORMAT_MAX_DECIMALS")) != 0)
829 		{
830 			uint32 tmp_int;
831 
832 			if(sscanf(tmp,"%lu",&tmp_int) == 0)
833 			{
834 
835 				char tmp_err[ERROR_OBJ_MSG_LEN];
836 				snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Invalid format in file %s"), filename );
837 				THROW_ERROR( ErrorType_File_IO, tmp_err );
838 			}
839 			if(tmp_int > 50)
840 			{
841 
842 				char tmp_err[ERROR_OBJ_MSG_LEN];
843 				snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Invalid format in file %s"), filename );
844 				THROW_ERROR( ErrorType_File_IO, tmp_err );
845 			}
846 			format.set_max_decimals( tmp_int );
847 		}
848 		GET_BOOLEAN_KEY( "FORMAT_SHOW_TRAILING", format.show_trailingzeros );
849 	}
850 	catch(error_obj error)
851 	{
852 		printf("\n\nKey file error: %s\n\n",error.msg);
853 	}
854 #ifndef NO_GTK
855 	build_std_names();
856 #endif
857 }
858 
term_quit(void)859 void term_quit(void)
860 {
861 	save_keyfile();
862 	exit(0);
863 }
term_showtext(const utf8_string & string)864 void term_showtext(const utf8_string &string)
865 {
866 	printf( "%s", string.c_str() );
867 }
868 
869 #ifndef NO_GTK
870 
build_std_names(void)871 void build_std_names(void)
872 {
873 	dialog_title_open_file = _("Open file...");
874 	dialog_title_save_as = _("Save as...");
875 
876 
877 	menu_file = _("_File");
878 	menu_file_new = _("_New");
879 	menu_file_open = _("_Open...");
880 	menu_file_save = _("_Save");
881 	menu_file_save_as = _("Save _as...");
882 	menu_file_close = _("_Close");
883 	menu_file_quit = _("_Quit");
884 	menu_tools = _("_Tools");
885 
886 	menu_tools_simple = _("Simple _calculator");
887 	menu_tools_advanced = _("_Advanced calculator");
888 	menu_tools_editor = _("Ump _editor");
889 	menu_tools_graphtool = _("_Graph tools");
890 	menu_tools_matrixedit = _("_Matrix editor");
891 
892 	menu_about = _("_About");
893 	menu_pref = _("Pr_eferences");
894 
895 	button_ok = _("_OK");
896 	button_cancel = _("_Cancel");
897 	button_close = menu_file_close;
898 
899 
900 	edit_edit = _("_Edit");
901 	edit_edit_cut = _("Cu_t");
902 	edit_edit_copy = _("_Copy");
903 	edit_edit_paste = _("_Paste");
904 	edit_edit_delete = _("_Delete");
905 	edit_edit_select_all = _("Select _All");
906 
907 	filter_ump_files = _("UMP files");
908 	filter_all_files = _("All files");
909 	filter_picture_files = _("Picture files");
910 	filter_ppm_files = _("PPM files");
911 	filter_pcx_files = _("PCX files");
912 }
913 
UMP_gtk_quit(void)914 void UMP_gtk_quit(void)
915 {
916 	graphwin_close();
917 
918 	save_keyfile();
919 	if((open_windows & EDITOR_WIN) == EDITOR_WIN)
920 		editor_close(); // gets the user a chance of saving unsaved work
921 	try{  math::global_varlist.get_pointer_rw( math::global_varlist.get_id( "degfix" ) )->set_change_func( 0 );  }
922 	catch(...) { }
923 	gtk_main_quit();
924 }
925 
926 #endif
927 
928 
929 
930 
931 
932 
933 
934 
935 
936 
937 
938 
update_translation(utf8_string translation_filename,bool window_updating)939 void update_translation( utf8_string translation_filename, bool window_updating )
940 {
941 	translation.reset();
942 
943 	if( translation_filename == "English"  ||  translation_filename == "" )
944 		translation_filename = "English";
945 	else if(translation_filename == "Svenska")
946 	{
947 		try{
948 			translation.read_intern( translation_svenska );
949 		}
950 		catch(error_obj error){
951 			printf("\n\nError while loading translation 'Svenska' '%s'\n\n", error.msg);
952 		}
953 	}
954 	else
955 	{
956 		try{
957 			translation.read( translation_filename.c_str() );
958 		}
959 		catch(error_obj error){
960 			printf("\n\nError while loading translation file '%s' '%s'\n\n", translation_filename.c_str(), error.msg);
961 		}
962 	}
963 
964 #ifndef NO_GTK
965 	build_std_names();
966 
967 	if(window_updating)
968 	{
969 		language_filename = translation_filename;
970 
971 		simplewin_translate();
972 		advancedwin_translate();
973 		editorwin_translate();
974 		picturewin_translate();
975 		graphwin_translate();
976 		matrix_editor_translate();
977 	}
978 #endif
979 }
980