/* file_act.c - part of asedit program */ /* * Copyright 1991 - 1994, Andrzej Stochniol, London, UK * * ASEDIT text editor, both binary and source (hereafter, Software) is * copyrighted by Andrzej Stochniol (hereafter, AS) and ownership remains * with AS. * * AS grants you (hereafter, Licensee) a license to use the Software * for academic, research and internal business purposes only, without a * fee. Licensee may distribute the binary and source code (if released) * to third parties provided that the copyright notice and this statement * appears on all copies and that no charge is associated with such copies. * * Licensee may make derivative works. However, if Licensee distributes * any derivative work based on or derived from the Software, then * Licensee will: * (1) notify AS regarding its distribution of the derivative work, and * (2) clearly notify users that such derivative work is a modified version * and not the original ASEDIT distributed by AS. * * Any Licensee wishing to make commercial use of the Software should * contact AS to negotiate an appropriate license for such commercial use. * Commercial use includes: * (1) integration of all or part of the source code into a product for sale * or license by or on behalf of Licensee to third parties, or * (2) distribution of the binary code or source code to third parties that * need it to utilize a commercial product sold or licensed by or on * behalf of Licensee. * * A. STOCHNIOL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS * SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR * IMPLIED WARRANTY. IN NO EVENT SHALL A. STOCHNIOL BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * By using or copying this Software, Licensee agrees to abide by the * copyright law and all other applicable laws, and the terms of this * license. * AS shall have the right to terminate this license immediately by * written notice upon Licensee's breach of, or non-compliance with, any * of its terms. Licensee may be held legally responsible for any * copyright infringement that is caused or encouraged by Licensee's * failure to abide by the terms of this license. * * * Andrzej Stochniol (A.Stochniol@ic.ac.uk) * 30 Hatch Road * London SW16 4PN * UK */ #include #include #include #include #include #include "asedit.h" #ifdef _NO_PROTO void open_file_in_last_window(filename) char *filename; #else /* ! _NO_PROTO */ void open_file_in_last_window(char *filename) #endif { /* opens the specified file in the asedit last window or the default file (when filename is NULL) */ char *work; /* work string */ char *error_open; int len; static int as_def_names_count = 0; /* counter for default names */ if(filename != NULL && (len=strlen(filename)) ) { asedit_last_window->filename = XtMalloc(len+1); strcpy(asedit_last_window->filename, filename); } else { /* use the default name .... */ char *NoName = (char *)lstr.noname; if(aseditWinCount == 1) as_def_names_count = 0; /* reset the counter when all windows were closed */ as_def_names_count ++; /* increase the counter */ len = strlen(NoName) + 5; asedit_last_window->filename = XtMalloc(len); sprintf(asedit_last_window->filename,"%s%d", NoName ,as_def_names_count); } /* open file; if file can't be opened or created (e.g. irregular) show message and set name to NULL; if file exists open it, if does not but can be created set the empty text */ if (!OpenFile(asedit_last_window, False)) /* OpenFile is called with only_existing_files = False */ { error_open = (char *)lstr.fm_unable_to_open; work = XtMalloc(strlen(error_open) + strlen(asedit_last_window->filename) +1); /***** pre 1.3 version (did not care for German syntax) strcpy(work, error_open); strcat(work, asedit_last_window->filename); ***** pre 1.3 version */ sprintf(work, error_open, asedit_last_window->filename); show_error_message(asedit_last_window, work); XtFree(asedit_last_window->filename); asedit_last_window->filename = NULL; XtFree(work); } } /* open_file_in_last_window */ /***************************** OpenFile ************************************ ** ** Calls ReadFile to read the file. Returns true if file ** exists and open is sucessful (for only_existing_files). ** Parameter only_existing_files gives a way of using this ** procedure for both file options: Load (only_existing_files=True) ** and New (only_existing_files parameter should be False). ** Adds file contents to the ** appropriate widget, makes appropriate items sensitive etc. ** Calls a procedure to set the title ot the main window (toplevel widget) ** and the icon name. */ #ifdef _NO_PROTO Boolean OpenFile(win, only_existing_files) aseditWindowStruct *win; Boolean only_existing_files; #else /* ! _NO_PROTO */ Boolean OpenFile(aseditWindowStruct *win, Boolean only_existing_files) #endif { char * file_string=NULL; /* Contents of file. */ Boolean read_only; /* shows the file read only status */ register int ac; /* arg count */ Arg al[10]; /* widget arg list */ int i; /* make sure the file is a regular text file (if not return False immediately)*/ if(!isFileRegular(win->filename)) { /* first set the read only colour (we do that here to avoid flashing the background colour in a healthy situation*/ ac = 0; XtSetArg(al[ac], XmNbackground, text_read_only_background); ac++;/* set the read only colour */ XtSetValues(win->edit_text1, al, ac); return(False); } if( (file_string = ReadFile(win->filename, &read_only)) != NULL || !only_existing_files) { /***win->file_read_only = read_only; SEPT */ if(read_only) win->file_read_only = read_only; /* 30 SEPT late change */ /**** SEPT version if(!read_only) { |* file was read/write; check if the user hasn't requested only view mode; if so set it to read only mode *| if(win->view_only_toggle!= NULL) |* safety check *| { if(XmToggleButtonGetState(win->view_only_toggle)) win->file_read_only = True; } } ***** SEPT version ***/ ac = 0; XtSetArg(al[ac], XmNeditable, !win->file_read_only); ac++; /* if file is read only editable is set to False & vice versa */ /* set appropriate colour for the text widget to distinguish between editable and read-only files */ if(win->file_read_only) XtSetArg(al[ac], XmNbackground, text_read_only_background); else XtSetArg(al[ac], XmNbackground, text_edit_background); ac++; XtSetArg(al[ac], XmNsensitive, True); ac++; /* make text sensitive */ XtSetValues(win->edit_text1, al, ac); /* hack for Motif 1.2: when the string for the text widget is NULL text modify callback is not generated; in that case we don't set the flag file_just_loaded; if we do we lose the first action during editing !!!! */ if(file_string != NULL && strlen(file_string)) win->file_just_loaded = True; /* reset the just loaded flag */ else win->file_just_loaded = False; /* we have to use XmTextSetString to set the string; when I use XtSetArg(al[ac], XmNvalue, (char *) file_string); etc... it does not work properly when file_string was empty and the rest was the same probably; it does not work occasionally during loading of a file (comments from Kennan (i.e. the there is an inconsistent behaviour ); ****/ XmTextSetString(win->edit_text, (char *)file_string); /* add the file string to the text widget */ /* free the memory associated with the file_string */ if(file_string != NULL) XtFree(file_string); /* reinitialize the changes counter, reset undo/redo stacks */ win->changes_counter = 0L; reset_undo_redo(win); /* write appropriate info into changes_status widget */ if(!win->file_read_only) write_ls(win->changes_status, charset, "%s", " "); else write_ls(win->changes_status, charset, "%s", (char *)lstr.read_only_marker); /* make undo/redo buttons insensitive */ XtSetSensitive(win->menu_undo_button, False); XtSetSensitive(win->menu_redo_button, False); XFlush(display); /* make sure that these buttons are insensitive before processing any keyboard actions (for very busy systems)*/ /* make appropriate items sensitive */ XtSetSensitive(win->menu_copy_button, True); /* set the sensitivity of tools buttons */ for (i=0; i < win->nToolsSelNeeded; i++) XtSetSensitive(win->toolsSelNeeded[i], True); /* set the sensitivity of buttons dependend only on read_only status of the file (cut button, clear button, replace button) */ if(!win->file_read_only) { XtSetSensitive(win->menu_cut_button, True); XtSetSensitive(win->menu_clear_button, True); XtSetSensitive(win->menu_replace_button, True); XtSetSensitive(win->menu_insert_button, True); } else { XtSetSensitive(win->menu_cut_button, False); XtSetSensitive(win->menu_clear_button, False); XtSetSensitive(win->menu_replace_button, False); XtSetSensitive(win->menu_insert_button, False); } /* set the sensitivity of the paste buttons */ if(!win->file_read_only && clipboard_filled) { XtSetSensitive(win->menu_paste_button, True); XtSetSensitive(win->popup_paste_button, True); } else { XtSetSensitive(win->menu_paste_button, False); XtSetSensitive(win->popup_paste_button, False); } /* set appropriate file buttons to sensitive */ XtSetSensitive(win->menu_close_button, True); XtSetSensitive(win->menu_save_as_button, True); XtSetSensitive(win->menu_print_button, True); /* menu_save_button will be insensitive for read only files .... */ if(!win->file_read_only) { XtSetSensitive(win->menu_save_button, True); XtSetSensitive(win->popup_save_button, True); } else { XtSetSensitive(win->menu_save_button, False); XtSetSensitive(win->popup_save_button, False); } /* set appropriate search buttons to sensitive */ XtSetSensitive(win->menu_find_button, True); XtSetSensitive(win->menu_gotoline_button, True); XtSetSensitive(win->menu_mark_button, True); XtSetSensitive(win->menu_match_button, True); XtSetSensitive(win->menu_find_again_button, True); XtSetSensitive(win->menu_spell_button, True); XtSetSensitive(win->menu_commands_button, True); /* setting a new title of the main window and the icon name. They include the name of the file just opened */ set_titles_mwindow_icon(win, win->filename, NULL); return(True); } else { /* setting a new title (name of the program only) */ set_titles_mwindow_icon(win, NULL, NULL); return(False); } } /* OpenFile */ /***************************** SaveFile ************************************ ** Save the currently edited file. */ #ifdef _NO_PROTO Boolean SaveFile(win) aseditWindowStruct *win; #else /* ! _NO_PROTO */ Boolean SaveFile(aseditWindowStruct *win) #endif { char * file_string = NULL; /* Contents of file. */ Boolean result; /* get the text string */ file_string = XmTextGetString(win->edit_text); result = WriteFile(win->filename, file_string); if (file_string != NULL) XtFree(file_string); /* free the text string */ if(result) { win->changes_counter = 0L; write_ls(win->changes_status, charset, "%s", " "); set_titles_mwindow_icon(win, win->filename, NULL); return(True); } else return(False); } /* SaveFile */ /***************************** ResetAllMarks *********************************** ** ** Reset all bookmarks and set the appropriate buttons to insensitive */ #ifdef _NO_PROTO void ResetAllMarks(win) aseditWindowStruct *win; #else /* ! _NO_PROTO */ void ResetAllMarks(aseditWindowStruct *win) #endif { int i, nmarks = TOTAL_MARKS; /* we should really get the number of marks from the size of the appropriate pulldown !! */ for(i=0; imarks_used = False; win->mark_set[i] = False; win->mark_pos[i] = 0; XtSetSensitive(win->menu_mark_go_button[i], False); } } /* ResetAllMarks */ /***************************** CloseFile *********************************** ** ** Close the present file. Set sensitivity of appropriate menu items. */ #ifdef _NO_PROTO void CloseFile(win) aseditWindowStruct *win; #else /* ! _NO_PROTO */ void CloseFile(aseditWindowStruct *win) #endif { /* zero out the text string in the text widget. Warning: it causes a value changed callback. */ Arg al[5]; register int ac; int i; /* check if it is not called for a file already closed */ if (win->filename == NULL) return; /* probable sequence was: File|Close, File|Exit */ /* we use Motif convenience function to zero out the text instead of setting the resources in one go i.e. using additionally XtSetArg(al[ac], XmNvalue , ""); ac++; because we have some problems with the other method in the ReadFile procedure; so to be on a safe side .... */ /* to avoid getting the flashing title (Changed) set the following */ win->file_just_loaded = True; XmTextSetString(win->edit_text1, ""); ac = 0; XtSetArg(al[ac], XmNsensitive, False); ac++; /* set text to insensitive */ /* set the colour of the text background to read only colour */ XtSetArg(al[ac], XmNbackground, text_read_only_background); ac++; XtSetValues(win->edit_text1, al, ac); /* reinitialize the changes counter, reset redo/undo stacks */ win->changes_counter = 0L; write_ls(win->changes_status, charset, "%s", " "); reset_undo_redo(win); /* free the file name */ if (win->filename != NULL) { XtFree(win->filename); win->filename = NULL; } /* blank the line & column number display */ write_ls(win->line_number, charset, "%s", " "); write_ls(win->column_number, charset, "%s", " "); /* unmanage replace_dialog & save_as_dialog if they are active (they may be on the screen and they do not make any sense when no file is open) */ if(win->replace_dialog != NULL) XtUnmanageChild( win->replace_dialog ); if(win->save_as_dialog != NULL) XtUnmanageChild( win->save_as_dialog ); /* set appropriate file buttons to insensitive */ XtSetSensitive(win->menu_close_button, False); XtSetSensitive(win->menu_save_button, False); XtSetSensitive(win->menu_save_as_button, False); XtSetSensitive(win->menu_insert_button, False); XtSetSensitive(win->menu_print_button, False); XtSetSensitive(win->menu_undo_button, False); XtSetSensitive(win->menu_redo_button, False); XtSetSensitive(win->menu_cut_button, False); XtSetSensitive(win->menu_copy_button, False); XtSetSensitive(win->menu_paste_button, False); XtSetSensitive(win->menu_clear_button, False); XtSetSensitive(win->menu_find_button, False); XtSetSensitive(win->menu_replace_button, False); XtSetSensitive(win->menu_find_again_button, False); XtSetSensitive(win->menu_gotoline_button, False); XtSetSensitive(win->menu_mark_button, False); XtSetSensitive(win->menu_match_button, False); XtSetSensitive(win->popup_undo_button, False); XtSetSensitive(win->popup_cut_button, False); XtSetSensitive(win->popup_copy_button, False); XtSetSensitive(win->popup_paste_button, False); XtSetSensitive(win->popup_save_button, False); /* set the sensitivity of tools buttons */ for (i=0; i < win->nToolsSelNeeded; i++) XtSetSensitive(win->toolsSelNeeded[i], False); XtSetSensitive(win->menu_spell_button, False); XtSetSensitive(win->menu_commands_button, False); /* setting a new title of the main window (name of the program only) */ set_titles_mwindow_icon(win, NULL, NULL); /* reset all bookmarks */ ResetAllMarks(win); } /* CloseFile */ /***************************** InsertFile ************************************ ** ** Inserts the specified file into the current edit_text widget. ** Calls ReadFile to read the file. Returns true if file ** exists and insert is sucessful. */ #ifdef _NO_PROTO Boolean InsertFile(win, filename) aseditWindowStruct *win; char *filename; #else /* ! _NO_PROTO */ Boolean InsertFile(aseditWindowStruct *win, char *filename) #endif { char * file_string=NULL; /* Contents of file. */ Boolean read_only; /* shows the file read only status */ register int ac; /* arg count */ Arg al[10]; /* widget arg list */ if( (file_string = ReadFile(filename, &read_only)) != NULL) { return(True); } else { return(False); } } /* InsertFile */ /*** old: #ifdef M_LANG_STD ***/ /**************************** PrintString ********************************** PrintString - prints a text pointed to by *text_string using *print_command (If successful returns True.) */ #ifdef _NO_PROTO Boolean PrintString(text_string, print_command) char *text_string; char *print_command; #else /* _NO_PROTO */ Boolean PrintString(char *text_string, char *print_command) #endif { FILE *tfp; /* Pointer to a temporary file. */ char work[256]; Boolean result=True; int status; char system_call_buf[BUFSIZ]; char *tempname; /* Temporary file name .*/ /* Note: errors here related to file operations shouldn't really happen, so just to simplify we leave them in English and write them out on stderr (they might happen when the temp dir is full, tmpDir (X) or TEMPDIR is set incorrectly etc.) */ if(text_string == NULL || print_command == NULL) return(False); tempname = make_tmpnam(); /* use tmpnam function and consider tmpDir X resource or TMPDIR environmental variable (if set) */ if ((tfp = fopen(tempname, "w")) == NULL) { fprintf(stderr, (char *)lstr.open_tmp_print_err, tempname); XtFree(tempname); return(False); } /* write to a temp file */ fwrite(text_string, sizeof(char), strlen(text_string) , tfp); /* flush and close the file (note that if we are unlucky we use in both cases the same error message saying we are unable to close the file; the flush error is very unlikely here) */ if (fflush(tfp)) { result=False; fprintf(stderr,(char *)lstr.close_tmp_err,tempname); } if (fclose(tfp)) { result=False; fprintf(stderr,(char *)lstr.close_tmp_err,tempname); } if(!result) { unlink(tempname); XtFree(tempname); return(result); } #ifndef vax11c sprintf(work, "cat %s | %s", tempname, print_command); #else /* VMS doesn't allow for I/O redirection at all (It's one major handicap). So let's setup the print command to just print the file. */ sprintf(work, "%s %s", print_command, tempname); #endif /* !vax11c */ #if defined(vax11c) || defined(__DECC) if (!(system(work)&1)) result=False; #else if (system(work)) result=False; #endif /* vax11c */ unlink (tempname); XtFree (tempname); return(result); } /* PrintString */