Files
harbour-core/harbour/contrib/hbide/functions.prg
Viktor Szakats 96a2b2dd49 2012-07-23 17:38 UTC+0200 Viktor Szakats (harbour syenar.net)
+ contrib/hbide/actions.prg
  + contrib/hbide/browse.prg
  + contrib/hbide/changelog.prg
  + contrib/hbide/console.prg
  + contrib/hbide/dict.prg
  + contrib/hbide/docks.prg
  + contrib/hbide/docwriter.prg
  + contrib/hbide/edit.prg
  + contrib/hbide/editor.prg
  + contrib/hbide/environ.prg
  + contrib/hbide/findreplace.prg
  + contrib/hbide/format.prg
  + contrib/hbide/functions.prg
  + contrib/hbide/harbourhelp.prg
  + contrib/hbide/home.prg
  + contrib/hbide/main.prg
  + contrib/hbide/misc.prg
  + contrib/hbide/object.prg
  + contrib/hbide/parseexpr.c
  + contrib/hbide/plugins.prg
  + contrib/hbide/projectwizard.prg
  + contrib/hbide/projmanager.prg
  + contrib/hbide/saveload.prg
  + contrib/hbide/shortcuts.prg
  + contrib/hbide/skeletons.prg
  + contrib/hbide/sources.prg
  + contrib/hbide/stylesheets.prg
  + contrib/hbide/tags.prg
  + contrib/hbide/themes.prg
  + contrib/hbide/tools.prg
  + contrib/hbide/uisrcmanager.prg
  + contrib/hbide/wizard.prg
  - contrib/hbide/ideactions.prg
  - contrib/hbide/idebrowse.prg
  - contrib/hbide/idechangelog.prg
  - contrib/hbide/ideconsole.prg
  - contrib/hbide/idedict.prg
  - contrib/hbide/idedocks.prg
  - contrib/hbide/idedocwriter.prg
  - contrib/hbide/ideedit.prg
  - contrib/hbide/ideeditor.prg
  - contrib/hbide/ideenviron.prg
  - contrib/hbide/idefindreplace.prg
  - contrib/hbide/ideformat.prg
  - contrib/hbide/idefunctions.prg
  - contrib/hbide/ideharbourhelp.prg
  - contrib/hbide/idehome.prg
  - contrib/hbide/idemain.prg
  - contrib/hbide/idemisc.prg
  - contrib/hbide/ideobject.prg
  - contrib/hbide/ideparseexpr.c
  - contrib/hbide/ideplugins.prg
  - contrib/hbide/ideprojectwizard.prg
  - contrib/hbide/ideprojmanager.prg
  - contrib/hbide/idesaveload.prg
  - contrib/hbide/ideshortcuts.prg
  - contrib/hbide/ideskeletons.prg
  - contrib/hbide/idesources.prg
  - contrib/hbide/idestylesheets.prg
  - contrib/hbide/idetags.prg
  - contrib/hbide/idethemes.prg
  - contrib/hbide/idetools.prg
  - contrib/hbide/ideuisrcmanager.prg
  - contrib/hbide/idewizard.prg
  * contrib/hbide/hbide.hbp
    * deleted 'ide' prefix from all source files
2012-07-23 15:42:26 +00:00

690 lines
19 KiB
Plaintext

