2009-07-14 13:50 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com)

* contrib/hbxbp/xbpdialog.prg
  * contrib/hbxbp/xbpgeneric.prg
    ! Changed the way AppEvent() eventloop was being executed.
      Not it is more near to Xbase++, not 100% but near. 
      CPU consumption is reduced to 2-3 percent.

  * contrib/hbxbp/xbprtf.prg
    + Implemented more XbpRTF() features.

  * contrib/hbxbp/tests/demoxbp.prg
    + Demonstrated more XbpRtf() features. 
      Play with Rtf tab.
This commit is contained in:
Pritpal Bedi
2009-07-14 21:02:52 +00:00
parent 79e770afe3
commit 933a678c12
5 changed files with 195 additions and 98 deletions

View File

@@ -17,6 +17,20 @@
past entries belonging to author(s): Viktor Szakats.
*/
2009-07-14 13:50 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com)
* contrib/hbxbp/xbpdialog.prg
* contrib/hbxbp/xbpgeneric.prg
! Changed the way AppEvent() eventloop was being executed.
Not it is more near to Xbase++, not 100% but near.
CPU consumption is reduced to 2-3 percent.
* contrib/hbxbp/xbprtf.prg
+ Implemented more XbpRTF() features.
* contrib/hbxbp/tests/demoxbp.prg
+ Demonstrated more XbpRtf() features.
Play with Rtf tab.
2009-07-14 22:42 UTC+0200 Viktor Szakats (harbour.01 syenar.hu)
* config/hpux/gcc.cf
* config/darwin/gcc.cf

View File

