* config/linux/clang.mk
! fixed rule for dynamic library
* src/3rd/png/Makefile
+ added -DPNG_ARM_NEON_OPT=0 to build flags
* contrib/3rd/sqlite3/sqlite3.c
* contrib/3rd/sqlite3/sqlite3.diff
! pacified warning
* contrib/gtwvg/gtwvgd.c
* contrib/gtwvg/wvgwing.c
! fixed missing break/return in case statements - please verify it.
* contrib/hbct/dattime3.c
* added #define _DEFAULT_SOURCE necessay in new Linux distors
* contrib/hblzf/3rd/liblzf/liblzf.diff
* contrib/hblzf/3rd/liblzf/lzfP.h
* do not use nested #define in #if statements - some C compilers do not
support it
* contrib/hbssl/bio.c
! tuned #if condition
* contrib/hbmisc/hbeditc.c
* simpliefied for condition and pacified warning
* contrib/hbodbc/hbodbc.hbp
* contrib/sddodbc/sddodbc.hbp
+ added check for iodbc library
* utils/hbmk2/hbmk2.prg
+ added support for clang in android builds
* include/hbdefs.h
+ added check for __BYTE_ORDER__ macro used in some new lib C
implementations
* include/hbapi.h
* include/hbdefs.h
* include/hbstack.h
* include/hbvmpub.h
* src/vm/classes.c
* src/vm/dynsym.c
* src/vm/estack.c
* src/vm/memvars.c
+ extended the size of dynamic symbol table from 65535 to 4294967295.
Adopting class code I decided to keep current algorithm of method indexes
hashing with only some minor modifications. It's very fast anyhow it may
cause noticeable (though static) quite big memory allocation for class
definitions in applications using millions of symbols and which increase
dynamic symbol table at runtime loading new classes dynamically form .hrb,
.dll, .so or other dynamic libraries supported by Harbour. It's random
and rather impossible to exploit situation in real life anyhow I cannot
exclude it so I'd like to report it in ChangeLog. The solution is very
simple, i.e. it's enough to use classic divide et impera algorithm using
symbol numbers to find method definition anyhow it will be slower then
current one and address only very seldom hypothetical situations so I
decided to not implement it. Such static memory cost begins to be
completely unimportant in the world of 64-bit architectures and extremely
big memory address space.
The modification was sponsored by TRES company.
* src/vm/estack.c
! fixed __mvClear() in MT builds - due to stupid typo GetList variable
was removed in MT programs by CLEAR MEMORY command (__mvClear())
So far noone reported it and I've found it analyzing the code before
increasing symbol table size.
* contrib/hbwin/hbolesrv.c
* updated for new size of dynamic symbol table
2605 lines
70 KiB
C
2605 lines
70 KiB
C
/* Copyright 1999 Ryszard Glab */
|
|
|
|
/* 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
|
|
4) Doesn't handle OS-specific EOL (only CRLG)
|
|
5) Unicode support
|
|
|
|
FIXME:
|
|
|
|
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 should be reallocated dynamically
|
|
*/
|
|
|
|
#include "hbapi.h"
|
|
#include "hbapifs.h"
|
|
#include "hbapigt.h"
|
|
#include "hbapierr.h"
|
|
|
|
#define _STABILIZE_UP 1
|
|
#define _STABILIZE_DOWN 0
|
|
|
|
#define _MAX_LINE_LEN 4096
|
|
|
|
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 */
|
|
HB_ISIZ line_length; /* maximal line length */
|
|
HB_ISIZ line_number; /* the number of lines stored in text buffer */
|
|
HB_ISIZ current_line; /* the offset in memory buffer where the current line starts (where the cursor is positioned) */
|
|
HB_ISIZ first_line; /* offset of the first line (usually 0) */
|
|
HB_ISIZ last_line; /* the offset in memory buffer of the last line */
|
|
int cursor_row; /* current cursor row in the window */
|
|
HB_ISIZ cursor_col; /* current cursor column in the window */
|
|
HB_ISIZ first_display; /* the offset of first visible (displayed) line */
|
|
HB_ISIZ last_display; /* the offset of last visible line */
|
|
HB_ISIZ first_col; /* first visible column */
|
|
HB_BOOL fStable; /* is the editor stabilized? */
|
|
int current_stabil; /* currently displayed row (during stabilization) */
|
|
int stabil; /* number of rows to stabilize */
|
|
char escape; /* ASCII code of color escape character (the next character after this will be used as color index */
|
|
HB_ISIZ 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 */
|
|
HB_ISIZ active; /* the line number where the cursor is positioned */
|
|
HB_BOOL fIsConfigured;
|
|
HB_ISIZ next_line; /* the offset of next line to return by ED_GetNextLine() */
|
|
HB_ISIZ text_length; /* the size (in bytes) of edited text */
|
|
HB_ISIZ buffer_size; /* the size of allocated memory buffer */
|
|
char * begin; /* the memory buffer */
|
|
|
|
} HB_EDITOR, * PHB_EDITOR;
|
|
|
|
static void KillText( PHB_EDITOR pEd );
|
|
static HB_ISIZ Clear( PHB_EDITOR pEd, HB_ISIZ e, HB_ISIZ * nEsc );
|
|
static void BackSpace( PHB_EDITOR pEd, HB_BOOL fInsert );
|
|
static void NextWord( PHB_EDITOR pEd );
|
|
static void Return( PHB_EDITOR pEd, HB_BOOL fInsert );
|
|
static void GoTo( PHB_EDITOR pEd, HB_ISIZ line );
|
|
static HB_BOOL format_line( PHB_EDITOR pEd, char Karetka, HB_ISIZ LineDl );
|
|
static void MoveText( PHB_EDITOR pEd, HB_ISIZ source, HB_ISIZ dest, HB_ISIZ ilb );
|
|
static HB_ISIZ GetLineLength( PHB_EDITOR pEd, HB_ISIZ off, HB_ISIZ * wsk );
|
|
|
|
static HB_GARBAGE_FUNC( PHB_EDITOR_release )
|
|
{
|
|
void ** ph = ( void ** ) Cargo;
|
|
|
|
/* Check if pointer is not NULL to avoid multiple freeing */
|
|
if( ph && *ph )
|
|
{
|
|
/* Destroy the object */
|
|
|
|
KillText( ( PHB_EDITOR ) *ph );
|
|
hb_xfree( ( ( PHB_EDITOR ) *ph )->begin );
|
|
hb_xfree( ( PHB_EDITOR ) *ph );
|
|
|
|
/* set pointer to NULL just in case */
|
|
*ph = NULL;
|
|
}
|
|
}
|
|
|
|
static const HB_GC_FUNCS s_gcPHB_EDITOR_funcs =
|
|
{
|
|
PHB_EDITOR_release,
|
|
hb_gcDummyMark
|
|
};
|
|
|
|
static void PHB_EDITOR_ret( PHB_EDITOR p )
|
|
{
|
|
if( p )
|
|
{
|
|
void ** ph = ( void ** ) hb_gcAllocate( sizeof( PHB_EDITOR * ), &s_gcPHB_EDITOR_funcs );
|
|
|
|
*ph = p;
|
|
|
|
hb_retptrGC( ph );
|
|
}
|
|
else
|
|
hb_retptr( NULL );
|
|
}
|
|
|
|
static PHB_EDITOR PHB_EDITOR_par( int iParam )
|
|
{
|
|
void ** ph = ( void ** ) hb_parptrGC( &s_gcPHB_EDITOR_funcs, iParam );
|
|
|
|
return ph ? ( PHB_EDITOR ) *ph : NULL;
|
|
}
|
|
|
|
/* Find the beginning of previous line starting from given offset */
|
|
static HB_ISIZ Prev( PHB_EDITOR pEd, HB_ISIZ adres )
|
|
{
|
|
if( adres > 0 )
|
|
{
|
|
HB_ISIZ i;
|
|
|
|
for( i = adres - 3; i >= 0; i-- )
|
|
{
|
|
if( pEd->begin[ i ] == '\n' )
|
|
return i + 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/* Find the beginning of next line starting from given offset */
|
|
static HB_ISIZ Next( PHB_EDITOR pEd, HB_ISIZ adres )
|
|
{
|
|
char * tmp;
|
|
|
|
tmp = strchr( pEd->begin + adres, '\n' );
|
|
|
|
if( tmp && tmp[ 1 ] )
|
|
return ++tmp - pEd->begin;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/* Initializes HB_EDITOR structure */
|
|
static void New( PHB_EDITOR pEd, int tab, HB_ISIZ ll, HB_ISIZ bufferSize )
|
|
{
|
|
|
|
pEd->line_length = ll;
|
|
pEd->first_line = 0;
|
|
pEd->last_line = 0;
|
|
pEd->current_line = 0;
|
|
pEd->first_display = 0;
|
|
pEd->last_display = 0;
|
|
pEd->cursor_row = 0;
|
|
pEd->cursor_col = 0;
|
|
pEd->first_col = 0;
|
|
pEd->stabil = 0;
|
|
pEd->current_stabil = 0;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->tab_size = tab;
|
|
pEd->active = 1;
|
|
pEd->line_number = 0;
|
|
pEd->fIsConfigured = HB_FALSE;
|
|
pEd->text_length = 0;
|
|
pEd->buffer_size = bufferSize;
|
|
|
|
pEd->begin[ 0 ] = '\r';
|
|
pEd->begin[ 1 ] = '\n';
|
|
pEd->begin[ 2 ] = '\0';
|
|
|
|
}
|
|
|
|
/* Creates new editor and returns index into internal editors table */
|
|
HB_FUNC( ED_NEW )
|
|
{
|
|
PHB_EDITOR pEd = ( PHB_EDITOR ) hb_xgrab( sizeof( HB_EDITOR ) );
|
|
|
|
HB_ISIZ ll;
|
|
int tab = hb_parni( 2 );
|
|
HB_ISIZ bufferSize;
|
|
|
|
ll = hb_parns( 1 );
|
|
if( ll > _MAX_LINE_LEN )
|
|
ll = _MAX_LINE_LEN;
|
|
|
|
bufferSize = HB_ISNUM( 3 ) ? hb_parns( 3 ) + 10 : 32767;
|
|
if( bufferSize <= 0 )
|
|
bufferSize = 32767;
|
|
|
|
pEd->escape = ( char ) hb_parni( 4 );
|
|
pEd->begin = ( char * ) hb_xgrab( bufferSize + 100 );
|
|
memset( pEd->begin, '\0', bufferSize );
|
|
|
|
New( pEd, tab, ll, bufferSize );
|
|
|
|
PHB_EDITOR_ret( pEd );
|
|
}
|
|
|
|
/* Replaces TAB with spaces and removes spaces from the end of line */
|
|
static void FormatText( PHB_EDITOR pEd )
|
|
{
|
|
HB_ISIZ dl;
|
|
char * wsk;
|
|
int i;
|
|
HB_ISIZ nEsc;
|
|
|
|
dl = pEd->current_line;
|
|
pEd->current_line = pEd->last_line;
|
|
|
|
/* TODO: remove this TAB replacement because it is time consuming
|
|
operation if a very large file is edited */
|
|
wsk = pEd->begin + pEd->last_line;
|
|
while( ( wsk = strchr( wsk, '\t' ) ) != 0 )
|
|
{
|
|
HB_ISIZ j = wsk - pEd->begin;
|
|
|
|
MoveText( pEd, j, j + pEd->tab_size - 1,
|
|
pEd->buffer_size - j - pEd->tab_size + 1 );
|
|
|
|
for( i = 0; i < pEd->tab_size; i++, wsk++ )
|
|
*wsk = ' ';
|
|
}
|
|
|
|
/* TODO: optimize this line formatting - format line only if
|
|
it will be displayed */
|
|
while( pEd->current_line >= 0 )
|
|
{
|
|
HB_ISIZ nLen;
|
|
|
|
pEd->last_line = pEd->current_line;
|
|
pEd->line_number++;
|
|
|
|
nLen = Clear( pEd, pEd->current_line, &nEsc );
|
|
|
|
if( ! format_line( pEd, HB_CHAR_HARD1, nLen ) )
|
|
pEd->current_line = Next( pEd, pEd->current_line );
|
|
}
|
|
|
|
pEd->current_line = dl;
|
|
pEd->first_col = 0;
|
|
}
|
|
|
|
/* Resets the editor state after pasting new content of text buffer */
|
|
static void NewText( PHB_EDITOR pEd )
|
|
{
|
|
HB_ISIZ dl;
|
|
int i;
|
|
|
|
/* text in buffer have to end with CR/LF */
|
|
dl = pEd->text_length;
|
|
if( pEd->begin[ dl - 1 ] != '\n' )
|
|
{
|
|
pEd->begin[ dl ] = '\r';
|
|
pEd->begin[ dl + 1 ] = '\n';
|
|
pEd->begin[ dl + 2 ] = '\0';
|
|
pEd->text_length += 2;
|
|
}
|
|
|
|
FormatText( pEd );
|
|
|
|
pEd->cursor_col = 0;
|
|
pEd->cursor_row = 0;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->current_stabil = 0;
|
|
pEd->first_display = pEd->last_display = 0;
|
|
pEd->next_stabil = 0;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
|
|
for( i = 0; i < pEd->stabil; i++ )
|
|
pEd->last_display = Next( pEd, pEd->last_display );
|
|
}
|
|
|
|
/* Appends passed text to the existing text buffer */
|
|
static void AddText( PHB_EDITOR pEd, const char * adres )
|
|
{
|
|
HB_ISIZ dl, dlold;
|
|
|
|
dl = strlen( adres );
|
|
dlold = pEd->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 ) <= ( pEd->buffer_size - 10 ) )
|
|
{
|
|
/* there is enough room in text buffer */
|
|
hb_strncpy( pEd->begin + dlold, adres, dl );
|
|
pEd->text_length += dl;
|
|
}
|
|
else
|
|
{
|
|
hb_strncpy( pEd->begin + dlold, adres, pEd->buffer_size - 10 - dlold );
|
|
pEd->text_length = pEd->buffer_size - 10;
|
|
}
|
|
|
|
NewText( pEd ); /* reformat text */
|
|
}
|
|
|
|
/* Appends passed text at the end of existing one */
|
|
HB_FUNC( ED_ADDTEXT )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
AddText( pEd, hb_parcx( 2 ) );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Moves text from one location into another */
|
|
static void MoveText( PHB_EDITOR pEd, HB_ISIZ source, HB_ISIZ dest, HB_ISIZ ilb )
|
|
{
|
|
HB_ISIZ diff;
|
|
|
|
diff = dest - source;
|
|
/* memmove supports overlapped buffers */
|
|
memmove( pEd->begin + dest, pEd->begin + source, ilb );
|
|
|
|
if( pEd->last_display > pEd->current_line )
|
|
pEd->last_display += diff;
|
|
|
|
if( pEd->current_line < pEd->last_line )
|
|
pEd->last_line += diff;
|
|
|
|
pEd->text_length += diff;
|
|
|
|
if( pEd->text_length > ( pEd->buffer_size - 8 ) )
|
|
{
|
|
pEd->text_length = pEd->buffer_size - 8;
|
|
pEd->begin[ pEd->text_length ] = '\0';
|
|
pEd->begin[ pEd->text_length - 1 ] = '\n';
|
|
pEd->begin[ pEd->text_length - 2 ] = '\r';
|
|
}
|
|
}
|
|
|
|
/* Skips to the beginning of given line */
|
|
static HB_ISIZ GoToLine( PHB_EDITOR pEd, HB_ISIZ linia )
|
|
{
|
|
char * p;
|
|
HB_ISIZ i;
|
|
|
|
i = 0;
|
|
p = pEd->begin;
|
|
while( ( ++i <= linia ) && ( p = strchr( p, '\n' ) ) != 0 )
|
|
p += 2;
|
|
|
|
if( i > linia )
|
|
return p - pEd->begin - 1;
|
|
else
|
|
return pEd->text_length; /* no such line number - go to the end */
|
|
}
|
|
|
|
/* Counts the number of printable characters in given line */
|
|
static HB_ISIZ GetLineLength( PHB_EDITOR pEd, HB_ISIZ off, HB_ISIZ * wsk )
|
|
{
|
|
HB_ISIZ i;
|
|
char * p;
|
|
char * tmp;
|
|
|
|
tmp = pEd->begin + off;
|
|
p = strchr( tmp, '\n' ); /* find EOL starting from given position */
|
|
|
|
if( p )
|
|
{
|
|
off = ( p - tmp );
|
|
i = off - 1;
|
|
}
|
|
else
|
|
i = strlen( tmp );
|
|
|
|
*wsk = 0; /* number of characters used in color escape codes */
|
|
if( pEd->escape )
|
|
{
|
|
HB_ISIZ j;
|
|
for( j = 0; j < i; j++ )
|
|
{
|
|
if( tmp[ j ] == pEd->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 HB_ISIZ InsText( PHB_EDITOR pEd, char * adres, HB_ISIZ line )
|
|
{
|
|
HB_ISIZ dl = strlen( adres ); /* length of text to insert */
|
|
HB_ISIZ dl1 = pEd->text_length; /* length of text that is currently in the buffer */
|
|
|
|
/* TODO: add reallocation of text buffer */
|
|
if( dl1 < ( pEd->buffer_size - 10 ) )
|
|
{
|
|
HB_BOOL addCRLF = HB_FALSE;
|
|
HB_ISIZ off, il;
|
|
HB_ISIZ cc;
|
|
|
|
/* there is some free space in text buffer */
|
|
|
|
/* Find the offset of given line */
|
|
if( line > 0 )
|
|
off = GoToLine( pEd, line ); /* Find the offset of given line */
|
|
else
|
|
off = 0;
|
|
|
|
if( ( dl + dl1 ) < ( pEd->buffer_size - 10 ) )
|
|
{
|
|
/* there is enough free room in text buffer */
|
|
if( adres[ dl - 1 ] != '\n' && adres[ 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 = HB_TRUE;
|
|
dl += 2;
|
|
}
|
|
MoveText( pEd, off, off + dl, pEd->buffer_size - ( off - 1 ) - dl );
|
|
hb_strncpy( pEd->begin + off, adres, dl );
|
|
}
|
|
else
|
|
{
|
|
/* not enough free space
|
|
text at the end of existing text buffer will be lost */
|
|
dl = pEd->buffer_size - 10 - dl1;
|
|
if( adres[ dl - 1 ] == '\r' )
|
|
adres[ dl - 1 ] = ' ';
|
|
|
|
if( adres[ dl - 1 ] != '\n' && adres[ dl - 2 ] != '\r' )
|
|
{
|
|
addCRLF = HB_TRUE;
|
|
dl += 2;
|
|
}
|
|
MoveText( pEd, off, off + dl, pEd->buffer_size - ( off - 1 ) - dl );
|
|
hb_strncpy( pEd->begin + off, adres, dl );
|
|
}
|
|
|
|
if( addCRLF )
|
|
{
|
|
pEd->begin[ off + dl - 2 ] = '\r';
|
|
pEd->begin[ off + dl - 1 ] = '\n';
|
|
pEd->text_length += 2;
|
|
}
|
|
|
|
if( ( off + dl ) == pEd->text_length )
|
|
pEd->begin[ pEd->text_length ] = '\0';
|
|
pEd->text_length = strlen( pEd->begin );
|
|
|
|
il = pEd->line_number;
|
|
cc = pEd->cursor_col;
|
|
|
|
FormatText( pEd );
|
|
|
|
pEd->cursor_col = cc;
|
|
|
|
if( off <= pEd->current_line )
|
|
{
|
|
pEd->current_line += pEd->text_length - dl1;
|
|
pEd->active += pEd->line_number - il;
|
|
}
|
|
}
|
|
|
|
return dl;
|
|
}
|
|
|
|
/* Inserts passed text into text buffer */
|
|
HB_FUNC( ED_INSTEXT )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
HB_ISIZ dl;
|
|
|
|
char * adres = hb_strdup( hb_parc( 2 ) );
|
|
HB_ISIZ linia = hb_parns( 3 );
|
|
|
|
dl = InsText( pEd, adres, linia );
|
|
pEd->last_line = Prev( pEd, strlen( pEd->begin ) );
|
|
|
|
hb_retns( dl );
|
|
|
|
hb_xfree( adres );
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Selects the editor as active - all next ED_*() calls will be send
|
|
to this editor. */
|
|
HB_FUNC( ED_CONFIG )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
int szer, wys;
|
|
int nwys;
|
|
HB_ISIZ j;
|
|
|
|
int top, left, bottom, right;
|
|
int nRow, nCol;
|
|
int i;
|
|
|
|
top = hb_parni( 2 );
|
|
left = hb_parni( 3 );
|
|
bottom = hb_parni( 4 );
|
|
right = hb_parni( 5 );
|
|
nRow = hb_parni( 6 );
|
|
nCol = hb_parni( 7 );
|
|
|
|
szer = pEd->right - pEd->left + 1;
|
|
wys = pEd->bottom - pEd->top + 1;
|
|
|
|
pEd->top = top;
|
|
pEd->left = left;
|
|
pEd->bottom = bottom;
|
|
pEd->right = right;
|
|
|
|
pEd->last_display = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
|
|
if( pEd->fIsConfigured )
|
|
{
|
|
/* In event driven world the position and size of the editor window can
|
|
change between activations - recalculate some required values */
|
|
pEd->first_display = pEd->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 < pEd->cursor_row; i++ )
|
|
{
|
|
j = Prev( pEd, pEd->first_display );
|
|
if( j >= 0 )
|
|
pEd->first_display = j;
|
|
else
|
|
pEd->cursor_row--;
|
|
if( pEd->cursor_row < 0 )
|
|
pEd->cursor_row = 0;
|
|
}
|
|
|
|
/* find the last line for display */
|
|
for( i = 0; i < pEd->bottom - pEd->top; i++ )
|
|
{
|
|
j = Next( pEd, pEd->last_display );
|
|
if( j >= 0 )
|
|
pEd->last_display = j;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pEd->first_display = pEd->first_line;
|
|
|
|
/* find the last line for display */
|
|
nwys = pEd->bottom - pEd->top;
|
|
for( i = 0; i < nwys; i++ )
|
|
{
|
|
j = Next( pEd, pEd->last_display );
|
|
if( j >= 0 )
|
|
pEd->last_display = j;
|
|
}
|
|
/* check if this line is empty */
|
|
if( strlen( pEd->begin + pEd->last_display ) == 0 )
|
|
pEd->last_display = Prev( pEd, pEd->last_display );
|
|
|
|
/* set initial cursor position in the window */
|
|
pEd->cursor_row = nRow;
|
|
pEd->cursor_col = nCol;
|
|
}
|
|
|
|
if( pEd->fIsConfigured )
|
|
{
|
|
int nszer;
|
|
int diff;
|
|
|
|
nszer = pEd->right - pEd->left + 1;
|
|
nwys = pEd->bottom - pEd->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( pEd->first_col > diff )
|
|
{
|
|
pEd->first_col -= diff;
|
|
pEd->cursor_col += diff;
|
|
}
|
|
else
|
|
{
|
|
pEd->cursor_col += pEd->first_col;
|
|
pEd->first_col = 0;
|
|
}
|
|
}
|
|
if( szer > nszer ) /* current width of the window is smaller then during previous activation */
|
|
{
|
|
if( pEd->cursor_col > ( nszer - 1 ) )
|
|
{
|
|
pEd->first_col += pEd->cursor_col - nszer + 1;
|
|
pEd->cursor_col = nszer - 1;
|
|
}
|
|
}
|
|
|
|
diff = abs( nwys - wys );
|
|
if( wys > nwys )
|
|
{
|
|
HB_ISIZ tmp;
|
|
/* current height of the window is smaller then during previous activation */
|
|
if( pEd->cursor_row < nwys )
|
|
{
|
|
/* the old cursor row position is smaller then the window height */
|
|
tmp = pEd->last_display;
|
|
for( i = 0; i < diff; i++ )
|
|
{
|
|
j = Prev( pEd, tmp );
|
|
if( j >= 0 )
|
|
tmp = j;
|
|
|
|
}
|
|
pEd->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 */
|
|
pEd->last_display = pEd->current_line;
|
|
tmp = pEd->last_display;
|
|
|
|
for( i = 0; i < nwys - 1; i++ )
|
|
{
|
|
j = Prev( pEd, tmp );
|
|
if( j >= 0 )
|
|
tmp = j;
|
|
}
|
|
pEd->first_display = tmp;
|
|
pEd->cursor_row = nwys - 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pEd->current_line = pEd->first_line;
|
|
pEd->active = 1;
|
|
}
|
|
|
|
pEd->fIsConfigured = HB_TRUE;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->current_stabil = 0;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Returns current text buffer */
|
|
HB_FUNC( ED_GETTEXT )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
HB_ISIZ dl;
|
|
char * buffer;
|
|
char * help;
|
|
|
|
char mietka = ( char ) hb_parni( 2 );
|
|
|
|
dl = strlen( pEd->begin ) + 3;
|
|
|
|
buffer = ( char * ) hb_xgrab( dl + 3 );
|
|
|
|
hb_strncpy( buffer, pEd->begin, dl - 1 );
|
|
|
|
help = buffer;
|
|
if( mietka != HB_CHAR_SOFT1 )
|
|
{
|
|
while( help != NULL )
|
|
{
|
|
help = strstr( buffer, "\x8D\n" ); /* Chr( 141 ) + Chr( 10 ) */
|
|
if( help )
|
|
help[ 0 ] = '\r';
|
|
}
|
|
}
|
|
|
|
hb_retc_buffer( buffer );
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Returns given line of text and positions caret at the beginning of next line */
|
|
HB_FUNC( ED_GETLINE )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
HB_ISIZ l;
|
|
HB_ISIZ tmp;
|
|
HB_ISIZ i;
|
|
|
|
HB_ISIZ linia = hb_parns( 2 );
|
|
|
|
l = 1;
|
|
tmp = pEd->first_line;
|
|
for( i = 1; i < linia; i++ )
|
|
{
|
|
HB_ISIZ j = Next( pEd, tmp );
|
|
if( j >= 0 )
|
|
{
|
|
tmp = j;
|
|
l++;
|
|
}
|
|
}
|
|
|
|
if( l == linia )
|
|
{
|
|
HB_ISIZ dl;
|
|
HB_ISIZ rdl;
|
|
|
|
dl = GetLineLength( pEd, tmp, &rdl );
|
|
|
|
hb_retclen( pEd->begin + tmp, dl );
|
|
}
|
|
else
|
|
hb_retc_null();
|
|
|
|
pEd->next_line = Next( pEd, tmp );
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Returns current line pointed by caret position and advances it to the beginning of next line */
|
|
HB_FUNC( ED_GETNEXT )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
if( pEd->next_line > 0 )
|
|
{
|
|
HB_ISIZ rdl;
|
|
HB_ISIZ dl;
|
|
|
|
dl = GetLineLength( pEd, pEd->next_line, &rdl );
|
|
|
|
hb_retclen( pEd->begin + pEd->next_line, dl );
|
|
|
|
pEd->next_line = Next( pEd, pEd->next_line );
|
|
}
|
|
else
|
|
hb_ret();
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Resets text buffer */
|
|
static void KillText( PHB_EDITOR pEd )
|
|
{
|
|
memset( pEd->begin, '\0', pEd->buffer_size );
|
|
pEd->first_line = pEd->last_line = 0;
|
|
}
|
|
|
|
/* Stores new text into editor */
|
|
HB_FUNC( ED_SETTEXT )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
KillText( pEd );
|
|
|
|
New( pEd, pEd->tab_size, pEd->line_length, pEd->buffer_size );
|
|
|
|
AddText( pEd, hb_parcx( 2 ) );
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Reads a text from the file */
|
|
HB_FUNC( ED_READTEXT )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
HB_BOOL lSuccess = HB_FALSE;
|
|
HB_FHANDLE nFile;
|
|
HB_ISIZ nSize;
|
|
HB_FOFFSET nRead;
|
|
HB_FOFFSET nSeek;
|
|
|
|
KillText( pEd );
|
|
New( pEd, pEd->tab_size, pEd->line_length, pEd->buffer_size );
|
|
|
|
nFile = hb_numToHandle( hb_parnint( 2 ) );
|
|
nSeek = hb_parnint( 3 );
|
|
nSize = hb_parns( 4 );
|
|
|
|
nRead = hb_fsSeekLarge( nFile, nSeek, FS_SET );
|
|
if( nRead == nSeek )
|
|
{
|
|
if( nSize > ( pEd->buffer_size - 10 ) )
|
|
nSize = pEd->buffer_size - 10;
|
|
|
|
nSize = hb_fsReadLarge( nFile, pEd->begin, nSize );
|
|
pEd->begin[ nSize ] = '\0';
|
|
|
|
pEd->text_length = nSize;
|
|
|
|
NewText( pEd );
|
|
|
|
lSuccess = HB_TRUE;
|
|
pEd->fStable = HB_FALSE;
|
|
}
|
|
|
|
hb_retl( lSuccess );
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Stabilize the editor
|
|
Redisplays all requested lines
|
|
It is similar to TBrowse:forceStable()
|
|
Incremental stabilization was too slow */
|
|
HB_FUNC( ED_STABILIZE )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
int nRow = 0;
|
|
int nLeft, nTop;
|
|
HB_ISIZ nEscLen, nLen, i, j, e;
|
|
char * EscPtr;
|
|
char * cPtr;
|
|
char adres[ _MAX_LINE_LEN + 2 ];
|
|
|
|
while( --pEd->stabil >= 0 )
|
|
{
|
|
/* there are some lines of text to display */
|
|
HB_ISIZ width = pEd->right - pEd->left + 1;
|
|
|
|
if( pEd->next_stabil >= 0 )
|
|
{
|
|
cPtr = pEd->begin + pEd->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( pEd->escape && *cPtr == pEd->escape )
|
|
nEscLen += 2;
|
|
}
|
|
j = nLen - nEscLen; /* length of printable text */
|
|
adres[ nLen ] = '\0';
|
|
|
|
if( pEd->first_col >= j )
|
|
adres[ nEscLen = nLen = 0 ] = '\0'; /* first visible column is greater then line length */
|
|
|
|
else if( pEd->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;
|
|
i = 0;
|
|
if( pEd->escape )
|
|
{
|
|
for( i = 0; i < ( pEd->first_col + e ); i++ )
|
|
{
|
|
if( adres[ i ] == pEd->escape )
|
|
{
|
|
adres[ 0 ] = adres[ i ];
|
|
adres[ 1 ] = adres[ ++i ];
|
|
e += 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( e )
|
|
{
|
|
nLen -= ( i - 2 );
|
|
if( adres[ i - 1 ] == pEd->escape )
|
|
{
|
|
i++;
|
|
nLen--;
|
|
}
|
|
hb_strncpy( adres + 2, adres + i, nLen - 2 );
|
|
nEscLen -= ( e - 2 );
|
|
}
|
|
else
|
|
{
|
|
nLen -= pEd->first_col;
|
|
hb_strncpy( adres, adres + pEd->first_col, nLen );
|
|
}
|
|
adres[ nLen ] = '\0';
|
|
}
|
|
|
|
if( nLen )
|
|
{
|
|
if( adres[ nLen - 1 ] & '\xd' ) /* soft or hard carriage */
|
|
adres[ --nLen ] = '\0';
|
|
}
|
|
|
|
/* find next line for displaying */
|
|
switch( pEd->dir )
|
|
{
|
|
case _STABILIZE_DOWN:
|
|
pEd->next_stabil = Next( pEd, pEd->next_stabil );
|
|
nRow = pEd->current_stabil++;
|
|
break;
|
|
|
|
case _STABILIZE_UP:
|
|
pEd->next_stabil = Prev( pEd, pEd->next_stabil );
|
|
nRow = pEd->current_stabil--;
|
|
break;
|
|
}
|
|
|
|
hb_gtColorSelect( 0 ); /* select default color */
|
|
|
|
nTop = pEd->top + nRow;
|
|
if( nLen )
|
|
{
|
|
if( pEd->escape && ( EscPtr = strchr( adres, pEd->escape ) ) != 0 )
|
|
{
|
|
i = EscPtr - adres;
|
|
nLeft = ( int ) ( pEd->left + i );
|
|
|
|
if( i )
|
|
hb_gtWriteAt( nTop, pEd->left, adres, ( width < i ) ? width : i );
|
|
|
|
for(; i < nLen && nLeft <= pEd->right; i++ )
|
|
{
|
|
if( adres[ i ] == pEd->escape )
|
|
hb_gtColorSelect( ( adres[ ++i ] & 0x0F ) - 1 );
|
|
else
|
|
hb_gtWriteAt( nTop, nLeft++, adres + i, 1 );
|
|
}
|
|
}
|
|
else
|
|
hb_gtWriteAt( nTop, pEd->left, adres, ( ( width < nLen ) ? width : nLen ) );
|
|
}
|
|
|
|
/* fill the rest of the row with spaces */
|
|
if( ( nLen - nEscLen ) < width )
|
|
hb_gtRepChar( nTop, ( int ) ( pEd->left + nLen - nEscLen ), ' ', width - nLen + nEscLen );
|
|
}
|
|
else
|
|
{
|
|
/* no more lines of text to display - fill the window with spaces */
|
|
switch( pEd->dir )
|
|
{
|
|
case _STABILIZE_DOWN:
|
|
nRow = pEd->current_stabil++;
|
|
break;
|
|
case _STABILIZE_UP:
|
|
nRow = pEd->current_stabil--;
|
|
break;
|
|
}
|
|
|
|
hb_gtColorSelect( 0 );
|
|
hb_gtRepChar( pEd->top + nRow, pEd->left, ' ', width );
|
|
}
|
|
|
|
hb_gtColorSelect( 0 );
|
|
}
|
|
|
|
pEd->fStable = HB_TRUE;
|
|
|
|
hb_retni( nRow );
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Removes trailing spaces from the end of line */
|
|
static HB_ISIZ Clear( PHB_EDITOR pEd, HB_ISIZ e, HB_ISIZ * nEsc )
|
|
{
|
|
HB_ISIZ nLen, i;
|
|
|
|
nLen = GetLineLength( pEd, e, nEsc );
|
|
i = e + nLen + *nEsc;
|
|
|
|
if( i )
|
|
{
|
|
while( pEd->begin[ i - 1 ] == ' ' )
|
|
{
|
|
if( pEd->cursor_col > 0 )
|
|
pEd->cursor_col--;
|
|
|
|
else if( pEd->first_col > 0 )
|
|
pEd->first_col--;
|
|
|
|
MoveText( pEd, i, i - 1, pEd->text_length - i + 3 );
|
|
nLen--;
|
|
}
|
|
}
|
|
|
|
return nLen;
|
|
}
|
|
|
|
/* Moves the cursor to the next line of text */
|
|
static void Down( PHB_EDITOR pEd )
|
|
{
|
|
HB_ISIZ j;
|
|
HB_ISIZ nEsc;
|
|
|
|
j = Next( pEd, pEd->current_line ); /* find the offset of next line */
|
|
if( pEd->begin[ j ] == '\0' )
|
|
j = -1; /* no more lines */
|
|
if( j < 0 )
|
|
{
|
|
pEd->fStable = HB_TRUE;
|
|
}
|
|
else
|
|
{
|
|
pEd->active++;
|
|
Clear( pEd, pEd->current_line, &nEsc );
|
|
|
|
j = Next( pEd, pEd->current_line );
|
|
|
|
if( j >= 0 )
|
|
pEd->current_line = j;
|
|
|
|
if( ( ( ++pEd->cursor_row ) + pEd->top ) > pEd->bottom )
|
|
{
|
|
/* attempt to move to the line that was not visible yet */
|
|
pEd->stabil = 1; /* only one line needs to be redisplayed */
|
|
|
|
pEd->cursor_row = pEd->bottom - pEd->top;
|
|
pEd->first_display = Next( pEd, pEd->first_display );
|
|
pEd->last_display = j;
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->last_display;
|
|
pEd->dir = _STABILIZE_UP;
|
|
pEd->current_stabil = pEd->cursor_row;
|
|
}
|
|
else
|
|
{
|
|
/* the new line is already visible */
|
|
if( pEd->line_number <= ( pEd->bottom - pEd->top + 1 ) )
|
|
pEd->last_display = pEd->last_line; /* the total number of lines is smaller then rows to display */
|
|
}
|
|
}
|
|
if( pEd->current_line > pEd->last_display )
|
|
pEd->last_display = pEd->current_line;
|
|
if( pEd->current_line > pEd->last_line )
|
|
pEd->last_line = pEd->current_line;
|
|
}
|
|
|
|
/* Moves cursor to the next line of text */
|
|
HB_FUNC( ED_DOWN )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
Down( pEd );
|
|
|
|
hb_retl( pEd->fStable );
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Moves the cursor to the previous line of text */
|
|
static void Up( PHB_EDITOR pEd )
|
|
{
|
|
HB_ISIZ jj;
|
|
|
|
/* find the previous line */
|
|
jj = Prev( pEd, pEd->current_line );
|
|
if( jj < 0 )
|
|
{
|
|
pEd->fStable = HB_TRUE;
|
|
}
|
|
else
|
|
{
|
|
HB_ISIZ nEsc;
|
|
|
|
pEd->active--;
|
|
Clear( pEd, pEd->current_line, &nEsc );
|
|
pEd->current_line = jj;
|
|
if( ( ( --pEd->cursor_row ) + pEd->top ) < pEd->top )
|
|
{
|
|
int j, i;
|
|
HB_ISIZ tmp;
|
|
|
|
/* the new line was not displayed yet */
|
|
pEd->stabil = 1; /* only one line needs redisplay - rest of lines will be scrolled */
|
|
|
|
j = 0;
|
|
pEd->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 */
|
|
pEd->first_display = Prev( pEd, pEd->first_display );
|
|
tmp = pEd->first_display;
|
|
for( i = 0; i < pEd->bottom - pEd->top + 1; i++ )
|
|
{
|
|
jj = Next( pEd, tmp );
|
|
if( jj >= 0 )
|
|
{
|
|
tmp = jj;
|
|
j++;
|
|
}
|
|
}
|
|
if( j == ( pEd->bottom - pEd->top + 1 ) )
|
|
pEd->last_display = Prev( pEd, pEd->last_display );
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->current_line;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Moves the cursor to the previous line */
|
|
HB_FUNC( ED_UP )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
Up( pEd );
|
|
|
|
hb_retl( pEd->fStable );
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Moves the cursor to the next page of text */
|
|
HB_FUNC( ED_PGDOWN )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
int i;
|
|
HB_ISIZ j;
|
|
|
|
j = Next( pEd, pEd->last_display );
|
|
if( pEd->begin[ j ] == '\0' ) /* no more lines */
|
|
{
|
|
pEd->fStable = HB_TRUE;
|
|
/* advance the cursor as much as possible (to the last line) */
|
|
for( i = 0; i < pEd->bottom - pEd->top + 1; i++ )
|
|
Down( pEd );
|
|
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 < pEd->bottom - pEd->top; i++ )
|
|
{
|
|
j = Next( pEd, pEd->last_display );
|
|
if( j >= 0 )
|
|
{
|
|
if( pEd->begin[ j ] != '\0' )
|
|
{
|
|
pEd->active++;
|
|
pEd->last_display = j;
|
|
}
|
|
}
|
|
else
|
|
break; /* no more lines */
|
|
}
|
|
|
|
if( pEd->begin[ pEd->last_display ] == '\0' )
|
|
pEd->last_display = Prev( pEd, pEd->last_display );
|
|
pEd->first_display = pEd->last_display;
|
|
|
|
/* find the first displayed line now */
|
|
for( i = 0; i < pEd->bottom - pEd->top; i++ )
|
|
{
|
|
j = Prev( pEd, pEd->first_display );
|
|
if( j >= 0 )
|
|
pEd->first_display = j;
|
|
else
|
|
pEd->first_display = 0;
|
|
}
|
|
|
|
/* find the offset of the line where the cursor will be displayed */
|
|
pEd->current_line = pEd->last_display;
|
|
for( i = 0; i < pEd->bottom - pEd->top - pEd->cursor_row; i++ )
|
|
{
|
|
j = Prev( pEd, pEd->current_line );
|
|
if( j >= 0 )
|
|
pEd->current_line = j;
|
|
else
|
|
pEd->current_line = 0;
|
|
}
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Moves the cursor to the previous page of text */
|
|
HB_FUNC( ED_PGUP )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
int i, bt;
|
|
HB_ISIZ j;
|
|
|
|
bt = pEd->bottom - pEd->top;
|
|
|
|
j = Prev( pEd, pEd->first_display );
|
|
if( j < 0 ) /* no more lines to move */
|
|
{
|
|
pEd->fStable = HB_TRUE;
|
|
/* advance the cursor to the topmost line */
|
|
for( i = 0; i < bt + 1; i++ )
|
|
Up( pEd );
|
|
return;
|
|
}
|
|
|
|
/* find the offset of the first visible line */
|
|
for( i = 0; i < bt; i++ )
|
|
{
|
|
j = Prev( pEd, pEd->first_display );
|
|
if( j >= 0 )
|
|
{
|
|
pEd->active--;
|
|
pEd->first_display = j;
|
|
}
|
|
else
|
|
break; /* no more line */
|
|
}
|
|
/* now the last visible line */
|
|
pEd->last_display = pEd->first_display;
|
|
for( i = 0; i < bt; i++ )
|
|
{
|
|
j = Next( pEd, pEd->last_display );
|
|
if( j >= 0 )
|
|
pEd->last_display = j;
|
|
}
|
|
|
|
/* update the offset of line where the cursor will be displayed
|
|
keep the cursor in the same row if possible */
|
|
pEd->current_line = pEd->last_display;
|
|
for( i = 0; i < bt - pEd->cursor_row; i++ )
|
|
{
|
|
j = Prev( pEd, pEd->current_line );
|
|
if( j >= 0 )
|
|
pEd->current_line = j;
|
|
else
|
|
pEd->current_line = 0;
|
|
}
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->last_display;
|
|
pEd->stabil = bt + 1;
|
|
pEd->dir = _STABILIZE_UP;
|
|
pEd->current_stabil = bt;
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Move the cursor to the beginning of the text */
|
|
HB_FUNC( ED_TOP )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
int i;
|
|
HB_ISIZ nEsc;
|
|
|
|
Clear( pEd, pEd->current_line, &nEsc );
|
|
pEd->current_line = pEd->first_line;
|
|
pEd->cursor_row = 0;
|
|
pEd->first_display = pEd->last_display = pEd->first_line;
|
|
|
|
/* find the last visible line */
|
|
for( i = 0; i < pEd->bottom - pEd->top; i++ )
|
|
{
|
|
HB_ISIZ j = Next( pEd, pEd->last_display );
|
|
if( j >= 0 )
|
|
pEd->last_display = j;
|
|
}
|
|
|
|
pEd->cursor_row = pEd->current_stabil = 0;
|
|
pEd->current_line = pEd->next_stabil = pEd->first_line;
|
|
pEd->active = 1;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->first_col = pEd->cursor_col = 0;
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Move the cursor to the last line of text */
|
|
HB_FUNC( ED_BOTTOM )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
int i, j;
|
|
HB_ISIZ nEsc;
|
|
|
|
j = 0;
|
|
Clear( pEd, pEd->current_line, &nEsc );
|
|
pEd->current_line = pEd->last_line;
|
|
pEd->cursor_row = 0;
|
|
pEd->first_display = pEd->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 */
|
|
pEd->last_display = pEd->first_display;
|
|
for( i = 0; i < pEd->bottom - pEd->top; i++ )
|
|
{
|
|
HB_ISIZ jj = Prev( pEd, pEd->first_display );
|
|
if( jj >= 0 )
|
|
{
|
|
pEd->first_display = jj;
|
|
j++;
|
|
}
|
|
}
|
|
|
|
pEd->current_line = pEd->last_display;
|
|
pEd->active = pEd->line_number;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
pEd->first_col = pEd->cursor_col = 0;
|
|
pEd->cursor_row = j;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Go to the specified line number */
|
|
static void GoTo( PHB_EDITOR pEd, HB_ISIZ line )
|
|
{
|
|
int i;
|
|
HB_ISIZ j;
|
|
HB_ISIZ nEsc;
|
|
|
|
Clear( pEd, pEd->current_line, &nEsc );
|
|
|
|
/* find specified line */
|
|
pEd->current_line = pEd->first_line;
|
|
for( i = 0; i < line - 1; i++ )
|
|
{
|
|
j = Next( pEd, pEd->current_line );
|
|
if( j >= 0 )
|
|
pEd->current_line = j;
|
|
}
|
|
pEd->cursor_row = 0;
|
|
pEd->first_display = pEd->current_line;
|
|
|
|
/* find the offset of the last visible line */
|
|
pEd->last_display = pEd->first_display;
|
|
for( i = 0; i < pEd->bottom - pEd->top; i++ )
|
|
{
|
|
j = Next( pEd, pEd->last_display );
|
|
if( j >= 0 )
|
|
pEd->last_display = j;
|
|
}
|
|
|
|
pEd->active = line;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->current_line;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = pEd->cursor_row;
|
|
pEd->first_col = 0;
|
|
}
|
|
|
|
/* Move the cursor to the given line using line number */
|
|
HB_FUNC( ED_GOTO )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
GoTo( pEd, hb_parns( 1 ) );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Move the cursor to the previous character */
|
|
static void Left( PHB_EDITOR pEd )
|
|
{
|
|
if( pEd->cursor_col > 0 )
|
|
pEd->cursor_col--; /* inside the window - decrement current column number */
|
|
else
|
|
{
|
|
if( pEd->first_col > 0 )
|
|
{
|
|
/* the text is scrolled right - scroll it back to the left by one column */
|
|
pEd->first_col--;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
/* else no wrap allowed */
|
|
}
|
|
}
|
|
|
|
/* Move the cursor to the previous character */
|
|
HB_FUNC( ED_LEFT )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
Left( pEd );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Move the cursor to the next character */
|
|
static void Right( PHB_EDITOR pEd )
|
|
{
|
|
if( pEd->cursor_col < ( pEd->right - pEd->left ) ) /* inside the window */
|
|
{
|
|
if( ( pEd->first_col + pEd->cursor_col ) < pEd->line_length )
|
|
pEd->cursor_col++;
|
|
/* else no wrap allowed */
|
|
}
|
|
else
|
|
{
|
|
/* scroll text to the right no more then the maximal line length */
|
|
if( ( ++pEd->first_col + pEd->cursor_col ) > pEd->line_length )
|
|
pEd->first_col--;
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
|
|
/* Move the cursor to the next character */
|
|
HB_FUNC( ED_RIGHT )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
Right( pEd );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Move the cursor to the beginning of line */
|
|
static void Home( PHB_EDITOR pEd )
|
|
{
|
|
if( pEd->first_col > 0 )
|
|
{
|
|
/* the line was scrolled to the right */
|
|
pEd->cursor_col = 0;
|
|
pEd->first_col = 0;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
else
|
|
{
|
|
pEd->cursor_col = 0;
|
|
pEd->first_col = 0;
|
|
}
|
|
}
|
|
|
|
/* Move the cursor to the beginning of the line */
|
|
HB_FUNC( ED_HOME )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
Home( pEd );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Move the cursor to the end of line */
|
|
static void End( PHB_EDITOR pEd )
|
|
{
|
|
HB_ISIZ ll;
|
|
HB_ISIZ nEsc;
|
|
|
|
ll = Clear( pEd, pEd->current_line, &nEsc );
|
|
if( ll < pEd->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 */
|
|
pEd->first_col = ll;
|
|
pEd->cursor_col = 0;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
else if( ( ll - pEd->first_col ) > ( pEd->right - pEd->left ) )
|
|
{
|
|
/* scroll text to the right */
|
|
pEd->cursor_col = pEd->right - pEd->left;
|
|
pEd->first_col = ll - ( pEd->right - pEd->left );
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
else
|
|
pEd->cursor_col = ll - pEd->first_col;
|
|
}
|
|
|
|
/* Move the cursor the the end of line (after the last non-space character) */
|
|
HB_FUNC( ED_END )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
End( pEd );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Format the current paragraph */
|
|
static void FormatParagraph( PHB_EDITOR pEd )
|
|
{
|
|
HB_ISIZ rdl;
|
|
int cr, cor;
|
|
HB_ISIZ cc;
|
|
|
|
cc = pEd->cursor_col;
|
|
cr = pEd->cursor_row;
|
|
cor = 0;
|
|
|
|
rdl = format_line( pEd, HB_CHAR_SOFT1, 0 );
|
|
pEd->stabil = 1; /* at least one line will be redisplayed */
|
|
|
|
#if 0
|
|
if( rdl )
|
|
#endif
|
|
{
|
|
HB_ISIZ dl, CrLine;
|
|
HB_ISIZ nEsc;
|
|
|
|
char pom[ _MAX_LINE_LEN * 2 ];
|
|
char * tmp;
|
|
|
|
dl = GetLineLength( pEd, pEd->current_line, &rdl );
|
|
hb_strncpy( pom, pEd->begin + pEd->current_line, dl + rdl + 10 );
|
|
pom[ pEd->line_length + rdl + 1 ] = '\0';
|
|
tmp = strchr( pom, '\n' );
|
|
if( tmp && ( *( tmp - 1 ) == HB_CHAR_SOFT1 ) )
|
|
{
|
|
tmp--;
|
|
cor++;
|
|
}
|
|
else
|
|
tmp = NULL;
|
|
|
|
CrLine = pEd->current_line;
|
|
|
|
while( tmp )
|
|
{
|
|
HB_ISIZ source = pEd->current_line + ( tmp - pom - 1 );
|
|
MoveText( pEd, source + 2, source + 1, pEd->buffer_size - source + 2 );
|
|
pEd->begin[ source + 1 ] = ' ';
|
|
|
|
rdl = format_line( pEd, HB_CHAR_SOFT1, 0 );
|
|
Clear( pEd, pEd->current_line, &nEsc );
|
|
|
|
pEd->current_line = Next( pEd, pEd->current_line );
|
|
dl = GetLineLength( pEd, pEd->current_line, &rdl );
|
|
hb_strncpy( pom, pEd->begin + pEd->current_line, dl + rdl + 10 );
|
|
pom[ pEd->line_length + rdl + 1 ] = '\0';
|
|
tmp = strchr( pom, '\n' );
|
|
if( tmp && ( *( tmp - 1 ) == HB_CHAR_SOFT1 ) )
|
|
{
|
|
tmp--;
|
|
cor++;
|
|
}
|
|
else
|
|
tmp = NULL;
|
|
|
|
}
|
|
pEd->current_line = CrLine;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
#if 0
|
|
else
|
|
#endif
|
|
{
|
|
pEd->stabil = 1;
|
|
pEd->next_stabil = pEd->current_line;
|
|
pEd->current_stabil = pEd->cursor_row;
|
|
}
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->cursor_col = cc;
|
|
pEd->cursor_row = cr;
|
|
pEd->line_number -= cor;
|
|
}
|
|
|
|
/* Delete the character under the cursor */
|
|
static void DelChar( PHB_EDITOR pEd )
|
|
{
|
|
HB_ISIZ ccc;
|
|
HB_ISIZ rdl;
|
|
HB_ISIZ cl;
|
|
|
|
cl = pEd->current_line;
|
|
ccc = pEd->cursor_col + pEd->first_col;
|
|
if( ccc <= GetLineLength( pEd, pEd->current_line, &rdl ) )
|
|
{
|
|
if( pEd->escape )
|
|
{
|
|
while( pEd->begin[ pEd->current_line + ccc ] == pEd->escape )
|
|
ccc += 2;
|
|
}
|
|
MoveText( pEd, pEd->current_line + ccc + 1,
|
|
pEd->current_line + ccc,
|
|
( pEd->buffer_size - ( pEd->current_line + ccc + 1 ) ) );
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->current_line;
|
|
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = pEd->cursor_row;
|
|
|
|
FormatParagraph( pEd );
|
|
|
|
if( pEd->current_line == pEd->last_line )
|
|
pEd->last_display = pEd->last_line;
|
|
|
|
pEd->current_line = cl;
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
|
|
/* Delete the character at current cursor position */
|
|
HB_FUNC( ED_DELCHAR )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
HB_ISIZ j;
|
|
HB_ISIZ rdl;
|
|
|
|
if( ( pEd->cursor_col + pEd->first_col ) >=
|
|
GetLineLength( pEd, pEd->current_line, &rdl ) )
|
|
{
|
|
/* The cursor is positioned after the last non-space character */
|
|
j = Next( pEd, pEd->current_line );
|
|
if( j >= 0 )
|
|
{
|
|
/* there are more lines below the cursor - join the lines */
|
|
Down( pEd ); /* goto the next line */
|
|
Home( pEd ); /* goto the beginning of line */
|
|
BackSpace( pEd, HB_TRUE ); /* delete separating CR/LF */
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* The cursor is inside the line or at the last character */
|
|
if( ( pEd->cursor_col + pEd->first_col ) <
|
|
GetLineLength( pEd, pEd->current_line, &rdl ) )
|
|
DelChar( pEd ); /* inside a line */
|
|
else /* at the last character */
|
|
{
|
|
j = Next( pEd, pEd->current_line );
|
|
if( j >= 0 ) /* if it is not the last line then delete character under the cursor */
|
|
DelChar( pEd );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Delete a character on the left side of the cursor */
|
|
static void BackSpace( PHB_EDITOR pEd, HB_BOOL fInsert )
|
|
{
|
|
HB_ISIZ ccc;
|
|
HB_ISIZ rdl;
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->current_line;
|
|
pEd->stabil = 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = pEd->cursor_row;
|
|
|
|
if( fInsert )
|
|
{
|
|
if( ( ccc = pEd->cursor_col + pEd->first_col ) >
|
|
GetLineLength( pEd, pEd->current_line, &rdl ) )
|
|
fInsert = HB_FALSE; /* cursor is scrolled after the last character in the line - just move the cursor left */
|
|
}
|
|
|
|
if( fInsert )
|
|
{
|
|
char tmp[ _MAX_LINE_LEN + 2 ];
|
|
char tmp1[ _MAX_LINE_LEN + 2 ];
|
|
|
|
/* in destructive mode */
|
|
*tmp = '\0';
|
|
*tmp1 = '\0';
|
|
if( ( ccc = pEd->cursor_col + pEd->first_col ) > 0 )
|
|
{
|
|
/* inside the line */
|
|
MoveText( pEd, pEd->current_line + ccc, pEd->current_line + ccc - 1,
|
|
( pEd->buffer_size - ( pEd->current_line + ccc + 1 ) ) );
|
|
Left( pEd );
|
|
}
|
|
else if( pEd->current_line != pEd->first_line ) /* at the beginning of the line */
|
|
{
|
|
char * w;
|
|
HB_ISIZ ww, j, kk;
|
|
HB_ISIZ nLen;
|
|
|
|
/* this is not the first line */
|
|
nLen = GetLineLength( pEd, pEd->current_line, &rdl );
|
|
|
|
if( pEd->current_line == pEd->last_line )
|
|
if( nLen == 0 )
|
|
pEd->last_line = Prev( pEd, pEd->last_line );
|
|
|
|
/* copy the last line into temporary buffer */
|
|
hb_strncpy( tmp, pEd->begin + pEd->current_line, nLen + rdl );
|
|
|
|
/* find the first space in current line (the new line will
|
|
be wrapped eventually at this position) */
|
|
if( ( w = strchr( tmp, ' ' ) ) != 0 )
|
|
ww = w - tmp;
|
|
else
|
|
ww = nLen + rdl;
|
|
|
|
/* go to the previous line */
|
|
j = Prev( pEd, pEd->current_line );
|
|
kk = GetLineLength( pEd, j, &rdl );
|
|
hb_strncpy( tmp1, pEd->begin + j, kk + rdl );
|
|
Up( pEd );
|
|
End( pEd );
|
|
|
|
/* 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 ) < pEd->line_length )
|
|
{
|
|
kk = GetLineLength( pEd, pEd->current_line, &rdl );
|
|
j = pEd->current_line + kk + rdl;
|
|
/* remove separating CRLF characters */
|
|
MoveText( pEd, j + 2, j, pEd->buffer_size - j - 2 );
|
|
|
|
pEd->line_number--;
|
|
|
|
j = Next( pEd, pEd->last_display );
|
|
if( j >= 0 )
|
|
pEd->last_display = j;
|
|
if( pEd->begin[ pEd->last_display + 1 ] == '\0' )
|
|
pEd->last_display = Prev( pEd, pEd->last_display );
|
|
|
|
/* split the new line if it is too long */
|
|
format_line( pEd, HB_CHAR_HARD1, 0 );
|
|
|
|
j = Next( pEd, pEd->current_line );
|
|
if( j < 0 )
|
|
{
|
|
pEd->last_display = Prev( pEd, pEd->last_display );
|
|
pEd->last_line = pEd->current_line;
|
|
}
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
|
|
FormatParagraph( pEd );
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
else
|
|
{
|
|
/* non-destructive mode - move cursor only */
|
|
ccc = pEd->cursor_col + pEd->first_col;
|
|
if( ccc > 0 )
|
|
{
|
|
Left( pEd );
|
|
}
|
|
else
|
|
{
|
|
if( pEd->current_line != pEd->first_line )
|
|
{
|
|
Up( pEd );
|
|
End( pEd );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Delete a character on the left side of the cursor */
|
|
HB_FUNC( ED_BSPACE )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
BackSpace( pEd, hb_parl( 2 ) /* fInsert */ );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Move to the beginning of next non-empty line */
|
|
static void GotoNextNonEmptyLine( PHB_EDITOR pEd )
|
|
{
|
|
HB_ISIZ rdl;
|
|
|
|
Down( pEd );
|
|
Home( pEd );
|
|
|
|
while( GetLineLength( pEd, pEd->current_line, &rdl ) == 0 )
|
|
{
|
|
Down( pEd );
|
|
Home( pEd );
|
|
if( Next( pEd, pEd->current_line ) < 0 )
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Move the cursor to the next word */
|
|
static void NextWord( PHB_EDITOR pEd )
|
|
{
|
|
char * adr;
|
|
char tmp[ _MAX_LINE_LEN + 2 ];
|
|
HB_ISIZ ccc;
|
|
HB_ISIZ nLen;
|
|
HB_ISIZ nEsc;
|
|
|
|
ccc = pEd->cursor_col + pEd->first_col;
|
|
nLen = Clear( pEd, pEd->current_line, &nEsc );
|
|
|
|
if( nLen < ccc )
|
|
GotoNextNonEmptyLine( pEd );
|
|
else
|
|
{
|
|
*tmp = '\0';
|
|
hb_strncpy( tmp, pEd->begin + pEd->current_line + ccc,
|
|
nLen - pEd->cursor_col - pEd->first_col );
|
|
if( ( adr = strchr( tmp, ' ' ) ) == NULL )
|
|
{
|
|
GotoNextNonEmptyLine( pEd );
|
|
if( ! pEd->fStable )
|
|
{
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pEd->cursor_col = adr - tmp + 1 + pEd->cursor_col + pEd->first_col;
|
|
|
|
if( pEd->cursor_col > ( pEd->right - pEd->left ) )
|
|
{
|
|
pEd->first_col += pEd->cursor_col - ( pEd->right - pEd->left );
|
|
pEd->cursor_col = pEd->right - pEd->left;
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pEd->begin[ ( pEd->current_line +
|
|
pEd->cursor_col + pEd->first_col ) ] == ' ' )
|
|
NextWord( pEd );
|
|
}
|
|
|
|
/* Move the cursor to the next word */
|
|
HB_FUNC( ED_NWORD )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
NextWord( pEd );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Move the cursor to the previous word */
|
|
static void PreviousWord( PHB_EDITOR pEd )
|
|
{
|
|
HB_ISIZ pom;
|
|
HB_ISIZ i;
|
|
HB_ISIZ rdl;
|
|
HB_ISIZ nLen;
|
|
HB_ISIZ nEsc;
|
|
|
|
pom = -1;
|
|
nLen = Clear( pEd, pEd->current_line, &nEsc );
|
|
if( nLen < ( pEd->cursor_col + pEd->first_col ) )
|
|
End( pEd );
|
|
|
|
if( ( pEd->first_col + pEd->cursor_col ) == 0 )
|
|
{
|
|
Up( pEd );
|
|
End( pEd );
|
|
}
|
|
|
|
for( i = pEd->first_col + pEd->cursor_col - 2; i >= 0; i-- )
|
|
{
|
|
if( pEd->begin[ pEd->current_line + i ] == ' ' )
|
|
{
|
|
pom = i;
|
|
break;
|
|
}
|
|
else
|
|
pom = -1;
|
|
}
|
|
|
|
if( pom < 0 )
|
|
{
|
|
Home( pEd );
|
|
while( GetLineLength( pEd, pEd->current_line, &rdl ) == 0 )
|
|
{
|
|
Up( pEd );
|
|
Home( pEd );
|
|
if( Prev( pEd, pEd->current_line ) < 0 )
|
|
break;
|
|
}
|
|
if( ! pEd->fStable )
|
|
{
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pEd->cursor_col = pom + 1;
|
|
if( pEd->first_col > 0 )
|
|
{
|
|
pEd->cursor_col -= pEd->first_col;
|
|
}
|
|
if( pEd->cursor_col < 0 )
|
|
{
|
|
pEd->first_col = pEd->cursor_col - ( pEd->right - pEd->left );
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
|
|
if( pEd->begin[ pEd->current_line + pEd->cursor_col +
|
|
pEd->first_col ] == ' ' )
|
|
PreviousWord( pEd );
|
|
}
|
|
|
|
/* Move the cursor to the previous word */
|
|
HB_FUNC( ED_PWORD )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
PreviousWord( pEd );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
/* Format given line - returns it the line has changed */
|
|
|
|
static HB_BOOL format_line( PHB_EDITOR pEd, char Karetka, HB_ISIZ LineDl )
|
|
{
|
|
HB_BOOL status;
|
|
HB_ISIZ rdl = 0;
|
|
|
|
if( ! LineDl )
|
|
LineDl = GetLineLength( pEd, pEd->current_line, &rdl );
|
|
|
|
status = HB_FALSE; /* the line is not split yet */
|
|
if( LineDl > pEd->line_length )
|
|
{
|
|
char * p;
|
|
HB_ISIZ podz, jj;
|
|
HB_ISIZ j;
|
|
|
|
char pom[ _MAX_LINE_LEN * 2 ];
|
|
|
|
/* the line is longer then maximal allowed length -
|
|
wrap the line */
|
|
status = HB_TRUE; /* the line will be split */
|
|
|
|
/* copy maximum allowed bytes form the line into temporary buffer */
|
|
hb_strncpy( pom, pEd->begin + pEd->current_line,
|
|
pEd->line_length + 10 + rdl );
|
|
pom[ pEd->line_length + rdl ] = '\0';
|
|
|
|
/* find the last space where the line can be split */
|
|
p = strrchr( pom, ' ' );
|
|
if( p )
|
|
{
|
|
/* use this position to split the line */
|
|
podz = p - pom + 1;
|
|
jj = 1 - podz + pEd->cursor_col + pEd->first_col;
|
|
}
|
|
else
|
|
{
|
|
/* there is no space in the line - split it at the maximal line length */
|
|
podz = pEd->line_length;
|
|
jj = 1;
|
|
}
|
|
|
|
j = pEd->current_line + podz;
|
|
MoveText( pEd, j, j + 2, pEd->buffer_size - j - 2 );
|
|
|
|
/* replace with separators */
|
|
pEd->begin[ j + 0 ] = Karetka;
|
|
pEd->begin[ j + 1 ] = '\n';
|
|
pEd->line_number++;
|
|
|
|
if( ( pEd->cursor_col + pEd->first_col ) >= podz )
|
|
{
|
|
HB_ISIZ i;
|
|
Home( pEd );
|
|
Down( pEd );
|
|
for( i = 0; i < jj; i++ )
|
|
Right( pEd );
|
|
}
|
|
else
|
|
Right( pEd );
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/* Appends the character at the end of line */
|
|
static HB_BOOL AppendChar( PHB_EDITOR pEd, char znak, char podz )
|
|
{
|
|
HB_BOOL status;
|
|
HB_ISIZ diff;
|
|
HB_ISIZ rdl;
|
|
HB_ISIZ iPos, nLen;
|
|
HB_ISIZ cl;
|
|
HB_ISIZ ccol, fcol;
|
|
char * cNew;
|
|
|
|
nLen = GetLineLength( pEd, pEd->current_line, &rdl );
|
|
iPos = pEd->current_line + nLen;
|
|
diff = pEd->cursor_col + pEd->first_col - nLen;
|
|
|
|
/* the cursor is positioned 'diff' columns after the last character
|
|
in the line - fill the gap with spaces before appending the character */
|
|
MoveText( pEd, iPos, iPos + diff + 1, pEd->buffer_size - 1 - iPos - diff );
|
|
memset( pEd->begin + ( pEd->current_line + nLen ), ' ', diff );
|
|
|
|
/* move the CRLF characters after the appended character */
|
|
cNew = pEd->begin + iPos + diff;
|
|
*cNew++ = znak;
|
|
if( *cNew != '\r' )
|
|
*cNew = podz; /* insert requested soft/hard carriage */
|
|
*++cNew = '\n';
|
|
|
|
/* the last line always have to end with the hard carriage return */
|
|
pEd->begin[ pEd->text_length - 2 ] = '\r';
|
|
|
|
status = format_line( pEd, HB_CHAR_SOFT1, 0 );
|
|
|
|
cl = pEd->current_line;
|
|
ccol = pEd->cursor_col;
|
|
fcol = pEd->first_col;
|
|
|
|
FormatParagraph( pEd );
|
|
|
|
pEd->current_line = cl;
|
|
pEd->cursor_col = ccol;
|
|
pEd->first_col = fcol;
|
|
|
|
return status;
|
|
}
|
|
|
|
/* Checks if there is enough free room in the text buffer */
|
|
static HB_BOOL Check_length( PHB_EDITOR pEd, HB_ISIZ iRequested )
|
|
{
|
|
if( ( pEd->text_length + iRequested ) <= ( pEd->buffer_size - 8 ) )
|
|
return HB_TRUE;
|
|
else
|
|
return HB_FALSE;
|
|
}
|
|
|
|
/* Adjusts the offset of last line */
|
|
static void SetLastLine( PHB_EDITOR pEd )
|
|
{
|
|
if( pEd->current_line > pEd->last_line )
|
|
pEd->last_line = pEd->current_line;
|
|
}
|
|
|
|
/* Insert or replace the new character into the text buffer */
|
|
static void PutChar( PHB_EDITOR pEd, HB_BOOL fInsert, char znak )
|
|
{
|
|
HB_BOOL jj;
|
|
HB_ISIZ cc;
|
|
HB_ISIZ rdl;
|
|
|
|
jj = HB_FALSE;
|
|
cc = pEd->cursor_col + pEd->first_col; /* current position in the line */
|
|
if( fInsert )
|
|
{
|
|
/* INSERT is ON */
|
|
if( Check_length( pEd, 1 ) )
|
|
{
|
|
/* TODO: add reallocation of text buffer */
|
|
if( cc < GetLineLength( pEd, pEd->current_line, &rdl ) )
|
|
{
|
|
HB_ISIZ i;
|
|
HB_ISIZ cl;
|
|
HB_ISIZ ccol, fcol;
|
|
|
|
/* the character will be inserted within the line - the cursor
|
|
is placed inside the line */
|
|
i = pEd->current_line + cc;
|
|
MoveText( pEd, i, i + 1, pEd->buffer_size - pEd->current_line - cc - 1 );
|
|
pEd->begin[ i ] = znak;
|
|
|
|
jj = format_line( pEd, HB_CHAR_SOFT1, 0 );
|
|
|
|
cl = pEd->current_line;
|
|
ccol = pEd->cursor_col;
|
|
fcol = pEd->first_col;
|
|
|
|
FormatParagraph( pEd );
|
|
|
|
pEd->current_line = cl;
|
|
pEd->cursor_col = ccol;
|
|
pEd->first_col = fcol;
|
|
|
|
if( jj )
|
|
SetLastLine( pEd );
|
|
}
|
|
else /* the cursor is located after the last character in the line */
|
|
jj = AppendChar( pEd, znak, HB_CHAR_SOFT1 );
|
|
|
|
if( ! jj )
|
|
Right( pEd );
|
|
else
|
|
SetLastLine( pEd );
|
|
}
|
|
}
|
|
else if( cc < GetLineLength( pEd, pEd->current_line, &rdl ) )
|
|
{
|
|
pEd->begin[ pEd->current_line + cc ] = znak;
|
|
jj = HB_FALSE;
|
|
Right( pEd );
|
|
}
|
|
else if( Check_length( pEd, 1 ) )
|
|
{
|
|
jj = AppendChar( pEd, znak, HB_CHAR_SOFT1 );
|
|
if( ! jj )
|
|
Right( pEd );
|
|
else
|
|
SetLastLine( pEd );
|
|
}
|
|
|
|
if( ! jj )
|
|
{
|
|
if( ( pEd->cursor_col + pEd->first_col ) > ( pEd->right - pEd->left ) )
|
|
jj = HB_TRUE;
|
|
}
|
|
|
|
if( jj )
|
|
{
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
else
|
|
{
|
|
pEd->stabil = 1;
|
|
pEd->next_stabil = pEd->current_line;
|
|
pEd->current_stabil = pEd->cursor_row;
|
|
}
|
|
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
}
|
|
|
|
/* Insert or replace the character into the text buffer */
|
|
HB_FUNC( ED_PUTCHAR )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
PutChar( pEd,
|
|
hb_parl( 3 ), /* current INSERT state */
|
|
( char ) hb_parni( 2 ) ); /* character to paste */
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
#if 0
|
|
static void Tab( PHB_EDITOR pEd, HB_BOOL fInsert )
|
|
{
|
|
if( fInsert )
|
|
{
|
|
for( i = 0; i < pEd->tab_size; i++ )
|
|
PutChar( pEd, HB_TRUE, ' ' );
|
|
}
|
|
else
|
|
{
|
|
for( i = 0; i < pEd->tab_size; i++ )
|
|
Right( pEd );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* --- */
|
|
|
|
#if 0
|
|
HB_FUNC( ED_TAB )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
Tab( pEd, hb_parl( 2 ) /* fInsert */ );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
#endif
|
|
|
|
static void DelLine( PHB_EDITOR pEd )
|
|
{
|
|
if( pEd->active < pEd->line_number )
|
|
{
|
|
HB_ISIZ tmp, j;
|
|
|
|
j = Next( pEd, pEd->last_display );
|
|
if( j >= 0 )
|
|
pEd->last_display = j;
|
|
|
|
tmp = Next( pEd, pEd->current_line );
|
|
if( tmp < 0 )
|
|
tmp = 0;
|
|
|
|
pEd->stabil = pEd->bottom - pEd->top + 1 - pEd->cursor_row;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
|
|
MoveText( pEd, tmp, pEd->current_line, pEd->buffer_size - pEd->current_line - 2 );
|
|
|
|
if( pEd->line_number > 0 )
|
|
pEd->line_number--;
|
|
|
|
pEd->next_stabil = pEd->current_line;
|
|
pEd->current_stabil = pEd->cursor_row;
|
|
pEd->fStable = HB_FALSE;
|
|
}
|
|
else
|
|
{
|
|
pEd->begin[ pEd->current_line + 0 ] = '\r';
|
|
pEd->begin[ pEd->current_line + 1 ] = '\n';
|
|
pEd->begin[ pEd->current_line + 2 ] = '\0';
|
|
memset( pEd->begin + pEd->current_line + 2, '\0',
|
|
pEd->buffer_size - strlen( pEd->begin ) );
|
|
|
|
pEd->last_display = pEd->last_line;
|
|
pEd->stabil = 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->next_stabil = pEd->current_line;
|
|
pEd->current_stabil = pEd->cursor_row;
|
|
pEd->fStable = HB_FALSE;
|
|
}
|
|
if( pEd->text_length == 0 )
|
|
{
|
|
pEd->begin[ 0 ] = '\r';
|
|
pEd->begin[ 1 ] = '\n';
|
|
pEd->begin[ 2 ] = '\0';
|
|
}
|
|
}
|
|
|
|
/* Delete the current line */
|
|
HB_FUNC( ED_DELLINE )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
DelLine( pEd );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Delete the word on the right side of the cursor */
|
|
HB_FUNC( ED_DELWORD )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
{
|
|
HB_ISIZ j = pEd->current_line + pEd->cursor_col + pEd->first_col;
|
|
|
|
if( pEd->begin[ j ] != ' ' )
|
|
{
|
|
HB_ISIZ rdl;
|
|
|
|
if( ( pEd->cursor_col + pEd->first_col ) <
|
|
GetLineLength( pEd, pEd->current_line, &rdl ) )
|
|
{
|
|
HB_ISIZ pos1, pos2;
|
|
HB_ISIZ cc, fc;
|
|
int cr;
|
|
HB_ISIZ fd, ld;
|
|
HB_ISIZ l;
|
|
|
|
cc = pEd->cursor_col;
|
|
cr = pEd->cursor_row;
|
|
fc = pEd->first_col;
|
|
fd = pEd->first_display;
|
|
ld = pEd->last_display;
|
|
l = pEd->current_line;
|
|
NextWord( pEd );
|
|
pos2 = pEd->cursor_col + pEd->first_col;
|
|
PreviousWord( pEd );
|
|
pos1 = pEd->cursor_col + pEd->first_col;
|
|
|
|
pEd->current_line = l;
|
|
pEd->cursor_col = cc;
|
|
pEd->cursor_row = cr;
|
|
pEd->first_col = fc;
|
|
pEd->first_display = fd;
|
|
pEd->last_display = ld;
|
|
|
|
if( pos2 == 0 )
|
|
pos2 = GetLineLength( pEd, pEd->current_line, &rdl );
|
|
|
|
MoveText( pEd, pEd->current_line + pos2, pEd->current_line + pos1,
|
|
pEd->buffer_size - pEd->current_line - pos2 );
|
|
FormatParagraph( pEd );
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
else
|
|
{
|
|
if( ( GetLineLength( pEd, pEd->current_line, &rdl ) ) == 0 )
|
|
{
|
|
DelLine( pEd );
|
|
Home( pEd );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Insert the CRLF characters */
|
|
static void Return( PHB_EDITOR pEd, HB_BOOL fInsert )
|
|
{
|
|
HB_ISIZ j;
|
|
HB_ISIZ nEsc;
|
|
|
|
if( Check_length( pEd, 2 ) )
|
|
{
|
|
if( fInsert )
|
|
{
|
|
/* only if INSERT state is ON */
|
|
HB_ISIZ nLen = Clear( pEd, pEd->current_line, &nEsc );
|
|
|
|
pEd->line_number++;
|
|
|
|
j = Next( pEd, pEd->current_line );
|
|
if( j < 0 )
|
|
{
|
|
pEd->last_line = pEd->text_length;
|
|
pEd->text_length += 2;
|
|
|
|
pEd->begin[ pEd->text_length - 2 ] = '\r';
|
|
pEd->begin[ pEd->text_length - 1 ] = '\n';
|
|
pEd->begin[ pEd->text_length ] = '\0';
|
|
}
|
|
else
|
|
{
|
|
HB_ISIZ ii;
|
|
if( ( pEd->first_col + pEd->cursor_col ) > nLen + 1 )
|
|
End( pEd );
|
|
ii = pEd->current_line + pEd->first_col +
|
|
pEd->cursor_col;
|
|
MoveText( pEd, ii, ii + 2, pEd->buffer_size - ii - 2 );
|
|
|
|
pEd->begin[ ii + 0 ] = '\r';
|
|
pEd->begin[ ii + 1 ] = '\n';
|
|
if( pEd->last_line == pEd->current_line )
|
|
pEd->last_line = Next( pEd, pEd->current_line );
|
|
}
|
|
|
|
if( pEd->cursor_row < ( pEd->bottom - pEd->top ) )
|
|
{
|
|
j = Prev( pEd, pEd->last_display );
|
|
if( j > 0 )
|
|
pEd->last_display = j;
|
|
|
|
pEd->next_stabil = pEd->current_line;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1 - pEd->cursor_row;
|
|
pEd->current_stabil = pEd->cursor_row;
|
|
}
|
|
else
|
|
{
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->current_stabil = 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Clear( pEd, pEd->current_line, &nEsc );
|
|
j = Next( pEd, pEd->current_line );
|
|
if( j > pEd->last_line )
|
|
{
|
|
if( Check_length( pEd, 2 ) )
|
|
{
|
|
pEd->line_number++;
|
|
pEd->last_line = j;
|
|
pEd->begin[ j + 0 ] = '\r';
|
|
pEd->begin[ j + 1 ] = '\n';
|
|
pEd->begin[ j + 2 ] = '\0';
|
|
}
|
|
}
|
|
}
|
|
|
|
if( Check_length( pEd, 0 ) )
|
|
{
|
|
pEd->fStable = HB_FALSE;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
Down( pEd );
|
|
Home( pEd );
|
|
}
|
|
|
|
if( ! pEd->fStable )
|
|
{
|
|
pEd->next_stabil = pEd->first_display;
|
|
pEd->stabil = pEd->bottom - pEd->top + 1;
|
|
pEd->current_stabil = 0;
|
|
pEd->dir = _STABILIZE_DOWN;
|
|
}
|
|
}
|
|
|
|
/* Insert the CRLF characters */
|
|
HB_FUNC( ED_RETURN )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
Return( pEd, hb_parl( 2 ) /* fInsert */ );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Returns the current cursor row inside the editor's window */
|
|
HB_FUNC( ED_WINROW )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
hb_retni( pEd->cursor_row );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Returns the line number where the cursor is positioned */
|
|
HB_FUNC( ED_ROW )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
hb_retns( pEd->active );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Return the current cursor column inside the editor's window */
|
|
HB_FUNC( ED_WINCOL )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
hb_retns( pEd->cursor_col );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Returns the current cursor position inside the line */
|
|
HB_FUNC( ED_COL )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
hb_retns( pEd->cursor_col + pEd->first_col + 1 );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Returns the total number of lines */
|
|
HB_FUNC( ED_MAXLINE )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
hb_retns( pEd->line_number );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Counts the total number of lines in passed editor */
|
|
HB_FUNC( ED_LCOUNT )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
hb_retns( pEd->line_number );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Returns if the editor is correctly displayed */
|
|
HB_FUNC( ED_STABLE )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
hb_retl( pEd->fStable );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
/* Returns the number of bytes stored in the text buffer */
|
|
HB_FUNC( ED_LENGTH )
|
|
{
|
|
PHB_EDITOR pEd = PHB_EDITOR_par( 1 );
|
|
|
|
if( pEd )
|
|
hb_retns( pEd->text_length );
|
|
else
|
|
hb_errRT_BASE( EG_ARG, 3001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|