From ac1131830aed1c392ce89df0a7a3e662d2f4d633 Mon Sep 17 00:00:00 2001 From: Sergii Stoian Date: Wed, 28 Dec 2005 23:51:35 +0000 Subject: [PATCH] Merge local changes git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/apps/projectcenter/branches/UNSTABLE_0_5@22224 72102866-910b-0410-8b05-ffd578937521 --- Documentation/ChangeLog | 16 +- Documentation/SCHEME | 60 +- Documentation/TODO | 60 +- GNUmakefile | 30 +- GNUmakefile.postamble | 31 +- GNUmakefile.preamble | 14 +- Library/GNUmakefile | 63 +- Library/GNUmakefile.postamble | 17 +- Library/GNUmakefile.preamble | 11 +- Library/PCAddFilesPanel.m | 4 +- Library/PCButton.m | 8 +- Library/PCFileCreator.m | 87 +- Library/PCFileManager.m | 134 +++- Library/PCFileNameField.m | 2 +- Library/PCFileNameIcon.m | 34 +- Library/PCMakefileFactory.m | 98 ++- Library/PCProject.m | 1358 ++++++++++++++++++-------------- Library/PCProjectBrowser.m | 184 +++-- Library/PCProjectBuilder.m | 14 +- Library/PCProjectEditor.m | 402 ++++++---- Library/PCProjectInspector.m | 235 ++++-- Library/PCProjectLauncher.m | 17 +- Library/PCProjectLoadedFiles.m | 42 +- Library/PCProjectManager.m | 321 ++++---- Library/PCProjectWindow.m | 197 +++-- Library/PCSplitView.m | 2 +- PCAppController.m | 35 +- PCInfoController.m | 3 +- PCMenuController.m | 15 +- 29 files changed, 2088 insertions(+), 1406 deletions(-) diff --git a/Documentation/ChangeLog b/Documentation/ChangeLog index d1d8361..a969b7a 100644 --- a/Documentation/ChangeLog +++ b/Documentation/ChangeLog @@ -1,3 +1,17 @@ +2005-11-20 Serg Stoyan + + * Rewritte bundle loading mechanizm. Bundle now loaded on demand. + + * Created Protocols directory. + + * PCEditor and friends moved to loadable bundle Modules/Editors/ProjectCenter. + + * PCLogController.[hm] and PCPrefController.[hm] was moved to Library. + + * Fixes for MingW environment (thanks to Adam Fedor). + + * Added attempt to find make and debugger utilities. + 2005-09-11 Serg Stoyan * Library/PCProject.m: (saveProjectWindowsAndPanels): save ProjectBrowser @@ -9,7 +23,7 @@ Used for restoring saved frame of ProjectBrowser. In general, used to restore subviews size of horisontal and verstical split views from last session. "Remember project windows and panels in PC.project" task from - TODO file is considered fully comleted now. Use this scheme for other + TODO file is considered fully comleted now. Will use this scheme for other split views in PC. * Library/PCFileNameIcon.[hm]: new files. I'm not sure yet if it should diff --git a/Documentation/SCHEME b/Documentation/SCHEME index c2156c9..f441b6c 100644 --- a/Documentation/SCHEME +++ b/Documentation/SCHEME @@ -1,49 +1,51 @@ - +- PCProjectInspector - | - +- PCLoadedFilesPanel - | - +- PCBuildPanel - | - +- PCLaunchPanel - | - +- [SI]PCFindPanel -PCAppController-\ | +PCAppController-\ | ----- PCProjectManager PCMenuController/ | || - | PCProject + | PCProject -> + | | + | +- PCProjectInspector | | | +- PCProjectWindow | | | +- PCProjectBrowser | | | +- PCProjectLoadedFiles + | | | + | | +- PCProjectLoadedFilesPanel | | | +- PCProjectBuilder + | | | + | | +- PCProjectBuilderPanel | | | +- PCProjectLauncher + | | | + | | +- PCProjectLauncherPanel | | - | +- [SI]PCProjectFinder + | +- PCProjectEditor -> + | | -> | | - | +- PCProjectEditor - | || - | PCEditor + | +- [*]PCProjectFinder | | - | +- PCEditorView + | +- [*]PCProjectFinderPanel + | + +- PCFileManager + | | + | +- PCFileCreator + | | + | +- PCAddFilesPanel | - PCTextFinder + +- PCMakefileFactory (Used by project type bundles) | - PCFileManager - | - +- PCFileCreator + +- PCBundleManager (loading of project types,editors,parsers) + +--- +[*] - not implemented ------------------------------ Other (controls, tools, etc.): ------------------------------ -PCButton (ProjectWindow, ProjectBuild, ProjectLaunch) -PCSplitView (ProjectWindow, ProjectBuild, ProjectLaunch) -PCBundleLoader (Used in ProjectCenter application) -PCMakefileFactory (Used in PC*Project bundles) -PCServer (don't used) +PCButton (ProjectWindow, ProjectBuilder, ProjectLauncher) +PCSplitView (ProjectWindow, ProjectBuilder, ProjectLauncher) ---------- THOUGHTS: @@ -62,10 +64,10 @@ THOUGHTS: Localization: ~~~~~~~~~~~~~ - On project creation, all resources go to Resources subdir and placed into - GNUmakefile as *_RESOURCE_FILES; [done!] + GNUmakefile as *_RESOURCE_FILES; [DONE!] - If some file from [PC*Proj localizableKeys] categories selected as "Localizable Resource", that file removed from *_RESOURCE_FILES and placed - into *_LOCALIZED_RESOURCE_FILES (for directories: Resources->Language.lproj); -- in PC.project add USER_LANGUAGES=(); [done!] -- in PC.project add LOCALIZED_RESOURCES=(); [done!] + into *_LOCALIZED_RESOURCE_FILES (for directories: .lproj); [] +- in PC.project add USER_LANGUAGES=(); [DONE!] +- in PC.project add LOCALIZED_RESOURCES=(); [] diff --git a/Documentation/TODO b/Documentation/TODO index d805991..36cef8e 100644 --- a/Documentation/TODO +++ b/Documentation/TODO @@ -1,20 +1,20 @@ TODO **** -This is the GNUstep ProjectCenter TODO list. "+" means that this task -is done. Feel free to propose changes to this list or make suggestions! +This is the GNUstep ProjectCenter TODO list. +Feel free to propose changes to this list or make suggestions! ProjectCenter 0.4 Owner ----------------- ------ -- Review and cleanup of PC project bundles/templates [done!] -- Finish Project Inspector [done!] -- Inspector UI using Gorm [done!] +- Review and cleanup of PC project bundles/templates [done!] +- Finish Project Inspector [done!] +- Inspector UI using Gorm [done!] - File creation (File->New in project) cleanup and finishing [done!] - Initial suprojects support [done!] -- Finish support of external editors [done!] -- Preferences enhancements and UI using Gorm [done!] -- Remember project windows and panels in PC.project [done!] +- Finish support of external editors [done!] +- Preferences enhancements and UI using Gorm [done!] +- Remember project windows and panels in PC.project [done!] ProjectCenter 0.5 ----------------- @@ -24,43 +24,53 @@ ProjectCenter 0.5 - Add "Resource Set" project type [done!] - Add "Palette" project type stoyan - Add "Component" project type stoyan +- Implement on demand loading of bundles [done!] +- Localization support for projects [done!] +- Finish save/restore size of split views in Project Window [done!] +- Save last used path separately for different file panels stoyan +--- Project Editor: + - Implement on demand loading (editor for file type) stoyan + - Open some files read only (Supporting Files) stoyan + - Implement code parser (get it from CodeEditor?) stoyan + - Project Browser should show file structure. stoyan + - Click on Browser item should move cursor to line in file stoyan + - Implement Editor indentation stoyan +--- Project Builder: + - Implement root build directory handling stoyan + - Parse gcc output + - Display warnings,errors,options etc. as clickable list stoyan +- Imlement pending adding/removal of files (history?) stoyan - Finish FileNameIcon (draggable, files can be dragged to it) stoyan -- Editor code parser (get it from CodeEditor?) stoyan -- Project Browser should show classes, #define's an so on stoyan -- Implement Editor indentation stoyan -- Implement Editor syntax highlighting stoyan -- Implement root build directory handling stoyan -- ProjectBuilder enhancements (warnings,errors,options etc.) stoyan -- Localization support for projects stoyan -- Add pending adding/removal of files stoyan +- Review all dialogs and situations when dialogs must be + popped up stoyan ProjectCenter 0.6 ----------------- -- Create custom Info panel ??? +- Rewrite Preferences (3rd party sections etc.) stoyan +- Implement Editor syntax highlighting stoyan - More options for file creation ??? -- Direct code documentation (using autogsdoc) ??? -- Better integration with other tools - (Gorm, CodeEditor, EasyDiff) ??? -- ProjectCenter localization ??? +- Better integration with other tools (Gorm) ??? +- Create custom Info panel ??? ProjectCenter 0.7 ----------------- -- Initial user documentation ??? -- Initial support for integrated debugging ??? -- Optimised support for integrated debugging ??? +- An initial project wide find feature ??? +- Implement support for integrated debugging ??? - More project customisation possibilities ??? - CVS integration ??? ProjectCenter 0.8 ----------------- -- An initial project wide find feature ??? +- Initial user documentation ??? +- Direct code documentation (using autogsdoc) ??? ProjectCenter 0.9 ----------------- +- ProjectCenter localization ??? - An initial class browser/documentation feature ??? ProjectCenter 1.0 diff --git a/GNUmakefile b/GNUmakefile index a8e9711..af5d35d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -18,15 +18,13 @@ ProjectCenter_APPLICATION_ICON = Images/ProjectCenter.tiff # SUBPROJECTS = \ Library \ - Modules \ + Modules # # Resource files # ProjectCenter_RESOURCE_FILES = \ Resources/ProjectCenter.gorm \ -Resources/LogPanel.gorm \ -Resources/Preferences.gorm \ Resources/Info-gnustep.plist \ Images/ProjectCenter.tiff \ Images/FileC.tiff \ @@ -77,23 +75,23 @@ Images/soundSuitcase.tiff \ Images/soundSuitcaseH.tiff \ Images/subprojectSuitcase.tiff \ Images/subprojectSuitcaseH.tiff \ -Modules/AggregateProject/Aggregate.project \ -Modules/ApplicationProject/Application.project \ -Modules/BundleProject/Bundle.project \ -Modules/FrameworkProject/Framework.project \ -Modules/LibraryProject/Library.project \ -Modules/ResourceSetProject/ResourceSet.project \ -Modules/ToolProject/Tool.project +Modules/Projects/Aggregate/Aggregate.project \ +Modules/Projects/Application/Application.project \ +Modules/Projects/Bundle/Bundle.project \ +Modules/Projects/Framework/Framework.project \ +Modules/Projects/Library/Library.project \ +Modules/Projects/ResourceSet/ResourceSet.project \ +Modules/Projects/Tool/Tool.project \ +Modules/Editors/ProjectCenter/ProjectCenter.editor \ +Modules/Parsers/ProjectCenter/ProjectCenter.parser # # Header files # ProjectCenter_HEADERS = \ -PCAppController.h \ -PCInfoController.h \ -PCLogController.h \ -PCMenuController.h \ -PCPrefController.h +Headers/PCAppController.h \ +Headers/PCInfoController.h \ +Headers/PCMenuController.h # # Class files @@ -101,9 +99,7 @@ PCPrefController.h ProjectCenter_OBJC_FILES = \ PCAppController.m \ PCInfoController.m \ -PCLogController.m \ PCMenuController.m \ -PCPrefController.m \ ProjectCenter_main.m -include GNUmakefile.preamble diff --git a/GNUmakefile.postamble b/GNUmakefile.postamble index c57708a..5fa6b18 100644 --- a/GNUmakefile.postamble +++ b/GNUmakefile.postamble @@ -20,8 +20,37 @@ # If not, write to the Free Software Foundation, # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -before-all:: +#HEADER_LINK_DEPENDS=link-setup +#before-all:: header-links + +before-install:: + cp -r Headers/Protocols Library/ProjectCenter.framework/Headers + after-clean:: +# rm -rf ProjectCenter $(HEADER_LINK_DEPENDS) after-uninstall:: + +# FIXME: Temporary solution to Library being in the wrong place - we really +# should just move the directory in CVS +#DO_HEADER_LINKS=no +#ifeq ($(GNUSTEP_TARGET_OS), mingw32) +# DO_HEADER_LINKS=yes +#endif +#ifeq ($(GNUSTEP_TARGET_OS), cygwin) +# DO_HEADER_LINKS=yes +#endif +#ifeq ($(DO_HEADER_LINKS), yes) +#header-links: $(HEADER_LINK_DEPENDS) +# -rm -rf ProjectCenter +# -mkdir ProjectCenter +# cp -f Library/*.h ProjectCenter +#else +#header-links: $(HEADER_LINK_DEPENDS) +# -rm -f ProjectCenter +# $(LN_S) Library ProjectCenter +#endif + +#$(HEADER_LINK_DEPENDS): +# touch $(HEADER_LINK_DEPENDS) diff --git a/GNUmakefile.preamble b/GNUmakefile.preamble index 9647474..eb82e39 100644 --- a/GNUmakefile.preamble +++ b/GNUmakefile.preamble @@ -30,20 +30,23 @@ ADDITIONAL_CPPFLAGS += # Additional flags to pass to the Objective-C compiler -ADDITIONAL_OBJCFLAGS += +ADDITIONAL_OBJCFLAGS += # Additional flags to pass to the C compiler ADDITIONAL_CFLAGS += # Additional include directories the compiler should search -ADDITIONAL_INCLUDE_DIRS += -I./ +ADDITIONAL_INCLUDE_DIRS += -I./ -I./Headers # Additional LDFLAGS to pass to the linker -ADDITIONAL_LDFLAGS += -lProjectCenter +ADDITIONAL_LDFLAGS += # Additional library directories the linker should search -#ADDITIONAL_LIB_DIRS += -L./Library/$(GNUSTEP_OBJ_DIR) -ADDITIONAL_LIB_DIRS += -L./Library/ProjectCenter.framework/Versions/Current +ADDITIONAL_LIB_DIRS += -L./Library/ProjectCenter.framework/Versions/Current \ + -L./Library/ProjectCenter.framework + +# Additional LDFLAGS to pass to the linker +ADDITIONAL_GUI_LIBS += -lProjectCenter # # Flags dealing with installing and uninstalling @@ -51,3 +54,4 @@ ADDITIONAL_LIB_DIRS += -L./Library/ProjectCenter.framework/Versions/Current # Additional directories to be created during installation ADDITIONAL_INSTALL_DIRS += + diff --git a/Library/GNUmakefile b/Library/GNUmakefile index 1e0c7a8..3d2d8b3 100644 --- a/Library/GNUmakefile +++ b/Library/GNUmakefile @@ -13,6 +13,7 @@ VERSION = 0.5.0 FRAMEWORK_NAME = ProjectCenter ProjectCenter_CURRENT_VERSION_NAME = 0.5.0 ProjectCenter_DEPLOY_WITH_CURRENT_VERSION = yes +ProjectCenter_HEADER_FILES_DIR = ../Headers/ProjectCenter ProjectCenter_LIBRARIES_DEPEND_UPON += -lgnustep-gui @@ -25,80 +26,64 @@ ProjectCenter_LIBRARIES_DEPEND_UPON += -lgnustep-gui # Header files # ProjectCenter_HEADER_FILES = \ - PCBundleLoader.h \ + PCDefines.h \ + ProjectCenter.h \ + \ + PCBundleManager.h \ PCFileManager.h \ PCAddFilesPanel.h \ PCFileCreator.h \ - PCServer.h \ PCMakefileFactory.h \ - PCSplitView.h \ - PCButton.h \ - PCFileNameField.h \ - PCFileNameIcon.h \ - PCObjCParser.h \ \ PCProjectManager.h \ - PCBuildPanel.h \ - PCLaunchPanel.h \ - PCLoadedFilesPanel.h \ PCProject.h \ PCProjectWindow.h \ PCProjectInspector.h \ PCProjectBuilder.h \ + PCProjectBuilderPanel.h \ PCProjectLauncher.h \ + PCProjectLauncherPanel.h \ PCProjectEditor.h \ \ PCProjectBrowser.h \ PCProjectLoadedFiles.h \ + PCProjectLoadedFilesPanel.h \ \ - PCEditor.h \ - PCEditorView.h \ - PCEditorView+Highlighting.h \ - PCTextFinder.h \ - PCTextFinder+UInterface.h \ - \ - PCDefines.h \ - ProjectCenter.h \ - ProjectType.h \ - Server.h \ - CodeParser.h + PCPrefController.h \ + PCLogController.h # # Class files # ProjectCenter_OBJC_FILES = \ - PCBundleLoader.m \ + PCBundleManager.m \ + PCMakefileFactory.m \ PCFileManager.m \ PCAddFilesPanel.m \ PCFileCreator.m \ - PCServer.m \ - PCMakefileFactory.m \ - PCSplitView.m \ - PCButton.m \ - PCFileNameField.m \ - PCFileNameIcon.m \ - PCObjCParser.m \ \ PCProjectManager.m \ - PCBuildPanel.m \ - PCLaunchPanel.m \ - PCLoadedFilesPanel.m \ PCProject.m \ PCProjectWindow.m \ PCProjectInspector.m \ PCProjectBuilder.m \ + PCProjectBuilderPanel.m \ PCProjectLauncher.m \ + PCProjectLauncherPanel.m \ PCProjectEditor.m \ \ PCProjectBrowser.m \ PCProjectLoadedFiles.m \ + PCProjectLoadedFilesPanel.m \ \ - PCEditor.m \ - PCEditorView.m \ - PCEditorView+Highlighting.m \ - PCTextFinder.m \ - PCTextFinder+UInterface.m + PCSplitView.m \ + PCButton.m \ + PCFileNameField.m \ + PCFileNameIcon.m \ + \ + PCPrefController.m \ + PCLogController.m # # Resources @@ -118,7 +103,9 @@ ProjectCenter_RESOURCE_FILES = \ Resources/gsmarkup.template \ Resources/header.template \ Resources/postamble.template \ - Resources/protocol.template + Resources/protocol.template \ + Resources/LogPanel.gorm \ + Resources/Preferences.gorm -include GNUmakefile.preamble diff --git a/Library/GNUmakefile.postamble b/Library/GNUmakefile.postamble index fce9554..a8e3f69 100644 --- a/Library/GNUmakefile.postamble +++ b/Library/GNUmakefile.postamble @@ -22,14 +22,15 @@ # If not, write to the Free Software Foundation, # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -before-all:: - cd ..;rm -f ProjectCenter;$(LN_S) Library ProjectCenter +#before-all:: +# cd ..;rm -f ProjectCenter;$(LN_S) Library ProjectCenter -after-clean:: - rm -f ../ProjectCenter +#after-clean:: +# rm -f ../ProjectCenter -after-uninstall:: -# rm -rf $(GNUSTEP_SYSTEM_ROOT)/Library/Headers/ProjectCenter -# rm -rf $(GNUSTEP_SYSTEM_ROOT)/Library/Libraries/Resources/ProjectCenter - rm -rf $(GNUSTEP_SYSTEM_ROOT)/Library/Libraries/libProjectCenter* +#after-uninstall:: +# rm -rf $(GNUSTEP_SYSTEM_ROOT)/Library/Libraries/libProjectCenter* +#after-install:: +# cp -r Protocols $(GNUSTEP_SYSTEM_ROOT)/Library/Headers/ProjectCenter +# cp -r Widgets $(GNUSTEP_SYSTEM_ROOT)/Library/Headers/ProjectCenter diff --git a/Library/GNUmakefile.preamble b/Library/GNUmakefile.preamble index e1a5e6c..f8d6252 100644 --- a/Library/GNUmakefile.preamble +++ b/Library/GNUmakefile.preamble @@ -33,6 +33,10 @@ # be put into Makefile.postamble. # +# TODO: Make sure if it's portable +GMAKE = `which gmake` +GDB = `which gdb` + # # Flags dealing with compiling and linking # @@ -41,16 +45,17 @@ ADDITIONAL_CPPFLAGS += # Additional flags to pass to the Objective-C compiler -ADDITIONAL_OBJCFLAGS += -Wall +ADDITIONAL_OBJCFLAGS += -Wall -DPCDefaultBuildTool=@"\"$(GMAKE)\"" \ + -DPCDefaultDebugger=@"\"$(GDB)\"" # Additional flags to pass to the C compiler ADDITIONAL_CFLAGS += # Additional include directories the compiler should search -ADDITIONAL_INCLUDE_DIRS += -I../ +ADDITIONAL_INCLUDE_DIRS += -I../ -I../Headers # Additional LDFLAGS to pass to the linker -#ADDITIONAL_LDFLAGS += +ADDITIONAL_LDFLAGS += # Additional library directories the linker should search ADDITIONAL_LIB_DIRS += -L../ProjectCenter/$(GNUSTEP_OBJ_DIR) diff --git a/Library/PCAddFilesPanel.m b/Library/PCAddFilesPanel.m index 7d987e6..8ed8b8f 100644 --- a/Library/PCAddFilesPanel.m +++ b/Library/PCAddFilesPanel.m @@ -22,8 +22,8 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCLogController.h" -#include "PCAddFilesPanel.h" +#include +#include static PCAddFilesPanel *addFilesPanel = nil; diff --git a/Library/PCButton.m b/Library/PCButton.m index 1ba9e19..d0c92b2 100644 --- a/Library/PCButton.m +++ b/Library/PCButton.m @@ -22,11 +22,11 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCButton.h" -#include "PCDefines.h" +#include +#include -#include "AppKit/NSBezierPath.h" -#include "GNUstepGUI/GSTrackingRect.h" +#include +#include @implementation PCButton diff --git a/Library/PCFileCreator.m b/Library/PCFileCreator.m index fc48a96..09e4dce 100644 --- a/Library/PCFileCreator.m +++ b/Library/PCFileCreator.m @@ -23,12 +23,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCDefines.h" -#include "PCProject.h" -#include "PCFileManager.h" -#include "PCFileCreator.h" +#include +#include +#include +#include -#include "PCLogController.h" +#include @implementation PCFileCreator @@ -122,10 +122,10 @@ static NSDictionary *dict = nil; project:(PCProject *)aProject { PCFileManager *pcfm = [PCFileManager defaultManager]; - NSString *_file; + NSString *_file = nil; NSString *newFile = nil; - NSMutableDictionary *files; - NSBundle *bundle; + NSMutableDictionary *files = nil; + NSBundle *bundle = nil; // A class and possibly a header files = [NSMutableDictionary dictionaryWithCapacity:2]; @@ -135,39 +135,33 @@ static NSDictionary *dict = nil; bundle = [NSBundle bundleForClass:[self class]]; newFile = [path copy]; + // Remove file extension from "path" + if (![[path pathExtension] isEqualToString: @""]) + { + path = [path stringByDeletingPathExtension]; + } + /* * Objective-C Class */ if ([type isEqualToString:ObjCClass]) { _file = [bundle pathForResource:@"class" ofType:@"template"]; - if ([[path pathExtension] isEqual: @"m"] == NO) - { - newFile = [path stringByAppendingPathExtension:@"m"]; - } + newFile = [path stringByAppendingPathExtension:@"m"]; [pcfm copyFile:_file toFile:newFile]; + [self replaceTagsInFileAtPath:newFile withProject:aProject]; [files setObject:ObjCClass forKey:newFile]; - - [self replaceTagsInFileAtPath:newFile withProject:aProject]; - - // Header must be created as well! - newFile = [path stringByAppendingPathExtension:@"h"]; - _file = [bundle pathForResource:@"header" ofType:@"template"]; - [pcfm copyFile:_file toFile:newFile]; - - [self replaceTagsInFileAtPath:newFile withProject:aProject]; - [files setObject:ObjCHeader forKey:newFile]; } + /* * Objective-C Header + * When creating Objective C Class file also create Objective C Header file */ - else if ([type isEqualToString:ObjCHeader]) + if ([type isEqualToString:ObjCHeader] || + [type isEqualToString:ObjCClass]) { _file = [bundle pathForResource:@"header" ofType:@"template"]; - if ([[path pathExtension] isEqual: @"h"] == NO) - { - newFile = [path stringByAppendingPathExtension:@"h"]; - } + newFile = [path stringByAppendingPathExtension:@"h"]; [pcfm copyFile:_file toFile:newFile]; [self replaceTagsInFileAtPath:newFile withProject:aProject]; [files setObject:ObjCHeader forKey:newFile]; @@ -176,36 +170,24 @@ static NSDictionary *dict = nil; /* * C File */ - else if ([type isEqualToString:CFile]) + if ([type isEqualToString:CFile]) { _file = [bundle pathForResource:@"cfile" ofType:@"template"]; - if ([[path pathExtension] isEqual: @"c"] == NO) - { - newFile = [path stringByAppendingPathExtension:@"c"]; - } + newFile = [path stringByAppendingPathExtension:@"c"]; [pcfm copyFile:_file toFile:newFile]; + [self replaceTagsInFileAtPath:newFile withProject:aProject]; [files setObject:CFile forKey:newFile]; - - [self replaceTagsInFileAtPath:newFile withProject:aProject]; - - // Header should be created as well. - newFile = [path stringByAppendingPathExtension:@"h"]; - _file = [bundle pathForResource:@"cheader" ofType:@"template"]; - [pcfm copyFile:_file toFile:newFile]; - - [self replaceTagsInFileAtPath:newFile withProject:aProject]; - [files setObject:CHeader forKey:newFile]; } + /* * C Header + * When creating C file also create C Header file */ - else if ([type isEqualToString:CHeader]) + if ([type isEqualToString:CHeader] || + [type isEqualToString:CFile]) { _file = [bundle pathForResource:@"cheader" ofType:@"template"]; - if ([[path pathExtension] isEqual: @"h"] == NO) - { - newFile = [path stringByAppendingPathExtension:@"h"]; - } + newFile = [path stringByAppendingPathExtension:@"h"]; [pcfm copyFile:_file toFile:newFile]; [self replaceTagsInFileAtPath:newFile withProject:aProject]; [files setObject:CHeader forKey:newFile]; @@ -216,10 +198,7 @@ static NSDictionary *dict = nil; else if ([type isEqualToString:GSMarkupFile]) { _file = [bundle pathForResource:@"gsmarkup" ofType:@"template"]; - if ([[path pathExtension] isEqual: @"gsmarkup"] == NO) - { - newFile = [path stringByAppendingPathExtension:@"gsmarkup"]; - } + newFile = [path stringByAppendingPathExtension:@"gsmarkup"]; [pcfm copyFile:_file toFile:newFile]; [files setObject:GSMarkupFile forKey:newFile]; } @@ -229,14 +208,12 @@ static NSDictionary *dict = nil; else if ([type isEqualToString:ProtocolFile]) { _file = [bundle pathForResource:@"protocol" ofType:@"template"]; - if ([[path pathExtension] isEqual: @"h"] == NO) - { - newFile = [path stringByAppendingPathExtension:@"h"]; - } + newFile = [path stringByAppendingPathExtension:@"h"]; [pcfm copyFile:_file toFile:newFile]; [self replaceTagsInFileAtPath:newFile withProject:aProject]; [files setObject:ProtocolFile forKey:newFile]; } + /* * Notify the browser! */ diff --git a/Library/PCFileManager.m b/Library/PCFileManager.m index dbf1c93..bff9320 100644 --- a/Library/PCFileManager.m +++ b/Library/PCFileManager.m @@ -23,16 +23,15 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCDefines.h" -#include "PCFileManager.h" -#include "PCFileCreator.h" -#include "PCProjectManager.h" -#include "PCProject.h" -#include "PCProjectBrowser.h" -#include "PCServer.h" -#include "PCAddFilesPanel.h" +#include +#include +#include +#include +#include +#include +#include -#include "PCLogController.h" +#include @implementation PCFileManager @@ -84,8 +83,16 @@ static PCFileManager *_mgr = nil; [super dealloc]; } +- (BOOL) fileManager:(NSFileManager *)manager + shouldProceedAfterError:(NSDictionary *)errorDict +{ + NSLog(@"FM error is: %@", [errorDict objectForKey:@"Error"]); + + return YES; +} + // =========================================================================== -// ==== File stuff +// ==== File handling // =========================================================================== - (NSMutableArray *)filesForOpenOfType:(NSArray *)types @@ -201,11 +208,13 @@ static PCFileManager *_mgr = nil; directoryPath = [toFile stringByDeletingLastPathComponent]; if ([self createDirectoriesIfNeededAtPath:directoryPath] == NO) { + NSLog(@"PCFileManager: createDirectoriesIfNeededAtPath: == NO"); return NO; } - if (![fm copyPath:file toPath:toFile handler:nil]) + if ([fm copyPath:file toPath:toFile handler:self] == NO) { + NSLog(@"PCFileManager: copyPath:toPath: == NO"); return NO; } } @@ -232,6 +241,27 @@ static PCFileManager *_mgr = nil; return YES; } +- (BOOL)copyFile:(NSString *)file + fromDirectory:(NSString *)fromDir + intoDirectory:(NSString *)toDir +{ + NSString *path = nil; + + if (!file || !fromDir || !toDir) + { + return NO; + } + + path = [fromDir stringByAppendingPathComponent:[file lastPathComponent]]; + + if (![self copyFile:path intoDirectory:toDir]) + { + return NO; + } + + return YES; +} + - (BOOL)copyFiles:(NSArray *)files intoDirectory:(NSString *)directory { NSEnumerator *enumerator = nil; @@ -283,9 +313,32 @@ static PCFileManager *_mgr = nil; path = [directory stringByAppendingPathComponent:file]; if (![fm removeFileAtPath:path handler:nil]) { + NSLog(@"PCFileManager: removeFileAtPath: == NO"); return NO; } + [self removeDirectoriesIfEmptyAtPath:directory]; + + return YES; +} + +- (BOOL)removeFileAtPath:(NSString *)file +{ + NSFileManager *fm = [NSFileManager defaultManager]; + + if (!file) + { + return NO; + } + + if (![fm removeFileAtPath:file handler:nil]) + { + return NO; + } + + [self + removeDirectoriesIfEmptyAtPath:[file stringByDeletingLastPathComponent]]; + return YES; } @@ -311,6 +364,20 @@ static PCFileManager *_mgr = nil; return YES; } +- (BOOL)moveFile:(NSString *)file intoDirectory:(NSString *)directory +{ + if ([self copyFile:file intoDirectory:directory] == YES) + { + [self removeFileAtPath:file]; + } + else + { + return NO; + } + + return YES; +} + - (void)createFile { NSString *path = nil; @@ -557,3 +624,48 @@ static PCFileManager *_mgr = nil; @end +@implementation PCFileManager (FileType) + +/** + * Returns YES if the file identified by `filename' is a text file, + * otherwise returns NO. + * + * The test is one by reading the first 512 bytes of the file + * and checking whether at least 90% of the data are printable + * ASCII characters. + * + * Author Saso Kiselkov + */ +- (BOOL)isTextFile:(NSString *)filename +{ + NSFileHandle *fh; + NSData *data; + unsigned int i, n; + const char *buf; + unsigned int printable; + + fh = [NSFileHandle fileHandleForReadingAtPath:filename]; + if (fh == nil) + { + return NO; + } + + data = [fh readDataOfLength:512]; + if ([data length] == 0) + { + return YES; + } + + buf = [data bytes]; + for (i = printable = 0, n = [data length]; i < n; i++) + { + if (isprint(buf[i]) || isspace(buf[i])) + { + printable++; + } + } + + return (((double) printable / n) > 0.9); +} + +@end diff --git a/Library/PCFileNameField.m b/Library/PCFileNameField.m index d51fe66..453ce92 100644 --- a/Library/PCFileNameField.m +++ b/Library/PCFileNameField.m @@ -24,7 +24,7 @@ #include -#include "PCFileNameField.h" +#include @implementation PCFileNameField diff --git a/Library/PCFileNameIcon.m b/Library/PCFileNameIcon.m index 5b6d007..64c3625 100644 --- a/Library/PCFileNameIcon.m +++ b/Library/PCFileNameIcon.m @@ -24,9 +24,9 @@ #include -#include "PCDefines.h" -#include "PCFileNameIcon.h" -#include "PCProjectBrowser.h" +#include +#include +#include @implementation PCFileNameIcon @@ -35,13 +35,6 @@ filePath = nil; msfText = nil; [self setImage:[NSImage imageNamed:@"projectSuitcase"]]; - - // Browser - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector (setFileIcon:) - name:PCBrowserDidSetPathNotification - object:nil]; } - (id)initWithFrame:(NSRect)frameRect @@ -54,13 +47,6 @@ [self setEditable:NO]; [self setImage:[NSImage imageNamed:@"projectSuitcase"]]; - // Browser - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector (setFileIcon:) - name:PCBrowserDidSetPathNotification - object:nil]; - return self; } @@ -87,9 +73,8 @@ msfText = [text copy]; } -- (void)setFileIcon:(NSNotification *)notification +- (void)setFileIcon:(id)object { - id object = [notification object]; NSString *categoryName = nil; NSString *fileName = nil; NSString *fileExtension = nil; @@ -193,18 +178,17 @@ @"%i files", [[object selectedFiles] count]]]; } } - else if (fileName) - { - [fileNameField setStringValue:fileName]; - } else if (categoryName) { [fileNameField setStringValue:categoryName]; } + else if (fileName) + { + [fileNameField setStringValue:fileName]; + } else { -// [fileNameField setStringValue:[project projectName]]; -// [inspector setFileName:nil andIcon:nil]; + [fileNameField setStringValue:@"No files selected"]; } } diff --git a/Library/PCMakefileFactory.m b/Library/PCMakefileFactory.m index 7c16259..53b156b 100644 --- a/Library/PCMakefileFactory.m +++ b/Library/PCMakefileFactory.m @@ -23,9 +23,9 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCDefines.h" -#include "PCProject.h" -#include "PCMakefileFactory.h" +#include +#include +#include #define COMMENT_HEADERS @"\n\n#\n# Header files\n#\n" #define COMMENT_RESOURCES @"\n\n#\n# Resource files\n#\n" @@ -59,12 +59,12 @@ static PCMakefileFactory *_factory = nil; - (void)createMakefileForProject:(NSString *)prName { - NSAssert( prName, @"No project name given!"); + NSAssert(prName, @"No project name given!"); - AUTORELEASE( mfile ); + AUTORELEASE(mfile); mfile = [[NSMutableString alloc] init]; - AUTORELEASE( pnme ); + AUTORELEASE(pnme); pnme = [prName copy]; [mfile appendString:@"#\n"]; @@ -244,7 +244,9 @@ static PCMakefileFactory *_factory = nil; - (void)appendClasses:(NSArray *)array { if (array == nil || [array count] == 0) - return; + { + return; + } [self appendClasses:array forTarget:pnme]; } @@ -252,7 +254,9 @@ static PCMakefileFactory *_factory = nil; - (void)appendClasses:(NSArray *)array forTarget:(NSString *)target { if (array == nil || [array count] == 0) - return; + { + return; + } [self appendString:COMMENT_CLASSES]; [self appendString: @@ -264,7 +268,9 @@ static PCMakefileFactory *_factory = nil; - (void)appendOtherSources:(NSArray *)array { if (array == nil || [array count] == 0) - return; + { + return; + } [self appendOtherSources: array forTarget: pnme]; } @@ -277,7 +283,9 @@ static PCMakefileFactory *_factory = nil; NSString *file; if (array == nil || [array count] == 0) - return; + { + return; + } // Other Sources can have both .m files and non .m files oenum = [array objectEnumerator]; @@ -331,25 +339,83 @@ static PCMakefileFactory *_factory = nil; } } -- (void)appendResources +- (void)appendResources:(NSArray *)array inDir:(NSString *)dir { + int i = 0; + int count = [array count]; + NSString *string = nil; + NSString *item = nil; + NSString *eol = [NSString stringWithString:@"\\\n"]; + + if (array == nil || count <= 0) + { + return; + } + + // Header [self appendString:COMMENT_RESOURCES]; [self appendString: - [NSString stringWithFormat:@"%@_RESOURCE_FILES = ",pnme]]; + [NSString stringWithFormat:@"%@_RESOURCE_FILES = \\\n",pnme]]; + + // Items + for (i = 0; i < count; i++) + { + item = [array objectAtIndex:i]; + string = [NSString stringWithFormat:@"%@/%@ %@", dir, item, eol]; + [self appendString:string]; + if (i == (count-2)) + { + eol = [NSString stringWithString:@"\n"]; + } + } } - (void)appendResourceItems:(NSArray *)array { if (array == nil || [array count] <= 0) - return; + { + return; + } [self appendString:@"\\\n"]; [self appendString:[array componentsJoinedByString:@" \\\n"]]; } -- (void)appendLocalization +- (void)appendLocalizedResources:(NSArray *)resources + forLanguages:(NSArray *)languages { + NSString *langs = [languages componentsJoinedByString:@" "]; + NSString *string = nil; + NSString *item = nil; + NSString *eol = [NSString stringWithString:@"\\\n"]; + int i = 0; + int count = [resources count]; + + if (resources == nil || count <= 0) + { + return; + } + + // Header [self appendString:COMMENT_LOCALIZATION]; + + // Languages + string = [NSString stringWithFormat:@"%@_LANGUAGES = %@\n", pnme, langs]; + [self appendString:string]; + + // Items + [self appendString: + [NSString stringWithFormat:@"%@_LOCALIZED_RESOURCE_FILES = \\\n",pnme]]; + for (i = 0; i < count; i++) + { + if (i == (count-1)) + { + eol = [NSString stringWithString:@"\n"]; + } + item = [resources objectAtIndex:i]; + string = [NSString stringWithFormat:@"%@ %@", item, eol]; + [self appendString:string]; + } } - (void)appendSubprojects:(NSArray*)array @@ -358,7 +424,9 @@ static PCMakefileFactory *_factory = nil; NSEnumerator *enumerator = nil; if (array == nil || [array count] == 0) - return; + { + return; + } [self appendString:COMMENT_SUBPROJECTS]; [self appendString:@"SUBPROJECTS = "]; diff --git a/Library/PCProject.m b/Library/PCProject.m index 654f55f..1c5fea1 100644 --- a/Library/PCProject.m +++ b/Library/PCProject.m @@ -23,21 +23,26 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCFileManager.h" -#include "PCProject.h" -#include "PCDefines.h" +// TODO: Split into several files with categories +// TODO: Take care of Libraries and Non Project Files -#include "PCProjectWindow.h" -#include "PCProjectBrowser.h" -#include "PCProjectLoadedFiles.h" +#include +#include +#include +#include -#include "PCProjectInspector.h" -#include "PCProjectBuilder.h" -#include "PCProjectEditor.h" -#include "PCProjectLauncher.h" -#include "PCEditor.h" +#include +#include +#include -#include "PCLogController.h" +#include +#include +#include +#include + +#include + +#include NSString *PCProjectDictDidChangeNotification = @"PCProjectDictDidChangeNotification"; @@ -54,11 +59,15 @@ NSString { if ((self = [super init])) { + projectDict = [[NSMutableDictionary alloc] init]; + projectPath = [[NSString alloc] init]; + projectName = [[NSString alloc] init]; buildOptions = [[NSMutableDictionary alloc] init]; + loadedSubprojects = [[NSMutableArray alloc] init]; + projectBuilder = nil; projectLauncher = nil; - loadedSubprojects = [[NSMutableArray alloc] init]; isSubproject = NO; activeSubproject = nil; } @@ -66,132 +75,238 @@ NSString return self; } -- (id)initWithProjectDictionary:(NSDictionary *)dict path:(NSString *)path; +- (PCProject *)openWithDictionaryAt:(NSString *)path { - NSAssert(dict,@"No valid project dictionary!"); + NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path]; - if ((self = [self init])) - { - if ([[path lastPathComponent] isEqualToString:@"PC.project"]) - { - projectPath = [[path stringByDeletingLastPathComponent] copy]; - } - else - { - projectPath = [path copy]; - } - - PCLogStatus(self, @"initWithProjectDictionary"); - - if (![self assignProjectDict:dict]) - { - PCLogError(self, @"could not load the project..."); - [self autorelease]; - return nil; - } - [self save]; - } + [self assignProjectDict:dict atPath:path]; return self; } -- (void)setProjectManager:(PCProjectManager *)aManager +- (void)dealloc { - projectManager = aManager; +#ifdef DEVELOPMENT + NSLog (@"PCProject %@: dealloc", projectName); +#endif + + [[NSNotificationCenter defaultCenter] removeObserver:self]; - if (isSubproject) + RELEASE(projectDict); + RELEASE(projectName); + RELEASE(projectPath); + RELEASE(buildOptions); + RELEASE(loadedSubprojects); + + // Initialized in -setProjectManager: of project and + // in setSuperProject: of subproject + RELEASE(projectWindow); + RELEASE(projectBrowser); + RELEASE(projectLoadedFiles); + RELEASE(projectEditor); + if (projectBuilder) RELEASE(projectBuilder); + if (projectLauncher) RELEASE(projectLauncher); + + if (isSubproject == YES) + { + RELEASE(rootProject); + RELEASE(superProject); + } + + [super dealloc]; +} + +// ============================================================================ +// ==== Project handling +// ============================================================================ + +// --- Dictionary +- (BOOL)assignProjectDict:(NSDictionary *)pDict atPath:(NSString *)pPath +{ + NSAssert(pDict,@"No valid project dictionary!"); + + PCLogStatus(self, @"assignProjectDict"); + + if (projectDict) + { + [projectDict release]; + } + projectDict = [[NSMutableDictionary alloc] initWithDictionary:pDict]; + + // Project path + if ([[pPath lastPathComponent] isEqualToString:@"PC.project"]) + { + [self setProjectPath:[pPath stringByDeletingLastPathComponent]]; + } + else + { + [self setProjectPath:pPath]; + } + + [projectDict setObject:[NSUserDefaults userLanguages] forKey:PCUserLanguages]; + + [self setProjectName:[projectDict objectForKey:PCProjectName]]; + [self writeMakefile]; + [self save]; + + return YES; +} + +- (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:@"project"]; + + origin = [NSMutableDictionary dictionaryWithContentsOfFile:_file]; + keys = [origin allKeys]; + + enumerator = [keys objectEnumerator]; + while ((key = [enumerator nextObject])) + { + if ([aDict objectForKey:key] == nil) + { + return NO; + } + } + + return YES; +} + +- (void)validateProjectDict +{ + if ([self isValidDictionary:projectDict] == NO) + { + [self updateProjectDict]; + + NSRunAlertPanel(@"Project updated!", + @"The project file was converted from previous version!\nPlease make sure that every project attribute contain valid values!", + @"OK",nil,nil); + } +} + +- (void)setProjectDictObject:(id)object forKey:(NSString *)key notify:(BOOL)yn +{ + id currentObject = [projectDict objectForKey:key]; + NSMutableDictionary *notifObject = [NSMutableDictionary dictionary]; + + if ([object isKindOfClass:[NSString class]] + && [currentObject isEqualToString:object]) { return; } - if (!projectBrowser && !isSubproject) - { - projectBrowser = [[PCProjectBrowser alloc] initWithProject:self]; - } + [projectDict setObject:object forKey:key]; - if (!projectLoadedFiles && !isSubproject) - { - projectLoadedFiles = [[PCProjectLoadedFiles alloc] initWithProject:self]; - } + // Send in notification project itself and project dictionary object key + // that was changed + [notifObject setObject:self forKey:@"Project"]; + [notifObject setObject:key forKey:@"Attribute"]; - if (!projectEditor && !isSubproject) + if (yn == YES) { - projectEditor = [[PCProjectEditor alloc] initWithProject:self]; - } - - if (!projectWindow && !isSubproject) - { - projectWindow = [[PCProjectWindow alloc] initWithProject:self]; + [[NSNotificationCenter defaultCenter] + postNotificationName:PCProjectDictDidChangeNotification + object:notifObject]; } } -- (BOOL)close:(id)sender +- (void)updateProjectDict { -// PCLogInfo(self, @"Closing %@ project", projectName); - - // Save visible windows and panels positions to project dictionary - if (isSubproject == NO) - { - [self saveProjectWindowsAndPanels]; - [projectBrowser setPath:@"/"]; - [projectManager setActiveProject:self]; - } - - // Project files (GNUmakefile, PC.project etc.) - if (isSubproject == NO && [self isProjectChanged] == YES) - { - int ret; + Class projClass = [self builderClass]; + NSString *_file = nil; + NSString *key = nil; + NSDictionary *origin = nil; + NSArray *keys = nil; + NSEnumerator *enumerator = nil; - ret = NSRunAlertPanel(@"Alert", - @"Project or subprojects are modified", - @"Save and Close",@"Don't save",@"Cancel"); - switch (ret) + _file = [[NSBundle bundleForClass:projClass] pathForResource:@"PC" + ofType:@"project"]; + + origin = [NSMutableDictionary dictionaryWithContentsOfFile:_file]; + keys = [origin allKeys]; + + enumerator = [keys objectEnumerator]; + while ((key = [enumerator nextObject])) + { + if ([projectDict objectForKey:key] == nil) { - case NSAlertDefaultReturn: - if ([self save] == NO) - { - return NO; - } - break; - - case NSAlertAlternateReturn: - break; - - case NSAlertOtherReturn: - return NO; - break; + // Doesn't call setProjectDictObject:forKey for opimization + [projectDict setObject:[origin objectForKey:key] forKey:key]; } } - - // Close subprojects - while ([loadedSubprojects count]) - { - [(PCProject *)[loadedSubprojects objectAtIndex:0] close:self]; - // We should release subproject here, because it retains us - // and we never reach -dealloc in other case. - [loadedSubprojects removeObjectAtIndex:0]; - } - if (isSubproject == YES) - { - return YES; - } + [self save]; +} - // Editors - // "Cancel" button on "Save Edited Files" panel selected - if ([projectEditor closeAllEditors] == NO) - { - return NO; - } +- (NSDictionary *)projectDict +{ + return (NSDictionary *)projectDict; +} - // Project window - if (sender != projectWindow) - { - [projectWindow close]; - } +// --- Name and path +- (NSString *)projectName +{ + return projectName; +} - // Remove self from loaded projects - [projectManager closeProject:self]; +- (void)setProjectName:(NSString *)aName +{ + if (projectName) + { + [projectName autorelease]; + } + projectName = [aName copy]; +// [projectWindow setFileIconTitle:projectName]; +} + +- (NSString *)projectPath +{ + return projectPath; +} + +- (void)setProjectPath:(NSString *)aPath +{ + if (projectPath) + { + [projectPath autorelease]; + } + projectPath = [aPath copy]; +} + +// --- Saving +- (BOOL)isProjectChanged +{ + return [projectWindow isDocumentEdited]; +} + +// Saves backup file +- (BOOL)writeMakefile +{ + NSString *mf = [projectPath stringByAppendingPathComponent:@"GNUmakefile"]; + NSString *bu = [projectPath stringByAppendingPathComponent:@"GNUmakefile~"]; + NSFileManager *fm = [NSFileManager defaultManager]; + + 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); + } + } return YES; } @@ -292,36 +407,136 @@ NSString return YES; } -- (void)dealloc +- (BOOL)save { -#ifdef DEVELOPMENT - NSLog (@"PCProject %@: dealloc", projectName); -#endif + NSString *file = [projectPath stringByAppendingPathComponent:@"PC.project"]; + NSString *backup = [file stringByAppendingPathExtension:@"backup"]; + NSFileManager *fm = [NSFileManager defaultManager]; + NSUserDefaults *defs = [NSUserDefaults standardUserDefaults]; + NSString *keepBackup = [defs objectForKey:KeepBackup]; + BOOL shouldKeep = [keepBackup isEqualToString:@"YES"]; + int spCount = [loadedSubprojects count]; + int i; + + for (i = 0; i < spCount; i++) + { + [[loadedSubprojects objectAtIndex:i] save]; + } + + // Remove backup file if exists + if ([fm fileExistsAtPath:backup] && ![fm removeFileAtPath:backup handler:nil]) + { + NSRunAlertPanel(@"Save project", + @"Error removing the old project backup!", + @"OK",nil,nil); + return NO; + } + + // Save backup + if (shouldKeep == YES && [fm isReadableFileAtPath:file]) + { + if ([fm copyPath:file toPath:backup handler:nil] == NO) + { + NSRunAlertPanel(@"Save project", + @"Error when saving project backup file!", + @"OK",nil,nil); + return NO; + } + } + + // Save project file + [projectDict setObject:[[NSCalendarDate date] description] + forKey:PCLastEditing]; + if ([projectDict writeToFile:file atomically:YES] == NO) + { + return NO; + } + + [[NSNotificationCenter defaultCenter] + postNotificationName:PCProjectDictDidSaveNotification + object:self]; + + // Save GNUmakefile + if ([self writeMakefile] == NO) + { + NSRunAlertPanel(@"Save project", + @"Error when writing makefile for project %@", + @"OK",nil,nil,projectName); + return NO; + } + + return YES; +} + +- (BOOL)close:(id)sender +{ +// PCLogInfo(self, @"Closing %@ project", projectName); - [[NSNotificationCenter defaultCenter] removeObserver:self]; + // Save visible windows and panels positions to project dictionary + if (isSubproject == NO) + { + [self saveProjectWindowsAndPanels]; + [projectBrowser setPath:@"/"]; + [projectManager setActiveProject:self]; + } + + // Project files (GNUmakefile, PC.project etc.) + if (isSubproject == NO && [self isProjectChanged] == YES) + { + int ret; - RELEASE(projectName); - RELEASE(projectPath); - RELEASE(projectDict); - RELEASE(loadedSubprojects); - RELEASE(buildOptions); + ret = NSRunAlertPanel(@"Alert", + @"Project or subprojects are modified", + @"Save and Close",@"Don't save",@"Cancel"); + switch (ret) + { + case NSAlertDefaultReturn: + if ([self save] == NO) + { + return NO; + } + break; + + case NSAlertAlternateReturn: + break; - // Initialized in -setProjectManager: of project and - // in setSuperProject: of subproject - RELEASE(projectWindow); - RELEASE(projectBrowser); - RELEASE(projectLoadedFiles); - RELEASE(projectEditor); - if (projectBuilder) RELEASE(projectBuilder); - if (projectLauncher) RELEASE(projectLauncher); + case NSAlertOtherReturn: + return NO; + break; + } + } + + // Close subprojects + while ([loadedSubprojects count]) + { + [(PCProject *)[loadedSubprojects objectAtIndex:0] close:self]; + // We should release subproject here, because it retains us + // and we never reach -dealloc in other case. + [loadedSubprojects removeObjectAtIndex:0]; + } if (isSubproject == YES) { - RELEASE(rootProject); - RELEASE(superProject); + return YES; } - [super dealloc]; + // Editors + // "Cancel" button on "Save Edited Files" panel selected + if ([projectEditor closeAllEditors] == NO) + { + return NO; + } + + // Project window + if (sender != projectWindow) + { + [projectWindow close]; + } + + // Remove self from loaded projects + [projectManager closeProject:self]; + + return YES; } // ============================================================================ @@ -333,6 +548,36 @@ NSString return projectManager; } +- (void)setProjectManager:(PCProjectManager *)aManager +{ + projectManager = aManager; + + if (isSubproject) + { + return; + } + + if (!projectBrowser) + { + projectBrowser = [[PCProjectBrowser alloc] initWithProject:self]; + } + + if (!projectLoadedFiles) + { + projectLoadedFiles = [[PCProjectLoadedFiles alloc] initWithProject:self]; + } + + if (!projectEditor) + { + projectEditor = [[PCProjectEditor alloc] initWithProject:self]; + } + + if (!projectWindow) + { + projectWindow = [[PCProjectWindow alloc] initWithProject:self]; + } +} + - (PCProjectWindow *)projectWindow { return projectWindow; @@ -378,164 +623,248 @@ NSString return projectEditor; } -- (void)setProjectDictObject:(id)object forKey:(NSString *)key notify:(BOOL)yn -{ - id currentObject = [projectDict objectForKey:key]; - NSMutableDictionary *notifObject = [NSMutableDictionary dictionary]; - - if ([object isKindOfClass:[NSString class]] - && [currentObject isEqualToString:object]) - { - return; - } - - [projectDict setObject:object forKey:key]; - - // Send in notification project itself and project dictionary object key - // that was changed - [notifObject setObject:self forKey:@"Project"]; - [notifObject setObject:key forKey:@"Attribute"]; - - if (yn == YES) - { - [[NSNotificationCenter defaultCenter] - postNotificationName:PCProjectDictDidChangeNotification - object:notifObject]; - } -} - -- (void)setProjectName:(NSString *)aName -{ - AUTORELEASE(projectName); - projectName = [aName copy]; -// [projectWindow setFileIconTitle:projectName]; -} - -- (NSString *)projectName -{ - return projectName; -} - -- (BOOL)isProjectChanged -{ - return [projectWindow isDocumentEdited]; -} - // ============================================================================ -// ==== Can be overriden +// ==== Bundle methods // ============================================================================ +//--- Project Inspector's "Project Attributes" - (NSView *)projectAttributesView { return nil; } +//--- Properties from Info.table +- (NSDictionary *)projectBundleInfoTable +{ + NSString *_file; + Class class = [self builderClass]; + + _file = [[NSBundle bundleForClass:class] pathForResource:@"Info" + ofType:@"table"]; + return [NSMutableDictionary dictionaryWithContentsOfFile:_file]; +} + +- (NSString *)projectTypeName +{ + return [[self projectBundleInfoTable] objectForKey:@"Name"]; +} + - (Class)builderClass { - return nil; + return [[self projectBundleInfoTable] objectForKey:@"BuilderClassName"]; } - (NSString *)projectDescription { - return @"Abstract PCProject class!"; + return [[self projectBundleInfoTable] objectForKey:@"Description"]; } - (BOOL)isExecutable { + if ([[[self projectBundleInfoTable] + objectForKey:@"Executable"] isEqualToString:@"YES"]) + { + return YES; + } + return NO; } - (NSString *)execToolName { - return nil; + return [[self projectBundleInfoTable] objectForKey:@"ExecuToolName"]; } +- (NSArray *)buildTargets +{ + return [[self projectBundleInfoTable] objectForKey:@"BuildTargets"]; +} + +- (NSArray *)sourceFileKeys +{ + return [[self projectBundleInfoTable] objectForKey:@"SourceFileKeys"]; +} + +- (NSArray *)resourceFileKeys +{ + return [[self projectBundleInfoTable] objectForKey:@"ResourceFileKeys"]; +} + +- (NSArray *)otherKeys +{ + return [[self projectBundleInfoTable] objectForKey:@"OtherFileKeys"]; +} + +- (NSArray *)allowableSubprojectTypes +{ + return [[self projectBundleInfoTable] + objectForKey:@"AllowableSubprojectTypes"]; +} + +- (NSArray *)localizableKeys +{ + return [[self projectBundleInfoTable] objectForKey:@"LocalizableCategories"]; +} + +//--- Public headers (for Library, Framework) - (BOOL)canHavePublicHeaders { + if ([[[self projectBundleInfoTable] + objectForKey:@"CanHavePublicHeaders"] isEqualToString:@"YES"]) + { + return YES; + } + return NO; } - (NSArray *)publicHeaders { + if ([self canHavePublicHeaders] == YES) + { + return [projectDict objectForKey:PCPublicHeaders]; + } + return nil; } - (void)setHeaderFile:(NSString *)file public:(BOOL)yn { + NSMutableArray *publicHeaders = nil; + + if ((yn == YES && [[self publicHeaders] containsObject:file]) + || [self canHavePublicHeaders] == NO) + { + return; + } + + publicHeaders = [[projectDict objectForKey:PCPublicHeaders] copy]; + + if (yn) + { + [publicHeaders addObject:file]; + } + else if ([publicHeaders count] > 0 && [publicHeaders containsObject:file]) + { + [publicHeaders removeObject:file]; + } + + [self setProjectDictObject:publicHeaders + forKey:PCPublicHeaders + notify:YES]; + + [publicHeaders release]; } -- (void)setLocalizableFile:(NSString *)file public:(BOOL)yn +//--- Localization +- (NSArray *)localizedResources { + return [projectDict objectForKey:PCLocalizedResources]; } -- (NSArray *)buildTargets +- (NSString *)resourceDirForLanguage:(NSString *)language { - return nil; + NSString *dir = nil; + + dir = [projectPath stringByAppendingPathComponent:language]; + dir = [dir stringByAppendingPathExtension:@"lproj"]; + + return dir; } -- (NSArray *)sourceFileKeys +- (void)setResourceFile:(NSString *)file localizable:(BOOL)yn { - return nil; -} + PCFileManager *fileManager = [projectManager fileManager]; + NSArray *userLanguages = nil; + NSEnumerator *enumerator = nil; + NSString *currentLanguage = nil; + NSString *resPath = nil; + NSString *resFilePath = nil; + NSString *langPath = nil; + NSMutableArray *localizedResources = nil; -- (NSArray *)resourceFileKeys -{ - return nil; -} + if (yn == YES && [[self localizedResources] containsObject:file]) + { + return; + } -- (NSArray *)otherKeys -{ - return nil; -} + resPath = [projectPath stringByAppendingPathComponent:@"Resources"]; + resFilePath = [resPath stringByAppendingPathComponent:file]; + localizedResources = [[self localizedResources] mutableCopy]; -- (NSArray *)allowableSubprojectTypes -{ - return nil; -} + userLanguages = [projectDict objectForKey:PCUserLanguages]; + enumerator = [userLanguages objectEnumerator]; + while ((currentLanguage = [enumerator nextObject])) + { + langPath = [self resourceDirForLanguage:currentLanguage]; + if (yn == YES) + { + [fileManager copyFile:resFilePath intoDirectory:langPath]; + } + else + { + if ([currentLanguage isEqualToString:@"English"]) + { + [fileManager copyFile:file + fromDirectory:langPath + intoDirectory:resPath]; + } + [fileManager removeFile:file fromDirectory:langPath]; + } + } -- (NSArray *)localizableKeys -{ - return nil; -} + if (yn == YES) + { + [fileManager removeFileAtPath:resFilePath]; + [localizedResources addObject:file]; + [self setProjectDictObject:localizedResources + forKey:PCLocalizedResources + notify:YES]; + } + else if ([localizedResources count] > 0 + && [localizedResources containsObject:file]) + { + [localizedResources removeObject:file]; + [self setProjectDictObject:localizedResources + forKey:PCLocalizedResources + notify:YES]; + } + [localizedResources release]; +} +//--- + +// May files will be added to category? - (BOOL)isEditableCategory:(NSString *)category { NSString *key = [self keyForCategory:category]; - if ([key isEqualToString:PCClasses] - || [key isEqualToString:PCHeaders] - || [key isEqualToString:PCSupportingFiles] - || [key isEqualToString:PCDocuFiles] - || [key isEqualToString:PCOtherSources] - || [key isEqualToString:PCOtherResources] - || [key isEqualToString:PCNonProject]) + if ([key isEqualToString:PCSupportingFiles]) { - return YES; + return NO; } - return NO; + return YES; } +// May file will be edited in PC editor? - (BOOL)isEditableFile:(NSString *)filePath { NSString *key = [self keyForCategory:[projectBrowser nameOfSelectedCategory]]; + NSString *fileName = [filePath lastPathComponent]; NSString *extension = [filePath pathExtension]; if ([key isEqualToString:PCSupportingFiles] || [key isEqualToString:PCDocuFiles]) { - return YES; - } - - if ([extension isEqualToString:@"m"] - || [extension isEqualToString:@"h"] - || [extension isEqualToString:@"c"] - || [extension isEqualToString:@"plist"]) - { - return YES; + if ([fileName isEqualToString:@"GNUmakefile"] || + [extension isEqualToString:@"plist"]) + { + return NO; + } } - return NO; + return YES; } - (NSArray *)fileTypesForCategoryKey:(NSString *)key @@ -590,10 +919,7 @@ NSString - (NSString *)dirForCategoryKey:(NSString *)key { - if ([key isEqualToString:PCInterfaces] - || [key isEqualToString:PCImages] - || [key isEqualToString:PCOtherResources] - || [key isEqualToString:PCDocuFiles]) + if ([[self resourceFileKeys] containsObject:key]) { return [projectPath stringByAppendingPathComponent:@"Resources"]; } @@ -601,6 +927,20 @@ NSString return projectPath; } +- (NSString *)localizedDirForCategoryKey:(NSString *)key +{ + NSString *language = nil; + + if ([[self resourceFileKeys] containsObject:key]) + { + language = [projectDict objectForKey:PCLanguage]; + language = [language stringByAppendingPathExtension:@"lproj"]; + return [projectPath stringByAppendingPathComponent:language]; + } + + return projectPath; +} + - (NSString *)complementaryTypeForType:(NSString *)type { if ([type isEqualToString:@"m"] || [type isEqualToString:@"c"]) @@ -615,35 +955,31 @@ NSString return nil; } -// Saves backup file -- (BOOL)writeMakefile -{ - NSString *mf = [projectPath stringByAppendingPathComponent:@"GNUmakefile"]; - NSString *bu = [projectPath stringByAppendingPathComponent:@"GNUmakefile~"]; - NSFileManager *fm = [NSFileManager defaultManager]; - - 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); - } - } - - return YES; -} - // ============================================================================ // ==== File Handling // ============================================================================ +- (NSString *)pathForFile:(NSString *)file forKey:(NSString *)key +{ + NSString *resPath = nil; + + if ([[self resourceFileKeys] containsObject:key]) + { + if ([[projectDict objectForKey:PCLocalizedResources] containsObject:file]) + { + resPath = [self localizedDirForCategoryKey:key]; + return [resPath stringByAppendingPathComponent:file]; + } + else + { + resPath = [self dirForCategoryKey:key]; + return [resPath stringByAppendingPathComponent:file]; + } + } + + return [projectPath stringByAppendingPathComponent:file]; +} + - (NSString *)projectFileFromFile:(NSString *)file forKey:(NSString *)type { NSString *projectFile = nil; @@ -714,12 +1050,12 @@ NSString - (BOOL)doesAcceptFile:(NSString *)file forKey:(NSString *)type { - NSString *pFile = [self projectFileFromFile:file forKey:type]; - NSArray *sourceKeys = [self sourceFileKeys]; - NSArray *resourceKeys = [self resourceFileKeys]; - NSEnumerator *keyEnum = nil; - NSString *key = nil; - NSArray *projectFiles = nil; + NSString *pFile = [self projectFileFromFile:file forKey:type]; + NSArray *sourceKeys = [self sourceFileKeys]; + NSArray *resourceKeys = [self resourceFileKeys]; + NSEnumerator *keyEnum = nil; + NSString *key = nil; + NSArray *projectFiles = nil; if ([sourceKeys containsObject:type]) { @@ -859,6 +1195,20 @@ NSString NSString *filePath = nil; NSString *file = nil; NSMutableArray *projectFiles = nil; + NSArray *localizedFiles = nil; + + // Check if file localazable. If yes, make it not localizable so file moved + // to Resources dir. + localizedFiles = [[self localizedResources] copy]; + enumerator = [files objectEnumerator]; + while ((file = [enumerator nextObject])) + { + if ([localizedFiles containsObject:file]) + { + [self setResourceFile:file localizable:NO]; + } + } + [localizedFiles release]; // Remove files from project projectFiles = [NSMutableArray arrayWithArray:[projectDict objectForKey:key]]; @@ -893,9 +1243,9 @@ NSString NSMutableArray *_array = nil; BOOL saveToFile = NO; int index = 0; - PCEditor *_editor = nil; + id _editor; NSString *_editorPath = nil; - NSString *_editorCategory = nil; + NSMutableString *_editorCategory = nil; selectedCategory = [projectBrowser nameOfSelectedCategory]; selectedCategoryKey = [self keyForCategory:selectedCategory]; @@ -909,7 +1259,7 @@ NSString { switch (NSRunAlertPanel(@"Rename file", @"File \"%@\" already exist", - @"Overwrite file",@"Cancel",nil, toFile)) + @"Overwrite file",@"Stop",nil, toFile)) { case NSAlertDefaultReturn: // Overwrite if ([fm removeFileAtPath:toPath handler:nil] == NO) @@ -927,263 +1277,94 @@ NSString /* PCLogInfo(self, @"{%@} move %@ to %@ category: %@", projectName, fromPath, toPath, selectedCategory);*/ - if ([fm movePath:fromPath toPath:toPath handler:nil] == YES) + if ([[self localizedResources] containsObject:fromFile]) + {// Rename file in language dirs + NSArray *userLanguages = nil; + NSEnumerator *enumerator = nil; + NSString *lang = nil; + NSString *langPath = nil; + NSMutableArray *localizedResources = [self localizedResources]; + + userLanguages = [projectDict objectForKey:PCUserLanguages]; + enumerator = [userLanguages objectEnumerator]; + while ((lang = [enumerator nextObject])) + { + langPath = [self resourceDirForLanguage:lang]; + fromPath = [langPath stringByAppendingPathComponent:fromFile]; + toPath = [langPath stringByAppendingPathComponent:toFile]; + if ([fm movePath:fromPath toPath:toPath handler:nil] == NO) + { + return NO; + } + } + index = [localizedResources indexOfObject:fromFile]; + [localizedResources replaceObjectAtIndex:index withObject:toFile]; + [projectDict setObject:localizedResources + forKey:PCLocalizedResources]; + } + else if ([fm movePath:fromPath toPath:toPath handler:nil] == NO) { - if ([self isProjectChanged]) - { - // Project already has changes - saveToFile = YES; - } + return NO; + } - // Make changes to projectDict - _array = [projectDict objectForKey:selectedCategoryKey]; - index = [_array indexOfObject:fromFile]; - [_array replaceObjectAtIndex:index withObject:toFile]; + // TODO: Rewrite this when file operations history will be implemented + if ([self isProjectChanged]) + { + // Project already has changes + saveToFile = YES; + } - // Put only this change to project file, leaving - // other changes in memory(projectDict) - if (saveToFile) - { - _file = [projectPath stringByAppendingPathComponent:@"PC.project"]; - _pDict = [NSMutableDictionary dictionaryWithContentsOfFile:_file]; - _array = [_pDict objectForKey:selectedCategoryKey]; - [_array removeObject:fromFile]; - [_array addObject:toFile]; - [_pDict setObject:_array forKey:selectedCategoryKey]; - [_pDict writeToFile:_file atomically:YES]; - } - else - { - [self save]; - } - + // Make changes to projectDict + _array = [projectDict objectForKey:selectedCategoryKey]; + index = [_array indexOfObject:fromFile]; + [_array replaceObjectAtIndex:index withObject:toFile]; + + // Put only this change to project file, leaving + // other changes in memory(projectDict) + if (saveToFile) + { + _file = [projectPath stringByAppendingPathComponent:@"PC.project"]; + _pDict = [NSMutableDictionary dictionaryWithContentsOfFile:_file]; + _array = [_pDict objectForKey:selectedCategoryKey]; + [_array removeObject:fromFile]; + [_array addObject:toFile]; + [_pDict setObject:_array forKey:selectedCategoryKey]; + [_pDict writeToFile:_file atomically:YES]; + } + else + { + [self save]; + } + + // Handle editor(if any) information + _editor = [projectEditor activeEditor]; + if (_editor) + { + NSRange range; + + _editorPath = [_editor path]; + _editorPath = [_editorPath stringByDeletingLastPathComponent]; + _editorPath = [_editorPath stringByAppendingPathComponent:toFile]; + [_editor setPath:_editorPath]; + + _editorCategory = [[_editor categoryPath] mutableCopy]; + range = [_editorCategory rangeOfString:fromFile]; + [_editorCategory replaceCharactersInRange:range withString:toFile]; + + [_editor setCategoryPath:_editorCategory]; + [projectBrowser setPath:_editorCategory]; + RELEASE(_editorCategory); + } + else + { // Set browser path to new file name [projectBrowser reloadLastColumnAndSelectFile:toFile]; - // Handle editor(if any) information -// if ([[[_editor path] lastPathComponent] isEqualToString:fromFile]) - _editor = [projectEditor activeEditor]; - if (_editor) - { - _editorPath = [_editor path]; - _editorPath = [_editorPath stringByDeletingLastPathComponent]; - _editorPath = [_editorPath stringByAppendingPathComponent:toFile]; - [_editor setPath:_editorPath]; - - _editorCategory = [_editor categoryPath]; - _editorCategory = [_editorCategory stringByDeletingLastPathComponent]; - _editorCategory = [_editorCategory - stringByAppendingPathComponent:toFile]; - [_editor setCategoryPath:_editorCategory]; - } } return YES; } -// ============================================================================ -// ==== Project handling -// ============================================================================ - -- (BOOL)assignProjectDict:(NSDictionary *)aDict -{ - NSAssert(aDict,@"No valid project dictionary!"); - - [projectDict release]; - projectDict = [[NSMutableDictionary alloc] initWithDictionary:aDict]; - - PCLogStatus(self, @"assignProjectDict"); - - [self setProjectName:[projectDict objectForKey:PCProjectName]]; - [self writeMakefile]; - - // Also notify on dictionary changes. Update the interface and so on. -// [projectDict setObject:[NSUserDefaults userLanguages] forKey:PCUserLanguages]; - - return YES; -} - -- (NSDictionary *)projectDict -{ - return (NSDictionary *)projectDict; -} - -- (void)setProjectPath:(NSString *)aPath -{ - [projectPath autorelease]; - projectPath = [aPath copy]; -} - -- (NSString *)projectPath -{ - return projectPath; -} - -- (NSArray *)rootKeys -{ - // e.g. CLASS_FILES - return rootKeys; -} - -- (NSArray *)rootCategories -{ - // e.g. Classes - return rootCategories; -} - -- (NSDictionary *)rootEntries -{ - return rootEntries; -} - -// Category - the name we see in project browser, e.g. "Classes" -// Key - the uppercase names located in PC.roject, e.g. "CLASS_FILES" -- (NSString *)keyForCategory:(NSString *)category -{ - int index = -1; - - if (![rootCategories containsObject:category]) - { - return nil; - } - - index = [rootCategories indexOfObject:category]; - return [rootKeys objectAtIndex:index]; -} - -- (NSString *)categoryForKey:(NSString *)key -{ - return [rootEntries objectForKey:key]; -} - -- (BOOL)save -{ - NSString *file = [projectPath stringByAppendingPathComponent:@"PC.project"]; - NSString *backup = [file stringByAppendingPathExtension:@"backup"]; - NSFileManager *fm = [NSFileManager defaultManager]; - NSUserDefaults *defs = [NSUserDefaults standardUserDefaults]; - NSString *keepBackup = [defs objectForKey:KeepBackup]; - BOOL shouldKeep = [keepBackup isEqualToString:@"YES"]; - int spCount = [loadedSubprojects count]; - int i; - - for (i = 0; i < spCount; i++) - { - [[loadedSubprojects objectAtIndex:i] save]; - } - - // Remove backup file if exists - if ([fm fileExistsAtPath:backup] && ![fm removeFileAtPath:backup handler:nil]) - { - NSRunAlertPanel(@"Save project", - @"Error removing the old project backup!", - @"OK",nil,nil); - return NO; - } - - // Save backup - if (shouldKeep == YES && [fm isReadableFileAtPath:file]) - { - if ([fm copyPath:file toPath:backup handler:nil] == NO) - { - NSRunAlertPanel(@"Save project", - @"Error when saving project backup file!", - @"OK",nil,nil); - return NO; - } - } - - // Save project file - [projectDict setObject:[[NSCalendarDate date] description] - forKey:PCLastEditing]; - if ([projectDict writeToFile:file atomically:YES] == NO) - { - return NO; - } - - [[NSNotificationCenter defaultCenter] - postNotificationName:PCProjectDictDidSaveNotification - object:self]; - - // Save GNUmakefile - if ([self writeMakefile] == NO) - { - NSRunAlertPanel(@"Save project", - @"Error when writing makefile for project %@", - @"OK",nil,nil,projectName); - return NO; - } - - return YES; -} - -- (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:@"project"]; - - origin = [NSMutableDictionary dictionaryWithContentsOfFile:_file]; - keys = [origin allKeys]; - - enumerator = [keys objectEnumerator]; - while ((key = [enumerator nextObject])) - { - if ([aDict objectForKey:key] == nil) - { - return NO; - } - } - - return YES; -} - -- (void)updateProjectDict -{ - Class projClass = [self builderClass]; - NSString *_file = nil; - NSString *key = nil; - NSDictionary *origin = nil; - NSArray *keys = nil; - NSEnumerator *enumerator = nil; - - _file = [[NSBundle bundleForClass:projClass] pathForResource:@"PC" - ofType:@"project"]; - - origin = [NSMutableDictionary dictionaryWithContentsOfFile:_file]; - keys = [origin allKeys]; - - enumerator = [keys objectEnumerator]; - while ((key = [enumerator nextObject])) - { - if ([projectDict objectForKey:key] == nil) - { - // Doesn't call setProjectDictObject:forKey for opimizations - [projectDict setObject:[origin objectForKey:key] forKey:key]; - } - } - - [self save]; -} - -- (void)validateProjectDict -{ - if ([self isValidDictionary:projectDict] == NO) - { - [self updateProjectDict]; - - NSRunAlertPanel(@"Project updated!", - @"The project file was converted from previous version!\nPlease make sure that every project attribute contain valid values!", - @"OK",nil,nil); - } -} - // ============================================================================ // ==== Subprojects // ============================================================================ @@ -1334,8 +1515,46 @@ NSString @end -@implementation PCProject (CategoryPaths) -// TODO: Think about moving all category related methods into PCProjectBrowser +@implementation PCProject (ProjectBrowser) + +// TODO: Think about moving all browser related methods into PCProjectBrowser + +- (NSArray *)rootKeys +{ + // e.g. CLASS_FILES + return rootKeys; +} + +- (NSArray *)rootCategories +{ + // e.g. Classes + return rootCategories; +} + +- (NSDictionary *)rootEntries +{ + return rootEntries; +} + +// Category - the name we see in project browser, e.g. "Classes" +// Key - the uppercase names located in PC.roject, e.g. "CLASS_FILES" +- (NSString *)keyForCategory:(NSString *)category +{ + int index = -1; + + if (![rootCategories containsObject:category]) + { + return nil; + } + + index = [rootCategories indexOfObject:category]; + return [rootKeys objectAtIndex:index]; +} + +- (NSString *)categoryForKey:(NSString *)key +{ + return [rootEntries objectForKey:key]; +} - (NSArray *)contentAtCategoryPath:(NSString *)categoryPath { @@ -1349,17 +1568,6 @@ NSString /* PCLogInfo(self, @"{%@}{contentAtCategoryPath:} %@", projectName, categoryPath);*/ - // Click on /Category - if ([pathArray count] == 2) - { - NSLog(@"Click on Category"); - if ([projectManager activeProject] != self) - { - [projectManager setActiveProject:self]; - } - activeSubproject = nil; - } - if ([categoryPath isEqualToString:@""] || [categoryPath isEqualToString:@"/"]) { if ([projectManager activeProject] != self) @@ -1368,14 +1576,17 @@ NSString } return rootCategories; } - else if ([[listEntry pathExtension] isEqualToString:@"m"] - || [[listEntry pathExtension] isEqualToString:@"h"]) - {// Class and header files (TODO: test subprojects) - return [[projectEditor activeEditor] classNames]; - } - else if ([[listEntry substringToIndex:1] isEqualToString:@"@"]) - {// Class name (TODO: test subprojects) - return [[projectEditor activeEditor] methodNamesForClass:listEntry]; + else if ([pathArray count] == 2) + { // Click on /Category. [pathArray count] == 2 even in subprojects + // because category path stripped from leading path components before + // going into subproject's code +// NSLog(@"Click on Category"); + if ([projectManager activeProject] != self) + { + [projectManager setActiveProject:self]; + } + activeSubproject = nil; + return [projectDict objectForKey:key]; } else if ([key isEqualToString:PCSubprojects] && [pathArray count] > 2) { // Click on "/Subprojects/Name+" @@ -1393,19 +1604,27 @@ NSString return [_subproject contentAtCategoryPath:spCategoryPath]; } -/* else if ([[[categoryPath lastPathComponent] pathExtension] isEqualToString:@"m"] - || [[[categoryPath lastPathComponent] pathExtension] isEqualToString:@"h"]) - { // ".m" file - return [[projectEditor activeEditor] listOfClasses]; + else + { // The file is selected, ask editor for browser items + return [[projectEditor activeEditor] browserItemsForItem:listEntry]; + } +/* else if ([[listEntry pathExtension] isEqualToString:@"m"] + || [[listEntry pathExtension] isEqualToString:@"h"]) + {// Class and header files (TODO: test subprojects) + return [[projectEditor activeEditor] classNames]; + } + else if ([[listEntry substringToIndex:1] isEqualToString:@"@"]) + {// Class name (TODO: test subprojects) + return [[projectEditor activeEditor] methodNamesForClass:listEntry]; }*/ - - return [projectDict objectForKey:key]; } - (BOOL)hasChildrenAtCategoryPath:(NSString *)categoryPath { NSString *listEntry = nil; PCProject *activeProject = [projectManager activeProject]; + NSString *category = [projectBrowser nameOfSelectedCategory]; + NSString *categoryKey = [self keyForCategory:category]; if (self != activeProject) { @@ -1422,27 +1641,26 @@ NSString // Subprojects if ([[projectDict objectForKey:PCSubprojects] containsObject:listEntry] - && [[projectBrowser nameOfSelectedCategory] isEqualToString:@"Subprojects"]) + && [category isEqualToString:@"Subprojects"]) { return YES; } - // Class and header files - if ([[listEntry pathExtension] isEqualToString:@"m"] - || [[listEntry pathExtension] isEqualToString:@"h"]) + // Files + if ([[projectDict objectForKey:categoryKey] containsObject:listEntry]) { - return YES; - } - - if ([[listEntry substringToIndex:1] isEqualToString:@"@"]) - { - return YES; - } +// NSLog(@"PCP [hasChildrenAtCategoryPath]: item is file selected"); + // TODO: Libraries + if ([category isEqualToString:@"Libraries"]) + { + return NO; + } - // TODO: Libraries -// if ([[projectBrowser nameOfSelectedCategory] isEqualToString:@"Libraries"]) -// { -// } + if ([projectEditor editorProvidesBrowserItemsForItem:listEntry] == YES) + { + return YES; + } + } return NO; } @@ -1461,52 +1679,6 @@ NSString return [pathComponents objectAtIndex:1]; } -/*- (NSString *)categoryForCategoryPath:(NSString *)categoryPath -{ - NSString *category = nil; - NSString *key = nil; - NSArray *pathComponents = nil; - int i = 0; - - category = [self rootCategoryForCategoryPath:categoryPath]; - if (category == nil) - { - return nil; - } - - key = [self keyForCategory:category]; - pathComponents = [categoryPath componentsSeparatedByString:@"/"]; - - if ([key isEqualToString:PCSubprojects]) - { - // /Subprojects/Name/Classes/Class.m, should return Classes - // 0 1 2 3 4 - // ("",Subprojects,Name,Classes,Class.m) - // 0 1 2 3 4 - // ("",Subprojects,Name,Subprojects,Name) - if ([pathComponents count] > 4 && activeSubproject) - { - i = [pathComponents count] - 1; - - for (; i >= 0; i--) - { - category = [pathComponents objectAtIndex:i]; - if ([[activeSubproject rootCategories] containsObject:category]) - { - return category; - } - } - } - } - - return category; -}*/ - -/*- (NSString *)keyForCategoryPath:(NSString *)categoryPath -{ - return [self keyForCategory:[self categoryForCategoryPath:categoryPath]]; -}*/ - - (NSString *)keyForRootCategoryInCategoryPath:(NSString *)categoryPath { NSString *category = nil; diff --git a/Library/PCProjectBrowser.m b/Library/PCProjectBrowser.m index c7c5f1f..1e73ef6 100644 --- a/Library/PCProjectBrowser.m +++ b/Library/PCProjectBrowser.m @@ -23,16 +23,14 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCDefines.h" -#include "PCFileManager.h" -#include "PCProjectManager.h" -#include "PCProject.h" -#include "PCProjectBrowser.h" -#include "PCProjectEditor.h" +#include +#include +#include +#include +#include +#include -#include "PCEditor.h" - -#include "PCLogController.h" +#include NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; @@ -48,9 +46,10 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; { project = aProject; - browser = [[NSBrowser alloc] initWithFrame:NSMakeRect(-1,251,562,128)]; + browser = [[NSBrowser alloc] initWithFrame:NSMakeRect(-10,-10,256,128)]; [browser setRefusesFirstResponder:YES]; - [browser setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin]; +// [browser setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin]; + [browser setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; [browser setTitled:NO]; [browser setMaxVisibleColumns:4]; [browser setSeparatesColumns:NO]; @@ -69,7 +68,7 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; object:nil]; [[NSNotificationCenter defaultCenter] - addObserver:self + addObserver:self selector:@selector(editorDidOpen:) name:PCEditorDidOpenNotification object:nil]; @@ -103,16 +102,29 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; // Returns nil if multiple files or category selected - (NSString *)nameOfSelectedFile { - NSString *name = nil; + NSString *name = [[browser path] lastPathComponent]; + NSString *category = [self nameOfSelectedCategory]; + NSMutableArray *pathArray; + NSEnumerator *enumerator; + NSString *pathItem; - if ([[browser selectedCells] count] == 1) + if ([[browser selectedCells] count] != 1 + || [name isEqualToString:[self nameOfSelectedCategory]]) { - name = [[browser path] lastPathComponent]; - if ([name isEqualToString:[self nameOfSelectedCategory]]) + return nil; + } + + pathArray = [[[browser path] pathComponents] mutableCopy]; + enumerator = [pathArray objectEnumerator]; + while ((pathItem = [enumerator nextObject])) + { + if ([pathItem isEqualToString:category]) { - return nil; + name = [enumerator nextObject]; + break; } } + RELEASE(pathArray); return name; } @@ -142,10 +154,10 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; // Returns nil of multiple categories selected - (NSString *)nameOfSelectedCategory { - NSString *name = nil; NSArray *pathArray = [[browser path] componentsSeparatedByString:@"/"]; PCProject *activeProject = [[project projectManager] activeProject]; NSArray *rootCategories = [activeProject rootCategories]; + NSString *name = nil; int i; if ([rootCategories containsObject:[pathArray lastObject]] @@ -190,10 +202,32 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; return path; } +// Returns nil of multiple categories selected +- (NSString *)pathFromSelectedCategory +{ + NSString *selectedCategory = [self nameOfSelectedCategory]; + NSMutableArray *bPathArray; + NSString *path = nil; + + if (selectedCategory) + { + bPathArray = + [[[browser path] componentsSeparatedByString:@"/"] mutableCopy]; + while (![[bPathArray objectAtIndex:1] isEqualToString:selectedCategory]) + { + [bPathArray removeObjectAtIndex:1]; + } + path = [bPathArray componentsJoinedByString:@"/"]; + RELEASE(bPathArray); + } + + return path; +} + - (NSString *)nameOfSelectedRootCategory { NSString *categoryPath = [self pathToSelectedCategory]; - NSArray *pathComponents = nil; + NSArray *pathComponents; if ([categoryPath isEqualToString:@"/"] || [categoryPath isEqualToString:@""]) { @@ -236,7 +270,7 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; - (BOOL)setPath:(NSString *)path { - BOOL res; + BOOL res; if ([[browser path] isEqualToString: path]) { @@ -256,7 +290,7 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; - (void)reloadLastColumnAndNotify:(BOOL)yn { - int column = [browser lastColumn]; + int column = [browser lastColumn]; NSString *category = [self nameOfSelectedCategory]; int selectedColumn = [browser selectedColumn]; NSMatrix *colMatrix = [browser matrixInColumn:selectedColumn]; @@ -298,7 +332,7 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; NSString *catKey = [p keyForCategory:[self nameOfSelectedCategory]]; NSArray *array = [[p projectDict] objectForKey:catKey]; NSString *path = [self path]; - NSString *tmp = nil; + NSString *tmp; // Determine last column with files (removing classes and methods from path) tmp = [[path lastPathComponent] substringWithRange:NSMakeRange(0,1)]; @@ -328,49 +362,31 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; - (void)click:(id)sender { - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - NSFileManager *fm = [NSFileManager defaultManager]; - NSString *category = nil; - NSString *fileName = nil; - NSString *filePath = nil; - NSString *key = nil; - PCProject *activeProject = nil; - BOOL isDir; + NSUserDefaults *ud; + NSString *category; + PCProject *activeProject; + NSString *browserPath; if (sender != browser) { return; } + ud = [NSUserDefaults standardUserDefaults]; category = [self nameOfSelectedCategory]; activeProject = [[project projectManager] activeProject]; + browserPath = [self path]; - // [[sender selectedCell] isLeaf] + NSLog(@"browserPath: %@ forProject: %@", + browserPath, [activeProject projectName]); - if ([activeProject isEditableCategory:category] - && [[self selectedFiles] count] == 1) + if ([[self selectedFiles] count] == 1 + && ![[ud objectForKey:SeparateEditor] isEqualToString:@"YES"]) { - fileName = [[sender selectedCell] stringValue]; - key = [activeProject keyForCategory:category]; - filePath = [activeProject dirForCategoryKey:key]; - filePath = [filePath stringByAppendingPathComponent:fileName]; - /* PCLogInfo(self, @"[click] category: %@ filePath: %@", - category, filePath);*/ - - if ([fm fileExistsAtPath:filePath isDirectory:&isDir] && !isDir - && [activeProject isEditableFile:filePath]) - { - if (![[ud objectForKey:SeparateEditor] isEqualToString:@"YES"]) - { - NSString *path = [self path]; - [[project projectEditor] editorForFile:filePath - categoryPath:[browser path] - windowed:NO]; - [self reloadLastColumnAndNotify:NO]; - [self setPath:path]; - } - } + category, filePath);*/ + [[activeProject projectEditor] editorForCategoryPath:browserPath + windowed:NO]; } [[NSNotificationCenter defaultCenter] @@ -380,7 +396,12 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; - (void)doubleClick:(id)sender { - id selectedCell; + id selectedCell; + NSString *category; + NSString *fileName; + PCProject *activeProject; + NSString *key; + NSString *filePath; if (sender != browser) { @@ -388,34 +409,23 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; } selectedCell = [sender selectedCell]; + category = [self nameOfSelectedCategory]; + fileName = [[sender selectedCell] stringValue]; + activeProject = [[project projectManager] activeProject]; + key = [activeProject keyForCategory:category]; + filePath = [activeProject pathForFile:fileName forKey:key]; - if ([selectedCell isLeaf]) + if ([self nameOfSelectedFile] != nil) { - NSString *category = [self nameOfSelectedCategory]; - NSString *fileName = [[sender selectedCell] stringValue]; - NSString *filePath = nil; - NSString *key = nil; - PCProject *activeProject = nil; - - activeProject = [[project projectManager] activeProject]; - key = [activeProject keyForCategory:category]; - filePath = [activeProject dirForCategoryKey:key]; - filePath = [filePath stringByAppendingPathComponent:fileName]; +/* PCLogInfo(self, @"{doubleClick} filePath: %@", filePath);*/ - PCLogInfo(self, @"{doubleClick} filePath: %@", filePath); - - if ([activeProject isEditableCategory:category]) + if (![[self nameOfSelectedCategory] isEqualToString:@"Libraries"]) { - [[project projectEditor] editorForFile:filePath - categoryPath:[browser path] - windowed:YES]; - } - else if (![[self nameOfSelectedCategory] isEqualToString:@"Libraries"] - && [[NSWorkspace sharedWorkspace] openFile:filePath] == NO) - { - NSRunAlertPanel(@"Attention!", - @"Could not open %@.", - @"OK",nil,nil,filePath); + if ([[NSWorkspace sharedWorkspace] openFile:filePath] == NO) + { + [[project projectEditor] editorForCategoryPath:[browser path] + windowed:YES]; + } } } else @@ -452,10 +462,13 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; { return; } + +// NSLog(@"PCPB: projectDictDidChange in %@ (%@)", +// [changedProject projectName], [project projectName]); - if ([[changedProject sourceFileKeys] containsObject:changedAttribute] - || [[changedProject resourceFileKeys] containsObject:changedAttribute] - || [[changedProject otherKeys] containsObject:changedAttribute]) + // If project dictionary changed after files adding/removal, + // refresh file list + if ([[changedProject rootKeys] containsObject:changedAttribute]) { [self reloadLastColumnAndNotify:YES]; } @@ -474,11 +487,12 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; @implementation PCProjectBrowser (ProjectBrowserDelegate) -- (void)browser:(NSBrowser *)sender createRowsForColumn:(int)column - inMatrix:(NSMatrix *)matrix +- (void) browser:(NSBrowser *)sender + createRowsForColumn:(int)column + inMatrix:(NSMatrix *)matrix { - NSString *pathToCol = nil; - NSArray *files = nil; + NSString *pathToCol; + NSArray *files; int i = 0; int count = 0; diff --git a/Library/PCProjectBuilder.m b/Library/PCProjectBuilder.m index d357644..a18b44b 100644 --- a/Library/PCProjectBuilder.m +++ b/Library/PCProjectBuilder.m @@ -25,15 +25,15 @@ #include -#include "PCDefines.h" -#include "PCSplitView.h" -#include "PCButton.h" +#include +#include +#include -#include "PCProjectManager.h" -#include "PCProject.h" -#include "PCProjectBuilder.h" +#include +#include +#include -#include "PCLogController.h" +#include #ifndef IMAGE #define IMAGE(X) [NSImage imageNamed: X] diff --git a/Library/PCProjectEditor.m b/Library/PCProjectEditor.m index 84f57ee..cd1e23b 100644 --- a/Library/PCProjectEditor.m +++ b/Library/PCProjectEditor.m @@ -23,16 +23,17 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCDefines.h" -#include "PCProjectWindow.h" -#include "PCProjectBrowser.h" -#include "PCProjectEditor.h" -#include "PCEditor.h" -#include "PCEditorView.h" +#include +#include +#include +#include +#include +#include +#include -#include "PCLogController.h" +#include -#include "CodeParser.h" +#include NSString *PCEditorDidChangeFileNameNotification = @"PCEditorDidChangeFileNameNotification"; @@ -103,59 +104,13 @@ NSString *PCEditorDidResignActiveNotification = @end @implementation PCProjectEditor -// =========================================================================== -// ==== Class Methods -// =========================================================================== - -+ (PCEditor *)openFileInEditor:(NSString *)path -{ - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - NSString *editor = [ud objectForKey:Editor]; - - if (![editor isEqualToString:@"ProjectCenter"]) - { - NSArray *ea = [editor componentsSeparatedByString:@" "]; - NSString *app = [ea objectAtIndex: 0]; - - if ([[app pathExtension] isEqualToString:@"app"]) - { - BOOL ret = [[NSWorkspace sharedWorkspace] openFile:path - withApplication:app]; - - if (ret == NO) - { - PCLogError(self, @"Could not open %@ using %@", path, app); - } - - return nil; - } - - editor = [[PCEditor alloc] initExternalEditor:editor - withPath:path - projectEditor:self]; - } - else - { - PCEditor *editor; - - editor = [[PCEditor alloc] initWithPath:path - categoryPath:nil - projectEditor:self]; - [editor setWindowed:YES]; - [editor show]; - - return editor; - } - - return nil; -} - // =========================================================================== // ==== Initialisation // =========================================================================== -- (id)initWithProject: (PCProject *)aProject +- (id)initWithProject:(PCProject *)aProject { + PCBundleManager *bundleManager; NSAssert(aProject, @"No project specified!"); if ((self = [super init])) @@ -164,6 +119,15 @@ NSString *PCEditorDidResignActiveNotification = project = aProject; componentView = nil; editorsDict = [[NSMutableDictionary alloc] init]; + + // Bundles + bundleManager = [[project projectManager] bundleManager]; + + // Editor bundles + editorBundlesInfo = [[bundleManager infoForBundlesOfType:@"editor"] copy]; + + // Parser bundles + parserBundlesInfo = [[bundleManager infoForBundlesOfType:@"parser"] copy]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -213,6 +177,8 @@ NSString *PCEditorDidResignActiveNotification = RELEASE(componentView); } + RELEASE(editorBundlesInfo); + RELEASE(parserBundlesInfo); RELEASE(editorsDict); [super dealloc]; @@ -237,32 +203,211 @@ NSString *PCEditorDidResignActiveNotification = // ==== Project and Editor handling // =========================================================================== -- (PCEditor *)editorForFile:(NSString *)path - categoryPath:(NSString *)categoryPath - windowed:(BOOL)yn +- (NSDictionary *)infoTableForBundleType:(NSString *)type + andFileType:(NSString *)extension { - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - NSString *ed = [ud objectForKey:Editor]; - PCEditor *editor; + NSDictionary *bundlesInfo = nil; + NSEnumerator *enumerator = nil; + NSString *bundlePathKey = nil; + NSDictionary *infoTable = nil; - if (![ed isEqualToString:@"ProjectCenter"]) + if ([type isEqualToString:@"editor"]) { - editor = [[PCEditor alloc] initExternalEditor:ed - withPath:path - projectEditor:self]; - return editor; + bundlesInfo = editorBundlesInfo; } + else + { + bundlesInfo = parserBundlesInfo; + } + + enumerator = [[bundlesInfo allKeys] objectEnumerator]; + while ((bundlePathKey = [enumerator nextObject])) + { + infoTable = [bundlesInfo objectForKey:bundlePathKey]; + if ([[infoTable objectForKey:@"FileTypes"] containsObject:extension]) + { + break; + } + else + { + infoTable = nil; + } + } + + return infoTable; +} + +- (NSString *)classNameForBundleType:(NSString*)type + andFile:(NSString *)file +{ + NSString *fileExtension = [file pathExtension]; + NSDictionary *infoTable = nil; + NSString *className = nil; + + infoTable = [self infoTableForBundleType:type andFileType:fileExtension]; + className = [infoTable objectForKey:@"PrincipalClassName"]; + + if (className == nil && [type isEqualToString:@"editor"]) + { + className = [NSString stringWithString:@"PCEditor"]; + } + + return className; +} + +// TODO: Should it be editor or parser? +- (BOOL)editorProvidesBrowserItemsForItem:(NSString *)item +{ + NSDictionary *infoTable = [self infoTableForBundleType:@"editor" + andFileType:[item pathExtension]]; + + if ([[infoTable objectForKey:@"ProvidesBrowserItems"] isEqualToString:@"YES"]) + { + return YES; + } + + return NO; +} + +// categoryPath: +// 1. "/Classes/Class.m/- init" +// 2. "/Subprojects/Project/Classes/Class.m/- init" +// 3. "/Library/gnustep-gui" +- (id)editorForCategoryPath:(NSString *)categoryPath + windowed:(BOOL)windowed +{ + NSArray *pathArray = [categoryPath pathComponents]; + PCProject *activeProject = [[project projectManager] activeProject]; + NSString *category = [[project projectBrowser] nameOfSelectedCategory]; + NSString *categoryKey = [activeProject keyForCategory:category]; + NSString *fileName = nil; + NSString *filePath = nil; + NSFileManager *fm = [NSFileManager defaultManager]; + BOOL isDir; + BOOL editable = YES; + id editor; + NSString *pathLastObject = nil; + NSString *firstSymbol = nil; + + fileName = [[[[project projectBrowser] pathFromSelectedCategory] + pathComponents] objectAtIndex:2]; + filePath = [activeProject pathForFile:fileName forKey:categoryKey]; + +/* NSLog(@"PCPE: fileName: %@ filePath: %@ project: %@", + fileName, filePath, [activeProject projectName]);*/ + + // Determine if file not exist or file is directory + if (![fm fileExistsAtPath:filePath isDirectory:&isDir] || isDir) + { + return nil; + } + + // Determine if file is text file + if (![[PCFileManager defaultManager] isTextFile:filePath]) + { + return nil; + } + + // Determine if file should be opened for read only + if (![project isEditableFile:fileName]) + { + editable = NO; + } + +// NSLog(@"fileName: %@ > %@", fileName, listEntry); + + editor = [self editorForFile:filePath + categoryPath:categoryPath + editable:editable + windowed:windowed]; + if (!editor) + { + NSLog(@"We don't have editor for file: %@", fileName); + } + + pathLastObject = [pathArray lastObject]; +/* NSLog(@"pathArray: c: %i %@", [pathArray count], pathArray); + NSLog(@"pathArray: lastObject %@", [pathArray lastObject]); + NSLog(@"lastObject[1]: %@", + [pathLastObject substringWithRange:NSMakeRange(0,1)]);*/ + + pathLastObject = [pathArray lastObject]; + firstSymbol = [pathLastObject substringWithRange:NSMakeRange(0,1)]; + if ([pathLastObject isEqualToString:@"/"]) // file selected + { + [[project projectBrowser] reloadLastColumnAndNotify:NO]; + } + else if ([firstSymbol isEqualToString:@"@"]) + { + } + else if ([firstSymbol isEqualToString:@"-"] + || [firstSymbol isEqualToString:@"+"]) + { + [editor scrollToMethodName:pathLastObject]; + } + + return editor; +} + +- (id)editorForFile:(NSString *)path + categoryPath:(NSString *)categoryPath + editable:(BOOL)editable + windowed:(BOOL)windowed +{ +// NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; +// NSString *ed = [ud objectForKey:Editor]; + PCBundleManager *bundleManager = [[project projectManager] bundleManager]; + NSString *editorClassName = nil; + NSString *parserClassName = nil; + id editor; + id parser; + + NSLog(@"PCPE: categoryPath: \"%@\"", categoryPath); + + // TODO: Include external editor code into editor bundle? +/* if (![ed isEqualToString:@"ProjectCenter"]) + { + [editor initExternalEditor:ed withPath:path projectEditor:self]; + return editor; + }*/ if (!(editor = [editorsDict objectForKey:path])) { - editor = [[PCEditor alloc] initWithPath:path - categoryPath:categoryPath - projectEditor:self]; + // Editor + editorClassName = [self classNameForBundleType:@"editor" + andFile:[path lastPathComponent]]; + editor = [bundleManager objectForClassName:editorClassName + withProtocol:@protocol(CodeEditor) + inBundleType:@"editor"]; + if (!editor) + { + return nil; + } + + // Parser + parserClassName = [self classNameForBundleType:@"parser" + andFile:[path lastPathComponent]]; + if (parserClassName != nil) + { + NSLog(@"PCPE: parser: %@", parserClassName); + parser = [bundleManager objectForClassName:parserClassName + withProtocol:@protocol(CodeParser) + inBundleType:@"parser"]; + AUTORELEASE(parser); + [editor setParser:parser]; + } + + [editor openFileAtPath:path + categoryPath:categoryPath + projectEditor:self + editable:editable]; + [editorsDict setObject:editor forKey:path]; RELEASE(editor); } - [editor setWindowed:yn]; + [editor setCategoryPath:categoryPath]; + [editor setWindowed:windowed]; [self orderFrontEditorForFile:path]; @@ -271,7 +416,12 @@ NSString *PCEditorDidResignActiveNotification = - (void)orderFrontEditorForFile:(NSString *)path { - PCEditor *editor = [editorsDict objectForKey:path]; + id editor = [editorsDict objectForKey:path]; + + if (!editor) + { + return; + } if ([editor isWindowed]) { @@ -285,7 +435,7 @@ NSString *PCEditorDidResignActiveNotification = } } -- (void)setActiveEditor:(PCEditor *)anEditor +- (void)setActiveEditor:(id)anEditor { if (anEditor != activeEditor) { @@ -293,7 +443,7 @@ NSString *PCEditorDidResignActiveNotification = } } -- (PCEditor *)activeEditor +- (id)activeEditor { return activeEditor; } @@ -305,14 +455,18 @@ NSString *PCEditorDidResignActiveNotification = - (void)closeActiveEditor:(id)sender { + if (!activeEditor) + { + return; + } + [activeEditor closeFile:self save:YES]; } - (void)closeEditorForFile:(NSString *)file { - PCEditor *editor = nil; + id editor; -// editor = [editorsDict objectForKey:file]; if ([editorsDict count] > 0 && (editor = [editorsDict objectForKey:file])) { [editor closeFile:self save:YES]; @@ -325,7 +479,7 @@ NSString *PCEditorDidResignActiveNotification = - (BOOL)closeAllEditors { NSEnumerator *enumerator = [editorsDict keyEnumerator]; - PCEditor *editor = nil; + id editor; NSString *key = nil; NSMutableArray *editedFiles = [[NSMutableArray alloc] init]; @@ -355,8 +509,8 @@ NSString *PCEditorDidResignActiveNotification = // Stop parser. It releases self. // TODO: There should be a few parsers. - [aParser stop]; - [parserConnection release]; +/* [aParser stop]; + [parserConnection release];*/ return YES; } @@ -396,10 +550,10 @@ NSString *PCEditorDidResignActiveNotification = - (BOOL)saveAllFiles { - NSEnumerator *enumerator = [editorsDict keyEnumerator]; - PCEditor *editor; - NSString *key; - BOOL ret = YES; + NSEnumerator *enumerator = [editorsDict keyEnumerator]; + id editor; + NSString *key; + BOOL ret = YES; while ((key = [enumerator nextObject])) { @@ -416,7 +570,7 @@ NSString *PCEditorDidResignActiveNotification = - (BOOL)saveFile { - PCEditor *editor = [self activeEditor]; + id editor = [self activeEditor]; if (editor != nil) { @@ -428,7 +582,7 @@ NSString *PCEditorDidResignActiveNotification = - (BOOL)saveFileAs:(NSString *)file { - PCEditor *editor = [self activeEditor]; + id editor = [self activeEditor]; if (editor != nil) { @@ -439,7 +593,10 @@ NSString *PCEditorDidResignActiveNotification = res = [editor saveFileTo:file]; [editor closeFile:self save:NO]; - [self editorForFile:file categoryPath:categoryPath windowed:iw]; + [self editorForFile:file + categoryPath:categoryPath + editable:YES + windowed:iw]; return res; } @@ -449,7 +606,7 @@ NSString *PCEditorDidResignActiveNotification = - (BOOL)saveFileTo:(NSString *)file { - PCEditor *editor = [self activeEditor]; + id editor = [self activeEditor]; if (editor != nil) { @@ -461,7 +618,7 @@ NSString *PCEditorDidResignActiveNotification = - (BOOL)revertFileToSaved { - PCEditor *editor = [self activeEditor]; + id editor = [self activeEditor]; if (editor != nil) { @@ -490,7 +647,7 @@ NSString *PCEditorDidResignActiveNotification = - (void)editorDidClose:(NSNotification *)aNotif { - PCEditor *editor = [aNotif object]; + id editor = [aNotif object]; // It is not our editor if ([editor projectEditor] != self) @@ -502,8 +659,8 @@ NSString *PCEditorDidResignActiveNotification = if ([editorsDict count]) { - NSString *lastEditorKey = [[editorsDict allKeys] lastObject]; - PCEditor *lastEditor = [editorsDict objectForKey:lastEditorKey]; + NSString *lastEditorKey = [[editorsDict allKeys] lastObject]; + id lastEditor = [editorsDict objectForKey:lastEditorKey]; lastEditorKey = [[editorsDict allKeys] lastObject]; [componentView setContentView:[lastEditor componentView]]; @@ -512,20 +669,19 @@ NSString *PCEditorDidResignActiveNotification = else { PCProjectBrowser *browser = [project projectBrowser]; - NSString *path = [browser path]; [componentView setContentView:scrollView]; [[project projectWindow] makeFirstResponder:scrollView]; - [browser setPath:[path stringByDeletingLastPathComponent]]; + [browser setPath:[browser pathToSelectedCategory]]; [self setActiveEditor:nil]; } } - (void)editorDidBecomeActive:(NSNotification *)aNotif { - PCEditor *editor = [aNotif object]; - NSString *categoryPath = nil; + id editor = [aNotif object]; + NSString *categoryPath = nil; if ([editor projectEditor] != self) // || activeEditor == editor) { @@ -558,10 +714,10 @@ NSString *PCEditorDidResignActiveNotification = - (void)editorDidChangeFileName:(NSNotification *)aNotif { - NSDictionary *_editorDict = [aNotif object]; - PCEditor *_editor = [_editorDict objectForKey:@"Editor"]; - NSString *_oldFileName = nil; - NSString *_newFileName = nil; + NSDictionary *_editorDict = [aNotif object]; + id _editor = [_editorDict objectForKey:@"Editor"]; + NSString *_oldFileName = nil; + NSString *_newFileName = nil; if ([_editor projectEditor] != self) { @@ -575,53 +731,5 @@ NSString *PCEditorDidResignActiveNotification = [editorsDict setObject:_editor forKey:_newFileName]; } -// =========================================================================== -// ==== Parser -// =========================================================================== - -- (id)parserForFile:(NSString *)path -{ - if (parserConnection == nil) - { - NSPort *port1 = nil; - NSPort *port2 = nil; - NSArray *portArray = nil; - - // Create connection to parser server - port1 = [NSPort new]; - port2 = [NSPort new]; - parserConnection = [[NSConnection alloc] initWithReceivePort:port1 - sendPort:port2]; - // Set self as root object for connection with parser. - // setRootObject retains self. - [parserConnection setRootObject:self]; - [self release]; - - // Ports switched here. - portArray = [NSArray arrayWithObjects:port2, port1, nil]; - - NSLog(@"PCProjectEditor: detaching parser thread..."); - - [NSThread detachNewThreadSelector:@selector(connectWithPorts:) - toTarget:[PCObjCParser class] - withObject:portArray]; - // Wait for parser thread initialization (setServer:) - while (aParser == nil) - { - [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode - beforeDate:[NSDate distantFuture]]; - } - } - - return aParser; -} - -- (oneway void)setServer:(id)anObject -{ - NSLog(@"PCProjectEditor: parser thread detached and ready to talk"); - [anObject setProtocolForProxy:@protocol(CodeParser)]; - aParser = [anObject retain]; -} - @end diff --git a/Library/PCProjectInspector.m b/Library/PCProjectInspector.m index 1006469..02de726 100644 --- a/Library/PCProjectInspector.m +++ b/Library/PCProjectInspector.m @@ -23,15 +23,14 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCDefines.h" -#include "PCProjectManager.h" -#include "PCProject.h" -#include "PCProjectBrowser.h" -#include "PCProjectWindow.h" -#include "PCFileNameField.h" -#include "PCProjectInspector.h" +#include +#include +#include +#include +#include +#include -#include "PCLogController.h" +#include @implementation PCProjectInspector @@ -58,6 +57,13 @@ selector:@selector(updateValues:) name:PCProjectDictDidChangeNotification object:nil]; + + // Track Browser selection changes + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector (browserDidSetPath:) + name:PCBrowserDidSetPathNotification + object:nil]; [self inspectorPopupDidChange:inspectorPopup]; @@ -334,6 +340,16 @@ authorsItems = [projectDict objectForKey:PCAuthors]; [authorsList reloadData]; + + // File Attributes + [fileIcon setFileIcon:(id)[project projectBrowser]]; + [self updateFileAttributes]; +} + +- (void)browserDidSetPath:(NSNotification *)aNotif +{ + [fileIcon setFileIcon:[aNotif object]]; + [self updateFileAttributes]; } // ============================================================================ @@ -501,9 +517,9 @@ [project setProjectDictObject:[sender titleOfSelectedItem] forKey:PCLanguage notify:NO]; + [[project projectWindow] setTitle]; } - // ============================================================================ // ==== Project Description // ============================================================================ @@ -661,8 +677,8 @@ [localizableButton setRefusesFirstResponder:YES]; [publicHeaderButton setRefusesFirstResponder:YES]; - [fileIconView setFileNameField:fileNameField]; - [fileIconView setMultipleFilesSelectionText:@"Multiple files selected"]; + [fileIcon setFileNameField:fileIconField]; + [fileIcon setMultipleFilesSelectionText:@"Multiple files selected"]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -671,24 +687,18 @@ object:inspectorPanel]; } -- (void)beginFileRename +- (void)updateFileAttributes { -/* if (fileName != nil) - { - [fileName release]; - } - - fileName = [[fileNameField stringValue] copy]; - NSLog(@"fileName: %@", fileName);*/ - - [fileNameField setEditableField:YES]; - [inspectorPanel makeFirstResponder:fileNameField]; -} - -// Delegate method of PCFileNameField class -- (void)controlStringValueDidChange:(NSString *)aString -{ - NSArray *publicHeaders = nil; + PCProjectBrowser *browser = [project projectBrowser]; + NSString *category = [browser nameOfSelectedCategory]; + NSString *categoryKey = [project keyForCategory:category]; + NSArray *files = [browser selectedFiles]; + NSString *file = nil; + int array_count = [files count]; + int present_count = 0; + NSArray *publicHeaders = nil; + NSArray *localizedResources = nil; + NSEnumerator *enumerator = nil; // Initial default buttons state [localizableButton setEnabled:NO]; @@ -696,25 +706,102 @@ [publicHeaderButton setEnabled:NO]; [publicHeaderButton setState:NSOffState]; + if (files == nil) + { + return; + } + + // --- Enable buttons + + // If selection is not category AND category is allow localization + // enable localizableButton checkbox + if ([[project localizableKeys] containsObject:categoryKey]) + { + [localizableButton setEnabled:YES]; + } + + // If selection is not category + // AND project accepts public headers + // AND file extension is .h or .H enable publicHeaders checkbox. + if ([project canHavePublicHeaders] == YES ) + { + BOOL enable = YES; + + enumerator = [files objectEnumerator]; + while ((file = [enumerator nextObject])) + { + if (![[file pathExtension] isEqualToString:@"h"] && + ![[file pathExtension] isEqualToString:@"H"]) + { + enable = NO; + } + } + + if (enable) + { + [publicHeaderButton setEnabled:YES]; + } + } + + // --- Set state of buttons + // There are 3 sutiuations: + // - all files present in group (state: ON) + // - part of file present in group (state: OFF) + // - no files present in group (state: OFF) + + // Set state of Public Headers button + if ([publicHeaderButton isEnabled]) + { + publicHeaders = [project publicHeaders]; + enumerator = [files objectEnumerator]; + present_count = 0; + while ((file = [enumerator nextObject])) + { + if ([publicHeaders containsObject:file]) + { + present_count++; + } + } + if (array_count == present_count) + { + [publicHeaderButton setState:NSOnState]; + } + } + + // Set state of Localized Resource button + if ([localizableButton isEnabled]) + { + localizedResources = [project localizedResources]; + enumerator = [files objectEnumerator]; + present_count = 0; + while ((file = [enumerator nextObject])) + { + if ([localizedResources containsObject:file]) + { + present_count++; + } + } + if (array_count == present_count) + { + [localizableButton setState:NSOnState]; + } + } +} + +- (void)beginFileRename +{ + [fileIconField setEditableField:YES]; + [inspectorPanel makeFirstResponder:fileIconField]; +} + +// Delegate method of PCFileNameField class +- (void)controlStringValueDidChange:(NSString *)aString +{ if (fileName != nil) { [fileName release]; } fileName = [aString copy]; - - if (fileName) - { - if ([project canHavePublicHeaders] - && [[fileName pathExtension] isEqualToString:@"h"]) - { - [publicHeaderButton setEnabled:YES]; - publicHeaders = [project publicHeaders]; - if (publicHeaders && [publicHeaders containsObject:fileName]) - { - [publicHeaderButton setState:NSOnState]; - } - } - } } // Delegate method of PCFileNameField class @@ -730,50 +817,66 @@ - (void)fileNameDidChange:(id)sender { - if ([fileName isEqualToString:[fileNameField stringValue]]) + if ([fileName isEqualToString:[fileIconField stringValue]]) { return; } /* PCLogInfo(self, @"{%@} file name changed from: %@ to: %@", - [project projectName], fileName, [fileNameField stringValue]);*/ + [project projectName], fileName, [fileIconField stringValue]);*/ - if ([project renameFile:fileName toFile:[fileNameField stringValue]] == NO) + if ([project renameFile:fileName toFile:[fileIconField stringValue]] == NO) { - [fileNameField setStringValue:fileName]; + [fileIconField setStringValue:fileName]; } } - (void)setPublicHeader:(id)sender { - if ([sender state] == NSOffState) + PCProjectBrowser *browser = [project projectBrowser]; + NSArray *files = [browser selectedFiles]; + NSEnumerator *enumerator = [files objectEnumerator]; + NSString *file = nil; + + while ((file = [enumerator nextObject])) { - [project setHeaderFile:fileName public:NO]; - } - else - { - [project setHeaderFile:fileName public:YES]; + if ([sender state] == NSOffState) + { + [project setHeaderFile:fileName public:NO]; + } + else + { + [project setHeaderFile:fileName public:YES]; + } } } - (void)setLocalizableResource:(id)sender { - if ([sender state] == NSOffState) + PCProjectBrowser *browser = [project projectBrowser]; + NSArray *files = [browser selectedFiles]; + NSEnumerator *enumerator = [files objectEnumerator]; + NSString *file = nil; + + while ((file = [enumerator nextObject])) { - [project setLocalizableFile:fileName public:NO]; - } - else - { - [project setLocalizableFile:fileName public:YES]; + if ([sender state] == NSOffState) + { + [project setResourceFile:file localizable:NO]; + } + else + { + [project setResourceFile:file localizable:YES]; + } } } - (void)panelDidResignKey:(NSNotification *)aNotif { - if ([fileNameField isEditable] == YES) + if ([fileIconField isEditable] == YES) { - [inspectorPanel makeFirstResponder:fileIconView]; - [fileNameField setStringValue:fileName]; + [inspectorPanel makeFirstResponder:fileIcon]; + [fileIconField setStringValue:fileName]; } } @@ -781,7 +884,7 @@ // ==== NSTableViews // ============================================================================ -- (int)numberOfRowsInTableView: (NSTableView *)aTableView +- (int)numberOfRowsInTableView:(NSTableView *)aTableView { if (searchOrderList != nil && aTableView == searchOrderList) { @@ -795,9 +898,9 @@ return 0; } -- (id) tableView: (NSTableView *)aTableView - objectValueForTableColumn: (NSTableColumn *)aTableColumn - row: (int)rowIndex +- (id) tableView:(NSTableView *)aTableView + objectValueForTableColumn:(NSTableColumn *)aTableColumn + row:(int)rowIndex { if (searchOrderList != nil && aTableView == searchOrderList) { @@ -814,7 +917,7 @@ - (void) tableView:(NSTableView *)aTableView setObjectValue:anObject forTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex + row:(int)rowIndex { if (authorsList != nil && aTableView == authorsList) { diff --git a/Library/PCProjectLauncher.m b/Library/PCProjectLauncher.m index 4115520..8f2073b 100644 --- a/Library/PCProjectLauncher.m +++ b/Library/PCProjectLauncher.m @@ -23,16 +23,17 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCProjectLauncher.h" -#include "PCDefines.h" -#include "PCProject.h" -#include "PCProjectManager.h" -#include "PCButton.h" - -#include "PCLogController.h" - #include +#include +#include +#include +#include + +#include + +#include + #ifndef NOTIFICATION_CENTER #define NOTIFICATION_CENTER [NSNotificationCenter defaultCenter] #endif diff --git a/Library/PCProjectLoadedFiles.m b/Library/PCProjectLoadedFiles.m index 217d42d..1edc98e 100644 --- a/Library/PCProjectLoadedFiles.m +++ b/Library/PCProjectLoadedFiles.m @@ -23,15 +23,15 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCDefines.h" -#include "PCProject.h" -#include "PCProjectEditor.h" -#include "PCEditor.h" +#include +#include +#include -#include "PCPrefController.h" -#include "PCLogController.h" +#include +#include -#include "PCProjectLoadedFiles.h" +#include +#include @implementation PCProjectLoadedFiles @@ -230,9 +230,9 @@ - (void)fileWillOpen:(NSNotification *)aNotif { - PCEditor *editor = [aNotif object]; - NSString *filePath = nil; - int row; + id editor = [aNotif object]; + NSString *filePath = nil; + int row; if ([editor projectEditor] != [project projectEditor]) { @@ -260,8 +260,8 @@ - (void)fileDidClose:(NSNotification *)aNotif { - PCEditor *editor = [aNotif object]; - NSString *filePath = [editor path]; + id editor = [aNotif object]; + NSString *filePath = [editor path]; if ([editor projectEditor] != [project projectEditor]) { @@ -287,10 +287,10 @@ - (void)editorDidBecomeActive:(NSNotification *)aNotif { - PCEditor *editor = [aNotif object]; - NSString *filePath = nil; - unsigned index; - unsigned filesCount; + id editor = [aNotif object]; + NSString *filePath = nil; + unsigned index; + unsigned filesCount; if ([editor projectEditor] != [project projectEditor]) { @@ -310,11 +310,11 @@ - (void)editorDidChangeFileName:(NSNotification *)aNotif { - NSDictionary *_editorDict = [aNotif object]; - PCEditor *_editor = [_editorDict objectForKey:@"Editor"]; - NSString *_oldFileName = nil; - NSString *_newFileName = nil; - unsigned index; + NSDictionary *_editorDict = [aNotif object]; + id _editor = [_editorDict objectForKey:@"Editor"]; + NSString *_oldFileName = nil; + NSString *_newFileName = nil; + unsigned index; if ([_editor projectEditor] != [project projectEditor]) { diff --git a/Library/PCProjectManager.m b/Library/PCProjectManager.m index 45f0e17..3eb0177 100644 --- a/Library/PCProjectManager.m +++ b/Library/PCProjectManager.m @@ -23,27 +23,26 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCDefines.h" -#include "PCPrefController.h" -#include "PCLogController.h" +#include +#include +#include -#include "PCBundleLoader.h" -#include "PCFileManager.h" -#include "PCProjectManager.h" +#include +#include +#include -#include "PCProject.h" -#include "PCProjectWindow.h" -#include "PCProjectBrowser.h" -#include "PCProjectInspector.h" -#include "PCProjectEditor.h" -#include "PCEditor.h" -#include "PCBuildPanel.h" -#include "PCLaunchPanel.h" -#include "PCLoadedFilesPanel.h" +#include +#include +#include +#include +#include +#include +#include +#include -#include "PCServer.h" - -#include "ProjectType.h" +#include "Protocols/ProjectType.h" +#include "Protocols/CodeEditor.h" +#include "Protocols/ProjectEditor.h" NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; @@ -63,9 +62,11 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; launchPanel = nil; loadedFilesPanel = nil; findPanel = nil; - - [self loadProjectTypeBunldes]; + // Prepare bundles + bundleManager = [[PCBundleManager alloc] init]; + projectTypes = [self loadProjectTypesInfo]; + loadedProjects = [[NSMutableDictionary alloc] init]; nonProjectEditors = [[NSMutableDictionary alloc] init]; @@ -111,7 +112,7 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; RELEASE(nonProjectEditors); RELEASE(fileManager); - RELEASE(bundleLoader); + RELEASE(bundleManager); RELEASE(projectTypes); RELEASE(projectTypeAccessaryView); RELEASE(fileTypeAccessaryView); @@ -176,6 +177,33 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; RELEASE(projectTypePopup); } +- (NSMutableDictionary *)loadProjectTypesInfo +{ + NSDictionary *bundlesInfo; + NSEnumerator *enumerator; + NSArray *bundlePaths; + NSString *key; + NSDictionary *infoTable; + + if (projectTypes == nil) + { + projectTypes = [[NSMutableDictionary alloc] init]; + bundlesInfo = [bundleManager infoForBundlesOfType:@"project"]; + + bundlePaths = [bundlesInfo allKeys]; + enumerator = [bundlePaths objectEnumerator]; + + while ((key = [enumerator nextObject])) + { + infoTable = [bundlesInfo objectForKey:key]; + [projectTypes setObject:[infoTable objectForKey:@"PrincipalClassName"] + forKey:[infoTable objectForKey:@"Name"]]; + } + } + + return projectTypes; +} + // ============================================================================ // ==== Timer handling // ============================================================================ @@ -223,6 +251,11 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; // ==== Accessory methods // ============================================================================ +- (PCBundleManager *)bundleManager +{ + return bundleManager; +} + - (PCFileManager *)fileManager { return fileManager; @@ -257,7 +290,7 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; && [[ud objectForKey:SeparateLoadedFiles] isEqualToString:@"YES"]) { loadedFilesPanel = - [[PCLoadedFilesPanel alloc] initWithProjectManager:self]; + [[PCProjectLoadedFilesPanel alloc] initWithProjectManager:self]; } return loadedFilesPanel; @@ -279,7 +312,7 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; if (!buildPanel && [[ud objectForKey:SeparateBuilder] isEqualToString:@"YES"]) { - buildPanel = [[PCBuildPanel alloc] initWithProjectManager:self]; + buildPanel = [[PCProjectBuilderPanel alloc] initWithProjectManager:self]; } return buildPanel; @@ -292,7 +325,7 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; if (!launchPanel && [[ud objectForKey:SeparateLauncher] isEqualToString:@"YES"]) { - launchPanel = [[PCLaunchPanel alloc] initWithProjectManager:self]; + launchPanel = [[PCProjectLauncherPanel alloc] initWithProjectManager:self]; } return launchPanel; @@ -398,24 +431,24 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; // ==== Project actions // ============================================================================ -- (NSString *)convertLegacyProject:(NSMutableDictionary *)pDict - atPath:(NSString *)aPath +- (PCProject *)convertLegacyProject:(NSMutableDictionary *)pDict + atPath:(NSString *)aPath { - NSString *pPath = nil; - NSString *projectClassName = nil; - NSString *projectTypeName = nil; - NSString *_projectPath = nil; - NSFileManager *fm = [NSFileManager defaultManager]; - NSString *_resPath = nil; - NSArray *_fromDirArray = nil; - NSString *_fromDirPath = nil; - NSString *_file = nil; - NSString *_2file = nil; - NSString *_resFile = nil; - int i = 0; - id projectCreator; - NSMutableArray *otherResArray = nil; - NSString *plistFile = nil; + NSString *pPath = nil; + NSString *projectClassName = nil; + NSString *projectTypeName = nil; + NSString *_projectPath = nil; + NSFileManager *fm = [NSFileManager defaultManager]; + NSString *_resPath = nil; + NSArray *_fromDirArray = nil; + NSString *_fromDirPath = nil; + NSString *_file = nil; + NSString *_2file = nil; + NSString *_resFile = nil; + int i = 0; + PCProject *project = nil; + NSMutableArray *otherResArray = nil; + NSString *plistFile = nil; projectClassName = [pDict objectForKey:PCProjectBuilderClass]; if (projectClassName == nil) @@ -424,6 +457,8 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; return nil; } + NSLog(@"Convert legacy"); + // Gorm project type doesn't exists anymore if ([projectClassName isEqualToString:@"PCGormProj"]) { @@ -499,9 +534,12 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; // Remove obsolete records from project dictionary and write to PC.project pPath = [[aPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"PC.project"]; - projectCreator = [NSClassFromString(projectClassName) sharedCreator]; - projectTypeName = [projectCreator projectTypeName]; + project = [bundleManager objectForClassName:projectClassName + withProtocol:@protocol(ProjectType) + inBundleType:@"project"]; + + projectTypeName = [project projectTypeName]; [pDict setObject:projectTypeName forKey:PCProjectType]; [pDict removeObjectForKey:PCProjectBuilderClass]; [pDict removeObjectForKey:PCPrincipalClass]; @@ -511,58 +549,57 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; // [[NSFileManager defaultManager] removeFileAtPath:aPath handler:nil]; } - return projectClassName; + return project; } - (PCProject *)loadProjectAt:(NSString *)aPath { - NSMutableDictionary *projectFile = nil; - NSString *projectTypeName = nil; - NSString *projectClassName = nil; - id projectCreator; - PCProject *project = nil; + NSMutableDictionary *projectFile = nil; + NSString *projectTypeName = nil; + NSString *projectClassName = nil; + PCProject *project = nil; projectFile = [NSMutableDictionary dictionaryWithContentsOfFile:aPath]; // For compatibility with 0.3.x projects - projectClassName = [self convertLegacyProject:projectFile atPath:aPath]; - if (projectClassName) - { + project = [self convertLegacyProject:projectFile atPath:aPath]; + if (project) + {// Project was converted and created PC*Project with alloc&init aPath = [[aPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"PC.project"]; } - - // No conversion were taken - if (projectClassName == nil) - { + else + {// No conversion were taken projectTypeName = [projectFile objectForKey:PCProjectType]; projectClassName = [projectTypes objectForKey:projectTypeName]; if (projectClassName == nil) { - NSRunAlertPanel(@"Loading Project Failed!", + NSRunAlertPanel(@"Load Project", @"Project type '%@' is not supported!", @"OK",nil,nil,projectTypeName); + return nil; } + project = [bundleManager objectForClassName:projectClassName + withProtocol:@protocol(ProjectType) + inBundleType:@"project"]; } - projectCreator = [NSClassFromString(projectClassName) sharedCreator]; - - if ((project = [projectCreator openProjectAt:aPath])) + if (![project openWithDictionaryAt:aPath]) { - PCLogStatus(self, @"Project %@ loaded as %@", - [project projectName], [projectCreator projectTypeName]); - // Started only if there's not save timer yet - [self startSaveTimer]; - [project validateProjectDict]; - - return project; + NSRunAlertPanel(@"Load Project", + @"Could not load project '%@'!", + @"OK",nil,nil,aPath); + return nil; } - NSRunAlertPanel(@"Loading Project Failed!", - @"Could not load project '%@'!", - @"OK",nil,nil,aPath); + PCLogStatus(self, @"Project %@ loaded as %@", + [project projectName], [project projectTypeName]); - return nil; + // Started only if there's not save timer yet + [self startSaveTimer]; + [project validateProjectDict]; + + return project; } - (BOOL)openProjectAt:(NSString *)aPath @@ -620,10 +657,10 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; - (PCProject *)createProjectOfType:(NSString *)projectType path:(NSString *)aPath { - NSString *className = [projectTypes objectForKey:projectType]; - Class creatorClass = NSClassFromString(className); - PCProject *project = nil; - NSString *projectName = [aPath lastPathComponent]; + NSString *className = [projectTypes objectForKey:projectType]; + PCProject *projectCreator; + PCProject *project = nil; + NSString *projectName = [aPath lastPathComponent]; if ((project = [loadedProjects objectForKey:projectName]) != nil) { @@ -631,14 +668,23 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; return project; } - if (![creatorClass conformsToProtocol:@protocol(ProjectType)]) + projectCreator = [bundleManager objectForClassName:className + withProtocol:@protocol(ProjectType) + inBundleType:@"project"]; +// NSLog(@"%@ CLASS: %@", className, projectCreator); + if (!projectCreator) { - [NSException raise:NOT_A_PROJECT_TYPE_EXCEPTION - format:@"%@ does not conform to ProjectType!", projectType]; return nil; } - if (!(project = [[creatorClass sharedCreator] createProjectAt:aPath])) + // Create project directory + if (![[PCFileManager defaultManager] createDirectoriesIfNeededAtPath:aPath]) + { + return nil; + } + + // Create project + if (!(project = [projectCreator createProjectAt:aPath])) { return nil; } @@ -661,12 +707,13 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; accView:nil]; filePath = [files objectAtIndex:0]; - if (filePath != nil && [self openProjectAt:filePath] == NO) + if (filePath != nil) { - NSRunAlertPanel(@"Attention!", + [self openProjectAt:filePath]; +/* NSRunAlertPanel(@"Attention!", @"Couldn't open project %@!", @"OK",nil,nil, - [filePath stringByDeletingLastPathComponent]); + [filePath stringByDeletingLastPathComponent]);*/ } } @@ -776,7 +823,7 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; NSString *category = [[project projectBrowser] nameOfSelectedCategory]; NSString *categoryKey = [project keyForCategory:category]; NSString *directory = [activeProject dirForCategoryKey:categoryKey]; - NSString *removeString = [NSString stringWithString:@"Remove files..."]; + NSString *removeString = nil; NSMutableArray *subprojs = [NSMutableArray array]; int i; @@ -793,6 +840,7 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; } else { + removeString = [NSString stringWithString:@"Remove files..."]; project = activeProject; } @@ -826,6 +874,7 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; BOOL flag = (ret == NSAlertDefaultReturn) ? YES : NO; // Remove from projectDict + // If files localizable make them not localizable ret = [project removeFiles:files forKey:categoryKey notify:YES]; // Remove files from disk @@ -1027,17 +1076,57 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; - (void)openFileWithEditor:(NSString *)path { - PCEditor *editor; +/* id editor; + NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + NSString *editor = [ud objectForKey:Editor]; - editor = [PCProjectEditor openFileInEditor:path]; +// editor = [PCProjectEditor openFileInEditor:path]; + + if (![editor isEqualToString:@"ProjectCenter"]) + { + NSArray *ea = [editor componentsSeparatedByString:@" "]; + NSString *app = [ea objectAtIndex: 0]; + + if ([[app pathExtension] isEqualToString:@"app"]) + { + BOOL ret = [[NSWorkspace sharedWorkspace] openFile:path + withApplication:app]; + + if (ret == NO) + { + PCLogError(self, @"Could not open %@ using %@", path, app); + } + + return nil; + } + + editor = [[editorClass alloc] initExternalEditor:editor + withPath:path + projectEditor:self]; + } + else + { + id editor; + + editor = [[editorClass alloc] initWithPath:path + categoryPath:nil + projectEditor:self]; + [editor setWindowed:YES]; + [editor show]; + + return editor; + } + + return nil; [nonProjectEditors setObject:editor forKey:path]; - RELEASE(editor); + + [editor release];*/ } - (void)editorDidClose:(NSNotification *)aNotif { - PCEditor *editor = [aNotif object]; + id editor = [aNotif object]; [nonProjectEditors removeObjectForKey:[editor path]]; } @@ -1073,46 +1162,6 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; @end -@implementation PCProjectManager (ProjectRegistration) - -- (void)loadProjectTypeBunldes -{ - projectTypes = [[NSMutableDictionary alloc] init]; - - bundleLoader = [[PCBundleLoader alloc] init]; - [bundleLoader setDelegate:self]; - [bundleLoader loadBundlesWithExtension:@"project"]; -} - -- (PCBundleLoader *)bundleLoader -{ - return bundleLoader; -} - -- (NSDictionary *)projectTypes -{ - return projectTypes; -} - -- (void)bundleLoader:(id)sender didLoadBundle:(NSBundle *)aBundle -{ - Class principalClass; - NSString *projectTypeName = nil; - - NSAssert(aBundle,@"No valid bundle!"); - - principalClass = [aBundle principalClass]; - projectTypeName = [[principalClass sharedCreator] projectTypeName]; - - if (![projectTypes objectForKey:projectTypeName]) - { - [projectTypes setObject:NSStringFromClass(principalClass) - forKey:projectTypeName]; - } -} - -@end - @implementation PCProjectManager (Subprojects) - (BOOL)newSubproject @@ -1190,9 +1239,9 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; - (PCProject *)createSubprojectOfType:(NSString *)projectType path:(NSString *)aPath { - NSString *className = [projectTypes objectForKey:projectType]; - Class creatorClass = NSClassFromString(className); - PCProject *subproject = nil; + NSString *className = [projectTypes objectForKey:projectType]; + PCProject *projectCreator; + PCProject *subproject = nil; /* NSString *subprojectName = [aPath lastPathComponent]; if ((project = [activeProject objectForKey:projectName]) != nil) @@ -1201,14 +1250,10 @@ NSString *PCActiveProjectDidChangeNotification = @"PCActiveProjectDidChange"; return project; }*/ - if (![creatorClass conformsToProtocol:@protocol(ProjectType)]) - { - [NSException raise:NOT_A_PROJECT_TYPE_EXCEPTION - format:@"%@ does not conform to ProjectType!", projectType]; - return nil; - } - - if (!(subproject = [[creatorClass sharedCreator] createProjectAt:aPath])) + projectCreator = [bundleManager objectForClassName:className + withProtocol:@protocol(ProjectType) + inBundleType:@"project"]; + if (!(subproject = [projectCreator createProjectAt:aPath])) { return nil; } diff --git a/Library/PCProjectWindow.m b/Library/PCProjectWindow.m index d07adb5..3d4ac26 100644 --- a/Library/PCProjectWindow.m +++ b/Library/PCProjectWindow.m @@ -23,23 +23,23 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCDefines.h" -#include "PCSplitView.h" -#include "PCButton.h" +#include +#include +#include -#include "PCProjectManager.h" -#include "PCProject.h" +#include +#include -#include "PCProjectWindow.h" -#include "PCProjectBrowser.h" -#include "PCProjectEditor.h" -#include "PCProjectBuilder.h" -#include "PCProjectLauncher.h" -#include "PCProjectLoadedFiles.h" -#include "PCProjectInspector.h" +#include +#include +#include +#include +#include +#include +#include -#include "PCPrefController.h" -#include "PCLogController.h" +#include +#include @implementation PCProjectWindow @@ -66,7 +66,7 @@ - (void)_initUI { NSRect rect; - NSView *browserView = nil; +// NSView *browserView = nil; if (projectWindow != nil) { @@ -122,11 +122,12 @@ rect = [[projectWindow contentView] frame]; if (h_split) { - rect.size.height = 130; + rect.size.height = 185; } v_split = [[PCSplitView alloc] initWithFrame:rect]; [v_split setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; [v_split setVertical:YES]; + [v_split setDelegate:self]; /* * File Browser @@ -217,6 +218,13 @@ selector:@selector(preferencesDidChange:) name:PCPreferencesDidChangeNotification object:nil]; + + // Track Browser selection changes for file icon updates + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector (browserDidSetPath:) + name:PCBrowserDidSetPathNotification + object:[project projectBrowser]]; } return self; @@ -224,9 +232,12 @@ - (void)setTitle { - [projectWindow setTitle: [NSString stringWithFormat: @"%@ - %@", - [project projectName], - [[project projectPath] stringByAbbreviatingWithTildeInPath]]]; + NSString *name = [project projectName]; + NSString *path = [[project projectPath] stringByAbbreviatingWithTildeInPath]; + NSString *language = [[project projectDict] objectForKey:PCLanguage]; + + [projectWindow + setTitle:[NSString stringWithFormat:@"%@ - %@ [%@]",name,path,language]]; } - (void)dealloc @@ -299,7 +310,7 @@ [customView display]; } -- (void)setStatusLineText:(NSString *)text +- (void)updateStatusLineWithText:(NSString *)text { [statusLine setStringValue:text]; } @@ -537,6 +548,7 @@ //--- Add Custom view if ([self hasCustomView] && customView == nil) { +// [browserView setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin]; [self _createCustomView]; } @@ -579,6 +591,7 @@ //--- Remove Custom view if (![self hasCustomView] && customView != nil) { +// [browserView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; [customView removeFromSuperview]; [h_split adjustSubviews]; customView = nil; @@ -603,6 +616,11 @@ } } +- (void)browserDidSetPath:(NSNotification *)aNotif +{ + [fileIcon setFileIcon:[aNotif object]]; +} + // ============================================================================ // ==== Window delegate // ============================================================================ @@ -717,69 +735,128 @@ // ==== SplitView delegate // ============================================================================ -- (void) splitView:(NSSplitView *)sender - resizeSubviewsWithOldSize:(NSSize)oldSize +// Subviews: browser and loaded files +- (void)resizeVerticalSubiewsWithOldSize:(NSSize)oldSize { - NSDictionary *projectDict = [project projectDict]; - NSDictionary *windowsDict = [projectDict objectForKey:@"PC_WINDOWS"]; - NSSize hSplitSize = [sender frame].size; + NSSize splitSize = [v_split frame].size; + NSDictionary *projectDict = nil; + NSDictionary *windowsDict = nil; + NSString *browserString = nil; NSRect browserRect; - NSRect vSplitRect; NSRect boxRect; + if (splitSize.width == oldSize.width && splitSize.height == oldSize.height) + { + return; + } + +// NSLog(@"resize vertical split view"); +// NSLog(@"v_split %@", NSStringFromRect([v_split frame])); + + if (!_splitViewsRestored) + { + projectDict = [project projectDict]; + windowsDict = [projectDict objectForKey:@"PC_WINDOWS"]; + if (windowsDict != nil) + { + browserString = [windowsDict objectForKey:@"ProjectBrowser"]; + if (browserString != nil && ![browserString isEqualToString:@""]) + { + browserRect = NSRectFromString(browserString); + } + } + else + { + browserRect = NSMakeRect(0, 0, splitSize.width, splitSize.height); + } + } + // Use saved frame of ProjectBrowser only first time. Every time window is // resized use new size of subviews. if (_splitViewsRestored) { browserRect = [[[project projectBrowser] view] frame]; - } - else - { - browserRect = - NSRectFromString([windowsDict objectForKey:@"ProjectBrowser"]); + browserRect.size.height = splitSize.height; + if (![self hasLoadedFilesView]) + { + browserRect.size.width = splitSize.width; + } } - // v_split resize - vSplitRect = browserRect; - if (vSplitRect.size.height > 0) - { - vSplitRect.size.width = hSplitSize.width; - } - else - { - vSplitRect.size.width = hSplitSize.width; - vSplitRect.size.height = 100; - vSplitRect.origin.x = 0; - vSplitRect.origin.y = 0; - } - NSLog(@"v_split %@", NSStringFromRect(vSplitRect)); - [v_split setFrame:vSplitRect]; + // Browser +// NSLog(@"browser %@", NSStringFromRect(browserRect)); + [browserView setFrame:browserRect]; - // v_split subviews resize + // Loaded Files if ([self hasLoadedFilesView]) { - // browser - NSLog(@"browser %@", NSStringFromRect(browserRect)); - [[[project projectBrowser] view] setFrame:browserRect]; - - // loaded files boxRect.origin.x = browserRect.size.width + [v_split dividerThickness]; boxRect.origin.y = 0; boxRect.size.width = [v_split frame].size.width - boxRect.origin.x; boxRect.size.height = [v_split frame].size.height; - NSLog(@"loadedFiles %@", NSStringFromRect(boxRect)); +// NSLog(@"loadedFiles %@", NSStringFromRect(boxRect)); [[[project projectLoadedFiles] componentView] setFrame:boxRect]; } - // editor - boxRect.origin.x = 0; - boxRect.origin.y = browserRect.size.height + [sender dividerThickness]; - boxRect.size.width = hSplitSize.width; - boxRect.size.height = hSplitSize.height - boxRect.origin.y; - [customView setFrame:boxRect]; - _splitViewsRestored = YES; } +// Subviews: vertical split view and custom view +- (void)resizeHorizontalSubiewsWithOldSize:(NSSize)oldSize +{ + NSSize splitSize = [h_split frame].size; + NSSize hSplitSize; + NSRect vSplitRect; + NSRect boxRect; + + if (splitSize.width == oldSize.width && splitSize.height == oldSize.height) + { + return; + } + +// NSLog(@"resize horizontal split view"); + + hSplitSize = [h_split frame].size; + + // Vertical Split View + vSplitRect = [browserView frame]; + vSplitRect.origin.x = 0; + vSplitRect.origin.y = 0; + if (![self hasCustomView]) + { + vSplitRect.size = hSplitSize; + } + else + { + vSplitRect.size.width = hSplitSize.width; + } + [v_split setFrame:vSplitRect]; + + // Custom view (Editor|Builder|Launcher) + if ([self hasCustomView]) + { + boxRect.origin.x = 0; + boxRect.origin.y = vSplitRect.size.height + [h_split dividerThickness]; + boxRect.size.width = hSplitSize.width; + boxRect.size.height = hSplitSize.height - boxRect.origin.y; + [customView setFrame:boxRect]; + } +} + +- (void) splitView:(NSSplitView *)sender + resizeSubviewsWithOldSize:(NSSize)oldSize +{ + if (sender == v_split) + { + [self resizeVerticalSubiewsWithOldSize:oldSize]; + } + else + { + [self resizeHorizontalSubiewsWithOldSize:oldSize]; + } + + return; +} + @end diff --git a/Library/PCSplitView.m b/Library/PCSplitView.m index af10812..7710936 100644 --- a/Library/PCSplitView.m +++ b/Library/PCSplitView.m @@ -23,7 +23,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCSplitView.h" +#include @implementation PCSplitView diff --git a/PCAppController.m b/PCAppController.m index e0689d2..3b86422 100644 --- a/PCAppController.m +++ b/PCAppController.m @@ -19,12 +19,12 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ +#include +#include #include "PCAppController.h" #include "PCMenuController.h" #include "PCInfoController.h" -#include "PCPrefController.h" -#include "PCLogController.h" #include @@ -95,11 +95,6 @@ return logController; } -- (PCServer *)doServer -{ - return doServer; -} - //============================================================================ //==== Misc... //============================================================================ @@ -136,29 +131,7 @@ } [logController - logMessage:@"Loading additional subsystems..." withTag:INFO sender:self]; - - doServer = [[PCServer alloc] init]; - - NS_DURING - - doConnection = [[NSConnection alloc] init]; - [doConnection registerName:connectionName]; - - NS_HANDLER - - NSRunAlertPanel(@"Warning!", - @"Could not register the DO connection %@", - @"OK",nil,nil,nil, - connectionName); - NS_ENDHANDLER - - [[NSNotificationCenter defaultCenter] addObserver:doServer - selector:@selector(connectionDidDie:) - name:NSConnectionDidDieNotification - object:doConnection]; - - [doConnection setDelegate:doServer]; + logMessage:NSLocalizedString(@"Loading additional subsystems...", @"When loaded additional bundles") withTag:INFO sender:self]; [[NSNotificationCenter defaultCenter] postNotificationName:PCAppDidInitNotification @@ -236,8 +209,6 @@ RELEASE(menuController); RELEASE(projectManager); - RELEASE(doServer); - #ifdef DEVELOPMENT NSLog (@"--- Application WILL terminate.END"); #endif diff --git a/PCInfoController.m b/PCInfoController.m index 5268e6c..a4dc9cf 100644 --- a/PCInfoController.m +++ b/PCInfoController.m @@ -20,9 +20,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#include "PCInfoController.h" #include +#include "PCInfoController.h" + @implementation PCInfoController - (id)init diff --git a/PCMenuController.m b/PCMenuController.m index 82656f3..13979b2 100644 --- a/PCMenuController.m +++ b/PCMenuController.m @@ -19,13 +19,13 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ +#include +#include +#include #include "PCAppController.h" #include "PCMenuController.h" #include "PCInfoController.h" -#include "PCPrefController.h" -#include "PCLogController.h" -#include @implementation PCMenuController @@ -208,6 +208,7 @@ notify:YES]; [[project projectEditor] editorForFile:newFilePath categoryPath:categoryPath + editable:YES windowed:NO]; } } @@ -254,7 +255,7 @@ } // Edit. PCProjectEditor have to provide this menu and functionality -- (void)findShowPanel:(id)sender +/*- (void)findShowPanel:(id)sender { [[PCTextFinder sharedFinder] showFindPanel:self]; } @@ -267,7 +268,7 @@ - (void)findPrevious:(id)sender { [[PCTextFinder sharedFinder] findPrevious:self]; -} +}*/ // Tools @@ -496,7 +497,7 @@ } // Find menu items - if (editorIsActive == NO && [menuTitle isEqualToString: @"Find"]) +/* if (editorIsActive == NO && [menuTitle isEqualToString: @"Find"]) { if (![[[PCTextFinder sharedFinder] findPanel] isVisible]) { @@ -507,7 +508,7 @@ if ([[menuItem title] isEqualToString:@"Jump to Selection"]) return NO; if ([[menuItem title] isEqualToString:@"Line Number..."]) return NO; if ([[menuItem title] isEqualToString:@"Man Page"]) return NO; - } + }*/ // Toolbar if ([[menuItem title] isEqualToString:@"Hide Tool Bar"]