/* * $Id$ */ /* * Harbour Project source code: * The Debugger Object Inspector * * Copyright 2001 Luiz Rafael Culik * www - http://www.harbour-project.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). * * As a special exception, the Harbour Project gives permission for * additional uses of the text contained in its release of Harbour. * * The exception is that, if you link the Harbour libraries with other * files to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the Harbour library code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * * This exception applies only to the code released by the Harbour * Project under the name Harbour. If you copy code from other * Harbour Project or Free Software Foundation releases into a copy of * Harbour, as the General Public License permits, the exception does * not apply to the code that you add in this way. To avoid misleading * anyone as to the status of such modified files, you must delete * this exception notice from them. * * If you write modifications of your own for Harbour, it is your choice * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. * */ #include "hbclass.ch" #include "common.ch" #include "inkey.ch" #include "setcurs.ch" CREATE CLASS HBDbObject VAR aWindows INIT {} VAR Theobj VAR objname VAR nCurWindow INIT 0 VAR pItems INIT {} VAR ArrayReference INIT {} VAR ArrayIndex INIT 1 VAR AllNames INIT {} VAR lEditable METHOD New( oObject, cVarName, lEditable ) METHOD addWindows( aArray, nRow ) METHOD doGet( oBrowse, pItem, nSet ) METHOD SetsKeyPressed( nKey, oBrwSets, nSets, aArray ) ENDCLASS METHOD New( oObject, cVarName, lEditable ) CLASS HBDbObject LOCAL aTemp DEFAULT lEditable TO .T. FOR EACH aTemp IN __objGetValueList( oObject ) AAdd( ::pItems, { aTemp[ 1 ], aTemp[ 2 ] } ) AAdd( ::AllNames, aTemp[ 1 ] ) NEXT FOR EACH aTemp IN __objGetMethodList( oObject ) IF !Empty( aTemp ) AAdd( ::pItems, { aTemp, "Method" } ) AAdd( ::AllNames, aTemp ) ENDIF NEXT ::objname := cVarName ::TheObj := oObject ::lEditable := lEditable ::addWindows( ::pItems ) RETURN Self METHOD addWindows( aArray, nRow ) CLASS HBDbObject LOCAL oBrwSets LOCAL nSize := Len( aArray ) LOCAL oWndSets LOCAL nWidth LOCAL oCol LOCAL nMaxLen IF nSize < MaxRow()-2 IF nRow != NIL oWndSets := HBDbWindow():New( nRow, 5, iif( nRow + nSize + 1 < MaxRow() - 2, nRow + nSize + 1, MaxRow() - 2 ), MaxCol() - 5, ::objname + " is of class: " + ::TheObj:ClassName(), "N/W" ) ELSE oWndSets := HBDbWindow():New( 1, 5, 2 + nSize, MaxCol() - 5, ::objname + " is of class: " + ::TheObj:ClassName(), "N/W" ) ENDIF ELSE oWndSets := HBDbWindow():New( 1, 5, MaxRow() - 2, MaxCol() - 5, ::objname + " is of class: " + ::TheObj:ClassName(), "N/W" ) ENDIF ::nCurWindow++ oWndSets:lFocused := .T. AAdd( ::aWindows, oWndSets ) nWidth := oWndSets:nRight - oWndSets:nLeft - 1 oBrwSets := HBDbBrowser():New( oWndSets:nTop + 1, oWndSets:nLeft + 1, oWndSets:nBottom - 1, oWndSets:nRight - 1 ) ::ArrayReference := aArray oBrwSets:ColorSpec := __Dbg():ClrModal() oBrwSets:GoTopBlock := { || ::Arrayindex := 1 } oBrwSets:GoBottomBlock := { || ::arrayindex := Len( ::ArrayReference ) } oBrwSets:SkipBlock := { | nSkip, nPos | nPos := ::arrayindex,; ::arrayindex := iif( nSkip > 0, Min( ::arrayindex + nSkip, Len( ::arrayreference ) ),; Max( 1, ::arrayindex + nSkip ) ), ::arrayindex - nPos } nMaxLen := ArrayMaxLen( ::AllNames ) oBrwSets:AddColumn( oCol := TBColumnNew( "",; { || PadR( ::ArrayReference[ ::arrayindex, 1 ], nMaxLen ) } ) ) oCol:width := nMaxLen oCol:ColorBlock := { || { iif( ::Arrayindex == oBrwSets:Cargo, 2, 1 ), 2 } } oBrwSets:Freeze := 1 oBrwSets:AddColumn( oCol := TBColumnNew( "", { || iif( ISCHARACTER( ::ArrayReference[ ::ArrayIndex, 2 ] ) .AND. ::ArrayReference[ ::ArrayIndex, 2 ] == "Method",; "Method",; PadR( __dbgValToStr( __objSendMsg( ::TheObj, ::ArrayReference[ ::arrayindex, 1 ] ) ), nWidth - 12 ) ) } ) ) oBrwSets:Cargo := 1 // Actual highlighted row oCol:ColorBlock := { || { iif( ::Arrayindex == oBrwSets:Cargo, 3, 1 ), 3 } } oCol:width := MaxCol() - 14 - nMaxLen oBrwSets:colPos := 2 ::aWindows[ ::nCurWindow ]:bPainted := { || oBrwSets:ForceStable() } ::aWindows[ ::nCurWindow ]:bKeyPressed := { | nKey | ::SetsKeyPressed( nKey, oBrwSets, Len( aArray ), ::Arrayreference ) } ::aWindows[ ::nCurwindow ]:cCaption := ::objname + " is of class: " +::TheObj:ClassName() SetCursor( SC_NONE ) ::aWindows[ ::nCurWindow ]:ShowModal() RETURN Self METHOD doGet( oBrowse, pItem, nSet ) CLASS HBDbObject #ifndef HB_NO_READDBG LOCAL column LOCAL nKey LOCAL GetList := {} LOCAL lScoreSave := Set( _SET_SCOREBOARD, .F. ) LOCAL lExitSave := Set( _SET_EXIT, .T. ) LOCAL bInsSave := SetKey( K_INS ) LOCAL cValue // make sure browse is stable oBrowse:forceStable() // if confirming new record, append blank // set insert key to toggle insert mode and cursor SetKey( K_INS, { || SetCursor( iif( ReadInsert( ! ReadInsert() ),; SC_NORMAL, SC_INSERT ) ) } ) // initial cursor setting SetCursor( iif( ReadInsert(), SC_INSERT, SC_NORMAL ) ) // get column object from browse column := oBrowse:getColumn( oBrowse:colPos ) // create a corresponding GET cValue := PadR( __dbgValToStr( pitem[ nSet, 2 ] ), column:Width ) @ Row(), Col() GET cValue ; VALID iif( Type( cValue ) == "UE", ( Alert( "Expression error" ), .F. ), .T. ) READ SetCursor( SC_NONE ) Set( _SET_SCOREBOARD, lScoreSave ) Set( _SET_EXIT, lExitSave ) SetKey( K_INS, bInsSave ) IF LastKey() == K_ENTER __objSendMsg( ::TheObj, "_" + pitem[ nSet, 1 ], &cValue ) ENDIF // check exit key from get nKey := LastKey() IF nKey == K_UP .OR. nKey == K_DOWN .OR. nKey == K_PGUP .OR. nKey == K_PGDN KEYBOARD Chr( nKey ) ENDIF #else HB_SYMBOL_UNUSED( oBrowse ) HB_SYMBOL_UNUSED( pItem ) HB_SYMBOL_UNUSED( nSet ) #endif RETURN NIL METHOD SetsKeyPressed( nKey, oBrwSets, nSets, aArray ) CLASS HBDbObject LOCAL nSet := oBrwSets:Cargo LOCAL cOldname := ::objname DO CASE CASE nKey == K_UP IF oBrwSets:Cargo > 1 oBrwSets:Cargo-- oBrwSets:RefreshCurrent() oBrwSets:Up() oBrwSets:ForceStable() ENDIF CASE nKey == K_DOWN IF oBrwSets:Cargo < nSets oBrwSets:Cargo++ oBrwSets:RefreshCurrent() oBrwSets:Down() oBrwSets:ForceStable() ENDIF CASE nKey == K_HOME .OR. nKey == K_CTRL_PGUP .OR. nKey == K_CTRL_HOME IF oBrwSets:Cargo > 1 oBrwSets:Cargo := 1 oBrwSets:GoTop() oBrwSets:ForceStable() ENDIF CASE nKey == K_END .OR. nKey == K_CTRL_PGDN .OR. nKey == K_CTRL_END IF oBrwSets:Cargo < nSets oBrwSets:Cargo := nSets oBrwSets:GoBottom() oBrwSets:ForceStable() ENDIF CASE nKey == K_PGUP oBrwSets:PageUp() oBrwSets:Cargo := ::ArrayIndex oBrwSets:RefreshCurrent() oBrwSets:ForceStable() CASE nKey == K_PGDN oBrwSets:PageDown() oBrwSets:Cargo := ::ArrayIndex oBrwSets:RefreshCurrent() oBrwSets:ForceStable() CASE nKey == K_ENTER IF nSet == oBrwSets:Cargo IF ISARRAY( aArray[ nSet, 2 ] ) IF Len( aArray[ nSet, 2 ] ) > 0 HBDbArray():New( aArray[ nSet, 2 ], ::pitems[ nSet, 1 ] ) ENDIF ELSEIF ValType( aArray[ nSet, 2 ] ) == "H" IF Len( aArray[ nSet, 2 ] ) > 0 HBDbHash():New( aArray[ nSet, 2 ], ::pitems[ nSet, 1 ] ) ENDIF ELSEIF ISOBJECT( aArray[ nSet, 2 ] ) HBDbObject():New( aArray[ nSet, 2 ], ::pitems[ nSet, 1 ] ) ELSEIF ( ISCHARACTER( aArray[ nSet, 2 ] ) .AND. ; aArray[ nSet, 2 ] == "Method" ) .OR. ; ISBLOCK( aArray[ nSet, 2 ] ) .OR. ; ValType( aArray[ nSet, 2 ] ) == "P" Alert( "Value cannot be edited" ) ELSE IF ::lEditable oBrwSets:RefreshCurrent() ::doGet( oBrwSets, ::arrayreference, nSet ) oBrwSets:RefreshCurrent() oBrwSets:ForceStable() else Alert( "Value cannot be edited" ) ENDIF ENDIF ENDIF ENDCASE RETURN NIL FUNCTION __dbgObject( aArray, cVarName, lEditable ) RETURN HBDbObject():New( aArray, cVarName, lEditable ) STATIC FUNCTION ArrayMaxLen( aArray ) LOCAL nMaxLen := 0 LOCAL nLen LOCAL cItem FOR EACH cItem IN aArray nLen := Len( cItem ) IF nMaxLen < nLen nMaxLen := nLen ENDIF NEXT RETURN nMaxLen