/* The following comment was added by Kari Laitinen on 15.3.2005 This is one of the Prolog programs of which an experimental software maintenance tool called InName is made. InName is a disabbreviation tool with which it is possible convert abbreviated names of C/C++ programs to more understandable, natural names. The Prolog source programs of the InName tool are now declared "Open Source" programs. People who have contributed to the original development of these programs include Kari Laitinen http://www.naturalprogramming.com Neil Rowe U.S. Naval Postgraduate School Markku Heikkila Currently works at Nokia. Jorma Taramaa Currently works at Nokia. The InName tool was developed at VTT Electronics, a division of the Technical Reseach Centre of Finland. The work was funded by VTT Electronics and the EU. It is the wish of the original developers that the above names will be mentioned if these programs are exploited in the development of other disabbreviation tools. A description about the InName tool and theoretical discussion related to it can be found at Laitinen, K., Taramaa, J., Heikkila, M., and Rowe, N. C.. Enhancing Maintainability of Source Programs through Disabbreviation. The Journal of Systems and Software, Vol. 37, No. 2, 1997, pp. 117 - 128. The text of the original file begins below. */ /*--------------------------------------------------------------------------- VTT Electronics Quintus Prolog/ProXL source program Embedded Software (Version 3.1.1) AMES / InName project Markku Heikkila (MaH) Kari Laitinen File: inname_graphic_ui.pro Version: 0.2 Status: draft Accepted by: File history: 19.6.94 v0.0 File created Markku Heikkila 29.8.94 v0.1 Last "Markku" version Markku Heikkila 16.5.95 v0.2 Last modification Kari Laitinen ---------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------- NOTES --------------------------------------------------------------------------- in2308.pl is the latest file which does not support the use of middle button. NOTICE: To improve the performance with large files it may be useful to define > setenv PROLOGINITSIZE ?M (or ?K, M for Mbytes, K for Kbytes, ? is a number) before executing the prolog interpreter/compiler. From 28.10.1994 onwards we will load only .qof files. Domain dictionary may not contain a empty string ''. Kari spent two days finding a bug in the programs, but the bug was an empty string in domain dictionary. 8.11.94 has been added the feature that the name substitutions will be stored to file "xxxx.c.substitutions" . Also, name legality is being checked: a new name may not be already in use, neither may two old names get the same substitution. Lots of cuts (!) have been added. Practically every rule is ended with a cut, though that does not seem to speed up the system. 26.4.95: The tool produces a file previous_name_substitutions.data when a file has been processed and updated with new names. This data will be used in subsequent disabbreviations. Need to be tested more thoroughly. ------------------------------------------------------------------------*/ :- no_style_check(single_var). :- use_module( library( proxl ) ). :- use_module( library( basics ), [ member/2, nonmember/2 ] ). :- use_module( library( files ), [ file_exists/1, file_exists/2 ] ). :- use_module( library( caseconv ), [ upper/1, upper/2, lower/2 ] ). :- use_module( library( lineio ), [ get_line/1, put_line/1 ] ). /* The global data is saved in the following structures. */ :- dynamic window_sizes/4, /* width, height for text and control windows */ window_identifiers/2, /* id's for not-a-button windows */ button_identifiers/8, /* id's for button windows */ button_label/2, /* button name, label as list */ button_activity_states/8, /* on or off */ saved_button_activity_states/8, /* on or off */ button_previously_pressed/1, /* button window in which previous press occured */ button_images/3, /* normal, highlight, off button images */ cursor_shapes/2, /* wait cursor, selection cursor */ pop_up_text_lines/2, /* used to help to pass parameters to refreshing routine of pop up windows */ program_file_name/1, /* name of file to deabbreviate as string */ domain_dictionary_name/1, /* name of domain dictionary as string */ text_buffer/2, /* line number, line as list */ first_line_in_window/1, /* the first line of file viewable in window */ colors_used/6, /* the 6 colors used in user interface */ text_font/3, /* font, font height, ascent */ button_font/3, /* font, font height, ascent */ text_styles/3, /* normal, highlighted, erase, as gc's */ button_size/2, /* width and height, common for all buttons */ max_number_of_lines_in_window/1, /* number of lines that fit in text window */ lines_in_file/1, /* total number of lines in file */ saved_unknown_name/4, /* name as string, name as list of words, list of line numbers, list of unknown words */ unknown_names_in_line/2, /* line number, number of unknown names in this line, fails if none */ list_of_name_candidates/1, /* as list of lists of words */ number_of_name_candidates/2, /* total number, max number in window */ first_name_candidate_in_window/1, /* ordinal number of first candidate in window */ selected_name_candidate/1, /* ordinal number of selected candidate, 0=none */ text_input_window_when/2, /* purpose, window identifier */ user_given_name/2, /* as dynamic clause, letter by letter */ user_given_name_as_list/2, /* as list of characters */ is_keyboard_grabbing_allowed/1, /* true or false */ keyboard_is_grabbed_for/1, /* purpose for which the keyboard has been grabbed */ cursor_coordinate_in_window/2. /* dynamic clause for saving coordinate of each typed character in window */ :- multifile lines_in_file/1, possible_word_substitution/1, name_candidate/1, word_substitution/2, name_substitution/3, unknown_name/4, general_counters/2, domain_word/1, potential_name/1, potential_substitution/2, found_name/2, previous_name_substitution/2, previously_used_name_substitution_found/0. :- dynamic possible_word_substitution/1, name_candidate/1, word_substitution/2, name_substitution/3, unknown_name/4, general_counters/2, domain_word/1, potential_name/1, potential_substitution/2, found_name/2, previous_name_substitution/2, previously_used_name_substitution_found/0. :- ensure_loaded(library(lists)). :- ensure_loaded(library(strings)). :- ensure_loaded('inname_utilities.pro.qof'). :- ensure_loaded('inname_first_pass.pro.qof'). :- ensure_loaded('inname_second_pass.pro.qof'). :- ensure_loaded('inname_third_pass.pro.qof'). :- ensure_loaded('inname_dictionary.pro.qof'). :- ensure_loaded('inname_statistics.pro.qof'). :- ensure_loaded('inname_comments.pro.qof'). :- ensure_loaded('inname_reserved_words_of_c.facts.qof'). :- ensure_loaded('inname_dictionary_words.facts.qof'). :- ensure_loaded('inname_usual_abbreviations.facts.qof'). /* user:runtime_entry( start ) :- in. * user:runtime_entry( abort ). */ runtime_entry(start) :- in, !. in :- /* With the unix command we should get the file name given as a command line argument. */ unix( args( [ File_name ] ) ), file_exists( File_name ), asserta( program_file_name( File_name ) ), fail. in :- write( 'Initializing the program ...' ), nl, initialize_program. in. in( File_name ) :- file_exists( File_name ), asserta( program_file_name( File_name ) ), initialize_program. in( _ ). initialize_program :- /* Use default domain dictionary file */ inname_data( default_dictionary_name( Default_dictionary_name ) ), assertz( domain_dictionary_name( Default_dictionary_name ) ), alloc_color( black, Black ), alloc_color( grey65, Darkgray ), alloc_color( grey75, Middlegray ), alloc_color( grey80, Gray ), alloc_color( grey90, Lightgray ), alloc_color( white, White ), assertz( colors_used( Black, Darkgray, Middlegray, Gray, Lightgray, White ) ), !, find_font( inname_font, Font ), !, find_font( button_font, Button_font ), get_font_attributes( Font, [ height( Text_font_height ), ascent( Text_font_ascent ) ] ), get_font_attributes( Button_font, [ height( Button_font_height ), ascent( Button_font_ascent ) ] ), assertz( text_font( Font, Text_font_height, Text_font_ascent ) ), assertz( button_font( Button_font, Button_font_height, Button_font_ascent ) ), create_cursor( watch, Wait_cursor ), create_cursor( left_ptr, Selection_cursor ), assertz( cursor_shapes( Wait_cursor, Selection_cursor ) ), Control_window_width is 476, Control_window_height is 286, Text_window_width is 600, Text_window_height is 600, /* Reserve room for 5 names in name candidates window */ Name_candidates_window_height is Button_font_height * 5 + 2, write( 'Opening text window ...'), nl, open_text_window( Text_window, Scroll_bar_window, Text_window_width, Text_window_height, 0, 0, Font, 'InName - none' ), open_control_window( Control_window, Unknown_name_window, Change_to_window, Name_candidates_window, Name_candidates_window_height, Domain_dictionary_window, File_name_window, Control_window_width, Control_window_height, 500, 30, Font ), refresh_control_window( Control_window ), flush, retractall( number_of_name_candidates( _, _ ) ), Number_of_name_candidates_fit_in_window is ( Name_candidates_window_height - 3 ) // Text_font_height, assertz( number_of_name_candidates( _, Number_of_name_candidates_fit_in_window ) ), assertz( window_sizes( Text_window_width, Text_window_height, Control_window_width, Control_window_height ) ), asserta( window_identifiers( scroll_bar_window, Scroll_bar_window ) ), asserta( window_identifiers( text_window, Text_window ) ), asserta( window_identifiers( control_window, Control_window ) ), asserta( window_identifiers( unknown_name_window, Unknown_name_window ) ), asserta( window_identifiers( change_to_window, Change_to_window ) ), asserta( window_identifiers( name_candidates_window, Name_candidates_window ) ), asserta( window_identifiers( domain_dictionary_window, Domain_dictionary_window ) ), asserta( window_identifiers( file_name_window, File_name_window ) ), assertz( button_size( 86, 20 ) ), create_button_images( Normal_button_image, Highlighted_button_image, Inactivated_button_image ), assertz( button_images( Normal_button_image, Highlighted_button_image, Inactivated_button_image ) ), create_skip_button( Skip_button, 10, 220, Control_window, Button_font ), create_change_button( Change_button, 100, 220, Control_window, Button_font ), create_add_button( Add_button, 190, 220, Control_window, Button_font ), create_more_button( More_button, 290, 220, Control_window, Button_font ), create_previous_button( Previous_button, 380, 220, Control_window, Button_font ), create_exit_button( Exit_button, 10, 250, Control_window, Button_font ), create_null_button( Not_existing_button ), refresh_control_window( Control_window ), assertz( button_identifiers( Skip_button, Change_button, Add_button, More_button, Previous_button, Not_existing_button, Not_existing_button, Exit_button ) ), assertz( button_label( Skip_button, "Skip" ) ), assertz( button_label( Change_button, "Change" ) ), assertz( button_label( Add_button, "Add>" ) ), assertz( button_label( More_button, "More" ) ), assertz( button_label( Previous_button, "Previous" ) ), assertz( button_label( Not_existing_button, "" ) ), assertz( button_label( Exit_button, "Exit>" ) ), /* Define text input windows in different cases. */ assertz( text_input_window_when( entering_new_name, Change_to_window ) ), assertz( text_input_window_when( entering_new_file, File_name_window ) ), assertz( text_input_window_when( entering_new_dictionary, Domain_dictionary_window ) ), /* Define starting values for button states. */ assertz( button_activity_states( off, off, off, off, off, off, off, on ) ), /* button_activity_states( Skip,Change,Add,More,Previous,Ok,Cancel,Exit )*/ set_activity_state_for_all_buttons( all_off ), put_window_attributes( Text_window, [ mapped( true ) ] ), put_window_attributes( Control_window, [ mapped( true ) ] ), flush, /* Create text styles as gc's. */ create_gc( Normal_text_style, [ background( White ), foreground( Black ), font( Font ) ] ), create_gc( Inverse_text_style, [ background( Black ), foreground( White ), font( Font ) ] ), create_gc( Erase_text_style, [ background( White ), foreground( White ), font( Font ) ] ), assertz( text_styles( Normal_text_style, Inverse_text_style, Erase_text_style ) ), assertz( is_keyboard_grabbing_allowed( true ) ), /* Load new file if given from the command prompt. */ /* The file can be given from command line when the tool is started in the Prolog interpreter. */ ( program_file_name( _ ) -> load_new_file ; true ), !, write( 'Jumping to main program loop ...'), nl, /* MAIN LOOP */ repeat, \+ main_program_loop, !, /* Repeat until the call fails (exit pressed) */ destroy_all_windows_and_global_data. load_new_file :- /* Change window title. */ program_file_name( New_file_name ), absolute_file_name( New_file_name, Absolute_file_name ), name( Absolute_file_name, File_name_character_list ), append( "InName - ", File_name_character_list, Combined_character_list ), name( Text_window_title, Combined_character_list ), window_identifiers( text_window, Text_window ), put_window_attributes( Text_window, [ property( 'WM_NAME', Text_window_title ) ] ), flush, retractall( domain_word( _ ) ), domain_dictionary_name( Dictionary_name ), load_domain_dictionary( Dictionary_name ), /* The previous name substitutions will be loaded always when new program file is to be loaded. */ load_previous_substitutions, /* Change cursor image. */ use_wait_cursor, /* Load the new file. */ retractall( text_buffer( _, _ ) ), retractall( found_word( _, _ ) ), retractall( found_name( _, _ ) ), retractall( unknown_name( _, _, _, _ ) ), retractall( general_counters( _, _ ) ), retractall( name_substitution( _, _, _ ) ), retractall( potential_name( _ ) ), retractall( potential_substitution( _, _ ) ), search_unknown_names_in_program_file( New_file_name ), count_total_line_number_in_file( New_file_name ), use_normal_cursor, !. main_program_loop :- ( get_next_unknown_name_to_be_deabbreviated( Skip_next_event_handling_loop ) /* Fails if no more names left. */ ; ( Skip_next_event_handling_loop = false, ( program_file_name( File_name ) /* Fails if no file loaded at all. */ -> inform_user( 'The file has been disabbreviated!' ), use_wait_cursor, ( domain_word( _ ) /* This should always succeed. */ -> domain_dictionary_name( Dictionary_name_as_string ), store_domain_dictionary( Dictionary_name_as_string ) ; true ), use_normal_cursor, ( name_substitution( _, _, _ ) -> ( use_wait_cursor, /* The following actions will take place when the file has been disabbreviated. */ store_name_substitutions_to_file( File_name ), produce_new_previous_substitutions_file, store_word_statistics( File_name ), store_name_statistics( File_name ), use_normal_cursor, ( ask_user( 'Update file with new names?' ), use_wait_cursor, replace_selected_names_in_program_file( File_name ), use_normal_cursor ; true ) ) ; true ), window_identifiers( text_window, Text_window ), put_window_attributes( Text_window, [ property( 'WM_NAME', 'Inname - none' ) ] ), retractall( text_buffer( _, _ ) ), retractall( program_file_name( _ ) ), retractall( selected_name_candidate( _ ) ), retractall( list_of_name_candidates( _ ) ), retractall( saved_unknown_name( _, _, _, _ ) ) ; true ) ), /* Make the ui to wait for exit command or new file or dictionary name.*/ set_activity_state_for_all_buttons( off, off, off, off, off, off, off, on ), window_identifiers( text_window, Text_window ), window_identifiers( file_name_window, File_name_window ), window_identifiers( unknown_name_window, Unknown_name_window ), window_identifiers( change_to_window, Change_to_window ), window_identifiers( name_candidates_window, Name_candidates_window ), window_identifiers( scroll_bar_window, Scroll_bar_window ), clear_window( Text_window ), clear_window( File_name_window ), clear_window( Scroll_bar_window ), clear_window( Unknown_name_window ), clear_window( Change_to_window ), clear_window( Name_candidates_window ) ), /* The main event handling loop, can be ordered to be skipped because there are situations e.g. when the Add button has been pressed and the name is not unknown anymore and there wouldn't be any changes to make into the name because it is normally constructed with underscores etc. */ ( Skip_next_event_handling_loop == false, handle_events( exit_from_event_handling( Status_after_event_handling ) ) ; Status_after_event_handling = event_handling_was_not_allowed ), !, Status_after_event_handling \== exit_button_pressed, ( Status_after_event_handling == new_file_entered -> load_new_file ; /* New confirmed and existing file entered. */ Status_after_event_handling == add_button_pressed -> true ; /* Do nothing, let the program handle this name once again, * now with updated domain dictionary. */ otherwise /* Change or Skip pressed or event_handling_was_not_allowed. */ -> saved_unknown_name( Name_in_string_form, _, _, _ ), retract( unknown_name( Name_in_string_form, _, _, _ ) ) ), !. get_next_unknown_name_to_be_deabbreviated( Skip_next_event_handling_loop ) :- set_activity_state_for_all_buttons( all_off ), !, program_file_name( File_name ), /* Fails if no program loaded */ !, get_earliest_unknown_name( Name_in_string_form, List_of_line_numbers, List_of_all_words, List_of_unknown_words ), increment_counter( number_of_unknown_names_processed ), retractall( saved_unknown_name( _, _, _, _ ) ), assertz( saved_unknown_name( Name_in_string_form, List_of_all_words, List_of_line_numbers, List_of_unknown_words ) ), /* If there are no unknown words and no changes to make in the 'unknown' name force the program to skip next event handling loop in main_program_loop. */ ( ( List_of_unknown_words == [], convert_list_of_words_to_underscored_string( List_of_all_words, Underscored_string_for_testing ), Name_in_string_form == Underscored_string_for_testing, Skip_next_event_handling_loop = true ) ; ( Skip_next_event_handling_loop = false, /* The next event handling won't be skipped, so generate name candidates, show the unknown name and text in windows etc... */ ( append( [ First_line_number | _ ], [], List_of_line_numbers ) ; First_line_number is 1 ), max_number_of_lines_in_window( Max_number_of_lines_in_window ), /* Show the first unknown name in the 7th line if possible. */ ( First_line_number > 6 -> First_line_to_show is First_line_number - 6 ; otherwise -> First_line_to_show is 1 ), Last_line_number is First_line_to_show + Max_number_of_lines_in_window - 1, /* Read text into the buffer in needed. */ read_text_from_file( File_name, First_line_to_show, Last_line_number ), retractall( first_line_in_window( _ ) ), assertz( first_line_in_window( First_line_to_show ) ), write_text_to_window, show_unknown_name, retractall( previously_used_name_substitution_found ), generate_list_of_name_candidates( Name_in_string_form, List_of_all_words, List_of_unknown_words, List_of_name_candidates ), retractall( list_of_name_candidates( _ ) ), assertz( list_of_name_candidates( List_of_name_candidates ) ), retractall( first_name_candidate_in_window( _ ) ), assertz( first_name_candidate_in_window( 1 ) ), retractall( keyboard_is_grabbed_for( _ ) ), /* Erase possible previously typed name. */ discard_user_given_name( entering_new_name ), /* If there are unknown words activate the add button. */ length( List_of_unknown_words, Number_of_unknown_words ), ( Number_of_unknown_words =:= 0 -> Add_button_state = off ; otherwise -> Add_button_state = on ), length( List_of_name_candidates, Number_of_name_candidates ), number_of_name_candidates( _, Lines_in_window ), retractall( number_of_name_candidates( _, _ ) ), assertz( number_of_name_candidates( Number_of_name_candidates, Lines_in_window ) ), retractall( selected_name_candidate( _ ) ), /* Select the first name candidate automaticly if there is one. */ ( Number_of_name_candidates =:= 0 -> assertz( selected_name_candidate( 0 ) ), /* No selected candidate */ Change_button_state = off ; otherwise -> assertz( selected_name_candidate( 1 ) ), append( [ First_candidate | _ ], [], List_of_name_candidates ), convert_list_of_words_to_underscored_string( First_candidate, Underscored_string ), name( Underscored_string, Underscored_list ), retractall( user_given_name_as_list( entering_new_name, _ ) ), assertz( user_given_name_as_list( entering_new_name, Underscored_list ) ), Change_button_state = on ), show_list_of_name_candidates( false, true ), show_selected_name_candidate, set_activity_state_for_all_buttons( on, Change_button_state, Add_button_state, same, same, same, same, on ), /* Forget all button events for control window (all buttons inactivated). */ remove_all_button_events_from_queue( control_window ), flush ) ), !. capitalize_name_candidates( [], [] ) :- !. capitalize_name_candidates( [ List_of_words_of_candidate | Rest_of_name_candidates ], [ Uppercase_candidate | Rest_of_uppercase_name_candidates ] ) :- convert_list_of_words_to_uppercase( List_of_words_of_name_candidate, Uppercase_candidate ), capitalize_name_candidates( Rest_of_name_candidates, Rest_of_uppercase_name_candidates ), !. convert_list_of_words_to_uppercase( [], [] ) :- !. convert_list_of_words_to_uppercase( [ Word | Rest_of_words ], [ Uppercase_word | Rest_of_uppercase_list ] ) :- ( upper( Word, Uppercase_word ) ; Uppercase_word = Word ), convert_list_of_words_to_uppercase( Rest_of_words, Rest_of_uppercase_list ), !. convert_list_of_words_to_lowercase( [], [] ) :- !. convert_list_of_words_to_lowercase( [ Word | Rest_of_words ], [ Lowercase_word | Rest_of_lowercase_list ] ) :- ( lower( Word, Lowercase_word ) ; Lowercase_word = Word ), convert_list_of_words_to_lowercase( Rest_of_words, Rest_of_lowercase_list ), !. count_total_line_number_in_file( File_name ) :- open( File_name, read, Stream ), see( Stream ), repeat, skip_line( Stream ), at_end_of_file, !, line_count( Stream, Counted_lines ), seen, close( Stream ), Lines_in_file is Counted_lines - 1, retractall( lines_in_file( _ ) ), assertz( lines_in_file( Lines_in_file ) ), !. read_text_from_file( File_name, First_line_number, Last_line_number ) :- lines_in_file( Lines_in_file ), First_line_number =< Lines_in_file, /* This can fail! */ ( Last_line_number =< Lines_in_file -> Valid_last_line_number is Last_line_number ; Valid_last_line_number is Lines_in_file ), /* If the text buffer does not consist all lines needed * read a new block from the file into the text buffer. * In other case read nothing from the file. */ ( text_buffer( First_line_number, _ ), text_buffer( Valid_last_line_number, _ ) ; use_wait_cursor, /* Forget lines that are not needed anymore. */ ( findall( Line_number, ( text_buffer( Line_number, _ ), Line_number < First_line_number, retractall( text_buffer( Line_number, _ ) ) ), _ ) ; true ), open( File_name, read, Stream ), see( Stream ), search_for_first_line( Stream, First_line_number ), /* Count the number of the last line in the new text buffer. */ inname_data( text_buffer_size_in_lines( Buffer_size ) ), ( First_line_number + Buffer_size =< Lines_in_file, Last_line_in_buffer is First_line_number + Buffer_size - 1 ; Last_line_in_buffer is Lines_in_file ), read_lines_from_file_into_buffer( Stream, Last_line_in_buffer ), seen, close( Stream ), use_normal_cursor ), !. read_text_from_file( _, _, _ ) :- retractall( text_buffer( _, _ ) ), !. /* Skip lines until the first line reached. */ search_for_first_line( Stream, First_line_number ) :- line_count( Stream, Line_number ), Line_number < First_line_number, skip_line( Stream ), search_for_first_line( Stream, First_line_number ), !. search_for_first_line( _, _ ) :- !. read_lines_from_file_into_buffer( Stream, Last_line_number ) :- line_count( Stream, Line_number ), Line_number =< Last_line_number, \+ at_end_of_file, /* Read the line if it is not yet in the memory and we're not at EOF. */ ( ( \+ text_buffer( Line_number, _ ), read_next_line( Stream, Next_line, [], 0 ), assertz( text_buffer( Line_number, Next_line ) ) ) ; skip_line( Stream ) ), read_lines_from_file_into_buffer( Stream, Last_line_number ), !. read_lines_from_file_into_buffer( _, _ ) :- !. read_next_line( Stream, Next_line_as_list_of_characters, List_of_characters, Characters_so_far_in_line ) :- ( at_end_of_file -> Next_line_as_list_of_characters = List_of_characters ; at_end_of_line -> skip_line( Stream ), Next_line_as_list_of_characters = List_of_characters ; otherwise -> get0( Character ), ( ( Character =\= 9, /* Character is not a tabulator character */ append( List_of_characters, [ Character ], New_list_of_characters ), Characters_after_this_one_in_line is Characters_so_far_in_line + 1, !, read_next_line( Stream, Next_line_as_list_of_characters, New_list_of_characters, Characters_after_this_one_in_line ) ) ; ( Total_number_of_spaces is Characters_so_far_in_line // 8 * 8 + 8 - Characters_so_far_in_line, add_tabulator_character_as_spaces_to_list( List_of_characters_with_tabulator, List_of_characters, 0, Total_number_of_spaces, Characters_so_far_in_line, Characters_in_line_after_operation ), !, read_next_line( Stream, Next_line_as_list_of_characters, List_of_characters_with_tabulator, Characters_in_line_after_operation ) ) ) ), !. add_tabulator_character_as_spaces_to_list( List_of_characters_with_tabulator, List_of_characters, Spaces_so_far, Total_number_of_spaces, Characters_so_far_in_line, Characters_in_line_after_operation ) :- Spaces_so_far < Total_number_of_spaces, /* This can fail! */ Spaces_after_this is Spaces_so_far + 1, Characters_after_this_in_line is Characters_so_far_in_line + 1, append( List_of_characters, [ 32 ], New_list_of_characters ), add_tabulator_character_as_spaces_to_list( List_of_characters_with_tabulator, New_list_of_characters, Spaces_after_this, Total_number_of_spaces, Characters_after_this_in_line, Characters_in_line_after_operation ), !. add_tabulator_character_as_spaces_to_list( List_of_characters, List_of_characters, _, _, Characters_so_far_in_line, Characters_so_far_in_line ) :- !. use_wait_cursor :- cursor_shapes( Wait_cursor, _ ), window_identifiers( control_window, Control_window ), window_identifiers( text_window, Text_window ), window_identifiers( name_candidates_window, Name_candidates_window ), put_window_attributes( Control_window, [ cursor( Wait_cursor ) ] ), put_window_attributes( Text_window, [ cursor( Wait_cursor ) ] ), put_window_attributes( Name_candidates_window, [ cursor( Wait_cursor ) ] ), flush, !. use_normal_cursor :- cursor_shapes( _, Selection_cursor ), window_identifiers( control_window, Control_window ), window_identifiers( text_window, Text_window ), window_identifiers( name_candidates_window, Name_candidates_window ), put_window_attributes( Control_window, [ cursor( none ) ] ), put_window_attributes( Text_window, [ cursor( none ) ] ), put_window_attributes( Name_candidates_window, [ cursor( Selection_cursor ) ] ), flush, !. write_text_to_window :- saved_unknown_name( Unknown_name_as_string, _, List_of_line_numbers, _ ), name( Unknown_name_as_string, Highlighted_word ), text_font( Font, Text_font_height, Text_font_ascent ), first_line_in_window( First_line_in_window ), max_number_of_lines_in_window( Max_number_of_lines_in_window ), Last_line_in_window is First_line_in_window + Max_number_of_lines_in_window - 1, retractall( unknown_names_in_line( _, _ ) ), get_number_of_unknown_names_in_each_line( First_line_in_window, Last_line_in_window, List_of_line_numbers ), window_identifiers( scroll_bar_window, Scroll_bar_window ), window_identifiers( text_window, Text_window ), clear_window( Text_window ), First_Y_coordinate is Text_font_ascent + 3, draw_lines_to_window( Text_window, 70, First_Y_coordinate, Font, Text_font_height, Text_font_ascent, First_line_in_window, Last_line_in_window, Highlighted_word ), update_scroll_bar( Scroll_bar_window, First_line_in_window, Last_line_in_window ), !. /* Lines with an unknown name are saved in a list as line numbers. If there are more * than one unknown name in some line there are also as many same line numbers in * the list as there are unknown names in this line. * For example, list: [ 9, 10, 10, 15 ... ] -> two unknown names in line 10 * Next routine makes this list easier to handle: * assertz( unknown_names_in_line( 9, 1 ) ), * assertz( unknown_names_in_line( 10, 2 ) ), ... * Now we get the number of unknown names in line 10 : unknown_names_in_line( 10, Number ) * -> Number = 2. */ get_number_of_unknown_names_in_each_line( First_line_in_window, Last_line_in_window, List_of_line_numbers ) :- /* Check if next line number will be shown in text window. */ append( [ Next_line_number | Rest_of_line_numbers ], [], List_of_line_numbers ), Next_line_number =< Last_line_in_window, ( ( Next_line_number >= First_line_in_window, /* Next line number is viewable in window, count how many same line numbers there are in the list. */ findall( Next_line_number, member( Next_line_number, List_of_line_numbers ), List_of_used_numbers ), append3( First_part, List_of_used_numbers, Rest_part, List_of_line_numbers ), append( First_part, Rest_part, List_after_all_same_numbers_found ), length( List_of_used_numbers, Total_number_of_unknown_names_in_line ), assertz( unknown_names_in_line( Next_line_number, Total_number_of_unknown_names_in_line ) ) ) ; List_after_all_same_numbers_found = Rest_of_line_numbers ), get_number_of_unknown_names_in_each_line( First_line_in_window, Last_line_in_window, List_after_all_same_numbers_found ), !. get_number_of_unknown_names_in_each_line( _, _, _ ) :- !. draw_lines_to_window( Text_window, Text_X_coordinate, Text_Y_coordinate, Font, Text_font_height, Text_font_ascent, Number_of_this_line, Last_line_in_window, Highlighted_word ) :- text_styles( Normal_text_style, _, _ ), text_buffer( Number_of_this_line, Next_line_as_list_of_characters ), /* Display every fifth line number. */ ( Number_of_this_line mod 5 =:= 0 -> name( Number_of_this_line, Number_as_list_of_characters ), text_width( Font, Number_as_list_of_characters, Width ), Number_X_coordinate is 55 - Width, draw_string( Text_window, Normal_text_style, Number_X_coordinate, Text_Y_coordinate, Number_as_list_of_characters ) ; otherwise -> true ), ( ( Next_line_as_list_of_characters \== [], ( unknown_names_in_line( Number_of_this_line, Number_of_unknown_names ), /* This can fail! */ split_text_line_into_parts( Next_line_as_list_of_characters, Highlighted_word, _, List_of_parts_of_line ), draw_line_with_unknown_name_to_window( Text_window, Number_of_unknown_names, 0, List_of_parts_of_line, Font, Text_X_coordinate, Text_Y_coordinate ) ; draw_image_string( Text_window, Normal_text_style, Text_X_coordinate, Text_Y_coordinate, Next_line_as_list_of_characters ) ) ) ; true ), Next_text_Y_coordinate is Text_Y_coordinate + Text_font_height, Number_of_next_line is Number_of_this_line + 1, max_number_of_lines_in_window( Max_number_of_lines_in_window ), /* Draw the next line if it fits into the the text window. */ ( Number_of_next_line =< Last_line_in_window, draw_lines_to_window( Text_window, Text_X_coordinate, Next_text_Y_coordinate, Font, Text_font_height, Text_font_ascent, Number_of_next_line, Last_line_in_window, Highlighted_word ) ; true ), !. draw_lines_to_window( _, _, _, _, _, _, _, _, _ ) :- !. /* The line is cut into parts: normal text, highlighted text, normal text, ... Every highlighted text part has to be checked if it really is an unknown name. */ draw_line_with_unknown_name_to_window( _, _, _, [], _, _, _ ) :- !. draw_line_with_unknown_name_to_window( Text_window, Number_of_unknown_names, Unknown_names_drawn, List_of_parts_of_line, Font, Normal_text_X_coordinate, Text_Y_coordinate ) :- text_styles( Normal_text_style, Inverse_text_style, _ ), inname_data( list_of_illegal_characters_next_to_unknown_name( List_of_illegal_characters ) ), get_unknown_name_and_bordering_parts_of_line( Word_before_unknown_name, Unknown_name, Word_after_unknown_name, List_of_parts_of_line, Rest_of_parts_for_next_call ), ( ( Word_before_unknown_name \== [], Word_before_unknown_name \== [ 0 ], draw_image_string( Text_window, Normal_text_style, Normal_text_X_coordinate, Text_Y_coordinate, Word_before_unknown_name ), text_width( Font, Word_before_unknown_name, Normal_text_width ), Unknown_name_X_coordinate is Normal_text_X_coordinate + Normal_text_width ) ; Unknown_name_X_coordinate is Normal_text_X_coordinate ), Unknown_name \== [], /* If an empty list the line is already drawn -> fail */ ( ( /* If all unknown names drawn fail and use normal style. */ Unknown_names_drawn < Number_of_unknown_names, /* Check if the name is really the unknown name. */ get_first_character_in_list( Word_after_unknown_name, First_character_in_word_after ), character_is_legal( First_character_in_word_after, List_of_illegal_characters ), get_last_character_in_list( Word_before_unknown_name, Last_character_in_word_before ), character_is_legal( Last_character_in_word_before, List_of_illegal_characters ), draw_image_string( Text_window, Inverse_text_style, Unknown_name_X_coordinate, Text_Y_coordinate, Unknown_name ), Unknown_names_drawn_after_this is Unknown_names_drawn + 1 ) ; ( draw_image_string( Text_window, Normal_text_style, Unknown_name_X_coordinate, Text_Y_coordinate, Unknown_name ), Unknown_names_drawn_after_this is Unknown_names_drawn ) ), text_width( Font, Unknown_name, Unknown_name_width ), Next_normal_text_X_coordinate is Unknown_name_X_coordinate + Unknown_name_width, draw_line_with_unknown_name_to_window( Text_window, Number_of_unknown_names, Unknown_names_drawn_after_this, Rest_of_parts_for_next_call, Font, Next_normal_text_X_coordinate, Text_Y_coordinate ), !. draw_line_with_unknown_name_to_window( _, _, _, _, _, _, _ ) :- !. get_unknown_name_and_bordering_parts_of_line( Word_before_unknown_name, Unknown_name, Word_after_unknown_name, [ Word_before_unknown_name | Rest_of_parts_of_line ], Rest_of_parts_for_next_call ) :- get_unknown_name_from_list( Word_before_unknown_name, Unknown_name, Word_after_unknown_name, Rest_of_parts_of_line, Rest_of_parts_for_next_call ), !. get_unknown_name_from_list( Word_before_unknown_name, Unknown_name, Word_after_unknown_name, [ Unknown_name | Rest_of_parts_for_next_call ], Rest_of_parts_for_next_call ) :- get_word_after_unknown_name_from_list( Word_before_unknown_name, Unknown_name, Word_after_unknown_name, Rest_of_parts_for_next_call, Rest_of_parts_for_next_call ), !. get_unknown_name_from_list( Word_before_unknown_name, [], [], _, [] ) :- !. get_word_after_unknown_name_from_list( Word_before_unknown_name, Unknown_name, Word_after_unknown_name, [ Word_after_unknown_name | _ ], Rest_of_parts_for_next_call ) :- !. character_is_legal( Character, [] ) :- !. character_is_legal( Character, [ Illegal_character | Rest_of_illegal_characters ] ) :- Character \== Illegal_character, character_is_legal( Character, Rest_of_illegal_characters ), !. get_first_character_in_list( [ First_character | _ ], First_character ) :- !. get_last_character_in_list( List, Last_character ) :- append( _, [ Last_character ], List ), !. /* This is a mess and should be recoded. */ split_text_line_into_parts( [], _, _, [ [] ] ) :- !. split_text_line_into_parts( Text_line, Unknown_name, List_of_parts_of_line, Final_list_of_parts_of_line ) :- append3( First_part_of_line, Unknown_name, Rest_of_text_line, Text_line ), ( First_part_of_line == [] -> First_part_as_it_is_saved_into_list = [ 0 ] ; otherwise -> First_part_as_it_is_saved_into_list = First_part_of_line ), append( List_of_parts_of_line, [ First_part_as_it_is_saved_into_list ], List_of_parts_of_line_with_first_part ), append( List_of_parts_of_line_with_first_part, [ Unknown_name ], List_of_parts_of_line_after_this_step ), split_rest_of_text_line_into_parts( Rest_of_text_line, Unknown_name, List_of_parts_of_line_after_this_step, Final_list_of_parts_of_line ),!. split_text_line_into_parts( Text_line, _, List_of_parts_of_line, Final_list_of_parts_of_line ) :- append( List_of_parts_of_line, [ Text_line ], New_list_of_parts_of_line_with_rest_of_text_line ), append( New_list_of_parts_of_line_with_rest_of_text_line, [ [] ], New_list_of_parts_of_line_with_empty_string_as_unknown_name ), append( New_list_of_parts_of_line_with_empty_string_as_unknown_name, [ [ 0 ] ], Final_list_of_parts_of_line ), !. split_rest_of_text_line_into_parts( [], _, List_of_parts_of_line, Final_list_of_parts_of_line) :- append( List_of_parts_of_line, [ [ 0 ] ], Final_list_of_parts_of_line ), !. split_rest_of_text_line_into_parts( Text_line, Unknown_name, List_of_parts_of_line, Final_list_of_parts_of_line ) :- append3( Next_part_of_line, Unknown_name, Rest_of_text_line, Text_line ), /* Previous call can fail! */ append( List_of_parts_of_line, [ Next_part_of_line ], List_of_parts_of_line_with_next_part), append( List_of_parts_of_line_with_next_part, [ Unknown_name ], List_of_parts_of_line_after_this_step ), split_rest_of_text_line_into_parts( Rest_of_text_line, Unknown_name, List_of_parts_of_line_after_this_step, Final_list_of_parts_of_line ),!. split_rest_of_text_line_into_parts( Text_line, _, List_of_parts_of_line, Final_list_of_parts_of_line ) :- append( List_of_parts_of_line, [ Text_line ], New_list_of_parts_of_line_with_rest_of_text_line ), append( New_list_of_parts_of_line_with_rest_of_text_line, [ [] ], New_list_of_parts_of_line_with_empty_string_as_unknown_name ), append( New_list_of_parts_of_line_with_empty_string_as_unknown_name, [ [ 0 ] ], Final_list_of_parts_of_line ), !. show_file_name :- window_identifiers( file_name_window, File_name_window ), clear_window( File_name_window ), /* If presently entering a new file name rewrite this name * else rewrite the name of the present file. */ ( keyboard_is_grabbed_for( entering_new_file ), user_given_name_as_list( entering_new_file, File_name ) ; program_file_name( File_name ) ), text_font( _, _, Text_font_ascent ), Y_coordinate is Text_font_ascent + 3, draw_string( File_name_window, 8, Y_coordinate, File_name ), flush, !. show_file_name :- !. show_dictionary_name :- window_identifiers( domain_dictionary_window, Domain_dictionary_window ), clear_window( Domain_dictionary_window ), ( keyboard_is_grabbed_for( entering_new_dictionary ), user_given_name_as_list( entering_new_dictionary, Dictionary_name ) ; domain_dictionary_name( Dictionary_name ) ), text_font( _, _, Text_font_ascent ), Y_coordinate is Text_font_ascent + 3, draw_string( Domain_dictionary_window, 8, Y_coordinate, Dictionary_name ), flush, !. show_dictionary_name :- !. show_unknown_name :- saved_unknown_name( Unknown_name_as_string, List_of_all_words, _, List_of_unknown_words ), window_identifiers( unknown_name_window, Unknown_name_window ), text_font( Text_font, Text_font_height, Text_font_ascent ), Y_coordinate is Text_font_ascent + 3, Line_Y_coordinate is Text_font_height + 4, clear_window( Unknown_name_window ), draw_string( Unknown_name_window, 8, Y_coordinate, Unknown_name_as_string ), underline_unknown_parts_in_name( Unknown_name_window, List_of_all_words, Unknown_name_as_string, List_of_unknown_words, Text_font, 8, Line_Y_coordinate ), flush, !. underline_unknown_parts_in_name( _, _, _, [], _, _, _ ) :- !. underline_unknown_parts_in_name( Unknown_name_window, [ Word_as_string | Rest_of_all_words ], Unknown_name_as_mixedcase_string, Unknown_words, Text_font, First_X_coordinate, Line_Y_coordinate ) :- lower( Unknown_name_as_mixedcase_string, Unknown_name_as_lowercase_string ), lower( Word_as_string, Word_as_lowercase_string ), name( Unknown_name_as_mixedcase_string, Unknown_name_as_mixedcase_list ), name( Unknown_name_as_lowercase_string, Unknown_name_as_lowercase_list ), name( Word_as_lowercase_string, Word_as_lowercase_list ), sublist( Unknown_name_as_lowercase_list, Word_as_lowercase_list, Offset_for_word, Length_of_word ), sublist( Unknown_name_as_mixedcase_list, Word_as_mixedcase_list, Offset_for_word, Length_of_word ), append3( First_part_as_mixedcase_list, Word_as_mixedcase_list, Rest_part_of_unknown_name_as_list, Unknown_name_as_mixedcase_list ), ( First_part_as_mixedcase_list \== [] /* text_width with [] does not give zero */ -> text_width( Text_font, First_part_as_mixedcase_list, Pixel_length_of_first_part ) ; Pixel_length_of_first_part is 0 ), ( Word_as_mixedcase_list \== [] -> text_width( Text_font, Word_as_mixedcase_list, Pixel_length_of_word ) ; Pixel_length_of_unknown_name is 0 ), New_first_X_coordinate is First_X_coordinate + Pixel_length_of_first_part + Pixel_length_of_word, append( [ Next_unknown_word_as_string | Rest_of_unknown_words ], [], Unknown_words ), lower( Next_unknown_word_as_string, Next_unknown_word_as_lowercase_string ), /* Underline the word if it is the next not underlined unknown word. */ ( Next_unknown_word_as_lowercase_string == Word_as_lowercase_string, Line_start_X_coordinate is First_X_coordinate + Pixel_length_of_first_part, Line_end_X_coordinate is New_first_X_coordinate, Line_hook_Y_coordinate is Line_Y_coordinate - 2, draw_lines( Unknown_name_window, [ point( Line_start_X_coordinate, Line_hook_Y_coordinate ), point( Line_start_X_coordinate, Line_Y_coordinate ), point( Line_end_X_coordinate, Line_Y_coordinate ), point( Line_end_X_coordinate, Line_hook_Y_coordinate ) ] ), Unknown_words_for_next_call = Rest_of_unknown_words ; Unknown_words_for_next_call = Unknown_words ), name( Rest_part_of_unknown_name_as_string, Rest_part_of_unknown_name_as_list ), underline_unknown_parts_in_name( Unknown_name_window, Rest_of_all_words, Rest_part_of_unknown_name_as_string, Unknown_words_for_next_call, Text_font, New_first_X_coordinate, Line_Y_coordinate ), !. show_selected_name_candidate :- window_identifiers( change_to_window, Change_to_window ), clear_window( Change_to_window ), ( ( user_given_name_as_list( entering_new_name, Substitution_list ), Substitution_list \== [], text_styles( Normal_text_style, _, _ ), text_font( _, _, Text_font_ascent ), Y_coordinate is Text_font_ascent + 3, draw_string( Change_to_window, Normal_text_style, 8, Y_coordinate, Substitution_list ), flush ) ; true ), !. get_name_from_list( [ First_name | Rest_of_names ], 1, First_name ) :- !. get_name_from_list( [ First_name | Rest_of_names ], Number_of_selected_name, Name_as_list_of_words ) :- Next_number_of_name is Number_of_selected_name - 1, get_name_from_list( Rest_of_names, Next_number_of_name, Name_as_list_of_words ), !. show_list_of_name_candidates( Show_selection, Clear_window_before_drawing ) :- list_of_name_candidates( List_of_name_candidates ), window_identifiers( name_candidates_window, Name_candidates_window), selected_name_candidate( Selected_name_candidate ), text_font( Text_font, Text_font_height, Text_font_ascent ), First_text_Y_coordinate is Text_font_ascent + 3, ( Clear_window_before_drawing -> clear_window( Name_candidates_window ) ; otherwise -> true ), draw_list_of_name_candidates( List_of_name_candidates, Name_candidates_window, First_text_Y_coordinate, Text_font_height, Selected_name_candidate, 1, Show_selection ), flush, !. show_list_of_name_candidates( _, _ ) :- !. draw_list_of_name_candidates( [], _, _, _, _, _, _ ) :- More_button_state = off, first_name_candidate_in_window( First_name_candidate_in_window ), ( First_name_candidate_in_window =:= 1 -> Previous_button_state = off ; Previous_button_state = on ), set_activity_state_for_all_buttons( same, same, same, More_button_state, Previous_button_state, same, same, same ), !. draw_list_of_name_candidates( [ First_name_candidate | Rest_of_name_candidates ], Target_window, Y_coordinate, Text_font_height, Selected_name_candidate, This_name_candidate, Show_selection ) :- first_name_candidate_in_window( First_name_candidate_in_window ), number_of_name_candidates( _, Lines_in_window ), ( ( This_name_candidate >= First_name_candidate_in_window, convert_list_of_words_to_underscored_string( First_name_candidate, Name_candidate_as_string ), /* When one of the name candidates is previously used as a substi- tution for the unknown name, it will be marked with four stars on the display. Added 25.4.1995. */ ( previously_used_name_substitution_found -> ( previous_name_substitution( _, Name_candidate_as_string ) -> string_append( Name_candidate_as_string, ' ****', String_to_be_displayed ); otherwise -> String_to_be_displayed = Name_candidate_as_string ) ; otherwise -> String_to_be_displayed = Name_candidate_as_string ), ( Selected_name_candidate =:= This_name_candidate, Show_selection -> text_styles( _, Text_style, _ ) /* Highlight */ ; otherwise -> text_styles( Text_style, _, _ ) /* Normal style */ ), draw_image_string( Target_window, Text_style, 8, Y_coordinate, String_to_be_displayed ), Next_Y_coordinate is Y_coordinate + Text_font_height ) ; Next_Y_coordinate is Y_coordinate /* No change */ ), Next_name_candidate is This_name_candidate + 1, Next_name_candidate =< First_name_candidate_in_window + Lines_in_window - 1, !, draw_list_of_name_candidates( Rest_of_name_candidates, Target_window, Next_Y_coordinate, Text_font_height, Selected_name_candidate, Next_name_candidate, Show_selection ), !. draw_list_of_name_candidates( _, _, _, _, _, This_name_candidate, _ ) :- number_of_name_candidates( Number_of_name_candidates, _ ), first_name_candidate_in_window( First_name_candidate_in_window ), ( First_name_candidate_in_window =:= 1 -> Previous_button_state = off ; Previous_button_state = on ), ( This_name_candidate + 1 =< Number_of_name_candidates -> More_button_state = on ; More_button_state = off ), set_activity_state_for_all_buttons( same, same, same, More_button_state, Previous_button_state, same, same, same ), !. name_candidate_selected( Pointer_Y_coordinate ) :- /* Do not allow selection if entering a new name for dictionary or file. */ ( keyboard_is_grabbed_for( Some_purpose ) ; Some_purpose = nothing ), !, ( Some_purpose == entering_new_name ; Some_purpose == nothing ), text_font( _, Text_font_height, _ ), first_name_candidate_in_window( First_name_candidate_in_window ), number_of_name_candidates( Number_of_name_candidates, Lines_in_window ), selected_name_candidate( Previously_selected_name_candidate ), Selected_name_candidate is ( Pointer_Y_coordinate - 3 ) // Text_font_height + First_name_candidate_in_window, ( ( Selected_name_candidate >= First_name_candidate_in_window + Lines_in_window, Real_selected_name_candidate is First_name_candidate_in_window + Lines_in_window - 1 ) ; Real_selected_name_candidate is Selected_name_candidate ), inactivate_current_text_input_window, ( ( Real_selected_name_candidate =< Number_of_name_candidates, ( ( Previously_selected_name_candidate =:= 0, set_activity_state_for_all_buttons( same, on, same, same, same, same, same, same ) /* Change */ ) ; true ), discard_user_given_name( entering_new_name ), retractall( selected_name_candidate( _ ) ), assertz( selected_name_candidate( Real_selected_name_candidate ) ), list_of_name_candidates( List_of_name_candidates ), get_name_from_list( List_of_name_candidates, Real_selected_name_candidate, Name_as_list_of_words ), convert_list_of_words_to_underscored_string( Name_as_list_of_words, Underscored_string ), name( Underscored_string, Underscored_list ), assertz( user_given_name_as_list( entering_new_name, Underscored_list ) ), show_list_of_name_candidates( true, false ), show_selected_name_candidate ) ; ( discard_user_given_name( entering_new_name ), retractall( selected_name_candidate( _ ) ), assertz( selected_name_candidate( 0 ) ), set_activity_state_for_all_buttons( same, off, same, same, same, same, same, same ), /* Change */ show_list_of_name_candidates( true, false ), show_selected_name_candidate ) ), !. find_font( Font_data, Font ) :- write( 'Looking for font: ' ), nl, inname_data( Font_data, Font_specification ), write( ' ' ), write( Font_specification ), ( current_font( Font_specification, Font_name ) ; write( ' ... Not found. ' ), nl, fail ), load_font( Font_name, Font ), write( ' ... Found. ' ), nl, !. find_font( _, _ ) :- nl, write( 'Error: cannot find suitable font. ' ), nl, !, fail. /* Routines for window and button handling. */ open_text_window( Text_window, Scroll_bar_window, Width, Height, X, Y, Font, Title ) :- colors_used( Black, _, _, Gray, _, White ), create_window( Text_window, [ size( Width, Height ), position( X, Y ), background( White ), border_width( 2 ), property( 'WM_NAME', Title ), property( 'WM_ICON_NAME', 'InName Program' ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Width, Height ), size( 100, 60 ), none, none, none ) ), mapped( false ), callback( configure_notify, [ size( New_width, New_height ) ], text_window_size_changed( New_width, New_height ) ), callback( expose, [ count( 0 ) ], refresh_text_window ) ], [ font( Font ), foreground( Black ) ] ), Scroll_bar_height is Height - 20, create_window( Scroll_bar_window, [ size( 4, Scroll_bar_height ), position( 5, 10 ), background( Gray ), border_width( 0 ), parent( Text_window ), mapped( true ), callback( expose, [ count( 0 ) ], refresh_text_window ) ], [ foreground( Black ) ] ), text_font( _, Text_font_height, _ ), Max_number_of_lines_in_window is ( Height - 3 ) // Text_font_height, assertz( max_number_of_lines_in_window( Max_number_of_lines_in_window ) ), !. open_control_window( Control_window, Unknown_name_window, Change_to_window, Name_candidates_window, Name_candidates_window_height, Domain_dictionary_window, File_name_window, Width, Height, X, Y, Font ) :- colors_used( Black, _, Middlegray, _, _, White), create_window( Control_window, [ size( Width, Height ), position( X, Y ), background( Middlegray ), border_width( 2 ), save_under( true ), property( 'WM_NAME', 'InName Command Window' ), property( 'WM_ICON_NAME', 'InName Command' ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Width, Height ), size( Width, Height ), none, none, none ) ), mapped( false ), callback( configure_notify, [ size( New_width, New_height ) ], control_window_size_changed( New_width, New_height ) ), callback( expose, [ count( 0 ) ], refresh_control_window( Control_window ) ) ], [ font( Font ), foreground( Black ) ] ), Child_window_width is Width - 140, Child_window_X_coordinate is 130, /* 130=140-10 */ create_window( File_name_window, [ position( Child_window_X_coordinate, 15 ), size( Child_window_width, 20 ), background( White ), border_width( 1 ), parent( Control_window ), mapped( true ), callback( button_press( [ 1 ] ), [], grab_keyboard_for( entering_new_file ) ), callback( key_press, [ keysym( Key_symbol ) ], exit_from_event_handling( new_file_entered ), key_pressed_in_window( Key_symbol ) ), callback( expose, [ count( 0 ) ], show_file_name ) ], [ font( Font ), foreground( Black ) ] ), create_window( Domain_dictionary_window, [ position( Child_window_X_coordinate, 40 ), size( Child_window_width, 20 ), background( White ), border_width( 1 ), parent( Control_window ), mapped( true ), callback( button_press( [ 1 ] ), [], grab_keyboard_for( entering_new_dictionary ) ), callback( key_press, [ keysym( Key_symbol ) ], key_pressed_in_window( Key_symbol ) ), callback( expose, [ count( 0 ) ], show_dictionary_name ) ], [ font( Font ), foreground( Black ) ] ), create_window( Unknown_name_window, [ position( Child_window_X_coordinate, 75 ), size( Child_window_width, 20 ), background( White ), border_width( 1 ), parent( Control_window ), mapped( true ), callback( expose, [ count( 0 ) ], show_unknown_name ) ], [ font( Font ), foreground( Black ) ] ), create_window( Change_to_window, [ position( Child_window_X_coordinate, 100 ), size( Child_window_width, 20 ), background( White ), border_width( 1 ), parent( Control_window ), mapped( true ), callback( expose, [ count( 0 ) ], show_selected_name_candidate ), callback( button_press, [ button( Button ), x( Pointer_X_coordinate ) ], button_pressed_in_change_to_window( Button, Pointer_X_coordinate ) ), callback( key_press, [ keysym( Key_symbol ) ], key_pressed_in_window( Key_symbol ) ) ], [ font( Font ), foreground( Black ) ] ), cursor_shapes( _, Selection_cursor ), create_window( Name_candidates_window, [ position( Child_window_X_coordinate, 125 ), size( Child_window_width, Name_candidates_window_height ), background( White ), border_width( 1 ), parent( Control_window ), cursor( Selection_cursor ), mapped( true ), callback( expose, [ count( 0 ) ], show_list_of_name_candidates( false, false ) ), callback( button_press, [ y( Pointer_Y_coordinate ) ], name_candidate_selected( Pointer_Y_coordinate ) ), callback( button_release, [], show_list_of_name_candidates( false, false ) ) ], [ font( Font ), foreground( Black ) ] ), !. text_window_size_changed( New_text_window_width, New_text_window_height ) :- window_identifiers( scroll_bar_window, Scroll_bar_window ), window_sizes( Old_text_window_width, Old_text_window_height, Control_window_width, Control_window_height ), ( New_text_window_width =:= Old_text_window_width, New_text_window_height =:= Old_text_window_height -> true ; New_scroll_bar_height is New_text_window_height - 20, put_window_attributes( Scroll_bar_window, [ height( New_scroll_bar_height ) ] ), retractall( window_sizes( _, _, _, _ ) ), assertz( window_sizes( New_text_window_width, New_text_window_height, Control_window_width, Control_window_height ) ), text_font( _, Text_font_height, _ ), max_number_of_lines_in_window( Old_number_of_lines_in_window ), Max_number_of_lines_in_window is ( New_text_window_height - 3 ) // Text_font_height, retractall( max_number_of_lines_in_window( _ ) ), assertz( max_number_of_lines_in_window( Max_number_of_lines_in_window ) ), ( Max_number_of_lines_in_window =< Old_number_of_lines_in_window -> true ; program_file_name( File_name ), first_line_in_window( First_line_in_window ), Last_line_in_window is First_line_in_window + Max_number_of_lines_in_window - 1, read_text_from_file( File_name, First_line_in_window, Last_line_in_window ) ) ), !. control_window_size_changed( New_control_window_width, New_control_window_height ) :- window_sizes( Text_window_width, Text_window_height, Old_control_window_width, Old_control_window_height ), ( New_control_window_width =:= Old_control_window_width -> true ; retractall( window_sizes( _, _, _, _ ) ), assertz( window_sizes( Text_window_width, Text_window_height, New_control_window_width, New_control_window_height ) ), ( New_control_window_width - 140 < 20 -> New_child_window_width is 20 ; otherwise -> New_child_window_width is New_control_window_width - 140 ), window_identifiers( unknown_name_window, Unknown_name_window ), window_identifiers( change_to_window, Change_to_window ), window_identifiers( name_candidates_window, Name_candidates_window ), window_identifiers( domain_dictionary_window, Domain_dictionary_window ), window_identifiers( file_name_window, File_name_window ), put_window_attributes( Unknown_name_window, [ width( New_child_window_width ) ] ), put_window_attributes( Change_to_window, [ width( New_child_window_width ) ] ), put_window_attributes( Name_candidates_window, [ width( New_child_window_width ) ] ), put_window_attributes( Domain_dictionary_window, [ width( New_child_window_width ) ] ), put_window_attributes( File_name_window, [ width( New_child_window_width ) ] ) ), !. destroy_all_windows_and_global_data :- window_identifiers( text_window, Text_window ), window_identifiers( control_window, Control_window ), destroy_subwindows( Text_window ), destroy_subwindows( Control_window ), destroy_window( Text_window ), destroy_window( Control_window ), /* clean_up, For some reason this command is not recognized, it should be. */ flush, /* Destroy the global data, this makes it possible to restart the program from * the Prolog interpreter without recompiling the file. */ retractall( window_sizes( _, _, _, _ ) ), retractall( window_identifiers( _, _ ) ), retractall( button_identifiers( _, _, _, _, _, _, _, _ ) ), retractall( button_label( _, _ ) ), retractall( button_activity_states( _, _, _, _, _, _, _, _ ) ), retractall( saved_button_activity_states( _, _, _, _, _, _, _, _ ) ), retractall( button_previously_pressed( _ ) ), retractall( button_images( _, _, _ ) ), retractall( cursor_shapes( _, _ ) ), retractall( pop_up_text_lines( _, _ ) ), retractall( program_file_name( _ ) ), retractall( domain_dictionary_name( _ ) ), retractall( text_in_window( _ ) ), retractall( first_line_in_window( _ ) ), retractall( colors_used( _, _, _, _, _, _ ) ), retractall( text_font( _, _, _ ) ), retractall( button_font( _, _, _ ) ), retractall( text_styles( _, _, _ ) ), retractall( button_size( _, _ ) ), retractall( max_number_of_lines_in_window( _ ) ), retractall( lines_in_file( _ ) ), retractall( saved_unknown_name( _, _, _, _ ) ), retractall( unknown_names_in_line( _, _ ) ), retractall( list_of_name_candidates( _ ) ), retractall( number_of_name_candidates( _, _ ) ), retractall( first_name_candidate_in_window( _ ) ), retractall( selected_name_candidate( _ ) ), retractall( text_input_window_when( _, _ ) ), retractall( user_given_name( _, _ ) ), retractall( user_given_name_as_list( _, _ ) ), retractall( keyboard_is_grabbed_for( _ ) ), retractall( cursor_coordinate_in_window( _, _ ) ), retractall( possible_word_substitution( _ ) ), retractall( name_candidate( _ ) ), retractall( word_substitution( _, _ ) ), retractall( name_substitution( _, _, _ ) ), retractall( unknown_name( _, _, _, _ ) ), retractall( general_counters( _, _ ) ), retractall( domain_word( _ ) ), !. refresh_text_window :- write_text_to_window, !. refresh_control_window( Control_window ) :- colors_used( Black, _, _, _, _, _ ), button_font( Font, _, Button_font_ascent ), put_graphics_attributes( Control_window, [ foreground( Black ), font( Font ) ] ), Y_offset is Button_font_ascent + 4, draw_string_with_offset( Control_window, 10, 15, Y_offset, "File name:" ), draw_string_with_offset( Control_window, 10, 40, Y_offset, "Domain dictionary:" ), draw_string_with_offset( Control_window, 10, 75, Y_offset, "Unknown name:" ), draw_string_with_offset( Control_window, 10, 100, Y_offset, "Change to:" ), draw_string_with_offset( Control_window, 10, 125, Y_offset, "Name candidates:" ), !. draw_string_with_offset( Window, X, Y, Y_offset, String ) :- New_Y_coordinate is Y + Y_offset, draw_string( Window, X, New_Y_coordinate, String ), !. update_scroll_bar( Scroll_bar_window, First_line_in_window, Last_line_in_window ) :- lines_in_file( Lines_in_file ), window_sizes( _, Text_window_height, _, _ ), One_line_in_bar_as_pixels is ( Text_window_height - 17 ) / Lines_in_file, ( Last_line_in_window > Lines_in_file -> Real_last_line_in_window is Lines_in_file ; otherwise -> Real_last_line_in_window is Last_line_in_window ), Bar_top is integer( ( First_line_in_window - 1 ) * One_line_in_bar_as_pixels ), ( ( Real_last_line_in_window - First_line_in_window + 1 ) * One_line_in_bar_as_pixels > 2 -> Bar_height is integer( ( Real_last_line_in_window - First_line_in_window + 1 ) * One_line_in_bar_as_pixels ) ; otherwise -> Bar_height is 2 ), clear_window( Scroll_bar_window ), fill_rectangle( Scroll_bar_window, 0, Bar_top, 4, Bar_height ), flush, !. /* Pop up a window, draw info text lines, show list of something on white * background / function as input window, create ok and cancel buttons, wait for answer. * Map_list_window == false -> do not map (show) the list window, set height to 1, * Activate_list_window_for_input must be false, * List_of_list_window_text_lines can be empty * Map_list_window == true -> map the list window, * count the height using the number of lines to show * Activate_list_window_for_input == true -> grab keyboard for list window, * function as a text input window, * refresh redraws typed characters * Activate_list_window_for_input == false -> use window for viewing text lines, * refresh redraws the list of text lines * Doing_what (when Activate_list_window_for_input == true) tells the purpose * of text typed by user, so far Doing_what should ALWAYS be 'entering_pop_up_text', * text is saved in user_given_name_as_list( Doing_what, Text_as_list ), * Doing_what also affects the keys which are accepted * (key_pressed_in_window(Win) controls this). * Answer returns ok/cancel according to the button pressed by user. */ pop_up_window_with_text( Pop_up_width, Ok_label, Map_ok_button, Cancel_label, Map_cancel_button, List_of_info_text_lines, List_of_list_window_text_lines, Map_list_window, Activate_list_window_for_input, Doing_what, Answer ) :- /* Prevent keyboard grabbing, this has no effect on pop up window itself. */ retractall( is_keyboard_grabbing_allowed( _ ) ), asserta( is_keyboard_grabbing_allowed( false ) ), retractall( pop_up_text_lines( _, _ ) ), assertz( pop_up_text_lines( List_of_info_text_lines, List_of_list_window_text_lines ) ), save_present_button_activity_states, set_activity_state_for_all_buttons( off, off, off, off, off, on, on, off ), colors_used( Black, _, Middlegray, _, _, White ), button_font( Button_font, Button_font_height, _ ), text_font( Text_font, Text_font_height, _ ), window_identifiers( control_window, Control_window ), length( List_of_list_window_text_lines, Number_of_lines_in_list_window ), length( List_of_info_text_lines, Number_of_info_text_lines ), List_window_Y is Number_of_info_text_lines * ( Button_font_height + 5 ) + 15, ( ( Activate_list_window_for_input == true ; Number_of_lines_in_list_window =:= 1 ) -> List_window_height is 20, Pop_up_height is List_window_Y + List_window_height + 45 ; Map_list_window == false -> List_window_height is 1, Pop_up_height is List_window_Y + 40 ; otherwise -> List_window_height is Number_of_lines_in_list_window * Text_font_height + 6, Pop_up_height is List_window_Y + List_window_height + 45 ), List_window_width is Pop_up_width - 30, Button_Y_coordinate is Pop_up_height - 30, Ok_button_X_coordinate is Pop_up_width - 186, Cancel_button_X_coordinate is Pop_up_width - 96, create_window( Shadow_window, [ size( Pop_up_width, Pop_up_height ), position( 47, 130 ), background( Black ), border_width( 0 ), save_under( true ), parent( Control_window ), mapped( false ) ] ), create_window( Pop_up_window, [ size( Pop_up_width, Pop_up_height ), position( 40, 123 ), background( Middlegray ), border_width( 1 ), save_under( true ), parent( Control_window ), callback( expose, [ count( 0 ) ], refresh_pop_up_window( Pop_up_window ) ), mapped( false ) ], [ foreground( Black ), font( Button_font ) ] ), create_window( List_window, [ size( List_window_width, List_window_height ), position( 20, List_window_Y ), background( White ), border_width( 1 ), parent( Pop_up_window ), callback( expose, [ count( 0 ) ], refresh_pop_up_list_window( List_window ) ), callback( key_press, [ keysym( Key_symbol ) ], key_pressed_in_window( Key_symbol ) ), mapped( Map_list_window ) ], [ foreground( Black ), font( Text_font ) ] ), create_ok_button( Ok_button, Map_ok_button, Ok_button_X_coordinate, Button_Y_coordinate, Pop_up_window, Button_font ), create_cancel_button( Cancel_button, Map_cancel_button, Cancel_button_X_coordinate, Button_Y_coordinate, Pop_up_window, Button_font ), set_activity_state_for_all_buttons( same, same, same, same, same, on, on, same ), put_window_attributes( Pop_up_window, [ mapped( true ) ] ), put_window_attributes( Shadow_window, [ mapped( true ) ] ), flush, ( Activate_list_window_for_input == true -> asserta( text_input_window_when( Doing_what, List_window ) ), ( grab_keyboard_for( Doing_what ) ; true ) ; otherwise -> true ), /* Save the identifiers of the newly created buttons */ retract( button_identifiers( Button_1, Button_2, Button_3, Button_4, Button_5, _, _, Button_8 ) ), assertz( button_identifiers( Button_1, Button_2, Button_3, Button_4, Button_5, Ok_button, Cancel_button, Button_8 ) ), assertz( button_label( Ok_button, Ok_label ) ), assertz( button_label( Cancel_button, Cancel_label ) ), /* Wait until Ok or Cancel pressed */ handle_events( exit_pop_up_event_handling( Answer ) ), /* Erase cursor character in text list and window */ ( Activate_list_window_for_input == true -> erase_cursor_in_user_given_name_as_list( Doing_what ) ; otherwise -> true ), /* Destroy the pop up window system */ retract( button_label( Ok_button, _ ) ), retract( button_label( Cancel_button, _ ) ), retractall( text_input_window_when( Doing_what, _ ) ), destroy_subwindows( Pop_up_window ), destroy_window( Shadow_window ), destroy_window( Pop_up_window ), set_activity_state_for_all_buttons( as_saved_before ), retractall( is_keyboard_grabbing_allowed( _ ) ), assertz( is_keyboard_grabbing_allowed( true ) ), flush, !. refresh_pop_up_window( Pop_up_window ) :- button_font( _, Button_font_height, Button_font_ascent ), Line_space is Button_font_height + 3, First_text_Y_coordinate is Button_font_ascent + 10, clear_window( Pop_up_window ), pop_up_text_lines( List_of_info_text_lines, _ ), draw_pop_up_text_lines( Pop_up_window, List_of_info_text_lines, First_text_Y_coordinate, Line_space ), !. refresh_pop_up_list_window( List_window ) :- text_font( _, Text_font_height, Text_font_ascent ), First_text_Y_coordinate is Text_font_ascent + 3, clear_window( List_window ), ( keyboard_is_grabbed_for( Doing_what ) /* If succeeds rewrite user given text */ -> user_given_name_as_list( Doing_what, User_given_name_as_list ), draw_string( List_window, 8, First_text_Y_coordinate, User_given_name_as_list ) ; otherwise /* User is not typing his own text, so rewrite given text lines */ -> pop_up_text_lines( _, List_of_list_window_text_lines ), draw_pop_up_text_lines( List_window, List_of_list_window_text_lines, First_text_Y_coordinate, Text_font_height ) ), !. draw_pop_up_text_lines( _, [], _, _ ) :- flush, !. draw_pop_up_text_lines( Target_window, [ Text_line | Rest_of_text_lines ], Text_Y_coordinate, Line_space ) :- /* If the next text line is a number convert it to a list of ascii codes. */ ( number( Text_line ), number_chars( Text_line, Next_line ) ; Next_line = Text_line ), draw_string( Target_window, 8, Text_Y_coordinate, Next_line ), Next_text_Y_coordinate is Text_Y_coordinate + Line_space, draw_pop_up_text_lines( Target_window, Rest_of_text_lines, Next_text_Y_coordinate, Line_space ), !. inform_user( Info_string ) :- pop_up_window_with_text( 360, '', false, 'Confirm', true, [ Info_string ], _, false, false, nothing, _ ), !. inform_user_with_list_of_strings( List_of_strings ) :- pop_up_window_with_text( 360, '', false, 'Confirm', true, List_of_strings, _, false, false, nothing, _ ), !. ask_user( Info_string ) :- pop_up_window_with_text( 360, 'Ok', true, 'Cancel', true, [ Info_string ], _, false, false, nothing, Answer ), !, Answer == ok, !. create_button_face( Button_image, Button_width, Button_height, Button_depth, Light_color, Middle_color, Dark_color, Black ) :- Coordinate_1 is Button_width - Button_depth, Coordinate_2 is Button_height - Button_depth, Box_width is Button_width - 2 * Button_depth, Box_height is Button_height - 2 * Button_depth, create_pixmap( Button_image, [ size( Button_width, Button_height ) ], [ foreground( Dark_color ) ] ), fill_rectangle( Button_image, 0, 0, Button_width, Button_height ), put_graphics_attributes( Button_image, [ foreground( Light_color ) ] ), fill_polygon( Button_image, [ point( 0, Button_height ), point( 0, 0 ), point( Button_width, 0 ), point( Coordinate_1, Button_depth ), point( Button_depth, Button_depth ), point( Button_depth, Coordinate_2 ), point( 0, Button_height ) ], convex ), put_graphics_attributes( Button_image, [ foreground( Middle_color ) ] ), fill_rectangle( Button_image, Button_depth, Button_depth, Box_width, Box_height ), !. create_button_images( Normal_button_image, Highlighted_button_image, Inactivated_button_image ) :- colors_used( Black, Darkgray, Middlegray, Gray, Lightgray, White ), button_size( Button_width, Button_height ), create_button_face( Normal_button_image, Button_width, Button_height, 2, Lightgray, Gray, Darkgray, Black ), create_button_face( Highlighted_button_image, Button_width, Button_height, 2, Darkgray, Middlegray, Gray, Black ), create_button_face( Inactivated_button_image, Button_width, Button_height, 2, Lightgray, Gray, Middlegray, Lightgray ), !. create_skip_button( Button_window, X, Y, Parent_window, Font ) :- button_images( Normal_button_image, _, _ ), button_size( Button_width, Button_height ), create_window( Button_window, [ position( X, Y ), size( Button_width, Button_height ), border_width( 1 ), background( Normal_button_image ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Button_width, Button_height ), size( Button_width, Button_height ), none, none, none ) ), parent( Parent_window ), mapped( true ), callback( button_press( [ 1 ] ), [], highlight_button( Button_window ) ), callback( button_release( [ 1 ] ), [], exit_from_event_handling( skip_button_pressed ), skip_button_pressed( Button_window ) ), callback( expose, [ count( 0 ) ], normalize_button( Button_window ) ) ], [ font( Font ) ] ), !. create_change_button( Button_window, X, Y, Parent_window, Font ) :- button_images( Normal_button_image, _, _ ), button_size( Button_width, Button_height ), create_window( Button_window, [ position( X, Y ), size( Button_width, Button_height ), border_width( 1 ), background( Normal_button_image ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Button_width, Button_height ), size( Button_width, Button_height ), none, none, none ) ), parent( Parent_window ), mapped( true ), callback( button_press( [ 1 ] ), [], highlight_button( Button_window ) ), callback( button_release( [ 1 ] ), [], exit_from_event_handling( change_button_pressed ), change_button_pressed( Button_window ) ), callback( expose, [ count( 0 ) ], normalize_button( Button_window ) ) ], [ font( Font ) ] ), !. create_add_button( Button_window, X, Y, Parent_window, Font ) :- button_images( Normal_button_image, _, _ ), button_size( Button_width, Button_height ), create_window( Button_window, [ position( X, Y ), size( Button_width, Button_height ), border_width( 1 ), background( Normal_button_image ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Button_width, Button_height ), size( Button_width, Button_height ), none, none, none ) ), parent( Parent_window ), mapped( true ), callback( button_press( [ 1 ] ), [], highlight_button( Button_window ) ), callback( button_release( [ 1 ] ), [], exit_from_event_handling( add_button_pressed ), add_button_pressed( Button_window ) ), callback( expose, [ count( 0 ) ], normalize_button( Button_window ) ) ], [ font( Font ) ] ), !. create_more_button( Button_window, X, Y, Parent_window, Font ) :- button_images( Normal_button_image, _, _ ), button_size( Button_width, Button_height ), create_window( Button_window, [ position( X, Y ), size( Button_width, Button_height ), border_width( 1 ), background( Normal_button_image ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Button_width, Button_height ), size( Button_width, Button_height ), none, none, none ) ), parent( Parent_window ), mapped( true ), callback( button_press( [ 1 ] ), [], highlight_button( Button_window ) ), callback( button_release( [ 1 ] ), [], more_button_pressed( Button_window ) ), callback( expose, [ count( 0 ) ], normalize_button( Button_window ) ) ], [ font( Font ) ] ), !. create_previous_button( Button_window, X, Y, Parent_window, Font ) :- button_images( Normal_button_image, _, _ ), button_size( Button_width, Button_height ), create_window( Button_window, [ position( X, Y ), size( Button_width, Button_height ), border_width( 1 ), background( Normal_button_image ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Button_width, Button_height ), size( Button_width, Button_height ), none, none, none ) ), parent( Parent_window ), mapped( true ), callback( button_press( [ 1 ] ), [], highlight_button( Button_window ) ), callback( button_release( [ 1 ] ), [], previous_button_pressed( Button_window ) ), callback( expose, [ count( 0 ) ], normalize_button( Button_window ) ) ], [ font( Font ) ] ), !. create_exit_button( Button_window, X, Y, Parent_window, Font ) :- button_images( Normal_button_image, _, _ ), button_size( Button_width, Button_height ), create_window( Button_window, [ position( X, Y ), size( Button_width, Button_height ), border_width( 1 ), background( Normal_button_image ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Button_width, Button_height ), size( Button_width, Button_height ), none, none, none ) ), parent( Parent_window ), mapped( true ), callback( button_press( [ 1 ] ), [], highlight_button( Button_window ) ), callback( button_release( [ 1 ] ), [], exit_from_event_handling( exit_button_pressed ), exit_button_pressed( Button_window ) ), callback( expose, [ count( 0 ) ], normalize_button( Button_window ) ) ], [ font( Font ) ] ), !. create_ok_button( Button_window, Map_ok_button, X, Y, Parent_window, Font ) :- button_images( Normal_button_image, _, _ ), button_size( Button_width, Button_height ), create_window( Button_window, [ position( X, Y ), size( Button_width, Button_height ), border_width( 1 ), background( Normal_button_image ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Button_width, Button_height ), size( Button_width, Button_height ), none, none, none ) ), parent( Parent_window ), mapped( Map_ok_button ), callback( button_press( [ 1 ] ), [], highlight_button( Button_window ) ), callback( button_release( [ 1 ] ), [], exit_pop_up_event_handling( ok ), ok_button_pressed( Button_window ) ), callback( expose, [ count( 0 ) ], normalize_button( Button_window ) ) ], [ font( Font ) ] ), !. create_cancel_button( Button_window, Map_cancel_button, X, Y, Parent_window, Font ) :- button_images( Normal_button_image, _, _ ), button_size( Button_width, Button_height ), create_window( Button_window, [ position( X, Y ), size( Button_width, Button_height ), border_width( 1 ), background( Normal_button_image ), property( 'WM_NORMAL_HINTS', wm_size_hints( program_position( X, Y ), program_size( Button_width, Button_height ), size( Button_width, Button_height ), none, none, none ) ), parent( Parent_window ), mapped( Map_cancel_button ), callback( button_press( [ 1 ] ), [], highlight_button( Button_window ) ), callback( button_release( [ 1 ] ), [], exit_pop_up_event_handling( cancel ), cancel_button_pressed( Button_window ) ), callback( expose, [ count( 0 ) ], normalize_button( Button_window ) ) ], [ font( Font ) ] ), !. create_null_button( Not_existing_button ) :- create_window( Not_existing_button, [ mapped( false ) ] ), destroy_window( Not_existing_button ), !. remove_all_button_events_from_queue( Window_name ) :- window_identifiers( Window_name, Window ), event_list_mask( [ button_press, button_release ], Event_mask ), remove_next_button_event( Window, Event_mask ), !. remove_next_button_event( Window, Event_mask ) :- xevents:check_mask_event( Window, Event_mask, _, _ ), /* This can fail! */ remove_next_button_event( Window, Event_mask ), !. remove_next_button_event( _, _ ) :- !. highlight_button( Button_window ) :- button_is_activated( Button_window ), /* This can fail! */ retractall( button_previously_pressed( _ ) ), assertz( button_previously_pressed( Button_window ) ), button_label( Button_window, Label ), button_images( _, Highlighted_button_image, _ ), button_font( Font, Button_font_height, Button_font_ascent ), colors_used( Black, _, _, _, _, _ ), /* Center the button label on the button face. */ button_size( Button_width, Button_height ), text_extents( Font, Label, Left_bearing, Right_bearing, _, _, _ ), Text_X is ( Button_width - Right_bearing + Left_bearing ) // 2, Text_Y is ( Button_height - Button_font_height ) // 2 + Button_font_ascent, put_window_attributes( Button_window, [ background( Highlighted_button_image ) ] ), put_graphics_attributes( Button_window, [ foreground( Black ) ] ), clear_window( Button_window ), draw_string( Button_window, Text_X, Text_Y, Label ), !. highlight_button( _ ) :- !. normalize_button( Button_window ) :- valid_window( Button_window ), /* This fails if Button_window = Not_existing_button */ ( button_is_activated( Button_window ) -> ( button_images( Button_image, _, _ ), colors_used( Label_color, _, _, _, _, _ ) ) ; otherwise -> ( button_images( _, _, Button_image ), colors_used( _, _, _, _, Label_color, _ ) ) ), button_label( Button_window, Label ), button_font( Font, Button_font_height, Button_font_ascent ), button_size( Button_width, Button_height ), text_extents( Font, Label, Left_bearing, Right_bearing, _, _, _ ), Text_X is ( Button_width - Right_bearing + Left_bearing ) // 2, Text_Y is ( Button_height - Button_font_height ) // 2 + Button_font_ascent, put_window_attributes( Button_window, [ background( Button_image ) ] ), put_graphics_attributes( Button_window, [ foreground( Label_color ) ] ), clear_window( Button_window ), draw_string( Button_window, Text_X, Text_Y, Label ), flush, !. normalize_button( _ ) :- !. skip_button_pressed( Skip_button ) :- /* If this does not fail, the event handling stops and execution * jumps to the line after handle_events/1. If this fails nothing happens. * This is true also in the other xxx_button_pressed routines if * button is programmed to send an exit code for handle_events/1. */ !, is_button_press_legal( Skip_button ), normalize_button( Skip_button ), inactivate_current_text_input_window, discard_user_given_name( entering_new_name ), increment_counter( number_of_skipped_unknown_names ), show_selected_name_candidate, !. change_button_pressed( Change_button ) :- !, is_button_press_legal( Change_button ), normalize_button( Change_button ), inactivate_current_text_input_window, erase_cursor_in_user_given_name_as_list( entering_new_name ), show_selected_name_candidate, /* Handle the name substitution */ saved_unknown_name( Name_in_string_form, List_of_all_words, List_of_line_numbers, _ ), user_given_name_as_list( entering_new_name, Name_as_list ), name( Name_as_string, Name_as_list ), convert_underscored_string_to_list_of_words( Name_as_string, Given_substitution_as_list_of_words ), !, given_name_substitution_is_legal( Name_as_string, Given_substitution_as_list_of_words ), selected_name_candidate( Number_of_selected_name_candidate ), /* Number_of_selected_name_candidate is zero when the user has given the substitution himself. */ ( Number_of_selected_name_candidate =:= 0 -> ( !, handle_typed_substitution( Given_substitution_as_list_of_words ), /* The previous call should succeed in order to execute the change. */ deduce_word_substitutions_from_given_name_substitution( List_of_all_words, Given_substitution_as_list_of_words ), increment_counter( number_of_user_given_substitutions ) ) ; ( previously_used_name_substitution_found -> ( convert_list_of_words_to_underscored_string( Given_substitution_as_list_of_words, Given_substitution_as_string ), previous_name_substitution( Name_in_string_form, Given_substitution_as_string ) -> ( increment_counter( number_of_accepted_previous_substitutions ) ) ; ( increment_counter( number_of_accepted_tool_given_substitutions ) ) ) ; ( increment_counter( number_of_accepted_tool_given_substitutions ) ) ) ), assertz( name_substitution( Name_in_string_form, Given_substitution_as_list_of_words, List_of_line_numbers ) ), increment_counter( total_number_of_name_substitutions ), !. given_name_substitution_is_legal( New_name_as_string, New_name_as_list_of_words ) :- ( found_name( New_name_as_string, _ ) -> ( ask_user( 'Ok to use a name already existing in the program ?' ) ) ; ( true ) ), ( name_substitution( _, New_name_as_list_of_words, _ ) -> ( ask_user( 'Ok to use a previously used replacement ?' ) ) ; ( true ) ), !. add_button_pressed( Add_button ) :- !, is_button_press_legal( Add_button ), normalize_button( Add_button ), inactivate_current_text_input_window, erase_cursor_in_user_given_name_as_list( entering_new_name ), show_selected_name_candidate, saved_unknown_name( _, _, _, List_of_unknown_words ), convert_list_of_words_to_lowercase( List_of_unknown_words, List_of_lowercase_unknown_words ), pop_up_window_with_text( 320, 'Add', true, 'Cancel', true, [ 'Add to the domain dictionary:' ], List_of_lowercase_unknown_words, true, false, nothing, Answer ), !, Answer == ok, /* This can fail! */ discard_user_given_name( entering_new_name ), show_selected_name_candidate, update_domain_dictionary_with_new_words( List_of_unknown_words ), increment_counter( number_of_add_button_pressings ), !. more_button_pressed( More_button ) :- is_button_press_legal( More_button ), normalize_button( More_button ), inactivate_current_text_input_window, number_of_name_candidates( _, Lines_in_window ), retract( first_name_candidate_in_window( First_name ) ), New_first_name_candidate_in_window is First_name + Lines_in_window, asserta( first_name_candidate_in_window( New_first_name_candidate_in_window ) ), show_list_of_name_candidates( false, true ), !. more_button_pressed( _ ) :- !. previous_button_pressed( Previous_button ) :- is_button_press_legal( Previous_button ), normalize_button( Previous_button ), inactivate_current_text_input_window, number_of_name_candidates( _, Lines_in_window ), retract( first_name_candidate_in_window( First_name ) ), New_first_name_candidate_in_window is First_name - Lines_in_window, asserta( first_name_candidate_in_window( New_first_name_candidate_in_window ) ), show_list_of_name_candidates( false, true ), !. previous_button_pressed( _ ) :- !. /* This button does not have to be visually an 'Ok' button, * it can be e.g. 'Add' or anything else that confirms the given order after the * program has wisely doubted the user's capabilities to do things as he wants to. * This is the case also with the 'Cancel' button which can be anything that takes back * the given order and makes the user pray for the almighty programmer.. */ ok_button_pressed( Ok_button ) :- !, is_button_press_legal( Ok_button ), normalize_button( Ok_button ), inactivate_current_text_input_window, !. cancel_button_pressed( Cancel_button ) :- !, is_button_press_legal( Cancel_button ), normalize_button( Cancel_button ), inactivate_current_text_input_window, !. exit_button_pressed( Exit_button ) :- !, is_button_press_legal( Exit_button ), normalize_button( Exit_button ), inactivate_current_text_input_window, /* If no program file name is known by the tool we can exit the program without asking anything from the user. */ ( program_file_name( _ ) -> ( pop_up_window_with_text( 280, 'Ok', true, 'Cancel', true, [ 'All changes will be lost!', 'Do you really want to exit?' ], [], false, false, nothing, Answer ), !, Answer == ok /* Succeeds if ok button pressed -> exit program */ ) ; ( true ) ), !. button_pressed_in_change_to_window( Button, Pointer_X_coordinate ) :- /* Check what button was pressed. */ ( Button =:= 1, grab_keyboard_for( entering_new_name ) ; Button =:= 2, middle_button_pressed_in_change_to_window( Pointer_X_coordinate ) ), !. /* The middle button changes the word under the pointer from lowercase to uppercase * or from uppercase to lowercase. */ middle_button_pressed_in_change_to_window( Pointer_X_coordinate ) :- /* Allow this operation only if user is entering a new substitution or * there already is one in the change_to window. */ ( keyboard_is_grabbed_for( Doing_what ) ; Doing_what = nothing ), !, ( Doing_what == entering_new_name, inactivate_current_text_input_window, erase_cursor_in_user_given_name_as_list( entering_new_name ) ; Doing_what == nothing ), user_given_name_as_list( entering_new_name, Name_as_list ), !, Name_as_list \== [], show_selected_name_candidate, name( Name_as_string, Name_as_list ), convert_underscored_string_to_list_of_words( Name_as_string, List_of_words ), text_font( Text_font, _, _ ), replace_pointed_word_of_name( Pointer_X_coordinate, List_of_words, Name_as_list, 0, Text_font, [], Resulting_list ), retractall( user_given_name_as_list( entering_new_name, _ ) ), assertz( user_given_name_as_list( entering_new_name, Resulting_list ) ), show_selected_name_candidate, !. /* Examine on which word the pointer was during the button_press event and * replace it with its uppercase or lowercase conversion. */ replace_pointed_word_of_name( _, [], Part_of_name_after_last_word, _, _, Name_with_all_words, Resulting_list ) :- append( Name_with_all_words, Part_of_name_after_last_word, Resulting_list ), !. replace_pointed_word_of_name( Pointer_X_coordinate, [ Word | Rest_of_words ], Name_as_list, Length_of_handled_part_of_name, Text_font, Name_without_this_word_as_list, Resulting_list ) :- name( Word, Word_as_list ), append3( Part_between_previous_word_and_this_word, Word_as_list, Rest_of_name, Name_as_list ), ( Part_between_previous_word_and_this_word == [], /* text_width does not work with []. */ Length_of_part_before_word is 0 ; text_width( Text_font, Part_between_previous_word_and_this_word, Length_of_part_before_word ) ), ( Word_as_list == [], Length_of_word is 0 ; text_width( Text_font, Word_as_list, Length_of_word ) ), New_length_of_handled_part_of_name is Length_of_handled_part_of_name + Length_of_part_before_word + Length_of_word, ( Pointer_X_coordinate - 8 =< New_length_of_handled_part_of_name, Pointer_X_coordinate - 8 >= New_length_of_handled_part_of_name - Length_of_word, /* 8 is the x coordinate of the text in window. */ ( upper( Word_as_list ), lower( Word_as_list, Changed_word_as_list ) ; upper( Word_as_list, Changed_word_as_list ) ), append3( Name_without_this_word_as_list, Part_between_previous_word_and_this_word, Changed_word_as_list, Name_with_this_word_added ) ; append3( Name_without_this_word_as_list, Part_between_previous_word_and_this_word, Word_as_list, Name_with_this_word_added ) ), replace_pointed_word_of_name( Pointer_X_coordinate, Rest_of_words, Rest_of_name, New_length_of_handled_part_of_name, Text_font, Name_with_this_word_added, Resulting_list ), !. handle_typed_substitution( Given_substitution_as_list_of_words ) :- find_unknown_words_in_given_substitution( Given_substitution_as_list_of_words, List_of_unknown_words ), ( List_of_unknown_words == [] ; /* There is unknown words in user given substitution. */ pop_up_window_with_text( 320, 'Add', true, 'Cancel', true, [ 'There are unknown words in the substitution!', 'Add to the domain dictionary:' ], List_of_unknown_words, true, false, nothing, Answer ), /* Answer has to be 'Add' in order to accept the typed substitution. */ !, Answer == ok, update_domain_dictionary_with_new_words( List_of_unknown_words ) ), !. handle_typed_dictionary_name :- user_given_name_as_list( entering_new_dictionary, New_dictionary_as_list ), name( New_dictionary_as_string, New_dictionary_as_list ), ( New_dictionary_as_string == '' -> show_dictionary_name, set_activity_state_for_all_buttons( as_saved_before ), flush ; true ), !, New_dictionary_as_string \== '', pop_up_window_with_text( 360, 'Ok', true, 'Cancel', true, [ 'The present dictionary will be updated.', 'Load the new dictionary?' ], _, false, false, nothing, Answer ), ( Answer == cancel -> discard_user_given_name( entering_new_dictionary ), show_dictionary_name, set_activity_state_for_all_buttons( as_saved_before ), flush ; true ), !, Answer == ok, retract( domain_dictionary_name( Old_dictionary_as_string ) ), assertz( domain_dictionary_name( New_dictionary_as_string ) ), /* Store dictionary if there are words to store in it. */ ( domain_word( _ ) -> store_domain_dictionary( Old_dictionary_as_string ) ;true ), retractall( domain_word( _ ) ), load_domain_dictionary( New_dictionary_as_string ), show_dictionary_name, set_activity_state_for_all_buttons( as_saved_before ), !. handle_typed_file_name :- user_given_name_as_list( entering_new_file, New_file_as_list ), name( New_file_as_string, New_file_as_list ), ( file_exists( New_file_as_string ) ; bell( 50 ), flush, inform_user( 'File does not exist!' ), show_file_name, set_activity_state_for_all_buttons( as_saved_before ), flush, !, fail ), ( program_file_name( _ ) /* User is interrupting the deabbreviation process. */ -> pop_up_window_with_text( 360, 'Ok', true, 'Cancel', true, [ 'All unsaved changes will be lost!', 'Do you really want to load a new file?' ], _, false, false, nothing, Answer ) ; otherwise -> Answer = ok /* Previous file has already been deabbreviated. */ ), ( ( Answer == cancel, discard_user_given_name( entering_new_file ), show_file_name, set_activity_state_for_all_buttons( as_saved_before ), flush ) ; true ), !, Answer == ok, retractall( program_file_name( _ ) ), assertz( program_file_name( New_file_as_string ) ), show_file_name, !. /* Grab keyboard for some purpose (=Doing_what) for the window corresponding to * the purpose, and activate this window for input. */ grab_keyboard_for( Doing_what ) :- /* Check if grabbing is not allowed right now. However, a pop up window * can always get keyboard control (=entering_pop_up_text). */ is_keyboard_grabbing_allowed( Grabbing_is_allowed ), !, ( Grabbing_is_allowed ; Doing_what = entering_pop_up_text ), /* Deny the grab request if user was currently entering something. */ !, \+ keyboard_is_grabbed_for( _ ), /* No text input activated presently */ /* If trying to enter a new name and no program file loaded -> fail */ ( Doing_what \== entering_new_name ; !, program_file_name( _ ) ), text_input_window_when( Doing_what, Input_window ), grab_keyboard( Input_window, false, async, async, current_time, Status ), !, Status == success, /* This fails if the grab did not succeed */ retractall( keyboard_is_grabbed_for( _ ) ), asserta( keyboard_is_grabbed_for( Doing_what ) ), clear_window( Input_window ), !, /* Do some purpose (=Doing_what) specific things */ ( Doing_what == entering_new_name -> retractall( selected_name_candidate( _ ) ), assertz( selected_name_candidate( 0 ) ), set_activity_state_for_all_buttons( same, off, same, same, same, same, same, same ) ; Doing_what == entering_new_dictionary -> save_present_button_activity_states, set_activity_state_for_all_buttons( all_off ) ; Doing_what == entering_new_file -> save_present_button_activity_states, set_activity_state_for_all_buttons( all_off ) ; otherwise -> true ), discard_user_given_name( Doing_what ), assertz( user_given_name_as_list( Doing_what, "|" ) ), assertz( cursor_coordinate_in_window( Doing_what, 8 ) ), text_styles( Normal_text_style, _, _ ), text_font( _, _, Text_font_ascent ), Y_coordinate is Text_font_ascent + 3, draw_string( Input_window, Normal_text_style, 8, Y_coordinate, "|" ), !. inactivate_current_text_input_window :- ( keyboard_is_grabbed_for( Doing_what ) /* Fails if there is no input window */ -> retractall( keyboard_is_grabbed_for( _ ) ), text_input_window_when( Doing_what, Input_window ), ungrab_keyboard( Input_window, current_time ) ; otherwise -> true ), !. /* Check if the key hit in a potential text input window is ment to be received, if so * check if the key is legal ( corresponding to the reason for typing ), * then write the character to the window ( or erase the previous character etc ). */ key_pressed_in_window( Key_symbol ) :- /* If the window has received a key_press event * it has to be checked if the window is ment to read characters * from keyboard, that is, the keyboard has to be grabbed for the window, too. * If not grabbed fail and forget typed character. */ keyboard_is_grabbed_for( Doing_what ), /* Fails if window is not ment to read keyboard */ keysym( Key_symbol, Key ), /* Find out what key the key_symbol means */ /* Get list of legal characters for this purpose in this situation */ user_given_name_as_list( Doing_what, String_without_typed_character ), ( String_without_typed_character == "|" /* This character is the first one */ -> inname_data( list_of_legal_first_characters( Doing_what, List_of_legal_characters ) ) ; otherwise -> inname_data( list_of_legal_characters( Doing_what, List_of_legal_characters ) ) ), /* Is pressed key in the the list of legal characters */ !, pressed_key_is_legal( Key, List_of_legal_characters ), text_font( Font, _, Text_font_ascent ), Y_coordinate is Text_font_ascent + 3, text_styles( Normal_text_style, _, Erase_text_style ), text_input_window_when( Doing_what, Input_window ), /* Get window id */ ( ( Key == 'BackSpace' ; Key == 'Delete' ) /* BackSpace or Delete hit */ -> retract( user_given_name( Doing_what, Previous_character ) ), erase_last_character_in_user_given_name_as_list( Doing_what, Previous_character ), retract( cursor_coordinate_in_window( Doing_what, Previous_cursor_coordinate ) ), draw_string( Input_window, Erase_text_style, Previous_cursor_coordinate, Y_coordinate, "|" ), cursor_coordinate_in_window( Doing_what, Previous_character_coordinate ), draw_string( Input_window, Erase_text_style, Previous_character_coordinate, Y_coordinate, Previous_character ), draw_string( Input_window, Normal_text_style, Previous_character_coordinate, Y_coordinate, "|" ), flush ; Key == 'Return' /* Guesswhatkey hit */ -> ( Doing_what == entering_new_name -> inactivate_current_text_input_window, erase_cursor_in_user_given_name_as_list( Doing_what ), /* Erase cursor character in window */ retract( cursor_coordinate_in_window( Doing_what, Previous_cursor_coordinate ) ), draw_string( Input_window, Erase_text_style, Previous_cursor_coordinate, Y_coordinate, "|" ), user_given_name_as_list( Doing_what, List ), length( List, Length_of_list ), ( Length_of_list = 0 -> discard_user_given_name( Doing_what ) ; otherwise -> true ) ; Doing_what == entering_new_dictionary -> inactivate_current_text_input_window, erase_cursor_in_user_given_name_as_list( Doing_what ), retract( cursor_coordinate_in_window( Doing_what, Previous_cursor_coordinate ) ), draw_string( Input_window, Erase_text_style, Previous_cursor_coordinate, Y_coordinate, "|" ), ( handle_typed_dictionary_name ; true ) ; Doing_what == entering_new_file -> inactivate_current_text_input_window, erase_cursor_in_user_given_name_as_list( Doing_what ), retract( cursor_coordinate_in_window( Doing_what, Previous_cursor_coordinate ) ), draw_string( Input_window, Erase_text_style, Previous_cursor_coordinate, Y_coordinate, "|" ) ; otherwise -> true ), flush ; otherwise /* Normal, legal character typed */ -> name( Key, Character ), cursor_coordinate_in_window( Doing_what, Character_coordinate ), draw_string( Input_window, Erase_text_style, Character_coordinate, Y_coordinate, "|" ), text_width( Font, Character, Character_width ), New_cursor_coordinate is Character_coordinate + Character_width, asserta( cursor_coordinate_in_window( Doing_what, New_cursor_coordinate ) ), draw_string( Input_window, Normal_text_style, Character_coordinate, Y_coordinate, Character ), draw_string( Input_window, Normal_text_style, New_cursor_coordinate, Y_coordinate, "|" ), asserta( user_given_name( Doing_what, Character ) ), add_typed_character_into_substitution_string( Doing_what, Character ), flush ), /* This routine can succeed only when a legal Return has been pressed after * entering an acceptable file name. * ( By succeeding this routine makes the callback definition to send * an exit code to the event handler after Return is pressed. ) */ !, Key == 'Return', !, Doing_what == entering_new_file, !, handle_typed_file_name, !. pressed_key_is_legal( Character, [ Legal_character | Rest_of_legal_characters ] ) :- ( Character == Legal_character ) ; pressed_key_is_legal( Character, Rest_of_legal_characters ), !. /* Notice: The cursor is in the end of the name as a normal * character ("|") as long as the user has finished typing. */ erase_last_character_in_user_given_name_as_list( Doing_what, Previous_character ) :- user_given_name_as_list( Doing_what, Substitution_string ), retractall( user_given_name_as_list( Doing_what, _ ) ), append( Substitution_string_without_cursor, "|", Substitution_string ), append( Substitution_string_without_cursor_and_previous_character, Previous_character, Substitution_string_without_cursor ), append( Substitution_string_without_cursor_and_previous_character, "|", New_substitution_string ), assertz( user_given_name_as_list( Doing_what, New_substitution_string ) ), /* If entering a new name substitution and all characters erased * -> inactivate change button. */ ( ( Doing_what == entering_new_name, New_substitution_string == "|" ) -> set_activity_state_for_all_buttons( same, off, same, same, same, same, same, same ) ; otherwise -> true ), !. erase_cursor_in_user_given_name_as_list( Doing_what ) :- user_given_name_as_list( Doing_what, Substitution_string ), /* Fails if no cursor character found. */ append( Substitution_string_without_cursor, "|", Substitution_string ), retractall( user_given_name_as_list( Doing_what, _ ) ), assertz( user_given_name_as_list( Doing_what, Substitution_string_without_cursor ) ), !. erase_cursor_in_user_given_name_as_list( _ ) :- !. add_typed_character_into_substitution_string( Doing_what, Character ) :- user_given_name_as_list( Doing_what, Substitution_list ), retractall( user_given_name_as_list( Doing_what, _ ) ), append( Substitution_list_without_cursor, "|", Substitution_list ), append3( Substitution_list_without_cursor, Character, "|", New_substitution_list ), assertz( user_given_name_as_list( Doing_what, New_substitution_list ) ), /* If this one is the first character -> activate change button. */ ( ( Doing_what == entering_new_name, Substitution_list == "|" ) /* This was the first character -> activate change button */ -> set_activity_state_for_all_buttons( same, on, same,same, same, same, same, same ) ; otherwise -> true ), !. discard_user_given_name( Doing_what ) :- retractall( user_given_name( Doing_what, _ ) ), retractall( user_given_name_as_list( Doing_what, _ ) ), retractall( cursor_coordinate_in_window( Doing_what, _ ) ), !. find_unknown_words_in_given_substitution( [], [] ) :- !. find_unknown_words_in_given_substitution( [ First_substitution_word | Rest_of_substitution_words ], List_of_unknown_words ) :- ( lower( First_substitution_word, First_substitution_word_as_lowercase ) ; First_substitution_word_as_lowercase = First_substitution_word ), /* lower fails if the word is a number! */ ( dictionary_word( First_substitution_word_as_lowercase ) ; domain_word( First_substitution_word_as_lowercase ) ), find_unknown_words_in_given_substitution( Rest_of_substitution_words, List_of_unknown_words ), !. find_unknown_words_in_given_substitution( [ First_substitution_word | Rest_of_substitution_words ], [ First_unknown_word | Rest_of_unknown_words ] ) :- ( lower( First_substitution_word, First_unknown_word ) ; First_unknown_word = First_substitution_word ), find_unknown_words_in_given_substitution( Rest_of_substitution_words, Rest_of_unknown_words ), !. set_activity_state_for_all_buttons( as_saved_before ) :- retract( saved_button_activity_states( Flag_1, Flag_2, Flag_3, Flag_4, Flag_5, Flag_6, Flag_7, Flag_8 ) ), set_activity_state_for_all_buttons( Flag_1, Flag_2, Flag_3, Flag_4, Flag_5, Flag_6, Flag_7, Flag_8 ), !. set_activity_state_for_all_buttons( all_off ) :- set_activity_state_for_all_buttons( off, off, off, off, off, off, off, off ), !. set_activity_state_for_all_buttons( Flag_1, Flag_2, Flag_3, Flag_4, Flag_5, Flag_6, Flag_7, Flag_8 ) :- button_identifiers( Skip_button, Change_button, Add_button, More_button, Previous_button, Ok_button, Cancel_button, Exit_button ), retract( button_activity_states( Old_1, Old_2, Old_3, Old_4, Old_5, Old_6, Old_7, Old_8 ) ), ( Flag_1 == same -> New_1 = Old_1 ; New_1 = Flag_1 ), ( Flag_2 == same -> New_2 = Old_2 ; New_2 = Flag_2 ), ( Flag_3 == same -> New_3 = Old_3 ; New_3 = Flag_3 ), ( Flag_4 == same -> New_4 = Old_4 ; New_4 = Flag_4 ), ( Flag_5 == same -> New_5 = Old_5 ; New_5 = Flag_5 ), ( Flag_6 == same -> New_6 = Old_6 ; New_6 = Flag_6 ), ( Flag_7 == same -> New_7 = Old_7 ; New_7 = Flag_7 ), ( Flag_8 == same -> New_8 = Old_8 ; New_8 = Flag_8 ), assertz( button_activity_states( New_1, New_2, New_3, New_4, New_5, New_6, New_7, New_8 ) ), ( Flag_1 \== same -> normalize_button( Skip_button ) ; true ), ( Flag_2 \== same -> normalize_button( Change_button ) ; true ), ( Flag_3 \== same -> normalize_button( Add_button ) ; true ), ( Flag_4 \== same -> normalize_button( More_button ) ; true ), ( Flag_5 \== same -> normalize_button( Previous_button ) ;true ), ( Flag_6 \== same -> normalize_button( Ok_button ) ; true ), ( Flag_7 \== same -> normalize_button( Cancel_button ) ; true ), ( Flag_8 \== same -> normalize_button( Exit_button ) ; true ), !. /* These saved button states can be used again by calling: * set_activity_state_for_all_buttons( as_saved_before ). */ save_present_button_activity_states :- button_activity_states( Flag_1, Flag_2, Flag_3, Flag_4, Flag_5, Flag_6, Flag_7, Flag_8 ), /*retractall( saved_button_activity_states( _, _, _, _, _, _, _, _ ) ),*/ asserta( saved_button_activity_states( Flag_1, Flag_2, Flag_3, Flag_4, Flag_5, Flag_6, Flag_7, Flag_8 ) ), !. is_button_press_legal( Button_window ) :- !, button_pressed_and_released_on_same_button( Button_window ), !, button_is_activated( Button_window ), !. button_pressed_and_released_on_same_button( Release_window ) :- retract( button_previously_pressed( Press_window ) ), ( Press_window \== Release_window -> normalize_button( Press_window ) ; otherwise -> true ), !, Release_window == Press_window, !. button_is_activated( Button_window ) :- button_identifiers( Skip_button, Change_button, Add_button, More_button, Previous_button, Ok_button, Cancel_button, Exit_button ), ( ( Button_window == Skip_button, button_activity_states( State, _, _, _, _, _, _, _ ) ) ; ( Button_window == Change_button, button_activity_states( _, State, _, _, _, _, _, _ ) ) ; ( Button_window == Add_button, button_activity_states( _, _, State, _, _, _, _, _ ) ) ; ( Button_window == More_button, button_activity_states( _, _, _, State, _, _, _, _ ) ) ; ( Button_window == Previous_button, button_activity_states( _, _, _, _, State, _, _, _ ) ) ; ( Button_window == Ok_button, button_activity_states( _, _, _, _, _, State, _, _ ) ) ; ( Button_window == Cancel_button, button_activity_states( _, _, _, _, _, _, State, _ ) ) ; ( Button_window == Exit_button, button_activity_states( _, _, _, _, _, _, _, State ) ) ), !, State == on, !. /* Fails if button is inactivated */ sublist( Long_list, Sublist_to_be_searched, Length_of_first_part, Length_of_sublist ) :- /* sublist( ABC, B, LenA, LenB ) */ append3( First_part, Sublist_to_be_searched, Third_part, Long_list ), length( First_part, Length_of_first_part ), length( Sublist_to_be_searched, Length_of_sublist ), !. /* --------------------- INNAME PREFERENCE DATA --------------------- */ /* Characters which are not allowed to be next to the name found in the text * so that it is the name searched for, not a part of another name. * ( This does not, however, exclude the possibility of finding the name inside * a comment. For this reason the real total number of names in the line has to be * taken into account. We assume that there are no comments inside the code lines. ) */ inname_data( list_of_illegal_characters_next_to_unknown_name( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" ) ). inname_data( default_dictionary_name( 'default.dic' ) ). /* This MUST be more than what fits in window with ANY window size! * The bigger the number is the longer it takes to read text into the buffer but * also there is more rarely need for that. */ inname_data( text_buffer_size_in_lines( 300 ) ). /* Characters/keys which are legal if no other characters have been typed before. */ inname_data( list_of_legal_first_characters( entering_new_name, [ 'Return','_', 'a','b','c','d','e','f','g','h','i','j','k', 'l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','A','B','C','D','E','F','G', 'H','I','J','K','L','M','N','O','P','Q','R', 'S','T','U','V','W','X','Y','Z' ] ) ). inname_data( list_of_legal_first_characters( entering_new_dictionary, [ 'Return','_','.','/', 'a','b','c','d','e','f','g','h','i','j','k', 'l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','A','B','C','D','E','F','G', 'H','I','J','K','L','M','N','O','P','Q','R', 'S','T','U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '-',':','!','@','#','$','%','^', '&','+','=',',','~' ] ) ). inname_data( list_of_legal_first_characters( entering_new_file, List_of_characters ) ) :- inname_data( list_of_legal_first_characters( entering_new_dictionary, List_of_characters ) ). /* Characters/keys which are legal if there is previously typed characters in name. */ inname_data( list_of_legal_characters( entering_new_name, [ 'BackSpace','Delete','Return','_', 'a','b','c','d','e','f','g','h','i','j','k', 'l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','A','B','C','D','E','F','G', 'H','I','J','K','L','M','N','O','P','Q','R', 'S','T','U','V','W','X','Y','Z', '1','2','3','4','5','6','7','8','9','0' ] ) ). inname_data( list_of_legal_characters( entering_new_dictionary, [ 'BackSpace','Delete','Return','_','.','/', 'a','b','c','d','e','f','g','h','i','j','k', 'l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','A','B','C','D','E','F','G', 'H','I','J','K','L','M','N','O','P','Q','R', 'S','T','U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9','-',':', '!','@','#','$','%','^','&','+', '=',',','~' ] ) ). inname_data( list_of_legal_characters( entering_new_file, List_of_characters ) ) :- inname_data( list_of_legal_characters( entering_new_dictionary, List_of_characters ) ). /* Text (inname) and button fonts; for both of them there are a few alternatives. * The first font is the preferred one, in case it is not found the second one is * searched for etc. If none of the text or button fonts has been found the execution * stops. */ inname_data( inname_font, '*typewriter-medium-r-normal-*-120-*-m-*' ). inname_data( inname_font, 'vgb-25' ). inname_data( inname_font, 'fixed' ). inname_data( button_font, '*adobe*helvetica-bold-r-*-120-*' ). inname_data( button_font, 'vgb-25' ). inname_data( button_font, 'f ixed' ).