12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880 |
- /*
- * 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
- */
- /* $TOG: EditAreaData.c /main/6 1998/03/03 16:18:13 mgreess $ */
- /**********************************<+>*************************************
- ***************************************************************************
- **
- ** File: EditAreaData.c
- **
- ** Project: DtEditor widget for editing services
- **
- ** Description: Contains functions for getting and setting the data
- ** on which the editor operates.
- ** -----------
- **
- *******************************************************************
- *
- * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of Novell, Inc.
- * (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.
- *
- ********************************************************************
- **
- **
- **************************************************************************
- **********************************<+>*************************************/
- #include "EditorP.h"
- #include <X11/Xutil.h>
- #include <Xm/TextP.h>
- #include <unistd.h>
- #include "DtWidgetI.h"
- typedef enum _LoadActionType {
- LOAD_DATA,
- INSERT_DATA,
- APPEND_DATA,
- REPLACE_DATA
- } LoadActionType;
- static DtEditorErrorCode Check4EnoughMemory(
- int numBytes);
- static DtEditorErrorCode StripEmbeddedNulls(
- char *stringData,
- int *length);
- static DtEditorErrorCode LoadFile(
- Widget w,
- char *fileName,
- LoadActionType action,
- XmTextPosition startReplace,
- XmTextPosition endReplace );
- #ifdef NEED_STRCASECMP
- /*
- * in case strcasecmp is not provided by the system here is one
- * which does the trick
- */
- static int
- strcasecmp(s1, s2)
- char *s1, *s2;
- {
- int c1, c2;
- while (*s1 && *s2) {
- c1 = isupper(*s1) ? tolower(*s1) : *s1;
- c2 = isupper(*s2) ? tolower(*s2) : *s2;
- if (c1 != c2)
- return (1);
- s1++;
- s2++;
- }
- if (*s1 || *s2)
- return (1);
- return (0);
- }
- #endif
- /*****************************************************************************
- *
- * Check4EnoughMemory - estimates whether there is enough memory to malloc
- * "numBytes" of memory. This routine doubles the amount needed because the
- * routines that use it are putting data into the text widget & we must make
- * sure the widget will have room, too.
- *
- * Returns DtEDITOR_NO_ERRORS
- * DtEDITOR_ILLEGAL_SIZE
- * DtEDITOR_INSUFFICIENT_MEMORY
- *
- *****************************************************************************/
- static DtEditorErrorCode
- Check4EnoughMemory(
- int numBytes)
- {
- DtEditorErrorCode returnVal = DtEDITOR_ILLEGAL_SIZE;
- if (numBytes > 0) {
- char *tmpString = (char *)malloc((2 * numBytes) + (numBytes/10));
- if(tmpString == (char *)NULL)
- returnVal = DtEDITOR_INSUFFICIENT_MEMORY;
- else {
- returnVal = DtEDITOR_NO_ERRORS;
- free(tmpString);
- }
- }
- return( returnVal );
- } /* end Check4EnoughMemory */
- /*****************************************************************************
- *
- * StripEmbeddedNulls - removes any embedded NULLs (\0) in a string of length
- * 'length'. The removal occurs in place, with 'length' set to the
- * new, stripped length. The resulting string is terminated with a
- * trailing NULL.
- *
- * Returns DtEDITOR_NO_ERRORS - the string did not contain any embedded NULLs
- * DtEDITOR_NULLS_REMOVED - the string did contain embedded
- * NULLs that were removed.
- *
- *****************************************************************************/
- static DtEditorErrorCode
- StripEmbeddedNulls(
- char *stringData,
- int *length)
- {
- DtEditorErrorCode returnVal = DtEDITOR_NO_ERRORS;
- if (strlen(stringData) != *length)
- {
- int firstNull;
- returnVal = DtEDITOR_NULLS_REMOVED;
- /*
- * The file contains NULL characters, so we strip them out and
- * report that we have done so.
- */
- while((firstNull = strlen(stringData)) != *length)
- {
- int lastNull = firstNull;
- while((lastNull + 1) < *length &&
- stringData[lastNull + 1] == (char)'\0')
- lastNull++;
- memcpy(&stringData[firstNull], &stringData[lastNull + 1],
- *length - lastNull);
- *length -= 1 + lastNull - firstNull;
- }
- }
- return( returnVal);
- } /* end StripEmbeddedNulls */
- /*****************************************************************************
- *
- * Retrieves the current location of the insert cursor
- *
- *****************************************************************************/
- XmTextPosition
- DtEditorGetInsertionPosition(
- Widget widget)
- {
- DtEditorWidget editor = (DtEditorWidget) widget;
- XmTextPosition result;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- result = XmTextGetInsertionPosition(M_text(editor));
- _DtAppUnlock(app);
- return result;
- }
- /*****************************************************************************
- *
- * Retrieves the current location of the last character in the widget
- *
- *****************************************************************************/
- XmTextPosition
- DtEditorGetLastPosition(
- Widget widget)
- {
- DtEditorWidget editor = (DtEditorWidget) widget;
- XmTextPosition result;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- result = XmTextGetLastPosition(M_text(editor));
- _DtAppUnlock(app);
- return result;
- }
- /*****************************************************************************
- *
- * Changes the current location of the insert cursor
- *
- *****************************************************************************/
- void
- DtEditorSetInsertionPosition(
- Widget widget,
- XmTextPosition position)
- {
- DtEditorWidget editor = (DtEditorWidget) widget;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- XmTextSetInsertionPosition(M_text(editor), position);
- _DtAppUnlock(app);
- }
- static DtEditorErrorCode
- setStringValue(
- DtEditorWidget editor,
- char *data)
- {
- /*
- * Tell _DtEditorModifyVerifyCB() that we're replacing the entire
- * contents, so it doesn't try to save the current document in an
- * undo structure for a later undo.
- */
- M_loadingAllNewData(editor) = True;
- XmTextSetString( M_text(editor), data );
- /*
- * If the _DtEditorModifyVerifyCB() did not get called, reset the
- * things which usually get reset there. The modifyVerify callback
- * will not get called if the contents are being set to a null string
- * and the widget is already empty.
- */
- if (M_loadingAllNewData(editor) == True) {
- M_loadingAllNewData(editor) = False;
- M_unreadChanges(editor) = False;
- _DtEditorResetUndo(editor);
- }
- return( DtEDITOR_NO_ERRORS );
- } /* end setStringValue */
- static DtEditorErrorCode
- setDataValue(
- DtEditorWidget widget,
- void *rawData,
- int length)
- {
- DtEditorErrorCode status = DtEDITOR_NULL_ITEM, tmpError;
- /*
- * Validate input
- */
- if (rawData != (void *)NULL)
- {
- /*
- * Check to see if we have a valid buffer size & enough memory to
- * load the buffer into the text widget. This is only an estimate
- * of our needs.
- * Check4EnoughMemory() returns DtEDITOR_NO_ERRORS,
- * DtEDITOR_ILLEGAL_SIZE, or DtEDITOR_INSUFFICIENT_MEMORY.
- */
- status = Check4EnoughMemory( length );
- if (status == DtEDITOR_NO_ERRORS)
- {
- /*
- * Convert the data buffer into a string & insert into the widget
- */
- char *textData = (char *)XtMalloc(length + 1);
- memcpy( textData, rawData, length );
- textData[length] = '\0';
- /*
- * Strip out any embedded NULLs because the text widget will only
- * accept data up to the first NULL.
- *
- * StripEmbeddedNulls() returns DtEDITOR_NO_ERRORS or
- * DtEDITOR_NULLS_REMOVED
- */
- status = StripEmbeddedNulls( textData, &length );
- /*
- * Now, insert the converted string into the text widget
- */
- tmpError = setStringValue( widget, textData );
- if (tmpError != DtEDITOR_NO_ERRORS)
- status = tmpError;
- XtFree( (char *)textData );
- }
- }
- return( status );
- } /* end setDataValue */
- static DtEditorErrorCode
- setWcharValue(
- DtEditorWidget editor,
- wchar_t *data)
- {
- DtEditorErrorCode status;
- wchar_t *tmp_wc;
- int result, num_chars=0;
- char *mb_value = (char *)NULL;
- /*
- * Convert the wide char string to a multi-byte string & stick it in
- * the text widget.
- */
-
- /*
- * Determine how big the resulting mb string may be
- */
- for (num_chars = 0, tmp_wc = data; *tmp_wc != (wchar_t)0L; num_chars++)
- tmp_wc++;
- /*
- * Check to see if we have enough memory to load the string
- * into the text widget. This is only an estimate of our needs.
- * status will be set to DtEDITOR_NO_ERRORS, DtEDITOR_ILLEGAL_SIZE, or
- * DtEDITOR_INSUFFICIENT_MEMORY.
- */
- status = Check4EnoughMemory( (num_chars + 1) * MB_CUR_MAX );
- if (status != DtEDITOR_NO_ERRORS) return status;
- mb_value = XtMalloc( (unsigned)(num_chars + 1) * MB_CUR_MAX );
- /*
- * Convert the wchar string
- * If wcstombs fails it returns (size_t) -1, so pass in empty
- * string.
- */
- result = wcstombs( mb_value, data, (num_chars + 1) * MB_CUR_MAX );
- if (result == (size_t)-1)
- result = 0;
- /*
- * wcstombs doesn't guarantee string is NULL terminated
- */
- mb_value[result] = 0;
- status = setStringValue( editor, mb_value );
- XtFree(mb_value);
- return( status );
- } /* end setWcharValue */
- static DtEditorErrorCode
- insertStringValue(
- DtEditorWidget editor,
- char *data,
- LoadActionType typeOfInsert,
- XmTextPosition beginInsert,
- XmTextPosition endInsert)
- {
- int numInserted;
- switch( typeOfInsert )
- {
- case INSERT_DATA:
- {
- beginInsert = endInsert = XmTextGetInsertionPosition( M_text(editor) );
- break;
- }
- case APPEND_DATA:
- {
- beginInsert = endInsert = XmTextGetLastPosition( M_text(editor) );
- break;
- }
- case REPLACE_DATA:
- {
- break;
- }
- default:
- {
- }
- } /* end switch */
- /*
- * Insert/Replace/Append the data and move the insertion cursor to
- * the end of the inserted data.
- */
- numInserted = _DtEditor_CountCharacters( data, strlen(data) );
- XmTextReplace(M_text(editor), beginInsert, endInsert, data);
- XmTextSetInsertionPosition( M_text(editor),
- (XmTextPosition)(beginInsert + numInserted) );
- return( DtEDITOR_NO_ERRORS );
- } /* insertStringValue */
- static DtEditorErrorCode
- insertDataValue(
- DtEditorWidget widget,
- void *rawData,
- int length,
- LoadActionType typeOfInsert,
- XmTextPosition beginInsert,
- XmTextPosition endInsert)
- {
- DtEditorErrorCode status = DtEDITOR_NULL_ITEM, loadError;
- /*
- * Validate input
- */
- if (rawData != (void *) NULL)
- {
- /*
- * Check to see if we have a valid buffer size & enough memory to
- * insert the buffer into the text widget. This is only an estimate
- * of our needs.
- * status will be set to DtEDITOR_NO_ERRORS, DtEDITOR_ILLEGAL_SIZE, or
- * DtEDITOR_INSUFFICIENT_MEMORY.
- */
- status = Check4EnoughMemory( length );
- if (status == DtEDITOR_NO_ERRORS)
- {
- /*
- * Convert the data buffer into a string & insert into the widget
- */
- char *textData = (char *)XtMalloc(length + 1);
- memcpy( textData, rawData, length );
- textData[length] = '\0';
- /*
- * Strip out any embedded NULLs because the text widget will only
- * accept data up to the first NULL.
- *
- * StripEmbeddedNulls() returns DtEDITOR_NO_ERRORS or
- * DtEDITOR_NULLS_REMOVED
- */
- status = StripEmbeddedNulls( textData, &length );
- /*
- * Now, insert the converted string into the text widget
- */
- loadError = insertStringValue( widget, textData, typeOfInsert,
- beginInsert, endInsert );
- if (loadError != DtEDITOR_NO_ERRORS)
- status = loadError;
- XtFree( (char *)textData );
- }
- }
- return( status );
- } /* insertDataValue */
- static DtEditorErrorCode
- insertWcharValue(
- DtEditorWidget editor,
- wchar_t *data,
- LoadActionType typeOfInsert,
- XmTextPosition beginInsert,
- XmTextPosition endInsert)
- {
- wchar_t *tmp_wc;
- int result, num_chars=0;
- char *mb_value = (char *)NULL;
- DtEditorErrorCode status;
- /*
- * Convert the wide char string to a multi-byte string & insert it into
- * the text widget.
- */
-
- /*
- * Determine how big the resulting mb string may be
- */
- for (num_chars = 0, tmp_wc = data; *tmp_wc != (wchar_t)0L; num_chars++)
- tmp_wc++;
- /*
- * Check to see if we have enough memory to insert the string
- * into the text widget. This is only an estimate of our needs.
- * status will be set to DtEDITOR_NO_ERRORS, DtEDITOR_ILLEGAL_SIZE, or
- * DtEDITOR_INSUFFICIENT_MEMORY.
- */
- status = Check4EnoughMemory( (num_chars + 1) * MB_CUR_MAX );
- if(status != DtEDITOR_NO_ERRORS) return status;
- mb_value = XtMalloc( (unsigned)(num_chars + 1) * MB_CUR_MAX );
- /*
- * Convert the wchar string.
- * If wcstombs fails it returns (size_t) -1, so pass in empty
- * string.
- */
- result = wcstombs( mb_value, data, (num_chars + 1) * MB_CUR_MAX );
- if (result == (size_t)-1)
- result = 0;
- /*
- * wcstombs doesn't guarantee string is NULL terminated
- */
- mb_value[result] = 0;
- status = insertStringValue( editor, mb_value, typeOfInsert,
- beginInsert, endInsert );
- XtFree( mb_value );
- return( status );
- } /* insertWcharValue */
- /***************************************************************************
- *
- * DtEditorSetContents - sets the contents of the DtEditor widget.
- *
- * Inputs: widget to set the contents
- *
- * a data structure containing the data to put into the
- * widget. Depending upon the type of data being set, this
- * structure will contain various fields:
- *
- * string - \0-terminated string of characters
- * data - the data, the size of the data
- *
- * Returns 0 - contents were set sucessfully
- * !0 - an error occurred while setting the contents
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorSetContents(
- Widget widget,
- DtEditorContentRec *data )
- {
- DtEditorErrorCode error = DtEDITOR_INVALID_TYPE;
- DtEditorWidget editor = (DtEditorWidget) widget;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- switch( data->type )
- {
- case DtEDITOR_TEXT:
- {
- error = setStringValue ( editor, data->value.string );
- break;
- }
- case DtEDITOR_DATA:
- {
- error = setDataValue ( editor, data->value.data.buf,
- data->value.data.length);
- break;
- }
- case DtEDITOR_WCHAR:
- {
- error = setWcharValue ( editor, data->value.wchar );
- break;
- }
- default :
- {
- error = DtEDITOR_INVALID_TYPE;
- }
- } /* end switch */
- /*
- * Update the current-line-display in the status line
- */
- if (error == DtEDITOR_NO_ERRORS)
- _DtEditorUpdateLineDisplay(editor, 1, False );
- _DtAppUnlock(app);
- return( error );
- }
- /***************************************************************************
- *
- * DtEditorSetContentsFromFile - read a data file, putting the contents
- * into a DtEditor widget.
- *
- * Inputs: widget to load the file into
- *
- * to indicate the type of contents loaded from the file:
- * string - a \0-terminated string of characters
- * data - untyped data
- *
- * filename - name of the file to read
- *
- * Returns 0 - contents were loaded sucessfully
- * !0 - an error occurred while loading the contents
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorSetContentsFromFile(
- Widget widget,
- char *fileName)
- {
- DtEditorErrorCode result;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- result = LoadFile(widget, fileName, LOAD_DATA, 0, 0);
- _DtAppUnlock(app);
- return result;
- }
- /***************************************************************************
- *
- * DtEditorAppend - append data to the contents of the DtEditor widget.
- *
- * Inputs: widget to add to the contents
- *
- * a data structure containing the data to append to the
- * widget. Depending upon the type of data being set, this
- * structure will contain various fields:
- *
- * string - \0-terminated string of characters
- * data - the data, the size of the data
- *
- * Returns 0 - contents were set sucessfully
- * !0 - an error occurred while setting the contents
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorAppend(
- Widget widget,
- DtEditorContentRec *data )
- {
- DtEditorErrorCode error = DtEDITOR_INVALID_TYPE;
- DtEditorWidget editor = (DtEditorWidget) widget;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- switch( data->type )
- {
- case DtEDITOR_TEXT:
- {
- error = insertStringValue ( editor, data->value.string,
- APPEND_DATA, 0, 0 );
- break;
- }
- case DtEDITOR_DATA:
- {
- error = insertDataValue ( editor, data->value.data.buf,
- data->value.data.length, APPEND_DATA, 0,0);
- break;
- }
- case DtEDITOR_WCHAR:
- {
- error = insertWcharValue ( editor, data->value.wchar,
- APPEND_DATA, 0, 0 );
- break;
- }
- default:
- {
- error = DtEDITOR_INVALID_TYPE;
- }
- } /* end switch */
- _DtAppUnlock(app);
- return( error );
- }
- /***************************************************************************
- *
- * DtEditorAppendFromFile - read a data file, appending the contents
- * into a DtEditor widget.
- *
- * Inputs: widget to append the file to
- *
- * to indicate the type of contents appended from the file:
- * string - a \0-terminated string of characters
- * data - untyped data
- *
- * filename - name of the file to read
- *
- * Returns 0 - contents were appended sucessfully
- * !0 - an error occurred while appending the contents
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorAppendFromFile(
- Widget widget,
- char *fileName)
- {
- DtEditorErrorCode result;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- result = LoadFile(widget, fileName, APPEND_DATA, 0, 0);
- _DtAppUnlock(app);
- return result;
- }
- /***************************************************************************
- *
- * DtEditorInsert - insert data into the contents of the DtEditor widget.
- *
- * Inputs: widget to add to the contents
- *
- * a data structure containing the data to insert into the
- * widget. Depending upon the type of data being set, this
- * structure will contain various fields:
- *
- * string - \0-terminated string of characters
- * data - the data, the size of the data
- *
- * Returns 0 - contents were set sucessfully
- * !0 - an error occurred while setting the contents
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorInsert(
- Widget widget,
- DtEditorContentRec *data )
- {
- DtEditorErrorCode error = DtEDITOR_INVALID_TYPE;
- DtEditorWidget editor = (DtEditorWidget) widget;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- switch( data->type )
- {
- case DtEDITOR_TEXT:
- {
- error = insertStringValue ( editor, data->value.string,
- INSERT_DATA, 0, 0 );
- break;
- }
- case DtEDITOR_DATA:
- {
- error = insertDataValue ( editor, data->value.data.buf,
- data->value.data.length, INSERT_DATA, 0,0);
- break;
- }
- case DtEDITOR_WCHAR:
- {
- error = insertWcharValue ( editor, data->value.wchar,
- INSERT_DATA, 0, 0 );
- break;
- }
- default :
- {
- error = DtEDITOR_INVALID_TYPE;
- }
- } /* end switch */
- _DtAppUnlock(app);
- return( error );
- }
- /***************************************************************************
- *
- * DtEditorInsertFromFile - read a data file, inserting the contents
- * into a DtEditor widget.
- *
- * Inputs: widget to insert the file to
- *
- * to indicate the type of contents inserted from the file:
- * string - a \0-terminated string of characters
- * data - untyped data
- *
- * filename - name of the file to read
- *
- * Returns 0 - contents were inserted sucessfully
- * !0 - an error occurred while inserting the contents
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorInsertFromFile(
- Widget widget,
- char *fileName)
- {
- DtEditorErrorCode result;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- result = LoadFile(widget, fileName, INSERT_DATA, 0, 0);
- _DtAppUnlock(app);
- return result;
- }
- /***************************************************************************
- *
- * DtEditorReplace - replace a specified portion of the contents of the
- * DtEditor widget with the supplied data.
- *
- * Inputs: widget to replace a portion of its contents
- *
- * starting character position of the portion to replace
- *
- * ending character position of the portion to replace
- *
- * a data structure containing the data to replace some data
- * in the widget. Depending upon the type of data being set,
- * this structure will contain various fields:
- *
- * string - \0-terminated string of characters
- * data - the data, the size of the data
- *
- *
- * Returns 0 - the portion was replaced sucessfully
- * !0 - an error occurred while replacing the portion
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorReplace(
- Widget widget,
- XmTextPosition startPos,
- XmTextPosition endPos,
- DtEditorContentRec *data)
- {
- DtEditorErrorCode error = DtEDITOR_INVALID_TYPE;
- DtEditorWidget editor = (DtEditorWidget) widget;
- XmTextWidget tw;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- tw = (XmTextWidget) M_text(editor);
- if( startPos < 0 )
- startPos = 0;
- if( startPos > tw->text.last_position )
- startPos = tw->text.last_position;
- if( endPos < 0 )
- endPos = 0;
- if( endPos > tw->text.last_position )
- endPos = tw->text.last_position;
- if( startPos > endPos )
- {
- error = DtEDITOR_INVALID_RANGE;
- }
- else
- {
- switch( data->type )
- {
- case DtEDITOR_TEXT:
- {
- error = insertStringValue ( editor, data->value.string,
- REPLACE_DATA, startPos, endPos );
- break;
- }
- case DtEDITOR_DATA:
- {
- error = insertDataValue ( editor, data->value.data.buf,
- data->value.data.length, REPLACE_DATA,
- startPos, endPos );
- break;
- }
- case DtEDITOR_WCHAR:
- {
- error = insertWcharValue ( editor, data->value.wchar,
- REPLACE_DATA, startPos, endPos );
- break;
- }
- default :
- {
- error = DtEDITOR_INVALID_TYPE;
- }
- } /* end switch */
- }
- _DtAppUnlock(app);
- return( error );
- }
- /***************************************************************************
- *
- * DtEditorReplaceFromFile - read a data file, using the contents to replace
- * a specified portion of the contntes of a
- * DtEditor widget.
- *
- * Inputs: widget to insert the file to
- *
- * starting character position of the portion to replace
- *
- * ending character position of the portion to replace
- *
- * to indicate the type of contents inserted from the file:
- * string - a \0-terminated string of characters
- * data - untyped data
- *
- * filename - local name of the file to read
- *
- * Returns 0 - contents were inserted sucessfully
- * !0 - an error occurred while inserting the contents
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorReplaceFromFile(
- Widget widget,
- XmTextPosition startPos,
- XmTextPosition endPos,
- char *fileName)
- {
- DtEditorWidget editor = (DtEditorWidget) widget;
- XmTextWidget tw;
- DtEditorErrorCode result;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- tw = (XmTextWidget) M_text(editor);
- if( startPos < 0)
- startPos = 0;
- if( startPos > tw->text.last_position )
- startPos = tw->text.last_position;
- if( endPos < 0 )
- endPos = 0;
- if( endPos > tw->text.last_position )
- endPos = tw->text.last_position;
- if(startPos > endPos)
- {
- result = DtEDITOR_INVALID_RANGE;
- }
- else
- {
- result = LoadFile(widget, fileName, REPLACE_DATA, startPos, endPos);
- }
- _DtAppUnlock(app);
- return result;
- }
- /***************************************************************************
- *
- * _DtEditorValidateFileAccess - check to see if file exists, whether we
- * can get to it, and whether it is readable
- * or writable.
- *
- * Note: does not check whether files for reading are read only.
- *
- * Inputs: filename - name of the local file to read
- * flag indicating whether we want to read or write
- * the file.
- *
- * Returns 0 file exists & we have read or write permissions.
- *
- * >0 if file cannot be read from/written to.
- * errno is set to one of the following values:
- *
- * General errors:
- * DtEDITOR_INVALID_FILENAME - 0 length filename
- * DtEDITOR_NONEXISTENT_FILE - file does not exist
- * (Note: this may not be considered an error when saving
- * to a file. The file may just need to be created.)
- * DtEDITOR_NO_FILE_ACCESS - cannot stat existing file
- * DtEDITOR_DIRECTORY - file is a directory
- * DtEDITOR_CHAR_SPECIAL_FILE - file is a device special file
- * DtEDITOR_BLOCK_MODE_FILE - file is a block mode file
- *
- * additional READ_ACCESS errors:
- * DtEDITOR_UNREADABLE_FILE -
- *
- * additional WRITE_ACCESS errors:
- * DtEDITOR_UNWRITABLE_FILE -
- * file or directory is write protected for
- * another reason
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- _DtEditorValidateFileAccess(
- char *fileName,
- int accessType )
- {
- struct stat statbuf; /* Information on a file. */
- DtEditorErrorCode error = DtEDITOR_INVALID_FILENAME;
- /*
- * First, make sure we were given a name
- */
- if (fileName && *fileName )
- {
- /*
- * Does the file already exist?
- */
- if ( access(fileName, F_OK) != 0 )
- error = DtEDITOR_NONEXISTENT_FILE;
- else
- {
- error = DtEDITOR_NO_ERRORS;
- /*
- * The file exists, so lets do some type checking
- */
- if( stat(fileName, &statbuf) != 0 )
- error = DtEDITOR_NO_FILE_ACCESS;
- else
- {
- /* if its a directory - can't save */
- if( (statbuf.st_mode & S_IFMT) == S_IFDIR )
- {
- error = DtEDITOR_DIRECTORY;
- return( error );
- }
- /* if its a character special device - can't save */
- if( (statbuf.st_mode & S_IFMT) == S_IFCHR )
- {
- error = DtEDITOR_CHAR_SPECIAL_FILE;
- return( error );
- }
- /* if its a block mode device - can't save */
- if((statbuf.st_mode & S_IFMT) == S_IFBLK)
- {
- error = DtEDITOR_BLOCK_MODE_FILE;
- return( error );
- }
- /*
- * We now know that it's a regular file so check to whether we
- * can read or write to it, as appropriate.
- */
- switch( accessType )
- {
- case READ_ACCESS:
- {
- if( access(fileName, R_OK) != 0 )
- error = DtEDITOR_UNREADABLE_FILE;
- break;
- }
- case WRITE_ACCESS:
- {
- if( access(fileName, W_OK) == 0 )
- {
- /*
- * Can write to it.
- */
- error = DtEDITOR_WRITABLE_FILE;
- }
- else
- {
- /*
- * Can't write to it.
- */
- error = DtEDITOR_UNWRITABLE_FILE;
- } /* end no write permission */
- break;
- }
- default:
- {
- break;
- }
- } /* end switch */
- } /* end stat suceeded */
- } /* end file exists */
- } /* end filename passed in */
- return( error );
- } /* end _DtEditorValidateFileAccess */
- /************************************************************************
- *
- * LoadFile - Check if file exists, whether we can get to it, etc.
- * If so, type and read its contents.
- *
- * Inputs: widget to set, add, or insert contents of file into
- *
- * name of file to read
- *
- * type of file (NULL). This will be set by LoadFile
- *
- * action to perform with the data (load, append, insert,
- * replace a portion, attach)
- *
- * The following information will be used if the file
- * contents will replace a portion of the widget's contents:
- *
- * starting character position of the portion to replace
- *
- * ending character position of the portion to replace
- *
- * Returns: DtEDITOR_NO_ERRORS - file was read sucessfully
- * DtEDITOR_READ_ONLY_FILE - file was read sucessfully but
- * is read only
- * DtEDITOR_DIRECTORY - the file is a directory
- * DtEDITOR_CHAR_SPECIAL_FILE - the file is a character
- * special device
- * DtEDITOR_BLOCK_MODE_FILE - the file is a block mode device
- * DtEDITOR_NONEXISTENT_FILE - file does not exist
- * DtEDITOR_NULLS_REMOVED - file contained embedded NULLs
- * that were removed
- * DtEDITOR_INSUFFICIENT_MEMORY - unable to allocate
- * enough memory for contents of file
- *
- ************************************************************************/
- static DtEditorErrorCode
- LoadFile(
- Widget w,
- char *fileName,
- LoadActionType action,
- XmTextPosition startReplace,
- XmTextPosition endReplace )
- {
- DtEditorContentRec cr; /* Structure for passing data to widget */
- struct stat statbuf; /* Information on a file. */
- int file_length; /* Length of file. */
- FILE *fp = NULL; /* Pointer to open file */
- DtEditorErrorCode returnVal = DtEDITOR_NONEXISTENT_FILE;
- /* Error accessing file & reading contents */
- DtEditorErrorCode loadError=DtEDITOR_NO_ERRORS;
- /* Error from placing bits into text widget */
- /*
- * First, make sure we were given a name
- */
- if (fileName && *fileName )
- {
- /*
- * Can we read the file?
- */
- returnVal = _DtEditorValidateFileAccess( fileName, READ_ACCESS );
- if( returnVal == DtEDITOR_NO_ERRORS )
- {
- /*
- * Open the file for reading. If we can read/write, then we're
- * cool, otherwise we might need to tell the user that the
- * file's read-only, or that we can't even read from it.
- */
- if( (fp = fopen(fileName, "r+")) == NULL )
- {
- /*
- * We can't update (read/write) the file so try opening read-
- * only
- */
- if( (fp = fopen(fileName, "r")) == NULL )
- {
- /*
- * We can't read from the file.
- */
- return ( DtEDITOR_UNREADABLE_FILE );
- }
- else
- {
- /*
- * Tell the application that the file's read-only.
- * Becareful not to overwrite this value with one of the calls
- * to set the widget's contents.
- */
- returnVal = DtEDITOR_READ_ONLY_FILE;
- }
- } /* end open for read/write */
- } /* end try to read the file */
- } /* end if no filename */
- /* If a file is open, get the bytes */
- if ( fp )
- {
- stat( fileName, &statbuf );
- file_length = statbuf.st_size;
- /*
- * Check to see if we have enough memory to load the file contents
- * into the text widget. This is only an estimate of our needs.
- * Check4EnoughMemory() returns DtEDITOR_NO_ERRORS,
- * DtEDITOR_ILLEGAL_SIZE, or DtEDITOR_INSUFFICIENT_MEMORY.
- */
- loadError = Check4EnoughMemory( file_length );
- if (loadError == DtEDITOR_INSUFFICIENT_MEMORY)
- returnVal = loadError;
- else {
- /*
- * Read the file contents (with room for null) & convert to a
- * string. We want to use a string because the
- * DtEditorSetContents/Append/Insert/... functions create another
- * copy of the data before actually putting it into the widget.
- */
- char *file_string = (char*) XtMalloc(file_length + 1);
- file_length = fread(file_string, sizeof(char), file_length, fp);
- file_string[file_length] = '\0';
- /*
- * Strip out any embedded NULLs because the text widget will only
- * accept data up to the first NULL.
- *
- * StripEmbeddedNulls() returns DtEDITOR_NO_ERRORS or
- * DtEDITOR_NULLS_REMOVED
- */
- loadError = StripEmbeddedNulls( file_string, &file_length );
- if ( loadError != DtEDITOR_NO_ERRORS )
- returnVal = loadError;
- /*
- * Insert it as a string, otherwise the following DtEditor*()
- * functions will make another copy of the data.
- */
- cr.type = DtEDITOR_TEXT;
- cr.value.string = file_string;
- /*
- * Load, insert, append, or attach the file, as specified
- */
- switch( action )
- {
- case LOAD_DATA:
- {
- loadError = DtEditorSetContents ( w, &cr );
- break;
- }
- case INSERT_DATA:
- {
- loadError = DtEditorInsert ( w, &cr );
- break;
- }
- case APPEND_DATA:
- {
- loadError = DtEditorAppend ( w, &cr );
- break;
- }
- case REPLACE_DATA:
- {
- loadError = DtEditorReplace(w, startReplace, endReplace, &cr);
- break;
- }
- default:
- {
- }
- } /* end switch */
-
- if ( loadError != DtEDITOR_NO_ERRORS )
- returnVal = loadError;
- /*
- * The file is loaded, clean up.
- */
- XtFree( file_string );
- } /* end there is enough memory */
-
- /* Close the file */
- fclose(fp);
- } /* end if a file is open */
- return( returnVal );
- } /* end LoadFile */
- static char *
- StringAdd(
- char *destination,
- char *source,
- int number)
- {
- memcpy(destination, source, number);
- destination[number] = (char)'\0';
- destination += number;
- return destination;
- }
- /***************************************************************************
- *
- * CopySubstring - copies out a portion of the text, optionally
- * adding newlines at any and all wordwrap-caused
- * "virtual" lines.
- *
- * Inputs: widget from which we get the data to write;
- * startPos determines the first character to write out;
- * endPos determines the last character to write out;
- * buf is the character buffer into which we write. It
- * is assumed to be large enough - be careful.
- * addNewlines specifies whether to add '/n' to "virtual" lines.
- * Returns Nuthin'
- *
- *
- ***************************************************************************/
- static char *
- CopySubstring(
- XmTextWidget widget,
- XmTextPosition startPos,
- XmTextPosition endPos,
- char *buf,
- Boolean addNewlines)
- {
- XmTextLineTable line_table = widget->text.line_table;
- int currLine, firstLine;
- char *pString, *pCurrChar, *pLastChar;
- int numToCopy;
- if(startPos < 0)
- startPos = 0;
- if(startPos > widget->text.last_position)
- startPos = widget->text.last_position;
- if(endPos < 0)
- endPos = 0;
- if(endPos > widget->text.last_position)
- endPos = widget->text.last_position;
- if(startPos > endPos)
- return buf;
- pString = XmTextGetString((Widget)widget);
- if(addNewlines == False)
- {
- pCurrChar = _DtEditorGetPointer(pString, startPos);
- pLastChar = _DtEditorGetPointer(pString, endPos);
- numToCopy = pLastChar - pCurrChar + mblen(pLastChar, MB_CUR_MAX);
- buf = StringAdd(buf, pCurrChar, numToCopy);
- }
- else
- {
- int *mb_str_loc, total, z, siz;
- char *bptr;
- mb_str_loc = (int *) XtMalloc(sizeof(int) * ((endPos-startPos)+1));
- if (NULL == mb_str_loc)
- {
- /* Should figure out some way to pass back an error code. */
- buf = CopySubstring(widget, startPos, endPos, buf, False);
- return buf;
- }
- /*
- * mb_str_loc[] is being used to replace the call
- * to _DtEditorGetPointer. That function used
- * mbtowc() to count the number of chars between the
- * beginning of pString and startChar. The problem
- * was that it sat in a loop and was also called for
- * every line, so it was SLOW. Now, we count once
- * and store the results in mb_str_loc[].
- */
- /* Because startPos may not always == 0: */
- /* mb_str_loc[0] = startPos */
- /* mb_str_loc[endPos - startPos] = endPos */
- /* */
- /* So when accessing items, dereference off of */
- /* startPos. */
- mb_str_loc[0] = 0;
- for(total=0, bptr=pString, z=1;
- z <= (endPos - startPos); bptr += siz, z++)
- {
- if (MB_CUR_MAX > 1)
- {
- if ( (siz = mblen(bptr, MB_CUR_MAX)) < 0)
- {
- siz = 1;
- total += 1;
- }
- else
- total += siz;
- }
- else
- {
- siz = 1;
- total += 1;
- }
- mb_str_loc[z] = total;
- }
- firstLine = currLine = _DtEditorGetLineIndex(widget, startPos);
- do
- {
- if(startPos > (XmTextPosition)line_table[currLine].start_pos)
- pCurrChar = pString + mb_str_loc[0];
- else
- {
- z = line_table[currLine].start_pos;
- pCurrChar = pString +
- mb_str_loc[z - startPos];
- }
- if(addNewlines == True && currLine > firstLine &&
- line_table[currLine].virt_line != 0)
- {
- buf[0] = (char)'\n';
- buf[1] = (char)'\0';
- buf++;
- }
- if(currLine >= (widget->text.total_lines - 1))
- pLastChar = pString +
- mb_str_loc[endPos - startPos];
- else if((XmTextPosition)line_table[currLine + 1].start_pos <= endPos)
- {
- z = line_table[currLine+1].start_pos - 1;
- pLastChar = pString +
- mb_str_loc[z - startPos];
- }
- else
- pLastChar = pString +
- mb_str_loc[endPos - startPos];
- numToCopy = pLastChar - pCurrChar + mblen(pLastChar, MB_CUR_MAX);
- buf = StringAdd(buf, pCurrChar, numToCopy);
- currLine++;
- } while(currLine < widget->text.total_lines &&
- (XmTextPosition)line_table[currLine].start_pos <= endPos);
- XtFree((char*)mb_str_loc);
- }
- XtFree(pString);
- return buf;
- }
- /*************************************************************************
- *
- * _DtEditorCopyDataOut - Writes the entire text editor buffer contents to
- * the specified character array.
- *
- * Inputs: tw, to supply the data.
- * buf, specifying the array to which to write the data.
- *
- *************************************************************************/
- static char *
- _DtEditorCopyDataOut(
- XmTextWidget tw,
- char *buf,
- Boolean addNewlines)
- {
- buf = CopySubstring(tw, 0, tw->text.last_position, buf, addNewlines);
- return buf;
- }
- static DtEditorErrorCode
- getStringValue(
- DtEditorWidget editor,
- char **buf,
- Boolean insertNewlines)
- {
- XmTextWidget tw = (XmTextWidget) M_text(editor);
- int bufSize;
- char *lastChar;
- DtEditorErrorCode returnVal = DtEDITOR_NO_ERRORS;
- /*
- * Calculate the size of the buffer we need for the data.
- * 1. Start with MB_CUR_MAX for each char in the text.
- * 3. Add in 1 char for each line, if we have to insert newlines.
- * 4. Add 1 for a terminating NULL.
- */
- bufSize = tw->text.last_position * MB_CUR_MAX;
- if(insertNewlines == True)
- bufSize += tw->text.total_lines;
- bufSize += 1;
- returnVal = Check4EnoughMemory(bufSize);
- if (DtEDITOR_NO_ERRORS != returnVal) return returnVal;
- *buf = (char *) XtMalloc(bufSize);
- lastChar = _DtEditorCopyDataOut(tw, *buf, insertNewlines);
- return returnVal;
- } /* end getStringValue */
- static DtEditorErrorCode
- getDataValue(
- DtEditorWidget editor,
- void **buf,
- unsigned int *size,
- Boolean insertNewlines)
- {
- DtEditorErrorCode error;
- error = getStringValue(editor, (char **)buf, insertNewlines);
- *size = strlen( *buf ); /* remember, strlen doesn't count \0 at end */
- return( error );
- } /* end getDataValue */
- static DtEditorErrorCode
- getWcharValue(
- DtEditorWidget editor,
- wchar_t **data,
- Boolean insertNewlines)
- {
- DtEditorErrorCode error;
- char *mb_value;
- wchar_t *pWchar_value;
- int num_char, result;
- size_t nbytes;
- error = getStringValue(editor, &mb_value, insertNewlines);
- if (error == DtEDITOR_NO_ERRORS)
- {
- /*
- * Allocate space for the wide character string
- */
- num_char = _DtEditor_CountCharacters(mb_value, strlen(mb_value)) + 1;
- nbytes = (size_t) num_char * sizeof(wchar_t);
- error = Check4EnoughMemory(nbytes);
- if (DtEDITOR_NO_ERRORS != error) return error;
- pWchar_value = (wchar_t*) XtMalloc(nbytes);
- /*
- * Convert the multi-byte string to wide character
- */
- result = mbstowcs(pWchar_value, mb_value, num_char*sizeof(wchar_t) );
- if (result < 0) pWchar_value[0] = 0L;
- *data = pWchar_value;
- XtFree( mb_value );
- }
- return( error );
- } /* end getWcharValue */
- /***************************************************************************
- *
- * DtEditorGetContents - gets the contents of the DtEditor widget.
- *
- * Inputs: widget to retrieve the contents
- *
- * pointer to a data structure indicating how the retrieved
- * data should be formatted. Depending upon the type of format,
- * this structure will contain various fields:
- * string - a NULL pointer (char *) to hold the data
- * a new container will be created.
- * data - void pointer to hold the data, unsigned int for the
- * size of the data,
- * a Boolean indicating whether Newline characters should be
- * inserted at the end of each line, in string format.
- * a Boolean indicating whether the the unsaved changes
- * flag should be cleared. There may be times when an
- * application will want to request a copy of the contents
- * without effecting whether DtEditorCheckForUnsavedChanges
- * reports there are unsaved changes.
- *
- * Returns 0 - contents were retrieved sucessfully
- * !0 - an error occurred while retrieving the contents
- *
- * The structure passed in will be set according to the
- * requested format:
- * string - a \0-terminated string of characters with
- * optional Newlines
- * container - handle to a Bento container
- * data - the data, the size of the data
- *
- * The application is responsible for free'ing any data in the
- * above structure.
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorGetContents(
- Widget widget,
- DtEditorContentRec *data,
- Boolean hardCarriageReturns,
- Boolean markContentsAsSaved )
- {
- DtEditorErrorCode error = DtEDITOR_INVALID_TYPE;
- DtEditorWidget editor = (DtEditorWidget) widget;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- switch( data->type )
- {
- case DtEDITOR_TEXT:
- {
- error = getStringValue( editor, &(data->value.string),
- hardCarriageReturns );
- break;
- }
- case DtEDITOR_DATA:
- {
- error = getDataValue( editor, &(data->value.data.buf),
- &(data->value.data.length),
- hardCarriageReturns );
- break;
- }
- case DtEDITOR_WCHAR:
- {
- error = getWcharValue( editor, &(data->value.wchar),
- hardCarriageReturns );
- break;
- }
- default :
- {
- error = DtEDITOR_INVALID_TYPE;
- }
- } /* end switch */
- /*
- * If there were no errors, mark there are now no unsaved changes (unless
- * we were told not to).
- */
- if ( error == DtEDITOR_NO_ERRORS && markContentsAsSaved == True )
- M_unreadChanges( editor ) = False;
- _DtAppUnlock(app);
- return( error );
- }
- /***************************************************************************
- *
- * DtEditorSaveContentsToFile - saves the contents of the DtEditor
- * widget to a disc file as string/data
- * or a CDE Document (Bento container).
- *
- * Inputs: widget to retrieve the contents
- *
- * filename - name of the file to read
- * a Boolean indicating whether the file should be
- * overwritten if it currently exists.
- * a Boolean indicating whether Newline characters should be
- * inserted at the end of each line (string format only).
- * a Boolean indicating whether the the unsaved changes
- * flag should be cleared. There may be times when an
- * application will want to request a copy of the contents
- * without effecting whether DtEditorCheckForUnsavedChanges
- * reports there are unsaved changes.
- *
- * Returns DtEDITOR_NO_ERRORS - contents were saved sucessfully
- * DtEDITOR_UNWRITABLE_FILE - file is write protected
- * DtEDITOR_WRITABLE_FILE - file exists and the
- * overwriteIfExists parameter is False.
- * DtEDITOR_SAVE_FAILED - write to the file failed; check
- * disk space, etc.
- * OR any errors from DtEditorGetContents
- *
- ***************************************************************************/
- extern DtEditorErrorCode
- DtEditorSaveContentsToFile(
- Widget widget,
- char *fileName,
- Boolean overwriteIfExists,
- Boolean hardCarriageReturns,
- Boolean markContentsAsSaved )
- {
- FILE *pFile;
- DtEditorContentRec cr; /* Structure for retrieving contents of widget */
- DtEditorWidget editor = (DtEditorWidget) widget;
- DtEditorErrorCode error = DtEDITOR_INVALID_FILENAME;
- _DtWidgetToAppContext(widget);
- _DtAppLock(app);
- /*
- * First, make sure we were given a name
- */
- if (fileName && *fileName )
- {
-
- /*
- * Can we save to the file?
- */
- error = _DtEditorValidateFileAccess( fileName, WRITE_ACCESS );
- if( error == DtEDITOR_NO_ERRORS ||
- error == DtEDITOR_NONEXISTENT_FILE ||
- error == DtEDITOR_WRITABLE_FILE )
- {
- /*
- * Don't overwrite an existing file if we've been told not to
- */
- if( error == DtEDITOR_WRITABLE_FILE && overwriteIfExists == False )
- {
- _DtAppUnlock(app);
- return( error );
- }
- /*
- * Open the file for writing
- */
- if ( (pFile = fopen(fileName, "w")) == NULL )
- {
- _DtAppUnlock(app);
- return( DtEDITOR_UNWRITABLE_FILE );
- }
- else
- {
- /*
- * Save the unsaved changes flag so we can restore it if the write
- * to the file fails.
- */
- Boolean saved_state = M_unreadChanges( editor );
- /*
- * Now, get the contents of the widget and write it to the file,
- * depending upon the format requested.
- */
- cr.type = DtEDITOR_DATA;
- error = DtEditorGetContents( widget, &cr, hardCarriageReturns,
- markContentsAsSaved );
- if ( error == DtEDITOR_NO_ERRORS )
- {
- /*
- * Write it to the file
- */
- size_t size_written = fwrite( cr.value.data.buf, 1,
- cr.value.data.length, pFile );
- if( cr.value.data.length != size_written )
- error = DtEDITOR_SAVE_FAILED;
- XtFree( cr.value.data.buf );
- }
- fclose(pFile);
- if( error == DtEDITOR_SAVE_FAILED )
- {
- /*
- * Restore the unsaved changes flag since the save failed
- */
- M_unreadChanges( editor ) = saved_state;
- }
- } /* end file is writable */
- } /* end filename is valid */
- }
- _DtAppUnlock(app);
- return( error );
- } /* end DtEditorSaveContentsToFile */
- /*
- * _DtEditorGetPointer returns a pointer to the _character_
- * numbered by startChar within the string pString.
- * It accounts for possible multibyte chars.
- */
- char *
- _DtEditorGetPointer(
- char *pString,
- int startChar)
- {
- char *bptr;
- int curChar, char_size;
- if(MB_CUR_MAX > 1)
- {
- for(bptr = pString, curChar = 0;
- curChar < startChar && *bptr != (char)'\0';
- curChar++, bptr += char_size)
- {
- if ( (char_size = mblen(bptr, MB_CUR_MAX)) < 0)
- char_size = 1;
- }
- }
- else
- {
- bptr = pString + startChar;
- }
- return bptr;
- } /* end _DtEditorGetPointer */
|