/* GNUstep ProjectCenter - http: //www.gnustep.org Copyright (C) 2001 Free Software Foundation Author: Serg Stoyan This file is part of GNUstep. This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include "PCAppProject+Inspector.h" // ---------------------------------------------------------------------------- // --- Customized text field // ---------------------------------------------------------------------------- NSString *PCITextFieldGetFocus = @"PCITextFieldGetFocusNotification"; @implementation PCAppTextField - (BOOL) becomeFirstResponder { [[NSNotificationCenter defaultCenter] postNotificationName: PCITextFieldGetFocus object: self]; return [super becomeFirstResponder]; } @end @implementation PCAppProject (Inspector) - (void) awakeFromNib { [docBasedAppButton setRefusesFirstResponder: YES]; [docBasedAppButton setState: ([[projectDict objectForKey: PCDocumentBasedApp] isEqualToString: @"YES"]) ? NSOnState : NSOffState]; } // ---------------------------------------------------------------------------- // --- User Interface // ---------------------------------------------------------------------------- - (void) createProjectAttributes { // Languages [projectLanguagePB removeAllItems]; [projectLanguagePB addItemsWithTitles: [projectDict objectForKey: PCUserLanguages]]; [projectLanguagePB selectItemWithTitle: [projectDict objectForKey: PCLanguage]]; // TFs Buttons [setFieldButton setRefusesFirstResponder: YES]; [clearFieldButton setRefusesFirstResponder: YES]; // Document types buttons [addDocTypeButton setRefusesFirstResponder: YES]; [removeDocTypeButton setRefusesFirstResponder: YES]; [docBasedAppButton setRefusesFirstResponder: YES]; [self setDocBasedApp: docBasedAppButton]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(tfGetFocus:) name: PCITextFieldGetFocus object: nil]; [projectAttributesView retain]; [self updateInspectorValues: nil]; } - (NSView *) projectAttributesView { if (!projectAttributesView) { if ([NSBundle loadNibNamed: @"Inspector" owner: self] == NO) { NSLog(@"PCAppProject: error loading Inspector NIB!"); return nil; } [self createProjectAttributes]; } return projectAttributesView; } // ---------------------------------------------------------------------------- // --- Actions // ---------------------------------------------------------------------------- - (void) setCurrentLanguage: (id)sender { NSLog(@"set current language to %@", [sender titleOfSelectedItem]); [self setProjectDictObject: [sender titleOfSelectedItem] forKey: PCLanguage notify: YES]; } - (void) setAppClass: (id)sender { [self setProjectDictObject: [appClassField stringValue] forKey: PCPrincipalClass notify: YES]; } - (void) setIconViewImage: (NSImage *)image { [iconView setImage: nil]; [iconView display]; if (image == nil) { return; } [iconView setImage: image]; [iconView display]; } - (void) setFile: (id)sender { if (!activeTextField) { return; } if (activeTextField == appImageField) { [self setAppIcon: self]; } else if (activeTextField == helpFileField) { NSString *value = [activeTextField stringValue]; [self setProjectDictObject: value forKey: PCHelpFile notify: YES]; NSLog(@"Set %@", value); } else if (activeTextField == mainNIBField) { [self setMainNib: self]; } } - (void) clearFile: (id)sender { if (!activeTextField) { return; } if (activeTextField == appImageField) { [self clearAppIcon: self]; } else if (activeTextField == helpFileField) { [infoDict removeObjectForKey: @"GSHelpContentsFile"]; [self setProjectDictObject: @"" forKey: PCHelpFile notify: YES]; } else if (activeTextField == mainNIBField) { [self clearMainNib: self]; } [self setIconViewImage: nil]; } // Application Icon - (void) setAppIcon: (id)sender { int result; NSArray *fileTypes = [NSImage imageFileTypes]; NSOpenPanel *openPanel = [NSOpenPanel openPanel]; NSString *dir = nil; [openPanel setAllowsMultipleSelection: NO]; [openPanel setTitle: @"Set Application Icon"]; dir = [[NSUserDefaults standardUserDefaults] objectForKey: @"LastOpenDirectory"]; result = [openPanel runModalForDirectory: dir file: nil types: fileTypes]; if (result == NSOKButton) { NSString *imageFilePath = [[openPanel filenames] objectAtIndex: 0]; if (![self setAppIconWithImageAtPath: imageFilePath]) { NSRunAlertPanel(@"Error while opening file!", @"Couldn't open %@", @"OK", nil, nil,imageFilePath); } } } - (void) clearAppIcon: (id)sender { [appImageField setStringValue: @""]; [infoDict setObject: @"" forKey: @"NSIcon"]; [infoDict setObject: @"" forKey: @"ApplicationIcon"]; [self setProjectDictObject: @"" forKey: PCAppIcon notify: YES]; } - (BOOL) setAppIconWithImageAtPath: (NSString *)path { NSImage *image = nil; NSString *imageName = nil; if (!(image = [[NSImage alloc] initWithContentsOfFile: path])) { return NO; } imageName = [path lastPathComponent]; [appImageField setStringValue: imageName]; [self setIconViewImage: image]; [self addAndCopyFiles: [NSArray arrayWithObject: path] forKey: PCImages]; [infoDict setObject: imageName forKey: @"NSIcon"]; [infoDict setObject: imageName forKey: @"ApplicationIcon"]; [self setProjectDictObject: imageName forKey: PCAppIcon notify: YES]; return YES; } // Main Interface File - (void) setMainNib: (id)sender { int result; NSOpenPanel *openPanel = [NSOpenPanel openPanel]; NSString *dir = nil; [openPanel setAllowsMultipleSelection: NO]; [openPanel setTitle: @"Set Main Interface File"]; dir = [[NSUserDefaults standardUserDefaults] objectForKey: @"LastOpenDirectory"]; result = [openPanel runModalForDirectory: dir file: nil types: [NSArray arrayWithObject: @"gorm"]]; if (result == NSOKButton) { NSString *file = [[openPanel filenames] objectAtIndex: 0]; if (![self setMainNibWithFileAtPath: file]) { NSRunAlertPanel(@"Error while opening file!", @"Couldn't open %@", @"OK", nil, nil,file); } } } - (BOOL) setMainNibWithFileAtPath: (NSString *)path { NSString *nibName = [path lastPathComponent]; [self setIconViewImage: [[NSWorkspace sharedWorkspace] iconForFile: path]]; [self addAndCopyFiles: [NSArray arrayWithObject: path] forKey: PCInterfaces]; [infoDict setObject: nibName forKey: @"NSMainNibFile"]; [self setProjectDictObject: nibName forKey: PCMainInterfaceFile notify: YES]; [mainNIBField setStringValue: nibName]; return YES; } - (void) clearMainNib: (id)sender { [mainNIBField setStringValue: @""]; [infoDict setObject: @"" forKey: @"NSMainNibFile"]; [self setProjectDictObject: @"" forKey: PCMainInterfaceFile notify: YES]; } // Document Types - (void) showDocTypesPanel: (id)sender { [docTypesPanel makeKeyAndOrderFront: nil]; } - (void) setDocBasedApp: (id)sender { NSString *docBased = [projectDict objectForKey: PCDocumentBasedApp]; if ([docBasedAppButton state] == NSOnState) { [docTypeLabel setTextColor: [NSColor blackColor]]; [docTypeField setBackgroundColor: [NSColor whiteColor]]; [docTypeField setTextColor: [NSColor blackColor]]; [docTypeField setEditable: YES]; [docNameLabel setTextColor: [NSColor blackColor]]; [docNameField setBackgroundColor: [NSColor whiteColor]]; [docNameField setTextColor: [NSColor blackColor]]; [docNameField setEditable: YES]; [docRoleLabel setTextColor: [NSColor blackColor]]; [docRoleField setBackgroundColor: [NSColor whiteColor]]; [docRoleField setTextColor: [NSColor blackColor]]; [docRoleField setEditable: YES]; [docClassLabel setTextColor: [NSColor blackColor]]; [docClassField setBackgroundColor: [NSColor whiteColor]]; [docClassField setTextColor: [NSColor blackColor]]; [docClassField setEditable: YES]; [nameColumn setIdentifier: @"NSHumanReadableName"]; [[nameColumn headerCell] setStringValue: @"Name"]; [docTypesList addTableColumn: roleColumn]; [docTypesList addTableColumn: classColumn]; RELEASE(roleColumn); RELEASE(classColumn); if (![docBased isEqualToString: @"YES"]) { [self setProjectDictObject: @"YES" forKey: PCDocumentBasedApp notify: YES]; } } else { [docTypeLabel setTextColor: [NSColor darkGrayColor]]; [docTypeField setBackgroundColor: [NSColor lightGrayColor]]; [docTypeField setTextColor: [NSColor darkGrayColor]]; [docTypeField setEditable: NO]; [docNameLabel setTextColor: [NSColor darkGrayColor]]; [docNameField setBackgroundColor: [NSColor lightGrayColor]]; [docNameField setTextColor: [NSColor darkGrayColor]]; [docNameField setEditable: NO]; [docRoleLabel setTextColor: [NSColor darkGrayColor]]; [docRoleField setBackgroundColor: [NSColor lightGrayColor]]; [docRoleField setTextColor: [NSColor darkGrayColor]]; [docRoleField setEditable: NO]; [docClassLabel setTextColor: [NSColor darkGrayColor]]; [docClassField setBackgroundColor: [NSColor lightGrayColor]]; [docClassField setTextColor: [NSColor darkGrayColor]]; [docClassField setEditable: NO]; // Columns // [docTypesList removeTableColumn: nameColumn]; [nameColumn setIdentifier: @"NSIcon"]; [[nameColumn headerCell] setStringValue: @"Icon"]; RETAIN(roleColumn); RETAIN(classColumn); [docTypesList removeTableColumn: roleColumn]; [docTypesList removeTableColumn: classColumn]; if (![docBased isEqualToString: @"NO"]) { [self setProjectDictObject: @"NO" forKey: PCDocumentBasedApp notify: YES]; } } } - (void) addDocType: (id)sender { int row; NSMutableDictionary *entry = [NSMutableDictionary dictionaryWithCapacity: 6]; int selectedRow = [docTypesList selectedRow]; [entry setObject: @"" forKey: @"NSName"]; [entry setObject: @"" forKey: @"NSHumanReadableName"]; [entry setObject: [NSArray array] forKey: @"NSUnixExtensions"]; [entry setObject: @"" forKey: @"NSIcon"]; [entry setObject: @"" forKey: @"NSRole"]; [entry setObject: @"NSDocumentClass" forKey: @"NSDocumentClass"]; if (selectedRow >= 0 && [docTypesItems count] > 0) { [docTypesItems insertObject: entry atIndex: selectedRow + 1]; row = selectedRow + 1; } else { [docTypesItems addObject: entry]; row = [docTypesItems count] - 1; } [docTypesList reloadData]; [docTypesList selectRow: row byExtendingSelection: NO]; [docTypesList scrollRowToVisible: row]; [self fillFieldsForRow: row]; [self setProjectDictObject: docTypesItems forKey: PCDocumentTypes notify: YES]; } - (void) removeDocType: (id)sender { int selectedRow = [docTypesList selectedRow]; if (selectedRow >= 0) { [docTypesItems removeObjectAtIndex: selectedRow]; [docTypesList reloadData]; } if (([docTypesList selectedRow] < 0) && ([docTypesItems count] > 0)) { [docTypesList selectRow: [docTypesItems count]-1 byExtendingSelection: NO]; } [self fillFieldsForRow: [docTypesList selectedRow]]; [self setProjectDictObject: docTypesItems forKey: PCDocumentTypes notify: YES]; } - (void) docFieldSet: (id)sender { NSMutableDictionary *object = nil; NSLog(@"docFieldSet"); if (sender != docTypeField && sender != docNameField && sender != docIconField && sender != docExtensionsField && sender != docRoleField && sender != docClassField) { return; } if ([docTypesItems count] <= 0) { [self addDocType: addDocTypeButton]; } object = [[docTypesItems objectAtIndex: [docTypesList selectedRow]] mutableCopy]; if (sender == docTypeField) { [object setObject: [sender stringValue] forKey: @"NSName"]; } else if (sender == docNameField) { [object setObject: [sender stringValue] forKey: @"NSHumanReadableName"]; } else if (sender == docIconField) { [object setObject: [sender stringValue] forKey: @"NSIcon"]; } else if (sender == docExtensionsField) { [object setObject: [[sender stringValue] componentsSeparatedByString: @","] forKey: @"NSUnixExtensions"]; } else if (sender == docRoleField) { [object setObject: [sender stringValue] forKey: @"NSRole"]; } else if (sender == docClassField) { [object setObject: [sender stringValue] forKey: @"NSDocumentClass"]; } [docTypesItems replaceObjectAtIndex: [docTypesList selectedRow] withObject: object]; [docTypesList reloadData]; [object release]; } // ---------------------------------------------------------------------------- // --- Document Types browser // ---------------------------------------------------------------------------- - (int) numberOfRowsInTableView: (NSTableView *)aTableView { return [docTypesItems count]; } - (id) tableView: (NSTableView *)aTableView objectValueForTableColumn: (NSTableColumn *)aTableColumn row: (int)rowIndex { NSDictionary *object = nil; if (docTypesItems != nil || [docTypesItems count] > 0) { object = [docTypesItems objectAtIndex: rowIndex]; if (aTableColumn == extensionsColumn) { return [[object objectForKey: @"NSUnixExtensions"] componentsJoinedByString: @","]; } else { return [object objectForKey: [aTableColumn identifier]]; } } return nil; } - (void) tableView: (NSTableView *)aTableView setObjectValue: anObject forTableColumn: (NSTableColumn *)aTableColumn row: (int)rowIndex { NSMutableDictionary *type = nil; if (docTypesItems == nil || [docTypesItems count] <= 0) { return; } type = [docTypesItems objectAtIndex: rowIndex]; if ([[aTableColumn identifier] isEqualToString: @"NSUnixExtensions"]) { [type removeObjectForKey: @"Extension"]; [type setObject: anObject forKey: @"Extension"]; } else if ([[aTableColumn identifier] isEqualToString: @"NSIcon"]) { [type removeObjectForKey: @"Icon"]; [type setObject: anObject forKey: @"Icon"]; } [self setProjectDictObject: docTypesItems forKey: PCDocumentTypes notify: YES]; } - (BOOL) tableView: (NSTableView *)aTableView shouldSelectRow: (int)rowIndex { [self fillFieldsForRow: rowIndex]; return YES; } - (void) fillFieldsForRow: (int)rowIndex { NSDictionary *type = nil; int itemCount = [docTypesItems count]; if (itemCount <= 0 || rowIndex > itemCount || rowIndex < 0) { [docTypeField setStringValue: @""]; [docNameField setStringValue: @""]; [docIconField setStringValue: @""]; [docExtensionsField setStringValue: @""]; [docRoleField setStringValue: @""]; [docClassField setStringValue: @""]; return; } type = [docTypesItems objectAtIndex: rowIndex]; [docTypeField setStringValue: [type objectForKey: @"NSName"]]; [docNameField setStringValue: [type objectForKey: @"NSHumanReadableName"]]; [docIconField setStringValue: [type objectForKey: @"NSIcon"]]; [docExtensionsField setStringValue: @""]; if ([[type objectForKey: @"NSUnixExtensions"] count] > 0) { [docExtensionsField setStringValue: [[type objectForKey: @"NSUnixExtensions"] componentsJoinedByString: @","]]; } [docRoleField setStringValue: [type objectForKey: @"NSRole"]]; [docClassField setStringValue: [type objectForKey: @"NSDocumentClass"]]; } // ---------------------------------------------------------------------------- // --- Notifications // ---------------------------------------------------------------------------- - (void) updateInspectorValues: (NSNotification *)aNotif { // NSLog (@"PCAppProject: updateInspectorValues"); // Project Attributes view [projectTypeField setStringValue: [projectDict objectForKey: PCProjectType]]; [projectNameField setStringValue: [projectDict objectForKey: PCProjectName]]; // [projectLanguageField setStringValue: [projectDict objectForKey: PCLanguage]]; [appClassField setStringValue: [projectDict objectForKey: PCPrincipalClass]]; [appImageField setStringValue: [projectDict objectForKey: PCAppIcon]]; [helpFileField setStringValue: [projectDict objectForKey: PCHelpFile]]; [mainNIBField setStringValue: [projectDict objectForKey: PCMainInterfaceFile]]; docTypesItems = [projectDict objectForKey: PCDocumentTypes]; [docTypesList reloadData]; } // TextFields (PCITextField subclass) // // NSTextField become first responder when user clicks on it and immediately // lost first responder status, so we can't catch when focus leaves textfield // with resignFirstResponder: method overriding. Here we're using // controlTextDidEndEditing (NSTextField's delegate method) to achieve this. - (void) tfGetFocus: (NSNotification *)aNotif { id anObject = [aNotif object]; NSString *file = nil; NSString *path = nil; if (anObject != appImageField && anObject != helpFileField && anObject != mainNIBField) { // NSLog(@"tfGetFocus: not that textfield"); return; } if (anObject == appImageField) { file = [appImageField stringValue]; if (![file isEqualToString: @""]) { path = [self dirForCategoryKey: PCImages]; path = [path stringByAppendingPathComponent: file]; [self setIconViewImage: [[NSImage alloc] initWithContentsOfFile: path]]; } activeTextField = appImageField; } else if (anObject == helpFileField) { activeTextField = helpFileField; } else if (anObject == mainNIBField) { file = [mainNIBField stringValue]; if (![file isEqualToString: @""]) { path = [projectPath stringByAppendingPathComponent: file]; [self setIconViewImage: [[NSWorkspace sharedWorkspace] iconForFile: path]]; } activeTextField = mainNIBField; } [setFieldButton setEnabled: YES]; [clearFieldButton setEnabled: YES]; } - (void) controlTextDidEndEditing: (NSNotification *)aNotification { NSControl *anObject = [aNotification object]; id target = [anObject target]; SEL action = [anObject action]; if (anObject == appImageField || anObject == helpFileField || anObject == mainNIBField) { activeTextField = nil; [self setIconViewImage: nil]; [setFieldButton setEnabled: NO]; [clearFieldButton setEnabled: NO]; return; } if ([target respondsToSelector: action]) { [target performSelector: action withObject: anObject]; } } @end