2000-12-18 16:55 GMT+1 Maurilio Longo <maurilio.longo@libero.it>
* source/rtl/memoedit.prg
+ Added all missing functionalities. Should be 100% compatible (tested very little)
* source/rtl/teditor.prg
* little changes to make it work better with memoedit.prg. Removed cUdF parameter from
::New() method.
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
2000-12-18 16:55 GMT+1 Maurilio Longo <maurilio.longo@libero.it>
|
||||
* source/rtl/memoedit.prg
|
||||
+ Added all missing functionalities. Should be 100% compatible (tested very little)
|
||||
* source/rtl/teditor.prg
|
||||
* little changes to make it work better with memoedit.prg. Removed cUdF parameter from
|
||||
::New() method.
|
||||
|
||||
2000-12-15 22:10 GMT -3 Luiz Rafael Culik <culik@sl.conex.net>
|
||||
*utils/hbmake/radios.prg
|
||||
utils/hbmake/checks.prg
|
||||
|
||||
@@ -313,9 +313,8 @@ METHOD BrowseTable(lCanEdit, aExitKeys) CLASS TBrowseSQL
|
||||
|
||||
while lKeepGoing
|
||||
|
||||
if !::Stable
|
||||
::ForceStable()
|
||||
endif
|
||||
while !::Stabilize() .and. NextKey() == 0
|
||||
enddo
|
||||
|
||||
nKey := Inkey(0)
|
||||
|
||||
|
||||
@@ -33,12 +33,191 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* TODO: MemoEdit() is not compatible with clipper one.
|
||||
Needs a lot more work to become */
|
||||
|
||||
#include "common.ch"
|
||||
#include "hbclass.ch"
|
||||
#include "memoedit.ch"
|
||||
#include "inkey.ch"
|
||||
|
||||
|
||||
// A specialized TEditor which can simulate MemoEdit() behaviour
|
||||
CLASS TMemoEditor FROM TEditor
|
||||
|
||||
DATA xUserFunction // User Function called to change default MemoEdit() behaviour
|
||||
|
||||
METHOD MemoInit(cUserFunction) // This method is called after ::New() returns to perform ME_INIT actions
|
||||
METHOD Edit() // Calls super:Edit(nKey) but is needed to handle configurable keys
|
||||
METHOD KeyboardHook(nKey) // Gets called every time there is a key not handled directly by TEditor
|
||||
METHOD IdleHook() // Gets called every time there are no more keys to hanlde just before TEditor blocks itself waiting for a char
|
||||
|
||||
ENDCLASS
|
||||
|
||||
|
||||
METHOD MemoInit(cUserFunction) CLASS TMemoEditor
|
||||
|
||||
local nKey
|
||||
|
||||
default cUserFunction to nil
|
||||
|
||||
// Save/Init object internal representation of user function
|
||||
::xUserFunction := cUserFunction
|
||||
|
||||
if ::xUserFunction <> nil
|
||||
// Keep calling user function until it returns 0
|
||||
while (nKey := Do(::xUserFunction, ME_INIT, ::nRow, ::nCol - 1)) <> ME_DEFAULT
|
||||
|
||||
do case
|
||||
case nKey >= 1 .AND. nKey <= 31
|
||||
super:Edit(nKey)
|
||||
|
||||
case nKey == ME_DATA
|
||||
super:Edit(nKey)
|
||||
|
||||
case nKey == ME_TOGGLEWRAP
|
||||
::lWordWrap := !::lWordWrap
|
||||
|
||||
case nKey == ME_TOGGLESCROLL
|
||||
// Don't know what to do ;-)
|
||||
|
||||
case nKey == ME_WORDRIGHT
|
||||
::MoveCursor(K_CTRL_RIGHT)
|
||||
|
||||
case nKey == ME_BOTTOMRIGHT
|
||||
::MoveCursor(K_CTRL_END)
|
||||
|
||||
otherwise
|
||||
|
||||
endcase
|
||||
|
||||
enddo
|
||||
|
||||
endif
|
||||
|
||||
return Self
|
||||
|
||||
|
||||
METHOD Edit() CLASS TMemoEditor
|
||||
|
||||
local nKey, nUserKey
|
||||
local lKeepGoing := .T.
|
||||
|
||||
// NOTE: K_ALT_W is not compatible with clipper exit memo and save key, but I cannot discriminate
|
||||
// K_CTRL_W and K_CTRL_END from harbour code.
|
||||
local aConfigurableKeys := {K_CTRL_Y, K_CTRL_T, K_CTRL_B, K_CTRL_V, K_ALT_W, K_ESC }
|
||||
|
||||
// If I have an user function I need to trap configurable keys and ask to
|
||||
// user function if handle them the standard way or not
|
||||
if ::lEditAllow .AND. ::xUserFunction <> nil
|
||||
|
||||
while lKeepGoing
|
||||
|
||||
// I need to test this condition here since I never block inside TEditor:Edit()
|
||||
// if there is an user function
|
||||
if NextKey() == 0
|
||||
::IdleHook()
|
||||
endif
|
||||
nKey := Inkey(0)
|
||||
|
||||
// Is it a configurable key ?
|
||||
if AScan(aConfigurableKeys, nKey) > 0
|
||||
nUserKey := Do(::xUserFunction, iif(::lDirty, ME_UNKEYX, ME_UNKEY), ::nRow, ::nCol - 1)
|
||||
|
||||
do case
|
||||
case nUserKey == ME_DEFAULT
|
||||
super:Edit(nKey)
|
||||
if nKey == K_ESC .OR. ::lSaved
|
||||
lKeepGoing := .F.
|
||||
endif
|
||||
|
||||
case nUserKey >= 1 .AND. nUserKey <= 31
|
||||
super:Edit(nUserKey)
|
||||
|
||||
case nUserKey == ME_DATA
|
||||
super:Edit(nKey)
|
||||
|
||||
case nUserKey == ME_TOGGLEWRAP
|
||||
::lWordWrap := !::lWordWrap
|
||||
|
||||
case nUserKey == ME_TOGGLESCROLL
|
||||
// Don't know what to do ;-)
|
||||
|
||||
case nUserKey == ME_WORDRIGHT
|
||||
::MoveCursor(K_CTRL_RIGHT)
|
||||
|
||||
case nUserKey == ME_BOTTOMRIGHT
|
||||
::MoveCursor(K_CTRL_END)
|
||||
|
||||
otherwise
|
||||
|
||||
endcase
|
||||
|
||||
else
|
||||
super:Edit(nKey)
|
||||
|
||||
endif
|
||||
|
||||
enddo
|
||||
|
||||
else
|
||||
// If I can't edit text buffer or there is not a user function enter standard TEditor
|
||||
// ::Edit() method which is able to handle everything
|
||||
super:Edit()
|
||||
|
||||
endif
|
||||
|
||||
return Self
|
||||
|
||||
|
||||
// I come here if I have an unknown key and it is not a configurable key
|
||||
// if there is an user function I leave to it its handling
|
||||
METHOD KeyboardHook(nKey) CLASS TMemoEditor
|
||||
|
||||
local nUserKey
|
||||
|
||||
if ::xUserFunction <> nil
|
||||
nUserKey := Do(::xUserFunction, iif(::lDirty, ME_UNKEYX, ME_UNKEY), ::nRow, ::nCol - 1)
|
||||
|
||||
do case
|
||||
case nUserKey >= 1 .AND. nUserKey <= 31
|
||||
super:Edit(nUserKey)
|
||||
|
||||
case nUserKey == ME_DATA
|
||||
//super:Edit(nKey)
|
||||
|
||||
case nUserKey == ME_TOGGLEWRAP
|
||||
::lWordWrap := !::lWordWrap
|
||||
|
||||
case nUserKey == ME_TOGGLESCROLL
|
||||
// Don't know what to do ;-)
|
||||
|
||||
case nUserKey == ME_WORDRIGHT
|
||||
::MoveCursor(K_CTRL_RIGHT)
|
||||
|
||||
case nUserKey == ME_BOTTOMRIGHT
|
||||
::MoveCursor(K_CTRL_END)
|
||||
|
||||
otherwise
|
||||
|
||||
endcase
|
||||
|
||||
endif
|
||||
|
||||
return Self
|
||||
|
||||
|
||||
METHOD IdleHook() CLASS TMemoEditor
|
||||
|
||||
if ::xUserFunction <> nil
|
||||
Do(::xUserFunction, ME_IDLE, ::nRow, ::nCol - 1)
|
||||
|
||||
endif
|
||||
|
||||
return Self
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
FUNCTION MemoEdit(cString,;
|
||||
nTop, nLeft,;
|
||||
nBottom, nRight,;
|
||||
@@ -64,9 +243,12 @@ FUNCTION MemoEdit(cString,;
|
||||
DEFAULT nTextBuffColumn TO 0
|
||||
DEFAULT nWindowRow TO 0
|
||||
DEFAULT nWindowColumn TO nTextBuffColumn
|
||||
DEFAULT cUserFunction TO nil
|
||||
DEFAULT cString TO ""
|
||||
|
||||
// Original MemoEdit() converts Tabs into spaces
|
||||
oEd := TEditor():New(StrTran(cString, Chr(K_TAB), Space(1)), nTop, nLeft, nBottom, nRight, lEditMode, nil, nLineLength, nTabSize)
|
||||
oEd := TMemoEditor():New(StrTran(cString, Chr(K_TAB), Space(1)), nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabSize)
|
||||
oEd:MemoInit(cUserFunction)
|
||||
oEd:RefreshWindow()
|
||||
|
||||
if ! ISLOGICAL(cUserFunction) .OR. cUserFunction == .T.
|
||||
@@ -79,5 +261,5 @@ FUNCTION MemoEdit(cString,;
|
||||
endif
|
||||
endif
|
||||
|
||||
RETURN cString
|
||||
RETURN cString
|
||||
|
||||
|
||||
@@ -74,13 +74,13 @@ CLASS TEditor
|
||||
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
|
||||
DATA lDirty // .T. if there are changes not saved
|
||||
|
||||
DATA cColorSpec INIT SetColor() // Color string used for screen writes
|
||||
|
||||
|
||||
METHOD New(cString, nTop, nLeft, nBottom,; // Converts a string to an array of strings splitting input string at EOL boundaries
|
||||
nRight, lEditMode, cUdF, nLineLength,;
|
||||
nTabSize)
|
||||
nRight, lEditMode, nLineLength, nTabSize)
|
||||
|
||||
METHOD LoadFile(cFileName) // Load cFileName into active editor
|
||||
METHOD LoadText(cString) // Load cString into active editor
|
||||
@@ -227,7 +227,7 @@ METHOD GetText() CLASS TEditor
|
||||
return cString
|
||||
|
||||
|
||||
METHOD New(cString, nTop, nLeft, nBottom, nRight, lEditMode, cUdF, nLineLength, nTabSize) CLASS TEditor
|
||||
METHOD New(cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabSize) CLASS TEditor
|
||||
|
||||
default cString to ""
|
||||
default nTop to 0
|
||||
@@ -235,7 +235,6 @@ METHOD New(cString, nTop, nLeft, nBottom, nRight, lEditMode, cUdF, nLineLength,
|
||||
default nBottom to MaxRow()
|
||||
default nRight to MaxCol()
|
||||
default lEditMode to .T.
|
||||
default cUdF to nil
|
||||
default nLineLength to nil
|
||||
default nTabSize to nil
|
||||
|
||||
@@ -266,6 +265,9 @@ METHOD New(cString, nTop, nLeft, nBottom, nRight, lEditMode, cUdF, nLineLength,
|
||||
::InsertState(::lInsert)
|
||||
endif
|
||||
|
||||
// No need to save
|
||||
::lDirty := .F.
|
||||
|
||||
// is word wrap required?
|
||||
if nLineLength != NIL
|
||||
::lWordWrap := .T.
|
||||
@@ -336,6 +338,7 @@ METHOD LoadFile(cFileName) CLASS TEditor
|
||||
::naTextLen++
|
||||
endif
|
||||
|
||||
::lDirty := .F.
|
||||
::MoveCursor(K_CTRL_PGUP)
|
||||
|
||||
return Self
|
||||
@@ -351,6 +354,7 @@ METHOD LoadText(cString) CLASS TEditor
|
||||
::naTextLen++
|
||||
endif
|
||||
|
||||
::lDirty := .F.
|
||||
::MoveCursor(K_CTRL_PGUP)
|
||||
|
||||
return Self
|
||||
@@ -363,7 +367,9 @@ METHOD SaveFile() CLASS TEditor
|
||||
|
||||
if !Empty(::cFile)
|
||||
cString := ::GetText()
|
||||
return MemoWrit(::cFile, cString)
|
||||
::lDirty := !MemoWrit(::cFile, cString)
|
||||
return !::lDirty
|
||||
|
||||
endif
|
||||
|
||||
return .F.
|
||||
@@ -817,6 +823,7 @@ METHOD Edit(nPassedKey) CLASS TEditor
|
||||
|
||||
do case
|
||||
case nKey >= K_SPACE .AND. nKey < 256
|
||||
::lDirty := .T.
|
||||
// If I'm past EOL I need to add as much spaces as I need to reach ::nCol
|
||||
if ::nCol > ::LineLen(::nRow)
|
||||
::aText[::nRow]:cText += Space(::nCol - ::LineLen(::nRow))
|
||||
@@ -832,6 +839,7 @@ METHOD Edit(nPassedKey) CLASS TEditor
|
||||
::SplitLine(::nRow)
|
||||
|
||||
case nKey == K_RETURN
|
||||
::lDirty := .T.
|
||||
if ::lInsert .OR. ::nRow == ::naTextLen
|
||||
if ::LineLen(::nRow) > 0
|
||||
// Split current line at cursor position
|
||||
@@ -851,6 +859,7 @@ METHOD Edit(nPassedKey) CLASS TEditor
|
||||
::InsertState(!::lInsert)
|
||||
|
||||
case nKey == K_DEL
|
||||
::lDirty := .T.
|
||||
// If I'm on last char of a line and there are more lines, append next line to current one
|
||||
lDelAppend := ::nCol > ::LineLen(::nRow)
|
||||
::aText[::nRow]:cText := Stuff(::aText[::nRow]:cText, ::nCol, 1, "")
|
||||
@@ -870,6 +879,7 @@ METHOD Edit(nPassedKey) CLASS TEditor
|
||||
// insert char if in insert mode or at end of current line
|
||||
if ::lInsert .OR. (::nCol == ::LineLen(::nRow))
|
||||
::aText[::nRow]:cText := Stuff(::aText[::nRow]:cText, ::nCol, 0, Space(::nTabWidth))
|
||||
::lDirty := .T.
|
||||
endif
|
||||
for i := 1 to ::nTabWidth
|
||||
::MoveCursor(K_RIGHT)
|
||||
@@ -877,6 +887,7 @@ METHOD Edit(nPassedKey) CLASS TEditor
|
||||
::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()
|
||||
@@ -885,6 +896,7 @@ METHOD Edit(nPassedKey) CLASS TEditor
|
||||
::RefreshLine()
|
||||
|
||||
case nKey == K_CTRL_Y
|
||||
::lDirty := .T.
|
||||
if ::naTextLen > 1
|
||||
::RemoveLine(::nRow)
|
||||
// if we have less lines of text than our current position, up one line
|
||||
|
||||
Reference in New Issue
Block a user