20000503-00:01 GMT+2 Maurilio Longo <maurilio.longo@libero.it>
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user