2014-12-29 20:27 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* include/hbznet.h
* src/rtl/hbinet.c
* src/rtl/hbinetz.c
* moved HB_INET_ERR_* macros to header file
+ added error and errorStr functions to hb_inet*() socket read/write
wrappers
! call close function of hb_inet*() socket read/write wrappers before
closing the socket
+ added hb_znetInetFD() C function
* src/rtl/teditor.prg
! use hb_ATokens( <cText>, .T. ) and MemoLine() to divide text into lines
to improve performance and fix TABs decoding
* src/rtl/memoedit.prg
* src/rtl/teditor.prg
* applied recent fixes and cleanups from Viktor's branch.
* src/rtl/tgetlist.prg
* applied recent fixes from Viktor's branch:
; (2014-12-19 01:00 UTC+0100 Viktor Szakats)
! HBGetList():GUIApplyKey(): fixed bug introduced with UNICODE
support in 93d3a46d84 (upstream).
That patch had an undocumented workaround for the problem inside
ListBox():findText(), which was not Cl*pper compatible, so
it was later removed in 6f8508ff54a3955822b36bf4a65a2775a11bab23.
This patch hopefully fixes the root cause.
Reported here: https://groups.google.com/d/msg/harbour-devel/7Cpax5TdHnY/n5XfXX8N9vMJ
This commit is contained in:
@@ -10,6 +10,36 @@
|
||||
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
|
||||
*/
|
||||
|
||||
2014-12-29 20:27 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
|
||||
* include/hbznet.h
|
||||
* src/rtl/hbinet.c
|
||||
* src/rtl/hbinetz.c
|
||||
* moved HB_INET_ERR_* macros to header file
|
||||
+ added error and errorStr functions to hb_inet*() socket read/write
|
||||
wrappers
|
||||
! call close function of hb_inet*() socket read/write wrappers before
|
||||
closing the socket
|
||||
+ added hb_znetInetFD() C function
|
||||
|
||||
* src/rtl/teditor.prg
|
||||
! use hb_ATokens( <cText>, .T. ) and MemoLine() to divide text into lines
|
||||
to improve performance and fix TABs decoding
|
||||
|
||||
* src/rtl/memoedit.prg
|
||||
* src/rtl/teditor.prg
|
||||
* applied recent fixes and cleanups from Viktor's branch.
|
||||
|
||||
* src/rtl/tgetlist.prg
|
||||
* applied recent fixes from Viktor's branch:
|
||||
; (2014-12-19 01:00 UTC+0100 Viktor Szakats)
|
||||
! HBGetList():GUIApplyKey(): fixed bug introduced with UNICODE
|
||||
support in 93d3a46d843daaf6d08149d83fa5203ff910c484 (upstream).
|
||||
That patch had an undocumented workaround for the problem inside
|
||||
ListBox():findText(), which was not Cl*pper compatible, so
|
||||
it was later removed in 6f8508ff54a3955822b36bf4a65a2775a11bab23.
|
||||
This patch hopefully fixes the root cause.
|
||||
Reported here: https://groups.google.com/d/msg/harbour-devel/7Cpax5TdHnY/n5XfXX8N9vMJ
|
||||
|
||||
2014-12-15 15:48 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
|
||||
* src/rtl/hbtoken.c
|
||||
* cleaner version of recent hb_tokenPtr() fix which works correctly
|
||||
|
||||
@@ -53,6 +53,12 @@
|
||||
|
||||
HB_EXTERN_BEGIN
|
||||
|
||||
#define HB_INET_ERR_OK 0
|
||||
#define HB_INET_ERR_TIMEOUT ( -1 )
|
||||
#define HB_INET_ERR_CLOSEDCONN ( -2 )
|
||||
#define HB_INET_ERR_BUFFOVERRUN ( -3 )
|
||||
#define HB_INET_ERR_CLOSEDSOCKET ( -4 )
|
||||
|
||||
#if defined( _HB_ZNET_INTERNAL_ )
|
||||
struct _HB_ZNETSTREAM;
|
||||
typedef struct _HB_ZNETSTREAM * PHB_ZNETSTREAM;
|
||||
@@ -60,10 +66,12 @@ HB_EXTERN_BEGIN
|
||||
typedef void * PHB_ZNETSTREAM;
|
||||
#endif
|
||||
|
||||
typedef long ( * HB_INET_SFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, const void *, long, HB_MAXINT, long * );
|
||||
typedef long ( * HB_INET_RFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, void *, long, HB_MAXINT );
|
||||
typedef long ( * HB_INET_FFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, HB_MAXINT );
|
||||
typedef void ( * HB_INET_CFUNC ) ( PHB_ZNETSTREAM );
|
||||
typedef long ( * HB_INET_RDFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, void *, long, HB_MAXINT );
|
||||
typedef long ( * HB_INET_WRFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, const void *, long, HB_MAXINT, long * );
|
||||
typedef long ( * HB_INET_FLFUNC ) ( PHB_ZNETSTREAM, HB_SOCKET, HB_MAXINT );
|
||||
typedef void ( * HB_INET_CLFUNC ) ( PHB_ZNETSTREAM );
|
||||
typedef int ( * HB_INET_ERFUNC ) ( PHB_ZNETSTREAM );
|
||||
typedef const char * ( * HB_INET_ESFUNC ) ( PHB_ZNETSTREAM, int );
|
||||
|
||||
extern HB_EXPORT PHB_ZNETSTREAM hb_znetOpen( int level, int strategy );
|
||||
extern HB_EXPORT void hb_znetEncryptKey( PHB_ZNETSTREAM pStream, const void * keydata, int keylen );
|
||||
@@ -73,11 +81,14 @@ extern HB_EXPORT long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void
|
||||
extern HB_EXPORT long hb_znetFlush( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_MAXINT timeout );
|
||||
extern HB_EXPORT long hb_znetWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, const void * buffer, long len, HB_MAXINT timeout, long * plast );
|
||||
|
||||
extern HB_EXPORT HB_SOCKET hb_znetInetFD( PHB_ITEM pItem, HB_BOOL fError );
|
||||
extern HB_EXPORT HB_BOOL hb_znetInetInitialize( PHB_ITEM, PHB_ZNETSTREAM,
|
||||
HB_INET_RFUNC,
|
||||
HB_INET_SFUNC,
|
||||
HB_INET_FFUNC,
|
||||
HB_INET_CFUNC );
|
||||
HB_INET_RDFUNC,
|
||||
HB_INET_WRFUNC,
|
||||
HB_INET_FLFUNC,
|
||||
HB_INET_CLFUNC,
|
||||
HB_INET_ERFUNC,
|
||||
HB_INET_ESFUNC );
|
||||
|
||||
HB_EXTERN_END
|
||||
|
||||
|
||||
111
src/rtl/hbinet.c
111
src/rtl/hbinet.c
@@ -64,12 +64,6 @@
|
||||
#include "hbthread.h"
|
||||
#include "hbznet.h"
|
||||
|
||||
#define HB_INET_ERR_OK 0
|
||||
#define HB_INET_ERR_TIMEOUT ( -1 )
|
||||
#define HB_INET_ERR_CLOSEDCONN ( -2 )
|
||||
#define HB_INET_ERR_BUFFOVERRUN ( -3 )
|
||||
#define HB_INET_ERR_CLOSEDSOCKET ( -4 )
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HB_SOCKET sd;
|
||||
@@ -85,10 +79,12 @@ typedef struct
|
||||
int iTimeLimit;
|
||||
PHB_ITEM pPeriodicBlock;
|
||||
PHB_ZNETSTREAM stream;
|
||||
HB_INET_RFUNC recvFunc;
|
||||
HB_INET_SFUNC sendFunc;
|
||||
HB_INET_FFUNC flushFunc;
|
||||
HB_INET_CFUNC cleanFunc;
|
||||
HB_INET_RDFUNC recvFunc;
|
||||
HB_INET_WRFUNC sendFunc;
|
||||
HB_INET_FLFUNC flushFunc;
|
||||
HB_INET_CLFUNC cleanFunc;
|
||||
HB_INET_ERFUNC errorFunc;
|
||||
HB_INET_ESFUNC errstrFunc;
|
||||
} HB_SOCKET_STRUCT, * PHB_SOCKET_STRUCT;
|
||||
|
||||
#define HB_INET_BUFFER_LEN 1500
|
||||
@@ -143,20 +139,29 @@ static HB_BOOL hb_inetIsOpen( PHB_SOCKET_STRUCT socket )
|
||||
return HB_TRUE;
|
||||
}
|
||||
|
||||
static int hb_inetCloseSocket( PHB_SOCKET_STRUCT socket )
|
||||
static int s_inetGetError( PHB_SOCKET_STRUCT socket )
|
||||
{
|
||||
int ret = hb_socketClose( socket->sd );
|
||||
int iError;
|
||||
|
||||
socket->sd = HB_NO_SOCKET;
|
||||
socket->inbuffer = 0;
|
||||
return ret;
|
||||
if( socket->errorFunc )
|
||||
iError = socket->errorFunc( socket->stream );
|
||||
else
|
||||
{
|
||||
iError = hb_socketGetError();
|
||||
if( iError == HB_SOCKET_ERR_TIMEOUT )
|
||||
iError = HB_INET_ERR_TIMEOUT;
|
||||
}
|
||||
return iError;
|
||||
}
|
||||
|
||||
static HB_BOOL s_inetIsTimeout( PHB_SOCKET_STRUCT socket )
|
||||
{
|
||||
return s_inetGetError( socket ) == HB_SOCKET_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
static void hb_inetGetError( PHB_SOCKET_STRUCT socket )
|
||||
{
|
||||
socket->iError = hb_socketGetError();
|
||||
if( socket->iError == HB_SOCKET_ERR_TIMEOUT )
|
||||
socket->iError = HB_INET_ERR_TIMEOUT;
|
||||
socket->iError = s_inetGetError( socket );
|
||||
}
|
||||
|
||||
static void hb_inetCloseStream( PHB_SOCKET_STRUCT socket )
|
||||
@@ -171,15 +176,30 @@ static void hb_inetCloseStream( PHB_SOCKET_STRUCT socket )
|
||||
socket->stream = NULL;
|
||||
}
|
||||
|
||||
static int hb_inetCloseSocket( PHB_SOCKET_STRUCT socket, HB_BOOL fShutDown )
|
||||
{
|
||||
int ret;
|
||||
|
||||
hb_inetCloseStream( socket );
|
||||
|
||||
if( fShutDown )
|
||||
hb_socketShutdown( socket->sd, HB_SOCKET_SHUT_RDWR );
|
||||
|
||||
ret = hb_socketClose( socket->sd );
|
||||
|
||||
socket->sd = HB_NO_SOCKET;
|
||||
socket->inbuffer = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HB_GARBAGE_FUNC( hb_inetSocketFinalize )
|
||||
{
|
||||
PHB_SOCKET_STRUCT socket = ( PHB_SOCKET_STRUCT ) Cargo;
|
||||
|
||||
if( socket->sd != HB_NO_SOCKET )
|
||||
{
|
||||
hb_socketShutdown( socket->sd, HB_SOCKET_SHUT_RDWR );
|
||||
hb_inetCloseSocket( socket );
|
||||
}
|
||||
hb_inetCloseSocket( socket, HB_TRUE );
|
||||
else
|
||||
hb_inetCloseStream( socket );
|
||||
|
||||
if( socket->pPeriodicBlock )
|
||||
{
|
||||
@@ -196,7 +216,6 @@ static HB_GARBAGE_FUNC( hb_inetSocketFinalize )
|
||||
hb_xfree( socket->buffer );
|
||||
socket->buffer = NULL;
|
||||
}
|
||||
hb_inetCloseStream( socket );
|
||||
}
|
||||
|
||||
static HB_GARBAGE_FUNC( hb_inetSocketMark )
|
||||
@@ -231,11 +250,25 @@ static void hb_inetAutoInit( void )
|
||||
}
|
||||
}
|
||||
|
||||
HB_SOCKET hb_znetInetFD( PHB_ITEM pItem, HB_BOOL fError )
|
||||
{
|
||||
PHB_SOCKET_STRUCT socket = ( PHB_SOCKET_STRUCT ) hb_itemGetPtrGC( pItem, &s_gcInetFuncs );
|
||||
|
||||
if( socket )
|
||||
return socket->sd;
|
||||
else if( fError )
|
||||
hb_inetErrRT();
|
||||
|
||||
return HB_NO_SOCKET;
|
||||
}
|
||||
|
||||
HB_BOOL hb_znetInetInitialize( PHB_ITEM pItem, PHB_ZNETSTREAM pStream,
|
||||
HB_INET_RFUNC recvFunc,
|
||||
HB_INET_SFUNC sendFunc,
|
||||
HB_INET_FFUNC flushFunc,
|
||||
HB_INET_CFUNC cleanFunc )
|
||||
HB_INET_RDFUNC recvFunc,
|
||||
HB_INET_WRFUNC sendFunc,
|
||||
HB_INET_FLFUNC flushFunc,
|
||||
HB_INET_CLFUNC cleanFunc,
|
||||
HB_INET_ERFUNC errorFunc,
|
||||
HB_INET_ESFUNC errstrFunc )
|
||||
{
|
||||
PHB_SOCKET_STRUCT socket = ( PHB_SOCKET_STRUCT ) hb_itemGetPtrGC( pItem, &s_gcInetFuncs );
|
||||
|
||||
@@ -247,6 +280,8 @@ HB_BOOL hb_znetInetInitialize( PHB_ITEM pItem, PHB_ZNETSTREAM pStream,
|
||||
socket->sendFunc = sendFunc;
|
||||
socket->flushFunc = flushFunc;
|
||||
socket->cleanFunc = cleanFunc;
|
||||
socket->errorFunc = errorFunc;
|
||||
socket->errstrFunc = errstrFunc;
|
||||
socket->stream = pStream;
|
||||
return HB_TRUE;
|
||||
}
|
||||
@@ -300,8 +335,7 @@ HB_FUNC( HB_INETCLOSE )
|
||||
{
|
||||
if( socket->sd != HB_NO_SOCKET )
|
||||
{
|
||||
hb_socketShutdown( socket->sd, HB_SOCKET_SHUT_RDWR );
|
||||
hb_retni( hb_inetCloseSocket( socket ) );
|
||||
hb_retni( hb_inetCloseSocket( socket, HB_TRUE ) );
|
||||
#ifdef HB_INET_LINUX_INTERRUPT
|
||||
kill( 0, HB_INET_LINUX_INTERRUPT );
|
||||
#endif
|
||||
@@ -388,7 +422,10 @@ HB_FUNC( HB_INETERRORDESC )
|
||||
case HB_INET_ERR_CLOSEDSOCKET : hb_retc_const( "Closed socket" ); return;
|
||||
case HB_INET_ERR_BUFFOVERRUN : hb_retc_const( "Buffer overrun" ); return;
|
||||
default:
|
||||
hb_retc( hb_socketErrorStr( socket->iError ) );
|
||||
if( socket->errstrFunc )
|
||||
hb_retc( socket->errstrFunc( socket->stream, socket->iError ) );
|
||||
else
|
||||
hb_retc( hb_socketErrorStr( socket->iError ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -706,7 +743,7 @@ static void s_inetRecvInternal( int iMode )
|
||||
if( iMode == 0 ) /* Called from hb_inetRecv()? */
|
||||
break;
|
||||
}
|
||||
else if( iLen == -1 && hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT )
|
||||
else if( iLen == -1 && s_inetIsTimeout( socket ) )
|
||||
{
|
||||
/* timed out; let's see if we have to run a cb routine */
|
||||
iTimeElapsed += socket->iTimeout;
|
||||
@@ -794,7 +831,7 @@ static void s_inetRecvPattern( const char * const * patterns, int * patternsizes
|
||||
}
|
||||
|
||||
iLen = s_inetRecv( socket, &cChar, 1, HB_TRUE, socket->iTimeout );
|
||||
if( iLen == -1 && hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT )
|
||||
if( iLen == -1 && s_inetIsTimeout( socket ) )
|
||||
{
|
||||
iLen = -2; /* this signals timeout */
|
||||
iTimeElapsed += socket->iTimeout;
|
||||
@@ -1030,7 +1067,7 @@ static void s_inetSendInternal( HB_BOOL lAll )
|
||||
|
||||
if( socket->flushFunc && ( lLastSnd > 0 || ( lLastSnd == -1 &&
|
||||
socket->iTimeout >= 0 && socket->iTimeout < 10000 &&
|
||||
hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT ) ) )
|
||||
s_inetIsTimeout( socket ) ) ) )
|
||||
{
|
||||
/* TODO: safe information about unflushed data and try to call
|
||||
flush before entering receive wait sate */
|
||||
@@ -1138,7 +1175,7 @@ HB_FUNC( HB_INETSERVER )
|
||||
if( ! socket )
|
||||
HB_SOCKET_INIT( socket, pSocket );
|
||||
else if( socket->sd != HB_NO_SOCKET )
|
||||
hb_inetCloseSocket( socket );
|
||||
hb_inetCloseSocket( socket, HB_FALSE );
|
||||
socket->sd = hb_socketOpen( HB_SOCKET_PF_INET, HB_SOCKET_PT_STREAM, 0 );
|
||||
if( socket->sd == HB_NO_SOCKET )
|
||||
hb_inetGetError( socket );
|
||||
@@ -1155,7 +1192,7 @@ HB_FUNC( HB_INETSERVER )
|
||||
hb_socketListen( socket->sd, iListen ) != 0 )
|
||||
{
|
||||
hb_inetGetError( socket );
|
||||
hb_inetCloseSocket( socket );
|
||||
hb_inetCloseSocket( socket, HB_FALSE );
|
||||
}
|
||||
else
|
||||
socket->iError = HB_INET_ERR_OK;
|
||||
@@ -1219,7 +1256,7 @@ static void hb_inetConnectInternal( HB_BOOL fResolve )
|
||||
if( ! socket )
|
||||
HB_SOCKET_INIT( socket, pSocket );
|
||||
else if( socket->sd != HB_NO_SOCKET )
|
||||
hb_inetCloseSocket( socket );
|
||||
hb_inetCloseSocket( socket, HB_FALSE );
|
||||
|
||||
if( fResolve )
|
||||
szHost = szAddr = hb_socketResolveAddr( szHost, HB_SOCKET_AF_INET );
|
||||
@@ -1310,7 +1347,7 @@ HB_FUNC( HB_INETDGRAMBIND )
|
||||
s_inetBind( socket, socket->remote, socket->remotelen ) != 0 )
|
||||
{
|
||||
hb_inetGetError( socket );
|
||||
hb_inetCloseSocket( socket );
|
||||
hb_inetCloseSocket( socket, HB_FALSE );
|
||||
}
|
||||
else if( hb_pcount() >= 4 )
|
||||
{
|
||||
|
||||
@@ -61,14 +61,14 @@ HB_FUNC( HB_INETCOMPRESS )
|
||||
iStrategy = hb_parnidef( 3, HB_ZLIB_STRATEGY_DEFAULT );
|
||||
|
||||
if( iLevel == HB_ZLIB_COMPRESSION_DISABLE )
|
||||
hb_znetInetInitialize( pItem, NULL, NULL, NULL, NULL, NULL );
|
||||
hb_znetInetInitialize( pItem, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
|
||||
else
|
||||
{
|
||||
PHB_ZNETSTREAM pStream = hb_znetOpen( iLevel, iStrategy );
|
||||
if( pStream == NULL )
|
||||
pItem = NULL; /* to force RTE */
|
||||
if( hb_znetInetInitialize( pItem, pStream, hb_znetRead, hb_znetWrite,
|
||||
hb_znetFlush, hb_znetClose ) )
|
||||
hb_znetFlush, hb_znetClose, NULL, NULL ) )
|
||||
{
|
||||
int keylen = ( int ) hb_parclen( 4 );
|
||||
if( keylen )
|
||||
|
||||
@@ -133,9 +133,7 @@ METHOD Edit() CLASS HBMemoEditor
|
||||
|
||||
// Is it a configurable key?
|
||||
IF AScan( aConfigurableKeys, nKey ) > 0
|
||||
IF ::HandleUserKey( nKey, ::xDo( iif( ::lDirty, ME_UNKEYX, ME_UNKEY ) ) )
|
||||
|
||||
ENDIF
|
||||
::HandleUserKey( nKey, ::xDo( iif( ::lDirty, ME_UNKEYX, ME_UNKEY ) ) )
|
||||
ELSE
|
||||
::super:Edit( nKey )
|
||||
ENDIF
|
||||
@@ -201,8 +199,8 @@ METHOD IdleHook() CLASS HBMemoEditor
|
||||
|
||||
METHOD HandleUserKey( nKey, nUdfReturn ) CLASS HBMemoEditor
|
||||
|
||||
DO CASE
|
||||
CASE nUdfReturn == ME_DEFAULT
|
||||
SWITCH nUdfReturn
|
||||
CASE ME_DEFAULT
|
||||
|
||||
// I won't reach this point during ME_INIT since ME_DEFAULT ends initialization phase of MemoEdit()
|
||||
|
||||
@@ -219,8 +217,9 @@ METHOD HandleUserKey( nKey, nUdfReturn ) CLASS HBMemoEditor
|
||||
ELSE
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
EXIT
|
||||
|
||||
CASE nUdfReturn == ME_DATA
|
||||
CASE ME_DATA
|
||||
IF HB_ISNUMERIC( nKey )
|
||||
IF nKey <= 256
|
||||
::super:Edit( nKey )
|
||||
@@ -228,25 +227,35 @@ METHOD HandleUserKey( nKey, nUdfReturn ) CLASS HBMemoEditor
|
||||
ELSE
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
EXIT
|
||||
|
||||
CASE nUdfReturn == ME_TOGGLEWRAP
|
||||
CASE ME_TOGGLEWRAP
|
||||
::lWordWrap := ! ::lWordWrap
|
||||
EXIT
|
||||
|
||||
CASE nUdfReturn == ME_TOGGLESCROLL
|
||||
CASE ME_TOGGLESCROLL
|
||||
// TODO: HBEditor does not support vertical scrolling of text inside window without moving cursor position
|
||||
EXIT
|
||||
|
||||
CASE nUdfReturn == ME_WORDRIGHT
|
||||
CASE ME_WORDRIGHT
|
||||
::MoveCursor( K_CTRL_RIGHT )
|
||||
EXIT
|
||||
|
||||
CASE nUdfReturn == ME_BOTTOMRIGHT
|
||||
CASE ME_BOTTOMRIGHT
|
||||
::MoveCursor( K_CTRL_END )
|
||||
EXIT
|
||||
|
||||
#ifndef HB_CLP_STRICT
|
||||
CASE nUdfReturn == ME_PASTE /* Xbase++ compatibility */
|
||||
CASE ME_PASTE /* Xbase++ compatibility */
|
||||
hb_gtInfo( HB_GTI_CLIPBOARDPASTE )
|
||||
EXIT
|
||||
#endif
|
||||
|
||||
CASE nUdfReturn != ME_IGNORE
|
||||
CASE ME_IGNORE
|
||||
/* do nothing */
|
||||
EXIT
|
||||
|
||||
OTHERWISE
|
||||
|
||||
// TOFIX: Not CA-Cl*pper compatible, see teditor.prg
|
||||
IF HB_ISNUMERIC( nKey ) .AND. ( ( nKey >= 1 .AND. nKey <= 31 ) .OR. nKey == K_ALT_W )
|
||||
@@ -255,7 +264,7 @@ METHOD HandleUserKey( nKey, nUdfReturn ) CLASS HBMemoEditor
|
||||
RETURN .F.
|
||||
ENDIF
|
||||
|
||||
ENDCASE
|
||||
ENDSWITCH
|
||||
|
||||
RETURN .T.
|
||||
|
||||
@@ -313,8 +322,7 @@ FUNCTION MemoEdit( ;
|
||||
hb_default( @nWindowColumn , nTextBuffColumn )
|
||||
hb_default( @cString , "" )
|
||||
|
||||
/* Original MemoEdit() converts tabs into spaces */
|
||||
oEd := HBMemoEditor():New( StrTran( cString, Chr( 9 ), Space( 1 ) ), ;
|
||||
oEd := HBMemoEditor():New( cString, ;
|
||||
hb_defaultValue( nTop, 0 ), ;
|
||||
nLeft, ;
|
||||
hb_defaultValue( nBottom, MaxRow() ), ;
|
||||
|
||||
@@ -139,7 +139,7 @@ CREATE CLASS HBEditor
|
||||
VAR nNumCols AS NUMERIC INIT 1 // How many columns / rows can be displayed inside editor window
|
||||
VAR nNumRows AS NUMERIC INIT 1
|
||||
|
||||
VAR nTabWidth AS NUMERIC INIT 8 // Size of Tab chars
|
||||
VAR nTabWidth AS NUMERIC INIT 4 // Size of Tab chars
|
||||
VAR lEditAllow AS LOGICAL INIT .T. // Are changes to text allowed?
|
||||
VAR lSaved AS LOGICAL INIT .F. // True if user exited editor with K_CTRL_W
|
||||
VAR lWordWrap AS LOGICAL INIT .F. // True if word wrapping is active
|
||||
@@ -209,7 +209,7 @@ METHOD LoadFile( cFileName ) CLASS HBEditor
|
||||
cString := ""
|
||||
ENDIF
|
||||
|
||||
::aText := Text2Array( cString, iif( ::lWordWrap, ::nNumCols, ) )
|
||||
::aText := Text2Array( cString, iif( ::lWordWrap, ::nNumCols, ), ::nTabWidth )
|
||||
::naTextLen := Len( ::aText )
|
||||
|
||||
IF ::naTextLen == 0
|
||||
@@ -224,7 +224,7 @@ METHOD LoadFile( cFileName ) CLASS HBEditor
|
||||
|
||||
METHOD LoadText( cString ) CLASS HBEditor
|
||||
|
||||
::aText := Text2Array( cString, iif( ::lWordWrap, ::nNumCols, ) )
|
||||
::aText := Text2Array( cString, iif( ::lWordWrap, ::nNumCols, ), ::nTabWidth )
|
||||
::naTextLen := Len( ::aText )
|
||||
|
||||
IF ::naTextLen == 0
|
||||
@@ -373,23 +373,14 @@ METHOD SplitLine( nRow ) CLASS HBEditor
|
||||
DO WHILE !( SubStr( cLine, --nFirstSpace, 1 ) == " " ) .AND. nFirstSpace > 1
|
||||
ENDDO
|
||||
|
||||
// If there is a space before beginning of line split there
|
||||
IF nFirstSpace > 1
|
||||
cSplitLine := Left( cLine, nFirstSpace )
|
||||
ELSE
|
||||
// else split at current cursor position
|
||||
cSplitLine := Left( cLine, ::nCol - 1 )
|
||||
ENDIF
|
||||
|
||||
::InsertLine( cSplitLine, .T., nStartRow++ )
|
||||
|
||||
::InsertLine( cSplitLine := ;
|
||||
Left( cLine, iif( nFirstSpace > 1, nFirstSpace, ::nCol - 1 ) ), .T., nStartRow++ )
|
||||
ELSE
|
||||
// remainder of line
|
||||
cSplitLine := cLine
|
||||
::InsertLine( cSplitLine, .F., nStartRow++ )
|
||||
::InsertLine( cSplitLine := cLine, .F., nStartRow++ )
|
||||
ENDIF
|
||||
|
||||
cLine := Right( cLine, Len( cLine ) - Len( cSplitLine ) )
|
||||
cLine := SubStr( cLine, Len( cSplitLine ) + 1 )
|
||||
ENDDO
|
||||
|
||||
IF lMoveToNextLine
|
||||
@@ -772,13 +763,15 @@ METHOD Edit( nPassedKey ) CLASS HBEditor
|
||||
::RefreshLine()
|
||||
|
||||
CASE nKey == K_BS
|
||||
::lDirty := .T.
|
||||
// delete previous character
|
||||
::aText[ ::nRow ]:cText := Stuff( ::aText[ ::nRow ]:cText, --::nCol, 1, "" )
|
||||
// correct column position for next call to MoveCursor()
|
||||
::nCol++
|
||||
::MoveCursor( K_LEFT )
|
||||
::RefreshLine()
|
||||
IF ::nCol > 1
|
||||
::lDirty := .T.
|
||||
// delete previous character
|
||||
::aText[ ::nRow ]:cText := Stuff( ::aText[ ::nRow ]:cText, --::nCol, 1, "" )
|
||||
// correct column position for next call to MoveCursor()
|
||||
::nCol++
|
||||
::MoveCursor( K_LEFT )
|
||||
::RefreshLine()
|
||||
ENDIF
|
||||
|
||||
CASE nKey == K_CTRL_Y
|
||||
::lDirty := .T.
|
||||
@@ -1003,7 +996,7 @@ METHOD New( cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabS
|
||||
nLineLength := NIL
|
||||
ENDIF
|
||||
|
||||
::aText := Text2Array( hb_defaultValue( cString, "" ), nLineLength )
|
||||
::aText := Text2Array( hb_defaultValue( cString, "" ), nLineLength, ::nTabWidth )
|
||||
::naTextLen := Len( ::aText )
|
||||
|
||||
IF ::naTextLen == 0
|
||||
@@ -1038,7 +1031,7 @@ METHOD New( cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabS
|
||||
|
||||
::nFirstRow := Max( 1, nTextRow - nWndRow )
|
||||
::nFirstCol := nTextCol - nWndCol + 1
|
||||
IF ::nFirstCol < 1
|
||||
IF ::nFirstCol < 1
|
||||
nTextCol -= ::nFirstCol - 1
|
||||
::nFirstCol := 1
|
||||
ENDIF
|
||||
@@ -1051,8 +1044,8 @@ METHOD New( cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabS
|
||||
::nFirstRow := ::naTextLen
|
||||
ENDIF
|
||||
|
||||
IF ( ::nFirstRow + nWndRow ) > ::naTextLen
|
||||
DO WHILE ( ::nFirstRow + ( --nWndRow ) ) > ::naTextLen
|
||||
IF ::nFirstRow + nWndRow > ::naTextLen
|
||||
DO WHILE ::nFirstRow + --nWndRow > ::naTextLen
|
||||
ENDDO
|
||||
ENDIF
|
||||
|
||||
@@ -1066,71 +1059,25 @@ METHOD New( cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabS
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
// Returns EOL char (be it either CR or LF or both)
|
||||
STATIC FUNCTION WhichEOL( cString )
|
||||
|
||||
LOCAL nCRPos := At( Chr( 13 ), cString )
|
||||
LOCAL nLFPos := At( Chr( 10 ), cString )
|
||||
|
||||
IF nCRPos > 0 .AND. nLFPos == 0
|
||||
RETURN Chr( 13 )
|
||||
ELSEIF nCRPos == 0 .AND. nLFPos > 0
|
||||
RETURN Chr( 10 )
|
||||
ELSEIF nCRPos > 0 .AND. nLFPos == nCRPos + 1
|
||||
RETURN Chr( 13 ) + Chr( 10 )
|
||||
ENDIF
|
||||
|
||||
RETURN hb_eol()
|
||||
|
||||
// Converts a string to an array of strings splitting input string at EOL boundaries
|
||||
STATIC FUNCTION Text2Array( cString, nWordWrapCol )
|
||||
STATIC FUNCTION Text2Array( cString, nWordWrapCol, nTabWidth )
|
||||
|
||||
LOCAL aArray := {}
|
||||
LOCAL cEOL := WhichEOL( cString )
|
||||
LOCAL nEOLLen := Len( cEOL )
|
||||
LOCAL nRetLen := 0
|
||||
LOCAL ncSLen := Len( cString )
|
||||
LOCAL nTokPos := 0
|
||||
|
||||
LOCAL cLine
|
||||
LOCAL nFirstSpace
|
||||
LOCAL cSplitLine
|
||||
LOCAL nLines
|
||||
LOCAL nLine
|
||||
|
||||
DO WHILE nRetLen < ncSLen
|
||||
|
||||
cLine := hb_tokenPtr( @cString, @nTokPos, cEOL )
|
||||
|
||||
nRetLen += Len( cLine ) + nEOLLen
|
||||
FOR EACH cLine IN hb_ATokens( cString, .T. )
|
||||
|
||||
IF nWordWrapCol != NIL .AND. Len( cLine ) > nWordWrapCol
|
||||
|
||||
DO WHILE ! Empty( cLine )
|
||||
|
||||
// Split line at nWordWrapCol boundary
|
||||
IF Len( cLine ) > nWordWrapCol
|
||||
|
||||
nFirstSpace := nWordWrapCol
|
||||
DO WHILE !( SubStr( cLine, --nFirstSpace, 1 ) == " " ) .AND. nFirstSpace > 1
|
||||
ENDDO
|
||||
|
||||
IF nFirstSpace > 1
|
||||
cSplitLine := Left( cLine, nFirstSpace )
|
||||
ELSE
|
||||
cSplitLine := Left( cLine, nWordWrapCol )
|
||||
ENDIF
|
||||
|
||||
AAdd( aArray, HBTextLine():New( cSplitLine, .T. ) )
|
||||
ELSE
|
||||
// remainder of line is shorter than split point
|
||||
cSplitLine := cLine
|
||||
AAdd( aArray, HBTextLine():New( cSplitLine, .F. ) )
|
||||
ENDIF
|
||||
|
||||
cLine := Right( cLine, Len( cLine ) - Len( cSplitLine ) )
|
||||
ENDDO
|
||||
nLines := MLCount( cLine, nWordWrapCol, nTabWidth )
|
||||
FOR nLine := 1 TO nLines
|
||||
AAdd( aArray, HBTextLine():New( MemoLine( cLine, nWordWrapCol, nLine, nTabWidth ), ;
|
||||
nLine < nLines ) )
|
||||
NEXT
|
||||
ELSE
|
||||
AAdd( aArray, HBTextLine():New( cLine, .F. ) )
|
||||
ENDIF
|
||||
ENDDO
|
||||
NEXT
|
||||
|
||||
RETURN aArray
|
||||
|
||||
@@ -915,6 +915,7 @@ METHOD GUIReader( oGet, oMenu, aMsg ) CLASS HBGetList
|
||||
oGet:varPut( oGUI:value )
|
||||
EXIT
|
||||
ENDIF
|
||||
/* fall through */
|
||||
OTHERWISE
|
||||
oGet:varPut( oGUI:buffer )
|
||||
ENDSWITCH
|
||||
@@ -942,6 +943,7 @@ METHOD GUIApplyKey( oGet, oGUI, nKey, oMenu, aMsg ) CLASS HBGetList
|
||||
LOCAL nMRow
|
||||
LOCAL nMCol
|
||||
LOCAL nButton
|
||||
LOCAL cKey
|
||||
|
||||
// Check for SET KEY first
|
||||
IF ( bKeyBlock := SetKey( nKey ) ) != NIL
|
||||
@@ -1011,7 +1013,8 @@ METHOD GUIApplyKey( oGet, oGUI, nKey, oMenu, aMsg ) CLASS HBGetList
|
||||
nKey := 0
|
||||
ENDIF
|
||||
|
||||
ELSEIF ( nButton := oGUI:FindText( hb_keyChar( nKey ), oGUI:Value + 1, .F., .F. ) ) != 0
|
||||
ELSEIF !( ( cKey := hb_keyChar( nKey ) ) == "" ) .AND. ;
|
||||
( nButton := oGUI:FindText( cKey, oGUI:Value + 1, .F., .F. ) ) != 0
|
||||
oGUI:Select( nButton )
|
||||
|
||||
ENDIF
|
||||
@@ -1189,6 +1192,7 @@ METHOD GUIPostValidate( oGet, oGUI, aMsg ) CLASS HBGetList
|
||||
xNewValue := oGUI:value
|
||||
EXIT
|
||||
ENDIF
|
||||
/* fall through */
|
||||
OTHERWISE
|
||||
xNewValue := oGUI:buffer
|
||||
ENDSWITCH
|
||||
@@ -1210,7 +1214,7 @@ METHOD GUIPostValidate( oGet, oGUI, aMsg ) CLASS HBGetList
|
||||
SetPos( oGet:row, oGet:col )
|
||||
|
||||
::ShowScoreBoard()
|
||||
IF ! ( oGUI:ClassName() == "TBROWSE" )
|
||||
IF !( oGUI:ClassName() == "TBROWSE" )
|
||||
oGUI:Select( oGet:varGet() )
|
||||
ENDIF
|
||||
|
||||
@@ -1219,7 +1223,7 @@ METHOD GUIPostValidate( oGet, oGUI, aMsg ) CLASS HBGetList
|
||||
__GetListLast( Self )
|
||||
|
||||
IF ::lKillRead
|
||||
oGet:exitState := GE_ESCAPE // Provokes ReadModal() exit
|
||||
oGet:exitState := GE_ESCAPE // Provokes ReadModal() exit
|
||||
lValid := .T.
|
||||
ENDIF
|
||||
|
||||
|
||||
Reference in New Issue
Block a user