@@ -86,8 +86,8 @@ PROCEDURE Main()
PROCEDURE BuildADialog()
LOCAL oDlg, mp1, mp2, oXbp, nEvent, aSize, aTabs, oDa
LOCAL nThread := ThreadID()
LOCAL cThread := hb_ntos( nThread )
LOCAL aPP, oHtm
//LOCAL cThread := hb_ntos( nThread )
LOCAL oHtm
/* Create Application Window */
oDlg := GuiStdDialog( "Harbour - Xbase++ - QT Dialog [ "+ hb_ntos( nThread )+" ]" )
@@ -172,13 +172,15 @@ PROCEDURE BuildADialog()
/* Enter Xbase++ Event Loop - working */
DO WHILE .t.
nEvent := AppEvent( @mp1, @mp2, @oXbp )
IF ( nEvent == xbeP_Close ) .OR. ( nEvent == xbeP_Keyboard .and. mp1 == xbeK_ESC )
hb_outDebug( " WOW " )
hb_outdebug( " WOW " )
EXIT
ELSEIF nEvent == xbeP_Keyboard .and. mp1 == xbeK_F1
oHtm:setHTML( '<html><h1>Direct HTML Injection</h1><p><font color="#ab00ff" size="16">'+;
'This HTML content</font> is pushed dynamically with<br><br>:setHTML()</br></br>.</html>' )
ENDIF
oXbp:handleEvent( nEvent, mp1, mp2 )
ENDDO
@@ -326,7 +328,7 @@ STATIC FUNCTION Build_MenuBar( oDlg )
oSubMenu:setColorFG( GraMakeRGBColor( { 255, 1, 1 } ) )
#ifdef __HARBOUR__
#if 0
#if 1
oSubMenu := XbpMenu():new( oMenuBar ):create()
oSubMenu:title := "~Dialogs"
#if 1 /* T H R E D E D D I A L O G */
@@ -903,7 +905,7 @@ PROCEDURE FieldStruct( oItem, aField )
/*----------------------------------------------------------------------*/
FUNCTION Build_Statics( oWnd )
LOCAL oGrp,oLbl, oLin, oBox, oBmp, oBmp1
LOCAL oGrp,oLbl, oLin, oBox, oBmp
LOCAL nC1 := 10, nC2 := 45, nC3 := 110, nC4 := 175
LOCAL nW := 50, nH := 50, nG := 10
LOCAL nT := 60
@@ -1115,23 +1117,7 @@ FUNCTION Build_Bitmap( oWnd )
LOCAL nFrmts := { XBPBMP_FORMAT_PNG, XBPBMP_FORMAT_GIF, XBPBMP_FORMAT_JPG, ;
XBPBMP_FORMAT_JPG, XBPBMP_FORMAT_WIN3X }
aFltr := {}
aadd( aFltr, { "Windows Bitmap ", "*.bmp" } )
aadd( aFltr, { "Graphic Interchange Format ", "*.gif" } )
aadd( aFltr, { "Joint Photographic Experts ", "*.jpg; *.jpeg" } )
aadd( aFltr, { "Portable Network Graphics ", "*.png" } )
aadd( aFltr, { "Portable Pixmap ", "*.ppm" } )
aadd( aFltr, { "Tagged Image File Format ", "*.tiff" } )
aadd( aFltr, { "X11 Bitmap ", "*.xbm" } )
aadd( aFltr, { "X11 Pixmap ", "*.xpm" } )
aeval( aFltr, {|e_,i| aFltr[ i,1 ] := trim( e_[ 1 ] ) } )
oDlg := XbpFileDialog():new( oWnd, , {10,10} )
oDlg:title := "Select an image to be converted"
oDlg:fileFilters := aFltr
oDlg:create()
cFile := oDlg:open( hb_DirBase(), , .f. )
cFile := GetAnImageFile( oWnd, "Select an image to be converted" )
IF !empty( cFile )
oBmp := XbpBitmap():new():create()
@@ -1166,6 +1152,30 @@ FUNCTION Build_Bitmap( oWnd )
/*----------------------------------------------------------------------*/
FUNCTION GetAnImageFile( oWnd, cTitle )
LOCAL aFltr := {}
DEFAULT cTitle TO "Select an Image"
aadd( aFltr, { "Portable Network Graphics ", "*.png" } )
aadd( aFltr, { "Windows Bitmap ", "*.bmp" } )
aadd( aFltr, { "Graphic Interchange Format ", "*.gif" } )
aadd( aFltr, { "Joint Photographic Experts ", "*.jpg; *.jpeg" } )
aadd( aFltr, { "Portable Pixmap ", "*.ppm" } )
aadd( aFltr, { "Tagged Image File Format ", "*.tiff" } )
aadd( aFltr, { "X11 Bitmap ", "*.xbm" } )
aadd( aFltr, { "X11 Pixmap ", "*.xpm" } )
aeval( aFltr, {|e_,i| aFltr[ i,1 ] := trim( e_[ 1 ] ) } )
oDlg := XbpFileDialog():new( oWnd, , {10,10} )
oDlg:title := cTitle
oDlg:fileFilters := aFltr
oDlg:create()
RETURN oDlg:open( hb_DirBase(), , .f. )
/*----------------------------------------------------------------------*/
FUNCTION Build_FontDialog( oWnd )
LOCAL oDlg
@@ -1222,42 +1232,63 @@ FUNCTION Build_PrintDialog( oWnd )
FUNCTION Build_Rtf( oWnd )
LOCAL oRTF, oBtn
LOCAL sz_:= oWnd:currentSize()
LOCAL nW := 50, nG := 8, nH := 20, nT := sz_[2]-55
oBtn := XbpPushButton():new( oWnd, , {10,sz_[2]-70}, {50,35} )
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*0, nT}, {nW,nH} )
oBtn:caption := 'Image'
oBtn:create()
oBtn:activate := {|| RtfInsertImage( oRtf ) }
oBtn := XbpPushButton():new( oWnd, , {10+60,sz_[2]-70}, {50,35} )
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*1, nT}, {nW,nH} )
oBtn:caption := 'Undo'
oBtn:create()
oBtn:activate := {|| oRtf:undo() }
oBtn := XbpPushButton():new( oWnd, , {10+120,sz_[2]-70}, {50,35} )
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*2, nT}, {nW,nH} )
oBtn:caption := 'Redo'
oBtn:create()
#ifdef __HARBOUR__
oBtn:activate := {|| oRtf:redo() }
#endif
oBtn := XbpPushButton():new( oWnd, , {10+180,sz_[2]-70}, {50,35} )
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*3, nT}, {nW,nH} )
oBtn:caption := 'ULine'
oBtn:create()
oBtn:activate := {|| oRtf:selUnderline := .t. }
oBtn := XbpPushButton():new( oWnd, , {10+240,sz_[2]-70}, {50,35} )
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*4, nT}, {nW,nH} )
oBtn:caption := 'Bold'
oBtn:create()
oBtn:activate := {|| oRtf:selBold := .t. }
oBtn := XbpPushButton():new( oWnd, , {10+295,sz_[2]-70}, {45,35} )
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*5, nT}, {nW,nH} )
oBtn:caption := 'Italic'
oBtn:create()
oBtn:activate := {|| oRtf:selItalic := .t. }
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*0, nT-25}, {nW,nH} )
oBtn:caption := 'Load'
oBtn:create()
oBtn:activate := {|| RtfLoadDocument( oRtf ) }
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*1, nT-25}, {nW,nH} )
oBtn:caption := 'Save'
oBtn:create()
oBtn:activate := {|| RtfSaveDocument( oRtf ) }
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*2, nT-25}, {nW,nH} )
oBtn:caption := 'Font++'
oBtn:create()
oBtn:activate := {|x| x := oRTF:selFontSize, IF( x == 0, x := 11, ), oRTF:selFontSize := x+1 }
oBtn := XbpPushButton():new( oWnd, , {10+(nW+nG)*3, nT-25}, {nW,nH} )
oBtn:caption := 'Font--'
oBtn:create()
oBtn:activate := {|x| x := oRTF:selFontSize, IF( x == 0, x := 11, ), oRTF:selFontSize := x-1 }
//------------------------//
oRTF := XbpRtf():new( oWnd )
oRTF:create( , , { 10,10 }, { sz_[ 1 ]-23, sz_[ 2 ]-90 } )
oRTF:create( , , { 10,10 }, { sz_[ 1 ]-23, sz_[ 2 ]-100 } )
oRTF:setColorBG( GraMakeRGBColor( {255,255,200} ) )
oRTF:setFontCompoundName( "12.Times" )
@@ -1296,24 +1327,72 @@ FUNCTION Build_Rtf( oWnd )
oRTF:SelItalic := .T.
// oRTF:SelStrikeThru := .T. /* OK */
oRTF:SelUnderline := .T.
oRTF:selAlignment := 2 //XBPRTF_SELALIGN_RIGHT
oRTF:selAlignment := XBPRTF_ALIGN_CENTER
// Reset the text cursor
//
oRTF:SelStart := Len( oRTF:Text )
oRTF:insertImage( 'copy.png' )
RETURN nil
/*----------------------------------------------------------------------*/
STATIC FUNCTION RtfInsertImage( oRtf )
#ifdef __HARBOUR__
LOCAL cFile
// Proivide a selection dialog
oRtf:insertImage( "abs3.png" )
cFile := GetAnImageFile( oRtf, 'Select Image to be Inserted' )
IF empty( cFile )
oRtf:insertImage( "abs3.png" )
ELSE
oRtf:insertImage( cFile )
ENDIF
#endif
RETURN nil
/*----------------------------------------------------------------------*/
STATIC FUNCTION RtfLoadDocument( oRTF )
LOCAL oDlg, cFile, aFiltr := {}
aadd( aFiltr, { "All Files", "*.*" } )
aadd( aFiltr, { "Text File", "*.txt" } )
aadd( aFiltr, { "RTF File" , "*.htm; *.html" } )
oDlg := XbpFileDialog():new():create( oRTF, , { 10,10 } )
oDlg:title := "Open an RTF Document"
oDlg:center := .t.
oDlg:fileFilters := aFiltr
oDlg:setColorBG( GraMakeRGBColor( { 255,255,200 } ) )
cFile := oDlg:open()
IF !empty( cFile )
oRTF:loadFile( cFile )
ENDIF
RETURN nil
/*----------------------------------------------------------------------*/
STATIC FUNCTION RtfSaveDocument( oRTF )
LOCAL oDlg, cFile, aFiltr := {}
aadd( aFiltr, { "RTF File" , "*.htm; *.html" } )
aadd( aFiltr, { "Text File", "*.txt" } )
oDlg := XbpFileDialog():new():create( oRTF, , { 10,10 } )
oDlg:title := "Open an RTF Document"
oDlg:center := .t.
oDlg:fileFilters := aFiltr
oDlg:setColorBG( GraMakeRGBColor( { 255,200,200 } ) )
cFile := oDlg:saveAs()
IF !empty( cFile )
oRTF:saveFile( cFile )
ENDIF
RETURN nil
/*----------------------------------------------------------------------*/

