// Controller.m - Charmap application delegate implementation // Copyright (C) 2003,2004 Christopher Culver // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef _CONTROLLER_H #include "Controller.h" #endif @implementation Controller : NSObject - (void) dealloc { RELEASE(charDecimalInfo); RELEASE(charHexInfo); RELEASE(charOctalInfo); RELEASE(charUTF8Info); RELEASE(charmapCell); RELEASE(charmapMatrix); RELEASE(charmapScroll); RELEASE(largeDict); RELEASE(cellDict); RELEASE(display); RELEASE(inspectorChar); RELEASE(inspectorPanel); RELEASE(unicodeData); [super dealloc]; } - (id) init { unicodeData = [[UnicodeData alloc] init]; inspectorOpen = NO; return self; } - (void) awakeFromNib { short int i; NSMutableParagraphStyle * paragraphStyle = [NSMutableParagraphStyle defaultParagraphStyle]; [paragraphStyle setAlignment: NSCenterTextAlignment]; ASSIGN(cellDict, ([NSMutableDictionary dictionaryWithObjectsAndKeys: [NSFont systemFontOfSize: 14], NSFontAttributeName, [NSColor blackColor], NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil])); ASSIGN(largeDict, ([NSMutableDictionary dictionaryWithObjectsAndKeys: [NSFont systemFontOfSize: 48], NSFontAttributeName, [NSColor blueColor], NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil])); /* Set some main window graphical properties. */ [blocksBrowser setMinColumnWidth: 250]; [blocksBrowser setAction: @selector (generateCharmap)]; [blocksBrowser setTarget: self]; charmapCell = [[NSTextFieldCell alloc] init]; [charmapCell setAllowsEditingTextAttributes: YES]; [charmapCell setEditable: NO]; [charmapCell setSelectable: NO]; [charmapCell setBordered: NO]; [charmapMatrix setAction: @selector (updateInspector:)]; [charmapMatrix setAllowsEmptySelection: NO]; [charmapMatrix setAutoscroll: YES]; [charmapMatrix setCellSize: NSMakeSize (30, 35)]; [charmapMatrix setAllowsEmptySelection: NO]; [charmapMatrix setDoubleAction: @selector (putSelected:)]; [charmapMatrix setMode: NSRadioModeMatrix]; [charmapMatrix setPrototype: charmapCell]; [charmapMatrix setSelectionByRect: NO]; for (i = 0; i < 10; i++) [charmapMatrix addColumn]; [copyButton setEnabled: NO]; [display setFont: [cellDict objectForKey: NSFontAttributeName]]; /* Set some inspector graphical properties. */ inspectorOpen = NO; [inspectorChar setAlignment: NSLeftTextAlignment]; [inspectorChar setDrawsBackground: NO]; [inspectorChar setEditable: NO]; [inspectorChar setRichText: YES]; [inspectorChar setSelectable: NO]; [inspectorChar setUsesFontPanel: NO]; [charDecompInfo setDrawsBackground: NO]; [charDecompInfo setEditable: NO]; [charDecompInfo setSelectable: NO]; [[charDecompInfo textContainer] setContainerSize: NSMakeSize([charNameInfo frame].size.width, 75)]; [[charDecompInfo textContainer] setWidthTracksTextView: YES]; [[charDecompInfo textStorage] setAttributedString: [[NSAttributedString alloc] initWithString: @"No character selected"]]; [charNameInfo setDrawsBackground: NO]; [charNameInfo setEditable: NO]; [charNameInfo setSelectable: NO]; [[charNameInfo textContainer] setContainerSize: NSMakeSize([charNameInfo frame].size.width, 50)]; [[charNameInfo textContainer] setWidthTracksTextView: YES]; [[charNameInfo textStorage] setAttributedString: [[NSAttributedString alloc] initWithString: @"No character selected"]]; [charAliasInfo setDrawsBackground: NO]; [charAliasInfo setEditable: NO]; [charAliasInfo setSelectable: NO]; [[charAliasInfo textContainer] setContainerSize: NSMakeSize([charAliasInfo frame].size.width, 50)]; [[charAliasInfo textContainer] setWidthTracksTextView: YES]; [self generateCharmap]; } - (void) generateCharmap { NSString *tempString = nil; NSTextFieldCell *tempCell; unichar aChar; int i, j, k, block, blockSize; unsigned int blockStart, blockEnd; /* Remove all rows */ for (i = [charmapMatrix numberOfRows]; i >= 0; i--) { if ([charmapMatrix cellAtRow: i column: 0]) [charmapMatrix removeRow: i]; } /* Add the necessary rows */ block = [blocksBrowser selectedRowInColumn: 0]; if (block == -1) block = 0; blockSize = [unicodeData getBlockSize: block]; blockStart = [unicodeData getBlockStart: block]; blockEnd = [unicodeData getBlockEnd: block]; for (i = 0; i < ((blockSize / [charmapMatrix numberOfColumns]) + 1); i++) [charmapMatrix insertRow: 0]; /* Fill the cells */ for (i = 0, k = blockStart; k < (blockEnd); i++) { for (j = 0; j < [charmapMatrix numberOfColumns]; j++, k++) { aChar = k; tempString = [[NSString alloc] initWithCharacters: &aChar length: 1]; tempCell = [charmapMatrix cellAtRow: i column: j]; [charmapCell setAllowsEditingTextAttributes: YES]; [tempCell setDrawsBackground: YES]; [tempCell setTag: k]; [tempCell setAlignment: NSCenterTextAlignment]; [tempCell setAttributedStringValue: [[NSAttributedString alloc] initWithString: tempString attributes: cellDict]]; if ( [[unicodeData getName: k] isEqual: @""] == NO) [tempCell setBackgroundColor: [NSColor whiteColor]]; else // Gray out positions which are not assigned. { [tempCell setBackgroundColor: [NSColor darkGrayColor]]; [tempCell setAttributedStringValue: [[NSAttributedString alloc] initWithString: @"" attributes: cellDict]]; } RELEASE(tempString); } } /* Finish setting display. */ [charmapMatrix sizeToCells]; [charmapMatrix scrollCellToVisibleAtRow: 1 column: 1]; [charmapMatrix selectCellAtRow: 0 column: 0]; [charmapMatrix setNeedsDisplay: YES]; if (inspectorOpen == YES) [self updateInspector: self]; } - (void)controlTextDidChange:(NSNotification *)aNotification { if ([[display stringValue] length] != 0) [copyButton setEnabled: YES]; else [copyButton setEnabled: NO]; } - (void) putSelected: (id) sender { NSMutableString *selectedString; int charTag; charTag = [[charmapMatrix selectedCell] tag]; selectedString = [[NSMutableString alloc] init]; [selectedString appendString: [display stringValue]]; [selectedString appendString: [[charmapMatrix selectedCell] stringValue]]; [display setStringValue: selectedString]; [self controlTextDidChange: (NSNotification *) NSControlTextDidChangeNotification]; } - (void) copySelected: (id) sender { NSPasteboard *pb = [NSPasteboard generalPasteboard]; [display selectText: self]; [pb declareTypes: [NSArray arrayWithObject: NSStringPboardType] owner: self]; if ([[display stringValue] length] != 0) { [pb setString: [display stringValue] forType: NSStringPboardType]; NSLog (_(@"Text copied.")); } else NSLog (_(@"No text selected.")); } - (void) updateInspector: (id) sender { NSAttributedString *charAliasAttrString = nil; NSAttributedString *charNameAttrString = nil; NSDictionary *charDict; NSMutableString *charDecompString = nil; NSMutableString *tempString; NSString *character; NSString *charCategoryString = nil; NSString *name = nil; const unsigned char * cs; unichar charTag; charTag = [[charmapMatrix selectedCell] tag]; character = [[NSString alloc] initWithCharacters: &charTag length: 1]; charDict = [[NSDictionary alloc] initWithDictionary: [unicodeData dictionaryForCharacter: charTag]]; if (![charDict objectForKey: @"Name"]) name = [unicodeData getName: charTag]; else name = [charDict objectForKey: @"Name"]; [[inspectorChar textStorage] setAttributedString: nil]; [[charAliasInfo textStorage] setAttributedString: nil]; if ([name isEqual: @""] == NO) { /* Show character "magnified". */ [[inspectorChar textStorage] setAttributedString: [[NSAttributedString alloc] initWithString: character attributes: largeDict]]; /* Show name. */ charNameAttrString = [[NSAttributedString alloc] initWithString: name]; [[charNameInfo textStorage] setAttributedString: charNameAttrString]; /* Show alias. */ if ([charDict objectForKey: @"Unicode1.0Name"]) { charAliasAttrString = [[NSAttributedString alloc] initWithString: [charDict objectForKey: @"Unicode1.0Name"]]; [[charAliasInfo textStorage] setAttributedString: charAliasAttrString]; } } else { // If position not assigned, don't show a character. [[inspectorChar textStorage] setAttributedString: nil]; charNameAttrString = [[NSAttributedString alloc] initWithString: name]; [[charNameInfo textStorage] setAttributedString: charNameAttrString]; [[charAliasInfo textStorage] setAttributedString: nil]; } /* Show general Unicode category. */ if ([charDict objectForKey: @"GeneralCategory"]) { charCategoryString = [[NSString alloc] initWithString: [charDict objectForKey: @"GeneralCategory"]]; [charCategoryInfo setStringValue: [unicodeData getFullCategoryName: charCategoryString]]; } else [charCategoryInfo setStringValue: nil]; /* Show canonical decomposition. */ [[charDecompInfo textStorage] setAttributedString: nil]; if ([ [charDict objectForKey: @"Decomposition"] length] > 0) { charDecompString = [[NSString alloc] initWithString: [unicodeData getFullDecomposition: charTag]]; [[charDecompInfo textStorage] setAttributedString: [[NSAttributedString alloc] initWithString: charDecompString]]; } /* Set various representations. */ [charDecimalInfo setStringValue: [NSString stringWithFormat: @"&#%d;", charTag]]; [charHexInfo setStringValue: [NSString stringWithFormat: @"U+%004X", charTag]]; tempString = [[NSMutableString alloc] init]; for (cs = [character UTF8String]; *cs != '\0'; cs++) [tempString appendString: [NSString stringWithFormat: @"0x%02X ", *cs]]; [charUTF8Info setStringValue: tempString]; RELEASE(tempString); tempString = [[NSMutableString alloc] init]; for (cs = [character UTF8String]; *cs != '\0'; cs++) [tempString appendString: [NSString stringWithFormat: @"\\%02o", *cs]]; [charOctalInfo setStringValue: tempString]; RELEASE(character); RELEASE(charAliasAttrString); RELEASE(charCategoryString); RELEASE(charDecompString); RELEASE(charNameAttrString); RELEASE(name); RELEASE(tempString); } - (id) showInspector: (id)sender { [self updateInspector: self]; [inspectorPanel center]; [inspectorPanel orderFront: self]; inspectorOpen = YES; return self; } - (void) changeFont: (id)fontManager { NSFont *newCellFont; NSFont *newLargeFont; /* Create new fonts */ newCellFont = [fontManager convertFont: [cellDict objectForKey: NSFontAttributeName]]; [cellDict setObject: newCellFont forKey: NSFontAttributeName]; newLargeFont = [fontManager convertFont: [largeDict objectForKey: NSFontAttributeName]]; [largeDict setObject: [fontManager convertFont: newLargeFont toSize: 48] forKey: NSFontAttributeName]; /* Update display */ [display setFont: newCellFont]; [display setNeedsDisplay: YES]; [self generateCharmap]; if (inspectorOpen == YES) { [self updateInspector: self]; [inspectorChar setNeedsDisplay: YES]; } } - (void) windowWillClose: (NSNotification *) theNotification { inspectorOpen = NO; } - (void) browser: (NSBrowser *)sender createRowsForColumn: (int)column inMatrix: (NSMatrix *)matrix { short int i; int count; NSBrowserCell *cell; NSString *category; blockNames = [unicodeData getBlockNames]; count = [blockNames count]; if (count) { [matrix addColumn]; for (i = 0; i < count; i++) { if (i > 0) [matrix addRow]; category = [blockNames objectAtIndex: i]; cell = [matrix cellAtRow: i column: 0]; [cell setStringValue: category]; [cell setLeaf: YES]; } } } @end