/* * $Id$ */ /* * Harbour Project source code: * * Copyright 2009-2010 Pritpal Bedi * 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 * 03Jan2010 */ /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ #include "hbide.ch" #include "hbqtgui.ch" #include "common.ch" #include "hbclass.ch" /*----------------------------------------------------------------------*/ // // Class IdeSource // /*----------------------------------------------------------------------*/ CLASS IdeSource DATA original DATA normalized DATA filter DATA path DATA file DATA ext DATA projPath METHOD new( cSource ) ENDCLASS /*----------------------------------------------------------------------*/ METHOD IdeSource:new( cSource ) LOCAL cFilt, cPathFile, cPath, cFile, cExt cSource := hbide_pathToOSPath( cSource ) hbide_parseHbpFilter( cSource, @cFilt, @cPathFile ) hb_fNameSplit( cPathFile, @cPath, @cFile, @cExt ) ::original := cSource ::normalized := hbide_pathNormalized( cSource, .t. ) ::filter := cFilt ::path := hbide_pathNormalized( cPath, .t. ) ::file := cFile //::ext := lower( cExt ) ::ext := cExt RETURN Self /*----------------------------------------------------------------------*/ // // Class IdeProject // /*----------------------------------------------------------------------*/ CLASS IdeProject DATA aProjProps INIT {} DATA fileName INIT "" DATA normalizedName INIT "" DATA type INIT "Executable" DATA title INIT "" DATA location INIT hb_dirBase() + "projects" DATA destination INIT "" DATA outputName INIT "" DATA backup INIT "" DATA launchParams INIT "" DATA launchProgram INIT "" DATA wrkDirectory INIT "" DATA isXhb INIT .f. DATA isXpp INIT .f. DATA isClp INIT .f. DATA hbpFlags INIT {} DATA sources INIT {} DATA dotHbp INIT "" DATA compilers INIT "" DATA cPathHbMk2 DATA hSources INIT {=>} DATA hPaths INIT {=>} DATA lPathAbs INIT .F. // Lets try relative paths first . xhp and hbp will be relative anyway DATA projPath INIT "" METHOD new( oIDE, aProps ) ENDCLASS /*----------------------------------------------------------------------*/ METHOD IdeProject:new( oIDE, aProps ) LOCAL b_, a_, oSource, cSource IF HB_ISARRAY( aProps ) .AND. !empty( aProps ) ::aProjProps := aProps b_:= aProps a_:= b_[ PRJ_PRP_PROPERTIES, 2 ] ::type := a_[ PRJ_PRP_TYPE ] ::title := a_[ PRJ_PRP_TITLE ] ::location := "" /* See below */ ::wrkDirectory := a_[ PRJ_PRP_WRKFOLDER ] ::destination := a_[ PRJ_PRP_DSTFOLDER ] ::outputName := a_[ PRJ_PRP_OUTPUT ] ::launchParams := a_[ PRJ_PRP_LPARAMS ] ::launchProgram := a_[ PRJ_PRP_LPROGRAM ] ::backup := a_[ PRJ_PRP_BACKUP ] ::isXhb := a_[ PRJ_PRP_XHB ] == "YES" ::isXpp := a_[ PRJ_PRP_XPP ] == "YES" ::isClp := a_[ PRJ_PRP_CLP ] == "YES" ::projPath := oIde:oPM:getProjectPathFromTitle( ::title ) IF empty( ::projPath ) ::projPath := hb_dirBase() /* In case of new project */ ENDIF ::location := ::projPath ::hbpFlags := aclone( b_[ PRJ_PRP_FLAGS , 2 ] ) ::sources := aclone( b_[ PRJ_PRP_SOURCES , 2 ] ) ::dotHbp := "" ::compilers := "" ::cPathHbMk2 := oIde:oINI:getHbmk2File() FOR EACH cSource IN ::sources cSource := hbide_syncProjPath( ::projPath, cSource ) oSource := IdeSource():new( cSource ) oSource:projPath := ::projPath ::hSources[ oSource:normalized ] := oSource ::hPaths[ oSource:path ] := NIL NEXT ENDIF RETURN Self /*----------------------------------------------------------------------*/ // IdeProjectManager /*----------------------------------------------------------------------*/ CLASS IdeProjManager INHERIT IdeObject DATA cargo DATA cSaveTo DATA aPrjProps INIT {} DATA nStarted INIT 0 DATA lLaunch INIT .F. DATA cProjectInProcess INIT "" DATA cPPO INIT "" DATA lPPO INIT .F. DATA oProject DATA cBatch DATA oProcess DATA lSaveOK INIT .F. DATA cProjFileName INIT "" DATA lNew INIT .F. DATA lFetch INIT .T. DATA lUpdateTree INIT .F. DATA cIfError INIT NIL METHOD new( oIDE ) METHOD create( oIDE ) METHOD destroy() METHOD populate() METHOD loadProperties( cProjFileName, lNew, lFetch, lUpdateTree ) METHOD fetchProperties() METHOD getProperties() METHOD sortSources( cMode ) METHOD save( lCanClose ) METHOD updateHbp( iIndex ) METHOD addSources() METHOD setCurrentProject( cProjectName ) METHOD selectCurrentProject() METHOD getCurrentProject( lAlert ) METHOD getCurrentProjectTitle() METHOD getProjectProperties( cProjectTitle ) METHOD getProjectByFile( cProjectFile ) METHOD getProjectByTitle( cProjectTitle ) METHOD getProjectsTitleList() METHOD getProjectFileNameFromTitle( cProjectTitle ) METHOD getProjectTypeFromTitle( cProjectTitle ) METHOD getProjectPathFromTitle( cProjectTitle ) METHOD getSourcesByProjectTitle( cProjectTitle ) METHOD removeProject( cProjectTitle ) METHOD closeProject( cProjectTitle ) METHOD promptForPath( oEditPath, cTitle, cObjFileName ) METHOD buildSource( lExecutable ) METHOD buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) METHOD launchProject( cProject, cExe ) METHOD showOutput( cOutput, mp2, oProcess ) METHOD finished( nExitCode, nExitStatus, oProcess ) METHOD isValidProjectLocation( lTell ) METHOD setProjectLocation( cPath ) METHOD buildInterface() METHOD pullHbpData( cHbp ) METHOD synchronizeAlienProject( cProjFileName ) METHOD outputText( cText ) METHOD runAsScript() METHOD insertHeader( aHdr, aHbp ) METHOD stripHeader( aHbp ) METHOD moveLine( nDirection ) ENDCLASS /*----------------------------------------------------------------------*/ METHOD IdeProjManager:new( oIDE ) ::oIDE := oIDE RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:create( oIDE ) DEFAULT oIDE TO ::oIDE ::oIDE := oIDE RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:destroy() IF !empty( ::oUI ) ::oUI:buttonCn :disconnect( "clicked()" ) ::oUI:buttonSave :disconnect( "clicked()" ) ::oUI:buttonSaveExit :disconnect( "clicked()" ) ::oUI:buttonSelect :disconnect( "clicked()" ) ::oUI:buttonUp :disconnect( "clicked()" ) ::oUI:buttonDown :disconnect( "clicked()" ) // ::oUI:buttonSort :disconnect( "clicked()" ) // ::oUI:buttonSortZA :disconnect( "clicked()" ) // ::oUI:buttonSortOrg :disconnect( "clicked()" ) ::oUI:tabWidget :disconnect( "currentChanged(int)" ) ::oUI:buttonChoosePrjLoc:disconnect( "clicked()" ) ::oUI:buttonChooseWd :disconnect( "clicked()" ) ::oUI:buttonChooseDest :disconnect( "clicked()" ) ::oUI:buttonBackup :disconnect( "clicked()" ) ::oUI:editPrjLoctn :disconnect( "textChanged(QString)" ) ::oUI:destroy() ENDIF IF !empty( ::aPrjProps ) ::aPrjProps[ 1,1 ] := NIL ::aPrjProps[ 1,2 ] := NIL ::aPrjProps[ 1 ] := NIL ::aPrjProps[ 2,1 ] := NIL ::aPrjProps[ 2,2 ] := NIL ::aPrjProps[ 2 ] := NIL ::aPrjProps[ 3,1 ] := NIL ::aPrjProps[ 3,2 ] := NIL ::aPrjProps[ 3 ] := NIL ::aPrjProps[ 4,1 ] := NIL ::aPrjProps[ 4,2 ] := NIL ::aPrjProps[ 4 ] := NIL ::aPrjProps[ 5 ] := NIL ::aPrjProps := NIL ENDIF RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:populate() LOCAL cProject FOR EACH cProject IN ::oINI:aProjFiles ::loadProperties( cProject, .f., .f., .T. ) NEXT RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getProperties() LOCAL cTmp, n cTmp := ::getCurrentProject() IF ( n := ascan( ::aProjects, {|e_| e_[ 3, PRJ_PRP_PROPERTIES, 2, PRJ_PRP_TITLE ] == cTmp } ) ) > 0 ::loadProperties( ::aProjects[ n, 1 ], .f., .t., .t. ) ENDIF RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:loadProperties( cProjFileName, lNew, lFetch, lUpdateTree ) LOCAL nAlready, cProjPath DEFAULT cProjFileName TO "" DEFAULT lNew TO .F. DEFAULT lFetch TO .T. DEFAULT lUpdateTree TO .F. ::cProjFileName := cProjFileName ::lNew := lNew ::lFetch := lFetch ::lUpdateTree := lUpdateTree ::aPrjProps := {} ::cSaveTo := "" ::oProject := NIL IF lNew lFetch := .t. ELSE IF empty( cProjFileName ) cProjFileName := hbide_fetchAFile( ::oDlg, "Open Project...", { { "Harbour Make Projects", "*.hbp" } , ; { "xMate Projects" , "*.xhp" } , ; { "xBuild Projects" , "*.xbp" } } ) cProjFileName := ::synchronizeAlienProject( cProjFileName ) ::oDockPT:show() ENDIF IF empty( cProjFileName ) RETURN Self ENDIF ENDIF cProjFileName := hbide_pathToOSPath( cProjFileName ) ::oIde:oPropertiesDock:setWindowTitle( cProjFileName ) nAlready := ascan( ::aProjects, {|e_| hb_FileMatch( e_[ 1 ], hbide_pathNormalized( cProjFileName ) ) } ) IF !empty( cProjFileName ) .AND. hb_fileExists( cProjFileName ) ::aPrjProps := ::pullHbpData( hbide_pathToOSPath( cProjFileName ) ) ENDIF IF lFetch IF lNew IF empty( cProjPath := hbide_fetchADir( ::oDlg, "Project Path", hbide_SetWrkFolderLast() ) ) RETURN Self ENDIF cProjPath := hbide_pathAppendLastSlash( cProjPath ) hbide_SetWrkFolderLast( cProjPath ) ENDIF /* Access/Assign via this object */ ::oProject := IdeProject():new( ::oIDE, ::aPrjProps ) IF !empty( cProjPath ) ::oProject:location := hbide_pathNormalized( cProjPath, .f. ) ::oProject:projPath := ::oProject:location ENDIF // ::oPropertiesDock:hide() ::oPropertiesDock:show() ELSE IF !empty( ::aPrjProps ) IF nAlready == 0 aadd( ::oIDE:aProjects, { hbide_pathNormalized( cProjFileName ), cProjFileName, aclone( ::aPrjProps ) } ) IF lUpdateTree ::oIDE:updateProjectTree( ::aPrjProps ) ENDIF hbide_mnuAddFileToMRU( ::oIDE, cProjFileName, "recent_projects" ) ELSE ::aProjects[ nAlready, 3 ] := aclone( ::aPrjProps ) IF lUpdateTree ::oIDE:updateProjectTree( ::aPrjProps ) ENDIF ENDIF ENDIF ::oHM:refresh() /* Rearrange Projects Data */ ENDIF RETURN Self /*----------------------------------------------------------------------*/ // // Without user-interface // METHOD IdeProjManager:pullHbpData( cHbp ) LOCAL n, n1, s, cKey, cVal, aOptns, aFiles, c3rd, nL, aData, cHome, cOutName, cType LOCAL aPrp := { ; "hbide_type=" , ; "hbide_title=" , ; "hbide_location=" , ; "hbide_workingfolder=" , ; "hbide_destinationfolder=" , ; "hbide_output=" , ; "hbide_launchparams=" , ; "hbide_launchprogram=" , ; "hbide_backupfolder=" , ; "hbide_xhb=" , ; "hbide_xpp=" , ; "hbide_clp=" , ; "hbide_launchim=" ; } LOCAL a1_0 := afill( array( PRJ_PRP_PRP_VRBLS ), "" ) LOCAL a1_1 := {} LOCAL a2_0 := {} LOCAL a2_1 := {} LOCAL a3_0 := {} LOCAL a3_1 := {} LOCAL a4_0 := {} LOCAL a4_1 := {} LOCAL a3rd := {} hb_fNameSplit( cHbp, @cHome, @cOutName ) cHome := hbide_pathStripLastSlash( cHome ) c3rd := "-3rd=" nL := Len( c3rd ) aData := hbide_fetchHbpData( cHbp ) aOptns := aData[ 1 ] aFiles := aData[ 2 ] FOR EACH s IN aFiles s := hbide_stripRoot( cHome, s ) NEXT IF ( n := ascan( aOptns, {|e| lower( e ) $ "-hbexe,-hblib,-hbdyn" } ) ) > 0 cType := lower( aOptns[ n ] ) cType := iif( cType == "-hblib", "Lib", iif( cType == "-hbdyn", "Dll", "Executable" ) ) ELSE cType := "Executable" ENDIF /* Separate HbIDE specific flags */ FOR EACH s IN aOptns IF ( n := at( c3rd, s ) ) > 0 IF ( n1 := hb_at( " ", s, n ) ) > 0 aadd( a3rd, substr( s, n + nL, n1 - n - nL ) ) s := substr( s, 1, n - 1 ) + substr( s, n1 ) ELSE aadd( a3rd, substr( s, n + nL ) ) s := substr( s, 1, n - 1 ) ENDIF ENDIF NEXT /* PRJ_PRP_PROPERTIES */ FOR EACH s IN a3rd IF ( n := at( "=", s ) ) > 0 cKey := alltrim( substr( s, 1, n ) ) cVal := alltrim( substr( s, n + 1 ) ) IF ( n := ascan( aPrp, {|e| e == cKey } ) ) > 0 a1_0[ n ] := hbide_amp2space( cVal ) ENDIF ENDIF NEXT a1_0[ PRJ_PRP_TYPE ] := iif( empty( a1_0[ PRJ_PRP_TYPE ] ), cType , a1_0[ PRJ_PRP_TYPE ] ) a1_0[ PRJ_PRP_TITLE ] := iif( empty( a1_0[ PRJ_PRP_TITLE ] ), cOutName, a1_0[ PRJ_PRP_TITLE ] ) a1_0[ PRJ_PRP_OUTPUT ] := cOutName a1_0[ PRJ_PRP_LOCATION ] := hbide_pathNormalized( cHome ) /* PRJ_PRP_FLAGS */ FOR EACH s IN aOptns IF !empty( s ) aadd( a2_0, s ) ENDIF NEXT /* PRJ_PRP_SOURCES */ FOR EACH s IN aFiles aadd( a3_0, s ) NEXT /* Check sources which are not compilable but make-up source list */ FOR EACH s IN a3rd IF "hbide_file=" == lower( left( s, 11 ) ) aadd( a3_0, hbide_stripRoot( cHome, alltrim( substr( s, 12 ) ) ) ) ENDIF NEXT /* Properties */ FOR EACH s IN a1_0 aadd( a1_1, s ) NEXT /* Flags */ IF !empty( a2_0 ) FOR EACH s IN a2_0 aadd( a2_1, s ) NEXT ENDIF /* Sources */ IF !empty( a3_0 ) FOR EACH s IN a3_0 IF !( "#" == left( s,1 ) ) .and. !empty( s ) aadd( a3_1, hbide_stripRoot( cHome, hbide_stripFilter( s ) ) ) ENDIF NEXT ENDIF RETURN { { a1_0, a1_1 }, { a2_0, a2_1 }, { a3_0, a3_1 }, { a4_0, a4_1 }, hbide_readSource( cHbp ) } /*----------------------------------------------------------------------*/ METHOD IdeProjManager:save( lCanClose ) LOCAL a_, lOk, txt_, nAlready LOCAL c3rd := "-3rd=" LOCAL hdr_:= {} * Validate certain parameters before continuing ... (vailtom) IF Empty( ::oUI:editPrjTitle:text() ) ::oUI:editPrjTitle:setText( ::oUI:editOutName:text() ) ENDIF IF Empty( ::oUI:editOutName:text() ) MsgBox( 'Invalid Output FileName' ) ::oUI:editOutName:setFocus() RETURN .F. ENDIF /* This must be valid, we cannot skip */ IF !hbide_isValidPath( ::oUI:editPrjLoctn:text(), 'Project Location' ) ::oUI:editPrjLoctn:setFocus() RETURN .F. ENDIF txt_:= {} // aadd( hdr_, c3rd + "hbide_version=" + "1.0" ) // IF ::oUI:comboPrjType:currentIndex() != 0 aadd( hdr_, c3rd + "hbide_type=" + { "Executable", "Lib", "Dll" }[ ::oUI:comboPrjType:currentIndex() + 1 ] ) ENDIF IF ! Empty( ::oUI:editPrjTitle :text() ) aadd( hdr_, c3rd + "hbide_title=" + hbide_space2amp( ::oUI:editPrjTitle :text() ) ) ENDIF IF ! Empty( ::oUI:editWrkFolder :text() ) aadd( hdr_, c3rd + "hbide_workingfolder=" + hbide_space2amp( ::oUI:editWrkFolder :text() ) ) ENDIF IF ! Empty( ::oUI:editDstFolder :text() ) aadd( hdr_, c3rd + "hbide_destinationfolder=" + hbide_space2amp( ::oUI:editDstFolder :text() ) ) ENDIF IF ! Empty( ::oUI:editOutName :text() ) aadd( hdr_, c3rd + "hbide_output=" + hbide_space2amp( ::oUI:editOutName :text() ) ) ENDIF IF ! Empty( ::oUI:editLaunchParams:text() ) aadd( hdr_, c3rd + "hbide_launchparams=" + hbide_space2amp( ::oUI:editLaunchParams:text() ) ) ENDIF IF ! Empty( ::oUI:editLaunchExe :text() ) aadd( hdr_, c3rd + "hbide_launchprogram=" + hbide_space2amp( ::oUI:editLaunchExe :text() ) ) ENDIF IF ! Empty( ::oUI:editBackup :text() ) aadd( hdr_, c3rd + "hbide_backupfolder=" + hbide_space2amp( ::oUI:editBackup :text() ) ) ENDIF IF ::oUI:checkXhb:isChecked() aadd( hdr_, c3rd + "hbide_xhb=" + iif( ::oUI:checkXhb:isChecked(), "YES", "NO" ) ) ENDIF IF ::oUI:checkXpp:isChecked() aadd( hdr_, c3rd + "hbide_xpp=" + iif( ::oUI:checkXpp:isChecked(), "YES", "NO" ) ) ENDIF IF ::oUI:checkClp:isChecked() aadd( hdr_, c3rd + "hbide_clp=" + iif( ::oUI:checkClp:isChecked(), "YES", "NO" ) ) ENDIF a_:= hbide_synchronizeForHbp( hbide_memoToArray( ::oUI:editSources:toPlainText() ) ) a_:= ::insertHeader( hdr_, a_ ) aeval( a_, {|e| aadd( txt_, e ) } ) aadd( txt_, " " ) ::cSaveTo := ::oUI:editPrjLoctn:text() + ::pathSep + ::oUI:editOutName:text() + ".hbp" ::cSaveTo := hbide_pathToOSPath( ::cSaveTo ) IF ( lOk := hbide_createTarget( ::cSaveTo, txt_ ) ) ::aPrjProps := ::pullHbpData( hbide_pathToOSPath( ::cSaveTo ) ) IF ( nAlready := ascan( ::aProjects, {|e_| hb_FileMatch( e_[ 1 ], hbide_pathNormalized( ::cSaveTo ) ) } ) ) == 0 aadd( ::oIDE:aProjects, { hbide_pathNormalized( ::cSaveTo ), ::cSaveTo, aclone( ::aPrjProps ) } ) IF ::lUpdateTree ::oIDE:updateProjectTree( ::aPrjProps ) ENDIF hbide_mnuAddFileToMRU( ::oIDE, ::cSaveTo, "recent_projects" ) ELSE ::aProjects[ nAlready, 3 ] := aclone( ::aPrjProps ) IF ::lUpdateTree ::oIDE:updateProjectTree( ::aPrjProps ) ENDIF ENDIF ::oHM:refresh() /* Rearrange Projects Data */ ELSE MsgBox( 'Error saving project file: ' + ::cSaveTo, 'Error saving project ...' ) ENDIF IF lCanClose .AND. lOk ::oPropertiesDock:hide() ENDIF IF lOk ::oDockPT:show() ENDIF RETURN lOk /*----------------------------------------------------------------------*/ METHOD IdeProjManager:insertHeader( aHdr, aHbp ) LOCAL txt_:={} aadd( txt_, "#" ) aadd( txt_, "# $" + "Id" + "$" ) aadd( txt_, "#" ) aadd( txt_, "" ) aeval( aHdr, {|e| aadd( txt_, e ) } ) aadd( txt_, "" ) aeval( aHbp, {|e| aadd( txt_, e ) } ) aadd( txt_, "" ) RETURN txt_ /*----------------------------------------------------------------------*/ METHOD IdeProjManager:stripHeader( aHbp ) LOCAL nStart, n, s LOCAL a_:= {} FOR EACH s IN aHbp n := s:__enumIndex() s := alltrim( s ) IF left( s, 1 ) == "#" .AND. n <= 3 nStart := n LOOP ENDIF IF empty( s ) LOOP ENDIF IF "-3rd=hbide_file" $ s nStart := n EXIT ENDIF IF ! ( "-3rd=hbide_" $ s ) nStart := n EXIT ENDIF NEXT IF ! empty( nStart ) FOR EACH s IN aHbp IF s:__enumIndex() < nStart LOOP ENDIF aadd( a_, s ) NEXT ELSE RETURN aHbp ENDIF RETURN a_ /*----------------------------------------------------------------------*/ METHOD IdeProjManager:updateHbp( iIndex ) LOCAL txt_ IF iIndex != 3 RETURN NIL ENDIF /* Sources */ txt_:= hbide_synchronizeForHbp( hb_atokens( ::oUI:editSources:toPlainText(), _EOL ) ) /* Final assault */ ::oUI:editHbp:setPlainText( hbide_arrayToMemo( txt_ ) ) RETURN txt_ /*----------------------------------------------------------------------*/ METHOD IdeProjManager:fetchProperties() IF empty( ::oProject ) ::oProject := IdeProject():new( ::oIDE, ::aPrjProps ) ENDIF IF empty( ::oUI ) ::buildInterface() ENDIF IF empty( ::aPrjProps ) ::oUI:comboPrjType:setCurrentIndex( 0 ) ::oUI:editPrjTitle :setText( "" ) ::oUI:editPrjLoctn :setText( hbide_pathNormalized( ::oProject:location, .F. ) ) ::oUI:editDstFolder:setText( "" ) ::oUI:editBackup :setText( "" ) ::oUI:editOutName :setText( "" ) ::oUI:editFlags :setPlainText( "" ) ::oUI:editSources :setPlainText( "" ) ::oUI:editLaunchParams:setText( "" ) ::oUI:editLaunchExe:setText( "" ) ::oUI:editWrkFolder:setText( "" ) ::oUI:editHbp:setPlainText( "" ) ::oUI:oWidget:setWindowTitle( 'New Project...' ) ELSE DO CASE CASE empty( ::aPrjProps ) ::oUI:comboPrjType:setCurrentIndex( 0 ) CASE ::aPrjProps[ PRJ_PRP_PROPERTIES, 2, E_qPrjType ] == "Lib" ::oUI:comboPrjType:setCurrentIndex( 1 ) CASE ::aPrjProps[ PRJ_PRP_PROPERTIES, 2, E_qPrjType ] == "Dll" ::oUI:comboPrjType:setCurrentIndex( 2 ) OTHERWISE ::oUI:comboPrjType:setCurrentIndex( 0 ) ENDCASE ::oUI:editPrjTitle :setText( ::oProject:title ) ::oUI:editPrjLoctn :setText( ::oProject:location ) ::oUI:editDstFolder:setText( ::oProject:destination ) ::oUI:editOutName :setText( ::oProject:outputName ) ::oUI:editBackup :setText( ::oProject:backup ) ::oUI:checkXhb :setChecked( ::oProject:isXhb ) ::oUI:checkXpp :setChecked( ::oProject:isXpp ) ::oUI:checkClp :setChecked( ::oProject:isClp ) ::oUI:editFlags :setPlainText( hbide_arrayToMemo( ::aPrjProps[ PRJ_PRP_FLAGS , 1 ] ) ) ::oUI:editSources :setPlainText( hbide_arrayToMemo( ::stripHeader( ::aPrjProps[ 5 ] ) ) ) ::oUI:editLaunchParams:setText( ::oProject:launchParams ) ::oUI:editLaunchExe:setText( ::oProject:launchProgram ) ::oUI:editWrkFolder:setText( ::oProject:wrkDirectory ) ::oUI:editHbp:setPlainText( "" ) ::oUI:oWidget:setWindowTitle( 'Properties for "' + ::oUI:editPrjTitle:Text() + '"' ) ENDIF RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:buildInterface() LOCAL cLukupPng ::oUI := hbide_getUI( "projectpropertiesex" ) ::oPropertiesDock:oWidget:setWidget( ::oUI:oWidget ) ::oUI:comboPrjType:addItem( "Executable" ) ::oUI:comboPrjType:addItem( "Library" ) ::oUI:comboPrjType:addItem( "Dll" ) cLukupPng := hbide_image( "folder" ) // ::oUI:buttonChoosePrjLoc:setIcon( QIcon( cLukupPng ) ) ::oUI:buttonChooseWd :setIcon( QIcon( cLukupPng ) ) ::oUI:buttonChooseDest :setIcon( QIcon( cLukupPng ) ) ::oUI:buttonBackup :setIcon( QIcon( cLukupPng ) ) ::oUI:buttonSelect :setIcon( QIcon( hbide_image( "open" ) ) ) ::oUI:buttonUp :setIcon( QIcon( hbide_image( "dc_up" ) ) ) ::oUI:buttonDown :setIcon( QIcon( hbide_image( "dc_down" ) ) ) ::oUI:buttonSort :setIcon( QIcon( hbide_image( "sort" ) ) ) ::oUI:buttonSortZA :setIcon( QIcon( hbide_image( "sortdescend" ) ) ) ::oUI:buttonSortOrg:setIcon( QIcon( hbide_image( "invertcase" ) ) ) ::oUI:buttonSort :hide() ::oUI:buttonSortZA :hide() ::oUI:buttonSortOrg:hide() ::oUI:buttonCn :connect( "clicked()", {|| ::lSaveOK := .f., ::oPropertiesDock:hide() } ) ::oUI:buttonSave :connect( "clicked()", {|| ::lSaveOK := .t., ::save( .F. ) } ) ::oUI:buttonSaveExit :connect( "clicked()", {|| ::lSaveOK := .t., ::save( .T. ) } ) ::oUI:buttonSelect :connect( "clicked()", {|| ::addSources() } ) ::oUI:buttonUp :connect( "clicked()", {|| ::moveLine( -1 ) } ) ::oUI:buttonDown :connect( "clicked()", {|| ::moveLine( +1 ) } ) // ::oUI:buttonSort :connect( "clicked()", {|| ::sortSources( "az" ) } ) // ::oUI:buttonSortZA :connect( "clicked()", {|| ::sortSources( "za" ) } ) // ::oUI:buttonSortOrg :connect( "clicked()", {|| ::sortSources( "org" ) } ) ::oUI:tabWidget :connect( "currentChanged(int)", {|p| ::updateHbp( p ) } ) ::oUI:buttonChoosePrjLoc:connect( "clicked()", {|| ::PromptForPath( ::oUI:editPrjLoctn , 'Choose Project Location...' ) } ) ::oUI:buttonChooseWd :connect( "clicked()", {|| ::PromptForPath( ::oUI:editWrkFolder, 'Choose Working Folder...' ) } ) ::oUI:buttonChooseDest :connect( "clicked()", {|| ::PromptForPath( ::oUI:editDstFolder, 'Choose Destination Folder...' ) } ) ::oUI:buttonBackup :connect( "clicked()", {|| ::PromptForPath( ::oUI:editBackup , 'Choose Backup Folder...' ) } ) ::oUI:editPrjLoctn :connect( "textChanged(QString)", {|cPath| ::setProjectLocation( cPath ) } ) /* Set monospaced fonts */ ::oUI:editFlags :setFont( ::oFont:oWidget ) ::oUI:editSources :setFont( ::oFont:oWidget ) ::oUI:editHbp :setFont( ::oFont:oWidget ) #if 0 ::oUI:editPrjTitle :setFont( ::oFont:oWidget ) ::oUI:editPrjLoctn :setFont( ::oFont:oWidget ) ::oUI:editWrkFolder :setFont( ::oFont:oWidget ) ::oUI:editDstFolder :setFont( ::oFont:oWidget ) ::oUI:editOutName :setFont( ::oFont:oWidget ) ::oUI:editBackup :setFont( ::oFont:oWidget ) ::oUI:editLaunchParams:setFont( ::oFont:oWidget ) ::oUI:editLaunchExe :setFont( ::oFont:oWidget ) #endif ::oUI:setTabOrder( ::oUI:comboPrjType , ::oUI:editPrjTitle ) ::oUI:setTabOrder( ::oUI:editPrjTitle , ::oUI:editPrjLoctn ) ::oUI:setTabOrder( ::oUI:editPrjLoctn , ::oUI:editOutName ) ::oUI:setTabOrder( ::oUI:editOutName , ::oUI:checkXhb ) ::oUI:setTabOrder( ::oUI:checkXhb , ::oUI:checkXpp ) ::oUI:setTabOrder( ::oUI:checkXpp , ::oUI:checkClp ) ::oUI:setTabOrder( ::oUI:checkClp , ::oUI:editDstFolder ) ::oUI:setTabOrder( ::oUI:editDstFolder , ::oUI:editBackup ) ::oUI:setTabOrder( ::oUI:editBackup , ::oUI:editLaunchParams ) ::oUI:setTabOrder( ::oUI:editLaunchParams, ::oUI:editLaunchExe ) ::oUI:setTabOrder( ::oUI:editLaunchExe , ::oUI:editWrkFolder ) ::oUI:setTabOrder( ::oUI:editWrkFolder , ::oUI:tabFiles ) // ::oUI:setTabOrder( ::oUI:tabFiles , ::oUI:editSources ) ::oUI:setTabOrder( ::oUI:editSources , ::oUI:tabFlags ) // ::oUI:setTabOrder( ::oUI:tabFlags , ::oUI:editFlags ) ::oUI:setTabOrder( ::oUI:editFlags , ::oUI:tabHbp ) // ::oUI:setTabOrder( ::oUI:tabHbp , ::oUI:editHbp ) // ::oUI:setTabOrder( ::oUI:editHbp , ::oUI:buttonSaveExit ) ::oUI:setTabOrder( ::oUI:buttonSaveExit , ::oUI:buttonSave ) ::oUI:setTabOrder( ::oUI:buttonSave , ::oUI:buttonCn ) ::oUI:tabHbp:hide() ::oUI:tabFlags:hide() RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:synchronizeAlienProject( cProjFileName ) LOCAL cPath, cFile, cExt, cHbp LOCAL cExeHbMk2, oProcess, cCmd hb_fNameSplit( cProjFileName, @cPath, @cFile, @cExt ) IF lower( cExt ) == ".hbp" /* Nothing to do */ RETURN cProjFileName ENDIF IF !( lower( cExt ) $ ".xhp|.xbp" ) /* Not a valid alien project file */ RETURN "" ENDIF cHbp := cPath + cFile + ".hbp" IF hb_fileExists( cHbp ) IF ! hbide_getYesNo( "A .hbp with converted name already exists, overwrite?", "", "Project exists" ) RETURN "" ENDIF ENDIF cExeHbMk2 := ::oINI:getHbmk2File() SWITCH lower( cExt ) CASE ".xhp" cCmd := cExeHbMk2 + " -xhp=" + cProjFileName EXIT CASE ".xbp" cCmd := cExeHbMk2 + " -xbp=" + cProjFileName EXIT CASE "???" cCmd := cExeHbMk2 + " -hbmake=" + cProjFileName EXIT ENDSWITCH oProcess := QProcess() oProcess:start( cCmd ) oProcess:waitForFinished() RETURN cHbp /*----------------------------------------------------------------------*/ METHOD IdeProjManager:sortSources( cMode ) LOCAL a_, cTyp, s, d_, n LOCAL aSrc := { ".prg", ".ch", ".c", ".cpp", ".h", ".obj", ".o", ".lib", ".a", ".rc", ".res" } LOCAL aTxt := { {} , {} , {} , {} , {} , {} , {} , {} , {} , {} , {} } LOCAL aRst := {} a_:= hbide_memoToArray( ::oUI:editSources:toPlainText() ) IF cMode == "az" asort( a_, , , {|e,f| lower( hbide_stripFilter( e ) ) < lower( hbide_stripFilter( f ) ) } ) ELSEIF cMode == "za" asort( a_, , , {|e,f| lower( hbide_stripFilter( f ) ) < lower( hbide_stripFilter( e ) ) } ) ELSEIF cMode == "org" asort( a_, , , {|e,f| lower( hbide_stripFilter( e ) ) < lower( hbide_stripFilter( f ) ) } ) FOR EACH s IN a_ s := alltrim( s ) IF !( left( s, 1 ) == "#" ) cTyp := hbide_sourceType( s ) IF ( n := ascan( aSrc, {|e| cTyp == e } ) ) > 0 aadd( aTxt[ n ], s ) ELSE aadd( aRst, s ) ENDIF ENDIF NEXT a_:= {} FOR EACH d_ IN aTxt IF !empty( d_ ) aadd( a_, " #" ) aadd( a_, " #" + aSrc[ d_:__enumIndex() ] ) aadd( a_, " #" ) FOR EACH s IN d_ aadd( a_, s ) NEXT ENDIF NEXT IF !empty( aRst ) aadd( a_, " #" ) aadd( a_, " #" + "Unrecognized..." ) aadd( a_, " #" ) FOR EACH s IN aRst aadd( a_, s ) NEXT ENDIF ENDIF ::oUI:editSources:clear() ::oUI:editSources:setPlainText( hbide_arrayToMemo( a_ ) ) RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:setProjectLocation( cPath ) IF ! hb_dirExists( cPath ) ::oUI:editPrjLoctn:setStyleSheet( "background-color: rgba( 240,120,120,255 );" ) ::oUI:editSources:setEnabled( .f. ) ::oUI:buttonSelect:setEnabled( .f. ) ELSE ::oProject:location := cPath ::oUI:editPrjLoctn:setStyleSheet( "" ) ::oUI:editSources:setEnabled( .T. ) ::oUI:buttonSelect:setEnabled( .T. ) ENDIF RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:isValidProjectLocation( lTell ) LOCAL lOk := .f. IF empty( ::oUI:editPrjLoctn:text() ) IF lTell MsgBox( "Please supply 'Project Location' first" ) ENDIF ELSEIF ! hb_dirExists( ::oUI:editPrjLoctn:text() ) IF lTell MsgBox( "Please ensure 'Project Location' is correct" ) ENDIF ELSE lOk := .t. ENDIF RETURN lOk /*----------------------------------------------------------------------*/ METHOD IdeProjManager:moveLine( nDirection ) IF nDirection == -1 ELSE ENDIF RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:addSources() LOCAL aFiles, a_, b_, s, cHome IF ::isValidProjectLocation( .t. ) IF !empty( aFiles := ::oSM:selectSource( "openmany", , , ::oUI:editPrjLoctn:text() ) ) a_:= hbide_memoToArray( ::oUI:editSources:toPlainText() ) b_:={} aeval( aFiles, {|e| aadd( b_, e ) } ) cHome := ::oUI:editPrjLoctn:text() FOR EACH s IN b_ s := hbide_prepareSourceForHbp( hbide_stripRoot( cHome, s ) ) IF ascan( a_, s ) == 0 aadd( a_, s ) ENDIF NEXT ::oUI:editSources:setPlainText( hbide_arrayToMemo( a_ ) ) ENDIF ENDIF RETURN Self /*----------------------------------------------------------------------*/ /* Set current project for build - vailtom * 26/12/2009 - 02:19:38 */ METHOD IdeProjManager:setCurrentProject( cProjectName ) LOCAL aPrjProps, n, oItem LOCAL cOldProject := ::cWrkProject LOCAL lValid := .T. IF Empty( cProjectName ) ::oIDE:cWrkProject := '' ELSEIF ( n := ascan( ::aProjects, {|e_| e_[ 3, PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] == cProjectName } ) ) > 0 aPrjProps := ::aProjects[ n, 3 ] ::oIDE:cWrkProject := aPrjProps[ PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] ELSE lValid := .F. ENDIF IF lValid IF !Empty( ::oSBar ) ::oDK:setStatusText( SB_PNL_PROJECT, ::cWrkProject ) ENDIF ::oIDE:updateTitleBar() /* Reset Old Color */ IF !empty( cOldProject ) IF !empty( oItem := hbide_findProjTreeItem( ::oIDE, cOldProject, "Project Name" ) ) oItem:oWidget:setForeground( 0, QBrush( QColor( 0,0,0 ) ) ) ENDIF ENDIF /* Set New Color */ IF !empty( ::cWrkProject ) IF !empty( oItem := hbide_findProjTreeItem( ::oIDE, ::cWrkProject, "Project Name" ) ) oItem:oWidget:setForeground( 0, QBrush( QColor( 255,0,0 ) ) ) ::oProjTree:oWidget:setCurrentItem( oItem:oWidget ) ENDIF ::loadProperties( ::getProjectFileNameFromTitle( ::cWrkProject ), .f., .f., .f. ) ENDIF ENDIF RETURN cOldProject /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getCurrentProjectTitle() IF Empty( ::aProjects ) RETURN "" ENDIF IF ! Empty( ::cWrkProject ) RETURN ::cWrkProject ENDIF IF Len( ::aProjects ) == 1 ::setCurrentProject( ::aProjects[ 1, 3, PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] ) RETURN ::aProjects[ 1, 3, PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] ENDIF RETURN "" /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getCurrentProject( lAlert ) DEFAULT lAlert TO .t. IF !Empty( ::cWrkProject ) RETURN ::cWrkProject ENDIF IF Empty( ::aProjects ) IF lAlert MsgBox( "No Projects Available" ) ENDIF RETURN "" ENDIF IF Len( ::aProjects ) == 1 ::setCurrentProject( ::aProjects[ 1, 3, PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] ) RETURN ::aProjects[ 1, 3, PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] ENDIF RETURN ::selectCurrentProject() /*----------------------------------------------------------------------*/ METHOD IdeProjManager:selectCurrentProject() LOCAL oDlg, p, t IF Empty( ::aProjects ) MsgBox( "No Projects Available" ) RETURN ::cWrkProject ENDIF oDlg := hbide_getUI( "selectproject", ::oDlg:oWidget ) FOR EACH p IN ::aProjects IF !empty( t := p[ 3, PRJ_PRP_PROPERTIES, 2, E_oPrjTtl ] ) oDlg:cbProjects:addItem( t ) ENDIF NEXT oDlg:btnCancel:connect( "clicked()", {|| oDlg:oWidget:done( 1 ) } ) oDlg:btnOk :connect( "clicked()", {|| ::setCurrentProject( oDlg:cbProjects:currentText() ), ; oDlg:done( 1 ) } ) oDlg:exec() oDlg:btnCancel:disconnect( "clicked()" ) oDlg:btnOk :disconnect( "clicked()" ) oDlg:destroy() oDlg := NIL RETURN ::cWrkProject /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getProjectsTitleList() LOCAL a_, aList := {} FOR EACH a_ IN ::aProjects aadd( aList, a_[ 3, PRJ_PRP_PROPERTIES, 2, PRJ_PRP_TITLE ] ) NEXT RETURN aList /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getProjectProperties( cProjectTitle ) LOCAL n IF ( n := ascan( ::aProjects, {|e_, x| x := e_[ 3 ], x[ 1, 2, PRJ_PRP_TITLE ] == cProjectTitle } ) ) > 0 RETURN ::aProjects[ n, 3 ] ENDIF RETURN {} /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getProjectByFile( cProjectFile ) LOCAL n, aProj cProjectFile := hbide_pathNormalized( cProjectFile ) IF ( n := ascan( ::aProjects, {|e_| hb_FileMatch( e_[ 1 ], cProjectFile ) } ) ) > 0 aProj := ::aProjects[ n ] ENDIF RETURN IdeProject():new( ::oIDE, aProj ) /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getProjectTypeFromTitle( cProjectTitle ) LOCAL n, cType := "" IF ( n := ascan( ::aProjects, {|e_, x| x := e_[ 3 ], x[ 1, 2, PRJ_PRP_TITLE ] == cProjectTitle } ) ) > 0 cType := ::aProjects[ n, 3, PRJ_PRP_PROPERTIES, 1, PRJ_PRP_TYPE ] ENDIF RETURN cType /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getProjectPathFromTitle( cProjectTitle ) LOCAL cPath hb_fNameSplit( ::getProjectFileNameFromTitle( cProjectTitle ), @cPath ) RETURN cPath /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getProjectFileNameFromTitle( cProjectTitle ) LOCAL n, cProjFileName := "" IF ( n := ascan( ::aProjects, {|e_, x| x := e_[ 3 ], x[ 1, 2, PRJ_PRP_TITLE ] == cProjectTitle } ) ) > 0 cProjFileName := ::aProjects[ n, 2 ] ENDIF RETURN cProjFileName /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getSourcesByProjectTitle( cProjectTitle ) LOCAL n, aProj IF ( n := ascan( ::aProjects, {|e_, x| x := e_[ 3 ], x[ 1, 2, PRJ_PRP_TITLE ] == cProjectTitle } ) ) > 0 aProj := ::aProjects[ n, 3 ] RETURN aProj[ PRJ_PRP_SOURCES, 2 ] /* 2 == parsed sources */ ENDIF RETURN {} /*----------------------------------------------------------------------*/ METHOD IdeProjManager:getProjectByTitle( cProjectTitle ) LOCAL n, aProj IF ( n := ascan( ::aProjects, {|e_, x| x := e_[ 3 ], x[ 1, 2, PRJ_PRP_TITLE ] == cProjectTitle } ) ) > 0 aProj := ::aProjects[ n, 3 ] ENDIF RETURN IdeProject():new( ::oIDE, aProj ) /*----------------------------------------------------------------------*/ METHOD IdeProjManager:removeProject( cProjectTitle ) LOCAL cProjFileName, nPos IF !empty( cProjFileName := ::getProjectFileNameFromTitle( cProjectTitle ) ) ::closeProject( cProjectTitle ) nPos := ascan( ::aProjects, {|e_| e_[ 2 ] == cProjFileName } ) IF nPos > 0 hb_adel( ::aProjects, nPos, .T. ) ::oINI:save() ENDIF ENDIF RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:closeProject( cProjectTitle ) LOCAL oProject, aProp IF Empty( ::aProjects ) RETURN Self ENDIF aProp := ::getProjectProperties( cProjectTitle ) oProject := IdeProject():new( ::oIDE, aProp ) IF empty( oProject:title ) RETURN Self ENDIF ::oIDE:removeProjectTree( aProp ) ::setCurrentProject( '' ) RETURN Self /*----------------------------------------------------------------------*/ /* Prompt for user to select a existing folder * 25/12/2009 - 19:03:09 - vailtom */ METHOD IdeProjManager:promptForPath( oEditPath, cTitle, cObjFileName ) LOCAL cTemp, cPath, cFile IF HB_ISOBJECT( ::oProject ) cTemp := oEditPath:Text() ELSE cTemp := "" ENDIF IF !HB_ISSTRING( cObjFileName ) cPath := hbide_fetchADir( ::oDlg, cTitle, cTemp ) ELSE cTemp := hbide_fetchAFile( ::oDlg, cTitle, { { "Harbour IDE Projects", "*.hbp" } }, cTemp ) IF !Empty( cTemp ) hb_fNameSplit( hbide_pathNormalized( cTemp, .f. ), @cPath, @cFile ) oEditPath:setText( cFile ) ENDIF ENDIF IF !Empty( cPath ) IF Right( cPath, 1 ) $ '/\' cPath := Left( cPath, Len( cPath ) - 1 ) ENDIF oEditPath:setText( cPath ) ENDIF oEditPath:setFocus() RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:buildSource( lExecutable ) LOCAL oEdit, cTmp, cExeHbMk2, cCmd, cC, cCmdParams, cBuf LOCAL cbRed := "", ceRed := "" LOCAL lRebuild := .T. LOCAL aHbp := {} ::lPPO := .t. ::lLaunch := lExecutable ::cProjectInProcess := NIL IF !empty( oEdit := ::oEM:getEditorCurrent() ) IF ! hbide_isSourcePRG( oEdit:sourceFile ) MsgBox( 'Operation not supported for this file type: "' + oEdit:sourceFile + '"' ) RETURN Self ENDIF ELSE MsgBox( "No active editing source available !" ) RETURN Self ENDIF IF ::oINI:lSaveSourceWhenComp ::oSM:saveNamedSource( oEdit:sourceFile ) ENDIF ::cargo := oEdit aadd( aHbp, "-q" ) aadd( aHbp, "-trace" ) aadd( aHbp, "-info" ) aadd( aHbp, "-lang=en" ) aadd( aHbp, "-width=0" ) aadd( aHbp, "-rebuild" ) IF lExecutable aadd( aHbp, "-hbexe" ) ELSE aadd( aHbp, "-s" ) ENDIF aadd( aHbp, hbide_pathToOSPath( oEdit:sourceFile ) ) ::oDockB2:show() ::oOutputResult:oWidget:clear() ::oOutputResult:oWidget:append( hbide_outputLine() ) cTmp := "Project [ " + oEdit:sourceFile + " ] " + ; "Launch [ " + iif( ::lLaunch, 'Yes', 'No' ) + " ] " + ; "Rebuild [ " + iif( lRebuild , 'Yes', 'No' ) + " ] " + ; "Started [ " + time() + " ]" ::oOutputResult:oWidget:append( cTmp ) ::oOutputResult:oWidget:append( hbide_outputLine() ) ::oIDE:oEV := IdeEnvironments():new():create( ::oIDE ) ::cBatch := ::oEV:prepareBatch( ::cWrkEnvironment ) aeval( ::oEV:getHbmk2Commands( ::cWrkEnvironment ), {|e| aadd( aHbp, e ) } ) cExeHbMk2 := "hbmk2" cCmdParams := hbide_array2cmdParams( aHbp ) ::oProcess := HbpProcess():new() // ::oProcess:output := {|cOut, mp2, oHbp| ::showOutput( cOut,mp2,oHbp ) } ::oProcess:finished := {|nEC , nES, oHbp| ::finished( nEC ,nES,oHbp ) } ::oProcess:workingPath := hbide_pathToOSPath( oEdit:cPath ) // cCmd := hbide_getShellCommand() cC := iif( hbide_getOS() == "nix", "", "/C " ) IF hb_fileExists( ::cBatch ) cBuf := memoread( ::cBatch ) cBuf += hb_eol() + cExeHbMk2 + " " + cCmdParams + hb_eol() hb_memowrit( ::cBatch, cBuf ) ENDIF // ::outputText( cbRed + "Batch File " + iif( hb_fileExists( ::cBatch ), " Exists", " : doesn't Exist" ) + " => " + ceRed + trim( ::cBatch ) ) ::outputText( cbRed + "Batch File Contents => " + ceRed ) ::outputText( memoread( ::cBatch ) ) ::outputText( cbRed + "Command => " + ceRed + cCmd ) ::outputText( cbRed + "Arguments => " + ceRed + cC + ::cBatch ) ::outputText( hbide_outputLine() ) // ::oProcess:addArg( cC + ::cBatch ) ::oProcess:start( cCmd ) RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:buildProject( cProject, lLaunch, lRebuild, lPPO, lViaQt ) LOCAL cHbpPath, oEdit, cHbpFN, cTmp, cExeHbMk2, aHbp, cCmd, cC, oSource, cCmdParams, cBuf LOCAL cbRed := "", ceRed := "" aHbp := {} DEFAULT lLaunch TO .F. DEFAULT lRebuild TO .F. DEFAULT lPPO TO .F. DEFAULT lViaQt TO .F. ::lPPO := lPPO ::lLaunch := lLaunch ::cProjectInProcess := cProject IF ::lPPO .AND. empty( ::oEM:getEditCurrent() ) MsgBox( 'No source available to be compiled' ) RETURN Self ENDIF IF empty( cProject ) cProject := ::getCurrentProject( .f. ) ENDIF IF empty( cProject ) .AND. !( ::lPPO ) RETURN Self ENDIF IF ::lPPO lRebuild := .t. ENDIF /* Set it as current project */ ::setCurrentProject( cProject ) /* Make Macros happy */ hbide_setProjectTitle( cProject ) ::oProject := ::getProjectByTitle( cProject ) // attempt to save the sources if are open in editors should it be controlled by some option ? IF ::oINI:lSaveSourceWhenComp FOR EACH oSource IN ::oProject:hSources ::oSM:saveNamedSource( oSource:original ) NEXT ENDIF cHbpFN := hbide_pathFile( ::oProject:location, iif( empty( ::oProject:outputName ), "_temp", ::oProject:outputName ) ) cHbpPath := cHbpFN + iif( ::lPPO, '_tmp', "" ) + ".hbp" IF !( ::lPPO ) IF ::oProject:type == "Lib" aadd( aHbp, "-hblib" ) ELSEIF ::oProject:type == "Dll" // aadd( aHbp, "-hbdynvm" ) /* Better if is provided as a flag -hbdyn or -hbdynvm */ ENDIF ENDIF IF ::oProject:isXhb aadd( aHbp, "-xhb" ) ENDIF aadd( aHbp, "-q" ) aadd( aHbp, "-trace" ) aadd( aHbp, "-info" ) aadd( aHbp, "-lang=en" ) aadd( aHbp, "-width=512" ) IF lRebuild aadd( aHbp, "-rebuild" ) ENDIF IF ::lPPO IF !empty( oEdit := ::oEM:getEditorCurrent() ) IF hbide_isSourcePRG( oEdit:sourceFile ) aadd( aHbp, "-s" ) aadd( aHbp, "-p" ) aadd( aHbp, "-hbraw" ) // TODO: We have to test if the current file is part of a project, and we // pull your settings, even though this is not the active project - vailtom aadd( aHbp, hbide_pathToOSPath( oEdit:sourceFile ) ) ::cPPO := hbide_pathFile( oEdit:cPath, oEdit:cFile + '.ppo' ) FErase( ::cPPO ) ELSE MsgBox( 'Operation not supported for this file type: "' + oEdit:sourceFile + '"' ) RETURN Self ENDIF lViaQt := .t. /* Donot know why it fails with Qt */ ENDIF ENDIF ::oDockB2:show() ::oOutputResult:oWidget:clear() IF .f. ::oOutputResult:oWidget:append( 'Error saving: ' + cHbpPath ) ELSE ::oOutputResult:oWidget:append( hbide_outputLine() ) cTmp := "Project [ " + cProject + " ] " + ; "Launch [ " + iif( lLaunch , 'Yes', 'No' ) + " ] " + ; "Rebuild [ " + iif( lRebuild, 'Yes', 'No' ) + " ] " + ; "Started [ " + time() + " ]" ::oOutputResult:oWidget:append( cTmp ) ::oOutputResult:oWidget:append( hbide_outputLine() ) ::oIDE:oEV := IdeEnvironments():new():create( ::oIDE ) ::cBatch := ::oEV:prepareBatch( ::cWrkEnvironment ) aeval( ::oEV:getHbmk2Commands( ::cWrkEnvironment ), {|e| aadd( aHbp, e ) } ) cExeHbMk2 := ::oINI:getHbmk2File() cCmdParams := hbide_array2cmdParams( aHbp ) ::oProcess := HbpProcess():new() // ::oProcess:output := {|cOut, mp2, oHbp| ::showOutput( cOut,mp2,oHbp ) } ::oProcess:finished := {|nEC , nES, oHbp| ::finished( nEC ,nES,oHbp ) } ::oProcess:workingPath := hbide_pathToOSPath( ::oProject:location ) // cCmd := hbide_getShellCommand() cC := iif( hbide_getOS() == "nix", "", "/C " ) IF hb_fileExists( ::cBatch ) cBuf := memoread( ::cBatch ) cBuf += hb_eol() + cExeHbMk2 + " " + cHbpPath + cCmdParams + hb_eol() hb_memowrit( ::cBatch, cBuf ) ENDIF // ::outputText( cbRed + "Batch File " + iif( hb_fileExists( ::cBatch ), " Exists", " : doesn't Exist" ) + " => " + ceRed + trim( ::cBatch ) ) ::outputText( cbRed + "Batch File Contents => " + ceRed ) ::outputText( memoread( ::cBatch ) ) ::outputText( cbRed + "Command => " + ceRed + cCmd ) ::outputText( cbRed + "Arguments => " + ceRed + cC + ::cBatch ) ::outputText( hbide_outputLine() ) // ::oProcess:addArg( cC + ::cBatch ) ::oProcess:start( cCmd ) ENDIF RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:showOutput( cOutput, mp2, oProcess ) LOCAL cIfError HB_SYMBOL_UNUSED( mp2 ) HB_SYMBOL_UNUSED( oProcess ) cIfError := hbide_convertBuildStatusMsgToHtml( cOutput, ::oOutputResult:oWidget ) IF ! empty( cIfError ) .AND. empty( ::cIfError ) ::cIfError := cIfError ENDIF RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:finished( nExitCode, nExitStatus, oProcess ) LOCAL cTmp, n, n1, cTkn, cExe, qDoc, qCursor HB_SYMBOL_UNUSED( oProcess ) ::outputText( hbide_outputLine() ) cTmp := "Exit Code [ " + hb_ntos( nExitCode ) + " ] Exit Status [ " + hb_ntos( nExitStatus ) + " ] " +; "Finished at [ " + time() + " ] Done in [ " + hb_ntos( seconds() - oProcess:started ) + " Secs ]" ::outputText( cTmp ) ::outputText( hbide_outputLine() ) ferase( ::cBatch ) IF ! empty( ::cIfError ) ::oOutputResult:SelStart := 0 ::oOutputResult:find( ::cIfError ) ::oOutputResult:SelBold := .T. qDoc := ::oOutputResult:document() FOR n := 0 TO qDoc:blockCount() - 1 IF ::cIfError == qDoc:findBlockByNumber( n ):text() qCursor := qDoc:find( ::cIfError ) ::oOutputResult:setTextCursor( qCursor ) EXIT ENDIF NEXT ENDIF cTmp := ::oOutputResult:oWidget:toPlainText() cExe := "" IF empty( cExe ) cTkn := "hbmk2: Linking... " IF ( n := at( cTkn, cTmp ) ) > 0 n1 := hb_at( Chr( 10 ), cTmp, n + Len( cTkn ) ) cExe := StrTran( substr( cTmp, n + Len( cTkn ), n1 - n - len( cTkn ) ), Chr( 13 ) ) ENDIF ENDIF IF empty( cExe ) cTkn := "hbmk2: Target up to date: " IF ( n := at( cTkn, cTmp ) ) > 0 n1 := hb_at( Chr( 10 ), cTmp, n + Len( cTkn ) ) cExe := StrTran( substr( cTmp, n + Len( cTkn ), n1 - n - len( cTkn ) ), Chr( 13 ) ) ENDIF ENDIF IF HB_ISOBJECT( ::cargo ) cExe := hb_PathJoin( hbide_pathToOSPath( ::cargo:cPath ), cExe ) ELSE cExe := hb_PathJoin( hbide_pathToOSPath( ::oProject:location ), cExe ) ENDIF IF !empty( cExe ) hb_fNameSplit( cExe, @cTmp ) hbide_setProjectOutputPath( cTmp ) ENDIF IF ::lLaunch ::outputText( " " ) IF empty( cExe ) ::outputText( "" + "Executable could not been detected from linker output!" + "" ) ELSE cExe := alltrim( cExe ) ::outputText( "" + "Detected executable => " + cExe + "" ) ENDIF ::outputText( " " ) IF nExitCode == 0 ::launchProject( ::cProjectInProcess, cExe ) ELSE ::outputText( "Sorry, cannot launch project because of errors..." ) ENDIF ENDIF IF ::lPPO .AND. hb_FileExists( ::cPPO ) ::editSource( ::cPPO ) ENDIF ::cIfError := NIL ::oOutputResult:ensureCursorVisible() IF !empty( qCursor ) qCursor:clearSelection() ::oOutputResult:setTextCursor( qCursor ) ENDIF RETURN Self /*----------------------------------------------------------------------*/ /* * Launch selected project. * 03/01/2010 - 09:24:50 */ METHOD IdeProjManager:launchProject( cProject, cExe ) LOCAL cTargetFN, cTmp, oProject, cPath LOCAL qProcess, qStr IF empty( cProject ) cProject := ::oPM:getCurrentProject( .f. ) ENDIF IF !empty( cProject ) oProject := ::getProjectByTitle( cProject ) ENDIF IF empty( cExe ) .AND. !empty( oProject ) cTargetFN := hbide_pathFile( oProject:destination, iif( empty( oProject:outputName ), "_temp", oProject:outputName ) ) #ifdef __PLATFORM__WINDOWS IF oProject:type == "Executable" cTargetFN += '.exe' ENDIF #endif IF ! hb_FileExists( cTargetFN ) cTargetFN := oProject:launchProgram ENDIF ELSE cTargetFN := cExe ENDIF IF empty( cTargetFN ) cTargetFN := "" ENDIF cTargetFN := hbide_pathToOSPath( cTargetFN ) IF ! hb_FileExists( cTargetFN ) cTmp := "Launch error: file not found - " + cTargetFN ELSEIF empty( oProject ) .OR. oProject:type == "Executable" cTmp := "Launching application [ " + cTargetFN + " ]" if .t. qProcess := QProcess() qStr := QStringList() IF !empty( oProject ) IF !empty( oProject:launchParams ) qStr:append( oProject:launchParams ) ENDIF qProcess:startDetached( cTargetFN, qStr, hbide_pathToOSPath( oProject:wrkDirectory ) ) ELSE hb_fNameSplit( cTargetFN, @cPath ) qProcess:startDetached( cTargetFN, qStr, hbide_pathToOSPath( cPath ) ) ENDIF qProcess:waitForStarted( 3000 ) qProcess := NIL else hb_processRun( cTargetFN, , , , .t. ) endif ELSE cTmp := "Launching application [ " + cTargetFN + " ] ( not applicable )." ENDIF ::oOutputResult:oWidget:append( cTmp ) RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:runAsScript() LOCAL oEdit IF !empty( oEdit := ::oEM:getEditorCurrent() ) hbide_runAScript( oEdit:qEdit:toPlainText() ) ENDIF RETURN Self /*----------------------------------------------------------------------*/ METHOD IdeProjManager:outputText( cText ) ::oOutputResult:oWidget:append( "" + cText + "" ) RETURN Self /*----------------------------------------------------------------------*/