From 0d8e65daf17670d976f6a1c9bee9df2dec6a3dae Mon Sep 17 00:00:00 2001 From: Pritpal Bedi Date: Mon, 23 Nov 2009 00:11:34 +0000 Subject: [PATCH] 2009-11-22 15:45 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbide/hbide.hbm ! Call hbmk2 hbid.hbm which includes all required files. + contrib/hbide/idestylesheets.prg + Added to implement Qt's powerful feature to apply style sheets to a widget. + contrib/hbide/idetags.prg + contrib/hbide/ideparseexpr.c + Code provided by Andy Wos almost an year back. Never thought it will be of much use for this purpose. Big thank you Andy. + contrib/hbide/freadlin.c ! Pulled from contrib/xhb. There may be a better option. * contrib/hbqt/hbqt.ch + Added more constants. * contrib/hbqt/hbqt_destruct.cpp + New PRG level function HB_FUNC( HBQT_QTPTR_FROM_GCPOINTER ) which returns Qt pointer sent the GC pointer as only parameter. * contrib/hbxbp/xbptabpage.prg ! Changed the way callback slots were implemented. * contrib/hbide/hbide.prg + Implemented right-hand . Just click on it and editor tab will scroll to the begining of function. It was very tricky and has the potential to improve. Please play. ! Implemented "Save" with or via icon. You can start real-time editing if you want to. Open many sources, change the tabs, press s or edit and save. Let me know if this behavior is ok. Note: after last tab is closed, hbide.exe terminates. --- harbour/ChangeLog | 37 ++ harbour/contrib/hbide/freadlin.c | 241 ++++++++++++ harbour/contrib/hbide/hbide.hbm | 21 ++ harbour/contrib/hbide/hbide.prg | 341 ++++++++++------- harbour/contrib/hbide/ideparseexpr.c | 357 ++++++++++++++++++ harbour/contrib/hbide/idestylesheets.prg | 122 ++++++ harbour/contrib/hbide/idetags.prg | 461 +++++++++++++++++++++++ harbour/contrib/hbqt/hbqt.ch | 10 + harbour/contrib/hbqt/hbqt_destruct.cpp | 16 +- harbour/contrib/hbxbp/xbptabpage.prg | 36 +- 10 files changed, 1490 insertions(+), 152 deletions(-) create mode 100644 harbour/contrib/hbide/freadlin.c create mode 100644 harbour/contrib/hbide/hbide.hbm create mode 100644 harbour/contrib/hbide/ideparseexpr.c create mode 100644 harbour/contrib/hbide/idestylesheets.prg create mode 100644 harbour/contrib/hbide/idetags.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 3d3ebf517d..84eea325bf 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,43 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-11-22 15:45 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) + * contrib/hbide/hbide.hbm + ! Call hbmk2 hbid.hbm which includes all required files. + + + contrib/hbide/idestylesheets.prg + + Added to implement Qt's powerful feature to apply style sheets to a widget. + + + contrib/hbide/idetags.prg + + contrib/hbide/ideparseexpr.c + + Code provided by Andy Wos almost an year back. Never thought + it will be of much use for this purpose. Big thank you Andy. + + + contrib/hbide/freadlin.c + ! Pulled from contrib/xhb. There may be a better option. + + * contrib/hbqt/hbqt.ch + + Added more constants. + + * contrib/hbqt/hbqt_destruct.cpp + + New PRG level function HB_FUNC( HBQT_QTPTR_FROM_GCPOINTER ) which + returns Qt pointer sent the GC pointer as only parameter. + + * contrib/hbxbp/xbptabpage.prg + ! Changed the way callback slots were implemented. + + * contrib/hbide/hbide.prg + + Implemented right-hand . + Just click on it and editor tab will scroll to the begining of function. + It was very tricky and has the potential to improve. Please play. + + ! Implemented "Save" with or via icon. + You can start real-time editing if you want to. + + Open many sources, change the tabs, press s or edit and save. + Let me know if this behavior is ok. Note: after last tab is closed, hbide.exe + terminates. + 2009-11-23 01:04 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbwin/axcore.c * contrib/hbwin/oleinit.c diff --git a/harbour/contrib/hbide/freadlin.c b/harbour/contrib/hbide/freadlin.c new file mode 100644 index 0000000000..caf23f61f2 --- /dev/null +++ b/harbour/contrib/hbide/freadlin.c @@ -0,0 +1,241 @@ +/* + * $Id$ + */ + +/* + * xHarbour Project source code: + * Text file reading functions + * + * Copyright 2003 Marcelo Lombardo - lombardo@uol.com.br + * http://www.xharbour.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 "hbapi.h" +#include "hbapifs.h" +#include "hbset.h" +#include "hbapiitm.h" +#include "hbapierr.h" + +#define READING_BLOCK 4096 + +char * hb_fsReadLine( HB_FHANDLE hFileHandle, LONG * plBuffLen, const char ** Term, int * iTermSizes, USHORT iTerms, BOOL * bFound, BOOL * bEOF ) +{ + USHORT uiPosTerm = 0, iPos, uiPosition; + USHORT nTries; + LONG lRead = 0, lOffset, lSize; + char * pBuff; + + HB_TRACE(HB_TR_DEBUG, ("hb_fsReadLine(%p, %ld, %p, %p, %hu, %i, %i)", ( void * ) ( HB_PTRDIFF ) hFileHandle, *plBuffLen, Term, iTermSizes, iTerms, *bFound, *bEOF )); + + *bFound = FALSE; + *bEOF = FALSE; + nTries = 0; + lOffset = 0; + lSize = *plBuffLen; + + if( *plBuffLen < 10 ) + *plBuffLen = READING_BLOCK; + + pBuff = ( char * ) hb_xgrab( *plBuffLen + 1 ); + + do + { + if( nTries > 0 ) + { + /* pBuff can be enlarged to hold the line as needed.. */ + lSize = ( *plBuffLen * ( nTries + 1 ) ) + 1; + pBuff = ( char * ) hb_xrealloc( pBuff, lSize ); + lOffset += lRead; + } + + /* read from file */ + lRead = hb_fsReadLarge( hFileHandle, pBuff + lOffset, lSize - lOffset ); + + /* scan the read buffer */ + + if( lRead > 0 ) + { + for( iPos = 0; iPos < lRead; iPos++ ) + { + for( uiPosTerm = 0; uiPosTerm < iTerms; uiPosTerm++ ) + { + /* Compare with the LAST terminator byte */ + if( pBuff[lOffset+iPos] == Term[uiPosTerm][iTermSizes[uiPosTerm]-1] && (iTermSizes[uiPosTerm]-1) <= (iPos+lOffset) ) + { + *bFound = TRUE; + + for(uiPosition=0; uiPosition < (iTermSizes[uiPosTerm]-1); uiPosition++) + { + if(Term[uiPosTerm][uiPosition] != pBuff[ lOffset+(iPos-iTermSizes[uiPosTerm])+uiPosition+1 ]) + { + *bFound = FALSE; + break; + } + } + + if( *bFound ) + break; + } + } + + if( *bFound ) + break; + } + + if( *bFound ) + { + *plBuffLen = lOffset + iPos - iTermSizes[ uiPosTerm ] + 1; + + pBuff[ *plBuffLen ] = '\0'; + + /* Set handle pointer in the end of the line */ + hb_fsSeek( hFileHandle, (((lRead-((LONG)iPos)))*-1)+1, FS_RELATIVE ); + + return pBuff; + } + } + else + { + if( ! *bFound ) + { + if( nTries == 0 ) + { + pBuff[ 0 ] = '\0'; + *plBuffLen = 0; + } + else + { + pBuff[ lOffset + lRead ] = '\0'; + *plBuffLen = lOffset + lRead; + } + + *bEOF = TRUE; + } + } + + nTries++; + } + while( ( ! *bFound ) && lRead > 0 ); + + return pBuff; +} + +/* PRG level fReadLine( , <@buffer>, [], [] ) */ + +HB_FUNC( HB_FREADLINE ) +{ + PHB_ITEM pTerm1; + HB_FHANDLE hFileHandle = ( HB_FHANDLE ) hb_parnint( 1 ); + const char ** Term; + char * pBuffer; + int * iTermSizes; + LONG lSize = hb_parnl( 4 ); + USHORT i, iTerms; + BOOL bFound, bEOF; + + if( ( !HB_ISBYREF( 2 ) ) || ( !HB_ISNUM( 1 ) ) ) + { + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, 4, + hb_paramError( 1 ), + hb_paramError( 2 ), + hb_paramError( 3 ), + hb_paramError( 4 ) ); + return; + } + + if( HB_ISARRAY( 3 ) || HB_ISCHAR( 3 ) ) + { + if( HB_ISARRAY( 3 ) ) + { + pTerm1 = hb_param( 3, HB_IT_ARRAY ); + iTerms = ( USHORT ) hb_arrayLen( pTerm1 ); + + if( iTerms <= 0 ) + { + hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, 4, + hb_paramError( 1 ), + hb_paramError( 2 ), + hb_paramError( 3 ), + hb_paramError( 4 ) ); + return; + } + + Term = ( const char ** ) hb_xgrab( sizeof( char * ) * iTerms ); + iTermSizes = ( int * ) hb_xgrab( sizeof( int ) * iTerms ); + + for( i = 0; i < iTerms; i++ ) + { + Term[ i ] = hb_arrayGetCPtr( pTerm1, i + 1 ); + iTermSizes[ i ] = hb_arrayGetCLen( pTerm1, i + 1 ); + } + } + else + { + pTerm1 = hb_param( 3, HB_IT_STRING ); + Term = ( const char ** ) hb_xgrab( sizeof( char * ) ); + iTermSizes = ( int * ) hb_xgrab( sizeof( int ) ); + Term[ 0 ] = hb_itemGetCPtr( pTerm1 ); + iTermSizes[ 0 ] = hb_itemGetCLen( pTerm1 ); + iTerms = 1; + } + } + else + { + Term = ( const char ** ) hb_xgrab( sizeof( char * ) ); + iTermSizes = ( int * ) hb_xgrab( sizeof( int ) ); + Term[ 0 ] = "\r\n"; /* Should be preplaced with the default EOL sequence */ + iTerms = 1; + iTermSizes[ 0 ] = 2; + } + + if( lSize == 0 ) + lSize = READING_BLOCK; + + pBuffer = hb_fsReadLine( hFileHandle, &lSize, Term, iTermSizes, iTerms, &bFound, &bEOF ); + + if( ! hb_storclen_buffer( pBuffer, lSize, 2 ) ) + hb_xfree( pBuffer ); + hb_retnl( bEOF ? -1 : 0 ); + hb_xfree( Term ); + hb_xfree( iTermSizes ); +} diff --git a/harbour/contrib/hbide/hbide.hbm b/harbour/contrib/hbide/hbide.hbm new file mode 100644 index 0000000000..05497a3d1b --- /dev/null +++ b/harbour/contrib/hbide/hbide.hbm @@ -0,0 +1,21 @@ +# +# $Id$ +# + +../hbxbp/hbxbp.hbc + +-inc + +-w3 +-es2 + +-ohbide + +hbide.prg +idestylesheets.prg +idetags.prg + +freadlin.c +ideparseexpr.c + + diff --git a/harbour/contrib/hbide/hbide.prg b/harbour/contrib/hbide/hbide.prg index e28475f172..155266a20e 100644 --- a/harbour/contrib/hbide/hbide.prg +++ b/harbour/contrib/hbide/hbide.prg @@ -80,15 +80,6 @@ /*----------------------------------------------------------------------*/ -#define TAB_1 1 -#define TAB_2 2 -#define TAB_3 3 -#define TAB_4 4 -#define TAB_5 5 -#define TAB_6 6 -#define TAB_7 7 -#define TAB_8 8 - #define CRLF chr( 13 )+chr( 10 ) STATIC s_resPath @@ -139,6 +130,7 @@ CLASS HbIde DATA qSplitter DATA qSplitterL DATA qSplitterR + DATA qTabWidget /* XBP Objects */ DATA oDlg @@ -156,6 +148,8 @@ CLASS HbIde DATA oOutputResult DATA oCompileResult DATA oLinkResult + DATA oNewDlg + DATA oTabWidget DATA oProjRoot DATA oExes @@ -165,6 +159,7 @@ CLASS HbIde DATA lDockRVisible INIT .t. DATA lDockBVisible INIT .t. + DATA lTabCloseRequested INIT .f. METHOD new( cProjectOrSource ) METHOD create( cProjectOrSource ) @@ -191,7 +186,21 @@ CLASS HbIde METHOD saveSource() METHOD updateFuncList() + METHOD gotoFunction() METHOD fetchNewProject() + METHOD closeTab() + METHOD activateTab() + METHOD getCurrentTab() + METHOD getYesNo() + + DATA aTags INIT {} + DATA aText INIT {} + DATA aSources INIT {} + DATA aFuncList INIT {} + DATA aLines INIT {} + DATA aComments INIT {} + + METHOD createTags() ENDCLASS @@ -228,7 +237,10 @@ METHOD HbIde:create( cProjectOrSource ) ::oDlg:Show() ::oDa:oTabWidget := XbpTabWidget():new():create( ::oDa, , {0,0}, {10,10}, , .t. ) - ::oDa:oTabWidget:oWidget:setTabsClosable( .t. ) +// ::oDa:oTabWidget:oWidget:setTabsClosable( .t. ) + ::oDa:oTabWidget:oWidget:setUsesScrollButtons( .f. ) + ::oTabWidget := ::oDa:oTabWidget + ::qTabWidget := ::oDa:oTabWidget:oWidget ::buildProjectTree() ::buildFuncList() @@ -293,29 +305,29 @@ METHOD HbIde:create( cProjectOrSource ) ::buildToolBar() ::editSource( ::cProjFile ) - ::updateFuncList() ::oDlg:Show() /* Enter Xbase++ Event Loop - working */ DO WHILE .t. ::nEvent := AppEvent( @::mp1, @::mp2, @::oXbp ) + IF ::nEvent == xbeP_Quit EXIT ENDIF - HBXBP_DEBUG( ::nEvent, ::mp1, ::mp2 ) + // HBXBP_DEBUG( ::nEvent, ::mp1, ::mp2 ) - IF ( ::nEvent == xbeP_Close ) .OR. ( ::nEvent == xbeP_Keyboard .and. ::mp1 == xbeK_ESC ) - IF ::nEvent == xbeP_Close - ::closeAllSources() + IF ::nEvent == xbeP_Close + ::closeAllSources() + EXIT + + ELSEIF ( ::nEvent == xbeP_Keyboard .and. ::mp1 == xbeK_ESC ) + ::closeSource() + IF ::qTabWidget:count() == 0 EXIT - ELSE - ::closeSource( ::nCurTab, .t. ) - IF empty( ::aTabs ) - EXIT - ENDIF ENDIF + ENDIF ::oXbp:handleEvent( ::nEvent, ::mp1, ::mp2 ) @@ -328,11 +340,21 @@ METHOD HbIde:create( cProjectOrSource ) /*----------------------------------------------------------------------*/ +METHOD HbIde:updateFuncList() + + ::oFuncList:clear() + IF !empty( ::aTags ) + aeval( ::aTags, {|e| ::oFuncList:addItem( e[ 2 ] + " " + e[ 5 ] ) } ) + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD HbIde:buildTabPage( oWnd, cSource ) + LOCAL oTab, cPath, cFile, cExt LOCAL aPos := { 5,5 } LOCAL aSize := { 890, 420 } - LOCAL oTab, o - LOCAL cPath, cFile, cExt//, qIcon LOCAL nIndex := len( ::aTabs ) DEFAULT cSource TO "Untitled" @@ -346,16 +368,15 @@ METHOD HbIde:buildTabPage( oWnd, cSource ) oTab:create() IF lower( cExt ) $ ".c;.cpp" - ::oDa:oTabWidget:oWidget:setTabIcon( nIndex, s_resPath + "filec.png" ) + ::qTabWidget:setTabIcon( nIndex, s_resPath + "filec.png" ) ELSE - ::oDa:oTabWidget:oWidget:setTabIcon( nIndex, s_resPath + "fileprg.png" ) + ::qTabWidget:setTabIcon( nIndex, s_resPath + "fileprg.png" ) ENDIF - ::oDa:oTabWidget:oWidget:setTabTooltip( nIndex, cSource ) + ::qTabWidget:setTabTooltip( nIndex, cSource ) + + oTab:tabActivate := {|mp1,mp2,oXbp| ::activateTab( mp1, mp2, oXbp ) } + oTab:closeRequested := {|mp1,mp2,oXbp| ::closeTab( mp1, mp2, oXbp ) } - oTab:tabActivate := {|mp1,mp2,oXbp| HB_SYMBOL_UNUSED( mp1 ), o := oXbp, ; - mp2 := ascan( ::aTabs, {|e_| e_[ 1 ] == o } ), ::nCurTab := mp2 } - oTab:closeRequested := {|mp1,mp2,oXbp| HB_SYMBOL_UNUSED( mp1 ), o := oXbp, ; - mp2 := ascan( ::aTabs, {|e_| e_[ 1 ] == o } ), ::nCurTab := mp2, ::closeSource( ::nCurTab, .t. ) } RETURN oTab /*----------------------------------------------------------------------*/ @@ -388,53 +409,60 @@ METHOD HbIde:editSource( cSourceFile ) ::nPrevTab := ::nCurTab ::nCurTab := len( ::aTabs ) - ::oDa:oTabWidget:oWidget:setCurrentIndex( ::nCurTab - 1 ) + ::qTabWidget:setCurrentIndex( ::qTabWidget:indexOf( QT_PTROFXBP( oTab ) ) ) + + ::aSources := { cSourceFile } + ::createTags() + ::updateFuncList() RETURN Self /*----------------------------------------------------------------------*/ -METHOD HbIde:saveSource( nTab ) - LOCAL cBuffer - LOCAL qDocument := QTextDocument():configure( ::aTabs[ nTab, 2 ]:document() ) +METHOD HbIde:closeTab( mp1, mp2, oXbp ) - IF qDocument:isModified() - HBXBP_DEBUG( "Document be Saved", "YES", ::aTabs[ nTab, 5 ] ) - cBuffer := ::aTabs[ nTab, 2 ]:toPlainText() - memowrit( ::aTabs[ nTab, 5 ], cBuffer ) - ELSE - HBXBP_DEBUG( "Document Modified", "NO ", ::aTabs[ nTab, 5 ] ) + HB_SYMBOL_UNUSED( mp1 ) + + IF ( mp2 := ascan( ::aTabs, {|e_| e_[ 1 ] == oXbp } ) ) > 0 + ::closeSource( mp2, .t. ) ENDIF - RETURN self + RETURN Self /*----------------------------------------------------------------------*/ -METHOD HbIde:closeSource( nTab, lDel ) +METHOD HbIde:activateTab( mp1, mp2, oXbp ) - DEFAULT lDel TO .T. + HB_SYMBOL_UNUSED( mp1 ) - HBXBP_DEBUG( " . " ) - HBXBP_DEBUG( "HbIde:closeSource( nTab, lDel )", nTab, lDel ) + IF ( mp2 := ascan( ::aTabs, {|e_| e_[ 1 ] == oXbp } ) ) > 0 + ::nCurTab := mp2 + ::aSources := { ::aTabs[ ::nCurTab, 5 ] } + ::createTags() + ::updateFuncList() + ENDIF - IF !empty( ::aTabs ) .and. !empty( nTab ) + RETURN Self + +/*----------------------------------------------------------------------*/ + +METHOD HbIde:getCurrentTab() + LOCAL qTab, nTab + + qTab := ::qTabWidget:currentWidget() + nTab := ascan( ::aTabs, {|e_| HBQT_QTPTR_FROM_GCPOINTER( e_[ 1 ]:oWidget:pPtr ) == qTab } ) + + RETURN nTab + +/*----------------------------------------------------------------------*/ + +METHOD HbIde:closeSource() + LOCAL nTab + + IF !empty( nTab := ::getCurrentTab() ) ::saveSource( nTab ) - /* Destroy at Qt level */ - ::oDa:oTabWidget:oWidget:removeTab( nTab - 1 ) - - /* Destroy at XBP level */ - ::aTabs[ nTab,1 ]:destroy() - - /* Destroy at this object level */ - IF lDel - adel( ::aTabs, nTab ) - asize( ::aTabs, len( ::aTabs ) - 1 ) - ENDIF - - IF empty( ::aTabs ) - PostAppEvent( xbeP_Quit ) - ENDIF + ::qTabWidget:removeTab( ::qTabWidget:currentIndex() ) ENDIF RETURN Self @@ -443,9 +471,10 @@ METHOD HbIde:closeSource( nTab, lDel ) METHOD HbIde:closeAllSources() LOCAL nTab + LOCAL nTabs := ::qTabWidget:count() - FOR nTab := len( ::aTabs ) TO 1 STEP -1 - ::closeSource( nTab, .f. ) + FOR nTab := 1 TO nTabs + ::closeSource() NEXT ::aTabs := {} @@ -453,6 +482,55 @@ METHOD HbIde:closeAllSources() /*----------------------------------------------------------------------*/ +METHOD HbIde:getYesNo( cMsg, cInfo, cTitle ) + LOCAL oMB + + DEFAULT cTitle TO "Option Please!" + + oMB := QMessageBox():new() + oMB:setText( ""+ cMsg +"" ) + IF !empty( cInfo ) + oMB:setInformativeText( cInfo ) + ENDIF + oMB:setIcon( QMessageBox_Information ) + oMB:setParent( SetAppWindow():pWidget ) + oMB:setWindowFlags( Qt_Dialog ) + oMB:setWindowTitle( cTitle ) + oMB:setStandardButtons( QMessageBox_Yes + QMessageBox_No ) + + RETURN ( oMB:exec() == QMessageBox_Yes ) + +/*----------------------------------------------------------------------*/ + +METHOD HbIde:saveSource( nTab, lConfirm ) + LOCAL cBuffer, qDocument + LOCAL lSave := .t. + + DEFAULT lConfirm TO .t. + + IF nTab > 0 + qDocument := QTextDocument():configure( ::aTabs[ nTab, 2 ]:document() ) + + IF qDocument:isModified() + IF lConfirm .and. !::getYesNo( ::aTabs[ nTab, 5 ] + " : has changed !", "Save this source ?" ) + lSave := .f. + ENDIF + + IF lSave + cBuffer := ::aTabs[ nTab, 2 ]:toPlainText() + memowrit( ::aTabs[ nTab, 5 ], cBuffer ) + qDocument:setModified( .f. ) + ::createTags() + ::updateFuncList() + ELSE + ENDIF + ENDIF + ENDIF + + RETURN Self + +/*----------------------------------------------------------------------*/ + METHOD HbIde:selectSource( cMode ) LOCAL oDlg, cFile//, aFiles @@ -528,7 +606,7 @@ METHOD HbIde:buildProjectTree() NEXT ::aProjData[ 3,3 ] := aExeD ::aProjData[ 3,1 ]:expand( .t. ) -#if 1 + /* Next classification by type of source */ aExe := ::aProjData[ 1,3 ] aPrjs := { "PRG Sources", "C Sources", "CPP Sources", "CH Headers", "H Headers" } @@ -540,7 +618,6 @@ METHOD HbIde:buildProjectTree() aExe[ j,3 ] := aExeD aExe[ j,1 ]:expand( .t. ) NEXT -#endif RETURN Self @@ -550,14 +627,17 @@ METHOD HbIde:executeAction( cKey ) LOCAL cFile DO CASE - CASE cKey == "3" + CASE cKey == "NewProject" + ::fetchNewProject() + + CASE cKey == "Open" IF !empty( cFile := ::selectSource( "open" ) ) ::oProjRoot:addItem( cFile ) ::editSource( cFile ) ENDIF - CASE cKey == "4" - ::saveSource( ::nCurTab ) + CASE cKey == "Save" + ::saveSource( ::getCurrentTab(), .f. ) CASE cKey == "5" ::closeSource( ::nCurTab, .t. ) @@ -582,9 +662,6 @@ METHOD HbIde:executeAction( cKey ) ENDIF ::lDockRVisible := !( ::lDockRVisible ) - CASE cKey == "NewProject" - ::fetchNewProject() - ENDCASE RETURN nil @@ -594,8 +671,7 @@ METHOD HbIde:executeAction( cKey ) METHOD HbIde:buildToolBar() ::oTBar := XbpToolBar():new( ::oDA ) - ::oTBar:create( , , { 0, ::oDa:currentSize()[ 2 ]-60 }, ; - { ::oDa:currentSize()[ 1 ], 60 } ) + ::oTBar:create( , , { 0, ::oDa:currentSize()[ 2 ]-60 }, { ::oDa:currentSize()[ 1 ], 60 } ) ::oTBar:imageWidth := 20 ::oTBar:imageHeight := 20 @@ -604,9 +680,9 @@ METHOD HbIde:buildToolBar() ::oTBar:addItem( "Exit" , s_resPath + "exit.png" , , , , , "1" ) ::oTBar:addItem( , , , , , XBPTOOLBAR_BUTTON_SEPARATOR ) - ::oTBar:addItem( "Properties" , s_resPath + "properties.png" , , , , , "2" ) - ::oTBar:addItem( "Open" , s_resPath + "open.png" , , , , , "3" ) - ::oTBar:addItem( "Save" , s_resPath + "save.png" , , , , , "4" ) + ::oTBar:addItem( "New Project" , s_resPath + "properties.png" , , , , , "NewProject" ) + ::oTBar:addItem( "Open" , s_resPath + "open.png" , , , , , "Open" ) + ::oTBar:addItem( "Save" , s_resPath + "save.png" , , , , , "Save" ) ::oTBar:addItem( "Close" , s_resPath + "close.png" , , , , , "5" ) ::oTBar:addItem( , , , , , XBPTOOLBAR_BUTTON_SEPARATOR ) ::oTBar:addItem( "Compile" , s_resPath + "compile.png" , , , , , "5" ) @@ -712,12 +788,17 @@ METHOD HbIde:buildDialog() /*----------------------------------------------------------------------*/ -METHOD HbIde:updateFuncList() - - ::oFuncList:addItem( "Procedure Main" ) - ::oFuncList:addItem( "Class HBIDE" ) - ::oFuncList:addItem( "Method HbIde:new" ) +METHOD HbIde:gotoFunction( mp1, mp2, oListBox ) + LOCAL n, cAnchor + mp1 := oListBox:getData() + mp2 := oListBox:getItem( mp1 ) + IF ( n := ascan( ::aTags, {|e| mp2 == e[ 2 ] + " " + e[ 5 ] } ) ) > 0 + cAnchor := trim( ::aText[ ::aTags[ n,3 ] ] ) + IF !( ::aTabs[ ::nCurTab, 2 ]:find( cAnchor, QTextDocument_FindCaseSensitively ) ) + ::aTabs[ ::nCurTab, 2 ]:find( cAnchor, QTextDocument_FindBackward + QTextDocument_FindCaseSensitively ) + ENDIF + ENDIF RETURN Self /*----------------------------------------------------------------------*/ @@ -735,6 +816,8 @@ METHOD HbIde:buildFuncList() ::oFuncList := XbpListBox():new( ::oDockR ):create( , , { 0,0 }, { 100,400 }, , .t. ) ::oFuncList:setStyleSheet( GetStyleSheet( "QListView" ) ) + ::oFuncList:setColorBG( GraMakeRGBColor( { 210,120,220 } ) ) + ::oFuncList:ItemMarked := {|mp1, mp2, oXbp| ::gotoFunction( mp1, mp2, oXbp ) } ::oDockR:oWidget:setWidget( QT_PTROFXBP( ::oFuncList ) ) @@ -821,59 +904,6 @@ METHOD HbIde:buildOutputResults() /*----------------------------------------------------------------------*/ -METHOD HbIde:fetchNewProject() - - RETURN self - -/*----------------------------------------------------------------------*/ - -STATIC FUNCTION GetStyleSheet( cWidget ) - LOCAL s, txt_:={} - - DO CASE - CASE cWidget == "QListView" - aadd( txt_, ' ' ) - aadd( txt_, ' QListView { ' ) - aadd( txt_, ' alternate-background-color: yellow; ' ) - aadd( txt_, ' } ' ) - aadd( txt_, ' ' ) - aadd( txt_, ' QListView { ' ) - aadd( txt_, ' show-decoration-selected: 1; /* make the selection span the entire width of the view */ ' ) - aadd( txt_, ' } ' ) - aadd( txt_, ' ' ) - aadd( txt_, ' QListView::item:alternate { ' ) - aadd( txt_, ' background: #EEEEEE; ' ) - aadd( txt_, ' } ' ) - aadd( txt_, ' ' ) - aadd( txt_, ' QListView::item:selected { ' ) - aadd( txt_, ' border: 1px solid #6a6ea9; ' ) - aadd( txt_, ' } ' ) - aadd( txt_, ' ' ) - aadd( txt_, ' QListView::item:selected:!active { ' ) - aadd( txt_, ' background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, ' ) - aadd( txt_, ' stop: 0 #ABAFE5, stop: 1 #8588B2); ' ) - aadd( txt_, ' } ' ) - aadd( txt_, ' ' ) - aadd( txt_, ' QListView::item:selected:active { ' ) - aadd( txt_, ' background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, ' ) - aadd( txt_, ' stop: 0 #6a6ea9, stop: 1 #888dd9); ' ) - aadd( txt_, ' } ' ) - aadd( txt_, ' ' ) - aadd( txt_, ' QListView::item:hover { ' ) - aadd( txt_, ' background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, ' ) - aadd( txt_, ' stop: 0 #FAFBFE, stop: 1 #DCDEF1); ' ) - aadd( txt_, '} ' ) - aadd( txt_, ' ' ) - - ENDCASE - - s := "" - aeval( txt_, {|e| s += e + chr( 13 )+chr( 10 ) } ) - - RETURN s - -/*----------------------------------------------------------------------*/ - STATIC FUNCTION MenuAddSep( oMenu ) oMenu:addItem( { NIL, NIL, XBPMENUBAR_MIS_SEPARATOR, NIL } ) @@ -881,3 +911,48 @@ STATIC FUNCTION MenuAddSep( oMenu ) RETURN nil /*----------------------------------------------------------------------*/ + +METHOD HbIde:CreateTags() + LOCAL aSumData := "" + LOCAL cComments, aSummary, i, cPath, cSource, cExt + + ::aTags := {} + + FOR i := 1 TO Len( ::aSources ) + HB_FNameSplit( ::aSources[ i ], @cPath, @cSource, @cExt ) + + IF Upper( cExt ) $ ".PRG.CPP" + IF !empty( ::aText := ReadSource( ::aSources[ i ] ) ) + aSumData := {} + + cComments := CheckComments( ::aText ) + aSummary := Summarize( ::aText, cComments, @aSumData , IIf( Upper( cExt ) == ".PRG", 9, 1 ) ) + ::aTags := UpdateTags( ::aSources[ i ], aSummary, aSumData, @::aFuncList, @::aLines ) + + #if 0 + IF !empty( aTags ) + aeval( aTags, {|e_| aadd( ::aTags, e_ ) } ) + ::hData[ cSource+cExt ] := { a[ i ], aTags, aclone( ::aText ), cComments, ::aFuncList, ::aLines } + aadd( ::aSrcLines, ::aText ) + aadd( ::aComments, cComments ) + ENDIF + #endif + ENDIF + ENDIF + NEXT + + RETURN ( NIL ) + +//----------------------------------------------------------------------// + +METHOD HbIde:fetchNewProject() +#if 1 // In Development + ::oNewDlg := XbpWindow():new( ::oDlg ) + ::oNewDlg:oWidget := QDialog():new( QT_PTROFXBP( ::oDlg ) ) + ::oNewDlg:oWidget:exec() + +#endif + RETURN self + +/*----------------------------------------------------------------------*/ + diff --git a/harbour/contrib/hbide/ideparseexpr.c b/harbour/contrib/hbide/ideparseexpr.c new file mode 100644 index 0000000000..3d1970812c --- /dev/null +++ b/harbour/contrib/hbide/ideparseexpr.c @@ -0,0 +1,357 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * + * Copyright 2009 Andy Wos + * 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. + * + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/* + * EkOnkar + * ( The LORD is ONE ) + * + * Harbour-Qt IDE + * + * Code Forwarded by Andy Wos + * + * Pritpal Bedi + * 22Nov2009 + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ + +#include "hbapi.h" +#include "hbapiitm.h" + +/*----------------------------------------------------------------------*/ + +#define MAX_LINE_LEN 2047 + +static char * good = "''_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890."; +static char* adouble[] = {"*/", "/*", "//", "->", "::", "||", "++", "--", "**", ":=", + "<=", ">=", "<>", "!=", "==", "+=", "-=", "*=", "/=", "%=", + "^=", "&&", "^^", ">>", "<<", "=>", "&=", "|=" }; +static int lengood = 66; +static int lendouble = 28; + +/*----------------------------------------------------------------------*/ + +UINT linearfind( char** array, char* cText, UINT lenarray, UINT lentext, int lMatchCase ) +{ + UINT i; + + if( lMatchCase ) + { + for( i = 0 ; i < lenarray ; i++ ) + { + if( strncmp( cText, array[ i ], lentext + 1 ) == 0 ) + { + return( i + 1 ); + } + } + } + else + { + for( i = 0 ; i < lenarray ; i++ ) + { + if( strnicmp( cText, array[ i ], lentext + 1 ) == 0 ) + { + return( i++ ); + } + } + + } + return 0; +} + +/*----------------------------------------------------------------------*/ + +BOOL strempty( char* string ) +{ + BOOL lRet = TRUE; + UINT i = 0; + + while( string[ i ] != 0 ) + { + if( string[ i++ ] != 32 ) + { + lRet = FALSE; + break; + } + } + return lRet; +} + +/*----------------------------------------------------------------------*/ + +UINT atbuff( char * chars, char * string, UINT StartFrom, UINT Target, UINT len_chars, UINT len ) +{ + UINT x ; + UINT Counter = 0; + + if( len >= len_chars && StartFrom <= len - len_chars ) + for( x = StartFrom; x <= ( len - len_chars ); x++ ) + if( strncmp( string + x, chars, len_chars ) == 0 ) + if( ++Counter == Target ) + return( x + 1 ); + return 0; +} + +/*----------------------------------------------------------------------*/ + +static int _GetWord( char * cText, BOOL lHonorSpacing, char * cWord, int * pnpos ) +{ + int maxlen = strlen( cText ); + int npos = 0; + int wordlen = 0; + char temp; + char ch; + char csingle[ 2 ]; + char cdouble[ 3 ]; + + // workaround +// good[ 0 ] = '"'; + + csingle[ 1 ] = 0; + cdouble[ 2 ] = 0; + + if( maxlen > 0 ) + { + ch = cText[ 0 ]; + + if( ch == ',' ) // lists + { + cWord[ wordlen++ ] = ch ; + npos++ ; + } + else // literals + { + if( ch == '"' || ch == '\'' ) + { + temp = ch; + cWord[ wordlen++ ] = ch; + npos++; + ch = ' '; + while( ( npos < maxlen ) && ( ch != temp ) ) + { + ch = cText[ npos ]; + cWord[ wordlen++ ] = ch; + npos ++; + } + } + else + { + csingle[0] = ch; + if( atbuff( csingle, good, 0, 1, 1, lengood ) ) //ch $ good ) // variables, commands, function names + { + while( ( npos < maxlen ) && atbuff( csingle, good, 0, 1, 1, lengood ) ) + { + cWord[ wordlen++ ] = ch; + npos++ ; + ch = cText[ npos ]; + csingle[ 0 ] = ch; + } + + } + else if( ch == ' ' ) + { + while( ( npos < maxlen ) && ch == ' ' ) + { + cWord[ wordlen++ ] = ch; + npos ++; + ch = cText[ npos ]; + } + + if( !lHonorSpacing ) + { + cWord[ 0 ] = ' '; //reduce spaces to 1 + wordlen = 1; + } + } + else //operators, punctuation + { + cWord[ wordlen++ ]= ch; + npos ++; + ch = cText[ npos ]; + if( maxlen > npos ) + { + cdouble[ 0 ] = cWord[ 0 ]; + cdouble[ 1 ] = ch; + if( linearfind( adouble, cdouble, lendouble, 2, TRUE ) ) //if( (cWord + ch) $ adouble) //aScan( adouble, cWord + ch ) > 0 + { + cWord[ wordlen++ ] = ch; + npos ++; + } + } + } + } + } + } + + cWord[ wordlen ] = 0 ; + *pnpos = npos; + + return wordlen; +} + +/*----------------------------------------------------------------------*/ + +/* + * ( c, lHonorSpacing, lInRemark, lUpperKeyWord, lKeepComments, lPRG, lKeepSpaces ) + */ +HB_FUNC( PARSEXPR ) +{ + char * c = ( char * ) hb_parc( 1 ); + BOOL lHonorSpacing = hb_parl( 2 ); + BOOL lInRemark = HB_ISLOG( 3 ) ? hb_parl( 3 ) : FALSE; + BOOL lKeepComments = HB_ISLOG( 5 ) ? hb_parl( 5 ) : TRUE; + BOOL bPRG = HB_ISLOG( 6 ) ? hb_parl( 6 ) : TRUE; + BOOL lKeepSpaces = HB_ISLOG( 7 ) ? hb_parl( 7 ) : TRUE; + PHB_ITEM aExpr = hb_itemArrayNew( 0 ); + PHB_ITEM element = hb_itemNew( NULL ); + BOOL lFirst = TRUE; + int lenprocessed = 0; + int lenwords = 0; + int wordlen ; + int npos ; + + char NextWord[ MAX_LINE_LEN+1 ]; + + NextWord[ 0 ] = 0; + + while( ( wordlen = _GetWord( c, lHonorSpacing, NextWord, &lenprocessed ) ) != 0 ) + { + c += lenprocessed; + + if( strncmp( NextWord, "*/", 3 ) == 0 ) // remark end + { + if( lKeepComments ) + { + lenwords++; + hb_arrayAdd( aExpr, hb_itemPutC( element, NextWord ) ); + } + lInRemark = FALSE; + } + else if( ( strncmp( NextWord, "/*", 3 ) == 0) || lInRemark ) // remark start + { + lInRemark = ( ( npos = atbuff( "*/", c, 0, 1, 2, strlen( c ) ) ) == 0 ); + + if( lInRemark ) + { + + if( lKeepComments ) + { + strcat( NextWord, c ); + lenwords++; + hb_arrayAdd( aExpr, hb_itemPutC( element, NextWord ) ); + } + break; + } + else + { + if( lKeepComments ) + { + strncpy( NextWord + wordlen, c, npos+1 ); + NextWord[ wordlen + npos + 1 ] = 0; + lenwords++; + hb_arrayAdd( aExpr, hb_itemPutC( element, NextWord ) ); + } + c += ( npos + 1 ) ;//2 ); + } + } + else if( strncmp( NextWord, "//", 3 ) == 0 || ( bPRG && strncmp( NextWord, "&&", 3 ) == 0 ) ) // inline remark + { + if( lKeepComments ) + { + strcat( NextWord, c ); + lenwords++; + hb_arrayAdd( aExpr, hb_itemPutC( element, NextWord ) ); + } + break; + } + else if( strncmp( NextWord, "**", 3 ) == 0 && ( lFirst && bPRG ) ) + { + if( lKeepComments ) + { + strcat( NextWord, c ); + lenwords++; + hb_arrayAdd( aExpr, hb_itemPutC( element, NextWord ) ); + } + break; + } + else + { + if( lKeepSpaces || ! strempty( NextWord ) ) + { + lenwords++; + hb_arrayAdd( aExpr, hb_itemPutC( element, NextWord ) ); + } + } + + if( ! strempty( NextWord ) ) + { + lFirst = FALSE; + } + } // end while + + if( !lKeepComments && !lenwords > 0 && hb_arrayGetCPtr( aExpr, lenwords ) ) + { + hb_arraySize( aExpr, lenwords ); + } + + if( HB_ISBYREF( 3 ) ) + hb_storl( lInRemark, 3 ); + + hb_itemReturn( aExpr ); + hb_itemRelease( element ); + hb_itemRelease( aExpr ); +} + +/*----------------------------------------------------------------------*/ + diff --git a/harbour/contrib/hbide/idestylesheets.prg b/harbour/contrib/hbide/idestylesheets.prg new file mode 100644 index 0000000000..0ccf2149fe --- /dev/null +++ b/harbour/contrib/hbide/idestylesheets.prg @@ -0,0 +1,122 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * + * Copyright 2009 Pritpal Bedi + * 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. + * + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/* + * EkOnkar + * ( The LORD is ONE ) + * + * Harbour-Qt IDE + * + * Pritpal Bedi + * 17Nov2009 + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ + +#include "common.ch" + +/*----------------------------------------------------------------------*/ + +FUNCTION GetStyleSheet( cWidget ) + LOCAL s, txt_:={} + + DO CASE + CASE cWidget == "QListView" + aadd( txt_, " " ) + aadd( txt_, " QListView { " ) + aadd( txt_, " alternate-background-color: yellow; " ) + aadd( txt_, " } " ) + aadd( txt_, " " ) + aadd( txt_, " QListView { " ) + aadd( txt_, " show-decoration-selected: 1; " ) + aadd( txt_, " } " ) + aadd( txt_, " " ) + aadd( txt_, " QListView::item:alternate { " ) + aadd( txt_, " background: #EEEEEE; " ) + aadd( txt_, " } " ) + aadd( txt_, " " ) + aadd( txt_, " QListView::item:selected { " ) + aadd( txt_, " border: 1px solid #6a6ea9; " ) + aadd( txt_, " } " ) + aadd( txt_, " " ) + aadd( txt_, " QListView::item:selected:!active { " ) + aadd( txt_, " background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, " ) + aadd( txt_, " stop: 0 #ABAFE5, stop: 1 #8588B2); " ) + aadd( txt_, " } " ) + aadd( txt_, " " ) + aadd( txt_, " QListView::item:selected:active { " ) + aadd( txt_, " background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, " ) + aadd( txt_, " stop: 0 #6a6ea9, stop: 1 #888dd9); " ) + aadd( txt_, " } " ) + aadd( txt_, " " ) + aadd( txt_, " QListView::item:hover { " ) + aadd( txt_, " background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, " ) + aadd( txt_, " stop: 0 #FAFBFE, stop: 1 #DCDEF1); " ) + aadd( txt_, "} " ) + aadd( txt_, " " ) + aadd( txt_, " QListView { " ) + aadd( txt_, " background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, " ) + aadd( txt_, " stop: 0 #8588B2, stop: 1 #DCDEF1); " ) + aadd( txt_, "} " ) + aadd( txt_, " " ) + + ENDCASE + + s := "" + aeval( txt_, {|e| s += e + chr( 13 )+chr( 10 ) } ) + + RETURN s + +/*----------------------------------------------------------------------*/ + diff --git a/harbour/contrib/hbide/idetags.prg b/harbour/contrib/hbide/idetags.prg new file mode 100644 index 0000000000..16329ec19c --- /dev/null +++ b/harbour/contrib/hbide/idetags.prg @@ -0,0 +1,461 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * + * Copyright 2009 Andy Wos + * 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. + * + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/* + * EkOnkar + * ( The LORD is ONE ) + * + * Harbour-Qt IDE + * + * Code Forwarded by Andy Wos + * + * Pritpal Bedi + * 22Nov2009 + */ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ +/*----------------------------------------------------------------------*/ + +#include "common.ch" +#include "xbp.ch" + +/*----------------------------------------------------------------------*/ + +FUNCTION UpdateTags( cModule, aSummary, aSumData, aFuncList, aLines ) + LOCAL cType, cName, cSyntax, n, m, i, cSource, cExt + LOCAL cClassName := "" + LOCAL aTags := {} + LOCAL cGoodFuncNameChars := "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + + Hb_FNameSplit( cModule, , @cSource, @cExt ) + cSource += cExt + + aFuncList := {} + aLines := {} + + FOR i := 1 TO LEN( aSummary ) + cSyntax := lTrim( Substr( aSummary[ i ], 8 ) ) + + IF LEFT( cSyntax,14 ) == "HB_FUNC_STATIC" + cType := "HB_FUNC_STATIC" + cSyntax := AllTrim( StrTran( StrTran( Substr( cSyntax, 15 ), "(", "" ), ")", "" ) ) + cName := cSyntax + cSyntax += "(void)" + + ELSEIF LEFT( cSyntax, 7 ) == "HB_FUNC" + cType := "HB_FUNC" + cSyntax := AllTrim( StrTran( StrTran( Substr( cSyntax,8 ), "(", "" ), ")", "" ) ) + cName := cSyntax + cSyntax += "(void)" + + ELSE + cType := Upper( Left( cSyntax, At( " ", cSyntax ) - 1 ) ) + IF ctype = "INIT" .OR. cType = "EXIT" + cSyntax := LTrim( Substr( cSyntax, 6 ) ) + cType +=" "+Upper( Left( cSyntax, ( n := At( " ", cSyntax ) ) - 1 ) ) + cSyntax := LTrim( Substr( cSyntax, n + 1 ) ) + + ELSEIF cType = "STATIC" + cSyntax := LTrim( Substr( cSyntax, 7 ) ) + cType += " " + Upper( Left( cSyntax, ( n := At( " ", cSyntax ) ) - 1 ) ) + cSyntax := LTrim( Substr( cSyntax, n + 1 ) ) + + ELSEIF cType = "DLL" + cSyntax := LTrim( Substr( cSyntax, 4 ) ) + cType += " " + Upper( Left( cSyntax, ( n := At( " ", cSyntax ) ) - 1 ) ) + cSyntax := LTrim( Substr( cSyntax, n + 1 ) ) + + ELSEIF cType = "DLL32" + cSyntax := LTrim( Substr( cSyntax, 6 ) ) + cType += " " + Upper( Left( cSyntax, ( n := At( " ", cSyntax ) ) - 1 ) ) + cSyntax := LTrim( Substr( cSyntax, n + 1 ) ) + + ELSEIF cType == "CLASS" + cSyntax := LTrim( SubStr( cSyntax, 7 ) ) + ELSE + cSyntax := lTrim( SubStr( cSyntax, Len( cType ) + 1 ) ) + ENDIF + + IF ( n := RAt( "(", cSyntax ) ) > 0 + cName := Trim( Left( cSyntax, n-1 ) ) + FOR m := Len( cName ) TO 1 STEP -1 + IF ( ! substr( cName, m, 1 ) $ cGoodFuncNameChars ) + EXIT + ENDIF + NEXT + + IF m > 0 + cType += " " + Left( cSyntax, m - 1 ) + cSyntax := SubStr( cSyntax, m + 1 ) + cName := SubStr( cName, m + 1 ) + ENDIF + + IF cType = "METH" + IF ( n := Rat( " CLASS ", cSyntax ) ) > 0 + cClassName := Upper( AllTrim( Substr( cSyntax, n + 7 ) ) ) + ELSE + cClassName := cClassName + ENDIF + ENDIF + + ELSEIF cType = "METH" + IF ( n := Rat( " CLASS ", cSyntax ) ) > 0 + cName := Left( cSyntax, n - 1 ) + cClassName := Upper( AllTrim( Substr( cSyntax, n + 7 ) ) ) + ELSE + cName := cSyntax + cClassName := cClassName + ENDIF + ELSE + cName := cSyntax + ENDIF + + IF cType == "CLASS" + cClassName := Upper( cName ) + cClassName := Left( cClassName, At( " ", cClassName + " " ) - 1 ) // remove INHERIT + ENDIF + + ENDIF + + IF !aSumData[ i,1 ] // not commented out ! + aAdd( aTags, { Upper( Trim( cName ) ) ,; + IF( cType = "METH", IF( !Empty( cClassName ), cClassName + ":" + Upper( cType ), Upper( cType ) ), Upper( cType ) ),; + aSumData[ i,2 ],; + cModule ,; + cSyntax ,; + 0 ,; + cSource ; + }; + ) + ENDIF + + AAdd( aFuncList, { Iif( cType = "METH", ":", "" ) + cSyntax, aSumData[ i, 2 ], aSumData[ i, 1 ] } ) + AAdd( aLines, i ) + NEXT + + RETURN aTags + +/*----------------------------------------------------------------------*/ + +FUNCTION Summarize( aText, cComments, aSumData, nFileType ) + LOCAL cline, i,j, n, c, a, aSummary + LOCAL cCLine := "" + LOCAL lInComment := .F. + LOCAL lInClass := .F. + LOCAL nLine := 1 + LOCAL nType := nFileType + LOCAL nNest := 0 + + aSummary := {} + aSumData := {} + n := Len( aText ) + + FOR i := 1 TO n + cline := Upper( AllTrim( aText[ i ] ) ) + + IF nType == 9 .OR. nType == 10 // PRG code + + IF ! lInClass .OR. ( cLine = "METH" ) + IF cline = 'FUNCTION ' .OR. ; + cline = 'PROCEDURE ' .OR. ; + cline = 'STATIC PROCEDURE ' .OR. ; + cline = 'STATIC FUNCTION ' .OR. ; + cline = 'DLL FUNC' .OR. ; + cline = 'DLL32 FUNC' .OR. ; + cline = 'METHOD ' .OR. ; + cline = 'FUNC ' .OR. ; + cline = 'PROC ' .OR. ; + cLine = 'METH ' .OR. ; + cline = 'STATIC PROC ' .OR. ; + cline = 'STATIC FUNC ' .OR. ; + cline = 'INIT FUNC' .OR. ; + cline = 'INIT PROC' .OR. ; + cline = 'EXIT FUNC' .OR. ; + cline = 'EXIT PROC' .OR. ; + cline = 'CLASS ' .OR. ; + cline = 'INIT CLASS ' + + // check for multiline declaration + a := ParsExpr( aText[ i ], .F., , , .F. ) + c := "" + AEval( a, {|x| c += x } ) + c := AllTrim( c ) + nLine := i + + DO WHILE Right( c, 1 ) == ";" + i++ + c := Left( c, Len( c ) - 1 ) + a := ParsExpr( aText[ i ] + " ", .F. , , ,.F. ) + AEval( a,{|x| c += x } ) + c := AllTrim( c ) + ENDDO + + IF lInClass + IF cLine = 'METH' + IF " INLINE " $ Upper( c ) + c := Trim( Left( c, At( " INLINE ", Upper( c ) ) ) ) + ELSE + LOOP + ENDIF + ENDIF + ENDIF + + IF ( j := At( ";", c ) ) > 0 + c := Left( c, j-1 ) + ENDIF + + lInComment := ( Asc( substr( cComments, nLine, 1 ) ) == 3 ) + aAdd( aSumData, { lInComment, nLine } ) + aAdd( aSummary, Str( nLine, 5, 0 ) + ': ' + c ) + + IF ! lInClass + lInClass := ( cline = 'CLASS ' ) + ENDIF + ELSEIF cLine = "#PRAGMA BEGINDUMP" + nType := 1 + nNest := 0 + ccLine := "" + ENDIF + ELSE + lInClass := ( cline # 'END' ) + ENDIF + + ELSE // C code + + IF cLine = "#PRAGMA ENDDUMP" + nType := nFileType + ELSE + IF nNest == 0 + IF .F. + nLine := i + a := ParsExpr( aText[ i ], .F., @lInComment , , .F., .F. ) + ccLine := "" + c := "" + + AEval( a, {|x| c += x, nNest := Max( 0, nNest + IIf( x == "{", 1, IIf( x == "}", -1, 0 ) ) ) } ) + ccLine := AllTrim( c ) + ELSE + IF ! Empty( cLine ) + a := ParsExpr( aText[ i ], .F. , @lInComment, , .F., .F. ) + c := "" + IF Len( a ) > 0 .AND. a[ 1 ] == "#" + ccLine := "" + nLine := i+1 + ELSE + AEval( a, {|x| IIf( x == ";", ( nLine := i+1, ccLine :="", c := "" ), c += x ), nNest := Max( 0, nNest + IIf( x == "{", 1, IIf( x == "}", -1, 0 ) ) ) } ) + ENDIF + IF !lInComment .AND. ! Empty(c) + ccLine += AllTrim( c ) + " " + ccLine := StrTran( ccLine, ") {", "){" ) + ENDIF + ELSE + nLine := i+1 + ENDIF + ENDIF + + IF "){" $ ccLine // this is a function call + ccline := Left( ccline, At( "){", ccline ) ) + aAdd( aSumData, { lInComment, nLine } ) + aAdd( aSummary, Str( nLine, 5, 0 ) + ': ' + ccline ) //lTrim( ::aText[ i ] ) ) + ccLine := "" + ENDIF + + ELSE + a := ParsExpr( aText[ i ], .F. , @lInComment, , .F., .F.) + AEval( a,{|x| nNest := Max( 0, nNest + IIf( x == "{", 1, IIf( x == "}", -1, 0 ) ) ) } ) + ccLine := "" + nLine := i+1 + ENDIF + ENDIF + ENDIF + NEXT + + RETURN( aSummary ) + +/*----------------------------------------------------------------------*/ + +FUNCTION ReadSource( cTxtFile ) + LOCAL cLine, nHandle, aTxt :={} + + if ( nHandle := fopen( cTxtFile ) ) != -1 + do WHILE ( hb_fReadLine( nHandle, @cLine ) == 0 ) + aadd( aTxt, cLine ) + enddo + aadd( aTxt, cLine ) + fclose( nHandle ) + endif + + RETURN aTxt + +/*----------------------------------------------------------------------*/ +/* + updates comments of the whole file or down from line nline (if supplied) + comment nState codes: + + start commented => 1 + leave commented => 2 + unchanged but contains comment code => 4 +*/ +FUNCTION CheckComments( aText ) + LOCAL i, j, lChanged, nState, cText, nPos, cQuote, lInString + LOCAL lInComment := .F. + LOCAL lLineComment := .F. + LOCAL cComments := "" + LOCAL nLine := 1 + LOCAL nLines := Len( aText ) + + cComments := Pad( cComments, nLines, chr( 0 ) ) + + FOR i := nLine TO nLines + + nState := if( lInComment, 1, 0 ) + lChanged := .F. + cText := aText[ i ] + + IF "*" $ cText .OR. "/" $ cText // quick test + nPos := 0 + + DO WHILE .T. + + // check if terminated + IF lInComment + IF ( nPos := At( "*/", cText ) ) > 0 + lChanged := .T. + lInComment := .F. + cText := SubStr( cText, nPos + 2 ) + ENDIF + ENDIF + + // check for comment start + IF !lInComment + DO WHILE ( nPos := hb_at( "//", cText, nPos+1 ) ) > 0 // is the line commented out ? + IF ! IsInString( cText, nPos, 1 ) // or is it just part of the string ? + cText := Left( cText, nPos - 1 ) + + IF Empty( cText ) + lInComment := .T. + lLineComment := .T. + ENDIF + + EXIT + ENDIF + ENDDO + ENDIF + + IF ( nPos := At( "/*", cText ) ) > 0 // does start of comment exits on that line + + IF ( lInstring := IsInString( cText, nPos, 1, @cQuote ) ) + + // find the end of the string + FOR j := nPos+1 TO Len( cText ) + IF substr( cText, j, 1 ) == cQuote + cText := SubStr( cText, j + 1 ) + nPos := At( "/*", cText ) + lInString := .F. + EXIT + ENDIF + NEXT + IF j > Len( cText ) .AND. lInString + cText := "" + ENDIF + + ELSE + lChanged := .T. + lInComment := .T. + cText := Substr( cText, nPos + 2 ) + ENDIF + + ENDIF + + IF nPos == 0 .OR. Empty( cText ) + EXIT + ENDIF + ENDDO + ENDIF + + cComments := substr( cComments, 1, i-1 ) + chr( nState + ( If( lInComment, 2, 0 ) + If( lChanged, 4, 0 ) ) ) + substr( cComments, i+1 ) + IF nState == 0 .AND. lLineComment + lInComment := .F. + ENDIF + lLineComment := .F. + + NEXT + + RETURN ( cComments ) + +/*----------------------------------------------------------------------*/ + +STATIC FUNCTION IsInString( cText, nPos, nStart, cQuote ) + LOCAL j, cTkn + LOCAL lInString := .F. + + STATIC cAnyQuote := '"' + "'" + + FOR j := nStart TO nPos-1 // check if string did not begin before it + cTkn := substr( cText, j, 1 ) + IF cTkn $ cAnyQuote // any quote characters present ? + IF lInstring // if we are already in string + IF cTkn == cQuote // is it a matching quote ? + lInstring := .F. // yes, we are no in string any more + ENDIF + ELSE // we are not in string yet + cQuote := cTkn // this is the streing quote + lInstring := .T. // now we are in string + ENDIF + ENDIF + NEXT + + RETURN ( lInString ) + +/*----------------------------------------------------------------------*/ + diff --git a/harbour/contrib/hbqt/hbqt.ch b/harbour/contrib/hbqt/hbqt.ch index 9d314d644f..498f4288ec 100644 --- a/harbour/contrib/hbqt/hbqt.ch +++ b/harbour/contrib/hbqt/hbqt.ch @@ -2159,6 +2159,16 @@ #define QTabWidget_Rounded 0 // The tabs are drawn with a rounded look. This is the default shape. #define QTabWidget_Triangular 1 // The tabs are drawn with a triangular look. +#define QTextDocument_FindBackward 0x00001 // Search backwards instead of forwards. +#define QTextDocument_FindCaseSensitively 0x00002 // By default find works case insensitive. Specifying this option changes the behaviour to a case sensitive find operation. +#define QTextDocument_FindWholeWords 0x00004 // Makes find match only complete words. +#define QTextDocument_DocumentTitle 0 // The title of the document. +#define QTextDocument_DocumentUrl 1 // The url of the document. The loadResource() function uses this url as the base when loading relative resources. +#define QTextDocument_HtmlResource 1 // The resource contains HTML. +#define QTextDocument_ImageResource 2 // The resource contains image data. Currently supported data types are QVariant::Pixmap and QVariant::Image. If the corresponding variant is of type QVariant::ByteArray then Qt attempts to load the image using QImage::loadFromData. QVariant::Icon is currently not supported. The icon needs to be converted to one of the supported types first, for example using QIcon::pixmap. +#define QTextDocument_StyleSheetResource 3 // The resource contains CSS. +#define QTextDocument_UserResource 100 // The first available value for user defined resource types. + /*----------------------------------------------------------------------*/ #define _HBQT_CH diff --git a/harbour/contrib/hbqt/hbqt_destruct.cpp b/harbour/contrib/hbqt/hbqt_destruct.cpp index 36e2d880e9..57bed118ce 100644 --- a/harbour/contrib/hbqt/hbqt_destruct.cpp +++ b/harbour/contrib/hbqt/hbqt_destruct.cpp @@ -121,6 +121,16 @@ HB_FUNC( HBQT_SET_RELEASE_METHOD ) hb_retni( s_iObjectReleaseMethod ); } +HB_FUNC( HBQT_QTPTR_FROM_GCPOINTER ) +{ + QGC_POINTER * p = ( QGC_POINTER * ) hb_parptrGC( gcFuncs(), 1 ); + + if( p && p->ph ) + { + hb_retptr( p->ph ); + } +} + #if defined( __HB_DEBUG__ ) #if defined( HB_OS_WIN ) @@ -134,12 +144,12 @@ void hbqt_debug( const char * sTraceMsg, ... ) { char buffer[ 1024 ]; va_list ap; - + va_start( ap, sTraceMsg ); hb_vsnprintf( buffer, sizeof( buffer ), sTraceMsg, ap ); va_end( ap ); - #if defined( UNICODE ) + #if defined( UNICODE ) { LPTSTR lpOutputString = HB_TCHAR_CONVTO( buffer ); OutputDebugString( lpOutputString ); @@ -194,7 +204,7 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX pmc.cb = sizeof(pmc); if( GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof( pmc ) ) ) #if (_WIN32_WINNT >= 0x0501) - size = ( int ) pmc.PrivateUsage / 1024; + size = ( int ) pmc.PrivateUsage / 1024; #else size = ( int ) pmc.WorkingSetSize / 1024; #endif diff --git a/harbour/contrib/hbxbp/xbptabpage.prg b/harbour/contrib/hbxbp/xbptabpage.prg index a73d8156a9..2ddf30ff35 100644 --- a/harbour/contrib/hbxbp/xbptabpage.prg +++ b/harbour/contrib/hbxbp/xbptabpage.prg @@ -281,34 +281,38 @@ METHOD XbpTabWidget:configure( oParent, oOwner, aPos, aSize, aPresParams, lVisib /*----------------------------------------------------------------------*/ METHOD XbpTabWidget:destroy() -//HBXBP_DEBUG( " XbpTabWidget:destroy()",0 ) ::oParent:oTabWidget := NIL -// ::disconnect() - ::xbpWindow:destroy() -//HBXBP_DEBUG( " XbpTabWidget:destroy()",1 ) + RETURN NIL /*----------------------------------------------------------------------*/ METHOD XbpTabWidget:exeBlock( nMode, iIndex ) + LOCAL qTab, nIndex, oTab IF !empty( ::aChildren ) .and. iIndex >= 0 .and. iIndex < len( ::aChildren ) - DO CASE - CASE nMode == 1 - HBXBP_DEBUG( "Tab Clicked", iIndex ) - IF hb_isBlock( ::aChildren[ iIndex+1 ]:sl_tabActivate ) - eval( ::aChildren[ iIndex+1 ]:sl_tabActivate, NIL, NIL, ::aChildren[ iIndex+1 ] ) - ENDIF + qTab := ::oWidget:widget( iIndex ) - CASE nMode == 2 - HBXBP_DEBUG( "Tab Close Requested", iIndex ) - IF hb_isBlock( ::aChildren[ iIndex+1 ]:sl_closeRequested ) - eval( ::aChildren[ iIndex+1 ]:sl_closeRequested, NIL, NIL, ::aChildren[ iIndex+1 ] ) - ENDIF + IF ( nIndex := ascan( ::aChildren, {|o| HBQT_QTPTR_FROM_GCPOINTER( o:oWidget:pPtr ) == qTab } ) ) > 0 + oTab := ::aChildren[ nIndex ] - ENDCASE + DO CASE + CASE nMode == 1 + HBXBP_DEBUG( "Tab Index Changed", nIndex ) + IF hb_isBlock( oTab:sl_tabActivate ) + eval( oTab:sl_tabActivate, NIL, NIL, oTab ) + ENDIF + + CASE nMode == 2 + HBXBP_DEBUG( "Tab Close Requested", nIndex ) + IF hb_isBlock( oTab:sl_closeRequested ) + eval( oTab:sl_closeRequested, NIL, NIL, oTab ) + ENDIF + + ENDCASE + ENDIF ENDIF RETURN nil