2000-08-27 19:11:42 +00:00
/ *
2001-08-03 14:23:25 +00:00
GNUstep ProjectCenter - http : // www . gnustep . org
2000-08-27 19:11:42 +00:00
2002-11-27 18:41:07 +00:00
Copyright ( C ) 2000 -2002 Free Software Foundation
2000-08-27 19:11:42 +00:00
2002-11-24 12:23:47 +00:00
Author : Philippe C . D . Robert < probert @ siggraph . org >
2000-08-27 19:11:42 +00:00
2001-08-03 14:23:25 +00:00
This file is part of GNUstep .
2000-08-27 19:11:42 +00:00
This application 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 of the License , or ( at your option ) any later version .
This application 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
Library General Public License for more details .
You should have received a copy of the GNU General Public
License along with this library ; if not , write to the Free
Software Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 USA .
$ Id $
* /
2003-04-21 13:46:10 +00:00
# include "PCProject.h"
# include "PCDefines.h"
# include "ProjectBuilder.h"
# include "PCProject+ComponentHandling.h"
# include "PCProjectBuilder.h"
# include "PCProjectEditor.h"
# include "PCProjectDebugger.h"
# include "PCEditor.h"
# include "PCEditorController.h"
# include "PCHistoryController.h"
# include "PCBrowserController.h"
# include "PCProject+UInterface.h"
2000-08-27 19:11:42 +00:00
@ implementation PCProject
2002-02-02 17:56:44 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === ===
2000-08-27 19:11:42 +00:00
// === = Init and free
2002-02-02 17:56:44 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === ===
2000-08-27 19:11:42 +00:00
- ( id ) init
{
2002-02-02 17:56:44 +00:00
if ( ( self = [ super init ] ) )
{
2000-09-17 12:13:10 +00:00
buildOptions = [ [ NSMutableDictionary alloc ] init ] ;
2000-08-27 19:11:42 +00:00
[ self _initUI ] ;
2002-02-02 17:56:44 +00:00
editorController = [ [ PCEditorController alloc ] init ] ;
[ editorController setProject : self ] ;
2000-08-27 19:11:42 +00:00
}
return self ;
}
- ( id ) initWithProjectDictionary : ( NSDictionary * ) dict path : ( NSString * ) path ;
{
NSAssert ( dict , @ "No valid project dictionary!" ) ;
2002-02-02 17:56:44 +00:00
if ( ( self = [ self init ] ) )
{
2000-08-27 19:11:42 +00:00
if ( [ [ path lastPathComponent ] isEqualToString : @ "PC.project" ] ) {
projectPath = [ [ path stringByDeletingLastPathComponent ] copy ] ;
}
else {
projectPath = [ path copy ] ;
}
if ( ! [ self assignProjectDict : dict ] ) {
NSLog ( @ "<%@ %x>: could not load the project..." , [ self class ] , self ) ;
[ self autorelease ] ;
return nil ;
}
}
return self ;
}
- ( void ) dealloc
{
2001-01-14 15:53:46 +00:00
RELEASE ( projectName ) ;
RELEASE ( projectPath ) ;
RELEASE ( projectDict ) ;
2002-02-17 13:14:51 +00:00
if ( projectBuilder ) RELEASE ( projectBuilder ) ;
2002-02-12 21:44:28 +00:00
if ( projectDebugger ) RELEASE ( projectDebugger ) ;
2002-02-17 13:14:51 +00:00
if ( projectEditor ) RELEASE ( projectEditor ) ;
2000-10-15 18:24:09 +00:00
2002-02-21 21:17:22 +00:00
RELEASE ( historyController ) ;
2001-01-14 15:53:46 +00:00
RELEASE ( browserController ) ;
RELEASE ( buildTargetPanel ) ;
RELEASE ( buildTargetHostField ) ;
RELEASE ( buildTargetArgsField ) ;
2000-10-15 18:24:09 +00:00
2001-01-14 15:53:46 +00:00
RELEASE ( buildOptions ) ;
2000-10-15 18:24:09 +00:00
2001-01-14 15:53:46 +00:00
RELEASE ( projectAttributeInspectorView ) ;
RELEASE ( installPathField ) ;
RELEASE ( toolField ) ;
RELEASE ( ccOptField ) ;
RELEASE ( ldOptField ) ;
RELEASE ( projectProjectInspectorView ) ;
RELEASE ( projectTypeField ) ;
RELEASE ( projectFileInspectorView ) ;
RELEASE ( fileNameField ) ;
RELEASE ( changeFileNameButton ) ;
2000-10-15 18:24:09 +00:00
2001-01-14 15:53:46 +00:00
RELEASE ( box ) ;
2002-02-02 17:56:44 +00:00
RELEASE ( editorController ) ;
2000-10-29 20:15:39 +00:00
2000-10-15 18:24:09 +00:00
[ super dealloc ] ;
2000-08-27 19:11:42 +00:00
}
2002-02-02 17:56:44 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === ===
2000-08-27 19:11:42 +00:00
// === = Accessor methods
2002-02-02 17:56:44 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === ===
2000-08-27 19:11:42 +00:00
- ( id ) browserController
{
return browserController ;
}
2000-09-17 12:13:10 +00:00
- ( NSString * ) selectedRootCategory
{
2001-01-13 20:46:59 +00:00
NSString * _path = [ browserController pathOfSelectedFile ] ;
return [ self projectKeyForKeyPath : _path ] ;
2000-09-17 12:13:10 +00:00
}
- ( NSArray * ) fileExtensionsForCategory : ( NSString * ) key
{
if ( [ key isEqualToString : PCGModels ] ) {
return [ NSArray arrayWithObjects : @ "gmodel" , @ "gorm" , nil ] ;
}
2003-01-26 03:43:19 +00:00
if ( [ key isEqualToString : PCGSMarkupFiles ] ) {
return [ NSArray arrayWithObjects : @ "gsmarkup" , nil ] ;
}
2000-09-17 12:13:10 +00:00
else if ( [ key isEqualToString : PCClasses ] ) {
return [ NSArray arrayWithObjects : @ "m" , nil ] ;
}
else if ( [ key isEqualToString : PCHeaders ] ) {
return [ NSArray arrayWithObjects : @ "h" , nil ] ;
}
else if ( [ key isEqualToString : PCOtherSources ] ) {
2003-04-29 04:33:39 +00:00
return [ NSArray arrayWithObjects : @ "c" , @ "C" , @ "m" , @ "M" , nil ] ;
2000-09-17 12:13:10 +00:00
}
else if ( [ key isEqualToString : PCLibraries ] ) {
return [ NSArray arrayWithObjects : @ "so" , @ "a" , @ "lib" , nil ] ;
}
else if ( [ key isEqualToString : PCSubprojects ] ) {
return [ NSArray arrayWithObjects : @ "subproj" , nil ] ;
}
else if ( [ key isEqualToString : PCImages ] ) {
2000-10-26 09:12:24 +00:00
return [ NSImage imageFileTypes ] ;
2000-09-17 12:13:10 +00:00
}
return nil ;
}
2000-08-27 19:11:42 +00:00
- ( void ) setProjectName : ( NSString * ) aName
{
2002-01-02 16:05:02 +00:00
AUTORELEASE ( projectName ) ;
2000-08-27 19:11:42 +00:00
projectName = [ aName copy ] ;
}
- ( NSString * ) projectName
{
return projectName ;
}
- ( NSWindow * ) projectWindow
{
2002-01-02 16:05:02 +00:00
return projectWindow ;
2000-08-27 19:11:42 +00:00
}
- ( Class ) principalClass
{
return [ self class ] ;
}
2002-02-02 17:56:44 +00:00
- ( PCEditorController * ) editorController
{
return editorController ;
}
// === === === === === === === === === === === === === === === === === === === === === === === === === ===
2000-08-27 19:11:42 +00:00
// === = Delegate and manager
2002-02-02 17:56:44 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === ===
2000-08-27 19:11:42 +00:00
- ( id ) delegate
{
2002-01-02 16:05:02 +00:00
return delegate ;
2000-08-27 19:11:42 +00:00
}
- ( void ) setDelegate : ( id ) aDelegate
{
2002-01-02 16:05:02 +00:00
delegate = aDelegate ;
2000-08-27 19:11:42 +00:00
}
2002-02-02 17:56:44 +00:00
- ( void ) setProjectBuilder : ( id < ProjectBuilder , NSObject > ) aBuilder
2000-08-27 19:11:42 +00:00
{
2002-04-26 03:12:50 +00:00
// This is our owner , don ' t retain .
// projectManager = aBuilder ;
ASSIGN ( projectManager , aBuilder ) ;
2000-08-27 19:11:42 +00:00
}
- ( id < ProjectBuilder > ) projectBuilder
{
2002-01-02 16:05:02 +00:00
return projectManager ;
2000-08-27 19:11:42 +00:00
}
2002-02-02 17:56:44 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === ===
2000-08-27 19:11:42 +00:00
// === = To be overriden
2002-02-02 17:56:44 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === ===
2000-08-27 19:11:42 +00:00
2002-01-01 17:27:41 +00:00
- ( Class ) builderClass
{
return Nil ;
}
2000-08-27 19:11:42 +00:00
- ( BOOL ) writeMakefile
{
2001-12-29 14:09:39 +00:00
NSString * mf = [ projectPath stringByAppendingPathComponent : @ "GNUmakefile" ] ;
NSString * bu = [ projectPath stringByAppendingPathComponent : @ "GNUmakefile~" ] ;
NSFileManager * fm = [ NSFileManager defaultManager ] ;
2001-12-29 14:41:43 +00:00
if ( [ fm isReadableFileAtPath : mf ] ) {
if ( [ fm isWritableFileAtPath : bu ] ) {
[ fm removeFileAtPath : bu handler : nil ] ;
}
if ( ! [ fm copyPath : mf toPath : bu handler : nil ] ) {
NSRunAlertPanel ( @ "Attention!" ,
@ "Could not keep a backup of the GNUMakefile!" ,
@ "OK" , nil , nil ) ;
}
2001-12-29 14:09:39 +00:00
}
2002-01-02 16:05:02 +00:00
return YES ;
2000-08-27 19:11:42 +00:00
}
- ( NSArray * ) sourceFileKeys
{
return nil ;
}
- ( NSArray * ) resourceFileKeys
{
return nil ;
}
- ( NSArray * ) otherKeys
{
return nil ;
}
- ( NSArray * ) buildTargets
{
return nil ;
}
- ( NSString * ) projectDescription
{
return @ "Abstract PCProject class!" ;
}
2000-11-04 13:20:40 +00:00
- ( BOOL ) isExecutable
{
return NO ;
}
2000-11-10 18:27:15 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === = =
// === = File Handling
// === === === === === === === === === === === === === === === === === === === === === === === === === = =
2000-08-27 19:11:42 +00:00
2002-02-21 10:05:42 +00:00
- ( void ) browserDidClickFile : ( NSString * ) fileName category : ( NSString * ) c
2000-10-15 18:24:09 +00:00
{
2002-02-11 22:19:39 +00:00
NSString * p = [ [ self projectPath ] stringByAppendingPathComponent : fileName ] ;
PCEditor * e ;
// Set the name in the inspector
2002-01-02 16:05:02 +00:00
[ fileNameField setStringValue : fileName ] ;
2002-02-11 22:19:39 +00:00
// Show the file in the internal editor !
2002-02-21 10:15:17 +00:00
e = [ editorController internalEditorForFile : p ] ;
2002-02-12 21:44:28 +00:00
if ( e = = nil )
{
NSLog ( @ "No editor for file '%@'..." , p ) ;
return ;
}
2002-02-11 22:19:39 +00:00
[ self showEditorView : self ] ;
2002-02-12 21:44:28 +00:00
[ e showInProjectEditor : projectEditor ] ;
2002-11-24 11:43:20 +00:00
[ projectWindow makeFirstResponder : ( NSResponder * ) [ projectEditor editorView ] ] ;
2000-10-15 18:24:09 +00:00
}
2002-02-21 10:05:42 +00:00
- ( void ) browserDidDblClickFile : ( NSString * ) fileName category : ( NSString * ) c
{
PCEditor * e ;
e = [ editorController editorForFile : fileName ] ;
if ( e )
{
[ e show ] ;
}
}
2000-08-27 19:11:42 +00:00
- ( BOOL ) doesAcceptFile : ( NSString * ) file forKey : ( NSString * ) type
{
if ( [ [ projectDict allKeys ] containsObject : type ] ) {
NSArray * files = [ projectDict objectForKey : type ] ;
if ( ! [ files containsObject : file ] ) {
return YES ;
}
}
return NO ;
}
- ( void ) addFile : ( NSString * ) file forKey : ( NSString * ) type
{
2002-01-02 16:05:02 +00:00
[ self addFile : file forKey : type copy : NO ] ;
2001-01-06 16:26:01 +00:00
}
2000-08-27 19:11:42 +00:00
2001-01-06 16:26:01 +00:00
- ( void ) addFile : ( NSString * ) file forKey : ( NSString * ) type copy : ( BOOL ) yn
{
2001-12-29 14:09:39 +00:00
NSArray * types = [ projectDict objectForKey : type ] ;
NSMutableArray * files = [ NSMutableArray arrayWithArray : types ] ;
NSString * lpc = [ file lastPathComponent ] ;
NSMutableString * newFile = [ NSMutableString stringWithString : lpc ] ;
2001-01-06 16:26:01 +00:00
2001-12-29 14:09:39 +00:00
if ( [ type isEqualToString : PCLibraries ] ) {
[ newFile deleteCharactersInRange : NSMakeRange ( 0 , 3 ) ] ;
2002-02-02 17:56:44 +00:00
newFile = ( NSMutableString * ) [ newFile stringByDeletingPathExtension ] ;
2001-12-29 14:09:39 +00:00
}
2001-01-06 16:26:01 +00:00
2001-12-29 14:09:39 +00:00
if ( [ files containsObject : newFile ] ) {
NSRunAlertPanel ( @ "Attention!" ,
@ "The file %@ is already part of this project!" ,
@ "OK" , nil , nil , newFile ) ;
return ;
}
2001-01-06 16:26:01 +00:00
2000-11-10 18:27:15 +00:00
# ifdef DEBUG
2001-12-29 14:09:39 +00:00
NSLog ( @ "<%@ %x>: adding file %@ for key %@" , [ self class ] , self , newFile , type ) ;
# endif // DEBUG
2001-01-06 16:26:01 +00:00
2001-12-29 14:09:39 +00:00
// Add the new file
[ files addObject : newFile ] ;
[ projectDict setObject : files forKey : type ] ;
2002-01-02 16:05:02 +00:00
[ projectWindow setDocumentEdited : YES ] ;
2001-01-06 16:26:01 +00:00
2001-12-29 14:09:39 +00:00
if ( yn ) {
NSFileManager * manager = [ NSFileManager defaultManager ] ;
NSString * destination = [ [ self projectPath ] stringByAppendingPathComponent : newFile ] ;
2000-08-27 19:11:42 +00:00
2001-12-29 14:09:39 +00:00
if ( ! [ manager copyPath : file toPath : destination handler : nil ] ) {
NSRunAlertPanel ( @ "Attention!" ,
@ "The file %@ could not be copied to %@!" ,
@ "OK" , nil , nil , newFile , destination ) ;
}
2001-01-06 16:26:01 +00:00
}
2002-02-21 11:25:33 +00:00
[ [ NSNotificationCenter defaultCenter ] postNotificationName : @ "ProjectDictDidChangeNotification" object : self ] ;
2000-08-27 19:11:42 +00:00
}
- ( void ) removeFile : ( NSString * ) file forKey : ( NSString * ) key
{
NSMutableArray * array ;
if ( ! file || ! key ) {
return ;
}
array = [ NSMutableArray arrayWithArray : [ projectDict objectForKey : key ] ] ;
[ array removeObject : file ] ;
[ projectDict setObject : array forKey : key ] ;
2002-01-02 16:05:02 +00:00
[ projectWindow setDocumentEdited : YES ] ;
2000-08-27 19:11:42 +00:00
}
- ( BOOL ) removeSelectedFilePermanently : ( BOOL ) yn
{
NSString * file = [ browserController nameOfSelectedFile ] ;
NSString * key ;
2000-09-17 12:13:10 +00:00
NSString * otherKey ;
NSString * ext ;
NSString * fn ;
BOOL ret = NO ;
2000-08-27 19:11:42 +00:00
if ( ! file ) {
return NO ;
}
key = [ self projectKeyForKeyPath : [ browserController pathOfSelectedFile ] ] ;
[ self removeFile : file forKey : key ] ;
2000-09-17 12:13:10 +00:00
if ( [ key isEqualToString : PCClasses ] ) {
otherKey = PCHeaders ;
ext = [ NSString stringWithString : @ "h" ] ;
fn = [ file stringByDeletingPathExtension ] ;
fn = [ fn stringByAppendingPathExtension : ext ] ;
if ( [ self doesAcceptFile : fn forKey : otherKey ] = = NO ) {
ret = NSRunAlertPanel ( @ "Removing Header?" , @ "Should %@ be removed from the project %@ as well?" , @ "Yes" , @ "No" , nil , fn , [ self projectName ] ) ;
}
}
else if ( [ key isEqualToString : PCHeaders ] ) {
otherKey = PCClasses ;
ext = [ NSString stringWithString : @ "m" ] ;
fn = [ file stringByDeletingPathExtension ] ;
fn = [ fn stringByAppendingPathExtension : ext ] ;
if ( [ self doesAcceptFile : fn forKey : otherKey ] = = NO ) {
ret = NSRunAlertPanel ( @ "Removing Class?" , @ "Should %@ be removed from the project %@ as well?" , @ "Yes" , @ "No" , nil , fn , [ self projectName ] ) ;
}
}
if ( ret ) {
[ self removeFile : fn forKey : otherKey ] ;
}
2000-08-27 19:11:42 +00:00
// Remove the file permanently ? !
if ( yn ) {
NSString * pth = [ projectPath stringByAppendingPathComponent : file ] ;
[ [ NSFileManager defaultManager ] removeFileAtPath : pth handler : nil ] ;
2000-09-17 12:13:10 +00:00
if ( ret ) {
pth = [ projectPath stringByAppendingPathComponent : fn ] ;
[ [ NSFileManager defaultManager ] removeFileAtPath : pth handler : nil ] ;
}
2000-08-27 19:11:42 +00:00
}
2002-02-21 11:29:38 +00:00
[ [ NSNotificationCenter defaultCenter ] postNotificationName : @ "ProjectDictDidChangeNotification" object : self ] ;
2000-08-27 19:11:42 +00:00
return YES ;
}
2000-10-15 18:24:09 +00:00
- ( void ) renameFile : ( NSString * ) aFile
{
}
2000-08-27 19:11:42 +00:00
- ( BOOL ) assignProjectDict : ( NSDictionary * ) aDict
{
NSAssert ( aDict , @ "No valid project dictionary!" ) ;
[ projectDict autorelease ] ;
projectDict = [ [ NSMutableDictionary alloc ] initWithDictionary : aDict ] ;
[ self setProjectName : [ projectDict objectForKey : PCProjectName ] ] ;
2003-04-21 13:46:10 +00:00
[ projectWindow setTitle : [ NSString stringWithFormat : @ "%@ - %@" ,
projectName ,
[ projectPath stringByAbbreviatingWithTildeInPath ] ] ] ;
2000-08-27 19:11:42 +00:00
2002-01-02 16:05:02 +00:00
// Update the interface
2000-11-10 18:27:15 +00:00
[ self updateValuesFromProjectDict ] ;
2000-08-27 19:11:42 +00:00
[ [ NSNotificationCenter defaultCenter ] postNotificationName : @ "ProjectDictDidChangeNotification" object : self ] ;
return YES ;
}
- ( NSDictionary * ) projectDict
{
return ( NSDictionary * ) projectDict ;
}
- ( void ) setProjectPath : ( NSString * ) aPath
{
[ projectPath autorelease ] ;
projectPath = [ aPath copy ] ;
}
- ( NSString * ) projectPath
{
return projectPath ;
}
- ( NSDictionary * ) rootCategories
{
return rootCategories ;
}
- ( BOOL ) save
{
2001-12-29 14:09:39 +00:00
BOOL ret = NO ;
2002-01-07 09:37:19 +00:00
NSString * file = [ [ projectPath stringByAppendingPathComponent : projectName ] stringByAppendingPathExtension : @ "pcproj" ] ;
2001-12-29 14:09:39 +00:00
NSString * backup = [ file stringByAppendingPathExtension : @ "backup" ] ;
NSFileManager * fm = [ NSFileManager defaultManager ] ;
NSUserDefaults * defs = [ NSUserDefaults standardUserDefaults ] ;
NSString * keepBackup = [ defs objectForKey : KeepBackup ] ;
BOOL shouldKeep = [ keepBackup isEqualToString : @ "YES" ] ;
2001-12-29 14:41:43 +00:00
if ( shouldKeep = = YES && [ fm isWritableFileAtPath : backup ] ) {
ret = [ fm removeFileAtPath : backup handler : nil ] ;
if ( ret = = NO ) {
NSRunAlertPanel ( @ "Attention!" ,
@ "Could not remove the old project backup '%@'!" ,
@ "OK" , nil , nil , backup ) ;
}
2001-12-29 14:09:39 +00:00
}
2002-03-02 13:11:05 +00:00
if ( shouldKeep && [ fm isReadableFileAtPath : file ] )
{
2001-12-29 14:09:39 +00:00
ret = [ fm copyPath : file toPath : backup handler : nil ] ;
2002-03-02 13:11:05 +00:00
if ( ret = = NO )
{
2001-12-29 14:09:39 +00:00
NSRunAlertPanel ( @ "Attention!" ,
2001-12-29 14:41:43 +00:00
@ "Could not save the project backup file '%@'!" ,
@ "OK" , nil , nil , file ) ;
2001-12-29 14:09:39 +00:00
}
}
ret = [ projectDict writeToFile : file atomically : YES ] ;
2002-01-02 16:05:02 +00:00
if ( ret = = YES )
{
[ projectWindow setDocumentEdited : NO ] ;
}
2002-03-02 13:11:05 +00:00
[ self saveAllFiles ] ;
2002-01-02 16:05:02 +00:00
[ self writeMakefile ] ;
2001-12-29 14:09:39 +00:00
return ret ;
2000-08-27 19:11:42 +00:00
}
- ( BOOL ) saveAt : ( NSString * ) projPath
{
2001-12-29 14:09:39 +00:00
return NO ;
2000-08-27 19:11:42 +00:00
}
2002-02-02 19:21:00 +00:00
- ( BOOL ) saveFile
2000-08-27 19:11:42 +00:00
{
2002-02-02 19:21:00 +00:00
return [ editorController saveFile ] ;
2000-08-27 19:11:42 +00:00
}
- ( BOOL ) saveAllFiles
{
2002-03-02 13:11:05 +00:00
return [ editorController saveAllFiles ] ;
2000-08-27 19:11:42 +00:00
}
- ( BOOL ) saveAllFilesIfNeeded
{
2001-12-29 14:09:39 +00:00
BOOL ret = YES ;
return ret ;
2000-08-27 19:11:42 +00:00
}
2002-02-02 19:21:00 +00:00
- ( BOOL ) revertFile
{
return [ editorController revertFile ] ;
}
2002-01-01 17:27:41 +00:00
- ( BOOL ) writeSpecFile
{
NSString * name = [ projectDict objectForKey : PCProjectName ] ;
NSString * specInPath = [ projectPath stringByAppendingPathComponent : name ] ;
NSMutableString * specIn = [ NSMutableString string ] ;
if ( [ [ projectDict objectForKey : PCRelease ] intValue ] < 1 )
{
NSRunAlertPanel ( @ "Spec Input File Creation!" ,
@ "The Release entry seems to be wrong, please fix it!" ,
@ "OK" , nil , nil ) ;
return NO ;
}
specInPath = [ specInPath stringByAppendingPathExtension : @ "spec.in" ] ;
[ specIn appendString : @ "# Automatically generated by ProjectCenter.app\n" ] ;
[ specIn appendString : @ "#\nsummary: " ] ;
[ specIn appendString : [ projectDict objectForKey : PCSummary ] ] ;
[ specIn appendString : @ "\nRelease: " ] ;
[ specIn appendString : [ projectDict objectForKey : PCRelease ] ] ;
[ specIn appendString : @ "\nCopyright: " ] ;
[ specIn appendString : [ projectDict objectForKey : PCCopyright ] ] ;
[ specIn appendString : @ "\nGroup: " ] ;
[ specIn appendString : [ projectDict objectForKey : PCGroup ] ] ;
[ specIn appendString : @ "\nSource: " ] ;
[ specIn appendString : [ projectDict objectForKey : PCSource ] ] ;
[ specIn appendString : @ "\n\n%description\n\n" ] ;
[ specIn appendString : [ projectDict objectForKey : PCDescription ] ] ;
return [ specIn writeToFile : specInPath atomically : YES ] ;
}
2000-11-10 18:27:15 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === = =
// === = Subprojects
// === === === === === === === === === === === === === === === === === === === === === === === === === = =
2000-08-27 19:11:42 +00:00
- ( NSArray * ) subprojects
{
return [ projectDict objectForKey : PCSubprojects ] ;
}
- ( void ) addSubproject : ( PCProject * ) aSubproject
{
}
- ( PCProject * ) superProject
{
return nil ;
}
- ( PCProject * ) rootProject
{
return self ;
}
- ( void ) newSubprojectNamed : ( NSString * ) aName
{
}
- ( void ) removeSubproject : ( PCProject * ) aSubproject
{
}
- ( BOOL ) isSubProject
{
2002-01-02 16:05:02 +00:00
return NO ;
2000-11-10 18:27:15 +00:00
}
// === === === === === === === === === === === === === === === === === === === === === === === === === = =
// === = Project Handling
// === === === === === === === === === === === === === === === === === === === === === === === === === = =
- ( void ) updateValuesFromProjectDict
{
2002-01-02 16:05:02 +00:00
[ projectTypeField setStringValue : [ projectDict objectForKey : PCProjType ] ] ;
[ installPathField setStringValue : [ projectDict objectForKey : PCInstallDir ] ] ;
[ toolField setStringValue : [ projectDict objectForKey : PCBuildTool ] ] ;
[ ccOptField setStringValue : [ projectDict objectForKey : PCCompilerOptions ] ] ;
[ ldOptField setStringValue : [ projectDict objectForKey : PCLinkerOptions ] ] ;
}
- ( void ) changeCommonProjectEntry : ( id ) sender
{
NSString * newEntry = [ sender stringValue ] ;
if ( sender = = installPathField )
{
[ projectDict setObject : newEntry forKey : PCInstallDir ] ;
}
else if ( sender = = toolField )
{
[ projectDict setObject : newEntry forKey : PCBuildTool ] ;
2002-01-02 17:43:11 +00:00
if ( ! [ [ NSFileManager defaultManager ] isExecutableFileAtPath : newEntry ] )
{
NSRunAlertPanel ( @ "Build Tool Error!" ,
@ "No valid executable found at '%@'!" ,
@ "OK" , nil , nil , newEntry ) ;
}
2002-01-02 16:05:02 +00:00
}
else if ( sender = = ccOptField )
{
[ projectDict setObject : newEntry forKey : PCCompilerOptions ] ;
}
else if ( sender = = ldOptField )
{
[ projectDict setObject : newEntry forKey : PCLinkerOptions ] ;
}
[ projectWindow setDocumentEdited : YES ] ;
2000-08-27 19:11:42 +00:00
}
2002-01-01 17:27:41 +00:00
- ( BOOL ) isValidDictionary : ( NSDictionary * ) aDict
{
NSString * _file ;
NSString * key ;
Class projClass = [ self builderClass ] ;
NSDictionary * origin ;
NSArray * keys ;
NSEnumerator * enumerator ;
_file = [ [ NSBundle bundleForClass : projClass ] pathForResource : @ "PC"
ofType : @ "proj" ] ;
origin = [ NSMutableDictionary dictionaryWithContentsOfFile : _file ] ;
keys = [ origin allKeys ] ;
enumerator = [ keys objectEnumerator ] ;
2002-04-26 03:12:50 +00:00
while ( ( key = [ enumerator nextObject ] ) )
2002-01-01 17:27:41 +00:00
{
if ( [ aDict objectForKey : key ] = = nil )
{
return NO ;
}
}
return YES ;
}
- ( void ) updateProjectDict
{
NSString * _file ;
NSString * key ;
Class projClass = [ self builderClass ] ;
NSDictionary * origin ;
NSArray * keys ;
NSEnumerator * enumerator ;
2002-01-02 16:05:02 +00:00
BOOL projectHasChanged = NO ;
2002-01-01 17:27:41 +00:00
_file = [ [ NSBundle bundleForClass : projClass ] pathForResource : @ "PC"
ofType : @ "proj" ] ;
origin = [ NSMutableDictionary dictionaryWithContentsOfFile : _file ] ;
keys = [ origin allKeys ] ;
enumerator = [ keys objectEnumerator ] ;
2003-04-29 04:33:39 +00:00
while ( ( key = [ enumerator nextObject ] ) )
2002-01-01 17:27:41 +00:00
{
if ( [ projectDict objectForKey : key ] = = nil )
{
[ projectDict setObject : [ origin objectForKey : key ] forKey : key ] ;
2002-01-02 16:05:02 +00:00
projectHasChanged = YES ;
2002-01-01 17:27:41 +00:00
NSRunAlertPanel ( @ "New Project Key!" ,
@ "The key '%@' has been added." ,
@ "OK" , nil , nil , key ) ;
}
}
2002-01-02 16:05:02 +00:00
if ( projectHasChanged = = YES )
{
[ projectWindow setDocumentEdited : YES ] ;
}
2002-01-01 17:27:41 +00:00
}
- ( void ) validateProjectDict
{
if ( [ self isValidDictionary : projectDict ] = = NO )
{
int ret = NSRunAlertPanel ( @ "Attention!" , @ "The project is not up to date, should it be updated automatically?" , @ "OK" , @ "No" , nil ) ;
if ( ret = = NSAlertDefaultReturn )
{
[ self updateProjectDict ] ;
[ self save ] ;
NSRunAlertPanel ( @ "Project updated!" , @ "The project file has been updated successfully!\nPlease make sure that all new project keys contain valid entries!" , @ "OK" , nil , nil ) ;
}
}
}
2000-08-27 19:11:42 +00:00
@ end
2002-02-11 22:19:39 +00:00
// === === === === === === === === === === === === === === === === === === === === === === === === === = =
// === === === === === === === === === === === === === === === === === === === === === === === === === = =
2000-08-27 19:11:42 +00:00
@ implementation PCProject ( ProjectKeyPaths )
- ( NSArray * ) contentAtKeyPath : ( NSString * ) keyPath
{
NSString * key ;
2000-11-01 10:38:57 +00:00
# ifdef DEBUG
2000-08-27 19:11:42 +00:00
NSLog ( @ "<%@ %x>: content at path %@" , [ self class ] , self , keyPath ) ;
2000-11-01 10:38:57 +00:00
# endif
2000-08-27 19:11:42 +00:00
if ( [ keyPath isEqualToString : @ "" ] || [ keyPath isEqualToString : @ "/" ] ) {
return [ rootCategories allKeys ] ;
}
key = [ [ keyPath componentsSeparatedByString : @ "/" ] lastObject ] ;
return [ projectDict objectForKey : [ rootCategories objectForKey : key ] ] ;
}
- ( BOOL ) hasChildrenAtKeyPath : ( NSString * ) keyPath
{
NSString * key ;
if ( ! keyPath || [ keyPath isEqualToString : @ "" ] ) {
return NO ;
}
key = [ [ keyPath componentsSeparatedByString : @ "/" ] lastObject ] ;
2000-09-17 12:13:10 +00:00
if ( [ [ rootCategories allKeys ] containsObject : key ] ||
[ [ projectDict objectForKey : PCSubprojects ] containsObject : key ] ) {
2000-08-27 19:11:42 +00:00
return YES ;
}
return NO ;
}
- ( NSString * ) projectKeyForKeyPath : ( NSString * ) kp
{
2000-09-17 12:13:10 +00:00
NSString * type = [ [ kp componentsSeparatedByString : @ "/" ] objectAtIndex : 1 ] ;
return [ rootCategories objectForKey : type ] ;
2000-08-27 19:11:42 +00:00
}
@ end
@ implementation PCProject ( ProjectWindowDelegate )
2002-02-11 22:19:39 +00:00
- ( void ) windowDidResignKey : ( NSNotification * ) aNotification
{
if ( editorIsActive )
{
[ [ NSNotificationCenter defaultCenter ] postNotificationName : PCEditorDidResignKeyNotification object : self ] ;
}
}
2000-08-27 19:11:42 +00:00
- ( void ) windowDidBecomeKey : ( NSNotification * ) aNotification
{
2002-02-11 22:19:39 +00:00
if ( editorIsActive )
{
[ [ NSNotificationCenter defaultCenter ] postNotificationName : PCEditorDidBecomeKeyNotification object : self ] ;
}
2000-09-17 12:13:10 +00:00
[ projectManager setActiveProject : self ] ;
2000-08-27 19:11:42 +00:00
}
- ( void ) windowDidBecomeMain : ( NSNotification * ) aNotification
{
2000-09-17 12:13:10 +00:00
[ projectManager setActiveProject : self ] ;
2000-08-27 19:11:42 +00:00
}
- ( void ) windowWillClose : ( NSNotification * ) aNotification
{
2000-09-17 12:13:10 +00:00
id object = [ aNotification object ] ;
2003-04-23 11:06:43 +00:00
2002-02-17 13:14:51 +00:00
if ( object = = [ self projectWindow ] )
2002-02-02 17:56:44 +00:00
{
2003-04-23 11:06:43 +00:00
if ( [ [ self projectWindow ] isDocumentEdited ] )
{
if ( NSRunAlertPanel ( @ "Project changed!" ,
@ "The project %@ has been edited! Should it be saved before closing?" ,
@ "Yes" , @ "No" , nil , [ self projectName ] ) )
{
[ self save ] ;
}
}
2002-02-17 13:14:51 +00:00
2003-04-23 11:06:43 +00:00
[ editorController closeAllEditors ] ;
2002-02-17 13:14:51 +00:00
2003-05-02 12:31:32 +00:00
if ( projectBuilder && [ projectBuilder buildPanel ] )
{
[ [ projectBuilder buildPanel ] performClose : self ] ;
[ [ projectBuilder buildPanel ] release ] ;
}
if ( projectDebugger && [ projectDebugger launchPanel ] )
{
[ [ projectDebugger launchPanel ] performClose : self ] ;
[ [ projectDebugger launchPanel ] release ] ;
}
2003-04-23 11:06:43 +00:00
// The PCProjectController is our delegate !
[ [ NSNotificationCenter defaultCenter ] removeObserver : browserController ] ;
[ projectManager closeProject : self ] ;
}
2000-09-17 12:13:10 +00:00
}
@ end