20000503-00:01 GMT+2 Maurilio Longo <maurilio.longo@libero.it>

This commit is contained in:
Maurilio Longo
2000-05-02 22:07:12 +00:00
parent 3587cf37d7
commit 193c2225ad
3 changed files with 200 additions and 148 deletions

View File

@@ -1,13 +1,24 @@
20000503-00:01 GMT+2 Maurilio Longo <maurilio.longo@libero.it>
* source/rtl/teditor.prg
+ added word wrapping capabilities
* text is saved if user presses K_ALT_W (sorry) this deviates from clipper
but until we find a way to detect real K_CTRL_W it's better than nothing.
! fixed a bug in text splitting when on last line of text
* source/rtl/memoedit.prg
* changed to match new TEditor capabilities
20000502-22:04 GMT+1 Victor Szakats <info@szelvesz.hu>
* source/lang/msges.c
! Updated by Jose Lalin
20000502-19:28 GMT+1 Victor Szakats <info@szelvesz.hu>
* source/vm/hvm.c
% hb_vmFunction() and hb_vmSendFunc() "inlined".
Note that hb_vmFunction() is still there since it's used from one
Note that hb_vmFunction() is still there since it's used from one
places in classes.c.
- Redundant declaration removed.
@@ -24,8 +35,8 @@
! Typo.
* make_gnu.cmd
+ Error output redirection readded to be in sync with the other make
files. If you need to customize this for your own taste, please make
+ Error output redirection readded to be in sync with the other make
files. If you need to customize this for your own taste, please make
a local copy of it before.
20000502-17:15 GMT+1 Ryszard Glab <rglab@imid.med.pl>
@@ -35,29 +46,29 @@
*source/vm/Makefile
-source/rtl/eval.c
+source/vm/eval.c
* fixed bug in EVAL function when a parameter was passed using
the reference
* since the EVAL function is using a direct stack access instead
of hb_param() function the file eval.c is now moved into
VM directory
* fixed bug in EVAL function when a parameter was passed using
the reference
* since the EVAL function is using a direct stack access instead
of hb_param() function the file eval.c is now moved into
VM directory
20000502-16:22 GMT+1 Ryszard Glab <rglab@imid.med.pl>
*source/compiler/harbour.l
* fixed syntax:
RETURN ++variable
* fixed syntax:
RETURN ++variable
20000502-16:07 GMT+1 Ryszard Glab <rglab@imid.med.pl>
*source/compiler/hbpcode.c
* increased buffers size used by sprintf to avoid GPF/code dumps
* increased buffers size used by sprintf to avoid GPF/code dumps
20000502-14:55 GMT+1 Ryszard Glab <rglab@imid.med.pl>
*source/vm/hvm.c
* fixed bug during accessing a constant arrays caused by
the optimization - { 1, 2, 3 }[ n ]
* fixed bug during accessing a constant arrays caused by
the optimization - { 1, 2, 3 }[ n ]
20000502-14:25 GMT+1 Ryszard Glab <rglab@imid.med.pl>
@@ -75,8 +86,8 @@
* source/compiler/hbfix.c
* source/compiler/genc.c
* source/vm/hvm.c
+ HB_P_SEND and HB_P_SENDSHORT pcodes added. At this moment they are
exactly the same as HB_P_FUNCTION[SHORT]. More work is needed to
+ HB_P_SEND and HB_P_SENDSHORT pcodes added. At this moment they are
exactly the same as HB_P_FUNCTION[SHORT]. More work is needed to
optimize the stack usage for SEND/DO/FUNCTION.
+ hb_vmSend() function added.

View File