View File

@@ -146,6 +146,9 @@ METHOD XbpDialog:create( oParent, oOwner, aPos, aSize, aPresParams, lVisible )
SetAppWindow( Self )
/* Thread specific event buffer */
InitializeEventBuffer()
/* Install Event Loop per Dialog Basis */
/* Limitng */
::oEventLoop := QEventLoop():new( ::pWidget )

View File

@@ -80,10 +80,11 @@
STATIC ts_mutex
STATIC oApp
STATIC aEventLoop := {}
STATIC ts_events
//THREAD STATIC ts_events
THREAD STATIC aEventLoop := {}
//STATIC ts_events
THREAD STATIC ts_events
THREAD STATIC nEventIn := 0
THREAD STATIC nEventOut := 0
@@ -97,80 +98,82 @@ THREAD STATIC oEventLoop
/*----------------------------------------------------------------------*/
INIT PROCEDURE Qt_Start()
ts_mutex := hb_mutexCreate()
oDummy := XbpObject():new()
qt_qapplication()
oApp := QApplication():new()
RETURN
/*----------------------------------------------------------------------*/
EXIT PROCEDURE Qt_End()
qt_qapplication_quit()
RETURN
/*----------------------------------------------------------------------*/
/*
* Will be called from XbpDialog() | XbpCRT()
*/
FUNCTION InitializeEventBuffer()
IF empty( ts_events )
ts_events := array( EVENT_BUFFER )
aeval( ts_events, {|e,i| e := e, ts_events[ i ] := { 0, NIL, NIL, NIL, -9999 } } )
ENDIF
//xbp_debug( len( ts_events ) )
RETURN nil
/*----------------------------------------------------------------------*/
/*
* Internal to the XbpParts , Must NOT be called from Application Code
*/
FUNCTION SetAppEvent( nEvent, mp1, mp2, oXbp )
//hb_mutexLock( ts_mutex )
IF ++nEventIn > EVENT_BUFFER
nEventIn := 1
ENDIF
ts_events[ nEventIn ] := { nEvent, mp1, mp2, oXbp, ThreadID() }
//xbp_debug( "SetAppEvent ... ", threadID(), nEventIn )
//hb_mutexUnLock( ts_mutex )
ts_events[ nEventIn,1 ] := nEvent
ts_events[ nEventIn,2 ] := mp1
ts_events[ nEventIn,3 ] := mp2
ts_events[ nEventIn,4 ] := oXbp
ts_events[ nEventIn,5 ] := ThreadID()
RETURN nil
/*----------------------------------------------------------------------*/
FUNCTION AppEvent( mp1, mp2, oXbp )
LOCAL nEvent, n
FUNCTION AppEvent( mp1, mp2, oXbp, nTimeout )
LOCAL nEvent //, n
//hb_idleSleep( 0.1 ) /* May be we need QT based mechanism */
#if 0
//hb_mutexLock( ts_mutex )
oApp:processEvents()
//hb_mutexUnLock( ts_mutex )
#else
/* Event Loop - Can be one per Application */
//oAppWindow:oEventLoop:processEvents()
//hb_mutexLock( ts_mutex )
IF( n := ascan( aEventLoop, {|e_| e_[ 2 ] == threadID() } ) ) > 0
//hb_outDebug( "<<<<<<<<<<<< "+hb_ntos( threadID() ) )
aEventLoop[ n,1 ]:processEvents()
//hb_outDebug( ">>>>>>>>>>>>.... "+hb_ntos( threadID() ) )
ENDIF
//hb_mutexUnLock( ts_mutex )
#endif
//hb_mutexLock( ts_mutex )
DEFAULT nTimeout TO 0
IF ++nEventOut > EVENT_BUFFER
nEventOut := 1
ENDIF
//xbp_debug( " AppEvent ... ", threadID(), nEventOut )
DO WHILE .t.
aEventLoop[ 1,1 ]:processEvents_1( 0, 200 )
IF empty( ts_events[ nEventOut ] ) .OR. ts_events[ nEventOut,5 ] <> ThreadID()
//nEventOut-- /* Stay back and ensure that no event is missed */
nEvent := 0
mp1 := NIL
mp2 := NIL
oXbp := oDummy
ELSE
//hb_outDebug( str( threadID() )+' '+ str( ts_events[ nEventOut,5 ] ) )
nEvent := ts_events[ nEventOut,1 ]
mp1 := ts_events[ nEventOut,2 ]
mp2 := ts_events[ nEventOut,3 ]
oXbp := ts_events[ nEventOut,4 ]
ts_events[ nEventOut ] := NIL
ENDIF
IF ts_events[ nEventOut,5 ] == ThreadID()
nEvent := ts_events[ nEventOut,1 ]
mp1 := ts_events[ nEventOut,2 ]
mp2 := ts_events[ nEventOut,3 ]
oXbp := ts_events[ nEventOut,4 ]
ts_events[ nEventOut,5 ] := -9999 /* an arbirary value never reached by ThreadID() */
EXIT
ENDIF
hb_idleSleep( 0.01 ) /* Releases CPU cycles */
ENDDO
//( "..........................", threadID() )
//hb_mutexUnLock( ts_mutex )
RETURN nEvent
/*----------------------------------------------------------------------*/
@@ -180,16 +183,6 @@ FUNCTION SetAppWindow( oXbp )
//hb_outDebug( str( threadId() )+' 0' )
IF empty( ts_mutex )
ts_mutex := hb_mutexCreate()
ENDIF
IF empty( ts_events )
ts_events := array( EVENT_BUFFER )
ENDIF
IF empty( oDummy )
oDummy := XbpObject():new()
ENDIF
oldAppWindow := oAppWindow
IF hb_isObject( oXbp )
@@ -286,11 +279,11 @@ FUNCTION SetEventFilter()
FUNCTION AddEventLoop( oEventLoop )
hb_mutexLock( ts_mutex )
//hb_mutexLock( ts_mutex )
aadd( aEventLoop, { oEventLoop, threadID() } )
hb_mutexUnLock( ts_mutex )
//hb_mutexUnLock( ts_mutex )
RETURN nil

