diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 63384e7045..df0ce58d9e 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,18 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-06-19 19:32 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + * harbour/contrib/hbxbp/hbxbp.hbc + * harbour/contrib/hbxbp/Makefile + * harbour/contrib/hbxbp/xbpdataref.prg + * harbour/contrib/hbxbp/xbpgeneric.prg + + harbour/contrib/hbxbp/xbpsle.prg + * harbour/contrib/hbxbp/xbpwindow.prg + * harbour/contrib/hbxbp/tests/demoxbp.prg + + Implemented XbpSLE() class. This implementation is almost + 95% identical to Xbase++. One or two features remain to be implemented. + Please test and report back the differences. + 2009-06-19 19:23 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * harbour/contrib/hbqt/generator/qt45.qtp * harbour/contrib/hbqt/hbqt.ch diff --git a/harbour/contrib/hbxbp/Makefile b/harbour/contrib/hbxbp/Makefile index a41dc7c6ec..fa3cd2700a 100644 --- a/harbour/contrib/hbxbp/Makefile +++ b/harbour/contrib/hbxbp/Makefile @@ -55,6 +55,7 @@ PRG_SOURCES=\ xbplistbox.prg \ xbpstatusbar.prg \ xbpscrollbar.prg \ + xbpsle.prg \ PRG_HEADERS=\ xbp.ch \ diff --git a/harbour/contrib/hbxbp/hbxbp.hbc b/harbour/contrib/hbxbp/hbxbp.hbc index 86f5307c13..49e8790e1d 100644 --- a/harbour/contrib/hbxbp/hbxbp.hbc +++ b/harbour/contrib/hbxbp/hbxbp.hbc @@ -4,5 +4,5 @@ incpaths=. -libs=hbxbp +libs=hbxbp hbwin libs=../hbqt/hbqt.hbc diff --git a/harbour/contrib/hbxbp/tests/demoxbp.prg b/harbour/contrib/hbxbp/tests/demoxbp.prg index 1aa4a10423..41eca8e599 100644 --- a/harbour/contrib/hbxbp/tests/demoxbp.prg +++ b/harbour/contrib/hbxbp/tests/demoxbp.prg @@ -81,7 +81,7 @@ FUNCTION BuildADialog() ( aSize[ 2 ] - oDlg:currentSize()[ 2 ] ) / 2 } ) /* Make background color of :drawingArea different */ - oDlg:drawingArea:setColorBG( GraMakeRGBColor( { 134,128,164 } ) ) + //oDlg:drawingArea:setColorBG( GraMakeRGBColor( { 134,128,164 } ) ) /* Install menu system */ Build_MenuBar() @@ -110,6 +110,9 @@ FUNCTION BuildADialog() /* Install Push Buttons */ Build_PushButton( oDlg:drawingArea ) + /* Install Single Line Edits */ + Build_SLEs( oDlg:drawingArea ) + /* Install ScrollBar */ Build_ScrollBar( aTabs[ 1 ] ) @@ -430,13 +433,10 @@ FUNCTION Build_ListBox( oWnd ) aeval( aItems, {|e| oListBox:addItem( e ) } ) // Code block for list box selection: - // The selected fields from the DbStruct() - // array are displayed using QOut() oListBox:ItemSelected := {|mp1, mp2, obj| mp1:=oListBox:getData(), ; mp2:=oListBox:getItem(mp1), MsgBox( "itemSelected:"+mp2 ) } - //oListBox:ItemMarked := {|mp1, mp2, obj| MsgBox( "itemMarked" ) } - /* DOES NOT Work */ + /* DOES NOT Work in Harbour Xbase++ == OK */ oListBox:setColorBG( GraMakeRGBColor( {127,12,210} ) ) RETURN nil @@ -480,3 +480,30 @@ FUNCTION Build_ScrollBar( oWnd ) /*----------------------------------------------------------------------*/ +FUNCTION Build_SLEs( oWnd ) + LOCAL oXbp + LOCAL cVarA := "Test A", cVarB := "Test B" + + // Create second SLE, specify position using :new() + oXbp := XbpSLE():new( oWnd, , {30,150}, {100,30} ) + oXbp:tabStop := .T. + oXbp:bufferLength := 15 + oXbp:dataLink := {|x| IIf( x==NIL, cVarA, cVarA := x ) } + oXbp:create() + oXbp:setData() + oXbp:setInputFocus := { |x,y,oSLE| oSLE:getData(), Qt_QDebug( "Var A =" + cVarA ) } + + oXbp := XbpSLE():new() + oXbp:autoTab := .T. + oXbp:bufferLength := 20 + // Data code block containing assignment to LOCAL variable + oXbp:dataLink := {|x| IIf( x==NIL, cVarB, cVarB := x ) } + oXbp:create( oWnd, , {30,200}, {100,30} ) + oXbp:setData() + // Assign the value of the edit buffer to a LOCAL variable + // when the input focus is lost + oXbp:killInputFocus := { |x,y,oSLE| oSLE:getData(), MsgBox( "Var B =" + cVarB ) } + + RETURN nil + +/*----------------------------------------------------------------------*/ diff --git a/harbour/contrib/hbxbp/xbpdataref.prg b/harbour/contrib/hbxbp/xbpdataref.prg index 83f943f7a6..561c39e93b 100644 --- a/harbour/contrib/hbxbp/xbpdataref.prg +++ b/harbour/contrib/hbxbp/xbpdataref.prg @@ -112,8 +112,8 @@ METHOD XbpDataRef:getData() LOCAL cClass := __ObjGetClsName( self ) DO CASE - CASE cClass $ "XBPSLE,XBPMLE" //::className == "EDIT" - //::sl_editBuffer := Win_GetMessageText( ::hWnd, WM_GETTEXT, ::bufferLength + 1 ) + CASE cClass $ "XBPSLE,XBPMLE" + ::sl_editBuffer := ::oWidget:text() CASE cClass == "XBPRADIOBUTTON" ::sl_editBuffer := ::oWidget:isChecked() @@ -167,7 +167,7 @@ METHOD XbpDataRef:setData( xValue, mp2 ) CASE cClass $ "XBPSLE,XBPMLE" IF hb_isChar( ::sl_editBuffer ) - //Win_SendMessageText( ::hWnd, WM_SETTEXT, 0, ::sl_editBuffer ) + ::oWidget:setText( ::sl_editBuffer ) ENDIF CASE ::className == "XBPSCROLLBAR" diff --git a/harbour/contrib/hbxbp/xbpgeneric.prg b/harbour/contrib/hbxbp/xbpgeneric.prg index 911999ea2b..a73a4d522b 100644 --- a/harbour/contrib/hbxbp/xbpgeneric.prg +++ b/harbour/contrib/hbxbp/xbpgeneric.prg @@ -252,3 +252,18 @@ FUNCTION Xbp_XtoS( xVar ) /*----------------------------------------------------------------------*/ +FUNCTION SetEventFilter() + LOCAL pEventFilter + + STATIC sEventFilter + + IF empty( sEventFilter ) + pEventFilter := QT_QEventFilter() + IF hb_isPointer( pEventFilter ) + sEventFilter := pEventFilter + ENDIF + ENDIF + + RETURN sEventFilter + +/*----------------------------------------------------------------------*/ diff --git a/harbour/contrib/hbxbp/xbpsle.prg b/harbour/contrib/hbxbp/xbpsle.prg new file mode 100644 index 0000000000..fa9e2e8743 --- /dev/null +++ b/harbour/contrib/hbxbp/xbpsle.prg @@ -0,0 +1,237 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Source file for the Xbp*Classes + * + * Copyright 2009 Pritpal Bedi + * 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. + * + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/* + * EkOnkar + * ( The LORD is ONE ) + * + * Xbase++ xbpSLE compatible Class + * + * Pritpal Bedi + * 17Jun2009 + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ + +#include "hbclass.ch" +#include "common.ch" + +#include "xbp.ch" +#include "appevent.ch" +#include "apig.ch" +#include "hbqt.ch" + +/*----------------------------------------------------------------------*/ + +CLASS XbpSLE INHERIT XbpWindow, XbpDataRef + + DATA align INIT XBPSLE_LEFT + DATA autoKeyboard INIT .T. + DATA autoSize INIT .F. + DATA autoTab INIT .F. + DATA border INIT .T. + DATA bufferLength INIT 32 + DATA editable INIT .T. + DATA unReadable INIT .F. + + DATA changed INIT .F. + + METHOD new() + METHOD create() + METHOD configure() VIRTUAL + METHOD destroy() + METHOD handleEvent() + METHOD exeBlock() + + METHOD clear() INLINE ::oWidget:clear() + METHOD copyMarked() INLINE ::oWidget:copy() + METHOD cutMarked() INLINE ::oWidget:cut() + METHOD delMarked() INLINE ::oWidget:del() + METHOD editBuffer() INLINE ::oWidget:text() + METHOD pasteMarked() INLINE ::oWidget:paste() + METHOD queryFirstChar() VIRTUAL + METHOD queryMarked() INLINE { ::oWidget:selectionStart(), ::oWidget:selectionEnd() } + METHOD setFirstChar( nPos ) VIRTUAL + METHOD setMarked( aStartEnd ) INLINE ::setSelection( aStartEnd[ 1 ], aStartEnd[ 2 ] ) + + METHOD setInsertMode( lInsertMode ) VIRTUAL + + DATA sl_hScroll + ACCESS hScroll INLINE ::sl_hScroll + ASSIGN hScroll( bBlock ) INLINE ::sl_hScroll := bBlock + + DATA sl_typeOut + ACCESS typeOut INLINE ::sl_typeOut + ASSIGN typeOut( bBlock ) INLINE ::sl_typeOut := bBlock + + ENDCLASS + +/*----------------------------------------------------------------------*/ + +METHOD XbpSLE:new( oParent, oOwner, aPos, aSize, aPresParams, lVisible ) + + ::Initialize( oParent, oOwner, aPos, aSize, aPresParams, lVisible ) + + ::className := "XBPSLE" + ::objType := objTypeSLE + + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD XbpSLE:create( oParent, oOwner, aPos, aSize, aPresParams, lVisible ) + LOCAL es_:= { Qt_AlignLeft, Qt_AlignRight, Qt_AlignHCenter } + + ::xbpWindow:create( oParent, oOwner, aPos, aSize, aPresParams, lVisible ) + + ::oWidget := QLineEdit():new( ::pParent ) + + ::oWidget:setAlignment( es_[ ::align ] ) + IF !::editable + ::oWidget:setReadOnly( .t. ) + ENDIF + + IF ::unReadable + ::oWidget:setEchoMode( QLineEdit_Password ) + ENDIF + + ::oWidget:setFrame( ::border ) + ::oWidget:setMaxLength( ::bufferLength ) + + QT_QObject_InstallEventFilter( ::pWidget, SetEventFilter() ) + + ::connectEvent( ::pWidget, QEvent_FocusIn , {|o,e| ::exeBlock( 7, e, o ) } ) + ::connectEvent( ::pWidget, QEvent_FocusOut, {|o,e| ::exeBlock( 8, e, o ) } ) + + ::connect( ::pWidget, "cursorPositionChanged(int,int)" , {|o,i,ii| ::exeBlock( 1, i, ii, o ) } ) + //::connect( ::pWidget, "editingFinished()" , {| | ::exeBlock( 2 ) } ) + //::connect( ::pWidget, "returnPressed()" , {| | ::exeBlock( 3 ) } ) + //::connect( ::pWidget, "selectionChanged()" , {| | ::exeBlock( 4 ) } ) + ::connect( ::pWidget, "textChanged(QString)" , {|o,s | ::exeBlock( 5, s, o ) } ) + ::connect( ::pWidget, "textEdited(QString)" , {|o,s | ::exeBlock( 6, s, o ) } ) + + ::setPosAndSize() + IF ::visible + ::show() + ENDIF + + IF hb_isBlock( ::datalink ) + eval( ::datalink ) + ENDIF + + ::oParent:addChild( Self ) + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD XbpSLE:exeBlock( nMsg, p1, p2 ) + + HB_SYMBOL_UNUSED( p1 ) + + DO CASE + CASE nMsg == 1 // "cursorPositionChanged(int,int)" + IF hb_isBlock( ::sl_hScroll ) + eval( ::sl_hScroll, NIL, NIL, self ) + ENDIF + IF p2 == ::bufferLength + IF hb_isBlock( ::sl_typeOut ) + eval( ::sl_typeOut, NIL, NIL, Self ) + ENDIF + ENDIF + + CASE nMsg == 2 // "editingFinished()" + + CASE nMsg == 3 // "returnPressed()" + ::sl_editBuffer := ::oWidget:text() + + CASE nMsg == 4 // "selectionChanged()" + + CASE nMsg == 5 // "textEdited(QString)" + ::changed := .t. + + CASE nMsg == 6 // "textEdited(QString)" + ::changed := .t. + + CASE nMsg == 7 // QEvent_FocusIn + IF hb_isBlock( ::sl_setInputFocus ) + eval( ::sl_setInputFocus, NIL, NIL, Self ) + ENDIF + + CASE nMsg == 8 // QEvent_FocusOut + IF hb_isBlock( ::sl_killInputFocus ) + eval( ::sl_killInputFocus, NIL, NIL, Self ) + ENDIF + + ENDCASE + + RETURN .t. + +/*----------------------------------------------------------------------*/ + +METHOD XbpSLE:handleEvent( nEvent, mp1, mp2 ) + + HB_SYMBOL_UNUSED( nEvent ) + HB_SYMBOL_UNUSED( mp1 ) + HB_SYMBOL_UNUSED( mp2 ) + + RETURN EVENT_UNHANDELLED + +/*----------------------------------------------------------------------*/ + +METHOD XbpSLE:destroy() + ::xbpWindow:destroy() + RETURN NIL + +/*----------------------------------------------------------------------*/ diff --git a/harbour/contrib/hbxbp/xbpwindow.prg b/harbour/contrib/hbxbp/xbpwindow.prg index 3167a415ff..f7ddaff061 100644 --- a/harbour/contrib/hbxbp/xbpwindow.prg +++ b/harbour/contrib/hbxbp/xbpwindow.prg @@ -291,7 +291,9 @@ EXPORTED: DATA xDummy METHOD connect() + METHOD connectEvent() DATA aConnections INIT {} + DATA aEConnections INIT {} ENDCLASS @@ -356,12 +358,24 @@ METHOD XbpWindow:configure( oParent, oOwner, aPos, aSize, aPresParams, lVisible /*----------------------------------------------------------------------*/ METHOD XbpWindow:connect( pWidget, cSignal, bBlock ) + LOCAL lSuccess - IF Qt_Connect_Signal( pWidget, cSignal, bBlock ) + IF ( lSuccess := Qt_Connect_Signal( pWidget, cSignal, bBlock ) ) aadd( ::aConnections, { pWidget, cSignal } ) ENDIF - RETURN Self + RETURN lSuccess + +/*----------------------------------------------------------------------*/ + +METHOD XbpWindow:connectEvent( pWidget, nEvent, bBlock ) + LOCAL lSuccess + + IF ( lSuccess := Qt_Connect_Event( pWidget, nEvent, bBlock ) ) + aadd( ::aEConnections, { pWidget, nEvent } ) + ENDIF + + RETURN lSuccess /*----------------------------------------------------------------------*/ @@ -372,6 +386,11 @@ METHOD XbpWindow:destroy() ::aConnections := {} ENDIF + IF len( ::aEConnections ) > 0 + aeval( ::aEConnections, {|e_| Qt_DisConnect_Event( e_[ 1 ], e_[ 2 ] ) } ) + ::aConnections := {} + ENDIF + IF Len( ::aChildren ) > 0 aeval( ::aChildren, {|o| o:destroy() } ) ::aChildren := {}