/*
* $Id$
*/
/*
* Harbour Project source code:
*
* Copyright 2010 Pritpal Bedi <pritpal@vouchcac.com>
* www - http://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 <pritpal@vouchcac.com>
* 06Mar2010
*/
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
#include "hbide.ch"
#include "common.ch"
#include "hbclass.ch"
#include "xbp.ch"
#include "hbqtgui.ch"
/*----------------------------------------------------------------------*/
#define FLIST_NAME 1
#define FLIST_TYPE 2
#define FLIST_LINE 3
#define FLIST_SOURCE 4
#define FLIST_NAME_1 5
#define FLIST_TYPE_1 6
#define FLIST_SYNTAX 7
/*----------------------------------------------------------------------*/
#define __editFunc_textChanged__ 2001
#define __editFunc_returnPressed__ 2002
#define __buttonMark_clicked__ 2003
#define __buttonLoad_clicked__ 2004
#define __buttonTag_clicked__ 2005
#define __buttonClose_clicked__ 2006
#define __tableFuncList_itemSelectionChanged__ 2007
#define __tableFuncList_itemDoubleClicked__ 2008
/*----------------------------------------------------------------------*/
CLASS IdeFunctions INHERIT IdeObject
DATA isNotSetYet INIT .t.
DATA aHdr INIT {}
DATA aItems INIT {}
DATA aTags INIT { { "", {} } }
DATA aList INIT {}
DATA inAction INIT .f.
DATA nPNm INIT 25
DATA nPPr INIT 15
DATA nPSr INIT 50
DATA aProjList INIT {}
METHOD new( oIde )
METHOD create( oIde )
METHOD destroy()
METHOD clear( lHdrAlso )
METHOD show()
METHOD tagProject( cProjectTitle )
METHOD populateTable()
METHOD consolidateList()
METHOD buildHeader()
METHOD execEvent( nEvent, p )
METHOD openFunction( lCheckDuplicates )
METHOD jumpToFunction( cWord )
METHOD positionToFunction( cWord, lShowTip )
METHOD buildTags()
METHOD loadTags( aProjects )
METHOD listProjects()
METHOD clearProjects()
METHOD getMarkedProjects()
METHOD enableControls( lEnable )
METHOD getFunctionPrototypes()
ENDCLASS
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:new( oIde )
::oIde := oIde
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:create( oIde )
DEFAULT oIde TO ::oIde
::oIde := oIde
::oUI := hbide_getUI( "funclist" )
::buildHeader()
::oUI:editFunction :connect( "textChanged(QString)" , {|p| ::execEvent( __editFunc_textChanged__ , p ) } )
::oUI:editFunction :connect( "returnPressed()" , {| | ::execEvent( __editFunc_returnPressed__ ) } )
::oUI:buttonMark :connect( "clicked()" , {| | ::execEvent( __buttonMark_clicked__ ) } )
::oUI:buttonLoad :connect( "clicked()" , {| | ::execEvent( __buttonLoad_clicked__ ) } )
::oUI:buttonTag :connect( "clicked()" , {| | ::execEvent( __buttonTag_clicked__ ) } )
::oUI:buttonClose :connect( "clicked()" , {| | ::execEvent( __buttonClose_clicked__ ) } )
::oUI:tableFuncList:connect( "itemSelectionChanged()" , {| | ::execEvent( __tableFuncList_itemSelectionChanged__ ) } )
::oUI:tableFuncList:connect( "itemDoubleClicked(QTableWidgetItem*)", {|p| ::execEvent( __tableFuncList_itemDoubleClicked__, p ) } )
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:execEvent( nEvent, p )
LOCAL n, nLen
IF ::lQuitting
RETURN Self
ENDIF
SWITCH nEvent
CASE __editFunc_textChanged__
p := upper( p )
nLen := Len( p )
IF ( n := ascan( ::aList, {|e_| left( e_[ 1 ], nLen ) == p } ) ) > 0
::oUI:tableFuncList:setCurrentItem( ::aItems[ n ] )
ENDIF
EXIT
CASE __editFunc_returnPressed__
::openFunction( .f. )
EXIT
CASE __tableFuncList_itemDoubleClicked__
::openFunction( .f. )
EXIT
CASE __buttonMark_clicked__
::oUI:listProjects:show()
::listProjects()
EXIT
CASE __buttonLoad_clicked__
::oUI:listProjects:hide()
::loadTags()
EXIT
CASE __buttonTag_clicked__
::oUI:listProjects:hide()
::buildTags()
::oEM:updateCompleter()
EXIT
CASE __buttonClose_clicked__
::oFunctionsDock:hide()
EXIT
CASE __tableFuncList_itemSelectionChanged__
n := ::oUI:tableFuncList:currentRow()
IF n >= 0
::oUI:editSyntax:setText( ::aList[ n + 1, 2 ] )
ENDIF
EXIT
ENDSWITCH
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:buildHeader()
LOCAL oTbl, qItm, cHdr, qFnt, qHdr
LOCAL cDH := " "
oTbl := ::oUI:tableFuncList
qFnt := QFont( "Courier New" )
oTbl:setFont( qFnt )
oTbl:verticalHeader():hide()
qHdr := oTbl:horizontalHeader()
qHdr:setStretchLastSection( .t. )
oTbl:setColumnCount( 1 )
cHdr := pad( "Name", ::nPNm ) + cDH + "Typ " + cDH + " Line" + cDH + ;
pad( "Project", ::nPPr ) + cDH + pad( "Source", ::nPSr )
qItm := QTableWidgetItem()
qItm:setText( cHdr )
qItm:setFont( qFnt )
qItm:setTextAlignment( Qt_AlignLeft )
aadd( ::aHdr, qItm )
oTbl:setHorizontalHeaderItem( 0, qItm )
oTbl:setColumnWidth( 0, 800 )
oTbl:setShowGrid( .f. )
oTbl:setAlternatingRowColors( .t. )
::oUI:listProjects:hide()
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:destroy()
LOCAL qitm
IF !empty( ::oUI )
::clearProjects()
FOR EACH qItm IN ::aHdr
qItm := NIL
NEXT
::aHdr := {}
::clear( .t. )
::oUI:destroy()
ENDIF
::isNotSetYet := NIL
::aHdr := NIL
::aItems := NIL
::aTags := NIL
::aList := NIL
::inAction := NIL
::nPNm := NIL
::nPPr := NIL
::nPSr := NIL
::aProjList := NIL
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:clear( lHdrAlso )
LOCAL qItm
IF lHdrAlso
FOR EACH qItm IN ::aHdr
qItm := NIL
NEXT
::aHdr := {}
ENDIF
FOR EACH qItm IN ::aItems
qItm := NIL
NEXT
::aItems := {}
IF lHdrAlso
::oUI:tableFuncList:clear()
ELSE
::oUI:tableFuncList:clearContents()
ENDIF
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:show()
IF ::isNotSetYet
::isNotSetYet := .f.
::oFunctionsDock:oWidget:setWidget( ::oUI:oWidget )
ENDIF
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:positionToFunction( cWord, lShowTip )
LOCAL nLen, p, n, cProto := ""
IF !empty( ::aList )
p := upper( cWord )
nLen := Len( p )
IF ( n := ascan( ::aList, {|e_| left( e_[ 1 ], nLen ) == p } ) ) > 0
::oUI:editFunction:setText( cWord )
::oUI:tableFuncList:setCurrentItem( ::aItems[ n ] )
cProto := ::aList[ n, 2 ]
IF lShowTip
// TODO: where
ENDIF
ENDIF
ENDIF
RETURN cProto
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:jumpToFunction( cWord )
LOCAL nLen, lOpened := .f., p, n
IF !empty( ::aList )
p := upper( cWord )
nLen := Len( p )
IF ( n := ascan( ::aList, {|e_| left( e_[ 1 ], nLen ) == p } ) ) > 0
::oUI:editFunction:setText( cWord )
::oUI:tableFuncList:setCurrentItem( ::aItems[ n ] )
lOpened := ::openFunction( .t. )
ENDIF
ENDIF
RETURN lOpened
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:openFunction( lCheckDuplicates )
LOCAL n, cFunc, cSource, oEdit, lFound, cProto
LOCAL lOpened := .f.
IF ( n := ::oUI:tableFuncList:currentRow() ) >= 0
n++
cFunc := ::aList[ n, 1 ]
IF lCheckDuplicates .AND. n < Len( ::aList ) .AND. ::aList[ n + 1, 1 ] == cFunc
::oFunctionsDock:show()
::oUI:tableFuncList:setFocus()
RETURN lOpened
ENDIF
cProto := ::aList[ n, 2 ]
cSource := alltrim( substr( ::aList[ n, 3 ], 53 ) )
::oSM:editSource( cSource, , , , , , .f. )
IF !empty( oEdit := ::oEM:getEditCurrent() )
IF !( lFound := oEdit:find( cProto, QTextDocument_FindCaseSensitively ) )
lFound := oEdit:find( cProto, QTextDocument_FindBackward + QTextDocument_FindCaseSensitively )
ENDIF
IF lFound
oEdit:centerCursor()
lOpened := .t.
ELSE
HB_TRACE( HB_TR_DEBUG, "IdeFunctions:openFunction()", "It should not happen." )
ENDIF
ENDIF
ENDIF
RETURN lOpened
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:clearProjects()
LOCAL qItm
IF !empty( ::aProjList )
FOR EACH qItm IN ::aProjList
qItm := NIL
NEXT
ENDIF
::aProjList := {}
::oUI:listProjects:clear()
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:listProjects()
LOCAL s, qItm, oLst := ::oUI:listProjects
::clearProjects()
FOR EACH s IN ::oPM:getProjectsTitleList()
qItm := QListWidgetItem()
qItm:setText( s )
qItm:setCheckState( Qt_Unchecked )
//oLst:addItem_1( qItm )
oLst:addItem( qItm )
aadd( ::aProjList, qItm )
NEXT
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:getMarkedProjects()
LOCAL qItm, a_:= {}
FOR EACH qItm IN ::aProjList
IF qItm:checkState() == 2
aadd( a_, qItm:text() )
ENDIF
NEXT
RETURN a_
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:enableControls( lEnable )
::inAction := ! lEnable
::oUI:buttonMark:setEnabled( lEnable )
::oUI:buttonLoad:setEnabled( lEnable )
::oUI:buttonTag:setEnabled( lEnable )
::oUI:editFunction:setEnabled( lEnable )
::showApplicationCursor( iif( lEnable, NIL, Qt_BusyCursor ) )
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:loadTags( aProjects )
LOCAL cProjectTitle, cProjFile, cTagFile, aTags, n, a_
LOCAL lPopulate := .f.
LOCAL qApp := QApplication()
DEFAULT aProjects TO ::getMarkedProjects()
IF empty( aProjects )
RETURN Self
ENDIF
a_:= aProjects
IF !( ::inAction )
::enableControls( .f. )
FOR EACH cProjectTitle IN a_
cProjFile := ::oPM:getProjectFileNameFromTitle( cProjectTitle )
IF ! empty( cProjFile ) .AND. hb_fileExists( cProjFile )
cTagFile := hb_FNameExtSet( cProjFile, ".tag" )
IF hb_fileExists( cTagFile )
lPopulate := .t.
aTags := hb_deserialize( hb_memoRead( cTagFile ) )
IF ( n := ascan( ::aTags, {|e_| e_[ 1 ] == cProjectTitle } ) ) == 0
aadd( ::aTags, { cProjectTitle, aTags } )
ELSE
::aTags[ n, 2 ] := aTags
ENDIF
ENDIF
ENDIF
qApp:processEvents()
IF ::lQuitting
EXIT
ENDIF
NEXT
IF lPopulate
::consolidateList()
::populateTable()
ENDIF
::enableControls( .t. )
ENDIF
::clearProjects()
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:buildTags()
LOCAL cProjectTitle
LOCAL a_:= ::getMarkedProjects()
IF !empty( a_ )
FOR EACH cProjectTitle IN a_
::tagProject( cProjectTitle )
NEXT
::oIde:oINI:aTaggedProjects := a_
::clearProjects()
ENDIF
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:tagProject( cProjectTitle )
LOCAL aSumData := ""
LOCAL cComments, aSummary, cPath, cSource, cExt, aTags, aText, aFuncList, aLines
LOCAL cProjFile, cRoot, aCTags, aSources, cSrc, a_, n
LOCAL qApp := QApplication()
IF !( ::inAction )
::enableControls( .f. )
cProjFile := ::oPM:getProjectFileNameFromTitle( cProjectTitle )
aSources := ::oPM:getSourcesByProjectTitle( cProjectTitle )
cRoot := ::oPM:getProjectPathFromTitle( cProjectTitle )
FOR EACH cSource IN aSources
aSources[ cSource:__enumIndex() ] := hbide_syncProjPath( cRoot, cSource )
NEXT
aCTags := {}
FOR EACH cSrc IN aSources
aFuncList := {}
aLines := {}
HB_FNameSplit( cSrc, @cPath, @cSource, @cExt )
IF upper( cExt ) $ ".PRG.CPP"
IF !empty( aText := hbide_readSource( cSrc ) )
aSumData := {}
cComments := CheckComments( aText )
aSummary := Summarize( aText, cComments, @aSumData , iif( upper( cExt ) == ".PRG", 9, 1 ) )
aTags := UpdateTags( cSrc, aSummary, aSumData, @aFuncList, @aLines, aText )
IF !empty( aTags )
aeval( aTags, {|e_| aadd( aCTags, { e_[1],e_[2],e_[3],e_[4],e_[7] } ) } )
ENDIF
ENDIF
ENDIF
qApp:processEvents()
IF ::lQuitting
EXIT
ENDIF
NEXT
FOR EACH a_ IN aCTags
a_[ 5 ] := iif( left( a_[ 5 ], 1 ) == ":", substr( a_[ 5 ], 2 ), a_[ 5 ] )
NEXT
IF ( n := ascan( ::aTags, {|e_| e_[ 1 ] == cProjectTitle } ) ) == 0
aadd( ::aTags, { cProjectTitle, aCTags } )
ELSE
::aTags[ n, 2 ] := aCTags
ENDIF
hb_memowrit( hb_FNameExtSet( cProjFile, ".tag" ), hb_serialize( aCTags ) )
::consolidateList()
::populateTable()
::enableControls( .t. )
ENDIF
RETURN cProjFile
//----------------------------------------------------------------------//
METHOD IdeFunctions:consolidateList()
LOCAL s, a_, b_, cProjectTitle
LOCAL cDL := " "
::aList := {}
FOR EACH b_ IN ::aTags
IF !empty( cProjectTitle := b_[ 1 ] )
FOR EACH a_ IN b_[ 2 ]
s := pad( a_[ 1 ], ::nPNm ) + ;
cDL + ;
hbide_abbrFuncType( a_[ 2 ] ) + ;
cDL + ;
padl( ltrim( str( a_[ 3 ] ) ), 6 ) + ;
cDL + ;
pad( cProjectTitle, ::nPPr ) + ;
cDL + ;
pad( a_[ 4 ], ::nPSr )
aadd( ::aList, { a_[ 1 ], a_[ 5 ], s } )
NEXT
ENDIF
NEXT
IF !empty( ::aList )
asort( ::aList, , , {|e_,f_| e_[ 1 ] < f_[ 1 ] } )
ENDIF
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:populateTable()
LOCAL oTbl, qItm, a_, n
LOCAL qApp := QApplication()
::clear( .t. )
::buildHeader()
oTbl := ::oUI:tableFuncList
oTbl:setRowCount( Len( ::aList ) )
n := 0
FOR EACH a_ IN ::aList
qItm := QTableWidgetItem()
qItm:setText( a_[ 3 ] )
qItm:setTooltip( a_[ 2 ] )
oTbl:setItem( n, 0, qItm )
oTbl:setRowHeight( n, 16 )
qApp:processEvents()
IF ::lQuitting
EXIT
ENDIF
aadd( ::aItems, qItm )
n++
::oUI:labelEntries:setText( "Entries: " + hb_ntos( n ) )
NEXT
RETURN Self
/*----------------------------------------------------------------------*/
METHOD IdeFunctions:getFunctionPrototypes()
LOCAL aProto := {}, a_
FOR EACH a_ IN ::aList
aadd( aProto, alltrim( a_[ 2 ] ) )
NEXT
RETURN aProto
/*----------------------------------------------------------------------*/
STATIC FUNCTION hbide_abbrFuncType( cFunc )
LOCAL cAbbr := ""
IF "STATIC" $ cFunc
cAbbr += "S"
ENDIF
IF "FUNC" $ cFunc
cAbbr += "F"
ENDIF
IF "PROC" $ cFunc
cAbbr += "P"
ENDIF
IF "HB_" $ cFunc
cAbbr += ":C"
ENDIF
IF "CLASS" $ cFunc
cAbbr += "C"
ENDIF
IF "METHOD" $ cFunc
cAbbr += "M"
IF ":" $ cFunc
cAbbr += ":D"
ENDIF
ENDIF
RETURN padc( cAbbr, 3 )
/*----------------------------------------------------------------------*/