@@ -38,17 +38,17 @@
#include "common.ch"
FUNCTION MemoEdit( cString,;
nTop, nLeft,;
nBottom, nRight,;
lEditMode,;
cUserFunction,;
nLineLength,;
nTabSize,;
nTextBuffRow,;
nTextBuffColumn,;
nWindowRow,;
nWindowColumn )
FUNCTION MemoEdit(cString,;
nTop, nLeft,;
nBottom, nRight,;
lEditMode,;
cUserFunction,;
nLineLength,;
nTabSize,;
nTextBuffRow,;
nTextBuffColumn,;
nWindowRow,;
nWindowColumn)
LOCAL oEd
@@ -64,10 +64,10 @@ FUNCTION MemoEdit( cString,;
DEFAULT nWindowRow TO 0
DEFAULT nWindowColumn TO nTextBuffColumn
oEd := TEditor():New( cString, nTop, nLeft, nBottom, nRight, lEditMode )
oEd := TEditor():New(cString, nTop, nLeft, nBottom, nRight, lEditMode, nil, nLineLength, nTabSize)
oEd:RefreshWindow()
if ! ISLOGICAL( cUserFunction ) .OR. cUserFunction == .T.
if ! ISLOGICAL(cUserFunction) .OR. cUserFunction == .T.
oEd:Edit()
if oEd:lSaved
cString := oEd:GetText()

View File

@@ -43,38 +43,40 @@
CLASS TEditor
DATA cFile INIT "" // name of file being edited
DATA cFile INIT "" // name of file being edited
DATA aText INIT {} // array with lines of text being edited
DATA naTextLen INIT 0 // number of lines of text inside aText. Len function is not OK since deleting elements from
// array creates NIL elements at array end which kill every text funcion (like substr) used on
// array elements
DATA aText INIT {} // array with lines of text being edited
DATA naTextLen INIT 0 // number of lines of text inside aText. Len function is not OK since deleting elements from
// array creates NIL elements at array end which kill every text funcion (like substr) used on
// array elements
DATA nTop // boundaries of editor window, without box around
DATA nTop // boundaries of editor window, without box around
DATA nLeft
DATA nBottom
DATA nRight
DATA nFirstCol INIT 1 // FirstCol/Row of current text visible inside editor window
DATA nFirstRow INIT 1
DATA nRow INIT 1 // Cursor position inside aText (nRow) and inside current line of text (nCol)
DATA nCol INIT 1
DATA nNumCols INIT 1 // How many columns / rows can be displayed inside editor window
DATA nNumRows INIT 1
DATA nFirstCol INIT 1 // FirstCol/Row of current text visible inside editor window
DATA nFirstRow INIT 1
DATA nRow INIT 1 // Cursor position inside aText (nRow) and inside current line of text (nCol)
DATA nCol INIT 1
DATA nNumCols INIT 1 // How many columns / rows can be displayed inside editor window
DATA nNumRows INIT 1
DATA lInsert INIT .F. // Is editor in Insert mode or in Overstrike one?
DATA nTabWidth INIT 8 // Size of Tab chars
DATA lEditAllow INIT .T. // Are changes to text allowed?
DATA lSaved INIT .F. // True if user exited editor with K_CTRL_W
DATA lInsert INIT .F. // Is editor in Insert mode or in Overstrike one?
DATA nTabWidth INIT 8 // Size of Tab chars
DATA lEditAllow INIT .T. // Are changes to text allowed?
DATA lSaved INIT .F. // True if user exited editor with K_CTRL_W
DATA lWordWrap INIT .F. // True if word wrapping is active
DATA nWordWrapCol INIT 0 // At which column word wrapping occurs
METHOD New(cString, nTop, nLeft, nBottom, nRight, lEditMode)
METHOD New(cString, nTop, nLeft, nBottom, nRight, lEditMode, cUdF, nLineLength, nTabSize)
METHOD GetText() // Returns aText as a string (for MemoEdit())
METHOD RefreshWindow()
METHOD RefreshLine()
METHOD RefreshColumn()
METHOD MoveCursor(nKey)
METHOD InsertState(lInsState) // Changes lInsert value and insertion / overstrike mode of editor
METHOD Edit()
METHOD Edit(nPassedKey)
ENDCLASS
@@ -125,7 +127,7 @@ METHOD GetText() CLASS TEditor
return cString
METHOD New(cString, nTop, nLeft, nBottom, nRight, lEditMode) CLASS TEditor
METHOD New(cString, nTop, nLeft, nBottom, nRight, lEditMode, cUdF, nLineLength, nTabSize) CLASS TEditor
::aText := Text2Array(cString)
::naTextLen := Len(::aText)
@@ -149,6 +151,17 @@ METHOD New(cString, nTop, nLeft, nBottom, nRight, lEditMode) CLASS TEditor
::InsertState(::lInsert)
endif
// is word wrap required?
if !nLineLength == NIL
::lWordWrap := .T.
::nWordWrapCol := nLineLength
endif
// how many spaces for each tab?
if !nTabSize == NIL
::nTabWidth := nTabSize
endif
// Empty area of screen which will hold editor window
Scroll(nTop, nLeft, nBottom, nRight)
@@ -392,117 +405,145 @@ METHOD InsertState(lInsState) CLASS TEditor
return Self
// if editing isn't allowed we enter this loop which
// handles only movement keys and discards all the others
STATIC procedure BrowseText(oSelf)
LOCAL nKey
while (nKey := InKey(0)) <> K_ESC
oSelf:MoveCursor(nKey)
enddo
return
// Edits text
METHOD Edit() CLASS TEditor
METHOD Edit(nPassedKey) CLASS TEditor
LOCAL i, nKey
LOCAL i, nKey, lOldInsert
LOCAL lKeepGoing := .T.
/* NOTE: changing EditMode SHOULD NOT be allowed from inside editor. Edit() method relies upon lEditAllow
being fixed for current editing session */
while ::lEditAllow
if !::lEditAllow
BrowseText(Self)
nKey := InKey(0)
do case
case (nKey >= 32 .AND. nKey < 256)
// insert char if in insert mode or at end of current line
if ::lInsert .OR. (::nCol > Len(::aText[::nRow]))
::aText[::nRow] := Stuff(::aText[::nRow], ::nCol, 0, Chr(nKey))
else
::aText[::nRow] := Stuff(::aText[::nRow], ::nCol, 1, Chr(nKey))
endif
::MoveCursor(K_RIGHT)
::RefreshLine()
else
case (nKey == K_RETURN)
if ::lInsert .OR. ::nRow == ::naTextLen
AAdd(::aText, "")
if ::nRow < ::naTextLen
AIns(::aText, ::nRow + 1)
if Len(::aText[::nRow]) > 0
// Split current line at cursor position
::aText[::nRow + 1] := Right(::aText[::nRow], Len(::aText[::nRow]) - ::nCol + 1)
::aText[::nRow] := Left(::aText[::nRow], ::nCol - 1)
else
::aText[::nRow + 1] := ""
endif
while lKeepGoing
// If I've been called with a key already preset, evaluate this key and then exit
if nPassedKey == NIL
nKey := InKey(0)
else
lKeepGoing := .F.
nKey := nPassedKey
endif
do case
case (nKey >= 32 .AND. nKey <= 255)
// insert char if in insert mode or at end of current line
if ::lInsert .OR. (::nCol > Len(::aText[::nRow]))
::aText[::nRow] := Stuff(::aText[::nRow], ::nCol, 0, Chr(nKey))
else
::aText[::nRow] := Stuff(::aText[::nRow], ::nCol, 1, Chr(nKey))
endif
::naTextLen++
endif
::MoveCursor(K_DOWN)
::MoveCursor(K_HOME)
case (nKey == K_INS)
::InsertState(!::lInsert)
case (nKey == K_DEL)
::aText[::nRow] := Stuff(::aText[::nRow], ::nCol, 1, "")
::RefreshLine()
if Len(::aText[::nRow]) == 0
KEYBOARD Chr(K_CTRL_Y)
endif
case (nKey == K_TAB)
// insert char if in insert mode or at end of current line
if ::lInsert .OR. (::nCol == Len(::aText[::nRow]))
::aText[::nRow] := Stuff(::aText[::nRow], ::nCol, 0, Space(::nTabWidth))
endif
for i := 1 to ::nTabWidth
::MoveCursor(K_RIGHT)
next
::RefreshLine()
case (nKey == K_BS)
// delete previous character
::aText[::nRow] := Stuff(::aText[::nRow], --::nCol, 1, "")
// correct column position for next call to MoveCursor()
::nCol++
::MoveCursor(K_LEFT)
::RefreshLine()
case (nKey == K_CTRL_Y)
if ::naTextLen > 1
// delete current line of text
ADel(::aText, ::nRow)
ASize(::aText, --::naTextLen)
// if we now have less than a screen full of text, adjust nFirstRow position
if ::nFirstRow + ::nNumRows > ::naTextLen
::nFirstRow := Max(::nFirstRow - 1, 1)
// if we have less lines of text than our current position on scree, up one line
if ::nRow > ::naTextLen
::nRow := Max(::nRow - 1, 1)
SetPos(Max(Row() -1, ::nTop), Col())
endif
endif
::RefreshWindow()
else
::aText[::nRow] := ""
::RefreshLine()
endif
case (::MoveCursor(nKey))
// if it's a movement key ::MoveCursor() handles it
// if we need to word wrap a word we simulate a word left + return
if ::lWordWrap .AND. (::nCol > ::nWordWrapCol)
::MoveCursor(K_CTRL_LEFT)
::MoveCursor(K_CTRL_RIGHT)
lOldInsert := ::lInsert
::lInsert := .T.
::Edit(K_RETURN)
::lInsert := lOldInsert
::MoveCursor(K_CTRL_RIGHT)
endif
case (nKey == K_CTRL_W)
::lSaved := .T.
exit
case (nKey == K_RETURN)
if ::lInsert .OR. ::nRow == ::naTextLen
AAdd(::aText, "")
if ::nRow <= ::naTextLen
AIns(::aText, ::nRow + 1)
if Len(::aText[::nRow]) > 0
// Split current line at cursor position
::aText[::nRow + 1] := Right(::aText[::nRow], Len(::aText[::nRow]) - ::nCol + 1)
::aText[::nRow] := Left(::aText[::nRow], ::nCol - 1)
else
::aText[::nRow + 1] := ""
endif
endif
// I increment naTextLen only here because now there is a "real" line of text, before
// this point we have only added some "space" to split current line
::naTextLen++
endif
::MoveCursor(K_DOWN)
::MoveCursor(K_HOME)
case (nKey == K_ESC)
exit
case (nKey == K_INS)
::InsertState(!::lInsert)
otherwise
/* TODO: Here we should call an user defined function (to match memoedit() behaviour) */
case (nKey == K_DEL)
::aText[::nRow] := Stuff(::aText[::nRow], ::nCol, 1, "")
::RefreshLine()
if Len(::aText[::nRow]) == 0
KEYBOARD Chr(K_CTRL_Y)
endif
case (nKey == K_TAB)
// insert char if in insert mode or at end of current line
if ::lInsert .OR. (::nCol == Len(::aText[::nRow]))
::aText[::nRow] := Stuff(::aText[::nRow], ::nCol, 0, Space(::nTabWidth))
endif
for i := 1 to ::nTabWidth
::MoveCursor(K_RIGHT)
next
::RefreshLine()
case (nKey == K_BS)
// delete previous character
::aText[::nRow] := Stuff(::aText[::nRow], --::nCol, 1, "")
// correct column position for next call to MoveCursor()
::nCol++
::MoveCursor(K_LEFT)
::RefreshLine()
case (nKey == K_CTRL_Y)
if ::naTextLen > 1
// delete current line of text
ADel(::aText, ::nRow)
ASize(::aText, --::naTextLen)
// if we now have less than a screen full of text, adjust nFirstRow position
if ::nFirstRow + ::nNumRows > ::naTextLen
::nFirstRow := Max(::nFirstRow - 1, 1)
// if we have less lines of text than our current position on scree, up one line
if ::nRow > ::naTextLen
::nRow := Max(::nRow - 1, 1)
SetPos(Max(Row() -1, ::nTop), Col())
endif
endif
::RefreshWindow()
else
::aText[::nRow] := ""
::RefreshLine()
endif
case (::MoveCursor(nKey))
// if it's a movement key ::MoveCursor() handles it
case (nKey == K_ALT_W)
/* TOFIX: Not clipper compatible */
::lSaved := .T.
lKeepGoing := .F.
case (nKey == K_ESC)
lKeepGoing := .F.
otherwise
/* TODO: Here we should call an user defined function (to match memoedit() behaviour) */
endcase
enddo
// if editing isn't allowed we enter this loop (instead of the previous one), this loop
// handles only movement keys and discards all the others
while !::lEditAllow
nKey := InKey(0)
if nKey <> K_ESC
::MoveCursor(nKey)
else
exit
endif
enddo
enddo
endif
return Self