diff --git a/harbour/ChangeLog b/harbour/ChangeLog index aae707f3a2..2154450874 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,9 @@ +19991012-10:38 GMT+2 Ryszard Glab + + *samples/pe + * new directory with a sample editor that can be used as a base for + MEMOEDIT and TEditor class + 19991012-00:52 EDT Paul Tucker * makefile.vc + source/rtl/input.prg diff --git a/harbour/samples/pe/Makefile b/harbour/samples/pe/Makefile new file mode 100644 index 0000000000..ba9282a736 --- /dev/null +++ b/harbour/samples/pe/Makefile @@ -0,0 +1,25 @@ +# +# $Id$ +# + +ROOT = ../../ + +PRG_SOURCES=\ + editorhi.prg \ + +C_SOURCES=\ + editorlo.c \ + +PRG_MAIN=pe.prg + +LIBS=\ + runner \ + tools \ + debug \ + rdd \ + vm \ + rdd \ + rtl \ + pp \ + +include $(TOP)$(ROOT)config/bin.cf diff --git a/harbour/samples/pe/editorhi.prg b/harbour/samples/pe/editorhi.prg new file mode 100644 index 0000000000..d2efae9af8 --- /dev/null +++ b/harbour/samples/pe/editorhi.prg @@ -0,0 +1,691 @@ +/* + * $Id$ +*/ +//#include "expand.ch" +//#include "windows.ch" +//#include "print.ch" +//#include "helpsys.ch" + +#include +#include +#include +#include + + +#define EXPORT +#define IFANY( x ) IF( (x) != NIL ) +#define IFNIL( x ) IF( (x) == NIL ) +#define IIFNIL( isnil, notnil ) IIF(notnil==NIL, isnil, notnil) + +#define EDIT_LOWER 0 // convert to lowercase +#define EDIT_UPPER 1 // convert to uppercase +#define EDIT_SAME 2 // no convertion + +#define EDIT_HARD 13 // hard cariage +#define EDIT_SOFT 141 // soft cariage + +#define EDIT_EDIT .T. // full edit mode +#define EDIT_VIEW .F. // view only mode + +// The editor structure +// +#define E_EDIT 1 // index returned be ED_NEW +#define E_TOP 2 // position on the screen +#define E_LEFT 3 +#define E_BOTTOM 4 +#define E_RIGHT 5 +#define E_TITLE 6 // title +#define E_COLOR 7 // used colors set +#define E_FRAME 8 // frame around the editor +#define E_LINELEN 9 // maximal line length +#define E_MODE 10 // editor mode (edit/view) +#define E_CARGO 11 // cargo slot +#define E_STRUCT_LEN 11 + + +STATIC nESize:=4096 // default buffer size +STATIC oEditor // static variable used to speed access to the editor +STATIC aEdit:={ } // the stack of used editors +STATIC lInsert //current Insert state + +// +** +// + +//--------------------------------------------------------- +//03-06-93 07:52pm +// +// nTop, nLeft, nBottom, nRight - position on the screen +// nLength - the line length +// cFrame - the frame to be drawed around the editor +// cTitle - comment displayed in upper, left corner +// cColor - colors used to draw the editor +// nSize - the size of memory buffer that holds the edited text - the buffer +// will not grow at current design +// nEscape - the character code used as a marker of color highlighing +// For example if its value is 126 '~' then the following text: +// normal text ~2text in bold~1 back to normal text +// will be displayed with 'text in bold' highlighted using the second +// color specified by 'cColor' parameter +// +EXPORT FUNCTION EditorNew( nTop, nLeft, nBottom, nRight, nLength, ; + cFrame, cTitle, cColor, nSize, nEscape ) +LOCAL nEdit, oEdit + + IF( nLength == NIL ) + nLength =80 + ENDIF + nEdit =ED_New( nLength, 4, IIFNIL(nESize, nSize), nEscape ) + IF( nEdit >= 0 ) + oEdit :=ARRAY( E_STRUCT_LEN ) + oEdit[E_EDIT] =nEdit + + oEdit[E_TOP] =nTop + oEdit[E_LEFT] =nLeft + oEdit[E_BOTTOM] =nBottom + oEdit[E_RIGHT] =nRight + oEdit[E_LINELEN] =nLength + oEdit[E_FRAME] =IIFNIL( B_DOUBLE, cFrame ) + oEdit[E_TITLE] =cTitle + oEdit[E_COLOR] =IIFNIL( "W/N,W+/N,W+/R,GR+/N,G+/N", cColor ) + oEdit[E_MODE] =EDIT_VIEW + + ED_Config( nEdit, nTop, nLeft, nBottom, nRight, 0, 0 ) + ENDIF + +RETURN( oEdit ) + +//--------------------------------------------------------- +//03-06-93 09:16pm +// +EXPORT PROCEDURE EditorKill( oEdit ) + + ED_Kill( oEdit[E_EDIT] ) + MEMORY( -1 ) + +RETURN + +//--------------------------------------------------------- +//96-02-29 22:22 +// +EXPORT PROCEDURE EditorUnlock( oEdit ) + + ED_Unlock( oEdit[E_EDIT] ) + +RETURN + +//--------------------------------------------------------- +//03-06-93 10:20pm +// +EXPORT FUNCTION EditorCargo( oEdit, xCargo ) +LOCAL _xCargo:=oEdit[E_CARGO] + + IFANY( xCargo ) + oEdit[E_CARGO] =xCargo + ENDIF + +RETURN( _xCargo ) + +//--------------------------------------------------------- +//19-07-93 01:08am +// +EXPORT FUNCTION EditorTitle( oEdit, cTitle ) +LOCAL _cTitle:=oEdit[E_TITLE] + + IFANY( cTitle ) + oEdit[E_TITLE] =cTitle + ENDIF + +RETURN( _cTitle ) + +//--------------------------------------------------------- +//04-06-93 02:18am +// +// Sets +// EDIT_EDIT - full edit mode +// EDIT_VIEW - view only mode (no changes in text are allowed) +// +EXPORT FUNCTION EditorMode( oEdit, lMode ) +LOCAL _lMode:=oEdit[E_MODE] + + IFANY( lMode ) + oEdit[E_MODE] =lMode + ENDIF + +RETURN( _lMode ) + +//--------------------------------------------------------- +//28-05-92 09:31am +// +EXPORT FUNCTION EditorSize( nSize ) +LOCAL _nSize:=nESize + + IF nSize != NIL + nESize =nSize + ENDIF + +RETURN( _nSize ) + +//--------------------------------------------------------- +//28-02-92 10:57pm +// +// Appends passed text to the text already stored in editor +// +EXPORT PROCEDURE EditorAddText( oEdit, cText ) + + ED_AddText( oEdit[E_EDIT], cText ) + +RETURN + +//--------------------------------------------------------- +//05-03-92 10:21pm +// +// Sets new text in editor +// +EXPORT PROCEDURE EditorSetText( oEdit, cText ) + + ED_SetText( oEdit[E_EDIT], cText ) + +RETURN + +//--------------------------------------------------------- +//05-03-92 10:23pm +// +// Inserts passed text into editor starting from passed line number +// +EXPORT PROCEDURE EditorInsText( oEdit, cText, nLine ) +LOCAL nNum:=IIFNIL( ED_LCount(oEdit[E_EDIT]), nLine ) + + ED_InsText( oEdit[E_EDIT], cText, nNum ) + +RETURN + +//--------------------------------------------------------- +//02-03-92 07:53pm +// +// Retrieves the text from editor +// nUpper - specifies if text should be changed to uppercase, lowercase +// or unchanged +// nCarret - specifies if soft carriage return (141/10) should be replaced by +// hard carriage returns (13/10) +// +EXPORT FUNCTION EditorGetText( oEdit, nUpper, nCarret ) + + IFNIL( nUpper ) + nUpper =EDIT_SAME + ENDIF + IFNIL( nCarret ) + nCarret =EDIT_HARD + ENDIF + +RETURN( ED_GetText( oEdit[E_EDIT], nUpper, nCarret ) ) + +//--------------------------------------------------------- +//04-03-92 02:35pm +// +// Returns the line count stored in editor +// +EXPORT FUNCTION EditorLCount( oEdit ) + +RETURN( ED_LCount( oEdit[E_EDIT] ) ) + +//--------------------------------------------------------- +//06-03-92 07:09pm +// +// Returns the specified line of text from the editor +// +EXPORT FUNCTION EditorGetLine( oEdit, nLine ) + +RETURN( ED_GetLine( oEdit[E_EDIT], nLine ) ) + +//--------------------------------------------------------- +//06-03-92 07:10pm +// +// Returns the next line of text +// +// It can be used: +// nLCount :=EditorLCount( oEdit ) +// cLine :=EditorGetLine( oEdit, 1 ) +// FOR i:=2 TO nLCount +// cLine :=EditorNextLine( oEdit ) +// NEXT +// +EXPORT FUNCTION EditorNextLine( oEdit ) + +RETURN( ED_GetNext(oEdit[E_EDIT]) ) + +//--------------------------------------------------------- +//03-06-93 10:11pm +// +// Edit the specified file +// +// xInput - the filename to edit or a handle to a file retrned by FOPEN +// cOutput - the name of the file created in 'save' operation +// nLineLen - the line length +// nHelp - the index into help subsystem +// lPrint - specifies if edited file can be printed +// lConv - it was used to convert some unprintable characters +// nEscape - the code of color escape character +// lSave - specifies if edited file can be saved under a different name +// +EXPORT FUNCTION EditorFile( xInput, cOutput, nLineLen, nHelp, ; + lPrint, lConv, nEscape, lSave ) +LOCAL nHandle, nLen, oEdit, bF2, bF8, oHelp, lSaved:=.F., lClose:=.F. +LOCAL nSize + + IF( lSave == NIL ) + lSave =.T. + ENDIF + IF( VALTYPE(xInput) == 'C' ) + nHandle =FOPEN( xInput ) + lClose =.T. + ELSE + nHandle =xInput + ENDIF + + IF( nHandle > 0 ) + nLen =MAX( FileLength( nHandle ), nESize ) + ELSE + nLen =nESize + ENDIF + + nSize =IIF( nLen < 8192, nLen*2, INT(nLen*1.5) ) + oEdit =EditorNew( 01,00,23,79, nLineLen, '--- ', cOutput, , ; + nSize, nEscape ) + + IF( nHandle > 0 ) + ED_ReadText( oEdit[E_EDIT], nHandle, 0, nLen, ; + IIF( lConv==NIL, .F., lConv ) ) + IF( lClose ) + FCLOSE( nHandle ) + ENDIF + ELSE + EditorSetText( oEdit, ' ' ) + ENDIF + + EditorCargo( oEdit, cOutput ) + +// SAVELINE 24 TO oHelp WITH 80, ColorHelp( ,COLOR_EXTEND ) +// IF( lSave ) +// DisplayHelp( 73 ) //F2-save +// bF2 =SETKEY( K_F2, {|oE| lSaved:=EditorSave(oE)} ) +// ENDIF +// IF( lPrint != NIL .AND. lPrint ) +// DisplayHelp( 74 ) //F8-print +// bF8 =SETKEY( K_F8, {|oE| EditorPrint(oE)} ) +// ENDIF + + lSaved :=EditorEdit( oEdit, EDIT_EDIT, .F., nHelp ) + EditorKill( oEdit ) + + IF( lSave ) + SETKEY( K_F2, bF2 ) + ENDIF + +// IF( lPrint != NIL .AND. lPrint ) +// SETKEY( K_F8, bF8 ) +// ENDIF +// RESTLINE FROM oHelp + +// FT_IDLE() + MEMORY(-1) + +RETURN( lSaved ) + +//--------------------------------------------------------- +//06-07-93 06:05pm +// +// Reads a text from a file into the editor +// +// oEditor - existing editor +// nHandle - handle to an open file to read from +// nOffset - the starting offset +// nLen - the number of characters to read +// lConv - specifies if some unprintable characters should be converted +// (NOTE: it was used to allow display charcters with ASCII code 27 and 26) +// +EXPORT FUNCTION EditorRead( oEditor, nHandle, nOffset, nLen, lConv ) + +RETURN( ED_ReadText( oEditor[E_EDIT], nHandle, nOffset, nLen, ; + IIF( lConv==NIL, .T., lConv ) ) ) + +//--------------------------------------------------------- +//03-06-93 08:31pm +// +// Start the editor +// +// oEdit - the editor object +// lEdit - .T. = edit allowed, .F. = view only mode +// lFrame - specifies if the frame around the editor should be displayed +// nHelp - the help index into help subsystem +// +EXPORT FUNCTION EditorEdit( oEdit, lEdit, lFrame, nHelp ) +LOCAL nRow:=0, nCol:=0, nKey, cLine, bKey, oBox, nCursor, nState +LOCAL nTop, nLeft, nBottom, nRight +LOCAL lSaveAllowed, lSaved:=.F. +//HELPSAVE( IIF(nHelp==NIL, H_EDITOR, nHelp ) ) + + oBox =SAVEBOX( oEdit[E_TOP], oEdit[E_LEFT], ; + oEdit[E_BOTTOM], oEdit[E_RIGHT], ; + oEdit[E_COLOR], oEdit[E_FRAME], oEdit[E_TITLE], .F. ) + + lInsert =SET( _SET_INSERT ) +// SayInsert() + nCursor =SetCursor( IIF(lInsert, SC_NORMAL, SC_SPECIAL1) ) + IFANY( lEdit ) + oEdit[E_MODE] =lEdit + ENDIF + lSaveAllowed :=( SETKEY(K_F2) == NIL ) +// IF( lSaveAllowed ) +// DisplayHelp( 73 ) //F2-save +// ENDIF + + nTop =oEdit[E_TOP] +1 + nLeft =oEdit[E_LEFT] +1 + nBottom =oEdit[E_BOTTOM] -1 + nRight =oEdit[E_RIGHT] -1 + IF( lFrame != NIL .AND. !lFrame ) + nLeft-- + nBottom++ + nRight++ + ENDIF + nState =oEdit[E_RIGHT] -8 + + /* It uses static variable 'oEditor' to speed access to the editor + If this function is called recursively then we have to push + currently used editor on the stack + */ + EditorPush( oEdit ) + + /* The position of the editor can be changed (in a windowed environment) + then it sets current position of editor. + It also sets the current editor as the working one. This means that + all next ED_* functions will used the editor handle specified + by oEditor[E_EDIT] - it is tricky solution to speed access (we + don't need to pass the editor handle with every ED_*() call + (Well... this editor was created when AT-286 computers worked in + its full glory :) + */ + ED_Config( oEditor[E_EDIT], nTop, nLeft, nBottom, nRight, 0, 0 ) + + DO WHILE .T. + nRow =ED_Stabilize() //displays all visible lines + // It don't uses incremantal stabilization for performance reasons + + IF( nRow != ED_Row() ) + nRow =ED_Row() + @ oEditor[E_TOP], nState SAY STRZERO( nRow,4 ) + ENDIF + IF( nCol != ED_Col() ) + nCol =ED_Col() + @ oEditor[E_TOP], nState+5 SAY STRZERO( nCol,3 ) + ENDIF + SETPOS( nTop+ED_WinRow(), nLeft+ED_WinCol() ) + +// nKey =WaitForKey() + nKey =INKEY(0) + + DO CASE + CASE( nKey>=32 .AND. nKey<256 ) + IF( oEdit[E_MODE] ) + ED_PutChar( nKey, lInsert ) + ENDIF + + CASE( nKey == K_F2 .AND. lSaveAllowed ) + lSaved :=EditorSave( oEditor ) //save the copy of edited buffer + + CASE( EditorMove( nKey ) ) + + CASE( nKey == K_DOWN ) + IF !ED_Down() + SCROLL( nTop, nLeft, nBottom, nRight, 1 ) + ENDIF + + CASE( nKey == K_UP ) + IF !ED_Up() + SCROLL( nTop, nLeft, nBottom, nRight, -1 ) + ENDIF + + CASE( nKey == K_ESC ) + EXIT + + OTHERWISE + bKey =SETKEY( nKey ) + IFNIL( bKey ) + IF( oEdit[E_MODE] ) + EditorKeys( nKey ) + ENDIF + ELSE + EVAL( bKey, oEditor ) + ENDIF + ENDCASE + ENDDO + + EditorPop() //restore the proviously used editor + + SetCursor( nCursor ) + RESTBOX( oBox ) +// HELPREST. + +// FT_IDLE() + MEMORY(-1) + +RETURN( lSaved ) + + +// +** +// + +//--------------------------------------------------------- +//03-06-93 08:35pm +// +STATIC PROCEDURE EditorKeys( nKey ) +LOCAL i + + DO CASE + CASE( nKey == K_CTRL_Y ) + ED_DelLine() + + CASE( nKey == K_CTRL_T ) + ED_DelWord() + + CASE( nKey == K_DEL ) + ED_DelChar() + + CASE( nKey == K_BS ) + ED_BSpace( lInsert ) + + CASE( nKey == K_RETURN ) + ED_Return( lInsert ) + + CASE( nKey == K_TAB ) +// ED_Tab( lInsert ) + FOR i=1 TO 4 + ED_PutChar( 32, lInsert ) + NEXT + + CASE( nKey == K_INS ) + lInsert = !lInsert + SET( _SET_INSERT, lInsert ) + SetCursor( IIF(lInsert, SC_NORMAL, SC_SPECIAL1) ) +// SayInsert() + + ENDCASE + +RETURN + +//--------------------------------------------------------- +//04-06-93 02:06am +// +STATIC FUNCTION EditorMove( nKey ) +LOCAL lMoved:=.T. + + DO CASE + CASE( nKey == K_PGDN ) + ED_PgDown() + + CASE( nKey == K_PGUP ) + ED_PgUp() + + CASE( nKey == K_CTRL_PGUP ) + ED_Top() + + CASE( nKey == K_CTRL_PGDN ) + ED_Bottom() + + CASE( nKey == K_RIGHT ) + ED_Right() + + CASE( nKey == K_LEFT ) + ED_Left() + + CASE( nKey == K_HOME ) + ED_Home() + + CASE( nKey == K_CTRL_HOME ) + ED_Home() + + CASE( nKey == K_END ) + ED_End() + + CASE( nKey == K_CTRL_END ) + ED_End() + + CASE( nKey == K_CTRL_RIGHT ) +// ED_NWord() //there are some problems with it + + CASE( nKey == K_CTRL_LEFT ) + ED_PWord() + + OTHERWISE + lMoved =.F. + + ENDCASE + +RETURN( lMoved ) + + +//--------------------------------------------------------- +//03-06-93 09:11pm +// +STATIC PROCEDURE EditorPush( oEdit ) + + ED_Push() + AADD( aEdit, oEditor ) + oEditor =oEdit + +RETURN + +//--------------------------------------------------------- +//03-06-93 09:12pm +// +STATIC PROCEDURE EditorPop( ) +LOCAL nLen + + nLen =LEN( aEdit ) + oEditor =aEdit[ nLen ] + ASIZE( aEdit, nLen-1 ) + ED_Pop() + +RETURN + +//--------------------------------------------------------- +//03-06-93 10:23pm +// +STATIC FUNCTION EditorSave( oEdit ) +LOCAL nHandle, cFile, cNew + + cFile =EditorCargo(oEdit) + IF( EMPTY(cFile) ) + cFile ='TESTFILE.TXT' //GetFileName( 10, 10 ) + ENDIF + + IF( EMPTY(cFile) ) + RETURN( .F. ) + ENDIF +/* + WorkStart( 75 ) + IF( FILE(cFile) ) + cNew =FileExtension( cFile, 'BAK' ) + DELETEFILE( cNew ) + nHandle =RENAMEFILE( cFile, cNew ) + IF( nHandle < 0 ) + FileError( cFile, -nHandle ) + WorkEnd() + + RETURN( .F. ) + ENDIF + ENDIF +*/ + nHandle =FCREATE( cFile, FC_NORMAL ) + IF( nHandle > 0 ) + FWRITE( nHandle, EditorGetText(oEdit) ) + + FCLOSE( nHandle ) +// ELSE +// FileError( cFile, FERROR() ) + ENDIF +// WorkEnd() + +RETURN( nHandle > 0 ) + +//--------------------------------------------------------- +//19-08-93 02:05am +// +/* +STATIC PROCEDURE EditorPrint( oEdit ) +LOCAL oParm + + IF PrintReady() + PrintNewQue() + PrintSetHead( AppsOwner(), , '-', PRN_OFF ) + + PrintAddJob( oEdit, PRN_EDITOR ) + PrintJob(PRN_OFF) + PrintDelQue() + ENDIF + +RETURN +*/ + +//--------------------------------------------------------- +*09/29/91 08:40pm +* +EXPORT FUNCTION SaveBox( top,left,bott,right, kolor, patt, head, shadow ) +LOCAL cBox, cClr, nBottom,nRight + + IF( PCOUNT() > 4 ) + cClr =SETCOLOR(kolor) + cBox =SAVESCREEN(top,left,bott,right) +// cBox =BoxShadow(top,left,bott,right, , patt, head, shadow) + @ top, left, bott, right BOX patt +// nBottom =bott+1 +// nRight =right+1 + ELSE + cClr =SETCOLOR() + cBox =SAVESCREEN(top,left,bott,right) + nBottom =bott + nRight =right + ENDIF + +RETURN( {top,left,nBottom,nRight, cBox, cClr} ) + + +//--------------------------------------------------------- +*09/29/91 08:42pm +* +EXPORT PROCEDURE RestBox( oBox ) + + RESTSCREEN( oBox[1], oBox[2], oBox[3], oBox[4], oBox[5] ) + SETCOLOR( oBox[6] ) + +RETURN + +STATIC FUNCTION FileLength( nH ) +LOCAL nPos:=FSEEK( nH, 0, FS_RELATIVE ) +LOCAL nLen:=FSEEK( nH, 0, FS_END ) + + FSEEK( nH, nPos, FS_SET ) + +RETURN( nLen ) diff --git a/harbour/samples/pe/editorlo.c b/harbour/samples/pe/editorlo.c new file mode 100644 index 0000000000..f773c341a2 --- /dev/null +++ b/harbour/samples/pe/editorlo.c @@ -0,0 +1,3259 @@ +/* + * $Id$ +*/ +#include +#include +#include +#include +#include +#include +#include + +/* If mc51 is defined then the code created will used Extend and GT API + If mc51 is not defined then the standalone editor will be created + */ +#define mc51 + +#ifdef mc51 + #include + #include + #include + #include + #include +#else + #include "rvideo.h" + #include + + #define CLIPPER void pascal + #define FALSE 0 + #define TRUE 1 +#endif + +#define CLIPPER_ACTION(action) void pascal action( void ) + + +#define Eof '\x0' +#define SOFT 141 +#define HARD '\r' +#define END '' + +#define LOWER 0 +#define UPPER 1 +#define SPOKO 2 + +#define UP 1 +#define DOWN 0 +#define YES 1 +#define NO 0 + +#define REWRITE 1 +#define NO_WRITE 0 + +#define MAX_LINE_LEN 254 + +#ifndef mc51 + + int xk,yk; + int xmax,ymax; + int il_kol; + int i, insert; + int array; + + char ramka[9] = "ķԳ"; + char *str; + char name[30]; + int adres; + char *adr; + +#endif + + + +typedef struct +{ + int top; /* topmost row of editor's window */ + int left; /* leftmost column of the editor's window */ + int bottom; /* bottom row position */ + int right; /* rightmost column */ + int line_length; /* maximal line length */ + long int line_number; /* the number of lines stored in text buffer */ + long int current_line; /* the offset in memory buffer where the current line starts (where the cursor is positioned) */ + long int first_line; /* offset of the first line (usually 0) */ + long int last_line; /* the offset in memory buffer of the last line */ + int cursor_row; /* current cursor row in the window */ + int cursor_col; /* current cursor column in the window */ + long int first_display; /* the offset of first visible (displayed) line */ + long int last_display; /* the offset of last visible line */ + int first_col; /* first visible column */ + int stable; /* is the editor stabilized? */ + int current_stabil; /* currently displayed row (during stabilisation) */ + int stabil; /* number of rows to stabilize */ + int space; /* should spaces at the end of line be removed */ + char escape; /* ASCII code of color escaspe character (the next character after this will be used as color index */ + long int next_stabil; /* the offset in memory buffer of next line to display */ + int dir; /* the direction of line stabilization */ + int tab_size; /* the number of spaces the replaces TAB character */ + long int active; /* the line number where the cursor is positioned */ + int IsConfigured; + long int next_line; /* the offset of next line to return by ED_GetNextLine() */ + long int text_length; /* the size (in bytes) of edited text */ + long int bufor_size; /* the size of allocated memory buffer */ + char *begin; /* the memory buffer */ + +} EDITOR ; + + + + +static EDITOR *EStack[] ={ NULL, NULL, NULL, NULL, NULL }; +/* table of created editors */ +static EDITOR *ETab[] ={ NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL }; +static EDITOR *ED; /* currently serviced editor */ + + + + + +#ifdef mc51 + + void _ncopyuc( char*, char*, int ); + void _ncopylc( char*, char*, int ); + static unsigned int Clear( EDITOR*, long int, unsigned int * ); + static void BackSpace( int ); + static void NextWord( void ); + static void Return( int ); + static void GoTo( int ); + static int format_line( EDITOR*, int, unsigned int ); + static void MoveText ( EDITOR*, long int, long int, long int ); + static unsigned int GetLineLength( EDITOR*, long int, int* ); + +#else +#pragma aux MS_C "_*" \ + parm caller [] \ + value struct float struct routine [ax]\ + modify [ax bx cx dx es]; + + static int format_line( EDITOR*, int, unsigned int ); + static void GoTo( int ); + static unsigned int Clear( EDITOR*, long int, unsigned int * ); + static void BackSpace( int ); + static void NextWord( void ); + static void Return( int ); + static void MoveText ( EDITOR*, long int, long int, long int ); + static unsigned int GetLineLength( EDITOR*, long int, int* ); + + #pragma aux (MS_C) DISPXYA; + #pragma aux (MS_C) REPXYA; + #pragma aux (MS_C) READKEY; + #pragma aux (MS_C) SETXY; + #pragma aux (MS_C) VIDEMODE; + #pragma aux (MS_C) DRAWBOX; + + static int nColor=15; + +void _gtWriteAt( int nTop, int nLeft, char *cText, int nLen ) +{ + char cBuff[232]; + + strncpy( cBuff, cText, nLen ); + cBuff[nLen] ='\x0'; + + DISPXYA( nLeft, nTop, nColor, cBuff ); +} + +void _gtRepChar( int nTop, int nLeft, int nChar, int nRep ) +{ + REPXYA( nLeft, nTop, nColor, nRep, (char)nChar ); +} + +void _gtColorSelect( int nClr ) +{ + nColor =nClr+1; +} + +#endif + +/* + * + ** + * +*/ + + +/* Find the beginning of previous line starting from given offset + */ +static long int Prev( EDITOR *E, long int adres ) +{ + long int i; + + if( adres > 0 ) + { + for( i = adres; i >= 0; i-- ) + { + if( E->begin[ (unsigned int) i ] == '\n' ) + { + if( i < adres-2 ) + return( i + 1 ); + } + } + return( 0 ); + } + + return( -1 ); +} + +/* Find the beginning of next line starting from given offset + */ +static long int Next( EDITOR *E, long int adres ) +{ + char *tmp; + + tmp =strchr( E->begin + (unsigned int) adres, '\n' ); + + if( tmp && tmp[1] ) + return( (long int)(++tmp - E->begin ) ); + else + return( -1 ); +} + +/* Initializes EDITOR structure + */ +static void New(EDITOR *E, int tab, int ll, long int BuforSize) +{ + + E->line_length = ll; + E->first_line = 0; + E->last_line = 0; + E->current_line = 0; + E->first_display = 0; + E->last_display = 0; + E->cursor_row = 0; + E->cursor_col = 0; + E->first_col = 0; + E->stabil = 0; + E->current_stabil = 0; + E->stable = FALSE; + E->tab_size = tab; + E->active = 1; + E->line_number = 0; + E->IsConfigured = 0; + E->text_length = 0; + E->bufor_size = BuforSize; + + E->begin [ 0 ] = '\r'; + E->begin [ 1 ] = '\n'; + E->begin [ 2 ] = '\x0'; + +} + + + +/* + ** Creates new editor and returns index into internal editors table +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_NEW ) +#else +int HB_ED_NEW( int ll, int tab, long int BuforSize ) +#endif +{ + EDITOR *E; + int nEdit=0; + +#ifdef mc51 + int ll, tab; + long int BuforSize; +#endif + + /* Find the free slot fpr new editor + */ + while ( (nEdit < 10 ) && (ETab[nEdit] != NULL) ) + nEdit++; + if( nEdit == 10 ) + #ifdef mc51 + _retni(-1); /* no more free slots */ + #else + return(-1); + #endif + + #ifdef mc51 + ll = _parni(1); + if( ll > MAX_LINE_LEN ) + ll = MAX_LINE_LEN; + tab = _parni(2); + E = (EDITOR *)_xalloc( sizeof(EDITOR) ); + #else + E = calloc(sizeof(EDITOR),1); + #endif + + ETab[nEdit] = E; + + if( E ) + { + #ifdef mc51 + if ( _parinfo ( 0 ) < 3 ) + BuforSize = 32767; + else + BuforSize = (long int )_parni ( 3 ) + 10; + + if( _parinfo( 0 ) < 4 ) + E->escape =0; + else + E->escape =(char)_parni(4); + #else + E->escape =0; + #endif + + #ifdef mc51 + E->begin = (char *)_xalloc( (unsigned int) BuforSize+100 ); + #else + E->begin = calloc( (unsigned int) BuforSize+100, 1 ); + #endif + memset( E->begin, '\x0', (unsigned int) BuforSize ); + + New(E, tab, ll, BuforSize); + + #ifdef mc51 + _retni ( nEdit ); + #else + return ( nEdit ); + #endif + } + else + { + #ifdef mc51 + _retni ( -1 ); /* failure */ + #else + return ( -1 ); + #endif + } +} + +/* Replaces TAB with spaces and removes spaces from the end of line + */ +static void FormatText ( EDITOR *E ) +{ + long int j, dl; + char *wsk; + int i; + unsigned int nLen, nEsc; + + dl = E->current_line; + E->current_line = E->last_line; + + /* TODO: remove this TAB replacement because it is time consuming + * operation if a very large file is edited + */ + wsk =E->begin +E->last_line; + while( (wsk = strchr( wsk, '\t' )) ) + { + j = wsk - E->begin; + + MoveText( E, j, j + E->tab_size-1, + (long int)( E->bufor_size - j - E->tab_size +1 ) ); + + for( i = 0; i < E->tab_size; i++, wsk++ ) + *wsk = ' '; + } + + /* TODO: optimize this line formating - format line only if + * it will be displayed + */ + while( E->current_line >= 0 ) + { + E->last_line =E->current_line; + E->line_number++; + + nLen =Clear( E, E->current_line, &nEsc ); + + if( !format_line( E, HARD, nLen ) ) + E->current_line = Next( E, E->current_line ); + } + + E->current_line = dl; + E->first_col = 0; +} + +/* Resets the editor state after pasting new content of text buffer + */ +static void NewText( EDITOR *E ) +{ + unsigned int i, dl; + + /* text in buffer have to end with CR/LF + */ + dl =(unsigned int)E->text_length; + if( E->begin[ dl-1 ] != '\n' ) + { + E->begin[ dl ] = '\r'; + E->begin[ dl + 1 ] = '\n'; + E->begin[ dl + 2 ] = '\x0'; + E->text_length +=2; + } + + FormatText( E ); + + E->cursor_col = 0; + E->cursor_row = 0; + E->stable = FALSE; + E->current_stabil = 0; + E->first_display = E->last_display = 0; + E->next_stabil = 0; + E->dir = DOWN; + E->stabil = E->bottom - E->top + 1; + + for( i = 0; i < E->stabil; i++ ) + E->last_display =Next( E, E->last_display ); +} + +/* Appends passed text to the existing text buffer + */ +static void AddText( int nEdit, char *adres ) +{ + EDITOR *E; + long int dl, dlold; + + E = ETab [ nEdit ]; + + dl = strlen( adres ); + dlold = E->text_length; + if( dlold == 2 ) + dlold =0; /* if current text buffer contains CRLF only then discard it */ + + /* TODO: add reallocation of text buffer + */ + if( (dl+dlold) <= (E->bufor_size - 10) ) + { + /* there is enough room in text buffer + */ + strcpy( E->begin+dlold, adres ); + E->text_length +=dl; + } + else + { + strncpy( E->begin+dlold, adres, (int)(E->bufor_size -10 -dlold) ); + E->text_length =E->bufor_size - 10; + } + + NewText( E ); /* reformat text */ +} + +/* + ** Appends passed text at the end of existing one +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_ADDTEXT ) +#else +CLIPPER HB_ED_ADDTEXT ( int nEdit, char *adres ) +#endif +{ + #ifdef mc51 + char *adres; + int nEdit; + + nEdit = _parni(1); + adres = _parc(2); + #endif + + AddText( nEdit, adres ); +} + +/* Moves text from one location into another + */ +static void MoveText ( EDITOR * E, long int source, long int dest, + long int ilb ) +{ + long int diff; + + diff = dest - source; + /* memmove supports overlapped buffers */ + memmove( E->begin + (unsigned int)dest, E->begin + (unsigned int)source, + (unsigned int) ilb ); + + if( E->last_display > E->current_line ) + E->last_display += diff; + + if ( E->current_line < E->last_line ) + E->last_line += diff; + + E->text_length +=diff; + + if( E->text_length > ( E->bufor_size - 8 ) ) + { + E->text_length =E->bufor_size - 8; + E->begin[ E->text_length ] = '\x0'; + E->begin[ E->text_length-1 ] = '\n'; + E->begin[ E->text_length-2 ] = '\r'; + } +} + +/* Skips to the beginning of given line + */ +static long int GoToLine( EDITOR *E, int linia ) +{ + char *p; + long int i; + + i =0; + p =E->begin; + while( (++i <= linia) && (p=strchr( p, '\n' )) ) + p +=2; + + if( i > linia ) + return( p - E->begin -1 ); + else + return( E->text_length ); /* no such line number - go to the end */ +} + +/* Counts the number of printable characters in given line + */ +static unsigned int GetLineLength( EDITOR *E, long int off, int *wsk ) +{ + unsigned int i, j; + char *p, *tmp; + + tmp =E->begin + (unsigned int)off; + p =strchr( tmp, '\n' ); /* find EOL starting from given position */ + + if( p ) + { + off =( p - tmp ); + i =(unsigned int)off -1; + } + else + i =strlen( tmp ); + + *wsk = 0; /* number of characters used in color escape codes */ + if( E->escape ) + { + for( j=0; j < i; j++ ) + if( (char)tmp[j] == E->escape ) + { + (*wsk) +=2; + j++; + } + } + + return( i - *wsk ); /* number of all chars minus number of escape chars */ +} + +/* Inserts text into existing text buffer starting from given line number + */ +static long int InsText ( EDITOR *E, char *adres, long int line ) +{ + long int dl, off, il, dl1; + int addCRLF, cc; + + addCRLF = 0; + dl = strlen ( adres ); /* length of text to insert */ + dl1 = E->text_length; /* length of text that is currently in the buffer */ + + /* TODO: add reallocation of text buffer + */ + if( dl1 < (E->bufor_size - 10) ) + { + /* there is some free space in text buffer + */ + /* Find the offset of given line */ + if( line > 0 ) + off = GoToLine( E, (unsigned int) line ); /* Find the offset of given line */ + else + off = 0; + + if( (long int)(dl + dl1) < (E->bufor_size-10) ) + { + /* there is enough free room in text buffer + */ + if ( (adres[(unsigned int) dl-1] != '\n') && (adres[(unsigned int) dl-2] != '\r') ) + { + /* There is no CRLF at the end of inserted text - + * we have to add CRLF to separate it from existing text + */ + addCRLF = 1; + dl += 2; + } + MoveText( E, off, off + dl, E->bufor_size - (off - 1) - dl ); + strncpy( E->begin + (unsigned int) off, adres , (unsigned int) dl ); + } + else + { + /* not enough free space + * text at the end of existing text buffer will be lost + */ + dl = E->bufor_size - 10 - dl1; + if( adres[ (unsigned int)dl-1 ] == '\r' ) + adres[ (unsigned int)dl-1 ] = ' '; + + if( (adres[(unsigned int) dl-1] != '\n') && (adres[(unsigned int) dl-2] != '\r') ) + { + addCRLF = 1; + dl += 2; + } + MoveText( E, off, off + dl, E->bufor_size - (off - 1) - dl ); + strncpy ( E->begin + (unsigned int) off, adres , (unsigned int) dl ); + } + + if( addCRLF ) + { + E->begin [(unsigned int) (off + dl - 2)] = '\r'; + E->begin [(unsigned int) (off + dl - 1)] = '\n'; + E->text_length += 2; + } + + if ( ( off + dl ) == E->text_length ) + E->begin [ (unsigned int) E->text_length ] = '\x0'; + E->text_length = strlen ( E->begin ); + + il = E->line_number; + cc = E->cursor_col; + + FormatText ( E ); + + E->cursor_col = cc; + + if ( off <= E->current_line ) + { + E->current_line += E->text_length - dl1; + E->active += E->line_number - il; + } + } + + return ( dl ); +} + +/* + ** Inserts passed text into text buffer +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_INSTEXT ) +#else +unsigned int HB_ED_INSTEXT ( int nEdit, char *adres, long int linia ) +#endif +{ + long int dl; + EDITOR *E; + + #ifdef mc51 + char *adres; + int nEdit; + long int linia; + + nEdit = _parni(1); + adres = _parc(2); + linia = (long int) _parni(3); + #endif + + E =ETab[nEdit]; + dl = InsText( E, adres, linia ); + E->last_line = Prev ( E, (long int) strlen ( E->begin ) ); + + #ifdef mc51 + _retni ( (unsigned int) dl ); + #else + return ( (unsigned int) dl ); + #endif +} + +/* + ** +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_PUSH ) +{ + int i; + + i =0; + while( i < 5 && EStack[i] ) + i++; + + EStack[ i ] =ED; +} + +CLIPPER_ACTION( HB_ED_POP ) +{ + int i; + + i =0; + while( i < 5 && EStack[i] ) + i++; + + if( i ) + { + ED =EStack[ i-1 ]; + EStack[ i-1 ] =NULL; + } +} +#endif + +/* + * Selects the editor as active - all next ED_*() calls will be send + * to this editor. +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_CONFIG ) +#else +CLIPPER HB_ED_CONFIG(int nEdit, int top, int left, int bottom, int right, + int nRow, int nCol) +#endif +{ + int szer, wys; + int nszer, nwys; + int diff; + long int tmp; + long int j; + +#ifdef mc51 + int top, left, bottom, right; + int nRow, nCol; + int nEdit, i; + + nEdit = _parni(1); + top = _parni(2); + left = _parni(3); + bottom = _parni(4); + right = _parni(5); + nRow = _parni(6); + nCol = _parni(7); +#endif + + ED = ETab[nEdit]; /* select the editor to work on */ + + szer = ED->right - ED->left + 1; + wys = ED->bottom - ED->top + 1; + + ED->top = top; + ED->left = left; + ED->bottom = bottom; + ED->right = right; + + ED->last_display = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + + if( ED->IsConfigured ) + { + /* In event driven world the position and size of the editor window can + * change between activations - recalculate some required values + */ + ED->first_display = ED->current_line; + + /* find the first line to display - try to keep visible the current line + * and display this line in the same row in the window (if possible) + */ + for ( i = 0; i < ED->cursor_row; i++ ) + { + j = Prev( ED, ED->first_display ); + if ( j >= 0 ) + ED->first_display = j; + else + ED->cursor_row--; + if ( ED->cursor_row < 0 ) + ED->cursor_row = 0; + } + + /* find the last line for display */ + for( i = 0; i < ED->bottom - ED->top; i++ ) + { + j = Next ( ED, ED->last_display ); + if ( j >= 0 ) + ED->last_display = j; + } + } + else + { + ED->first_display = ED->first_line; + + /* find the last line for display */ + nwys =ED->bottom - ED->top; + for( i = 0; i < nwys; i++ ) + { + j = Next( ED, ED->last_display ); + if ( j >= 0 ) + ED->last_display = j; + } + /* check if this line is empty */ + if( strlen(ED->begin+(unsigned int)ED->last_display) == 0 ) + ED->last_display = Prev( ED, ED->last_display ); + + /* set initial cursor position in the window */ + ED->cursor_row = nRow; + ED->cursor_col = nCol; + } + + if( ED->IsConfigured ) + { + nszer = ED->right - ED->left + 1; + nwys = ED->bottom - ED->top + 1; + + diff = abs(szer - nszer); + if(szer < nszer) + { + /* current width of the window is greater then during previous activation + * adjust the first visible column + */ + if(ED->first_col > diff) + { + ED->first_col -= diff; + ED->cursor_col+= diff; + } + else + { + ED->cursor_col+= ED->first_col; + ED->first_col = 0; + } + } + if(szer > nszer) + { /* current width of the window is smaller then during previous activation + */ + if(ED->cursor_col > (nszer - 1)) + { + ED->first_col += ED->cursor_col - nszer + 1; + ED->cursor_col = nszer - 1; + } + } + + diff = abs(nwys - wys); + if(wys > nwys) + { + /* current height of the window is smaller then during previous activation + */ + if( ED->cursor_row < nwys ) + { + /* the old cursor row position is smaller then the window height + */ + tmp = ED->last_display; + for ( i = 0; i < diff; i++ ) + { + j = Prev ( ED, tmp ); + if ( j >= 0 ) + tmp = j; + + } + ED->last_display = tmp; + } + else + { + /* old cursor row position is greater then current window height + * display the line where the cursor is placed as the last visible + * line in the window + */ + ED->last_display = ED->current_line; + tmp = ED->last_display; + + for(i = 0; i < nwys-1; i++) + { + j = Prev ( ED, tmp ); + if ( j >= 0 ) + tmp = j; + } + ED->first_display = tmp; + ED->cursor_row = nwys - 1; + } + } + } + else + { + ED->current_line = ED->first_line; + ED->active = 1; + } + + ED->IsConfigured = 1; + ED->stable = FALSE; + ED->current_stabil = 0; + ED->next_stabil = ED->first_display; + ED->dir = DOWN; +} + +/* + ** Returns current text buffer +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_GETTEXT ) +#else +char *HB_ED_GETTEXT(int nEdit, int Case, int mietka ) +#endif +{ + long int dl; + char *bufor, *help; + EDITOR *E; + +#ifdef mc51 + int Case, mietka; + int nEdit; + + nEdit = _parni(1); + Case = _parni(2); + mietka = _parni(3); +#else + int p; +#endif + + E = ETab[nEdit]; + + dl = strlen ( E->begin ) +3; + + #ifdef mc51 + bufor = (char *)_xalloc((unsigned int) dl); + #else + bufor = calloc((unsigned int) dl,1); + + strcpy(name,"c:\\out.txt"); + p = open(name,O_CREAT+O_WRONLY+O_BINARY); + #endif + + strcpy ( bufor, E->begin ); + + switch (Case) + { + /* IT USES INTERNAL CLIPPER FUNCTIONS + #ifdef mc51 + case 0: _ncopyuc(bufor, bufor, (unsigned int) dl); + break; + case 1: _ncopylc(bufor, bufor, (unsigned int) dl); + break; + #else + */ + case 0: bufor = strlwr(bufor); + break; + case 1: bufor = strupr(bufor); + /* #endif */ + + default:; + } + + help = bufor; + if(mietka != SOFT) + { + while(help !=NULL) + { + help = strstr(bufor,"\n"); /* CHR(141)+CHR(10) */ + if( help ) + help[0] = '\r'; + } + } + +#ifdef mc51 + _retc ( bufor ); + _xfree ( bufor ); +#else + write(p, bufor, (unsigned int) dl); + return(bufor); +#endif +} + +/* + ** Returns given line of text and positions caret at the beginning of next line +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_GETLINE ) +#else +char *HB_ED_GETLINE(int nEdit, long int linia ) +#endif +{ + long int l, j; + long int tmp; + char *bufor; + EDITOR *E; + int rdl, i, dl; + +#ifdef mc51 + long int linia; + int nEdit; + + nEdit = _parni(1); + linia = (long int) _parni(2); +#endif + + E = ETab[nEdit]; + + l = 1; + tmp = E->first_line; + for(i = 1; i < (unsigned int) linia; i++) + { + j = Next ( E, tmp ); + if ( j >= 0 ) + { + tmp = j; + l++; + } + } + if( l == linia ) + { + dl = GetLineLength ( E, tmp, &rdl ); + dl++; + #ifdef mc51 + bufor = (char *)_xalloc( dl ); + #else + bufor = calloc( dl,1 ); + #endif + + strncpy ( bufor, E->begin + (unsigned int) tmp, dl-1 ); + bufor[ (dl-1) ] = '\x0'; + } + + E->next_line = Next ( E, tmp ); + +#ifdef mc51 + _retc ( bufor ); + _xfree ( bufor ); +#else + return( bufor ); +#endif +} + +/* + ** Returns current line pointed by caret position and advances it to the beginning of next line +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_GETNEXT ) +#else +char *HB_ED_GETNEXT(int nEdit) +#endif +{ + char *bufor; + EDITOR *E; + int rdl, dl; + +#ifdef mc51 + int nEdit; + + nEdit = _parni(1); +#endif + + E = ETab[nEdit]; + if ( E->next_line > 0 ) + { + dl = GetLineLength ( E, E->next_line, &rdl ); + dl++; + #ifdef mc51 + bufor = (char *)_xalloc ( dl ); + #else + bufor = calloc ( dl, 1 ); + #endif + + strncpy ( bufor, E->begin + (unsigned int) E->next_line, dl-1 ); + bufor [ (unsigned int) (dl-1) ] = '\x0'; + E->next_line = Next ( E, E->next_line ); + + #ifdef mc51 + _retc ( bufor ); + _xfree ( bufor ); + #else + + DISPXYA( 1, 24, 5, bufor ); + return( bufor ); + #endif + } + else + { + #ifdef mc51 + _ret(); + #else + DISPXYA( 1, 24, 5, "KONIEC" ); + return( NULL ); + #endif + } +} + +/* Resets text buffer + */ +static void KillText ( EDITOR *E ) +{ + memset( E->begin, '\x0', (unsigned int) E->bufor_size ); + E->first_line = E->last_line = 0; +} + +/* + ** Stores new text into editor +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_SETTEXT ) +#else +CLIPPER HB_ED_SETTEXT(int nEdit, char *adres) +#endif +{ + EDITOR *E; + +#ifdef mc51 + char *adres; + int nEdit; + + nEdit = _parni (1); + adres = _parc (2); +#endif + + E = ETab[nEdit]; + + KillText( E ); + + New( E, E->tab_size, E->line_length, E->bufor_size ); + + AddText ( nEdit, adres ); +} + +/* + ** Reads a text from the file +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_READTEXT ) +{ + unsigned int nEdit, nFile, nSize, lSuccess=FALSE; + long int nSeek, nRead; + EDITOR *E; + BOOL lConv; + + nEdit =_parni( 1 ); + E =ETab[ nEdit ]; + + KillText( E ); + New( E, E->tab_size, E->line_length, E->bufor_size ); + + nFile =_parni( 2 ); + nSeek =_parnl( 3 ); + nSize =_parni( 4 ); + lConv =_parl( 5 ); + + nRead =_fsSeek( nFile, nSeek, FS_SET ); + if( nRead == nSeek ) + { + if( nSize > (unsigned int)(E->bufor_size-10) ) + nSize =(unsigned int)E->bufor_size-10; + + nSize =_fsRead( nFile, (unsigned char *)E->begin, nSize ); + E->begin[ nSize ] ='\x0'; + + E->text_length =nSize; + +/* + * Characters with ASCII code 27 and 26 cannot be stored inside + * a file - for this reason the replacement characters were used 181 and 198 + * and stored in a file on disk + * + if( lConv ) + { + unsigned char *cPtr; + + cPtr =(unsigned char *) E->begin; + while( nSize-- ) + { + if( *cPtr == 181 ) + *cPtr =27; + else if( *cPtr == 198 ) + *cPtr =26; + + cPtr++; + } + } +*/ + NewText( E ); + + lSuccess =TRUE; + E->stable =FALSE; + } + + _retl( lSuccess ); +} +#endif + +/* + ** Releases memory occupied by the editor +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_KILL ) +#else +CLIPPER HB_ED_KILL(int nEdit) +#endif +{ + EDITOR *E; + +#ifdef mc51 + int nEdit; + + nEdit = _parni(1); +#endif + + E = ETab[nEdit]; + KillText( E ); + + #ifdef mc51 + _xfree ( E->begin ); + #else + free ( E->begin ); + #endif + + #ifdef mc51 + _xfree(E); + #else + free(E); + #endif + + ETab[nEdit] = NULL; +} + +/* Sorry - I don't remember why it is here + */ +CLIPPER_ACTION( HB_ED_UNLOCK ) +{ +} + +/* + * Stabilize the editor + * Redisplays all requested lines + * It is simmilar to TBrowse:forceStable() + * Incremental stabilisation was too slow +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_STABILIZE ) +#else +int HB_ED_STABILI( void ) +#endif +{ + unsigned int nRow=0, nEscLen, nLen, width, i,j, e; + int nLeft, nTop; + char *EscPtr; + char *cPtr; + char adres[ MAX_LINE_LEN + 2 ]; + + while( --ED->stabil >= 0 ) + { + /* there are some lines of text to display + */ + width =ED->right - ED->left + 1; + + if( ED->next_stabil >= 0 ) + { + cPtr =ED->begin +ED->next_stabil; + for( nEscLen=nLen=0; *cPtr && *cPtr != '\n'; cPtr++ ) + { + /* copy the line into temporary buffer - count characters used + * as color escape codes + */ + adres[nLen++] =*cPtr; + if( ED->escape && (char)*cPtr == ED->escape ) + nEscLen +=2; + } + j =nLen -nEscLen; /* length of printable text */ + adres[nLen] = '\x0'; + + if( ED->first_col >= j ) + adres[ nEscLen=nLen=0 ] ='\x0'; /* first visible column is greater then line length */ + + else if( ED->first_col ) + { + /* text is scrolled right - we need to find the first + * color escape code that will be visible + * text ~2 in bold ~1 in normal + * ^-first visible column + */ + e =0; + if( ED->escape ) + { + for( i=0; i < (ED->first_col+e) ; i++ ) + if( (char)adres[i] == ED->escape ) + { + adres[0] =adres[i]; + adres[1] =adres[++i]; + e +=2; + }; + } + + if( e ) + { + nLen -=(i-2); + if( (char)adres[i-1] == ED->escape ) + i++, nLen--; + strncpy( adres+2, adres+i, nLen-2 ); + nEscLen -=(e-2); + } + else + { + nLen -=ED->first_col; + strncpy( adres, adres+ED->first_col, nLen ); + } + adres[ nLen ] = '\x0'; + } + + if( nLen ) + if( adres[ nLen-1 ] & '\xd' ) /* soft or hard carriage */ + adres[ --nLen ] = '\x0'; + + /* find next line for displaying */ + switch( ED->dir ) + { + case DOWN : ED->next_stabil =Next( ED, ED->next_stabil ); + nRow =ED->current_stabil++; + break; + + case UP : ED->next_stabil =Prev( ED, ED->next_stabil ); + nRow =ED->current_stabil--; + break; + + default : ; + } + + _gtColorSelect( 0 ); /* select default color */ + + nTop =ED->top +nRow; + if( nLen ) + { + if( ED->escape && ( EscPtr = strchr( adres, ED->escape ) ) ) + { + i =(unsigned int)(EscPtr - adres); + nLeft =ED->left +i; + + if( i ) + _gtWriteAt( nTop, ED->left, (unsigned char *)adres, (width < i)?width:i ); + + for( ; i < nLen && nLeft <= ED->right; i++ ) + if( (char)adres[i] == ED->escape ) + _gtColorSelect( (adres[++i] & '\x0F')-1 ); + else + _gtWriteAt( nTop, nLeft++, (unsigned char *)adres+i, 1 ); + } + else + _gtWriteAt( nTop, ED->left, (unsigned char *)adres, ((width < nLen)?width:nLen ) ); + } + + /* fill the rest of the row with spaces */ + if( (nLen-nEscLen) < width ) + _gtRepChar( nTop, ED->left+nLen-nEscLen, ' ', width-nLen+nEscLen ); + } + else + { + /* no more lines of text to display - fill the window with spaces + */ + switch( ED->dir ) + { + case DOWN : nRow = ED->current_stabil++; + break; + case UP : nRow = ED->current_stabil--; + break; + default : ; + } + + _gtColorSelect( 0 ); + _gtRepChar( ED->top+nRow, ED->left, ' ', width ); + } + + _gtColorSelect( 0 ); + } + + ED->stable = TRUE; + +#ifdef mc51 + _retni( nRow ); +#else + return( nRow ); +#endif +} + +#ifndef mc51 + void IInsert(void) + { + if(insert) + insert = FALSE; + else + insert = TRUE; + } +#endif + +#ifndef mc51 + void init_window(void) + { + HB_ED_STABILI(); + } +#endif + +/* Removes trailing spaces from the end of line + */ +static unsigned int Clear( EDITOR *E, long int e, unsigned int *nEsc ) +{ + unsigned int nLen, i; + + nLen =GetLineLength( E, e, (int*)nEsc ); + i =(unsigned int)e + nLen + *nEsc; + + if( i ) + while( E->begin[ i-1 ] == ' ' ) + { + if( E->cursor_col > 0 ) + E->cursor_col--; + + else if( E->first_col > 0 ) + E->first_col--; + + MoveText( E, (long int)i, (long int)i-1, E->text_length -i +3 ); + nLen--; + } + + return( nLen ); +} + +/* Moves the cursor to the next line of text + */ +static void Down( EDITOR *E ) +{ + long int j; + unsigned int nEsc; + + j = Next( E, E->current_line ); /* find the offset of next line */ + if ( E->begin [ (unsigned int) j ] == '\x0' ) + j = -1; /* no more lines */ + if ( j < 0 ) + { + E->stable = TRUE; + } + else + { + E->active++; + Clear( E, E->current_line, &nEsc ); + + j = Next( E, E->current_line ); + if ( j >= 0 ) + { + E->current_line = j; + } + if( ((++E->cursor_row)+E->top) > E->bottom ) + { + /* attempt to move to the line that was not visible yet + */ + #ifdef mc51 + E->stabil = 1; /* only one line needs to be redisplayed */ + #else + E->stabil = E->bottom - E->top + 1; + #endif + + E->cursor_row = E->bottom - E->top; + E->first_display = Next( E, E->first_display ); + E->last_display = j; + + E->stable = FALSE; + E->next_stabil = E->last_display; + E->dir = UP; + E->current_stabil = E->cursor_row; + } + else + { + /* the new line is already visible */ + if( E->line_number <= (E->bottom - E->top + 1) ) + E->last_display = E->last_line; /* the total number of lines is smaller then rows to display */ + } + } + if( E->current_line > E->last_display ) + E->last_display = E->current_line; + if( E->current_line > E->last_line ) + E->last_line = E->current_line; +} + + + + +/* + ** Moves cursor to the next line of text +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_DOWN ) +#else +CLIPPER HB_ED_DOWN(void) +#endif +{ + Down( ED ); + +#ifdef mc51 + _retl(ED->stable); +#endif +} + +/* Moves the cursor to the previous line of text + */ +static void Up( void ) +{ + int j, i; + long int jj, tmp; + unsigned int nEsc; + + /* find the previous line */ + jj = Prev ( ED, ED->current_line ); + if ( jj < 0 ) + { + ED->stable = TRUE; + } + else + { + ED->active--; + Clear( ED, ED->current_line, &nEsc ); + ED->current_line = jj; + if( ((--ED->cursor_row)+ED->top) < ED->top ) + { + /* the new line was not displayed yet */ + #ifdef mc51 + ED->stabil = 1; /* only one line needs redisplay - rest of lines will be scrolled */ + #else + ED->stabil = ED->bottom - ED->top + 1; + #endif + + j = 0; + ED->cursor_row = 0; + + /* count the number of lines that will be visible in the window. + * If the number of lines is smaller then the window height then + * the offset of last displayed line will be not changed + */ + ED->first_display = Prev ( ED, ED->first_display ); + tmp = ED->first_display; + for(i = 0; i < ED->bottom - ED->top + 1; i++) + { + jj = Next ( ED, tmp ); + if ( jj >= 0 ) + { + tmp = jj; + j++; + } + } + if( j == (ED->bottom - ED->top + 1) ) + ED->last_display = Prev ( ED, ED->last_display ); + + ED->stable = FALSE; + ED->next_stabil = ED->current_line; + ED->dir = DOWN; + ED->current_stabil = 0; + } + } +} + +/* + ** Moves the cursor to the previous line +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_UP ) +#else +CLIPPER HB_ED_UP(void) +#endif +{ + Up(); + +#ifdef mc51 + _retl(ED->stable); +#endif +} + +/* + ** Moves the cursor to the next page of text +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_PGDOWN ) +#else +CLIPPER HB_ED_PGDOWN(void) +#endif +{ + int i; + long int j; + + j = Next( ED, ED->last_display ); + if( ED->begin[ (unsigned int) j ] == '\x0' ) + { /* no more lines */ + ED->stable = TRUE; + /* advance the cursor as much as possible (to the last line) */ + for( i=0; i < ED->bottom - ED->top +1; i++ ) + Down( ED ); + return; + } + + /* the last possible line will be displayed at the very bottom of the window */ + /* find the last line to display */ + for(i = 0; i < ED->bottom - ED->top; i++) + { + j = Next ( ED, ED->last_display ); + if ( j >= 0 ) + { + if ( ED->begin [ (unsigned int)j ] != '\x0' ) + { + ED->active++; + ED->last_display = j; + } + } + else + break; /* no more lines */ + } + + if ( ED->begin[ (unsigned int)ED->last_display ] == '\x0' ) + ED->last_display = Prev ( ED, ED->last_display ); + ED->first_display = ED->last_display; + + /* find the first displayed line now */ + for(i = 0; i < ED->bottom - ED->top; i++) + { + j = Prev ( ED, ED->first_display ); + if ( j >= 0 ) + ED->first_display = j; + else + ED->first_display = 0; + } + + /* find the offset of the line where the currsor will be displayed */ + ED->current_line = ED->last_display; + for(i = 0; i < ED->bottom - ED->top - ED->cursor_row; i++) + { + j = Prev ( ED, ED->current_line ); + if ( j >= 0 ) + ED->current_line = j; + else + ED->current_line = 0; + } + + ED->stable = FALSE; + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + +} + + +/* + ** Moves the cursor to the previous page of text +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_PGUP ) +#else +CLIPPER HB_ED_PGUP(void) +#endif +{ + int i, bt; + long int j; + + bt = ED->bottom - ED->top; + + j = Prev ( ED, ED->first_display ); + if( j < 0 ) + { /* no more lines to move */ + ED->stable = TRUE; + /* advannce the cursor to the topmost line */ + for(i=0; i < bt + 1; i++) + Up(); + return; + } + + /* find the offset of the first visible line */ + for(i = 0; i < bt; i++) + { + j = Prev ( ED, ED->first_display ); + if ( j >= 0 ) + { + ED->active--; + ED->first_display = j; + } + else + break; /* no more line */ + } + /* now the last visible line */ + ED->last_display = ED->first_display; + for(i = 0; i < bt; i++) + { + j = Next ( ED, ED->last_display ); + if ( j >= 0 ) + ED->last_display = j; + } + + /* update the offset of line where the cursor will be displayed + * keep the cursor in the same row if possible + */ + ED->current_line = ED->last_display; + for(i = 0; i < bt - ED->cursor_row; i++) + { + j = Prev ( ED, ED->current_line ); + if ( j >= 0 ) + ED->current_line = j; + else + ED->current_line = 0; + } + + ED->stable = FALSE; + ED->next_stabil = ED->last_display; + ED->stabil = bt + 1; + ED->dir = UP; + ED->current_stabil = bt; +} + +/* + ** Move the cursor to the beginning of the text +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_TOP ) +#else +CLIPPER HB_ED_TOP(void) +#endif +{ + long int j; + int i; + unsigned int nEsc; + + Clear( ED, ED->current_line, &nEsc ); + ED->current_line = ED->first_line; + ED->cursor_row = 0; + ED->first_display = ED->last_display = ED->first_line; + + /* find the last visible line */ + for(i = 0; i < ED->bottom - ED->top; i++) + { + j = Next ( ED, ED->last_display ); + if ( j >= 0 ) + ED->last_display = j; + } + + ED->cursor_row = ED->current_stabil = 0; + ED->current_line = ED->next_stabil = ED->first_line; + ED->active = 1; + ED->stable = FALSE; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->first_col = ED->cursor_col = 0; +} + +/* + ** Move the cursor to the last line of text +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_BOTTOM ) +#else +CLIPPER HB_ED_BOTTOM(void) +#endif +{ + int i, j; + long int jj; + unsigned int nEsc; + + j = 0; + Clear( ED, ED->current_line, &nEsc ); + ED->current_line = ED->last_line; + ED->cursor_row = 0; + ED->first_display = ED->last_line; + + /* find the first visible line */ + /* We have to count from the bottom to make it work in case the number + * of lines is smaller then the height of the window + */ + ED->last_display = ED->first_display; + for(i = 0; i < ED->bottom - ED->top; i++) + { + jj = Prev ( ED, ED->first_display ); + if ( jj >= 0 ) + { + ED->first_display = jj; + j++; + } + } + + ED->current_line = ED->last_display; + ED->active = ED->line_number; + ED->stable = FALSE; + ED->next_stabil = ED->first_display; + ED->dir = DOWN; + ED->current_stabil = 0; + ED->first_col = ED->cursor_col = 0; + ED->cursor_row = j; + ED->stabil = ED->bottom - ED->top + 1; +} + +/* Go to the specified line number + */ +static void GoTo(int line) +{ + int i; + long int j; + unsigned int nEsc; + + Clear( ED, ED->current_line, &nEsc ); + + /* find specified line */ + ED->current_line = ED->first_line; + for(i = 0; i < line-1; i++) + { + j = Next( ED, ED->current_line ); + if ( j >= 0 ) + ED->current_line = j; + } + ED->cursor_row = 0; + ED->first_display = ED->current_line; + + /* find the offset of the last visible line */ + ED->last_display = ED->first_display; + for(i = 0; i < ED->bottom - ED->top; i++) + { + j = Next ( ED, ED->last_display ); + if( j >= 0 ) + ED->last_display = j; + } + + ED->active = line; + ED->stable = FALSE; + ED->next_stabil = ED->current_line; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = ED->cursor_row; + ED->first_col = 0; +} + +/* + ** Move the cursor to the given line using line number +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_GOTO ) +#else +CLIPPER HB_ED_GOTO(long int line) +#endif +{ +#ifdef mc51 + long int line; + + line = (long int)_parni(1); +#endif + + GoTo((unsigned int) line); +} + +/* Move the cursor to the previous character + */ +static void Left(void) +{ + if( ED->cursor_col > 0 ) + ED->cursor_col--; /* inside the window - decrement current column number */ + else + { + if( ED->first_col > 0 ) + { + /* the text is scrolled right - scroll it back to the left by one column */ + ED->first_col--; + ED->stable = FALSE; + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + } + /* else no wrap allowed */ + } +} + +/* + ** Move the cursor to the previous character +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_LEFT ) +#else +CLIPPER HB_ED_LEFT(void) +#endif +{ + Left(); +} + + +/* Move the cursor to the next character + */ +static void Right( EDITOR *E ) +{ + if( E->cursor_col < (E->right - E->left) ) + { /* inside the window */ + if( (E->first_col + E->cursor_col) < E->line_length ) + E->cursor_col++; + /* else no wrap allowed */ + } + else + { + /* scroll text to the right no more then the maximal line length */ + if( (++E->first_col + E->cursor_col) > E->line_length ) + E->first_col--; + + E->stable = FALSE; + E->next_stabil = E->first_display; + E->stabil = E->bottom - E->top + 1; + E->dir = DOWN; + E->current_stabil = 0; + } +} + +/* + ** Move the cursor to the next character +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_RIGHT ) +#else +CLIPPER HB_ED_RIGHT(void) +#endif +{ + Right( ED ); +} + +/* Move the cursor to the beginning of line + */ +static void Home( EDITOR *E ) +{ + if( E->first_col > 0 ) + { + /* the line was scrolled to the right */ + E->cursor_col = 0; + E->first_col = 0; + E->stable = FALSE; + E->next_stabil = E->first_display; + E->stabil = E->bottom - E->top + 1; + E->dir = DOWN; + E->current_stabil = 0; + + } + else + { + E->cursor_col = 0; + E->first_col = 0; + } +} + + +/* + ** Move the cursor to the beginning of the line +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_HOME ) +#else +CLIPPER HB_ED_HOME(void) +#endif +{ + Home( ED ); +} + +/* Move the cursor to the end of line + */ +static void End( EDITOR *E ) +{ + unsigned int ll, nEsc; + + ll =Clear( E, E->current_line, &nEsc ); + if( ll < E->first_col ) + { + /* the line length is smaller then the number of characters scrolled - + * adjust the first visible column to make the end of line visible + */ + E->first_col = ll; + E->cursor_col = 0; + E->stable = FALSE; + E->next_stabil = E->first_display; + E->stabil = E->bottom - E->top + 1; + E->dir = DOWN; + E->current_stabil = 0; + } + else + if( ( ll - E->first_col ) > (E->right - E->left) ) + { + /* scroll text to the right */ + E->cursor_col = E->right - E->left; + E->first_col = (int ) ( ll - (E->right - E->left) ); + E->stable = FALSE; + E->next_stabil = E->first_display; + E->stabil = E->bottom - E->top + 1; + E->dir = DOWN; + E->current_stabil = 0; + } + else + E->cursor_col = ll - E->first_col; +} + + +/* + ** Move the cursor the the end of line (after the last non-space character) +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_END ) +#else +CLIPPER HB_ED_END(void) +#endif +{ + End( ED ); +} + + +/* Format the current paragraph + */ +static void FormatParagraph ( EDITOR *E ) +{ + int rdl, cc, cr, cor; + long int dl, source, CrLine; + char pom[ MAX_LINE_LEN * 2 ], *tmp; + unsigned int nEsc; + + cc = E->cursor_col; + cr = E->cursor_row; + cor = 0; + + rdl = format_line( E, SOFT, 0 ); + E->stabil = 1; /* at least one line will be redisplayed */ + +/* if ( rdl ) +*/ + { + dl = (long int)GetLineLength( E, E->current_line, &rdl ); + strncpy( pom, E->begin+(unsigned int)E->current_line, (int)(dl+rdl+10) ); + pom[ E->line_length + rdl + 1 ] = '\x0'; + tmp = strchr( pom, '\n' ); + if( tmp && ((unsigned char)*(tmp-1) == 141u) ) /* soft CR */ + { + tmp--; + cor++; + } + else + tmp = NULL; + + CrLine = E->current_line; + + while( tmp ) + { + source = E->current_line + (long int)(tmp - pom - 1); + MoveText ( E, source+2, source+1, E->bufor_size - source + 2 ); + E->begin[ (unsigned int)(source+1) ] = ' '; + + rdl = format_line( E, SOFT, 0 ); + Clear( E, E->current_line, &nEsc ); + + E->current_line = Next( E, E->current_line ); + dl = (long int)GetLineLength( E, E->current_line, &rdl ); + strncpy( pom, E->begin+(unsigned int)E->current_line, (int)(dl+rdl+10) ); + pom[ E->line_length + rdl + 1 ] = '\x0'; + tmp = strchr( pom, '\n' ); + if( tmp && ((unsigned char)*(tmp-1) == 141u) ) + { + tmp--; + cor++; + } + else + tmp = NULL; + + } + E->current_line = CrLine; + E->stabil = E->bottom - E->top + 1; + E->next_stabil = E->first_display; + E->current_stabil = 0; + } +/* else +*/ + { + E->stabil = 1; + E->next_stabil = E->current_line; + E->current_stabil = E->cursor_row; + } + + E->stable = FALSE; + E->dir = DOWN; + E->cursor_col = cc; + E->cursor_row = cr; + E->line_number-= cor; +} + + + +/* Delete the character under the cursor + */ +static void DelChar ( EDITOR *E ) +{ + int ccc, rdl; + long int cl; + + cl = E->current_line; + ccc = E->cursor_col + E->first_col; + if( ccc <= GetLineLength( E, E->current_line, &rdl ) ) + { + if( E->escape ) + while( (char)E->begin[ (unsigned int)(E->current_line + ccc) ] == E->escape ) + ccc += 2; + MoveText ( E, E->current_line + (long int) (ccc + 1), + E->current_line + (long int) ccc, + (E->bufor_size - ( E->current_line + (long int)(ccc + 1)))); + + E->stable = FALSE; + E->next_stabil = E->current_line; + + E->dir = DOWN; + E->current_stabil = E->cursor_row; + + FormatParagraph ( E ); + + if( E->current_line == E->last_line ) + E->last_display = E->last_line; + + E->current_line = cl; + + E->stable = FALSE; + E->next_stabil = E->first_display; + E->stabil = E->bottom - E->top + 1; + E->dir = DOWN; + E->current_stabil = 0; + } +} + +/* + ** Delete the character at current cursor position +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_DELCHAR ) +#else +CLIPPER HB_ED_DELCHAR(void) +#endif +{ + long int j; + int rdl; + + if ( ( (unsigned int) (ED->cursor_col + ED->first_col) ) >= + ( (unsigned int) GetLineLength ( ED, ED->current_line, &rdl ) ) ) + { + /* The cursor is positioned after the last non-space character + */ + j = Next ( ED, ED->current_line ); + if ( j >= 0 ) + { + /* there are more lines below the cursor - join the lines + */ + Down( ED ); /* goto the next line */ + Home( ED ); /* goto the beginning of line */ + BackSpace(1); /* delete separating CR/LF */ + + ED->stable = FALSE; + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + } + } + else + { + /* The cursor is inside the line or at the last character + */ + if ( (unsigned int) ( ED->cursor_col + ED->first_col ) < + (unsigned int) ( GetLineLength ( ED, ED->current_line, &rdl ) ) ) + DelChar ( ED ); /* inside a line */ + else + { /* at the last character */ + j = Next ( ED, ED->current_line ); + if ( j >= 0 ) /* if it is not the last line then delete character unde the cursor */ + DelChar ( ED ); + } + } +} + +/* Delete a character on the left side of the cursor + */ +static void BackSpace( int INS ) +{ + char tmp[ MAX_LINE_LEN + 2 ], tmp1[ MAX_LINE_LEN + 2 ], *w; + long int ww, j, ccc, kk; + int rdl, nLen; + + ED->stable = FALSE; + ED->next_stabil = ED->current_line; + ED->stabil = 1; + ED->dir = DOWN; + ED->current_stabil = ED->cursor_row; + + if( INS ) + { + if( ( ccc = ED->cursor_col+ED->first_col ) > + GetLineLength( ED, ED->current_line, &rdl ) ) + INS = 0; /* cursor is scrolled after the last character in the line - just move the cursor left */ + } + + if( INS ) + { + /* in destructive mode + */ + *tmp ='\x0'; + *tmp1 ='\x0'; + if( (ccc = ED->cursor_col+ED->first_col) > 0 ) + { + /* inside the line */ + MoveText ( ED, ED->current_line + ccc, ED->current_line + ccc - 1, + (ED->bufor_size - (ED->current_line + (long int) ccc + 1))); + Left(); + } + else + { + /* at the beginning of the line */ + if( ED->current_line != ED->first_line ) + { + /* this is not the first line */ + nLen =GetLineLength( ED, ED->current_line, &rdl ); + + if( ED->current_line == ED->last_line ) + if( nLen == 0 ) + ED->last_line = Prev( ED, ED->last_line ); + + /* copy the last line into temporary buffer */ + strncpy( tmp, ED->begin + (unsigned int) ED->current_line, nLen+rdl ); + tmp[ nLen+rdl ] = '\x0'; + + /* find the first space in current line (the new line will + * be wrapped eventually at this position) */ + if( ( w = strchr ( tmp, ' ') ) ) + ww = (int)(w - tmp); + else + ww = nLen+rdl; + + /* go to the previous line */ + j = Prev ( ED, ED->current_line ); + kk = GetLineLength( ED, j, &rdl ); + strncpy( tmp1, ED->begin + (unsigned int) j, (unsigned int)( kk + rdl ) ); + tmp1[ (unsigned int)( kk + rdl ) ] = '\x0'; + Up(); + End( ED ); + + /* the lines can be joined + * the sum of whole length of these lines is smaller then maximal allowed + * or there is a space where the line can be wrapped + */ + if( (ww + kk + rdl - 1) < ( ED->line_length ) ) + { + kk = GetLineLength ( ED, ED->current_line, &rdl ); + j = ED->current_line + kk + rdl; + /* remove separating CRLF characters */ + MoveText( ED, j + 2, j, ED->bufor_size - j - 2 ); + + ED->line_number--; + + j = Next ( ED, ED->last_display ); + if ( j >= 0 ) + ED->last_display = j; + if ( ED->begin[ (unsigned int) ED->last_display + 1 ] == '\x0' ) + ED->last_display = Prev ( ED, ED->last_display ); + + /* split the new line if it is too long */ + format_line( ED, HARD, 0 ); + + j = Next ( ED, ED->current_line ); + if ( j < 0 ) + { + ED->last_display = Prev ( ED, ED->last_display ); + ED->last_line = ED->current_line; + } + ED->stable = FALSE; + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + } + } + } + FormatParagraph ( ED ); + + ED->stable = FALSE; + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + } + else + { + /* non-destructive mode - move cursor only */ + ccc = ED->cursor_col+ED->first_col; + if( ccc > 0 ) + { + Left(); + } + else + { + if( ED->current_line != ED->first_line ) + { + Up(); + End( ED ); + } + } + } +} + + +/* + ** Delete a character on the left side of the cursor +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_BSPACE ) +#else +CLIPPER HB_ED_BSPACE(int INS) +#endif +{ +#ifdef mc51 + int INS; + + INS = _parl(1); /* get current INSERT state */ +#endif + + BackSpace(INS); +} + + +/* Move to the beginning of next non-empty line + */ +static CLIPPER GotoNextNonEmptyLine(void) +{ + int rdl; + + Down( ED ); + Home( ED ); + + while( GetLineLength ( ED, ED->current_line, &rdl ) == 0 ) + { + Down( ED ); + Home( ED ); + if( Next ( ED, ED->current_line ) < 0 ) + break; + } +} + + +/* Move the cursor to the next word + */ +static void NextWord(void) +{ + char *adr; + char tmp[ MAX_LINE_LEN + 2 ]; + int ccc; + unsigned int nEsc, nLen; + + ccc = ED->cursor_col + ED->first_col; + nLen =Clear( ED, ED->current_line, &nEsc ); + + if( nLen < ccc ) + GotoNextNonEmptyLine(); + else + { + *tmp ='\x0'; + strncpy( tmp, ED->begin + (unsigned int) ED->current_line + ccc, + nLen - ED->cursor_col - ED->first_col ); + tmp[ nLen - ED->cursor_col - ED->first_col ] = '\x0'; + if( (adr = strchr ( tmp, ' ' ) ) == NULL ) + { + GotoNextNonEmptyLine(); + if( !ED->stable ) + { + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + } + } + else + { + ED->cursor_col = (int)( adr - tmp + 1 +ED->cursor_col + ED->first_col); + + if(ED->cursor_col > (ED->right - ED->left)) + { + ED->first_col += ED->cursor_col - (ED->right - ED->left); + ED->cursor_col = ED->right - ED->left; + ED->stable = FALSE; + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + } + } + } + + if( ED->begin[ (unsigned int) (ED->current_line + + ED->cursor_col + ED->first_col) ] == ' ') + NextWord(); +} + + +/* + ** Move the cursor to the next word +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_NWORD ) +#else +CLIPPER HB_ED_NWORD(void) +#endif +{ + NextWord(); +} + +/* Move the cursor to the previous word + */ +static void PreviousWord(void) +{ + int pom, i, rdl; + unsigned int nLen, nEsc; + + pom = -1; + nLen =Clear ( ED, ED->current_line, &nEsc ); + if( nLen < ( ED->cursor_col + ED->first_col ) ) + End( ED ); + + if( ( ED->first_col + ED->cursor_col ) == 0 ) + { + Up(); + End( ED ); + } + + for ( i = ED->first_col + ED->cursor_col - 2; i >= 0; i-- ) + { + if ( ED->begin [ (unsigned int) (ED->current_line + i) ] == ' ') + { + pom = i; + break; + } + else + pom = -1; + } + + if(pom < 0) + { + Home( ED ); + while( GetLineLength( ED, ED->current_line, &rdl ) == 0 ) + { + Up(); + Home( ED ); + if( Prev( ED, ED->current_line ) < 0 ) + break; + } + if(!ED->stable) + { + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + } + } + else + { + ED->cursor_col = pom + 1; + if( ED->first_col > 0 ) + { + ED->cursor_col-= ED->first_col; + } + if( ED->cursor_col < 0 ) + { + ED->first_col = ED->cursor_col - (ED->right - ED->left); + ED->stable = FALSE; + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + } + } + + if ( ED->begin [ (unsigned int) (ED->current_line + ED->cursor_col + + ED->first_col) ] == ' ') + PreviousWord(); +} + + +/* + ** Move the cursor to the previous word +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_PWORD ) +#else +CLIPPER HB_ED_PWORD(void) +#endif +{ + PreviousWord(); +} + + +/* Format given line - returns it the line has changed + */ +static int format_line( EDITOR *E, int Karetka, unsigned int LineDl ) +{ + char pom[ MAX_LINE_LEN * 2 ], *p; + int podz, jj, status, i; + long int j; + int rdl = 0; + + if( !LineDl ) + LineDl = GetLineLength( E, E->current_line, &rdl ); + + status = 0; /* the line is not splitted yet */ + if( LineDl > E->line_length ) + { + /* the line is longer then maximal allowed length - + * wrap the line + */ + status = 1; /* the line will be splitted */ + + /* copy maximum allowed bytes form the line into temporary buffer */ + strncpy( pom, E->begin+(unsigned int)E->current_line, + (int)( E->line_length + 10 + rdl ) ); + pom[ (unsigned int)(E->line_length + rdl) ] = '\x0'; + + /* find the last space where the line can be splitted */ + p = strrchr( pom, ' ' ); + if( p ) + { + /* use this position to split the line */ + podz = (int)( p - pom + 1 ); + jj = 1 - podz + E->cursor_col + E->first_col; + } + else + { + /* there is no space in the line - split it at the maximal line length */ + podz = E->line_length; + jj = 1; + } + + j = (long int) (E->current_line + podz ); + MoveText ( E, j, j + 2, E->bufor_size - j - 2 ); + + /* replace with separators */ + E->begin [ (unsigned int) j + 0 ] = (char)Karetka; + E->begin [ (unsigned int) j + 1 ] = '\n'; + E->line_number++; + + if( ( E->cursor_col + E->first_col ) >= podz ) + { + Home( E ); + Down( E ); + for( i = 0; i < jj; i++ ) + Right( E ); + } + else + Right( E ); + } + + return ( status ); +} + +/* Appends the character at the end of line + */ +static int AppendChar( EDITOR *E, int znak, int podz ) +{ + int diff, rdl, status; + long int iPos, nLen; + long int cl; + int ccol, fcol; + char *cNew; + + nLen = GetLineLength ( E, E->current_line, &rdl ); + iPos = E->current_line + nLen ; + diff = E->cursor_col + E->first_col - (int) nLen; + + /* the cursor is positioned 'diff' columns after the last character + * in the line - fill the gap with spaces before appending the character + */ + MoveText ( E, iPos, iPos + diff + 1, E->bufor_size - 1 - iPos - diff ); + memset( E->begin + (unsigned int) (E->current_line + nLen), ' ', diff ); + + /* move the CRLF characters after the appended character */ + cNew =E->begin +iPos +diff; + *cNew++ = (char) znak; + if( *cNew != '\r' ) + *cNew = (char) podz; /* insert requested soft/hard carriage */ + *++cNew = '\n'; + + /* the last line always have to end with the hard carriage return */ + E->begin [ (unsigned int) E->text_length - 2 ] = '\r'; + + status = format_line( E, SOFT, 0 ); + + cl = E->current_line; + ccol = E->cursor_col; + fcol = E->first_col; + + FormatParagraph( E ); + + E->current_line = cl; + E->cursor_col = ccol; + E->first_col = fcol; + + return ( status ); +} + + +/* Checks if there is enough free room in the text buffer + */ +static int Check_length( int iRequested ) +{ + if ( ( ED->text_length + iRequested ) <= ( ED->bufor_size - 8 ) ) + return( 1 ); + else + return( 0 ); +} + + +/* Adjusts the offset of last line + */ +static void SetLastLine( EDITOR *E ) +{ + if ( E->current_line > E->last_line ) + E->last_line = E->current_line ; +} + + +/* Insert or replace the new character into the text buffer + */ +static void PutChar( int INS, int znak ) +{ + long int i, jj, cc; + int rdl; + long int cl; + int ccol, fcol; + + jj = 0; + cc = ED->cursor_col + ED->first_col; /* currnt position in the line */ + if( INS ) + { + /* INSERT is ON */ + if ( Check_length( 1 ) ) + { + /* TODO: add reallocation of text buffer + */ + if( (unsigned int) cc < GetLineLength ( ED, ED->current_line, &rdl ) ) + { + /* the character will be inserted within the line - the cursor + * is placed inside the line + */ + i = ED->current_line + cc; + MoveText( ED, i, i + 1, ED->bufor_size - ED->current_line - cc - 1); + ED->begin [ (unsigned int) i ] = (char) znak; + + jj = format_line( ED, SOFT, 0 ); + + cl = ED->current_line; + ccol = ED->cursor_col; + fcol = ED->first_col; + + FormatParagraph( ED ); + + ED->current_line = cl; + ED->cursor_col = ccol; + ED->first_col = fcol; + + if ( jj ) + SetLastLine( ED ); + } + else /* the cursor is located after the last character in the line */ + jj = AppendChar(ED, znak, SOFT); + + if( !jj ) + Right ( ED ); + else + SetLastLine( ED ); + } + } + else + { + if((long int) cc < (GetLineLength(ED, ED->current_line, &rdl))) + { + ED->begin [ (unsigned int)(ED->current_line + cc) ] = (char)znak; + jj = 0; + Right ( ED ); + } + else + if ( Check_length( 1 ) ) + { + jj = AppendChar(ED, znak, SOFT); + if( !jj ) + Right ( ED ); + else + SetLastLine( ED ); + } + } + + if( !jj ) + if( ( ED->cursor_col + ED->first_col ) > ( ED->right - ED->left ) ) + jj = 1; + + if(jj) + { + ED->stabil = ED->bottom - ED->top + 1; + ED->next_stabil = ED->first_display; + ED->current_stabil = 0; + } + else + { + ED->stabil = 1; + ED->next_stabil = ED->current_line; + ED->current_stabil = ED->cursor_row; + } + + ED->stable = FALSE; + ED->dir = DOWN; +} + + +/* + ** Insert or replace the character into the text buffer +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_PUTCHAR ) +#else +CLIPPER HB_ED_PUTCHAR(int INS, int znak) +#endif +{ +#ifdef mc51 + int INS, znak; + + znak = _parni(1); /* character to paste */ + INS = _parl(2); /* current INSERT state */ +#endif + + PutChar( INS, znak ); +} + + +/* +static void Tab ( int INS ) +{ + if(INS) + for(i=0; itab_size; i++) + PutChar(TRUE, 32); + else + for(i=0; itab_size; i++) + Right(); +} +*/ + +/* + ** +*/ + +/* +#ifdef mc51 +CLIPPER_ACTION( HB_ED_TAB ) +#else +CLIPPER HB_ED_TAB(int INS) +#endif +{ +#ifdef mc51 + int INS = _parl(1); +#endif + + Tab ( INS ); +} +*/ + + + +/* + ** Delete the current line +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_DELLINE ) +#else +CLIPPER HB_ED_DELLINE(void) +#endif +{ + long int tmp, j; + + if( ED->active < ED->line_number ) + { + j = Next ( ED, ED->last_display ); + if ( j >= 0 ) + ED->last_display = j; + + tmp = Next ( ED, ED->current_line ); + if( tmp < 0 ) + tmp = 0; + + ED->stabil = ED->bottom - ED->top + 1 - ED->cursor_row; + ED->dir = DOWN; + + MoveText( ED, tmp, ED->current_line, ED->bufor_size - ED->current_line - 2 ); + + if(ED->line_number > 0) + ED->line_number--; + + ED->next_stabil = ED->current_line; + ED->current_stabil = ED->cursor_row; + ED->stable = FALSE; + + } + else + { + ED->begin [ (unsigned int) ED->current_line + 0 ] = '\r'; + ED->begin [ (unsigned int) ED->current_line + 1 ] = '\n'; + ED->begin [ (unsigned int) ED->current_line + 2 ] = '\x0'; + memset( ED->begin + (unsigned int) ED->current_line + 2, '\x0', + (unsigned int) (ED->bufor_size - strlen (ED->begin )) ); + + ED->last_display = ED->last_line; + ED->stabil = 1; + ED->dir = DOWN; + ED->next_stabil = ED->current_line; + ED->current_stabil = ED->cursor_row; + ED->stable = FALSE; + } + if( ED->text_length == 0 ) + { + ED->begin [ 0 ] = '\r'; + ED->begin [ 1 ] = '\n'; + ED->begin [ 2 ] = '\x0'; + } +} + +/* + ** Delete the word on the right side of the cursor +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_DELWORD ) +#else +CLIPPER HB_ED_DELWORD(void) +#endif +{ + long int pos1, pos2, j; + int cc, fc, cr, rdl; + long int fd, ld; + long int l; + + j = ED->current_line + ED->cursor_col + ED->first_col; + if ( ED->begin [ (unsigned int) j ] != ' ' ) + { + if((unsigned int) ( ED->cursor_col + ED->first_col ) < + (unsigned int) ( GetLineLength ( ED, ED->current_line, &rdl ) )) + { + cc = ED->cursor_col; + cr = ED->cursor_row; + fc = ED->first_col; + fd = ED->first_display; + ld = ED->last_display; + l = ED->current_line; + NextWord(); + pos2 = ED->cursor_col + ED->first_col; + PreviousWord(); + pos1 = ED->cursor_col + ED->first_col; + + ED->current_line = l; + ED->cursor_col = cc; + ED->cursor_row = cr; + ED->first_col = fc; + ED->first_display = fd; + ED->last_display = ld; + + if(pos2 == 0) + pos2 = GetLineLength ( ED, ED->current_line, &rdl ); + + MoveText ( ED, ED->current_line + pos2, ED->current_line + pos1, + ED->bufor_size - ED->current_line - pos2 ); + FormatParagraph ( ED ); + ED->stable = FALSE; + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->dir = DOWN; + ED->current_stabil = 0; + } + else + { + if( ( GetLineLength( ED, ED->current_line, &rdl ) ) == 0 ) + { + HB_ED_DELLINE( ); + Home( ED ); + } + } + } +} + + +/* Insert the CRLF characters + */ +static void Return(int INS) +{ + long int ii, j; + unsigned int nEsc, nLen; + + if( Check_length( 2 ) ) + { + if( INS ) + { + /* only if INSERT state is ON + */ + nLen =Clear( ED, ED->current_line, &nEsc ); + + ED->line_number++; + + j = Next( ED, ED->current_line ); + if ( j < 0 ) + { + ED->last_line =ED->text_length; + ED->text_length +=2; + + ED->begin[ ED->text_length -2 ] = '\r'; + ED->begin[ ED->text_length -1 ] = '\n'; + ED->begin[ ED->text_length ] = '\x0'; + } + else + { + if( (ED->first_col + ED->cursor_col) > nLen+1 ) + End( ED ); + ii = ED->current_line + (long int) ED->first_col + + (long int) ED->cursor_col; + MoveText ( ED, ii, ii + 2, ED->bufor_size - ii - 2 ); + + ED->begin [ (unsigned int) ii + 0 ] = '\r'; + ED->begin [ (unsigned int) ii + 1 ] = '\n'; + if ( ED->last_line == ED->current_line ) + ED->last_line = Next ( ED, ED->current_line ); + } + + if( ED->cursor_row < (ED->bottom - ED->top) ) + { + j = Prev ( ED, ED->last_display ); + if ( j > 0 ) + ED->last_display = j; + + ED->next_stabil = ED->current_line; + ED->stabil = ED->bottom - ED->top + 1 - ED->cursor_row; + ED->current_stabil = ED->cursor_row; + } + else + { + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->current_stabil = 0; + } + } + } + else + { + Clear( ED, ED->current_line, &nEsc ); + j = Next ( ED, ED->current_line ); + if ( j > ED->last_line ) + { + if ( Check_length( 2 ) ) + { + ED->line_number++; + ED->last_line = j; + ED->begin [ (unsigned int) j + 0 ] = '\r'; + ED->begin [ (unsigned int) j + 1 ] = '\n'; + ED->begin [ (unsigned int) j + 2 ] = '\x0'; + } + } + } + if( Check_length( 0 ) ) + { + ED->stable = FALSE; + ED->dir = DOWN; + Down( ED ); + Home( ED ); + } + + if( !ED->stable ) + { + ED->next_stabil = ED->first_display; + ED->stabil = ED->bottom - ED->top + 1; + ED->current_stabil = 0; + ED->dir = DOWN; + } +} + + +/* + ** Insert the CRLF characters +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_RETURN ) +#else +CLIPPER HB_ED_RETURN(int INS) +#endif +{ +#ifdef mc51 + int INS = _parl(1); +#endif + + Return(INS); +} + + +/* + ** Returns the current cursor row inside the editor's window +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_WINROW ) +#else +int HB_ED_WINROW(void) +#endif +{ +#ifdef mc51 + _retni( ED->cursor_row ); +#else + return( ED->cursor_row ); +#endif +} + +/* + ** Returns the line number where the cursor is positioned +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_ROW ) +#else +int HB_ED_ROW(void) +#endif +{ +#ifdef mc51 + _retni( (unsigned int) ED->active ); +#else + return( (unsigned int) ED->active ); +#endif +} + + +/* + ** Return the current cursor column inside the editor's window +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_WINCOL ) +#else +int HB_ED_WINCOL(void) +#endif +{ +#ifdef mc51 + _retni( ED->cursor_col ); +#else + return( ED->cursor_col ); +#endif +} + +/* + ** Returns the current cursor position inside the line +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_COL ) +#else +int HB_ED_COL(void) +#endif +{ +#ifdef mc51 + _retni( ED->cursor_col + ED->first_col + 1 ); +#else + return( ED->cursor_col + ED->first_col + 1 ); +#endif +} + + +/* + ** Returns the total number of lines +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_MAXLINE ) +#else +long int HB_ED_MAXLINE(void) +#endif +{ +#ifdef mc51 + _retni((unsigned int) ED->line_number); +#else + return((unsigned int) ED->line_number); +#endif +} + +/* + ** Counts the total number of lines in passed editor +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_LCOUNT ) +#else +long int HB_ED_LCOUNT(int nEdit) +#endif +{ + EDITOR *E; + +#ifdef mc51 + E = ETab[ _parni(1) ]; + + _retni( (unsigned int) E->line_number ); +#else + E = ETab[ nEdit ]; + + return( (unsigned int) E->line_number ); +#endif +} + + +/* + ** Returns if the editor is correctly displayed +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_STABLE ) +#else +int HB_ED_STABLE(void) +#endif +{ +#ifdef mc51 + _retl( ED->stable ); +#else + return( ED->stable ); +#endif +} + + +/* + ** Returns the number of bytes stored in the text buffer +*/ +#ifdef mc51 +CLIPPER_ACTION( HB_ED_LENGTH ) +#else +long int HB_ED_LENGTH(void) +#endif +{ +#ifdef mc51 + _retni((unsigned int) ED->text_length); +#else + return(ED->text_length); +#endif +} + + +/* + * + ** This is a standalone version of editor for testing + * it requires home made screen library + * +*/ + +#ifndef mc51 + + CLIPPER Ed(EDITOR *E) + { + int l; + unsigned int i; + char *adres, pom[80]; + char *str1, strall[ MAX_LINE_LEN + 2 ], str11[100]; + + str1 = str11; + while((i = READKEY(12)) != 283) + { + switch(i) + { + case UPARR : HB_ED_UP(); + break; + case DNARR : HB_ED_DOWN(); + break; + case 0x51E0u: HB_ED_PGDOWN(); + break; + case 0x49E0u: HB_ED_PGUP(); + break; + case 0x84E0u: HB_ED_TOP(); + break; + case 0x76E0u: HB_ED_BOTTOM(); + break; + case EEE : HB_ED_GOTO( 1L ); + break; + case LTARR : HB_ED_LEFT(); + break; + case RTARR : HB_ED_RIGHT(); + break; + case 0x47E0u: HB_ED_HOME(); + break; + case 0x4FE0u: HB_ED_END(); + break; + case DEL : HB_ED_DELCHAR(); + break; + case 0x0E08u: HB_ED_BSPACE(insert); + break; + case 0x74E0u: HB_ED_NWORD(); + break; + case 0x73E0u: HB_ED_PWORD(); + break; + case 0x1519u: HB_ED_DELLINE(); + break; + case 0x1414u: HB_ED_DELWORD(); + break; + case ENTER : HB_ED_RETURN(insert); + break; + case 33333u : HB_ED_ROW(); + break; + case 44444u : HB_ED_COL(); + break; + case 55555u : HB_ED_STABLE(); + break; + case INSERT : IInsert(); + break; + default : i &= 0xff; + HB_ED_PUTCHAR(insert, i); + break; + } + l= HB_ED_STABILI(); + + strcpy( strall, "col "); + str1 = itoa( E->cursor_col+E->first_col, str1, 10 ); + strcat( strall, str1 ); + strcat( strall, " row " ); + str1 = itoa( E->cursor_row, str1, 10 ); + strcat( strall, str1 ); + strcat( strall, " lines " ); + str1 = itoa( (int)E->line_number, str1, 10 ); + strcat( strall, str1 ); + strcat( strall, " " ); + + DISPXYA( 1, 1, 5, strall ); + + if(insert) + { + str1 = itoa( (int)E->active, str1, 10 ); + strcpy( strall, " INS ON " ); + strcat( strall, str1 ); + DISPXYA( 30, 1, 5, strall ); + } + else + { + str1 = itoa( (int)E->active, str1, 10 ); + strcpy( strall, " INS OFF " ); + strcat( strall, str1 ); + DISPXYA( 30, 1, 5, strall ); + } + str1 = itoa( (int)strlen( E->begin ) , str1, 10 ); + strcpy( strall, " Length=" ); + strcat( strall, str1 ); + strcat( strall, " " ); + DISPXYA( 60, 1, 5, strall ); + + + + strncpy( pom, E->begin, 70 ); + pom[70] = ' '; + pom[71] = '\x0'; + DISPXYA( 1, 21, 5, pom ); + + str1 = ltoa( E->line_number , str1, 10 ); + strcpy( strall, " li " ); + strcat( strall, str1 ); + strcat( strall, " " ); + DISPXYA( 48, 1, 5, strall ); + + SETXY(E->cursor_col+E->left, E->cursor_row+E->top); + } + } + + + void main() + { + int xg, yg, xd, yd, nE, p; + char *aaa; + int mode, page, row, col; + + + + VIDEMODE( &mode, &page, &row, &col ); + + DRAWBOX( 00, 00, 79, 24, 7, 7, "Ŀ;" ); + + xg = 0; + yg = 1; + xd = 79; + yd = 23; + + nE = HB_ED_NEW( 96, 8, 4096l ); + ED = ETab[ nE ]; + + strcpy( name, "test.xxx" ); + p = open ( name, O_RDONLY+O_BINARY ); + adr = calloc( 7000, 1 ); + read ( p, adr, 7000 ); + + close ( p ); + + HB_ED_SETTEXT( nE, adr ); + +// HB_ED_INSTEXT( nE, adr, 0l ); + + DRAWBOX( xg, yg, xd, yd, 14, 14, "Ŀ;" ); + HB_ED_CONFIG( nE, yg+1, xg+1, yd-1, xd-1, 0, 0 ); + HB_ED_STABILI(); + + Ed( ED ); + + HB_ED_KILL(nE); + + } + +#endif diff --git a/harbour/samples/pe/license.txt b/harbour/samples/pe/license.txt new file mode 100644 index 0000000000..524cf3c6dd --- /dev/null +++ b/harbour/samples/pe/license.txt @@ -0,0 +1,60 @@ +/* + + * $Id$ + + */ + + + + 2THE HARBOUR PROJECT LICENSE1 + +3 =========================== + + + + This program is free software; you can redistribute it and/or modify + + it under the terms of the GNU General Public License as published by + + the Free Software Foundation; either version 2 of the License, or + + (at your option) any later version, with one exception: + + + + The exception is that if you link the Harbour Runtime Library (HRL) + + and/or the Harbour Virtual Machine (HVM) with other files to produce + + an executable, this does not by itself cause the resulting executable + + to be covered by the GNU General Public License. Your use of that + + executable is in no way restricted on account of linking the HRL + + and/or HVM code into it. + + + + This program is distributed in the hope that it will be useful, + + but 2WITHOUT ANY WARRANTY1; without even the implied warranty of + + 4MERCHANTABILITY1 or 5FITNESS FOR A PARTICULAR PURPOSE1. See the + + GNU General Public License for more details. + + + + You should have received a copy of the GNU General Public License + + along with this program; if not, write to the Free Software + + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit + + their web site at http://www.gnu.org/). + + + +5This file have to be separated with CR/LF characters1 + diff --git a/harbour/samples/pe/pe.prg b/harbour/samples/pe/pe.prg new file mode 100644 index 0000000000..c7a940cb70 --- /dev/null +++ b/harbour/samples/pe/pe.prg @@ -0,0 +1,41 @@ +/* + * $Id$ + */ +#define EDIT_EDIT .T. +#define EDIT_VIEW .F. + +PROCEDURE MAIN( cFile ) +LOCAL cText +LOCAL lMode:=EDIT_EDIT + + IF( cFile == NIL ) + cFile ="license.txt" + IF( !FILE(cFile) ) + cFile ="../../license.txt" + ENDIF + lMode =EDIT_VIEW + ENDIF + + cText =MEMOREAD( cFile ) + cText =MEMOEDITOR( cText, 0,0, MAXROW(), MAXCOL(), lMode ) + MEMOWRIT( "OUTPUT.TXT", cText ) + +RETURN + +STATIC FUNCTION MEMOEDITOR( cText, nTop, nLeft, nBottom, nRight, lMode ) +LOCAL oED + + /* NOTE: In current design of editor it doesn't reallocate the memory + buffer used to hold the text + */ + oED :=EditorNew( nTop, nLeft, nBottom, nRight, 254, , , , LEN(cText)*2, 168 ) + IF( oED != NIL ) + EditorSetText( oED, cText ) + EditorEdit( oED, lMode, .T. ) + cText :=EditorGetText( oED ) + EditorKill( oED ) + ELSE + ? "Editor not created" + ENDIF + +RETURN( cText ) \ No newline at end of file diff --git a/harbour/samples/pe/readme.txt b/harbour/samples/pe/readme.txt new file mode 100644 index 0000000000..197f0c4e22 --- /dev/null +++ b/harbour/samples/pe/readme.txt @@ -0,0 +1,19 @@ +/* + * $Id$ +*/ +Known bugs: +---------- +1) It requires files separated with CR/LF pairs +2) NextWord() doesn't work correctly +3) If text contains color escape codes then deleting or inserting + of characters doesn't work correctly in the line that contains it + +To fix: +------ +1) All TAB characters are replaced with spaces at startup - if edited file is + very large and contains many TABs then it can take a vary long time - TAB + characters should be left unchanged and interpreted during editing +2) It reformats whole text at startup - again for a very long text it can + take too much time +3) Text buffer shold be reallocated dynamically +4) Remove static table of created editors