12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: SearchCalls.c /main/13 1996/11/21 20:00:02 drk $ */
- /**********************************<+>*************************************
- ***************************************************************************
- **
- ** File: SearchCalls.c
- **
- ** Project: DtEditor widget for editing services
- **
- ** Description: Spell and Find functions
- ** -----------
- **
- *******************************************************************
- *
- * (c) Copyright 1996 Digital Equipment Corporation.
- * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company.
- * (c) Copyright 1993, 1994, 1996 International Business Machines Corp.
- * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
- * (c) Copyright 1996 Novell, Inc.
- * (c) Copyright 1996 FUJITSU LIMITED.
- * (c) Copyright 1996 Hitachi.
- * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of Novell, Inc.
- *
- ********************************************************************/
- #include "EditorP.h"
- #include <Xm/TextF.h>
- #include <Xm/MessageB.h>
- #include <Xm/List.h>
- #include <ctype.h>
- #include <limits.h>
- #include <Dt/DtMsgsP.h>
- #include <Dt/HourGlass.h>
- #include "DtWidgetI.h"
- #include <Xm/XmPrivate.h> /* _XmStringSourceGetString */
- #define X_INCLUDE_STRING_H
- #define XOS_USE_XT_LOCKING
- #include <X11/Xos_r.h>
- extern XtPointer
- _XmStringUngenerate(XmString string,
- XmStringTag tag,
- XmTextType tag_type,
- XmTextType output_type);
- static Boolean DoReplace(
- DtEditorWidget pPriv,
- char *replace_string,
- Time time);
- static int SearchForString(
- DtEditorWidget pPriv,
- XmTextPosition startLocation,
- char *searchString);
- static Boolean DoSearch(
- DtEditorWidget pPriv,
- char *search_string,
- Time time);
- static Boolean IsValidFilter(
- DtEditorWidget pPriv);
- static Boolean IsInGroup(
- gid_t gid);
- static Boolean IsExecutable(
- struct stat statbuf);
- static void DestroyThisWidgetCB(
- Widget w,
- XtPointer client,
- XtPointer call);
- DtEditorErrorCode
- DtEditorInvokeSpellDialog(
- Widget widget)
- {
- DtEditorWidget pPriv = (DtEditorWidget) widget;
- char fileName[L_tmpnam], com[L_tmpnam + 7], *string, newline[1];
- char *line;
- FILE *fp; /* pipe to read words from */
- int len = 0; /* length of line read in */
- int maxLen = 0; /* max length of the line buffer */
- XmString word; /* processed word ready to add to list */
- DtEditorErrorCode error = DtEDITOR_NO_TMP_FILE;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- newline[0]='\n';
- if (!IsValidFilter(pPriv)) {
- error = DtEDITOR_SPELL_FILTER_FAILED;
- }
- else {
- _DtTurnOnHourGlass(M_topLevelShell(pPriv));
- /*
- * Write out to a tmp file, getting the name back
- */
- (void)tmpnam(fileName);
- if((fp = fopen(fileName, "w")) != (FILE *)NULL)
- {
- /*
- * Temporary file created sucessfully so write out contents of
- * widget in preparation of feeding it to the 'spell' filter.
- */
- string = (char *)XmTextGetString(M_text(pPriv));
- fwrite(string, sizeof(char), strlen(string), fp);
- XtFree(string);
- /*
- * Tack on a final newline (\n) cuz spell(1) does not spell-check
- * lines which do not terminate with a newline.
- */
- fwrite(newline, sizeof(char), 1, fp);
- fclose(fp);
- /* start spell command */
- sprintf(com, "%s %s", M_spellFilter(pPriv), fileName);
- fp = popen(com, "r");
- if ( fp == (FILE *)NULL )
- error = DtEDITOR_SPELL_FILTER_FAILED;
- else {
- error = DtEDITOR_NO_ERRORS;
- /*
- * The filter was started successfully.
- * Initialize the Spell dialog and get ready to receive
- * the list of misspelled words.
- */
- _DtEditorSearch(pPriv, True, True);
- _DtTurnOnHourGlass(M_search_dialog(pPriv));
- /* needed for bug in list */
- XmListSetPos(M_search_spellList(pPriv), 1);
- XmListDeleteAllItems(M_search_spellList(pPriv));
- /*
- * malloc the buffer
- */
- maxLen = 50;
- line = (char *) XtMalloc (sizeof(char) * (maxLen + 1));
- len = 0;
- /*
- * Now, get each word and hand it to the list
- */
- while(fgets(&line[len], maxLen - len, fp))
- {
- len += strlen(&line[len]);
- if (len > 0)
- {
- if (line[len - 1] == '\n')
- {
- line[len - 1] = '\0';
- word = XmStringCreateLocalized(line);
- XmListAddItemUnselected(M_search_spellList(pPriv), word, 0);
- XmStringFree(word);
- len = 0;
- }
- else
- {
- maxLen += 50;
- line = (char *) XtRealloc (line, sizeof(char) * (maxLen + 1));
- }
- }
- }
- /* clean up and display the results */
- XtFree(line);
- pclose(fp);
- _DtEditorSearch(pPriv, True, False);
- _DtTurnOffHourGlass(M_search_dialog(pPriv));
- } /* end start the spell filter */
- unlink(fileName);
- } /* end create temporary file */
- _DtTurnOffHourGlass(M_topLevelShell(pPriv));
- }
- if (error != DtEDITOR_NO_ERRORS) {
- XmString title, msg1, msg2, msg3;
- Arg al[10];
- Cardinal ac;
- char *buf;
- Widget dialog;
- buf = XtMalloc((strlen(BAD_FILTER2) +
- strlen(M_spellFilter(pPriv)) + 1) *
- sizeof(char));
- sprintf(buf, BAD_FILTER2, M_spellFilter(pPriv));
- msg1 = XmStringGenerate(BAD_FILTER,
- XmFONTLIST_DEFAULT_TAG,
- XmCHARSET_TEXT, NULL);
- msg2 = XmStringSeparatorCreate();
- msg3= XmStringConcatAndFree(msg1, msg2);
- msg1 = XmStringGenerate(buf,
- XmFONTLIST_DEFAULT_TAG,
- XmCHARSET_TEXT, NULL);
- msg2 = XmStringConcatAndFree(msg3, msg1);
- XtFree(buf);
- title = XmStringCreateLocalized(ERROR_TITLE);
- ac = 0;
- XtSetArg(al[ac], XmNdialogTitle, title); ac++;
- XtSetArg(al[ac], XmNdialogType, XmDIALOG_ERROR); ac++;
- XtSetArg(al[ac], XmNmessageString, msg2); ac++;
- dialog = XmCreateMessageDialog((Widget)pPriv,
- "Spell Error", al, ac
- );
- XtUnmanageChild(XmMessageBoxGetChild(dialog,
- XmDIALOG_HELP_BUTTON));
- XtUnmanageChild(XmMessageBoxGetChild(dialog,
- XmDIALOG_CANCEL_BUTTON));
- XtAddCallback(dialog, XmNokCallback, DestroyThisWidgetCB, NULL);
- XtVaSetValues(XtParent(dialog),
- XmNdeleteResponse, XmDESTROY,
- NULL);
- XtManageChild(dialog);
- XmStringFree(msg2);
- XmStringFree(title);
- }
- _DtAppUnlock(app);
- return( error );
- } /* end DtEditorInvokeSpellDialog */
- static void DestroyThisWidgetCB (
- Widget w,
- XtPointer client,
- XtPointer call)
- {
- XtDestroyWidget(w);
- }
- /* ARGSUSED */
- Boolean
- DtEditorFind(
- Widget widget,
- char *find)
- {
- DtEditorWidget editor = (DtEditorWidget) widget;
- Boolean foundIt = True;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- /*
- * If we were passed a string to find, then use it. Otherwise,
- * use the last find string entered in the Find/Change dialog.
- */
- if ( find != (char *)NULL )
- foundIt = DoSearch(editor, find, CurrentTime);
- else
- {
- /*
- * If there is no value from the dialog, then post the Find/Change
- * dialog to get one.
- */
- if (!M_search_string(editor))
- _DtEditorSearch(editor, False, False);
- else
- foundIt = DoSearch(editor, M_search_string(editor), CurrentTime);
- }
- _DtAppUnlock(app);
- return( foundIt );
- } /* DtEditorFind */
- /* Count the number of characters represented in the char* str.
- * By definition, if MB_CUR_MAX == 1 then numBytes == number of characters.
- * Otherwise, use mblen to calculate.
- */
- int
- _DtEditor_CountCharacters(
- char *str,
- int numBytes)
- {
- char *bptr;
- int count = 0;
- int char_size = 0;
- int mbCurMax = MB_CUR_MAX; /* invoke the macro just once */
- if (mbCurMax <= 1)
- return (numBytes < 0)? 0 : numBytes;
- if (numBytes <=0 || str == NULL || *str == '\0')
- return 0;
- for(bptr = str; numBytes > 0; count++, bptr+= char_size)
- {
- char_size = mblen(bptr, mbCurMax);
- if (char_size <= 0)
- break; /* error */
- numBytes -= char_size;
- }
- return count;
- }
- /*
- * SearchForString takes an Editor widget, a position at which
- * to begin its search, and the string for which it is to search.
- * It searches first from startLocation to the end of the file, and
- * then if necessary from the start of the file to startLocation.
- * It returns an integer indicating the location of the string, or
- * -1 if the string is not found.
- */
- static int
- SearchForString(
- DtEditorWidget pPriv,
- XmTextPosition startLocation,
- char *searchString)
- {
- XmTextPosition pos, searchAnchor, topAnchor, cursorLocation,
- lastPosition = XmTextGetLastPosition(M_text(pPriv));
- topAnchor = 0;
- searchAnchor = cursorLocation = startLocation;
- while((Boolean)XmTextFindString(M_text(pPriv), searchAnchor,
- searchString, XmTEXT_FORWARD,
- &pos) ||
- ((Boolean)XmTextFindString(M_text(pPriv), topAnchor,
- searchString, XmTEXT_FORWARD, &pos) &&
- pos < cursorLocation))
- {
- char *word, leadingChar, trailingChar;
- XmTextPosition endPos;
- int length;
- /*
- * Do some extra work for the Spell case, so we find only "words"
- * and not strings.
- * Get the word with the leading & trailing characters.
- * It's a word if it's bounded by:
- * a. 16-bit characters
- * b. Spaces
- * c. Punctuation
- */
- /*
- * Variables:
- *
- * 0 (constant) - first character position in the document.
- * lastPosition - last character position in the document.
- *
- * pos - Position in the document of the first character
- * of the word. Does not include leading character.
- * endPos - Position in the document of the last character
- * of the word + 1. Points to the trailing character,
- * if any.
- *
- * word - The string we have matched. Includes the leading
- * & trailing characters, if any.
- * word[0] - Leading character, if any, otherwise first
- * character of the matched string.
- * word[length] - Trailing character, if any, otherwise last
- * character of the matched string.
- *
- */
- endPos = pos + 1 + _DtEditor_CountCharacters(searchString,
- strlen(searchString));
- if(pos < cursorLocation)
- topAnchor = pos + 1;
- else
- searchAnchor = pos + 1;
- /*
- * If the first character of the word is the first character in
- * the document there is no leading character. Likewise, if the
- * last character of the word is the last character in the document
- * there is no trailing character.
- */
- if( pos > 0 ) {
- /*
- * There is a leading character.
- */
- if (endPos <= lastPosition) {
- /*
- * There is a trailing character.
- */
- word = (char *)_XmStringSourceGetString(
- (XmTextWidget) M_text(pPriv),
- pos - 1, endPos, False);
- length = strlen(word) - 1;
- trailingChar = word[length];
- }
- else {
- /*
- * There is no trailing character.
- */
- word = (char *)_XmStringSourceGetString(
- (XmTextWidget) M_text(pPriv),
- pos - 1, lastPosition, False);
- length = strlen(word);
- trailingChar = ' ';
- }
- leadingChar = word[0];
- }
- else {
- /*
- * There is no leading character.
- */
- if (endPos <= lastPosition) {
- /*
- * There is a trailing character.
- */
- word = (char *)_XmStringSourceGetString(
- (XmTextWidget) M_text(pPriv),
- 0, endPos, False);
- length = strlen(word) - 1;
- trailingChar = word[length];
- }
- else {
- /*
- * There is no trailing character.
- */
- word = (char *)_XmStringSourceGetString(
- (XmTextWidget) M_text(pPriv),
- 0, lastPosition, False);
- length = strlen(word);
- trailingChar = ' ';
- }
- leadingChar = ' ';
- }
- if ((M_search_dialogMode(pPriv) != SPELL) ||
- (
- ((mblen(word, MB_CUR_MAX) > 1) ||
- ( isascii(leadingChar) &&
- (isspace(leadingChar) || ispunct(leadingChar))
- )
- ) &&
- ((mblen(word+length-1, MB_CUR_MAX) > 1) ||
- ( isascii(trailingChar) &&
- (isspace(trailingChar) || ispunct(trailingChar))
- )
- )
- )
- )
- {
- /*
- * Either we are not in Spell mode or we have a word
- * so return
- */
- if (word != (char *)NULL)
- XtFree(word);
- return (int)pos;
- }
- XtFree(word);
- }
- return -1;
- }
- static Boolean
- DoSearch(
- DtEditorWidget widget,
- char *search_string,
- Time time)
- {
- int stringPosition;
- Boolean foundIt = False;
- stringPosition = SearchForString(widget,
- XmTextGetInsertionPosition(M_text(widget)),
- search_string);
- if(stringPosition == -1) {
- /*
- * If the string was not found unselect everything
- */
- XmTextClearSelection(M_text(widget), time);
- }
- else {
- /*
- * The string was found so highlight the word and scroll the window
- * if it is not visible.
- */
- XmTextPosition pos = (XmTextPosition) stringPosition;
- XmTextWidget tw = (XmTextWidget)M_text(widget);
- foundIt = True;
- XmTextSetInsertionPosition(M_text(widget), pos);
- XmTextSetSelection( M_text(widget), pos,
- pos+_DtEditor_CountCharacters(search_string, strlen(search_string)),
- XtLastTimestampProcessed(XtDisplay(M_text(widget))) );
- /*
- * Scroll the widget, if necessary
- */
- if (pos < tw->text.top_character || pos >= tw->text.bottom_position)
- {
- Arg al[5];
- int ac;
- Dimension height;
- short rows;
- Position x, y;
- ac = 0;
- XtSetArg(al[ac], XmNheight, &height); ac++;
- XtSetArg(al[ac], XmNrows, &rows); ac++;
- XtGetValues(M_text(widget), al, ac);
- if(XmTextPosToXY(M_text(widget), pos, &x, &y) == True)
- {
- int offset = (int)((y - height/2) * rows) / (int)height;
- XmTextScroll(M_text(widget), offset);
- }
- }
- }
- return ( foundIt );
- } /* end DoSearch */
- /*
- * DtEditorInvokeFindChangeDialog posts the "Find/Change" dialog.
- */
- void
- DtEditorInvokeFindChangeDialog(
- Widget widget)
- {
- DtEditorWidget pPriv = (DtEditorWidget) widget;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- _DtEditorSearch(pPriv, False, False);
- _DtAppUnlock(app);
- }
- /*
- * DoReplace checks that there is a non-null selection, and
- * if so, replaces the selection with the replace_string argument.
- */
- static Boolean
- DoReplace(
- DtEditorWidget pPriv,
- char *replace_string,
- Time time)
- {
- XmTextPosition first, last;
- Boolean replaced = False;
- /*
- * Only do a replace if we have a non-null selection.
- * We could check that the selection == the Find string, but
- * this allows a little more flexibility for the user.
- */
- if (XmTextGetSelectionPosition(M_text(pPriv), &first, &last) &&
- first != last)
- {
- XmTextReplace(M_text(pPriv), first, last, replace_string);
- XmTextSetSelection(M_text(pPriv), first,
- first +
- _DtEditor_CountCharacters(replace_string, strlen(replace_string)),
- time);
- replaced = True;
- }
- return( replaced );
- }
- /*
- * ReplaceAll replaces all occurrences of search_string with
- * replacement_string in widget.
- */
- static Boolean
- ReplaceAll(
- DtEditorWidget widget,
- char *search_string,
- char *replace_string )
- {
- int replacementLength, searchLength, lastOccurrence, thisOccurrence;
- Boolean replaceOK = False;
- /*
- * Make sure there is a string to find. Null replacement strings
- * are OK.
- */
- if( search_string && *search_string )
- {
- /*
- * How long is the string we are searching for?
- */
- searchLength = _DtEditor_CountCharacters( search_string,
- strlen(search_string) );
- /*
- * How long is the replacement string?
- */
- replacementLength = _DtEditor_CountCharacters( replace_string,
- strlen(replace_string) );
- /*
- * Start at the beginning and search for the string
- */
- lastOccurrence = -1;
- while( ((thisOccurrence = SearchForString(widget,
- (lastOccurrence > 0)? (XmTextPosition)lastOccurrence : 0,
- search_string)
- ) != -1 ) &&
- thisOccurrence >= lastOccurrence )
- {
- XmTextReplace( M_text(widget), (XmTextPosition)thisOccurrence,
- (XmTextPosition) (thisOccurrence + searchLength),
- replace_string );
- lastOccurrence = thisOccurrence + replacementLength;
- } /* end while */
- if (lastOccurrence != -1)
- replaceOK = True;
- }
- return( replaceOK );
- } /* end ReplaceAll */
- /*
- * DtEditorChange replaces either the current selection, the next occurrence
- * of a string, or all occurrences of the string with a replacement string.
- * If no find or change to strings are passed in, DtEditorFindChange uses
- * the last find and change to strings from the Find/Change dialog.
- */
- Boolean
- DtEditorChange(
- Widget widget,
- DtEditorChangeValues *findChangeStrings,
- unsigned int instanceToChange)
- {
- Boolean returnVal = False;
- DtEditorWidget editor = (DtEditorWidget) widget;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- switch( instanceToChange )
- {
- case DtEDITOR_NEXT_OCCURRENCE:
- {
- /*
- * Find the next occurrence and replace it (by treating it as
- * a current selection).
- */
- /*
- * If we were passed a Find string use it. Otherwise, tell
- * DtEditorFind to use the last search string value
- * (M_search_string).
- */
- if ( findChangeStrings != (DtEditorChangeValues *) NULL )
- returnVal = DtEditorFind( widget, findChangeStrings->find );
- else
- returnVal = DtEditorFind( widget, (char *)NULL );
-
- if ( returnVal == False)
- break;
- }
- case DtEDITOR_CURRENT_SELECTION:
- {
- /*
- * Replace whatever is selected.
- */
- /*
- * If we were passed a Change To string use it. Otherwise,
- * use the last replace string value.
- */
- if ( findChangeStrings != (DtEditorChangeValues *) NULL )
- returnVal = DoReplace( editor, findChangeStrings->changeTo,
- CurrentTime );
- else
- returnVal= DoReplace(editor,M_replace_string(editor),CurrentTime);
- break;
- }
- case DtEDITOR_ALL_OCCURRENCES:
- {
- _DtTurnOnHourGlass( M_topLevelShell(editor) );
- if ( findChangeStrings != (DtEditorChangeValues *) NULL )
- returnVal = ReplaceAll( editor, findChangeStrings->find,
- findChangeStrings->changeTo );
- else
- returnVal = ReplaceAll( editor, M_search_string(editor),
- M_replace_string(editor) );
- _DtTurnOffHourGlass( M_topLevelShell( editor ) );
- break;
- } /* replace all occurrences */
- default :
- {
- }
- } /* end switch */
- _DtAppUnlock(app);
- return( returnVal );
- } /* end DtEditorChange */
- /* ARGSUSED */
- void
- _DtEditorSearchMapCB(
- Widget w,
- caddr_t client_data,
- caddr_t call_data )
- {
- int ac;
- Arg al[4];
- Widget parent;
- Position newX, newY, pY, pX;
- Dimension pHeight, myHeight, pWidth, myWidth;
- DtEditorWidget pPriv = (DtEditorWidget) client_data;
- parent = M_topLevelShell(pPriv);
- pX = XtX(parent);
- pY = XtY(parent);
- pHeight = XtHeight(parent);
- pWidth = XtWidth(parent);
- myHeight = XtHeight(w);
- myWidth = XtWidth(w);
- if ((newY = pY - (int)myHeight + 5) < 0)
- newY = pY + pHeight;
- newX = pX + pWidth/2 - ((int)myWidth)/2;
- ac = 0;
- XtSetArg(al[ac], XmNx, newX); ac++;
- XtSetArg(al[ac], XmNy, newY); ac++;
- XtSetValues(w,al,ac);
- }
- /*
- *
- * _DtEditorDialogSearchCB is called whenever the Find button is pressed
- * in the Find/Change dialog. If the dialog is displayed in Find/Change
- * mode, it updates the contents of M_search_string() with the contents
- * of the "Find" text field, and then invokes DtEditorFind(). If the
- * find is successful, the Change button is enabled, otherwise the
- * "String not found" dialog is displayed.
- *
- * When the dialog is in Spell mode, the selected misspelled word is merely
- * passed to DtEditorFind(). The Change (and Change All) buttons are left
- * insentive until the user types something into the Change To field
- * (too many users were replacing misspelled words with blanks).
- *
- */
- /* ARGSUSED */
- void
- _DtEditorDialogSearchCB(
- Widget w,
- caddr_t client_data,
- caddr_t call_data )
- {
- DtEditorWidget pPriv = (DtEditorWidget) client_data;
- /*
- * Is the dialog in Find/Change or Spell mode?
- */
- if (M_search_dialogMode(pPriv) == REPLACE) {
- /*
- * Find/Change mode
- * Free the existing search string and get the new one.
- */
- XtFree(M_search_string(pPriv));
- M_search_string(pPriv) = XmTextFieldGetString( M_findText(pPriv) );
- /*
- * Find the string
- */
- if( DtEditorFind((Widget)pPriv, M_search_string(pPriv)) ) {
- /*
- * If the string was found then enable the Change button.
- * It will be disabled when it is pressed or a new Find string is
- * entered.
- */
- _DtEditorSetReplaceSensitivity( pPriv, True );
- }
- else {
- /*
- * Post a dialog informing the user the string was not found.
- */
- char *tempStr = (char *)XtMalloc(strlen(NO_FIND) +
- strlen(M_search_string(pPriv)) + 1);
- sprintf(tempStr, NO_FIND, M_search_string(pPriv));
- _DtEditorWarning(pPriv, tempStr, XmDIALOG_INFORMATION);
- XtFree(tempStr);
- }
- }
- else {
- /*
- * Spell mode.
- */
- char *pString;
- M_misspelled_found(pPriv) = DtEditorFind((Widget)pPriv,
- M_misspelled_string(pPriv) );
- /*
- * If the word was found & there is a Change To string then enable
- * the Change button. If there is no Change To string, Change will
- * be enabled when a string is entered if M_misspelled_found is True
- * (see _DtEditorReplaceTextChangedCB)
- *
- * Change All is enabled in _DtEditorReplaceTextChangedCB()
- * (ie. anytime there is a Change To string). It is not
- * dependent upon a sucessful Find because it initiates its own
- * find.
- */
- if ( M_misspelled_found(pPriv) == True ) {
- /*
- * Is there a Change To string?
- */
- pString = XmTextFieldGetString(M_replaceText(pPriv));
- if( pString != (char *)NULL && *pString != (char)'\0' )
- _DtEditorSetReplaceSensitivity( pPriv, True );
- XtFree(pString);
- }
- else {
- /*
- * Post a dialog informing the user the string was not found.
- */
- char *tempStr = (char *)XtMalloc(strlen(NO_FIND) +
- strlen(M_misspelled_string(pPriv)) + 1);
- sprintf(tempStr, NO_FIND, M_misspelled_string(pPriv));
- _DtEditorWarning(pPriv, tempStr, XmDIALOG_INFORMATION);
- XtFree(tempStr);
- }
- }
- } /* end _DtEditorDialogSearchCB */
- /*
- * _DtEditorDialogReplaceCB is called whenever the Change button is pressed
- * in the Find/Change dialog. If the dialog is displayed in Find/Change
- * mode, it updates the contents of M_replace_string() with the contents
- * of the "Change To" text field, and then invokes DtEditorChange().
- *
- * When the dialog is in Spell mode, the contents of the "Change To" text
- * field is passed to DtEditorChange() without updating M_replace_string().
- *
- * In both cases, the Change button is disabled after the change is
- * complete.
- */
- /* ARGSUSED */
- void
- _DtEditorDialogReplaceCB(
- Widget w,
- caddr_t client_data,
- caddr_t call_data )
- {
- DtEditorWidget pPriv = (DtEditorWidget) client_data;
- /*
- * Is the dialog in Find/Change or Spell mode?
- */
- if (M_search_dialogMode(pPriv) == REPLACE) {
- /*
- * Find/Change mode
- * Free the existing Change To string and get the new one.
- */
- XtFree(M_replace_string(pPriv));
- M_replace_string(pPriv) = XmTextFieldGetString(M_replaceText(pPriv));
- DtEditorChange( (Widget)pPriv, (DtEditorChangeValues *)NULL,
- DtEDITOR_CURRENT_SELECTION );
- }
- else {
- /*
- * Spell mode.
- */
- DtEditorChangeValues newWord;
- newWord.changeTo = XmTextFieldGetString(M_replaceText(pPriv));
- if (newWord.changeTo != (char *)NULL) {
- /* This field ignored when changing the current selection */
- newWord.find = (char *)NULL;
- DtEditorChange( (Widget)pPriv, &newWord, DtEDITOR_CURRENT_SELECTION );
- XtFree(newWord.changeTo);
- }
- }
- /*
- * Disable the Change button. In Find/Change mode, it will be enabled
- * when the Find button is pressed and the Find text is successfully
- * found. In Spell mode, there must also be a value in the Change To
- * field.
- */
- _DtEditorSetReplaceSensitivity(pPriv, False );
- /*
- * Want the traversal to be on the Find button, so that the user
- * can initiate another search.
- */
- XmProcessTraversal(M_search_findBtn(pPriv), XmTRAVERSE_CURRENT);
- }
- /*
- * _DtEditorDialogReplaceAllCB is attached to the "Change All" button
- * in the Find/Change dialog. It replaces all occurrences of the "Find"
- * string with the "Change To" string.
- */
- /* ARGSUSED */
- void
- _DtEditorDialogReplaceAllCB(
- Widget w,
- caddr_t client_data,
- caddr_t call_data )
- {
- DtEditorWidget pPriv = (DtEditorWidget) client_data;
- /*
- * Is the dialog in Find/Change or Spell mode?
- */
- if (M_search_dialogMode(pPriv) == REPLACE) {
- /*
- * Find/Change mode
- * Free any existing search string before getting the current one.
- */
- XtFree(M_search_string(pPriv));
- M_search_string(pPriv) = XmTextFieldGetString(M_findText(pPriv));
- /*
- * Free the existing Change To string and get the new one.
- */
- XtFree(M_replace_string(pPriv));
- M_replace_string(pPriv) = XmTextFieldGetString(M_replaceText(pPriv));
- /*
- * Make the change with the current values (set above).
- */
- if( !DtEditorChange((Widget)pPriv, (DtEditorChangeValues *)NULL,
- DtEDITOR_ALL_OCCURRENCES) ) {
- /*
- * If the replace failed, post a dialog informing the user
- * the string was not found.
- */
- char *tempStr = (char *)XtMalloc(strlen(NO_FIND) +
- strlen(M_search_string(pPriv)) + 1);
- sprintf(tempStr, NO_FIND, M_search_string(pPriv));
- _DtEditorWarning(pPriv, tempStr, XmDIALOG_INFORMATION);
- XtFree(tempStr);
- }
- }
- else {
- /*
- * Spell mode.
- */
- DtEditorChangeValues changeValues;
- changeValues.find = M_misspelled_string(pPriv);
- changeValues.changeTo = XmTextFieldGetString(M_replaceText(pPriv));
- DtEditorChange((Widget)pPriv, &changeValues, DtEDITOR_ALL_OCCURRENCES);
- XtFree( changeValues.changeTo );
- }
- /*
- * Disable the Change button. It will be enabled when the Find
- * button is pressed and the Find text is successfully found.
- * In Spell mode, there must also be a value in the Change To field.
- */
- _DtEditorSetReplaceSensitivity(pPriv, False );
- } /* _DtEditorDialogReplaceAllCB */
- /* ARGSUSED */
- void
- _DtEditorDialogFindCancelCB(
- Widget w,
- caddr_t client_data,
- caddr_t call_data )
- {
- DtEditorWidget pPriv = (DtEditorWidget)client_data;
- XtUnmanageChild(M_search_dialog(pPriv));
- }
- /*
- * _DtEditorMisspelledSelectCB is called when a new word has been selected
- * from the list of misspelled words.
- */
- /* ARGSUSED */
- void
- _DtEditorMisspelledSelectCB(
- Widget w,
- caddr_t client_data,
- caddr_t call_data )
- {
- XmListCallbackStruct *cb = (XmListCallbackStruct *)call_data;
- DtEditorWidget editor = (DtEditorWidget)client_data;
- /*
- * Get the selected word for use when the Find or Replace All button
- * is pressed.
- */
- XtFree(M_misspelled_string(editor));
- M_misspelled_string(editor) =
- _XmStringUngenerate(cb->item, NULL, XmCHARSET_TEXT, XmCHARSET_TEXT);
- /*
- * Mark that it has not been found
- */
- M_misspelled_found(editor) = False;
- /*
- * Enable the Find button
- */
- _DtEditorSetFindSensitivity(editor, True );
- /*
- * Clear the "Change To" text field.
- */
- XmTextFieldSetString(M_replaceText(editor), (char *)NULL);
- } /* end _DtEditorMisspelledSelectCB */
- /*
- * _DtEditorMisspelledDblClickCB is called when a word has been double-
- * clicked from the list of misspelled words. First, the word will become
- * the new misspelled string and, then, a find will be initiated for it.
- */
- /* ARGSUSED */
- void
- _DtEditorMisspelledDblClickCB(
- Widget w,
- caddr_t client_data,
- caddr_t call_data )
- {
- _DtEditorMisspelledSelectCB(w, client_data, call_data );
- _DtEditorDialogSearchCB(w, client_data, call_data );
- } /* end _DtEditorMisspelledDblClickCB */
- /*
- * The following functions effectively track whether the user has
- * entered or changed the "Find" text. This information is used to make
- * the "Find" and "Change All" buttons sensitive/desensitive. The
- * "Find" button must be pressed and the Find text found before the
- * "Change" button is sensitive. These functions also set the default
- * button to either the "Find" or "Close" button.
- */
-
- void
- _DtEditorSetFindSensitivity(
- DtEditorWidget widget,
- Boolean sensitivity)
- {
- XtSetSensitive(M_search_findBtn(widget), sensitivity);
- }
- void
- _DtEditorSetReplaceSensitivity(
- DtEditorWidget editor,
- Boolean sensitivity)
- {
- /*
- * Cannot enable Change button if widget is read only
- */
- if ( M_editable(editor) || !sensitivity )
- XtSetSensitive(M_search_replaceBtn(editor), sensitivity);
- }
- void
- _DtEditorSetReplaceAllSensitivity(
- DtEditorWidget editor,
- Boolean sensitivity)
- {
- /*
- * Cannot enable Change All button if widget is read only
- */
- if ( M_editable(editor) || !sensitivity )
- XtSetSensitive(M_search_replaceAllBtn(editor), sensitivity);
- }
- /* ARGSUSED */
- void
- _DtEditorFindTextChangedCB(
- Widget w,
- caddr_t client_data,
- caddr_t call_data )
- {
- Arg al[10]; /* arg list */
- Widget defaultButton;
- char *pString;
- DtEditorWidget editor = (DtEditorWidget)client_data;
- /*
- * Is there a Find string?
- */
- pString = XmTextFieldGetString(M_findText(editor));
- /*
- * Only enable the Find & Change All buttons if there is a
- * string to search for (i.e. a Find string).
- */
- if(pString == (char *)NULL || *pString == (char)'\0') {
- _DtEditorSetFindSensitivity(editor, False );
- _DtEditorSetReplaceAllSensitivity(editor, False );
- /*
- * Make the Close button the default
- */
- defaultButton = M_search_closeBtn(editor);
- }
- else {
- _DtEditorSetFindSensitivity( editor, True );
- _DtEditorSetReplaceAllSensitivity(editor, True );
- /*
- * Make the Find button the default
- */
- defaultButton = M_search_findBtn(editor);
- }
- XtFree(pString);
- /*
- * Set the default button
- */
- XtSetArg(al[0], XmNdefaultButton, defaultButton);
- XtSetValues(M_search_dialog(editor), al, 1);
- /*
- * Disable the Change button. It will be enabled when the Find
- * button is pressed and the Find text is successfully found.
- */
- _DtEditorSetReplaceSensitivity(editor, False );
- } /* end _DtEditorFindTextChangedCB */
- /*
- * The following functions effectively track whether the user has
- * entered or changed the Change To text. This information is used
- * in the Spell dialog to make the Change and Change All buttons
- * sensitive/desensitive so users cannot replace a misspelled word with
- * a null string.
- */
- /* ARGSUSED */
- void
- _DtEditorReplaceTextChangedCB(
- Widget w,
- caddr_t client_data,
- caddr_t call_data )
- {
- char *pString;
- DtEditorWidget editor = (DtEditorWidget)client_data;
- /*
- * Ignore this callback if it is not being called from the Spell
- * dialog.
- */
- if( M_search_dialogMode(editor) == SPELL ) {
- /*
- * Is there a Change To string?
- */
- pString = XmTextFieldGetString(M_replaceText(editor));
- /*
- * Disable the Change & Change All buttons if there is
- * no Change To string.
- */
- if( pString == (char *)NULL || *pString == (char)'\0' ) {
- _DtEditorSetReplaceSensitivity(editor, False );
- _DtEditorSetReplaceAllSensitivity(editor, False );
- }
- else {
- /*
- * If there is a Change To string enable the Change
- * All button, but only enable the Change button if.
- * the Find button has been pressed & the misspelled
- * word found (see _DtEditorDialogSearchCB()
- */
- _DtEditorSetReplaceAllSensitivity(editor, True );
- if ( M_misspelled_found(editor) )
- _DtEditorSetReplaceSensitivity(editor, True );
- XtFree(pString);
- }
- }
- } /* end _DtEditorReplaceTextChangedCB */
- /***
- IsInGroup -
- Check to see if the process is in the group, gid.
- ***/
- static Boolean IsInGroup(gid_t gid)
- {
- gid_t grps[NGROUPS_MAX];
- int i;
- int num_grps;
- num_grps = getgroups(NGROUPS_MAX, grps);
- if (num_grps == -1)
- return(False);
- for (i=0; i < num_grps; i++) {
- if (gid == grps[i])
- return(True);
- }
- return(False);
- }
- /***
- IsExecutable -
- Check to see if the process can execute the filter.
- ****/
- static Boolean IsExecutable(struct stat statbuf)
- {
- Boolean ingroup = IsInGroup(statbuf.st_gid);
- if (geteuid() == 0) { /** if root **/
- /** if any execute bit is set, root can execute **/
- if ((statbuf.st_mode & S_IXUSR)
- || (statbuf.st_mode & S_IXGRP)
- || (statbuf.st_mode & S_IXOTH))
- {
- return (True);
- }
- else {
- return (False);
- }
- }
- /*
- * if this process is the user and the user
- * does have execute permission, then the
- * filter will run, so return false
- */
- if ((statbuf.st_uid == geteuid())
- && (statbuf.st_mode & S_IXUSR))
- {
- return(True);
- }
- /*
- * if this process is in the group for the
- * filter and group execute is set (and the
- * process isn't the user, then return true
- */
- if (ingroup
- && (statbuf.st_mode & S_IXGRP)
- && (statbuf.st_uid != geteuid()))
- {
- return(True);
- }
- /*
- * if this process is not in the group or the user
- * for the filter and other execute is set, then
- * return true
- */
- if ((statbuf.st_mode & S_IXOTH)
- && (statbuf.st_uid != geteuid())
- && !ingroup)
- {
- return(True);
- }
- return(False);
- }
- /*****
- IsValidFilter -
- This function checks to makes sure that this filter
- can be found, i.e. is in the current path and istalled.
- *****/
- static Boolean IsValidFilter(DtEditorWidget pPriv)
- {
- char *pathstr;
- char *pathtmp;
- char *pathtok;
- char *tmp;
- struct stat statbuf;
- _Xstrtokparams strtok_buf;
- /** check to see if a full path to the filter is given **/
- if (*M_spellFilter(pPriv) == '/') {
- if (stat(M_spellFilter(pPriv), &statbuf) != -1)
- return(IsExecutable(statbuf));
- else
- return(False);
- }
- /*
- * get the PATH from the environment and check to see if
- * the filter is in the path
- */
- pathstr = getenv("PATH");
- if (pathstr == NULL)
- return(FALSE);
- pathtmp = XtNewString(pathstr);
- pathtok = _XStrtok(pathtmp, ":", strtok_buf);
- while (pathtok != NULL) {
- tmp = (char*)XtMalloc((strlen(pathtok)
- + strlen(M_spellFilter(pPriv))
- + 2) * sizeof(char));
- strcpy(tmp, pathtok);
- strcat(tmp, "/");
- strcat(tmp, M_spellFilter(pPriv));
- if (stat(tmp, &statbuf) != -1) {
- XtFree(pathtmp);
- XtFree(tmp);
- return(IsExecutable(statbuf));
- }
- XtFree(tmp);
- pathtok = _XStrtok(NULL,":", strtok_buf);
- }
- XtFree(pathtmp);
- return(False);
- }
|