View File

@@ -208,6 +208,8 @@ METHOD XbpRtf:exeBlock( nEvent, p1 )
::changed := .t. // .f. only at save
::change()
CASE nEvent == 7 /* Xbase++ Implements */
::oTextCursor:configure( ::oWidget:textCursor() )
::oCurCursor := ::oTextCursor
::selChange()
ENDCASE
@@ -230,7 +232,9 @@ METHOD XbpRtf:destroy()
METHOD XbpRtf:loadFile( cFile )
HB_SYMBOL_UNUSED( cFile )
IF file( cFile )
::oWidget:setText( memoread( cFile ) )
ENDIF
RETURN Self
@@ -238,7 +242,11 @@ METHOD XbpRtf:loadFile( cFile )
METHOD XbpRtf:saveFile( cFile )
HB_SYMBOL_UNUSED( cFile )
IF ( '.txt' $ lower( cFile ) )
memowrit( cFile, ::oWidget:toPlainText() )
ELSE
memowrit( cFile, ::oWidget:toHTML() )
ENDIF
RETURN Self
@@ -277,8 +285,8 @@ METHOD XbpRtf:find( cSearchString, nStart, nEnd, nOptions )
IF hb_isChar( cSearchString )
::oTextDocument:pPtr := ::oWidget:document()
::oTextCursor:pPtr := ::oTextDocument:find_2( cSearchString )
::oCurCursor := ::oTextCursor
::oTextCursor:pPtr := ::oTextDocument:find_2( cSearchString )
::oCurCursor := ::oTextCursor
ENDIF
RETURN nPos
@@ -483,10 +491,10 @@ METHOD XbpRtf:selFontSize( ... ) // 0
LOCAL xRet := 0
LOCAL aP := hb_aParams()
IF len( aP ) >= 1 .and. hb_isNumeric( aP[ 1 ] )
::oTextCharFormat:pPtr := ::oCurCursor:charFormat()
IF ::oTextCharFormat:isValid()
xRet := ::oTextCharFormat:fontPointSize()
::oTextCharFormat:pPtr := ::oCurCursor:charFormat()
IF ::oTextCharFormat:isValid()
xRet := ::oTextCharFormat:fontPointSize()
IF len( aP ) >= 1 .and. hb_isNumeric( aP[ 1 ] )
::oTextCharFormat:setFontPointSize( aP[ 1 ] )
::oCurCursor:setCharFormat( QT_PTROF( ::oTextCharFormat ) )
ENDIF