diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 3dd4e13b58..68842b9689 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,10 @@ The license applies to all entries newer than 2009-04-28. */ +2011-05-25 19:43 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) + * contrib/xhb/xhbtedit.prg + ! fixed formatting (using hbformat + manual corrections) + 2011-05-25 19:35 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) + contrib/xhb/xhbtedit.prg * contrib/xhb/xhb.hbp diff --git a/harbour/contrib/xhb/xhbtedit.prg b/harbour/contrib/xhb/xhbtedit.prg index 8ef836807b..328408f191 100644 --- a/harbour/contrib/xhb/xhbtedit.prg +++ b/harbour/contrib/xhb/xhbtedit.prg @@ -101,9 +101,9 @@ #include "color.ch" #include "hbgtinfo.ch" -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// -CREATE CLASS XHBEditor + CREATE CLASS XHBEditor DATA cFile INIT "" // name of file being edited @@ -121,7 +121,7 @@ CREATE CLASS XHBEditor DATA nPhysRow INIT 0 // Hardware cursor position, I cannot rely on Row()/Col() because I could be inside another DATA nPhysCol INIT 0 // application/object and this one could be moving real cursor. If I'm running full - // screen nPhysRow will always have the same value as Row() and nPhysCol as Col() + // screen nPhysRow will always have the same value as Row() and nPhysCol as Col() DATA nTextRow INIT 0 // Display position of the cursor whitin the text buffer. DATA nTextCol INIT 0 // idem. @@ -162,11 +162,10 @@ CREATE CLASS XHBEditor // READINSERT(), ::lInsert must check in it. // DATA lInsert INIT .F. // Is editor in Insert mode or in Overstrike one? Default : Overstrike - Clipper METHOD lInsert() BLOCK { | | Set( _SET_INSERT ) } - METHOD _lInsert( lInsert ) BLOCK { | Self, lInsert | HB_SYMBOL_UNUSED( Self ), IIF( ISLOGICAL( lInsert ), Set( _SET_INSERT, lInsert ), Set( _SET_INSERT ) ) } - - METHOD New( cString, nTop, nLeft, nBottom,; // Converts a string to an array of strings splitting input string at EOL boundaries - nRight, lEditMode, nLineLength, nTabSize, nTextRow, nTextCol, nWndRow, nWndCol ) + METHOD _lInsert( lInsert ) BLOCK { | Self, lInsert | HB_SYMBOL_UNUSED( Self ), iif( ISLOGICAL( lInsert ), Set( _SET_INSERT, lInsert ), Set( _SET_INSERT ) ) } + METHOD New( cString, nTop, nLeft, nBottom, ; // Converts a string to an array of strings splitting input string at EOL boundaries + nRight, lEditMode, nLineLength, nTabSize, nTextRow, nTextCol, nWndRow, nWndCol ) METHOD LoadFile( cFileName ) // Load cFileName into active editor METHOD LoadText( cString ) // Load cString into active editor METHOD SaveFile() // Save active file ( not for MemoEdit() emulation ) @@ -175,7 +174,7 @@ CREATE CLASS XHBEditor METHOD InsertLine( cLine, lSoftCR, nRow ) // Insert a line of text at a defined row METHOD RemoveLine( nRow ) // Remove a line of text METHOD GetLine( nRow ) // Return line n of text - METHOD LineLen( nRow ) INLINE iif(nRow==NIL,nRow:=::nRow,), iif( nRow <= ::LastRow(), Len( ::aText[ nRow ]:cText ), 0 ) // Return text length of line n + METHOD LineLen( nRow ) INLINE iif( nRow == NIL, nRow := ::nRow, ), iif( nRow <= ::LastRow(), Len( ::aText[ nRow ]:cText ), 0 ) // Return text length of line n METHOD SplitLine( nRow ) // If a line of text is longer than nWordWrapCol divides it into multiple lines METHOD GotoLine( nRow ) // Put line nRow at cursor position METHOD GotoCol( nCol ) // Put line nCol at cursor position @@ -184,12 +183,12 @@ CREATE CLASS XHBEditor METHOD DelText() // Clear aText METHOD AddText( cString, lAtPos ) // Add text at the cursor METHOD GetTextIndex() // Return current cursor position in text. - + METHOD SetTextSelection( cAction, nCount ) // Start or modify the current selection. METHOD GetTextSelection( lSoftCr ) // Return the current selection. METHOD DelTextSelection() // Delete the current selection METHOD ClrTextSelection() // Clear the current selection. - + METHOD RefreshWindow() // Redraw a window METHOD RefreshLine( lRefreshColSel ) // Redraw a line METHOD RefreshColumn() // Redraw a column of text @@ -217,20 +216,17 @@ CREATE CLASS XHBEditor METHOD PageDown() METHOD Bottom() METHOD GoBottom() - METHOD Up() METHOD PageUp() METHOD Top() METHOD GoTop() - METHOD Right() METHOD WordRight() METHOD End() - METHOD Left() METHOD WordLeft() METHOD Home() - + METHOD K_Ascii( nKey ) METHOD K_Return() METHOD K_Del() @@ -249,6 +245,7 @@ CREATE CLASS XHBEditor METHOD DelTextRight( nRow ) // Delete text right of cursor. METHOD DelWordRight() // Delete word right key. METHOD ReformParagraph() // Reformat paragraph. CTRL-B behaviour + ///////////////// PROTECTED: @@ -256,8 +253,9 @@ CREATE CLASS XHBEditor METHOD BrowseText( nPassedKey, lHandleOneKey ) // 2006/07/25 - E.F. - Internal use only. - METHOD GetCol( nRow, nCol ) INLINE iif(nRow>0.and.nRow<=::LastRow(),iif(nCol>0.and.nCol<=Min(::nWordWrapCol+1,::LineLen(nRow)),::aText[ nRow ]:cText[ nCol ],""),"") - METHOD IsEmptyLine( nRow ) INLINE iif(nRow>0.and.nRow<=::LastRow(),Empty(::aText[ nRow ]:cText ),.T.) + + METHOD GetCol( nRow, nCol ) INLINE iif( nRow > 0 .AND. nRow <= ::LastRow(), iif( nCol > 0 .AND. nCol <= Min(::nWordWrapCol + 1,::LineLen(nRow ) ),::aText[ nRow ]:cText[ nCol ],"" ), "" ) + METHOD IsEmptyLine( nRow ) INLINE iif( nRow > 0 .AND. nRow <= ::LastRow(), Empty( ::aText[ nRow ]:cText ), .T. ) ENDCLASS @@ -265,27 +263,27 @@ ENDCLASS METHOD New( cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabSize, nTextRow, nTextCol, nWndRow, nWndCol ) CLASS XHBEditor - default cString to "" - default nTop to 0 - default nLeft to 0 - default nBottom to MaxRow() - default nRight to MaxCol() - default lEditMode to .T. - default nLineLength to NIL - default nTabSize to NIL - default nTextRow to 1 - default nTextCol to 0 // 1 Clipper Documentations says it is 0 - default nWndRow to 0 // 1 " - default nWndCol to 0 // 1 " + DEFAULT cString TO "" + DEFAULT nTop TO 0 + DEFAULT nLeft TO 0 + DEFAULT nBottom TO MaxRow() + DEFAULT nRight TO MaxCol() + DEFAULT lEditMode TO .T. + DEFAULT nLineLength TO NIL + DEFAULT nTabSize TO NIL + DEFAULT nTextRow TO 1 + DEFAULT nTextCol TO 0 // 1 Clipper Documentations says it is 0 + DEFAULT nWndRow TO 0 // 1 " + DEFAULT nWndCol TO 0 // 1 " // 2006/JUL/22 - E.F. To avoid run time error. IF nTop > nBottom .OR. nLeft > nRight - Throw( ErrorNew( "BASE", 0, 1127, "Argument error: " , Procname() ) ) + Throw( ErrorNew( "BASE", 0, 1127, "Argument error: " , ProcName() ) ) ENDIF // fix setcolor() to value at New() call - ::cColorSpec := setcolor() + ::cColorSpec := SetColor() // Note original cursor to restore after editing ::nOrigCursor := SetCursor() @@ -293,8 +291,8 @@ METHOD New( cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabS // 2006/JUL/21 - E.F. To avoid out of boundaries. // Editor window boundaries - ::nTop := Min( Max(0,nTop), MaxRow() ) - ::nLeft := Min( Max(0,nLeft), MaxCol() ) + ::nTop := Min( Max( 0,nTop ), MaxRow() ) + ::nLeft := Min( Max( 0,nLeft ), MaxCol() ) ::nBottom := Max( 0, Min( MaxRow(),nBottom ) ) ::nRight := Max( 0, Min( MaxCol(),nRight ) ) @@ -305,47 +303,46 @@ METHOD New( cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabS // 2006/AUG/18 - E.F. Adjusted nLineLenght in accordance with Clipper's // memoedit. - //. - if !Hb_IsNumeric( nLineLength ) + IF !Hb_IsNumeric( nLineLength ) nLineLength := ::nNumCols - else - if nLineLength < 0 + ELSE + IF nLineLength < 0 nLineLength := 255 - ::lWordWrap := .f. - else - nLineLength := Max(6,nLineLength) - endif - endif + ::lWordWrap := .F. + ELSE + nLineLength := Max( 6, nLineLength ) + ENDIF + ENDIF ::nWordWrapCol := nLineLength - 1 // please don't change it. - if lEditMode != NIL + IF lEditMode != NIL ::lEditAllow := lEditMode - endif + ENDIF // set correct insert state if ::lEditAllow // Force to redraw INS message - ::InsertState( ! SET( _SET_INSERT ) ) - ::InsertState( ! SET( _SET_INSERT ) ) - endif + ::InsertState( ! Set( _SET_INSERT ) ) + ::InsertState( ! Set( _SET_INSERT ) ) + ENDIF // No need to save ::lChanged := .F. // how many spaces for each tab? - if nTabSize != NIL + IF nTabSize != NIL ::nTabWidth := nTabSize - endif + ENDIF - ::nTextRow := max( 1, nTextRow ) - ::nTextCol := max( 0, nTextCol ) - ::nWndRow := max( 0, nWndRow ) - ::nWndCol := max( 0, nWndCol ) + ::nTextRow := Max( 1, nTextRow ) + ::nTextCol := Max( 0, nTextCol ) + ::nWndRow := Max( 0, nWndRow ) + ::nWndCol := Max( 0, nWndCol ) - ::nFirstRow := max( 1, ::nTextRow - ::nWndRow ) - ::nFirstCol := max( 1, ::nTextCol - ::nWndCol ) + ::nFirstRow := Max( 1, ::nTextRow - ::nWndRow ) + ::nFirstCol := Max( 1, ::nTextCol - ::nWndCol ) // If memofield was created with Clipper, it needs to have chr( 141 )+chr( 10 ) stripped @@ -372,12 +369,12 @@ METHOD New( cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabS if ::LastRow() == 0 AAdd( ::aText, HBTextLine():New() ) - endif + ENDIF // Setting datas that depend of ::aText filled. // - ::nRow := max( 1, min( ::nTextRow, Len( ::aText ) ) ) - ::nCol := max( 1, min( Len( ::aText[ ::nRow ]:cText ) , ::nTextCol + 1 ) ) + ::nRow := Max( 1, Min( ::nTextRow, Len( ::aText ) ) ) + ::nCol := Max( 1, Min( Len( ::aText[ ::nRow ]:cText ) , ::nTextCol + 1 ) ) // extra sanitization over max bounds IF ::nFirstRow > ::LastRow() @@ -395,19 +392,20 @@ METHOD New( cString, nTop, nLeft, nBottom, nRight, lEditMode, nLineLength, nTabS ::RefreshWindow() -return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Redefines editor window size and refreshes it + // -//-------------------------------------------------------------------// -// -// Redefines editor window size and refreshes it -// METHOD Resize( nTop, nLeft, nBottom, nRight ) CLASS XHBEditor // don't change coordinates not given - default nTop to ::nTop - default nLeft to ::nLeft - default nBottom to ::nBottom - default nRight to ::nRight + DEFAULT nTop to ::nTop + DEFAULT nLeft to ::nLeft + DEFAULT nBottom to ::nBottom + DEFAULT nRight to ::nRight ::nTop := nTop ::nLeft := nLeft @@ -434,16 +432,17 @@ METHOD Resize( nTop, nLeft, nBottom, nRight ) CLASS XHBEditor ::RefreshWindow() -return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Screen Output + // + //-------------------------------------------------------------------// + // + // Redraws a screenfull of text + // -//-------------------------------------------------------------------// -// -// Screen Output -// -//-------------------------------------------------------------------// -// -// Redraws a screenfull of text -// METHOD RefreshWindow() CLASS XHBEditor LOCAL i @@ -451,7 +450,6 @@ METHOD RefreshWindow() CLASS XHBEditor LOCAL nORow LOCAL nOCur - nOCol := ::Col() nORow := ::Row() nOCur := SetCursor( SC_NONE ) @@ -465,14 +463,14 @@ METHOD RefreshWindow() CLASS XHBEditor // //ScrollFixed( ::nTop, ::nLeft, ::nBottom, ::nRight ) - for i := 0 to Min( ::nNumRows - 1, ::LastRow() - 1 ) + for i := 0 TO Min( ::nNumRows - 1, ::LastRow() - 1 ) // 2006/JUL/23 - E.F. Adjusted to avoid out of bound. // Don't replace ::GetLine(nRow) by ::aText[nRow]:cText here, // because getline return line number in tbrwtext.prg (debug). - DispOutAt( Min(::nTop + i,::nBottom), ::nLeft, ; - PadR( iif(::nFirstRow+i <= ::LastRow(), SubStr( ::GetLine( ::nFirstRow + i ), ::nFirstCol, ::nNumCols ),Space(::nNumCols) ) , ::nNumCols ), ; - ::LineColor( ::nFirstRow + i ) ) + DispOutAt( Min( ::nTop + i,::nBottom ), ::nLeft, ; + PadR( iif( ::nFirstRow + i <= ::LastRow(), SubStr( ::GetLine( ::nFirstRow + i ), ::nFirstCol, ::nNumCols ),Space(::nNumCols ) ) , ::nNumCols ), ; + ::LineColor( ::nFirstRow + i ) ) next @@ -483,50 +481,54 @@ METHOD RefreshWindow() CLASS XHBEditor SetCursor( nOCur ) ::SetPos( nORow, nOCol ) -return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Return the color of the row + // -//-------------------------------------------------------------------// -// -// Return the color of the row -// METHOD LineColor( nRow ) CLASS XHBEditor - local cColor + LOCAL cColor - if ::lSelActive .and. ( ( nRow >= ::nRowSelStart ) .and. ( nRow <= ::nRowSelEnd ) ) .and.; - ::nRowSelStart > 0 .and. ::nRowSelEnd > 0 + if ::lSelActive .AND. ( ( nRow >= ::nRowSelStart ) .AND. ( nRow <= ::nRowSelEnd ) ) .AND. ; + ::nRowSelStart > 0 .AND. ::nRowSelEnd > 0 cColor := hb_ColorIndex( ::cColorSpec, CLR_ENHANCED ) - else + ELSE cColor := hb_ColorIndex( ::cColorSpec, CLR_STANDARD ) - endif + ENDIF + + RETURN cColor + + //-------------------------------------------------------------------// + // + // Return the color of the Col + // -return cColor -//-------------------------------------------------------------------// -// -// Return the color of the Col -// METHOD ColColor() CLASS XHBEditor - local cColor + LOCAL cColor - if ::lSelActive .and. ::nColSelStart > 0 .and. ::nColSelEnd > 0 .and.; - ::nColSelStart <= ::nColSelEnd + if ::lSelActive .AND. ::nColSelStart > 0 .AND. ::nColSelEnd > 0 .AND. ; + ::nColSelStart <= ::nColSelEnd cColor := hb_ColorIndex( ::cColorSpec, CLR_ENHANCED ) - else + ELSE cColor := hb_ColorIndex( ::cColorSpec, CLR_STANDARD ) - endif + ENDIF -return cColor + RETURN cColor + + //-------------------------------------------------------------------// + // + // Redraws current screen line + // -//-------------------------------------------------------------------// -// -// Redraws current screen line -// METHOD RefreshLine( lRefreshColSel ) CLASS XHBEditor LOCAL nOCol LOCAL nORow - LOCAL nCol,nFirstCol + LOCAL nCol, nFirstCol DEFAULT lRefreshColSel TO .F. @@ -535,38 +537,39 @@ METHOD RefreshLine( lRefreshColSel ) CLASS XHBEditor nOCol := ::Col() nORow := ::Row() - Dispbegin() + DispBegin() // 2006/AUG/02 - E.F. // Don't replace ::GetLine(nRow) by ::aText[nRow]:cText here // because getline return line number in tbrwtext.prg (debug). DispOutAt( ::Row(), ::nLeft, PadR( SubStr( ::GetLine( ::nRow ), ::nFirstCol, ::nNumCols ), ::nNumCols, " " ), ::LineColor( ::nRow ) ) - if lRefreshColSel + IF lRefreshColSel - nFirstCol := Max(::nTextCol,::nWndCol) - nFirstCol := Max(nFirstCol,::nLeft) + nFirstCol := Max( ::nTextCol, ::nWndCol ) + nFirstCol := Max( nFirstCol, ::nLeft ) -/* 2006/SEP/20 - E.F. - Fine cursor adjustment. */ -// nCol := nFirstCol + ::nColSelStart - 1 + /* 2006/SEP/20 - E.F. - Fine cursor adjustment. */ + // nCol := nFirstCol + ::nColSelStart - 1 nCol := Max( ::nLeft, nFirstCol + ::nColSelStart - 1 ) - DispOutAt( ::Row(), nCol, SubStr( ::GetLine( ::nRow ), Max(1,::nColSelStart), (::nColSelEnd - ::nColSelStart+1) ) , ::ColColor() ) + DispOutAt( ::Row(), nCol, SubStr( ::GetLine( ::nRow ), Max(1,::nColSelStart ), (::nColSelEnd - ::nColSelStart + 1 ) ) , ::ColColor() ) - endif + ENDIF - Dispend() + DispEnd() ::SetPos( nORow, nOCol ) ENDIF -return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Refreshes only one screen column of text ( for Left() and Right() movements ) + // -//-------------------------------------------------------------------// -// -// Refreshes only one screen column of text ( for Left() and Right() movements ) -// METHOD RefreshColumn() CLASS XHBEditor LOCAL i @@ -578,600 +581,602 @@ METHOD RefreshColumn() CLASS XHBEditor nORow := ::Row() nOCur := SetCursor( SC_NONE ) - Dispbegin() + DispBegin() // 2006/AUG/02 - E.F. // Don't replace ::GetLine(nRow) by ::aText[nRow]:cText here // because getline return line number in tbrwtext.prg (debug). - for i := 0 to Min( ::nNumRows - 1, ::LastRow() - 1 ) + for i := 0 TO Min( ::nNumRows - 1, ::LastRow() - 1 ) DispOutAt( ::nTop + i, nOCol, SubStr( ::GetLine(::nFirstRow + i ), ::nCol, 1 ), ::LineColor( ::nFirstRow + i ) ) next - Dispend() + DispEnd() SetCursor( nOCur ) ::SetPos( nORow, nOCol ) -return Self + RETURN Self -//-------------------------------------------------------------------// -// -// Wrapper for Cursor Movement to be used from Outside of This Class -// -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// + // + // Wrapper for Cursor Movement to be used from Outside of This Class + // + //-------------------------------------------------------------------// METHOD MoveCursor( nKey ) CLASS XHBEditor + // Modified to handle cursor movements inside text array without crashing! // Modified to allow line wrapping, and to track cursor to line ends. // Switch nKey // TODO: for optimization, change this with relativie GOTOCOL, GOTOPOS and GOTOROW - case K_DOWN - ::ClrTextSelection() - ::Down() - exit + CASE K_DOWN + ::ClrTextSelection() + ::Down() + EXIT - case K_PGDN - ::ClrTextSelection() - ::PageDown() - exit + CASE K_PGDN + ::ClrTextSelection() + ::PageDown() + EXIT - case K_CTRL_PGDN - ::ClrTextSelection() - ::GoBottom() - exit + CASE K_CTRL_PGDN + ::ClrTextSelection() + ::GoBottom() + EXIT - case K_UP - ::ClrTextSelection() - ::Up() - exit + CASE K_UP + ::ClrTextSelection() + ::Up() + EXIT - case K_PGUP - ::ClrTextSelection() - ::PageUp() - exit + CASE K_PGUP + ::ClrTextSelection() + ::PageUp() + EXIT - case K_CTRL_PGUP - ::ClrTextSelection() - ::GoTop() - exit + CASE K_CTRL_PGUP + ::ClrTextSelection() + ::GoTop() + EXIT - case K_RIGHT - ::ClrTextSelection() - ::Right() - exit + CASE K_RIGHT + ::ClrTextSelection() + ::Right() + EXIT - case K_CTRL_RIGHT - ::ClrTextSelection() - ::WordRight() - exit + CASE K_CTRL_RIGHT + ::ClrTextSelection() + ::WordRight() + EXIT - case K_LEFT - ::ClrTextSelection() - ::Left() - exit + CASE K_LEFT + ::ClrTextSelection() + ::Left() + EXIT - case K_CTRL_LEFT - ::ClrTextSelection() - ::WordLeft() - exit + CASE K_CTRL_LEFT + ::ClrTextSelection() + ::WordLeft() + EXIT - case K_HOME - ::ClrTextSelection() - ::Home() - exit + CASE K_HOME + ::ClrTextSelection() + ::Home() + EXIT - case K_CTRL_HOME - ::ClrTextSelection() - ::Top() - exit + CASE K_CTRL_HOME + ::ClrTextSelection() + ::Top() + EXIT - case K_END - ::ClrTextSelection() - ::End() - exit + CASE K_END + ::ClrTextSelection() + ::End() + EXIT - case K_CTRL_END - ::ClrTextSelection() - ::Bottom() - ::End() - exit + CASE K_CTRL_END + ::ClrTextSelection() + ::Bottom() + ::End() + EXIT - otherwise - return .F. + OTHERWISE + RETURN .F. endswitch -return .T. + RETURN .T. -//-------------------------------------------------------------------// -// -// Editing -// -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// + // + // Editing + // + //-------------------------------------------------------------------// METHOD Edit( nPassedKey ) CLASS XHBEditor LOCAL nKey LOCAL lSingleKeyProcess := .F. - // If user pressed an exiting key ( K_ESC or K_ALT_W ) or I've received // a key to handle and then exit DO WHILE ! ::lExitEdit .AND. ! lSingleKeyProcess - // If I haven't been called with a key already preset, evaluate - // this key and then exit. - // - if nPassedKey == NIL + // If I haven't been called with a key already preset, evaluate + // this key and then exit. + // + IF nPassedKey == NIL - if NextKey() == 0 - ::IdleHook() - endif + IF NextKey() == 0 + ::IdleHook() + ENDIF - nKey := InKey( 0, INKEY_ALL ) + nKey := Inkey( 0, INKEY_ALL ) - else + ELSE - lSingleKeyProcess := .T. - nKey := nPassedKey + lSingleKeyProcess := .T. + nKey := nPassedKey - endif + ENDIF /* * 2006/AUG/12 -E.F. Trap Set key only if nKey is nil. */ - IF nPassedKey == NIL - if ( ::bKeyBlock := Setkey( nKey ) ) != NIL - Eval( ::bKeyBlock, ::ProcName, ::ProcLine, "", Self ) - Loop - endif + IF nPassedKey == NIL + IF ( ::bKeyBlock := SetKey( nKey ) ) != NIL + Eval( ::bKeyBlock, ::ProcName, ::ProcLine, "", Self ) + LOOP + ENDIF + ENDIF + + Switch nKey + CASE K_LBUTTONUP + CASE K_MWFORWARD + CASE K_MWBACKWARD + ::K_Mouse( nKey ) + EXIT + +#ifdef HB_EXT_INKEY + + CASE K_SH_DOWN + if ::nRow <= ::LastRow() + ::SetTextSelection( "ROW", + 1 ) + ENDIF + EXIT + + CASE K_SH_UP + if ::nRow > 1 + ::SetTextSelection( "ROW", - 1 ) + ENDIF + EXIT + + CASE K_SH_RIGHT + if ::nCol < ::nWordWrapCol + 1 + ::SetTextSelection( "COL", + 1 ) + ENDIF + EXIT + + CASE K_SH_END + if ::nCol < ::nWordWrapCol + 1 + ::SetTextSelection( "END" ) + ENDIF + EXIT + + CASE K_SH_LEFT + if ::nCol > 1 + ::SetTextSelection( "COL", - 1 ) + ENDIF + EXIT + + CASE K_SH_HOME + if ::nCol > 1 + ::SetTextSelection( "HOME" ) + ENDIF + EXIT + + CASE K_CTRL_A // Select all + ::SetTextSelection( "ALL" ) + EXIT + + CASE K_CTRL_C // Copy + hb_gtInfo( GTI_CLIPBOARDDATA, ::GetTextSelection() ) + //::ClrTextSelection() + EXIT + + CASE K_CTRL_X // Cut + CASE K_SH_DEL // Cut + hb_gtInfo( GTI_CLIPBOARDDATA, ::GetTextSelection() ) + if ::lEditAllow + ::DelTextSelection() + ENDIF + EXIT + + CASE K_CTRL_V // Paste + CASE K_SH_INS // Paste + if ::lEditAllow + ::AddText( StrTran( hb_gtInfo( GTI_CLIPBOARDDATA ), Chr(0 ), Chr(32 ) ), .T. ) + ::ClrTextSelection() + ENDIF + EXIT + + CASE K_ALT_W // Exit and return text buffer content. + CASE K_CTRL_W // idem + ::lSaved := .T. + ::lExitEdit := .T. + SetCursor( ::nOrigCursor ) // restore original cursor saved at startup + EXIT + + CASE K_CTRL_END + ::ClrTextSelection() + ::Bottom() + ::End() + EXIT + + CASE K_CTRL_B // Reformat paragraph + if ::lEditAllow + ::ClrTextSelection() + ::ReformParagraph() // 2006/JUL/29 -E.F. Added. + ENDIF + EXIT +#else + CASE K_ALT_W + EXIT + + CASE K_CTRL_W + ::lSaved := .T. + ::lExitEdit := .T. + SetCursor( ::nOrigCursor ) // restore original cursor saved at startup + EXIT +#endif + + + CASE K_CTRL_N + if ::lEditAllow // Clipper compatibility + ::ClrTextSelection() + ::lChanged := .T. + ::Home() + ::InsertLine( "", .F. , ::nRow ) + ::RefreshLine() + ::RefreshWindow() + ENDIF + EXIT + + CASE K_CTRL_T + if ::lEditAllow + ::ClrTextSelection() + ::lChanged := .T. + ::DelWordRight() + ::RefreshLine() + ENDIF + EXIT + + CASE K_CTRL_Y + if ::lEditAllow // Clipper compatibility + ::lChanged := .T. + ::ClrTextSelection() + if ::LastRow() > 1 .AND. ::nRow < ::LastRow() + ::RemoveLine( ::nRow ) + ::RefreshWindow() + if ::LastRow() > 0 + ::Home() + ::RefreshLine() + ENDIF + ELSE + ::aText[ ::nRow ]:cText := "" + ::RefreshLine() + ::Home() + ::RefreshLine() + ENDIF + ENDIF + EXIT + + CASE K_DOWN + ::ClrTextSelection() + ::Down() + EXIT + + CASE K_PGDN + ::ClrTextSelection() + ::PageDown() + EXIT + + CASE K_CTRL_PGDN + ::ClrTextSelection() + ::GoBottom() + EXIT + + CASE K_UP + ::ClrTextSelection() + ::Up() + EXIT + + CASE K_PGUP + ::ClrTextSelection() + ::PageUp() + EXIT + + CASE K_CTRL_PGUP + ::ClrTextSelection() + ::GoTop() + EXIT + + CASE K_RIGHT + ::ClrTextSelection() + ::Right() + EXIT + + CASE K_CTRL_RIGHT + ::ClrTextSelection() + ::WordRight() + EXIT + + CASE K_LEFT + ::ClrTextSelection() + ::Left() + EXIT + + CASE K_CTRL_LEFT + ::ClrTextSelection() + ::WordLeft() + EXIT + + CASE K_HOME + ::ClrTextSelection() + ::Home() + EXIT + + CASE K_CTRL_HOME + ::ClrTextSelection() + ::Top() + EXIT + + CASE K_END + ::ClrTextSelection() + ::End() + EXIT + + CASE K_ESC + ::ClrTextSelection() + ::K_Esc() + EXIT + + CASE K_RETURN + ::ClrTextSelection() + ::K_Return() + EXIT + + CASE K_INS + // 2006/JUL/22 - E.F. - Insert is allowed only in edit mode. + if ::lEditAllow + ::ClrTextSelection() + ::InsertState( !::lInsert ) + ENDIF + EXIT + +#ifdef HB_EXT_INKEY + CASE K_DEL + if ::lSelActive .AND. ::lEditAllow + ::DelTextSelection() + elseif ::lEditAllow // Clipper compatibility + ::K_Del() + ENDIF + EXIT +#else + CASE K_DEL + if ::lEditAllow // Clipper compatibility + ::K_Del() + ENDIF + EXIT +#endif + CASE K_TAB + if ::lEditAllow // Clipper compatibility + ::ClrTextSelection() + ::K_Tab() + ENDIF + EXIT + + CASE K_BS + ::ClrTextSelection() + if ::lEditAllow // Clipper compatibility + ::K_Bs() + ELSE + // 2006/JUL/22 - E.F. - Clipper backspace in read only is same as left movement. + ::Left() + ENDIF + EXIT + + CASE K_CTRL_BS // block chr( 127 ), a printable character in windows + ::ClrTextSelection() + EXIT + + OTHERWISE + + IF nKey >= K_SPACE .AND. nKey < 256 + if ::lEditAllow + ::ClrTextSelection() + ::K_Ascii( nKey ) + ENDIF + ELSE + // NOTE: if you call ::Edit() with a key that is passed to ::KeyboardHook() and then + // ::KeyboardHook() calls ::Edit() with the same key you end up with an endless loop + ::ClrTextSelection() + ::KeyboardHook( nKey ) ENDIF - Switch nKey - case K_LBUTTONUP - case K_MWFORWARD - case K_MWBACKWARD - ::K_Mouse( nKey ) - exit - -#ifdef HB_EXT_INKEY - - case K_SH_DOWN - if ::nRow <= ::LastRow() - ::SetTextSelection( "ROW", +1 ) - endif - exit - - case K_SH_UP - if ::nRow > 1 - ::SetTextSelection( "ROW", -1 ) - endif - exit - - case K_SH_RIGHT - if ::nCol < ::nWordWrapCol + 1 - ::SetTextSelection( "COL", +1 ) - endif - exit - - case K_SH_END - if ::nCol < ::nWordWrapCol + 1 - ::SetTextSelection( "END" ) - endif - exit - - case K_SH_LEFT - if ::nCol > 1 - ::SetTextSelection( "COL", -1 ) - endif - exit - - case K_SH_HOME - if ::nCol > 1 - ::SetTextSelection( "HOME" ) - endif - exit - - case K_CTRL_A // Select all - ::SetTextSelection( "ALL" ) - exit - - case K_CTRL_C // Copy - hb_gtInfo( GTI_CLIPBOARDDATA, ::GetTextSelection() ) - //::ClrTextSelection() - exit - - case K_CTRL_X // Cut - case K_SH_DEL // Cut - hb_gtInfo( GTI_CLIPBOARDDATA, ::GetTextSelection() ) - if ::lEditAllow - ::DelTextSelection() - endif - exit - - case K_CTRL_V // Paste - case K_SH_INS // Paste - if ::lEditAllow - ::AddText( strtran( hb_gtInfo( GTI_CLIPBOARDDATA ), chr(0), chr(32) ), .T. ) - ::ClrTextSelection() - endif - exit - - case K_ALT_W // Exit and return text buffer content. - case K_CTRL_W // idem - ::lSaved := .T. - ::lExitEdit := .T. - SetCursor( ::nOrigCursor ) // restore original cursor saved at startup - exit - - case K_CTRL_END - ::ClrTextSelection() - ::Bottom() - ::End() - exit - - case K_CTRL_B // Reformat paragraph - if ::lEditAllow - ::ClrTextSelection() - ::ReformParagraph() // 2006/JUL/29 -E.F. Added. - endif - exit -#else - case K_ALT_W - exit - - case K_CTRL_W - ::lSaved := .T. - ::lExitEdit := .T. - SetCursor( ::nOrigCursor ) // restore original cursor saved at startup - exit -#endif - - - case K_CTRL_N - if ::lEditAllow // Clipper compatibility - ::ClrTextSelection() - ::lChanged := .T. - ::Home() - ::InsertLine( "", .F., ::nRow ) - ::RefreshLine() - ::RefreshWindow() - endif - exit - - case K_CTRL_T - if ::lEditAllow - ::ClrTextSelection() - ::lChanged := .T. - ::DelWordRight() - ::RefreshLine() - endif - exit - - case K_CTRL_Y - if ::lEditAllow // Clipper compatibility - ::lChanged := .T. - ::ClrTextSelection() - if ::LastRow() > 1 .AND. ::nRow < ::LastRow() - ::RemoveLine( ::nRow ) - ::RefreshWindow() - if ::LastRow()>0 - ::Home() - ::RefreshLine() - endif - else - ::aText[ ::nRow ]:cText := "" - ::RefreshLine() - ::Home() - ::RefreshLine() - endif - endif - exit - - case K_DOWN - ::ClrTextSelection() - ::Down() - exit - - case K_PGDN - ::ClrTextSelection() - ::PageDown() - exit - - case K_CTRL_PGDN - ::ClrTextSelection() - ::GoBottom() - exit - - case K_UP - ::ClrTextSelection() - ::Up() - exit - - case K_PGUP - ::ClrTextSelection() - ::PageUp() - exit - - case K_CTRL_PGUP - ::ClrTextSelection() - ::GoTop() - exit - - case K_RIGHT - ::ClrTextSelection() - ::Right() - exit - - case K_CTRL_RIGHT - ::ClrTextSelection() - ::WordRight() - exit - - case K_LEFT - ::ClrTextSelection() - ::Left() - exit - - case K_CTRL_LEFT - ::ClrTextSelection() - ::WordLeft() - exit - - case K_HOME - ::ClrTextSelection() - ::Home() - exit - - case K_CTRL_HOME - ::ClrTextSelection() - ::Top() - exit - - case K_END - ::ClrTextSelection() - ::End() - exit - - case K_ESC - ::ClrTextSelection() - ::K_Esc() - exit - - case K_RETURN - ::ClrTextSelection() - ::K_Return() - exit - - case K_INS - // 2006/JUL/22 - E.F. - Insert is allowed only in edit mode. - if ::lEditAllow - ::ClrTextSelection() - ::InsertState( !::lInsert ) - endif - exit - -#ifdef HB_EXT_INKEY - case K_DEL - if ::lSelActive .and. ::lEditAllow - ::DelTextSelection() - elseif ::lEditAllow // Clipper compatibility - ::K_Del() - endif - exit -#else - case K_DEL - if ::lEditAllow // Clipper compatibility - ::K_Del() - endif - exit -#endif - case K_TAB - if ::lEditAllow // Clipper compatibility - ::ClrTextSelection() - ::K_Tab() - endif - exit - - case K_BS - ::ClrTextSelection() - if ::lEditAllow // Clipper compatibility - ::K_Bs() - else - // 2006/JUL/22 - E.F. - Clipper backspace in read only is same as left movement. - ::Left() - endif - exit - - case K_CTRL_BS // block chr( 127 ), a printable character in windows - ::ClrTextSelection() - exit - - otherwise - - if nKey >= K_SPACE .AND. nKey < 256 - if ::lEditAllow - ::ClrTextSelection() - ::K_Ascii( nKey ) - endif - else - // NOTE: if you call ::Edit() with a key that is passed to ::KeyboardHook() and then - // ::KeyboardHook() calls ::Edit() with the same key you end up with an endless loop - ::ClrTextSelection() - ::KeyboardHook( nKey ) - endif - - endswitch + endswitch ENDDO -Return Self + RETURN Self -//-------------------------------------------------------------------// -// -// Vertical Navigation -// -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// + // + // Vertical Navigation + // + //-------------------------------------------------------------------// METHOD Down() CLASS XHBEditor - IF ::lVerticalScroll - IF ::nRow < ::LastRow() - ::GotoLine( ::nRow + 1 ) - ENDIF - ELSE - IF ::nFirstRow < ::LastRow() .AND. ::LastRow() > ::nNumRows - ::nFirstRow++ - ::nRow++ - if ::nRow > ::LastRow() - ::nRow-- - endif - ::RefreshWindow() - ELSEIF ::nRow < ::LastRow() - ::GotoLine( ::nRow + 1 ) - ENDIF - ENDIF + IF ::lVerticalScroll + IF ::nRow < ::LastRow() + ::GotoLine( ::nRow + 1 ) + ENDIF + ELSE + IF ::nFirstRow < ::LastRow() .AND. ::LastRow() > ::nNumRows + ::nFirstRow ++ + ::nRow ++ + if ::nRow > ::LastRow() + ::nRow -- + ENDIF + ::RefreshWindow() + ELSEIF ::nRow < ::LastRow() + ::GotoLine( ::nRow + 1 ) + ENDIF + ENDIF -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD PageDown() CLASS XHBEditor + LOCAL nJump nJump := Min( ::nNumRows, ::LastRow() - ::nFirstRow - ( ::nPhysRow - ::nTop ) ) -IF ::lVerticalScroll + IF ::lVerticalScroll + + IF nJump > ( ::LastRow() - ::nRow ) //nJump < ::nNumRows + ::Bottom() + ELSE + ::nFirstRow += nJump + if ::nFirstRow > ::LastRow() + ::nFirstRow := ::LastRow() + ENDIF + + ::nRow += nJump + if ::nRow > ::LastRow() + ::nRow := ::LastRow() + ENDIF + ::RefreshWindow() + ENDIF + // ::GotoLine( min( ::nRow + ::nNumRows - 1, ::LastRow() ) ) - IF nJump > (::LastRow() - ::nRow) //nJump < ::nNumRows - ::Bottom() ELSE + nJump := Min( nJump, ::LastRow() - ::nFirstRow + 1 ) ::nFirstRow += nJump - if ::nFirstRow > ::LastRow() - ::nFirstRow := ::LastRow() - endif - - ::nRow += nJump - if ::nRow > ::LastRow() - ::nRow := ::LastRow() - endif + ::nRow += nJump ::RefreshWindow() ENDIF - // ::GotoLine( min( ::nRow + ::nNumRows - 1, ::LastRow() ) ) -ELSE - nJump := Min( nJump, ::LastRow() - ::nFirstRow + 1 ) - ::nFirstRow += nJump - ::nRow += nJump - ::RefreshWindow() -ENDIF + RETURN Self -Return Self - -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD Bottom() CLASS XHBEditor - LOCAL nRowTo := min( ::nFirstRow + ::nNumRows-1, ::LastRow() ) + + LOCAL nRowTo := Min( ::nFirstRow + ::nNumRows - 1, ::LastRow() ) ::GotoLine( nRowTo ) -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD GoBottom() CLASS XHBEditor ::GotoPos( ::LastRow(), ::LineLen( ::LastRow() ) + 1, .T. ) -Return Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD Up() CLASS XHBEditor - IF ::lVerticalScroll - IF ::nRow > 1 - ::GotoLine( ::nRow - 1 ) - //::GotoPos( ::nRow - 1, ::nCol ) - ENDIF - ELSE - IF ::nFirstRow > 1 - ::nFirstRow-- - ::nRow-- - if ::nRow < 1 - ::nRow := 1 - endif - ::RefreshWindow() - ELSEIF ::nRow > 1 - ::GotoLine( ::nRow - 1 ) - ENDIF - ENDIF + IF ::lVerticalScroll + IF ::nRow > 1 + ::GotoLine( ::nRow - 1 ) + //::GotoPos( ::nRow - 1, ::nCol ) + ENDIF + ELSE + IF ::nFirstRow > 1 + ::nFirstRow -- + ::nRow -- + if ::nRow < 1 + ::nRow := 1 + ENDIF + ::RefreshWindow() + ELSEIF ::nRow > 1 + ::GotoLine( ::nRow - 1 ) + ENDIF + ENDIF -Return Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD PageUp() CLASS XHBEditor + LOCAL nJump - nJump := min( ::nNumRows, ::nFirstRow - 1 ) + nJump := Min( ::nNumRows, ::nFirstRow - 1 ) -IF ::lVerticalScroll - if nJump == 0 - ::GoToLine( 1 ) - else + IF ::lVerticalScroll + IF nJump == 0 + ::GoToLine( 1 ) + ELSE + ::nFirstRow -= nJump + if ::nFirstRow < 1 + ::nFirstRow := 1 + ENDIF + + ::nRow -= nJump + if ::nRow < 1 + ::nRow := 1 + ENDIF + ::RefreshWindow() + ENDIF + + // ::GotoLine( Max( 1, ::nRow - ::nNumRows ) ) + ELSE + nJump := Min( nJump, ::nNumRows - 1 ) ::nFirstRow -= nJump - if ::nFirstRow < 1 - ::nFirstRow := 1 - endif - - ::nRow -= nJump - if ::nRow < 1 - ::nRow := 1 - endif + ::nRow -= nJump ::RefreshWindow() - endif - // ::GotoLine( Max( 1, ::nRow - ::nNumRows ) ) -ELSE - nJump := Min( nJump, ::nNumRows - 1 ) - ::nFirstRow -= nJump - ::nRow -= nJump - ::RefreshWindow() + ENDIF -ENDIF + RETURN Self - -RETURN Self - -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD Top() CLASS XHBEditor ::GotoPos( ::nFirstRow, 1, .T. ) -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD GoTop() CLASS XHBEditor ::GotoPos( 1, 1 ) -RETURN Self + RETURN Self -//-------------------------------------------------------------------// -// -// Horizontal Navigation -// -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// + // + // Horizontal Navigation + // + //-------------------------------------------------------------------// METHOD Right() CLASS XHBEditor - if ( ::lWordWrap ) + IF ( ::lWordWrap ) // 2006/07/19 - E.F. Changed max right point to pos cursor to next. // IF ::nCol > ::nWordWrapCol .AND. ::nRow < ::LastRow() @@ -1183,32 +1188,33 @@ METHOD Right() CLASS XHBEditor * method too, theres no spare in IF here. * ::GotoCol( ::nCol + 1 ) */ - ::GotoPos( ::nRow, ::nCol + 1, .T.) + ::GotoPos( ::nRow, ::nCol + 1, .T. ) ENDIF - else - if ::nCol < Max(::nNumCols,::nWordWrapCol+1) + ELSE + if ::nCol < Max( ::nNumCols, ::nWordWrapCol + 1 ) //::GotoCol( ::nCol + 1 ) - ::GotoPos( ::nRow, ::nCol+1 , .T. ) - endif - endif + ::GotoPos( ::nRow, ::nCol + 1 , .T. ) + ENDIF + ENDIF -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD WordRight() CLASS XHBEditor -LOCAL nMaxCol := Min( ::nWordWrapCol+1, ::LineLen( ::nRow ) ) + + LOCAL nMaxCol := Min( ::nWordWrapCol + 1, ::LineLen( ::nRow ) ) // NOTE: should be faster without call to ::GetLine() // - if !::lWordWrap .and. ::IsEmptyLine( ::nRow ) .OR.; - ::LastRow()==0 .OR.; - ( At(" ", ::aText[ ::nRow ]:cText ) == 0 .AND. ::LineLen(::nRow) >= ::nWordWrapCol ) - return self - endif + IF !::lWordWrap .AND. ::IsEmptyLine( ::nRow ) .OR. ; + ::LastRow() == 0 .OR. ; + ( At( " ", ::aText[ ::nRow ]:cText ) == 0 .AND. ::LineLen( ::nRow ) >= ::nWordWrapCol ) + RETURN self + ENDIF - dispbegin() // to minimize flicker. + DispBegin() // to minimize flicker. // 2006/JUL/21 - E.F. Changed to verify empty character instead space. // In any circunstancies wordright stop at space. @@ -1216,30 +1222,30 @@ LOCAL nMaxCol := Min( ::nWordWrapCol+1, ::LineLen( ::nRow ) ) // rightmost position. // - do while ::nCol <= nMaxCol .AND. !Empty( ::GetCol( ::nRow, ::nCol ) ) + DO while ::nCol <= nMaxCol .AND. !Empty( ::GetCol( ::nRow, ::nCol ) ) ::Right() - if ::nCol > nMaxCol .OR.; - (!::lWordWrap .AND. ::nCol >= nMaxCol ) - exit - endif - enddo + if ::nCol > nMaxCol .OR. ; + ( !::lWordWrap .AND. ::nCol >= nMaxCol ) + EXIT + ENDIF + ENDDO - do while ::nCol <= nMaxCol .AND. Empty( ::GetCol( ::nRow, ::nCol ) ) + DO while ::nCol <= nMaxCol .AND. Empty( ::GetCol( ::nRow, ::nCol ) ) ::Right() - if ::nCol > nMaxCol .OR.; - (!::lWordWrap .AND. ::nCol >= nMaxCol ) - exit - endif - enddo + if ::nCol > nMaxCol .OR. ; + ( !::lWordWrap .AND. ::nCol >= nMaxCol ) + EXIT + ENDIF + ENDDO - if !::lWordWrap - do while ::nCol > 1 .AND. !Empty( ::GetCol( ::nRow, ::nCol ) ) - ::Left() - enddo - do while ::nCol < nMaxCol .AND. empty( ::GetCol(::nRow,::nCol ) ) - ::right() - enddo - endif + IF !::lWordWrap + DO while ::nCol > 1 .AND. !Empty( ::GetCol( ::nRow, ::nCol ) ) + ::Left() + ENDDO + DO while ::nCol < nMaxCol .AND. Empty( ::GetCol( ::nRow,::nCol ) ) + ::Right() + ENDDO + ENDIF // mod = move to next line // @@ -1248,63 +1254,65 @@ LOCAL nMaxCol := Min( ::nWordWrapCol+1, ::LineLen( ::nRow ) ) if ::lWordWrap // 2006/JUL/21 - E.F. - If cursor reach rightmost position // go to the next line. - if ::nCol > nMaxCol .and. ::nRow < ::LastRow() + if ::nCol > nMaxCol .AND. ::nRow < ::LastRow() ::Down() ::Home() - if Empty(::GetCol( ::nRow, ::nCol )) + IF Empty( ::GetCol( ::nRow, ::nCol ) ) ::WordRight() - endif - // 2006/JUL/21 - E.F. - If cursor stop at empty char and it is the - // last reachable position go back to the previous word. - elseif ::nCol >= nMaxCol .and. ::nRow == ::LastRow() - if !Empty( ::GetCol( ::nRow, ::nCol ) ) + ENDIF + // 2006/JUL/21 - E.F. - If cursor stop at empty char and it is the + // last reachable position go back to the previous word. + elseif ::nCol >= nMaxCol .AND. ::nRow == ::LastRow() + IF !Empty( ::GetCol( ::nRow, ::nCol ) ) ::end() - endif + ENDIF ::WordLeft() - elseif ::nCol == 1 .and. Empty( ::GetCol( ::nRow, ::nCol ) ) + elseif ::nCol == 1 .AND. Empty( ::GetCol( ::nRow, ::nCol ) ) ::WordRight() - endif - else + ENDIF + ELSE // 2006/JUL/21 - E.F. - If cursor reach rightmost position go to back to prior word. if ::nCol > nMaxCol ::Wordleft() - endif - endif - endif + ENDIF + ENDIF + ENDIF - dispend() + DispEnd() -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD End() CLASS XHBEditor // 2006/07/19 - E.F. Changed to avoid the cursor out of line. // - ::GotoCol( Min( ::LineLen( ::nRow )+1, Max(::nNumCols,::nWordWrapCol+1)) ) + ::GotoCol( Min( ::LineLen( ::nRow ) + 1, Max(::nNumCols,::nWordWrapCol + 1 ) ) ) -Return Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD Left() CLASS XHBEditor + // Gotocol checks for nCol > 1 also, but this saves a func call IF ::nCol == 1 - if ( ::lWordWrap ) + IF ( ::lWordWrap ) IF ::nRow > 1 // 2006/07/19 E.F. left should be at max in the leftmost column. // - ::GotoPos(::nRow - 1, Max(::nNumCols,::nWordWrapCol+1) , .T. ) + ::GotoPos( ::nRow - 1, Max( ::nNumCols,::nWordWrapCol + 1 ) , .T. ) ENDIF //else do nothing - endif + ENDIF ELSE ::GotoCol( ::nCol - 1 ) ENDIF -RETURN Self -//-------------------------------------------------------------------// + RETURN Self + + //-------------------------------------------------------------------// METHOD WordLeft() CLASS XHBEditor @@ -1312,118 +1320,119 @@ METHOD WordLeft() CLASS XHBEditor // modifed to wrap lines and position at first letter of word, not word end // - if !::lWordWrap .and. ::IsEmptyLine( ::nRow ) .OR. ::LastRow()==0 - Return self - endif + IF !::lWordWrap .AND. ::IsEmptyLine( ::nRow ) .OR. ::LastRow() == 0 + RETURN self + ENDIF - dispbegin() // to minimize flicker + DispBegin() // to minimize flicker - if ::lWordWrap .and. ::nCol == 1 .and. ::nRow > 1 + if ::lWordWrap .AND. ::nCol == 1 .AND. ::nRow > 1 ::Up() ::End() - do while ::nCol == 1 .and. ::nRow > 1 .AND. Empty( ::GetCol( ::nRow,::nCol ) ) - ::Up() - if !::IsEmptyLine( ::nRow ) - ::End() - exit - endif - enddo - endif + DO while ::nCol == 1 .AND. ::nRow > 1 .AND. Empty( ::GetCol( ::nRow,::nCol ) ) + ::Up() + IF !::IsEmptyLine( ::nRow ) + ::End() + EXIT + ENDIF + ENDDO + ENDIF // 2006/JUL/21 - E.F. - Changed to verifiy empty char instead space. In any // circunstancies wordleft stop at space. // - do while ::nCol > 1 .AND. !Empty( ::GetCol( ::nRow, ::nCol ) ) + DO while ::nCol > 1 .AND. !Empty( ::GetCol( ::nRow, ::nCol ) ) ::Left() - enddo - do while ::nCol > 1 .AND. Empty( ::GetCol( ::nRow, ::nCol ) ) + ENDDO + DO while ::nCol > 1 .AND. Empty( ::GetCol( ::nRow, ::nCol ) ) ::Left() - enddo - do while ::nCol > 1 .AND. !Empty( ::GetCol( ::nRow, ::nCol-1 ) ) // move to front of word + ENDDO + DO while ::nCol > 1 .AND. !Empty( ::GetCol( ::nRow, ::nCol - 1 ) ) // move to front of word ::Left() - enddo + ENDDO // 2006/JUL/24 -E.F. - If cursor stoped at empty char, then // go to the next word. - if !::lWordWrap .AND. ; - ::nCol < ::LineLen(::nRow) .and.; - Empty( ::GetCol( ::nRow,::nCol ) ) - ::WordRight() - elseif ::lWordWrap .and. ::nCol=1 .and. ::nRow=1 .and.; - Empty( ::GetCol( ::nRow,::nCol ) ) - ::WordRight() - elseif ::lWordWrap .and. ::nCol=1 .and. ::nRow > 1 - do While ::nCol=1 .and. ::nRow>1 .and. empty( ::GetCol( ::nRow, ::nCol ) ) + IF !::lWordWrap .AND. ; + ::nCol < ::LineLen( ::nRow ) .AND. ; + Empty( ::GetCol( ::nRow,::nCol ) ) + ::WordRight() + elseif ::lWordWrap .AND. ::nCol = 1 .AND. ::nRow = 1 .AND. ; + Empty( ::GetCol( ::nRow,::nCol ) ) + ::WordRight() + elseif ::lWordWrap .AND. ::nCol = 1 .AND. ::nRow > 1 + DO While ::nCol = 1 .AND. ::nRow > 1 .AND. Empty( ::GetCol( ::nRow, ::nCol ) ) ::up() - if !::IsEmptyLine( ::nRow ) + IF !::IsEmptyLine( ::nRow ) ::end() ::wordLeft() - exit - endif - Enddo - endif + EXIT + ENDIF + ENDDO + ENDIF - dispend() + DispEnd() -Return Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD Home() CLASS XHBEditor ::GotoCol( 1 ) -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD K_Mouse( nKey ) CLASS XHBEditor + LOCAL nRow, nCol, nJump Switch nKey - case K_LBUTTONUP + CASE K_LBUTTONUP nRow := MRow() nCol := MCol() - if ( nRow >= ::nTop .and. nRow <= ::nBottom ) - if nCol >= ::nLeft .and. nCol <= ::nRight - if ( ::nRow + ( nJump := nRow - ::nPhysRow ) ) <= ::LastRow() - ::GotoPos( max( 1, ::nRow + nJump ), max( 1, ::nCol + ( nCol - ::nPhysCol ) ), .t. ) - endif - endif - endif - exit - case K_MWFORWARD + IF ( nRow >= ::nTop .AND. nRow <= ::nBottom ) + IF nCol >= ::nLeft .AND. nCol <= ::nRight + IF ( ::nRow + ( nJump := nRow - ::nPhysRow ) ) <= ::LastRow() + ::GotoPos( Max( 1, ::nRow + nJump ), Max( 1, ::nCol + ( nCol - ::nPhysCol ) ), .T. ) + ENDIF + ENDIF + ENDIF + EXIT + CASE K_MWFORWARD ::ClrTextSelection() ::Up() - exit - case K_MWBACKWARD + EXIT + CASE K_MWBACKWARD ::ClrTextSelection() ::Down() - exit + EXIT end -RETURN Self + RETURN Self -//-------------------------------------------------------------------// -// -// Keystroke Handelling -// -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// + // + // Keystroke Handelling + // + //-------------------------------------------------------------------// METHOD K_Ascii( nKey ) CLASS XHBEditor // nKey := ASC( HB_ANSITOOEM( CHR( nKey ) ) ) // convert from windows - IF !::lEditAllow .OR. ::nCol > ::nWordWrapCol+1 - Return Self + IF !::lEditAllow .OR. ::nCol > ::nWordWrapCol + 1 + RETURN Self ENDIF // 2006/JUL/22 - E.F. - IF there is no line into memo add a new one. IF ::LastRow() == 0 - ::AddLine("",.F.) + ::AddLine( "", .F. ) ENDIF ::nMarkPos := 0 @@ -1435,21 +1444,21 @@ METHOD K_Ascii( nKey ) CLASS XHBEditor if ::nCol > ::LineLen( ::nRow ) + 1 // At end of line, add room ::aText[ ::nRow ]:cText += Space( ::nCol - ::LineLen( ::nRow ) ) ::lChanged := .T. - endif + ENDIF // 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, Chr( nKey ) ) ::lChanged := .T. - else + ELSE ::aText[ ::nRow ]:cText := Stuff( ::aText[ ::nRow ]:cText, ::nCol, 1, Chr( nKey ) ) ::lChanged := .T. - endif + ENDIF // eventually wordwrap // - IF ::lWordWrap .and. ::LineLen( ::nRow ) > ::nWordWrapCol + IF ::lWordWrap .AND. ::LineLen( ::nRow ) > ::nWordWrapCol ::SplitLine( ::nRow ) ::Right() ELSE @@ -1457,11 +1466,12 @@ METHOD K_Ascii( nKey ) CLASS XHBEditor ::Right() ENDIF -RETURN Self + RETURN Self + + //-------------------------------------------------------------------// + // Backspace + // -//-------------------------------------------------------------------// -// Backspace -// METHOD K_Bs() CLASS XHBEditor IF !::lEditAllow @@ -1476,13 +1486,13 @@ METHOD K_Bs() CLASS XHBEditor // IF ::nCol == 1 - if ( ::lWordWrap ) + IF ( ::lWordWrap ) if ::nRow > 1 .AND. ::nRow <= ::LastRow() // 2006/JUL/21 - E.F. - Determine new ::nCol position. // - ::nCol := Min(::LineLen( ::nRow-1 ) + 1,::nWordWrapCol) + ::nCol := Min( ::LineLen( ::nRow - 1 ) + 1, ::nWordWrapCol ) ::nRow -- @@ -1491,7 +1501,7 @@ METHOD K_Bs() CLASS XHBEditor // remove a SINGLE trailing space, if it exists IF ::aText[ ::nRow ]:cText[-1] == " " - ::aText[ ::nRow ]:cText := Substr( ::aText[ ::nRow ]:cText, 1, ::LineLen( ::nRow ) - 1 ) + ::aText[ ::nRow ]:cText := SubStr( ::aText[ ::nRow ]:cText, 1, ::LineLen( ::nRow ) - 1 ) ENDIF ::aText[ ::nRow ]:cText += ::aText[ ::nRow + 1 ]:cText @@ -1506,25 +1516,25 @@ METHOD K_Bs() CLASS XHBEditor // 2006/JUL/21 - E.F. - Delete the rightmost char and pos the cursor on it. IF ::LineLen( ::nRow ) >= ::nWordWrapCol - ::aText[ ::nRow ]:cText := SubStr( ::aText[ ::nRow ]:cText, 1, ::LineLen(::nRow ) - 1 ) + " " - ::nCol := Min(::nCol+1,::nWordWrapCol+1) + ::aText[ ::nRow ]:cText := SubStr( ::aText[ ::nRow ]:cText, 1, ::LineLen( ::nRow ) - 1 ) + " " + ::nCol := Min( ::nCol + 1, ::nWordWrapCol + 1 ) ENDIF IF !Empty( ::aText[ ::nRow ]:cText ) ::GotoPos( ::nRow, ::nCol, .T. ) // also refresh ELSE - ::GotoPos( ::nRow, 1, .T.) + ::GotoPos( ::nRow, 1, .T. ) ENDIF - endif - endif + ENDIF + ENDIF // 2006/JUL/19 - E.F. When backspace reach column 1 and the line is // empty and exist next line, we need set linelen to // zero and set lSoftCR to true as Clipper does. // - IF ::nCol == 1 .AND. Empty( ::aText[ ::nRow ]:cText ) .AND.; - ::nRow+1 <= ::LastRow() + IF ::nCol == 1 .AND. Empty( ::aText[ ::nRow ]:cText ) .AND. ; + ::nRow + 1 <= ::LastRow() ::aText[ ::nRow ]:cText := "" ::aText[ ::nRow ]:lSoftCR := .T. @@ -1534,24 +1544,26 @@ METHOD K_Bs() CLASS XHBEditor ELSEIF ::nCol >= ::nFirstCol // delete previous character - ::aText[ ::nRow ]:cText := Stuff( ::aText[ ::nRow ]:cText, ::nCol-1, 1, "" ) - ::GotoCol( ::nCol -1 ) + ::aText[ ::nRow ]:cText := Stuff( ::aText[ ::nRow ]:cText, ::nCol - 1, 1, "" ) + ::GotoCol( ::nCol - 1 ) ::RefreshLine() ENDIF ::lChanged := .T. -RETURN Self + RETURN Self + + //-------------------------------------------------------------------// + // Process DEL key + // -//-------------------------------------------------------------------// -// Process DEL key -// METHOD K_Del() CLASS XHBEditor + LOCAL lMerge := .F. LOCAL nCurRow, nCurCol IF !::lEditAllow - Return Self + RETURN Self ENDIF IF ::nCol > ::LineLen( ::nRow ) //.and. ::nRow < ::LastRow() @@ -1580,7 +1592,7 @@ METHOD K_Del() CLASS XHBEditor // the first column, remove it after del. // IF ::IsEmptyLine( ::nRow ) .AND. ::nCol == 1 - ::RemoveLine(::nRow) + ::RemoveLine( ::nRow ) ENDIF lMerge := .T. ELSE @@ -1597,7 +1609,7 @@ METHOD K_Del() CLASS XHBEditor // 2006/07/19 - E.F. Merge line only if ::nRow+1 is valid, // to avoid bound error. // - IF ::nRow+1 <= ::LastRow() + IF ::nRow + 1 <= ::LastRow() // copy the other line ::aText[ ::nRow ]:cText += ::aText[ ::nRow + 1 ]:cText // copy its softcr setting @@ -1613,22 +1625,23 @@ METHOD K_Del() CLASS XHBEditor ::RefreshWindow() ENDIF -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD K_Tab() CLASS XHBEditor + LOCAL lHardCR, i IF !::lEditAllow - Return Self + RETURN Self ENDIF // insert char if in insert mode or at end of current line if ::nCol < ::nWordWrapCol - ::nTabWidth - ::nTabWidth if ::lInsert .OR. ( ::nCol == ::LineLen( ::nRow ) ) ::aText[ ::nRow ]:cText := Stuff( ::aText[ ::nRow ]:cText, ::nCol, 0, Space( ::nTabWidth ) ) - endif + ENDIF ::lChanged := .T. ::lRightScroll := .F. //prevent auto linewrap @@ -1636,23 +1649,23 @@ METHOD K_Tab() CLASS XHBEditor if ::nCol < ::nWordWrapCol - ::nTabWidth - ::nTabWidth ::Right() ::RefreshLine() - else + ELSE i := ::nTabWidth // end of line, stop it! - endif + ENDIF next - ::lRightScroll :=.T. + ::lRightScroll := .T. // wrap lines - if ::LineLen( ::nRow )> ::nWordWrapCol + if ::LineLen( ::nRow ) > ::nWordWrapCol lHardCR := .F. // should already by .F., but just to be safe, and it is a tiny line of code... if ::aText[ ::nRow ]:lSoftCR - if !::aText[ ::nRow+1 ]:lSoftCR // the next line has a hard return, keep it + IF !::aText[ ::nRow+1 ]:lSoftCR // the next line has a hard return, keep it lHardCR := .T. - endif + ENDIF if ::nRow == ::LastRow() - 1 // if next to last line of array, last line MUST have HR lHardCR := .T. - endif + ENDIF ::aText[ ::nRow ]:cText := ::aText[ ::nRow ]:cText + ::GetLine( ::nRow + 1 ) ::RemoveLine( ::nRow + 1 ) @@ -1660,23 +1673,23 @@ METHOD K_Tab() CLASS XHBEditor ::SplitLine( ::nRow ) ::RefreshWindow() - endif - endif - endif + ENDIF + ENDIF + ENDIF - Return Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD K_Return() CLASS XHBEditor - IF ::LastRow()==0 .AND. !::lInsert - Return Self + IF ::LastRow() == 0 .AND. !::lInsert + RETURN Self ENDIF IF ::lEditAllow -// 2006/JUL/24 - E.F. - Fixed at insert mode. + // 2006/JUL/24 - E.F. - Fixed at insert mode. /* * IF ::lInsert * IF ::nRow == ::LastRow() @@ -1699,15 +1712,15 @@ METHOD K_Return() CLASS XHBEditor */ IF ::lInsert - IF ::LastRow()==0 + IF ::LastRow() == 0 ::AddLine( "", .F. ) ENDIF - IF ::nRow == ::LastRow() .AND.; - ::nCol > ::LineLen( ::nRow ) + IF ::nRow == ::LastRow() .AND. ; + ::nCol > ::LineLen( ::nRow ) ::AddLine( "", .F. ) ELSE - ::InsertLine( Substr( ::aText[ ::nRow ]:cText, ::nCol ), .F., ::nRow + 1 ) + ::InsertLine( SubStr( ::aText[ ::nRow ]:cText, ::nCol ), .F. , ::nRow + 1 ) ENDIF ::aText[ ::nRow ]:cText := Left( ::aText[ ::nRow ]:cText, ::nCol - 1 ) @@ -1730,46 +1743,48 @@ METHOD K_Return() CLASS XHBEditor ::lChanged := .T. -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD K_Esc() CLASS XHBEditor - LOCAL cScreenMsg, nCurRow, nCurCol, nCursor,nKey + + LOCAL cScreenMsg, nCurRow, nCurCol, nCursor, nKey ::lExitEdit := .T. IF ::lEditAllow .AND. ::lChanged .AND. Set( _SET_SCOREBOARD ) nCurCol := ::Col() nCurRow := ::Row() - cScreenMsg := SaveScreen( 0,60,0,77 ) + cScreenMsg := SaveScreen( 0, 60, 0, 77 ) nCursor := SetCursor( SC_NORMAL ) - @ 0,60 say '(Abort Edit? Y/N)' - nKey := inkey( 0 ) - inkey() + @ 0, 60 SAY '(Abort Edit? Y/N)' + nKey := Inkey( 0 ) + Inkey() RestScreen( 0, 60, 0, 77, cScreenMsg ) - SetCursor(nCursor) - SetPos( nCurRow,nCurCol ) + SetCursor( nCursor ) + SetPos( nCurRow, nCurCol ) // 2006/JUL/21 - E.F - Exit only if "Y" is pressed. // - ::lExitEdit := ( Upper( Chr(nKey) ) == "Y" ) + ::lExitEdit := ( Upper( Chr(nKey ) ) == "Y" ) ENDIF IF ::lExitEdit SetCursor( ::nOrigCursor ) // restore original cursor saved at startup ENDIF -Return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Data Retrieval Methods + // + //-------------------------------------------------------------------// + // + // Add a new Line of text at end of current text + // -//-------------------------------------------------------------------// -// -// Data Retrieval Methods -// -//-------------------------------------------------------------------// -// -// Add a new Line of text at end of current text -// METHOD AddLine( cLine, lSoftCR ) CLASS XHBEditor DEFAULT cLine TO "" @@ -1777,12 +1792,13 @@ METHOD AddLine( cLine, lSoftCR ) CLASS XHBEditor AAdd( ::aText, HBTextLine():New( cLine, lSoftCR ) ) -return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Insert a line of text at a defined row + // -//-------------------------------------------------------------------// -// -// Insert a line of text at a defined row -// METHOD InsertLine( cLine, lSoftCR, nRow ) CLASS XHBEditor DEFAULT nRow TO ::nRow @@ -1797,150 +1813,161 @@ METHOD InsertLine( cLine, lSoftCR, nRow ) CLASS XHBEditor AIns( ::aText, nRow, HBTextLine():New( cLine, lSoftCR ), .T. ) ENDIF -return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Remove a line of text + // -//-------------------------------------------------------------------// -// -// Remove a line of text -// METHOD RemoveLine( nRow ) CLASS XHBEditor + DEFAULT nRow TO ::nRow ADel( ::aText, nRow, .T. ) -return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Return line n of text + // -//-------------------------------------------------------------------// -// -// Return line n of text -// METHOD GetLine( nRow ) CLASS XHBEditor + DEFAULT nRow TO ::nRow - if nRow <= ::LastRow() .AND. nRow > 0 - if ::lEditAllow .or. Empty(::nTabWidth) + IF nRow <= ::LastRow() .AND. nRow > 0 + if ::lEditAllow .OR. Empty( ::nTabWidth ) return ::aText[ nRow ]:cText - else - return HB_TabExpand(::aText[ nRow ]:cText, ::nTabWidth) - endif - else - return "" - endif + ELSE + RETURN HB_TabExpand( ::aText[ nRow ]:cText, ::nTabWidth ) + ENDIF + ELSE + RETURN "" + ENDIF -Return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Delete text from cursor to end of line. + // -//-------------------------------------------------------------------// -// -// Delete text from cursor to end of line. -// METHOD DelTextRight( nRow ) CLASS XHBEditor + DEFAULT nRow TO ::nRow IF !::lEditAllow - Return Self + RETURN Self ENDIF - if nRow > 0 .AND. nRow <= ::LastRow() + IF nRow > 0 .AND. nRow <= ::LastRow() ::lChanged := .T. - ::aText[ nRow ]:cText := Stuff( ::aText[ nRow ]:cText, ::nCol, ::LineLen(nRow) - ::nCol+1,"") + ::aText[ nRow ]:cText := Stuff( ::aText[ nRow ]:cText, ::nCol, ::LineLen( nRow ) - ::nCol + 1, "" ) ::RefreshLine() - endif + ENDIF -return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Delete a word to the right of cursor. + // -//-------------------------------------------------------------------// -// -// Delete a word to the right of cursor. -// METHOD DelWordRight() CLASS XHBEditor -LOCAL nCol,nCutCol -LOCAL nSpacesPre,cText + LOCAL nCol, nCutCol + LOCAL nSpacesPre, cText - nCutCol := 0 - nCol := ::nCol + nCutCol := 0 + nCol := ::nCol - IF !::lEditAllow - Return Self - ENDIF + IF !::lEditAllow + RETURN Self + ENDIF - ::lChanged :=.T. + ::lChanged := .T. - nSpacesPre := 0 - cText := SubStr(::aText[ ::nRow ]:cText,nCol) + nSpacesPre := 0 + cText := SubStr( ::aText[ ::nRow ]:cText, nCol ) - do While .T. - if Left( cText,1 )== " " .AND. Len( cText ) > 0 - cText := SubStr( cText, 2 ) - nSpacesPre++ - else - exit - endif - Enddo - - do While nCutCol <= 1 .AND. nCol < ::LineLen(::nRow) -1 - nCutCol := At(" ",SubStr(::aText[ ::nRow ]:cText,nCol) ) - if nCutCol <= 1 .AND. nCol < ::LineLen( ::nRow )-1 - nCol++ - elseif nCutCol <= 1 .AND. nCol >= ::LineLen( ::nRow ) - nCutCol := Len(SubStr(::aText[::nRow]:cText,::nCol,nCol-::nCol)) - exit - endif - Enddo - - - if nCutCol == 0 .AND. ::LineLen( ::nRow ) >= ::nCol - nCutCol := ::LineLen( ::nRow ) - ::nCol + 1 - endif - - if nCutCol > 0 - - ::aText[ ::nRow ]:cText := Stuff( ::aText[ ::nRow ]:cText,::nCol,+nSpacesPre+nCutCol," ") - - if ::lWordWrap .AND. ::aText[ ::nRow ]:lSoftCR - ::SplitLine( ::nRow ) - else - ::aText[::nRow]:lSoftCR := .F. - endif - - endif - -return Self - -//-------------------------------------------------------------------// -// behaviour. -// -METHOD ReformParagraph() CLASS XHBEditor -LOCAL nRow -LOCAL cHardCR := hb_eol() -LOCAL cSoftCR := chr(141) +chr(10) - - IF !::lEditAllow - Return Self - ENDIF - - IF ::LastRow() > 0 - - ::lChanged :=.T. - - FOR nRow := 1 TO ::LastRow() - - ::aText[ nRow ]:cText := StrTran(::aText[ nRow ]:cText, cSoftCR, "") - ::aText[ nRow ]:lSoftCR := .f. - - IF At( cHardCR, ::aText[ nRow ]:cText ) != 0 + DO WHILE .T. + IF Left( cText, 1 ) == " " .AND. Len( cText ) > 0 + cText := SubStr( cText, 2 ) + nSpacesPre ++ + ELSE EXIT ENDIF + ENDDO - NEXT + DO WHILE nCutCol <= 1 .AND. nCol < ::LineLen( ::nRow ) - 1 + nCutCol := At( " ", SubStr( ::aText[ ::nRow ]:cText,nCol ) ) + IF nCutCol <= 1 .AND. nCol < ::LineLen( ::nRow ) - 1 + nCol ++ + ELSEIF nCutCol <= 1 .AND. nCol >= ::LineLen( ::nRow ) + nCutCol := Len( SubStr( ::aText[::nRow]:cText,::nCol,nCol - ::nCol ) ) + EXIT + ENDIF + ENDDO - ENDIF -Return Self -//-------------------------------------------------------------------// + IF nCutCol == 0 .AND. ::LineLen( ::nRow ) >= ::nCol + nCutCol := ::LineLen( ::nRow ) - ::nCol + 1 + ENDIF + + IF nCutCol > 0 + + ::aText[ ::nRow ]:cText := Stuff( ::aText[ ::nRow ]:cText, ::nCol, + nSpacesPre + nCutCol, " " ) + + if ::lWordWrap .AND. ::aText[ ::nRow ]:lSoftCR + ::SplitLine( ::nRow ) + ELSE + ::aText[::nRow]:lSoftCR := .F. + ENDIF + + ENDIF + + RETURN Self + + //-------------------------------------------------------------------// + // behaviour. + // + +METHOD ReformParagraph() CLASS XHBEditor + + LOCAL nRow + LOCAL cHardCR := hb_eol() + LOCAL cSoftCR := Chr( 141 ) + Chr( 10 ) + + IF !::lEditAllow + RETURN Self + ENDIF + + IF ::LastRow() > 0 + + ::lChanged := .T. + + FOR nRow := 1 TO ::LastRow() + + ::aText[ nRow ]:cText := StrTran( ::aText[ nRow ]:cText, cSoftCR, "" ) + ::aText[ nRow ]:lSoftCR := .F. + + IF At( cHardCR, ::aText[ nRow ]:cText ) != 0 + EXIT + ENDIF + + NEXT + + ENDIF + + RETURN Self + + //-------------------------------------------------------------------// METHOD GotoLine( nRow ) CLASS XHBEditor - LOCAL lRefresh := .f. + + LOCAL lRefresh := .F. IF nRow > 0 .AND. nRow <= ::LastRow() @@ -1949,25 +1976,25 @@ METHOD GotoLine( nRow ) CLASS XHBEditor // IF nRow < ::nFirstRow ::nFirstRow := nRow - lRefresh := .t. + lRefresh := .T. ELSEIF nRow - ::nFirstRow >= ::nNumRows ::nFirstRow := Max( 1, nRow - ::nNumRows + 1 ) - lRefresh := .t. + lRefresh := .T. ENDIF - ::nRow := Max(1, Min( nRow, ::LastRow() ) ) + ::nRow := Max( 1, Min( nRow, ::LastRow() ) ) - if lRefresh + IF lRefresh ::RefreshWindow() - endif + ENDIF ::SetPos( ::nTop + nRow - ::nFirstRow, ::nLeft + ::nCol - ::nFirstCol ) ENDIF -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD GotoCol( nCol ) CLASS XHBEditor @@ -1977,7 +2004,7 @@ METHOD GotoCol( nCol ) CLASS XHBEditor // line, with or without chars. // Note: ::nWordWrapCol can be different than ::nNumCols if user has // informed nLineLength > 0. - nCol := Max( 1, Min( nCol, Max(::nNumCols,::nWordWrapCol+1) ) ) + nCol := Max( 1, Min( nCol, Max(::nNumCols,::nWordWrapCol + 1 ) ) ) // I need to move cursor if is past requested line number and if requested line is // inside first screen of text otherwise ::nFirstRow would be wrong @@ -1993,17 +2020,17 @@ METHOD GotoCol( nCol ) CLASS XHBEditor ::SetPos( ::Row(), ::nLeft + nCol - ::nFirstCol ) ENDIF -RETURN Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD GotoPos( nRow, nCol, lRefresh ) CLASS XHBEditor DEFAULT lRefresh TO .F. - dispbegin() // to minimize flicker + DispBegin() // to minimize flicker - if nRow > 0 .AND. nRow <= ::LastRow() + IF nRow > 0 .AND. nRow <= ::LastRow() // I need to move cursor if is past requested line number and if requested line is // inside first screen of text otherwise ::nFirstRow would be wrong // @@ -2011,7 +2038,7 @@ METHOD GotoPos( nRow, nCol, lRefresh ) CLASS XHBEditor ::nFirstRow := nRow lRefresh := .T. ELSEIF nRow - ::nFirstRow >= ::nNumRows - ::nFirstRow := Max(1, nRow - ::nNumRows + 1 ) + ::nFirstRow := Max( 1, nRow - ::nNumRows + 1 ) lRefresh := .T. ENDIF ::nRow := nRow @@ -2023,7 +2050,7 @@ METHOD GotoPos( nRow, nCol, lRefresh ) CLASS XHBEditor // line, with or without chars. // Note: ::nWordWrapCol can be different than ::nNumCols if user has // informed nLineLength > 0 - nCol := Max( 1, Min( nCol, Max(::nNumCols,::nWordWrapCol+1) ) ) + nCol := Max( 1, Min( nCol, Max(::nNumCols,::nWordWrapCol + 1 ) ) ) // I need to move cursor if is past requested line number and if requested line is @@ -2038,20 +2065,20 @@ METHOD GotoPos( nRow, nCol, lRefresh ) CLASS XHBEditor ::nCol := nCol ENDIF - dispend() + DispEnd() IF lRefresh ::RefreshWindow() ENDIF ::SetPos( ::nTop + nRow - ::nFirstRow, ::nLeft + nCol - ::nFirstCol ) -RETURN Self + RETURN Self -//-------------------------------------------------------------------// -// -// Rebuild a long line from multiple short ones ( wrapped at soft CR ) -// -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// + // + // Rebuild a long line from multiple short ones ( wrapped at soft CR ) + // + //-------------------------------------------------------------------// /* *STATIC function GetParagraph( oSelf, nRow ) @@ -2076,40 +2103,42 @@ RETURN Self *return cLine */ -STATIC function GetParagraph( oSelf, nRow ) +STATIC FUNCTION GetParagraph( oSelf, nRow ) LOCAL cLine := "" + // V@ - do while nRow <= oSelf:LastRow() .AND. ValType( oSelf:aText[ nRow ]:lSoftCR ) == 'L' .and. oSelf:aText[ nRow ]:lSoftCR + DO WHILE nRow <= oSelf:LastRow() .AND. ValType( oSelf:aText[ nRow ]:lSoftCR ) == 'L' .AND. oSelf:aText[ nRow ]:lSoftCR cLine += oSelf:aText[ nRow ]:cText oSelf:RemoveLine( nRow ) - if oSelf:LastRow() <= 0 // V@ - exit - endif + IF oSelf:LastRow() <= 0 // V@ + EXIT + ENDIF //GAD This is not needed and will corrupt long lines that do not have any spaces with wordwrap on. /* IF Len( cLine ) > 0 .and. cLine[ -1 ] != " " cLine += " " ENDIF */ - enddo + ENDDO // Last line, or only one line // - if nRow <= oSelf:LastRow() .AND. oSelf:LastRow() > 0 // V@ + IF nRow <= oSelf:LastRow() .AND. oSelf:LastRow() > 0 // V@ cLine += oSelf:aText[ nRow ]:cText oSelf:RemoveLine( nRow ) // this is where array error occurs IF final line of text is allowed to have :lSoftCR - endif + ENDIF -return cLine + RETURN cLine -//-------------------------------------------------------------------// -// -// If a line of text is longer than nWordWrapCol divides it into multiple lines, -// Used during text editing to reflow a paragraph -// -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// + // + // If a line of text is longer than nWordWrapCol divides it into multiple lines, + // Used during text editing to reflow a paragraph + // + //-------------------------------------------------------------------// METHOD SplitLine( nRow ) CLASS XHBEditor + LOCAL nFirstSpace, nCurSpace LOCAL cLine LOCAL cSplittedLine @@ -2135,7 +2164,7 @@ METHOD SplitLine( nRow ) CLASS XHBEditor // nFirstSpace := 0 nCurSpace := At( " ", cLine ) - DO WHILE nCurSpace <= ::nCol .and. nCurSpace > 0 + DO WHILE nCurSpace <= ::nCol .AND. nCurSpace > 0 nFirstSpace := nCurSpace nCurSpace := hb_At( " ", cLine, nCurSpace + 1 ) ENDDO @@ -2144,12 +2173,12 @@ METHOD SplitLine( nRow ) CLASS XHBEditor // remember that nFirstSpace is zero based, and pointing to one space // before the current word. // - nPosInWord := IIF( ::nCol > nFirstSpace, ::nCol - nFirstSpace, 1 ) + nPosInWord := iif( ::nCol > nFirstSpace, ::nCol - nFirstSpace, 1 ) nStartRow := nRow cLine := GetParagraph( Self, nRow ) - do while Len( cLine ) >= ::nWordWrapCol + DO WHILE Len( cLine ) >= ::nWordWrapCol // Added + 1 because it is possible that line ends when there is a space // next to nWordWrapCol // @@ -2157,15 +2186,15 @@ METHOD SplitLine( nRow ) CLASS XHBEditor // Split line at fist space before current position // - do while nFirstSpace > 1 .and. !( cLine[nFirstSpace] == " " ) + DO WHILE nFirstSpace > 1 .AND. !( cLine[nFirstSpace] == " " ) nFirstSpace -- - enddo + ENDDO // If there is a space before beginning of line split there // - if nFirstSpace > 1 + IF nFirstSpace > 1 cSplittedLine := Left( cLine, nFirstSpace ) - else + ELSE // Changed -- now splits line at the nWordWrapCol when no space! The cursor position is not reliable! // This avoids error if the line has NO SPACES! Without this modif. code enters infinite loop on wrap // Note that cursor postioning when wrapping lines that have NO space is funky due to MovetoNextLine() problems @@ -2177,26 +2206,26 @@ METHOD SplitLine( nRow ) CLASS XHBEditor // amount of chars same as Clipper. // //cSplittedLine := Left( cLine, ::nWordWrapCol ) - cSplittedLine := Left( cLine, Min(::nWordWrapCol+1,::nNumCols) ) + cSplittedLine := Left( cLine, Min( ::nWordWrapCol + 1,::nNumCols ) ) - endif + ENDIF // A necessity because xHarbour does not insert the SoftCarriage and // then we are unable to keep trace of where the line break was while // reformatting // -//GAD - if !( right( cSplittedLine, 1 ) == " " ) .AND. nFirstSpace > 1 + //GAD + IF !( Right( cSplittedLine, 1 ) == " " ) .AND. nFirstSpace > 1 // 2006/JUL/21 - E.F. - Added condition to not stay out of max columns. - if Len(cSplittedLine) < ::nNumCols + IF Len( cSplittedLine ) < ::nNumCols cSplittedLine += " " - endif - endif + ENDIF + ENDIF // We must not trim the line as split occurs next to a space // - ::InsertLine( cSplittedLine, .T., nStartRow++ ) - cLine := Substr( cLine, Len( cSplittedLine ) + 1 ) - enddo + ::InsertLine( cSplittedLine, .T. , nStartRow ++ ) + cLine := SubStr( cLine, Len( cSplittedLine ) + 1 ) + ENDDO // insert EVEN an empty row (it will be added at bottom) // I have to recheck if trim is viable here ??? @@ -2204,12 +2233,12 @@ METHOD SplitLine( nRow ) CLASS XHBEditor // 2006/JUL/21 - E.F. Only insert a line in any circunstancies. // - IF nStartRow+1 <= ::LastRow() - IF ::LineLen( nStartRow+1 ) == 0 .OR. Len( alltrim(cLine) ) > 0 - ::InsertLine( Trim(cLine), .F., nStartRow ) + IF nStartRow + 1 <= ::LastRow() + IF ::LineLen( nStartRow + 1 ) == 0 .OR. Len( AllTrim( cLine ) ) > 0 + ::InsertLine( Trim( cLine ), .F. , nStartRow ) ENDIF ELSE - ::InsertLine( Trim(cLine), .F., nStartRow ) + ::InsertLine( Trim( cLine ), .F. , nStartRow ) ENDIF // re-count words and see where current word has gone. @@ -2218,7 +2247,7 @@ METHOD SplitLine( nRow ) CLASS XHBEditor IF Len( cLine ) < ::nCol nCurSpace := At( " ", cLine ) // stop when word count has matched OR when nCol is passed (all stay in current line). - DO WHILE nCurSpace > 0 .and. nCurSpace <= ::nCol + DO WHILE nCurSpace > 0 .AND. nCurSpace <= ::nCol nCurSpace := hb_At( " ", cLine, nCurSpace + 1 ) ENDDO @@ -2239,50 +2268,49 @@ METHOD SplitLine( nRow ) CLASS XHBEditor ENDIF ::lRightScroll := .T. // set at beginning of if/endif -- must be .F. in SplitScreen() -RETURN Self + RETURN Self -//-------------------------------------------------------------------// -// -// Utility Methods -// -//-------------------------------------------------------------------// -// -// This in an empty method which can be used by classes subclassing HBEditor to be able -// to handle particular keys. -// -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// + // + // Utility Methods + // + //-------------------------------------------------------------------// + // + // This in an empty method which can be used by classes subclassing HBEditor to be able + // to handle particular keys. + // + //-------------------------------------------------------------------// METHOD KeyboardHook() CLASS XHBEditor -return Self + RETURN Self -//-------------------------------------------------------------------// -// -// There are no more keys to handle. Can I do something for you? -// + //-------------------------------------------------------------------// + // + // There are no more keys to handle. Can I do something for you? + // METHOD IdleHook() CLASS XHBEditor -return Self + RETURN Self - -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD SetColor( cColorString ) CLASS XHBEditor - local cOldColor := ::cColorSpec + LOCAL cOldColor := ::cColorSpec - if cColorString != nil - ::cColorSpec := cColorString - endif + IF cColorString != nil + ::cColorSpec := cColorString + ENDIF -return cOldColor + RETURN cOldColor -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD Hilite() CLASS XHBEditor - local cEnhanced := "" + LOCAL cEnhanced := "" // Swap CLR_STANDARD and CLR_ENHANCED cEnhanced += __StrToken( ::cColorSpec, 2, "," ) + "," @@ -2290,13 +2318,13 @@ METHOD Hilite() CLASS XHBEditor ::SetColor( cEnhanced + Right( ::cColorSpec, Len( ::cColorSpec ) - Len( cEnhanced ) ) ) -return Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD DeHilite() CLASS XHBEditor - local cStandard := "" + LOCAL cStandard := "" // Swap CLR_STANDARD and CLR_ENHANCED back to their original position inside cColorSpec cStandard += __StrToken( ::cColorSpec, 2, "," ) + "," @@ -2304,26 +2332,27 @@ METHOD DeHilite() CLASS XHBEditor ::SetColor( cStandard + Right( ::cColorSpec, Len( ::cColorSpec ) - Len( cStandard ) ) ) -return Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD SetPos( nRow, nCol ) CLASS XHBEditor - default nRow to ::nPhysRow - default nCol to ::nPhysCol + DEFAULT nRow to ::nPhysRow + DEFAULT nCol to ::nPhysCol ::nPhysRow := nRow ::nPhysCol := nCol SetPos( ::nPhysRow, ::nPhysCol ) -return ::nPhysRow + return ::nPhysRow + + //-------------------------------------------------------------------// + // + // Changes lInsert value and insertion / overstrike mode of editor + // -//-------------------------------------------------------------------// -// -// Changes lInsert value and insertion / overstrike mode of editor -// METHOD InsertState( lInsState ) CLASS XHBEditor // 2006/JUL/22 - E.F. - Insert only in edit mode. @@ -2334,86 +2363,87 @@ METHOD InsertState( lInsState ) CLASS XHBEditor // Redundant, but useful if ::lInsert is used as class DATA SET( _SET_INSERT, lInsState ) - if lInsState - Setcursor( SC_INSERT ) - else - Setcursor( SC_NORMAL ) - endif + IF lInsState + SetCursor( SC_INSERT ) + ELSE + SetCursor( SC_NORMAL ) + ENDIF - ::DisplayInsert( lInsState ) + ::DisplayInsert( lInsState ) ENDIF -return Self + RETURN Self + + //-------------------------------------------------------------------// + // 2006/JUL/15 - E.F. - Display "" message + // -//-------------------------------------------------------------------// -// 2006/JUL/15 - E.F. - Display "" message -// METHOD DisplayInsert( lInsert ) CLASS XHBEditor + LOCAL nCurRow, nCurCol, nCursor - if Set( _SET_SCOREBOARD ) + IF SET( _SET_SCOREBOARD ) nCurCol := Col() nCurRow := Row() - nCursor := SetCursor(SC_NONE) + nCursor := SetCursor( SC_NONE ) - if lInsert + IF lInsert IF ::cInsLabel == NIL - ::cInsLabel := SaveScreen(0,60,0,67 ) + ::cInsLabel := SaveScreen( 0, 60, 0, 67 ) ENDIF - @ 0,60 say "" - else + @ 0, 60 SAY "" + ELSE IF ::cInsLabel != NIL - RestScreen(0,60,0,67, ::cInsLabel ) + RestScreen( 0, 60, 0, 67, ::cInsLabel ) ::cInsLabel := NIL ENDIF - endif + ENDIF - SetCursor(nCursor) - SetPos( nCurRow,nCurCol ) + SetCursor( nCursor ) + SetPos( nCurRow, nCurCol ) - endif + ENDIF + RETURN NIL -Return NIL + //-------------------------------------------------------------------// + // + // Converts an array of text lines to a String + // -//-------------------------------------------------------------------// -// -// Converts an array of text lines to a String -// METHOD GetText( lSoftCr ) CLASS XHBEditor - LOCAL cString := "", cSoft:= "" + LOCAL cString := "", cSoft := "" LOCAL cEOL := hb_eol() - DEFAULT lSoftCr TO .F. -IF ::LastRow() > 0 + IF ::LastRow() > 0 - if lSoftCr - cSoft:= CHR( 141 ) + CHR( 10 ) - endif + IF lSoftCr + cSoft := Chr( 141 ) + Chr( 10 ) + ENDIF - if ::lWordWrap - AEval( ::aText, {| cItem | cString += cItem:cText + iif( cItem:lSoftCR, cSoft, cEOL )},,::LastRow() - 1) - else - AEval( ::aText, {| cItem | cString += cItem:cText + cEOL},, ::LastRow() - 1) - endif + if ::lWordWrap + AEval( ::aText, { | cItem | cString += cItem:cText + iif( cItem:lSoftCR, cSoft, cEOL ) }, , ::LastRow() - 1 ) + ELSE + AEval( ::aText, { | cItem | cString += cItem:cText + cEOL }, , ::LastRow() - 1 ) + ENDIF - // Last line does not need a cEOL delimiter - cString += ::aText[ ::LastRow() ]:cText + // Last line does not need a cEOL delimiter + cString += ::aText[ ::LastRow() ]:cText -ENDIF + ENDIF -return cString + RETURN cString + //-------------------------------------------------------------------// + // + // Returns the text selection in a string + // -//-------------------------------------------------------------------// -// -// Returns the text selection in a string -// METHOD GetTextSelection( lSoftCr ) CLASS XHBEditor LOCAL cString := "" @@ -2425,152 +2455,152 @@ METHOD GetTextSelection( lSoftCr ) CLASS XHBEditor DEFAULT lSoftCr TO .F. - if !::lSelActive - Return cString - endif + IF !::lSelActive + RETURN cString + ENDIF - if lSoftCr - cSoft:= CHR( 141 ) + CHR( 10 ) - endif + IF lSoftCr + cSoft := Chr( 141 ) + Chr( 10 ) + ENDIF - if ::nRowSelStart > 0 .and. ::nRowSelEnd > 0 + if ::nRowSelStart > 0 .AND. ::nRowSelEnd > 0 if ::nRowSelStart > ::nRowSelEnd nRowSelStart := ::nRowSelEnd nRowSelEnd := ::nRowSelStart - else + ELSE nRowSelStart := ::nRowSelStart nRowSelEnd := ::nRowSelEnd - endif + ENDIF FOR nI := nRowSelStart TO nRowSelEnd - cString += ::aText[ nI ]:cText + iif(::lWordWrap .and. ::aText[ nI ]:lSoftCR, cSoft, cEOL ) + cString += ::aText[ nI ]:cText + iif( ::lWordWrap .AND. ::aText[ nI ]:lSoftCR, cSoft, cEOL ) NEXT - endif + ENDIF - if ::nColSelStart > 0 .and. ::nColSelEnd > 0 - cString += SubStr( ::aText[ ::nRow ]:cText, ::nColSelStart, ::nColSelEnd - ::nColSelStart + 1 ) + iif(::lWordWrap .and. ::aText[ ::nRow ]:lSoftCR, cSoft, cEOL ) - endif + if ::nColSelStart > 0 .AND. ::nColSelEnd > 0 + cString += SubStr( ::aText[ ::nRow ]:cText, ::nColSelStart, ::nColSelEnd - ::nColSelStart + 1 ) + iif( ::lWordWrap .AND. ::aText[ ::nRow ]:lSoftCR, cSoft, cEOL ) + ENDIF -Return cString + RETURN cString + + //-------------------------------------------------------------------// + // + // Set current selection + // -//-------------------------------------------------------------------// -// -// Set current selection -// METHOD SetTextSelection( cAction, nCount ) CLASS XHBEditor - - if !::lSelActive + IF !::lSelActive ::lSelActive := .T. - if cAction == "ALL" + IF cAction == "ALL" ::nRowSelStart := 1 ::nRowSelEnd := ::LastRow() ::nColSelStart := ::nColSelEnd := 0 ::RefreshWindow() - elseif cAction == "ROW" + ELSEIF cAction == "ROW" ::GotoCol( 1 ) - if nCount > 0 // Shift-Down + IF nCount > 0 // Shift-Down ::nRowSelStart := ::nRow ::nRowSelEnd := ::nRowSelStart ::RefreshLine() if ::nRow < ::LastRow() ::GotoLine( ::nRow + 1 ) - endif + ENDIF - elseif nCount < 0 // Shift-UP + ELSEIF nCount < 0 // Shift-UP if ::nRow > 1 ::GotoLine( ::nRow - 1 ) - endif + ENDIF ::nRowSelStart := ::nRow ::nRowSelEnd := ::nRowSelStart ::RefreshLine() - endif + ENDIF - elseif cAction == "COL" + ELSEIF cAction == "COL" - if nCount > 0 // Shift Right - if ::nCol < ::nWordWrapCol+1 - ::GotoCol( ::nCol + 1) - if ::nColSelStart==0 + IF nCount > 0 // Shift Right + if ::nCol < ::nWordWrapCol + 1 + ::GotoCol( ::nCol + 1 ) + if ::nColSelStart == 0 ::nColSelRow := ::nRow - ::nColSelStart := Max(1,::nCol-1) - endif - ::nColSelEnd := Max(1,::nCol-1) - ::RefreshLine(.T.) - endif - elseif nCount < 0 // Shift Left + ::nColSelStart := Max( 1, ::nCol - 1 ) + ENDIF + ::nColSelEnd := Max( 1, ::nCol - 1 ) + ::RefreshLine( .T. ) + ENDIF + ELSEIF nCount < 0 // Shift Left if ::nCol > 1 - if ::nColSelStart=0 .and. ::nColSelEnd=0 + if ::nColSelStart = 0 .AND. ::nColSelEnd = 0 ::nColSelEnd := ::nColSelStart := ::nCol - endif + ENDIF ::GotoCol( ::nCol - 1 ) - ::nColSelEnd := Max(::nColSelEnd,::nCol) + ::nColSelEnd := Max( ::nColSelEnd, ::nCol ) ::nColSelRow := ::nRow ::nColSelStart := ::nCol - else + ELSE ::nColSelRow := ::nColSelStart := ::nColSelEnd := 0 ::lSelActive := .F. - endif - ::RefreshLine(.T.) - endif + ENDIF + ::RefreshLine( .T. ) + ENDIF - elseif cAction == "END" + ELSEIF cAction == "END" - if ::nColSelStart==0 - ::nColSelRow := ::nRow - ::nColSelStart := Max(1,::nCol-1) - endif + if ::nColSelStart == 0 + ::nColSelRow := ::nRow + ::nColSelStart := Max( 1, ::nCol - 1 ) + ENDIF ::End() - ::nColSelEnd := Max(1,::nCol-1) - ::RefreshLine(.T.) + ::nColSelEnd := Max( 1, ::nCol - 1 ) + ::RefreshLine( .T. ) - elseif cAction == "HOME" + ELSEIF cAction == "HOME" ::nColSelRow := ::nRow ::nColSelEnd := ::nCol ::nColSelStart := 1 ::GotoCol( 1 ) - ::RefreshLine(.T.) + ::RefreshLine( .T. ) - endif + ENDIF - else + ELSE - if cAction == "ALL" + IF cAction == "ALL" ::nRowSelStart := 1 ::nRowSelEnd := ::LastRow() ::nColSelStart := ::nColSelEnd := 0 ::RefreshWindow() - elseif cAction == "ROW" + ELSEIF cAction == "ROW" - if nCount > 0 // Shift-Down + IF nCount > 0 // Shift-Down if ::nRowSelStart == 0 ::nRowSelStart := ::nRow elseif ::nRowSelEnd > ::nRow ::Clrtextselection() - ::lSelActive := .t. - ::nRowSelEnd := ::nRowSelStart := ::nRow -1 - endif + ::lSelActive := .T. + ::nRowSelEnd := ::nRowSelStart := ::nRow - 1 + ENDIF - if ::nRow >= ::nRowSelStart .and. ::nRow <= ::nRowSelEnd - if ::nColSelStart > 0 .and. ::nColSelEnd > 0 + if ::nRow >= ::nRowSelStart .AND. ::nRow <= ::nRowSelEnd + if ::nColSelStart > 0 .AND. ::nColSelEnd > 0 ::nRowSelStart := ::nRow - else - ::nRowSelStart := ::nRow+1 - endif - else + ELSE + ::nRowSelStart := ::nRow + 1 + ENDIF + ELSE ::nRowSelEnd := ::nRow - endif + ENDIF ::nColSelStart := ::nColSelEnd := 0 @@ -2579,134 +2609,135 @@ METHOD SetTextSelection( cAction, nCount ) CLASS XHBEditor /* 2006/SEP/17 - E.F. - At this point we need add a new line to be able to select the last row. */ - if !Empty( ::aText[::nRowSelEnd]:cText ) + IF !Empty( ::aText[::nRowSelEnd]:cText ) ::AddLine() - else - ::nRowSelEnd := ::LastRow()-1 - endif - endif + ELSE + ::nRowSelEnd := ::LastRow() - 1 + ENDIF + ENDIF ::RefreshLine() if ::nRow < ::LastRow() ::GotoLine( ::nRow + 1 ) - endif + ENDIF - elseif nCount < 0 // Shift-Up + ELSEIF nCount < 0 // Shift-Up // if columns was already selected before... // - if (::nRowSelStart == 0 .and. ::nRowSelEnd==0) .or.; - (::nRowSelEnd - ::nRowSelStart == 1 .and.; - ::nColSelStart > 0 .and. ::nColSelEnd > 0) + IF ( ::nRowSelStart == 0 .AND. ::nRowSelEnd == 0 ) .OR. ; + ( ::nRowSelEnd - ::nRowSelStart == 1 .AND. ; + ::nColSelStart > 0 .AND. ::nColSelEnd > 0 ) ::nColSelStart := ::nColSelEnd := 0 ::nRowSelStart := ::nRow ::nRowSelEnd := ::nRow ::RefreshLine() - elseif ::nRowSelEnd - ::nRowSelStart > 1 .and.; - ::nColSelStart > 0 .and. ::nColSelEnd > 0 + elseif ::nRowSelEnd - ::nRowSelStart > 1 .AND. ; + ::nColSelStart > 0 .AND. ::nColSelEnd > 0 ::Clrtextselection() - ::lSelActive :=.t. - ::nRowSelEnd := ::nRow-1 + ::lSelActive := .T. + ::nRowSelEnd := ::nRow - 1 ::nRowSelStart := ::nRowSelEnd ::RefreshLine() - endif + ENDIF if ::nRow > 1 ::GotoLine( ::nRow - 1 ) - endif + ENDIF if ::nRow >= ::nRowSelStart .AND. ::nRow <= ::nRowSelEnd if ::nRowSelEnd - ::nRowSelStart > 0 ::nRowSelEnd := ::nRow - 1 - else + ELSE ::nRowSelEnd := ::nRow - endif - else + ENDIF + ELSE ::nRowSelStart := ::nRow - endif + ENDIF - if ::nRow==1 .and. ::nRowSelStart == 1 .and. ::nRowSelEnd == 1 + if ::nRow == 1 .AND. ::nRowSelStart == 1 .AND. ::nRowSelEnd == 1 ::Clrtextselection() - endif + ENDIF ::RefreshLine() - endif + ENDIF - elseif cAction == "COL" + ELSEIF cAction == "COL" - if nCount > 0 // Shift-Right - if ::nCol < ::nWordWrapCol+1 - ::GotoCol( ::nCol + 1) - if ::nColSelStart==0 + IF nCount > 0 // Shift-Right + if ::nCol < ::nWordWrapCol + 1 + ::GotoCol( ::nCol + 1 ) + if ::nColSelStart == 0 ::nColSelRow := ::nRow - ::nColSelStart := Max(1,::nCol-1) - endif - ::nColSelEnd := Max(::nColSelStart,::nCol-1) + ::nColSelStart := Max( 1, ::nCol - 1 ) + ENDIF + ::nColSelEnd := Max( ::nColSelStart, ::nCol - 1 ) if ::nColSelStart == ::nColSelEnd - ::nColSelStart := ::nColSelEnd := Max(1,::nCol-1) + ::nColSelStart := ::nColSelEnd := Max( 1, ::nCol - 1 ) ::nColSelRow := 0 - endif - ::RefreshLine(.T.) - endif + ENDIF + ::RefreshLine( .T. ) + ENDIF - elseif nCount < 0 // Shift-Left + ELSEIF nCount < 0 // Shift-Left if ::nCol > 1 ::GotoCol( ::nCol - 1 ) - if ::nColSelEnd==0 + if ::nColSelEnd == 0 ::nColSelRow := ::nRow - ::nColSelEnd := Max(::nColSelEnd,::nCol) - endif - if ::nColSelStart <=::nCol-1 - ::nColSelEnd := Min(::nColSelEnd,::nCol-1) - else - ::nColSelStart := Max(1,::nCol) - endif - if ::nCol=1 .and. ::nColSelStart == ::nColSelEnd + ::nColSelEnd := Max( ::nColSelEnd, ::nCol ) + ENDIF + if ::nColSelStart <= ::nCol - 1 + ::nColSelEnd := Min( ::nColSelEnd, ::nCol - 1 ) + ELSE + ::nColSelStart := Max( 1, ::nCol ) + ENDIF + if ::nCol = 1 .AND. ::nColSelStart == ::nColSelEnd ::lSelActive := .F. - endif - ::RefreshLine(.T.) - else + ENDIF + ::RefreshLine( .T. ) + ELSE if ::nColSelEnd == ::nColSelStart ::nColSelStart := ::nColSelEnd := 0 ::nColSelRow := 0 - endif + ENDIF ::lSelActive := .F. - endif + ENDIF - endif + ENDIF - elseif cAction == "END" + ELSEIF cAction == "END" - if ::nColSelStart==0 - ::nColSelStart := Max(1,::nCol-1) - endif + if ::nColSelStart == 0 + ::nColSelStart := Max( 1, ::nCol - 1 ) + ENDIF ::End() - ::nColSelEnd := Max(1,::nCol-1) - ::RefreshLine(.T.) + ::nColSelEnd := Max( 1, ::nCol - 1 ) + ::RefreshLine( .T. ) - elseif cAction == "HOME" + ELSEIF cAction == "HOME" ::nColSelEnd := ::nCol ::nColSelStart := 1 ::GotoCol( 1 ) - ::RefreshLine(.T.) + ::RefreshLine( .T. ) - endif + ENDIF - endif + ENDIF -return nil + RETURN nil + + //-------------------------------------------------------------------// + // + // Clear current selection + // -//-------------------------------------------------------------------// -// -// Clear current selection -// METHOD ClrTextSelection() CLASS XHBEditor if ::lSelActive @@ -2715,14 +2746,14 @@ METHOD ClrTextSelection() CLASS XHBEditor ::nColSelRow := 0 ::nColSelStart := ::nColSelEnd := 0 ::RefreshWindow() - endif + ENDIF -Return nil + RETURN nil METHOD DelText() CLASS XHBEditor IF !::lEditAllow - Return self + RETURN self ENDIF // 2006/SEP/17 - E.F. - changed to ::top() to avoid cursor out of bound. @@ -2739,8 +2770,7 @@ METHOD DelText() CLASS XHBEditor ::RefreshWindow() -return Self - + RETURN Self METHOD DelTextSelection() CLASS XHBEditor @@ -2749,66 +2779,66 @@ METHOD DelTextSelection() CLASS XHBEditor LOCAL nI LOCAL cText - if !::lEditAllow - Return Self - endif + IF !::lEditAllow + RETURN Self + ENDIF if ::lSelActive // if only rows are selected - if ::nRowSelStart > 0 .and. ::nRowSelEnd > 0 + if ::nRowSelStart > 0 .AND. ::nRowSelEnd > 0 if ::nRowSelStart > ::nRowSelEnd nRowSelStart := ::nRowSelEnd nRowSelEnd := ::nRowSelStart - else + ELSE nRowSelStart := ::nRowSelStart nRowSelEnd := ::nRowSelEnd - endif + ENDIF ::lChanged := .T. - for nI := nRowSelStart to nRowSelEnd - ::RemoveLine( nRowSelStart ) + for nI := nRowSelStart TO nRowSelEnd + ::RemoveLine( nRowSelStart ) next ::nRow := nRowSelStart - if empty( ::aText ) + IF Empty( ::aText ) ::DelText() - else - ::GoToPos( max(1,nRowSelStart) , 1 ) - endif + ELSE + ::GoToPos( Max( 1,nRowSelStart ) , 1 ) + ENDIF ::ClrTextSelection() - else + ELSE - if ::nColSelStart > 0 .and. ::nColSelEnd > 0 -// if empty( nRowSelStart ) -// nRowSelStart := ::nColSelRow -// endif + if ::nColSelStart > 0 .AND. ::nColSelEnd > 0 + // if empty( nRowSelStart ) + // nRowSelStart := ::nColSelRow + // endif cText := ::aText[::nRow]:cText ::aText[::nRow]:cText := Stuff( cText, ::nColSelStart, ::nColSelEnd - ::nColSelStart + 1, "" ) ::RefreshLine() - ::GoToPos( ::nRow, max(1,::nColSelStart ) ) + ::GoToPos( ::nRow, Max( 1,::nColSelStart ) ) ::nColSelStart := ::nColSelEnd := 0 ::lChanged := .T. - if empty( ::aText ) + IF Empty( ::aText ) ::DelText() - endif - endif + ENDIF + ENDIF - endif + ENDIF // 3/03/2008 8:26a.m. added next 4 lines to fix array out of bounds RTL if ::nRow > ::LastRow() - ::Addline("", .F. ) + ::Addline( "", .F. ) ::GoBottom() - endif + ENDIF - endif + ENDIF -Return Self + RETURN Self METHOD AddText( cString, lAtPos ) CLASS XHBEditor @@ -2818,50 +2848,51 @@ METHOD AddText( cString, lAtPos ) CLASS XHBEditor LOCAL nAtRow LOCAL lSaveIns - if !::lEditAllow - Return Self - endif + IF !::lEditAllow + RETURN Self + ENDIF - if !empty( cString ) + IF !Empty( cString ) aTmpText := Text2Array( cString, iif( ::lWordWrap, ::nNumCols, nil ) ) nLines := Len( aTmpText ) nAtRow := ::nRow lSaveIns := ::lInsert - if !lSaveIns + IF !lSaveIns ::InsertState( .T. ) - endif + ENDIF DEFAULT lAtPos TO .F. - if !lAtPos .or. ( nAtRow > ::LastRow() ) - for i := 1 to nLines - aadd( ::aText, aTmpText[ i ] ) + IF !lAtPos .OR. ( nAtRow > ::LastRow() ) + for i := 1 TO nLines + AAdd( ::aText, aTmpText[ i ] ) next - else - nAtRow-- - for i := 1 to nLines - AIns( ::aText, nAtRow+i, aTmpText[ i ], .T. ) + ELSE + nAtRow -- + for i := 1 TO nLines + AIns( ::aText, nAtRow + i, aTmpText[ i ], .T. ) next - if nLines > 0 - // ::RemoveLine(nAtRow+nLines) - endif - endif + IF nLines > 0 + // ::RemoveLine(nAtRow+nLines) + ENDIF + ENDIF - if !lSaveIns + IF !lSaveIns ::InsertState( .F. ) - endif + ENDIF ::lChanged := .T. ::RefreshWindow() - endif + ENDIF -return Self + RETURN Self METHOD GetTextIndex() CLASS XHBEditor + LOCAL nPos := 0 LOCAL oItem, nCount LOCAL nEol := Len( hb_eol() ) @@ -2880,9 +2911,10 @@ METHOD GetTextIndex() CLASS XHBEditor ENDIF nPos += ::nCol -RETURN nPos -//-------------------------------------------------------------------// + RETURN nPos + + //-------------------------------------------------------------------// METHOD LoadText( cString ) CLASS XHBEditor @@ -2890,82 +2922,85 @@ METHOD LoadText( cString ) CLASS XHBEditor if ::LastRow() == 0 AAdd( ::aText, HBTextLine():New() ) - endif + ENDIF ::lChanged := .F. ::GoTop() -Return Self + RETURN Self -//-------------------------------------------------------------------// + //-------------------------------------------------------------------// METHOD LoadFile( cFileName ) CLASS XHBEditor - local cString := "" + LOCAL cString := "" - if File( cFileName ) + IF File( cFileName ) ::cFile := cFileName cString := MemoRead( cFileName ) - endif + ENDIF ::aText := Text2Array( cString, iif( ::lWordWrap, ::nNumCols, nil ) ) if ::LastRow() == 0 AAdd( ::aText, HBTextLine():New() ) - endif + ENDIF ::lChanged := .F. ::GoTop() -return Self + RETURN Self + + //-------------------------------------------------------------------// + // + // Saves file being edited, if there is no file name does nothing, returns .T. if OK + // -//-------------------------------------------------------------------// -// -// Saves file being edited, if there is no file name does nothing, returns .T. if OK -// METHOD SaveFile() CLASS XHBEditor - local cString + LOCAL cString - if !Empty( ::cFile ) + IF !Empty( ::cFile ) cString := ::GetText() ::lChanged := !MemoWrit( ::cFile, cString ) - return !::lChanged - endif + RETURN !::lChanged + ENDIF -Return .F. + RETURN .F. -//-------------------------------------------------------------------// -// -// Utility Functions -// -//-------------------------------------------------------------------// -// -// Returns EOL char ( be it either CR or LF or both ) -// -STATIC function WhichEOL( cString ) + //-------------------------------------------------------------------// + // + // Utility Functions + // + //-------------------------------------------------------------------// + // + // 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 ) + IF nCRPos > 0 .AND. nLFPos == 0 + RETURN Chr( 13 ) - elseif nCRPos == 0 .AND. nLFPos > 0 - return Chr( 10 ) + ELSEIF nCRPos == 0 .AND. nLFPos > 0 + RETURN Chr( 10 ) - elseif nCRPos > 0 .AND. nLFPos == nCRPos + 1 - return Chr( 13 ) + Chr( 10 ) + ELSEIF nCRPos > 0 .AND. nLFPos == nCRPos + 1 + RETURN Chr( 13 ) + Chr( 10 ) - endif + ENDIF -return hb_eol() + RETURN hb_eol() -//-------------------------------------------------------------------// -// -// Converts a string to an array of strings splitting input string at EOL boundaries -// -STATIC function Text2Array( cString, nWordWrapCol ) + //-------------------------------------------------------------------// + // + // Converts a string to an array of strings splitting input string at EOL boundaries + // + +STATIC FUNCTION Text2Array( cString, nWordWrapCol ) LOCAL cLine LOCAL aArray @@ -2976,8 +3011,8 @@ STATIC function Text2Array( cString, nWordWrapCol ) LOCAL nFirstSpace LOCAL cSplittedLine LOCAL nTokPos := 0 - LOCAL lTokenized:=.f. - LOCAL cSoftCR := CHR(141)+CHR(10) + LOCAL lTokenized := .F. + LOCAL cSoftCR := Chr( 141 ) + Chr( 10 ) // 2005/JUL/19 - E.F. - SoftCR must be removed before convert string to // array. It will be treated by HBEditor. @@ -2992,49 +3027,49 @@ STATIC function Text2Array( cString, nWordWrapCol ) nEOLLen := Len( cEOL ) // __StrTkPtr() needs that string to be tokenized be terminated with a token delimiter - if ! Right( cString, Len( cEOL ) ) == cEOL + IF ! Right( cString, Len( cEOL ) ) == cEOL cString += cEOL //GAD so we don't add a blank line by accident at the end of this. - lTokenized:=.t. - endif + lTokenized := .T. + ENDIF nRetLen := 0 ncSLen := Len( cString ) // If cString starts with EOL delimiters I have to add empty lines since __StrTkPtr // gives back _next_ token and would skip these first EOL delimiters - do while SubStr( cString, nTokPos + 1, nEOLLen ) == cEOL + DO WHILE SubStr( cString, nTokPos + 1, nEOLLen ) == cEOL AAdd( aArray, HBTextLine():New( cLine, .F. ) ) nTokPos += nEOLLen nRetLen += nEOLLen - enddo + ENDDO - do while nRetLen < ncSLen + DO WHILE nRetLen < ncSLen /* TOFIX: Note that __StrToken is not able to cope with delimiters longer than one char */ // Dos - OS/2 - Windows have CRLF as EOL - if nEOLLen > 1 + IF nEOLLen > 1 cLine := StrTran( __StrTkPtr( @cString, @nTokPos, cEOL ), SubStr( cEOL, 2 ), "" ) - else + ELSE cLine := __StrTkPtr( @cString, @nTokPos, cEOL ) - endif + ENDIF nRetLen += Len( cLine ) + nEOLLen - if HB_IsNumeric( nWordWrapCol ) .AND. Len( cLine ) > nWordWrapCol - do while .T. + IF HB_IsNumeric( nWordWrapCol ) .AND. Len( cLine ) > nWordWrapCol + DO WHILE .T. // Split line at nWordWrapCol boundary - if Len( cLine ) > nWordWrapCol + IF Len( cLine ) > nWordWrapCol nFirstSpace := RAt( " ", Left( cLine, nWordWrapCol + 1 ) ) - if nFirstSpace > 1 + IF nFirstSpace > 1 cSplittedLine := Left( cLine, nFirstSpace ) cLine := SubStr( cLine, nFirstSpace + 1 ) - else + ELSE cSplittedLine := Left( cLine, nWordWrapCol ) // 2006/07/19 - E.F. Changed cut point of second split. //cLine := SubStr( cLine, nWordWrapCol + 1 ) - cLine := SubStr( cLine, Len(cSplittedLine) + 1 ) - endif + cLine := SubStr( cLine, Len( cSplittedLine ) + 1 ) + ENDIF AAdd( aArray, HBTextLine():New( cSplittedLine, .T. ) ) - else + ELSE // remainder of line is shorter than split point // 2006/JUL/21 - E.F. Only add a new line if cLine is not empty. // @@ -3042,60 +3077,59 @@ STATIC function Text2Array( cString, nWordWrapCol ) AAdd( aArray, HBTextLine():New( cLine, .F. ) ) ENDIF // Done. - exit - endif + EXIT + ENDIF - enddo - else + ENDDO + ELSE AAdd( aArray, HBTextLine():New( cLine, .F. ) ) - endif + ENDIF - enddo + ENDDO //If string ends with EOL delimeters we have to add it here. - if !lTokenized .AND. right( cString, nEOLLen ) == cEOL + IF !lTokenized .AND. Right( cString, nEOLLen ) == cEOL AAdd( aArray, HBTextLine():New( , .F. ) ) - endif + ENDIF + RETURN aArray -return aArray + //-------------------------------------------------------------------// + // + // if editing isn't allowed we enter this loop which + // handles only movement keys and discards all the others + // -//-------------------------------------------------------------------// -// -// if editing isn't allowed we enter this loop which -// handles only movement keys and discards all the others -// METHOD BrowseText( nPassedKey, lHandleOneKey ) CLASS XHBEditor - LOCAL nKey,bKeyBlock + LOCAL nKey, bKeyBlock + + DEFAULT lHandleOneKey TO .F. - default lHandleOneKey TO .F. - - - do while ! ::lExitEdit + DO WHILE ! ::lExitEdit // If I haven't been called with a key already preset, evaluate this key and then exit - if nPassedKey == NIL + IF nPassedKey == NIL - if NextKey() == 0 + IF NextKey() == 0 ::IdleHook() - endif + ENDIF - nKey := InKey( 0 ) - else + nKey := Inkey( 0 ) + ELSE nKey := nPassedKey - endif + ENDIF - if ( bKeyBlock := Setkey( nKey ) ) != NIL + IF ( bKeyBlock := SetKey( nKey ) ) != NIL Eval( bKeyBlock, ::ProcName, ::ProcLine, "", Self ) - Loop - endif + LOOP + ENDIF // ******* modified to add exit with K_LEFT when in non-edit mode - if nKey == K_ESC .or. nkey == K_CTRL_W + IF nKey == K_ESC .OR. nkey == K_CTRL_W ::lExitEdit := .T. - else + ELSE ::MoveCursor( nKey ) /* 02/09/2004 - If I'm on a readonly editor don't call KeyboardHook() because @@ -3105,15 +3139,15 @@ METHOD BrowseText( nPassedKey, lHandleOneKey ) CLASS XHBEditor oSelf:KeyboardHook( nKey ) endif */ - endif + ENDIF // If I want to handle only one key and then exit... - if lHandleOneKey - exit - endif + IF lHandleOneKey + EXIT + ENDIF - enddo + ENDDO -return nil + RETURN nil //-------------------------------------------------------------------//