1 
2 /*
3  *  UMP - Unnamed Math Program
4  *  Copyright (c) 2004-2005 by Mattias Hultgren <mattias_hultgren@tele2.se>
5  *
6  *  See main.cpp
7  */
8 
9 #include <gtk/gtk.h>
10 #include "ump_editor.h"
11 #include "ump_simplewin.h"
12 #include "ump_aboutwin.h"
13 #include "ump_advancedwin.h"
14 #include "ump_prefwin.h"
15 #include "ump_graphwin.h"
16 #include "matrix_editor.h"
17 #include "vartypes.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "main.h"
22 
23 GtkWidget *editorwin = 0, *editorwin_menu, *editorwin_vbox, *editor_status;
24 GtkTextBuffer *textbuffer;
25 
26 char *filename = 0;
27 uint32 namelen = 0;
28 
29 bool modified = false;
30 bool editor_autoindent = true;
31 
aboutwin_show_editor(void)32 void aboutwin_show_editor(void) { aboutwin_show(GTK_WINDOW(editorwin)); }
prefwin_show_editor(void)33 void prefwin_show_editor(void) { prefwin_show(GTK_WINDOW(editorwin)); }
34 
35 void file_save(void);
36 void file_save_as(void);
37 
update_title(void)38 void update_title(void)
39 {
40 	char *str;
41 
42 	const char *trans = _("Ump Code editor");
43 
44 	try{ str = new char [strlen(filename) + 30]; }
45 	catch(...)
46 	{
47 		gtk_window_set_title(GTK_WINDOW(editorwin), trans);
48 		return;
49 	}
50 
51 	if(modified == false)
52 		snprintf(str,strlen(filename) + 30,"%s - %s",filename,trans);
53 	else
54 		snprintf(str,strlen(filename) + 30,"%s * - %s",filename,trans);
55 	gtk_window_set_title(GTK_WINDOW(editorwin), str);
56 	delete [] str;
57 }
setfilename(const char * newfilename)58 void setfilename(const char *newfilename)
59 {
60 	uint32 newnamelen;
61 
62 	modified = false;
63 
64 	newnamelen = strlen(newfilename) + 1;
65 	if(newnamelen > namelen)
66 	{
67 		char *newfile;
68 
69 		try{  newfile = new char [newnamelen];  }
70 		catch(...)
71 		{
72 			delete [] filename;
73 			filename = 0;
74 			gtk_window_set_title(GTK_WINDOW(editorwin), _("Ump Code editor") );
75 		}
76 		delete [] filename;
77 		filename = newfile;
78 		namelen = newnamelen;
79 	}
80 	strcpy(filename,newfilename);
81 
82 	update_title();
83 }
84 
check_save(void)85 void check_save(void)
86 {
87 	GtkWidget *dialog;
88 
89 	if(modified == true)
90 	{
91 		gint response;
92 
93 		dialog = gtk_message_dialog_new( GTK_WINDOW(editorwin), GTK_DIALOG_DESTROY_WITH_PARENT,
94 		                                 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
95 		             _("File '%s' has been changed.\nDo you want to save the changes?"), filename );
96 
97 		gtk_window_set_title( GTK_WINDOW(dialog), _("Save file?") );
98 		response = gtk_dialog_run(GTK_DIALOG(dialog));
99 		gtk_widget_destroy(dialog);
100 
101 		if(response == GTK_RESPONSE_YES)
102 			file_save();
103 	}
104 }
105 
file_new(void)106 void file_new(void)
107 {
108 	check_save();
109 
110 	gtk_text_buffer_set_text(textbuffer,"",-1);
111 
112 	setfilename( _("[Unsaved]") );
113 }
file_open(void)114 void file_open(void)
115 {
116 	GtkWidget *file_chooser;
117 	GtkFileFilter *filter;
118 	char *selected_filename;
119 	FILE *fp;
120 	long filesize;
121 	char *str;
122 
123 	check_save();
124 
125 
126 	file_chooser = gtk_file_chooser_dialog_new( dialog_title_open_file, GTK_WINDOW(editorwin),
127 	                                            GTK_FILE_CHOOSER_ACTION_OPEN,
128 	                                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
129 	                                            GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL );
130 
131 	filter = gtk_file_filter_new();
132 	gtk_file_filter_add_pattern(filter, "*.ump");
133 	gtk_file_filter_set_name(filter, filter_ump_files);
134 	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), filter);
135 
136 	filter = gtk_file_filter_new();
137 	gtk_file_filter_add_pattern(filter, "*");
138 	gtk_file_filter_set_name(filter, filter_all_files);
139 	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), filter);
140 
141 	if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
142 	{
143 		selected_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
144 
145 		fp = fopen(selected_filename,"rb");
146 		if(fp == 0)
147 		{
148 			setcode_thrower_error:
149 			if(fp != 0)
150 				fclose(fp);
151 
152 			GtkWidget *dialog;
153 			char tmp_err[ERROR_OBJ_MSG_LEN];
154 			snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Couldn't open/read from file (%s)"), filename );
155 			dialog = gtk_message_dialog_new( GTK_WINDOW(editorwin),
156 			                                 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
157 			                                 GTK_BUTTONS_CLOSE, tmp_err );
158 			gtk_dialog_run(GTK_DIALOG(dialog));
159 			gtk_widget_destroy(dialog);
160 			g_free(selected_filename);
161 			gtk_widget_destroy(file_chooser);
162 			return;
163 		}
164 
165 		if(fseek(fp,0L,SEEK_END) != 0)
166 			goto setcode_thrower_error;
167 		filesize = ftell(fp);
168 		if(filesize == -1)
169 			goto setcode_thrower_error;
170 		if(fseek(fp,0L,SEEK_SET) != 0)
171 			goto setcode_thrower_error;
172 
173 		try{  str = new char [filesize + 1];  }
174 		catch(...)
175 		{
176 			fclose(fp);
177 			GtkWidget *dialog;
178 			try{ THROW_ERROR( ErrorType_Memory, _("Couldn't get memory.") ); }
179 			catch(error_obj error)
180 			{
181 				dialog = gtk_message_dialog_new( GTK_WINDOW(editorwin),
182 				                                 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
183 				                                 GTK_BUTTONS_CLOSE, error.msg );
184 			}
185 			gtk_dialog_run(GTK_DIALOG(dialog));
186 			gtk_widget_destroy(dialog);
187 			g_free(selected_filename);
188 			gtk_widget_destroy(file_chooser);
189 			return;
190 		}
191 
192 		if(fread(str,1,filesize,fp) != filesize)
193 		{
194 			delete [] str;
195 			goto setcode_thrower_error;
196 		}
197 		if(fclose(fp) != 0)
198 		{
199 			delete [] str;
200 
201 			GtkWidget *dialog;
202 			char tmp_err[ERROR_OBJ_MSG_LEN];
203 			snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Couldn't close file (%s)"), selected_filename );
204 			dialog = gtk_message_dialog_new( GTK_WINDOW(editorwin),
205 			                                 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
206 			                                 GTK_BUTTONS_CLOSE, tmp_err );
207 			gtk_dialog_run(GTK_DIALOG (dialog));
208 			gtk_widget_destroy(dialog);
209 			g_free(selected_filename);
210 			gtk_widget_destroy(file_chooser);
211 			return;
212 		}
213 
214 		str[filesize] = '\0';
215 
216 		gtk_text_buffer_set_text(textbuffer,str,-1);
217 
218 		delete [] str;
219 
220 		setfilename(selected_filename);
221 		g_free(selected_filename);
222 	}
223 
224 	gtk_widget_destroy(file_chooser);
225 }
file_save(void)226 void file_save(void)
227 {
228 	GtkTextIter start, end;
229 	char *text;
230 	uint32 bufferlen;
231 	FILE *fp;
232 
233 	if(filename == 0)
234 	{
235 		file_save_as();
236 		return;
237 	}
238 	if( filename[0] == '\0'  ||  filename[0] == '[' )
239 	{
240 		file_save_as();
241 		return;
242 	}
243 
244 	gtk_text_buffer_get_bounds(textbuffer, &start, &end);
245 	text = gtk_text_iter_get_text(&start, &end);
246 
247 	fp = fopen(filename,"wb");
248 	if(fp == 0)
249 	{
250 		GtkWidget *dialog;
251 		char tmp_err[ERROR_OBJ_MSG_LEN];
252 		snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Couldn't open/read from file (%s)"), filename );
253 		dialog = gtk_message_dialog_new( GTK_WINDOW(editorwin), GTK_DIALOG_DESTROY_WITH_PARENT,
254 		                                 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, tmp_err );
255 		gtk_dialog_run(GTK_DIALOG(dialog));
256 		g_free(text);
257 		return;
258 	}
259 
260 	bufferlen = strlen(text);
261 	if( fwrite(text,1,bufferlen,fp) != bufferlen )
262 	{
263 		GtkWidget *dialog;
264 		char tmp_err[ERROR_OBJ_MSG_LEN];
265 		snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Couldn't open/read from file (%s)"), filename );
266 		dialog = gtk_message_dialog_new( GTK_WINDOW(editorwin), GTK_DIALOG_DESTROY_WITH_PARENT,
267 		                                 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, tmp_err );
268 		gtk_dialog_run(GTK_DIALOG(dialog));
269 		g_free(text);
270 		return;
271 	}
272 	g_free(text);
273 
274 	if(fclose(fp) != 0)
275 	{
276 		GtkWidget *dialog;
277 		char tmp_err[ERROR_OBJ_MSG_LEN];
278 		snprintf( tmp_err, ERROR_OBJ_MSG_LEN, _("Couldn't close file (%s)"), filename );
279 		THROW_ERROR( ErrorType_File_IO, tmp_err );
280 		dialog = gtk_message_dialog_new( GTK_WINDOW(editorwin), GTK_DIALOG_DESTROY_WITH_PARENT,
281 		                                 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, tmp_err );
282 		gtk_dialog_run(GTK_DIALOG(dialog));
283 		return;
284 	}
285 
286 	modified = false;
287 	update_title();
288 }
file_save_as_umpfile(GtkWidget * widget,gpointer user_data)289 void file_save_as_umpfile(GtkWidget *widget, gpointer user_data)
290 {
291 	GtkWidget *file_selector = (GtkWidget *)user_data;
292 	const gchar *selected_filename;
293 
294 	selected_filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION(file_selector));
295 
296 	{
297 		bool tmp = modified;
298 		setfilename(selected_filename);
299 		modified = tmp;
300 	}
301 
302 	file_save();
303 }
file_save_as(void)304 void file_save_as(void)
305 {
306 	GtkWidget *file_chooser;
307 	GtkFileFilter *filter;
308 
309 	file_chooser = gtk_file_chooser_dialog_new( dialog_title_save_as, GTK_WINDOW(editorwin),
310 	                                            GTK_FILE_CHOOSER_ACTION_SAVE,
311 	                                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
312 	                                            GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL );
313 
314 	filter = gtk_file_filter_new();
315 	gtk_file_filter_add_pattern(filter, "*.ump");
316 	gtk_file_filter_set_name(filter, filter_ump_files);
317 	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), filter);
318 
319 	filter = gtk_file_filter_new();
320 	gtk_file_filter_add_pattern(filter, "*");
321 	gtk_file_filter_set_name(filter, filter_all_files);
322 	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), filter);
323 
324 	if(gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT)
325 	{
326 		bool tmp = modified;
327 		char *filename;
328 
329 		filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
330 
331 		setfilename(filename);
332 		modified = tmp;
333 
334 		file_save();
335 
336 		g_free(filename);
337 	}
338 
339 	gtk_widget_destroy(file_chooser);
340 }
edit_cut(void)341 void edit_cut(void)
342 {
343 	gtk_text_buffer_cut_clipboard(textbuffer, gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), TRUE);
344 }
edit_copy(void)345 void edit_copy(void)
346 {
347 	gtk_text_buffer_copy_clipboard(textbuffer, gtk_clipboard_get(GDK_SELECTION_CLIPBOARD) );
348 }
edit_paste(void)349 void edit_paste(void)
350 {
351 	gtk_text_buffer_paste_clipboard(textbuffer, gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), NULL, TRUE);
352 }
edit_delete(void)353 void edit_delete(void)
354 {
355 	gtk_text_buffer_delete_selection(textbuffer,TRUE,TRUE);
356 }
edit_sel_all(void)357 void edit_sel_all(void)
358 {
359 	GtkTextIter start, end;
360 
361 	gtk_text_buffer_get_bounds(textbuffer, &start, &end);
362 
363 	gtk_text_buffer_move_mark_by_name(textbuffer,"selection_bound",&start);
364 	gtk_text_buffer_move_mark_by_name(textbuffer,"insert",&end);
365 }
366 
text_changed(GtkTextBuffer * textbuf,gpointer user_data)367 void text_changed(GtkTextBuffer *textbuf, gpointer user_data)
368 {
369 	modified = true;
370 
371 	update_title();
372 }
373 
374 
skip_white_spaces(gunichar ch,gpointer user_data)375 gboolean skip_white_spaces(gunichar ch, gpointer user_data)
376 {
377 	if( ch == gunichar(' ')  ||  ch == gunichar('\t') )
378 		return FALSE;
379 	else
380 		return TRUE;
381 }
382 
editor_status_update_buffer(GtkTextBuffer * buffer)383 void editor_status_update_buffer( GtkTextBuffer *buffer )
384 {
385 	static char str[50];
386 	static char tmp_row[20];
387 	static char tmp_col[20];
388 	GtkTextIter iter, iter_start;
389 	gint row, col;
390 
391 	gtk_text_buffer_get_iter_at_mark( buffer, &iter,
392 	gtk_text_buffer_get_mark( buffer, "insert" ) );
393 
394 	row = gtk_text_iter_get_line( &iter );
395 	gtk_text_buffer_get_iter_at_line( buffer, &iter_start, row );
396 	col = gtk_text_iter_get_offset( &iter ) - gtk_text_iter_get_offset( &iter_start );
397 
398 	uint64_to_char( uint64(row+1), tmp_row );
399 	uint64_to_char( uint64(col+1), tmp_col );
400 	snprintf( str, 50, " %s: %s  %s: %s ", _("Row"), tmp_row, _("Column"),  tmp_col );
401 
402 	gtk_label_set_text( GTK_LABEL( editor_status ), str );
403 }
404 
editor_status_update(GtkTextView * widget)405 void editor_status_update( GtkTextView *widget )
406 {
407 	editor_status_update_buffer( gtk_text_view_get_buffer( widget ) );
408 }
409 
text_insert(GtkTextBuffer * textbuf,GtkTextIter * iter,gchar * str,gint length)410 void text_insert(GtkTextBuffer *textbuf, GtkTextIter *iter, gchar *str, gint length)
411 {
412 	GtkTextIter start_of_prev_line = *iter, end_of_indentation;
413 
414 	if( str[0] == '\n'  &&  length == 1  &&  editor_autoindent )
415 	{
416 		if( gtk_text_iter_backward_line( &start_of_prev_line ) == TRUE )
417 		{
418 			end_of_indentation = start_of_prev_line;
419 			if( gtk_text_iter_forward_find_char( &end_of_indentation, skip_white_spaces,
420 			      NULL, 0) == TRUE )
421 			{
422 				gchar *text;
423 
424 				text = gtk_text_iter_get_text( &start_of_prev_line, &end_of_indentation );
425 
426 				if( *text == ' '  ||  *text == '\t' )
427 					gtk_text_buffer_insert_at_cursor( textbuf, text, strlen( text ) );
428 			}
429 		}
430 	}
431 	editor_status_update_buffer( textbuf );
432 }
433 
editorwin_build_menu(void)434 GtkWidget* editorwin_build_menu(void)
435 {
436 	GtkActionGroup *actions;
437 	GtkUIManager *ui_manager;
438 	GError *error = NULL;
439 	static const gchar *menu =
440 "<ui>"
441 "  <menubar name='MenuBar'>"
442 "    <menu action='FileMenu'>"
443 "      <menuitem action='New'/>"
444 "      <menuitem action='Open'/>"
445 "      <separator/>"
446 "      <menuitem action='Save'/>"
447 "      <menuitem action='SaveAs'/>"
448 "      <separator/>"
449 "      <menuitem action='Close'/>"
450 "      <separator/>"
451 "      <menuitem action='Quit'/>"
452 "    </menu>"
453 "    <menu action='EditMenu'>"
454 "      <menuitem action='Cut'/>"
455 "      <menuitem action='Copy'/>"
456 "      <menuitem action='Paste'/>"
457 "      <menuitem action='Delete'/>"
458 "      <separator/>"
459 "      <menuitem action='SelAll'/>"
460 "      <separator/>"
461 "      <menuitem action='Preferences'/>"
462 "    </menu>"
463 "    <menu action='ToolsMenu'>"
464 "      <menuitem action='Simple'/>"
465 "      <menuitem action='Advanced'/>"
466 "      <menuitem action='Graphtool'/>"
467 "      <menuitem action='MatrixEdit'/>"
468 "    </menu>"
469 "    <menuitem action='About'/>"
470 "  </menubar>"
471 "</ui>";
472 	GtkActionEntry entries[] = {
473 { "FileMenu",    NULL,                  menu_file },
474 { "New",         GTK_STOCK_NEW,         menu_file_new,        "<ctrl>N",        NULL, G_CALLBACK(file_new) },
475 { "Open",        GTK_STOCK_OPEN,        menu_file_open,       "<ctrl>O",        NULL, G_CALLBACK(file_open) },
476 { "Save",        GTK_STOCK_SAVE,        menu_file_save,       "<ctrl>S",        NULL, G_CALLBACK(file_save) },
477 { "SaveAs",      GTK_STOCK_SAVE_AS,     menu_file_save_as,    "<shift><ctrl>S", NULL, G_CALLBACK(file_save_as) },
478 { "Close",       GTK_STOCK_CLOSE,       menu_file_close,      "<ctrl>W",        NULL, G_CALLBACK(editor_close) },
479 { "Quit",        GTK_STOCK_QUIT,        menu_file_quit,       "<ctrl>Q",        NULL, G_CALLBACK(UMP_gtk_quit) },
480 { "EditMenu",    NULL,                  edit_edit },
481 { "Cut",         GTK_STOCK_CUT,         edit_edit_cut,        "<ctrl>X",        NULL, G_CALLBACK(edit_cut) },
482 { "Copy",        GTK_STOCK_COPY,        edit_edit_copy,       "<ctrl>C",        NULL, G_CALLBACK(edit_copy) },
483 { "Paste",       GTK_STOCK_PASTE,       edit_edit_paste,      "<ctrl>V",        NULL, G_CALLBACK(edit_paste) },
484 { "Delete",      NULL,                  edit_edit_delete,     NULL,             NULL, G_CALLBACK(edit_delete) },
485 { "SelAll",      NULL,                  edit_edit_select_all, "<ctrl>A",        NULL, G_CALLBACK(edit_sel_all) },
486 { "Preferences", GTK_STOCK_PREFERENCES, menu_pref,            NULL,             NULL, G_CALLBACK(prefwin_show_editor) },
487 { "ToolsMenu",   NULL,                  menu_tools },
488 { "Simple",      NULL,                  menu_tools_simple,    NULL,             NULL, G_CALLBACK(simplewin_show) },
489 { "Advanced",    NULL,                  menu_tools_advanced,  NULL,             NULL, G_CALLBACK(advancedwin_show) },
490 { "Graphtool",   NULL,                  menu_tools_graphtool, NULL,             NULL, G_CALLBACK(graphwin_show) },
491 { "MatrixEdit",  NULL,                  menu_tools_matrixedit,NULL,             NULL, G_CALLBACK(matrix_editor_show) },
492 { "About",       NULL,                  menu_about,           NULL,             NULL, G_CALLBACK(aboutwin_show_editor) }
493 };
494 	guint n_entries = G_N_ELEMENTS(entries);
495 
496 
497 	actions = gtk_action_group_new("Actions");
498 	gtk_action_group_add_actions(actions, entries, n_entries, NULL);
499 	ui_manager = gtk_ui_manager_new();
500 	gtk_ui_manager_insert_action_group(ui_manager, actions, 0);
501 	gtk_window_add_accel_group( GTK_WINDOW(editorwin), gtk_ui_manager_get_accel_group(ui_manager) );
502 	if(!gtk_ui_manager_add_ui_from_string(ui_manager, menu, -1, &error))
503 	{
504 		g_message("building menus failed: %s", error->message);
505 		g_error_free(error);
506 		return 0;
507 	}
508 	gtk_ui_manager_ensure_update(ui_manager);
509 
510 	return gtk_ui_manager_get_widget(ui_manager, "/MenuBar");
511 }
512 
editor_showwin(void)513 GtkWindow* editor_showwin(void)
514 {
515 	if(editorwin == 0)
516 	{
517 		GtkWidget *textview,*scrolled;
518 
519 		editorwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
520 
521 		setfilename( _("[Unsaved]") );
522 		g_signal_connect_swapped(G_OBJECT(editorwin), "delete-event", G_CALLBACK(editor_close), NULL);
523 		gtk_widget_set_size_request(GTK_WIDGET(editorwin), 150,100);
524 
525 		editorwin_vbox = gtk_vbox_new(FALSE, 0);
526 		gtk_container_add(GTK_CONTAINER(editorwin), editorwin_vbox);
527 
528 		if((editorwin_menu = editorwin_build_menu()) == 0)
529 		{
530 			gtk_widget_destroy( editorwin );
531 			editorwin = 0;
532 			return 0;
533 		}
534 		gtk_box_pack_start(GTK_BOX(editorwin_vbox), editorwin_menu, FALSE, FALSE, 0);
535 
536 
537 		textbuffer = gtk_text_buffer_new(NULL);
538 		g_signal_connect_swapped(G_OBJECT(textbuffer), "changed", G_CALLBACK(text_changed), NULL);
539 		g_signal_connect_after(G_OBJECT(textbuffer), "insert-text", G_CALLBACK(text_insert), NULL);
540 		g_signal_connect_after(G_OBJECT(textbuffer), "delete-range", G_CALLBACK(editor_status_update_buffer), NULL);
541 
542 		textview = gtk_text_view_new_with_buffer(textbuffer);
543 		g_signal_connect_after( G_OBJECT(textview), "move-cursor",
544 		G_CALLBACK(editor_status_update), NULL);
545 
546 		{
547 			PangoFontDescription *font_desc;
548 			font_desc = pango_font_description_from_string("Monospace 10");
549 			gtk_widget_modify_font(textview, font_desc);
550 			pango_font_description_free(font_desc);
551 		}
552 
553 
554 		modified = false;
555 
556 		scrolled = gtk_scrolled_window_new( NULL, NULL);
557 		gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC,
558 										GTK_POLICY_AUTOMATIC );
559 
560 		gtk_container_add(GTK_CONTAINER(scrolled), textview);
561 
562 		gtk_box_pack_start(GTK_BOX(editorwin_vbox), scrolled, TRUE, TRUE, 0);
563 
564 		{
565 			GtkWidget *tbox, *tbar;
566 			tbox = gtk_hbox_new( FALSE, 0 );
567 
568 			editor_status = gtk_label_new( PRG_NAME );
569 			gtk_misc_set_alignment( GTK_MISC(editor_status), 0.0f, 0.5f );
570 			gtk_box_pack_start( GTK_BOX(tbox), editor_status, FALSE, FALSE, 0 );
571 
572 			tbar = gtk_statusbar_new();
573 			gtk_box_pack_start( GTK_BOX(tbox), tbar, TRUE, TRUE, 0 );
574 
575 			gtk_box_pack_start( GTK_BOX(editorwin_vbox), tbox, FALSE, FALSE, 0 );
576 		}
577 
578 
579 
580 		gtk_window_resize(GTK_WINDOW(editorwin),500,400);
581 		gtk_widget_show_all(editorwin);
582 		open_windows |= EDITOR_WIN;
583 	}
584 	else
585 		gtk_window_present(GTK_WINDOW(editorwin));
586 
587 	return GTK_WINDOW( editorwin );
588 }
589 
editor_close(void)590 void editor_close(void)
591 {
592 	if(editorwin != 0)
593 	{
594 		check_save();
595 
596 		gtk_widget_destroy(editorwin);
597 		editorwin = 0;
598 
599 		delete [] filename;
600 		filename = 0;
601 		namelen = 0;
602 
603 		open_windows &= ~EDITOR_WIN;
604 		if(open_windows == 0)
605 			UMP_gtk_quit();
606 	}
607 }
608 
editorwin_translate(void)609 void editorwin_translate(void)
610 {
611 	if(editorwin != 0)
612 	{
613 		GtkWidget *new_menu;
614 
615 		if(( new_menu = editorwin_build_menu()) == 0 )
616 			return;
617 
618 		gtk_widget_destroy( editorwin_menu );
619 		editorwin_menu = new_menu;
620 
621 		gtk_box_pack_start(GTK_BOX(editorwin_vbox), editorwin_menu, FALSE, FALSE, 0);
622 		gtk_box_reorder_child( GTK_BOX(editorwin_vbox), editorwin_menu, 0 );
623 
624 		update_title();
625 
626 		editor_status_update_buffer( textbuffer );
627 	}
628 }
629