diff --git a/CoreDataUtil.xcodeproj/project.pbxproj b/CoreDataUtil.xcodeproj/project.pbxproj index 7e8549b..5eec773 100644 --- a/CoreDataUtil.xcodeproj/project.pbxproj +++ b/CoreDataUtil.xcodeproj/project.pbxproj @@ -21,7 +21,6 @@ 830D04EE1598CC4D003874CA /* MFLMainWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 830D04EC1598CC4D003874CA /* MFLMainWindowController.xib */; }; 832C9696159BD69E00AC8FA8 /* CoreData.ext in Resources */ = {isa = PBXBuildFile; fileRef = 832C9695159BD69E00AC8FA8 /* CoreData.ext */; }; 832C969B159BDBB000AC8FA8 /* MFLCoreDataEditorProjectLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 832C969A159BDBB000AC8FA8 /* MFLCoreDataEditorProjectLoader.m */; }; - 833DF7F31593556000793430 /* MFLButtonTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 833DF7F21593556000793430 /* MFLButtonTableViewCell.m */; }; 833DF7FB1593718600793430 /* MFLTextTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 833DF7FA1593718600793430 /* MFLTextTableCellView.m */; }; 833DF7FE1593836600793430 /* MFLEntityTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 833DF7FD1593836600793430 /* MFLEntityTableCellView.m */; }; 833FF6FD187860F1003ADCEA /* MFLConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 833FF6FC187860F1003ADCEA /* MFLConstants.m */; }; @@ -29,13 +28,11 @@ 8359411F159217770045B287 /* refreshButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 8359411E159217770045B287 /* refreshButton.png */; }; 835941221592351D0045B287 /* MFLCoreDataCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 835941211592351D0045B287 /* MFLCoreDataCommon.m */; }; 83656E6619378FB7003D0E74 /* CoreDataUtilityStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 83656E6519378FB7003D0E74 /* CoreDataUtilityStyle.m */; }; - 83656E6919379D0C003D0E74 /* TransformableDataTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 83656E6819379D0C003D0E74 /* TransformableDataTableViewCell.m */; }; 83656E6E1937A73B003D0E74 /* ObjectInfoController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83656E6C1937A73B003D0E74 /* ObjectInfoController.m */; }; 83656E6F1937A73B003D0E74 /* ObjectInfoController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 83656E6D1937A73B003D0E74 /* ObjectInfoController.xib */; }; 837C067B1A0E646600F4D5D4 /* MFLBuild.m in Sources */ = {isa = PBXBuildFile; fileRef = 837C067A1A0E646600F4D5D4 /* MFLBuild.m */; }; 838055C915A3A67200D050E7 /* ApplicationIcon-CDP.icns in Resources */ = {isa = PBXBuildFile; fileRef = 838055C715A3A67200D050E7 /* ApplicationIcon-CDP.icns */; }; 838055CA15A3A67200D050E7 /* ApplicationIcon-MOM.icns in Resources */ = {isa = PBXBuildFile; fileRef = 838055C815A3A67200D050E7 /* ApplicationIcon-MOM.icns */; }; - 83922D381598F264004C273C /* MFLCellBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 83922D371598F264004C273C /* MFLCellBuilder.m */; }; 83AE7D3019FF1AB400DD152B /* SimulatorItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 83AE7D2F19FF1AB400DD152B /* SimulatorItem.m */; }; 83AE7D3219FF1CE900DD152B /* simulatorIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 83AE7D3119FF1CE900DD152B /* simulatorIcon.png */; }; 83B158FD158F6AE2002B46C2 /* MFLCoreDataIntrospection.m in Sources */ = {isa = PBXBuildFile; fileRef = 83B158FC158F6AE2002B46C2 /* MFLCoreDataIntrospection.m */; }; @@ -119,8 +116,6 @@ 832C9695159BD69E00AC8FA8 /* CoreData.ext */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = CoreData.ext; sourceTree = ""; }; 832C9699159BDBB000AC8FA8 /* MFLCoreDataEditorProjectLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLCoreDataEditorProjectLoader.h; sourceTree = ""; }; 832C969A159BDBB000AC8FA8 /* MFLCoreDataEditorProjectLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLCoreDataEditorProjectLoader.m; sourceTree = ""; }; - 833DF7F11593556000793430 /* MFLButtonTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLButtonTableViewCell.h; sourceTree = ""; }; - 833DF7F21593556000793430 /* MFLButtonTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLButtonTableViewCell.m; sourceTree = ""; }; 833DF7F91593718600793430 /* MFLTextTableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLTextTableCellView.h; sourceTree = ""; }; 833DF7FA1593718600793430 /* MFLTextTableCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLTextTableCellView.m; sourceTree = ""; }; 833DF7FC1593836600793430 /* MFLEntityTableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLEntityTableCellView.h; sourceTree = ""; }; @@ -133,8 +128,6 @@ 835941211592351D0045B287 /* MFLCoreDataCommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLCoreDataCommon.m; sourceTree = ""; }; 83656E6419378FB7003D0E74 /* CoreDataUtilityStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreDataUtilityStyle.h; sourceTree = ""; }; 83656E6519378FB7003D0E74 /* CoreDataUtilityStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreDataUtilityStyle.m; sourceTree = ""; }; - 83656E6719379D0C003D0E74 /* TransformableDataTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformableDataTableViewCell.h; sourceTree = ""; }; - 83656E6819379D0C003D0E74 /* TransformableDataTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TransformableDataTableViewCell.m; sourceTree = ""; }; 83656E6B1937A73B003D0E74 /* ObjectInfoController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectInfoController.h; sourceTree = ""; }; 83656E6C1937A73B003D0E74 /* ObjectInfoController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjectInfoController.m; sourceTree = ""; }; 83656E6D1937A73B003D0E74 /* ObjectInfoController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ObjectInfoController.xib; sourceTree = ""; }; @@ -142,8 +135,6 @@ 837C067A1A0E646600F4D5D4 /* MFLBuild.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLBuild.m; sourceTree = ""; }; 838055C715A3A67200D050E7 /* ApplicationIcon-CDP.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "ApplicationIcon-CDP.icns"; sourceTree = ""; }; 838055C815A3A67200D050E7 /* ApplicationIcon-MOM.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "ApplicationIcon-MOM.icns"; sourceTree = ""; }; - 83922D361598F264004C273C /* MFLCellBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLCellBuilder.h; sourceTree = ""; }; - 83922D371598F264004C273C /* MFLCellBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLCellBuilder.m; sourceTree = ""; }; 83AE7D2E19FF1AB400DD152B /* SimulatorItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimulatorItem.h; sourceTree = ""; }; 83AE7D2F19FF1AB400DD152B /* SimulatorItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimulatorItem.m; sourceTree = ""; }; 83AE7D3119FF1CE900DD152B /* simulatorIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = simulatorIcon.png; sourceTree = ""; }; @@ -282,16 +273,10 @@ children = ( 5B330A6E1590CB1E00D79D4D /* EntityDataTableViewCell.h */, 5B330A6F1590CB1E00D79D4D /* EntityDataTableViewCell.m */, - 833DF7F11593556000793430 /* MFLButtonTableViewCell.h */, - 833DF7F21593556000793430 /* MFLButtonTableViewCell.m */, - 83922D361598F264004C273C /* MFLCellBuilder.h */, - 83922D371598F264004C273C /* MFLCellBuilder.m */, 833DF7FC1593836600793430 /* MFLEntityTableCellView.h */, 833DF7FD1593836600793430 /* MFLEntityTableCellView.m */, 833DF7F91593718600793430 /* MFLTextTableCellView.h */, 833DF7FA1593718600793430 /* MFLTextTableCellView.m */, - 83656E6719379D0C003D0E74 /* TransformableDataTableViewCell.h */, - 83656E6819379D0C003D0E74 /* TransformableDataTableViewCell.m */, ); name = TableViewCells; sourceTree = ""; @@ -634,7 +619,6 @@ buildActionMask = 2147483647; files = ( C1CEFE621463779D00466EB3 /* main.m in Sources */, - 83656E6919379D0C003D0E74 /* TransformableDataTableViewCell.m in Sources */, 83656E6619378FB7003D0E74 /* CoreDataUtilityStyle.m in Sources */, C1CEFE691463779D00466EB3 /* MFLAppDelegate.m in Sources */, 837C067B1A0E646600F4D5D4 /* MFLBuild.m in Sources */, @@ -647,12 +631,10 @@ 83B158FD158F6AE2002B46C2 /* MFLCoreDataIntrospection.m in Sources */, 5B330A701590CB1E00D79D4D /* EntityDataTableViewCell.m in Sources */, 835941221592351D0045B287 /* MFLCoreDataCommon.m in Sources */, - 833DF7F31593556000793430 /* MFLButtonTableViewCell.m in Sources */, 833DF7FB1593718600793430 /* MFLTextTableCellView.m in Sources */, 83656E6E1937A73B003D0E74 /* ObjectInfoController.m in Sources */, 833DF7FE1593836600793430 /* MFLEntityTableCellView.m in Sources */, 830D04ED1598CC4D003874CA /* MFLMainWindowController.m in Sources */, - 83922D381598F264004C273C /* MFLCellBuilder.m in Sources */, 832C969B159BDBB000AC8FA8 /* MFLCoreDataEditorProjectLoader.m in Sources */, 5B2BA5C4159C9FEB00AFEC9D /* CoreDataHistoryObject.m in Sources */, 833FF6FD187860F1003ADCEA /* MFLConstants.m in Sources */, diff --git a/CoreDataUtil/EntityDataTableView.m b/CoreDataUtil/EntityDataTableView.m index 6bbc450..efbe9d9 100644 --- a/CoreDataUtil/EntityDataTableView.m +++ b/CoreDataUtil/EntityDataTableView.m @@ -164,11 +164,11 @@ - (IBAction) copyFormatted:(id)sender - (IBAction) copyCell:(id)sender { MFLTextTableCellView *cell = [self viewAtColumn:rightClickedCol row:rightClickedRow makeIfNecessary:NO]; - NSLog(@"copyCell: r:%d, c:%d, %@", (int)rightClickedRow, (int)rightClickedCol, cell.infoField.stringValue); + NSLog(@"copyCell: r:%d, c:%d, %@", (int)rightClickedRow, (int)rightClickedCol, cell.text); NSPasteboard *pb = [NSPasteboard generalPasteboard]; [pb declareTypes:@[NSStringPboardType] owner:nil]; - [pb setString:cell.infoField.stringValue forType:NSStringPboardType]; + [pb setString:cell.text forType:NSStringPboardType]; } @end diff --git a/CoreDataUtil/MFLButtonTableViewCell.h b/CoreDataUtil/MFLButtonTableViewCell.h deleted file mode 100644 index 433ccd8..0000000 --- a/CoreDataUtil/MFLButtonTableViewCell.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// MFLButtonTableViewCell.h -// CoreDataUtil -// -// Created by Chris Wilson on 6/21/12. -// Copyright (c) 2012 mFluent LLC. All rights reserved. -// - -#import - -@interface MFLButtonTableViewCell : NSTableCellView - -@property (strong) IBOutlet NSTextField* infoField; -@property (strong) IBOutlet NSButton* cellButton; - -@end diff --git a/CoreDataUtil/MFLButtonTableViewCell.m b/CoreDataUtil/MFLButtonTableViewCell.m deleted file mode 100644 index 2472f75..0000000 --- a/CoreDataUtil/MFLButtonTableViewCell.m +++ /dev/null @@ -1,35 +0,0 @@ -// -// MFLButtonTableViewCell.m -// CoreDataUtil -// -// Created by Chris Wilson on 6/21/12. -// Copyright (c) 2012 mFluent LLC. All rights reserved. -// - -#import "MFLButtonTableViewCell.h" - -@interface MFLButtonTableViewCell () - - - -@end - - -@implementation MFLButtonTableViewCell - -- (id)initWithFrame:(NSRect)frame -{ - self = [super initWithFrame:frame]; - if (self) { - - } - - return self; -} - -- (void)drawRect:(NSRect)dirtyRect -{ - // Drawing code here. -} - -@end diff --git a/CoreDataUtil/MFLCellBuilder.h b/CoreDataUtil/MFLCellBuilder.h deleted file mode 100644 index 8605472..0000000 --- a/CoreDataUtil/MFLCellBuilder.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// MFLCellBuilder.h -// CoreDataUtil -// -// Created by Chris Wilson on 6/25/12. -// Copyright (c) 2012 mFluent LLC. All rights reserved. -// - -#import - -@class MFLTextTableCellView; -@class MFLButtonTableViewCell; -@class TransformableDataTableViewCell; - -@interface MFLCellBuilder : NSObject - -+ (MFLTextTableCellView* ) textCellWithString:(NSTableView *)tableView textToSet:(NSString*) textToSet owner:(id) owner; -+ (MFLTextTableCellView* ) numberCellWithString:(NSTableView *)tableView textToSet: (NSString*) textToSet owner:(id) owner; -+ (MFLTextTableCellView* ) nullCell:(NSTableView *)tableView owner:(id) owner; -+ (MFLButtonTableViewCell* ) objectCellWithString:(NSTableView *)tableView textToSet:(NSString*) textToSet owner:(id) owner; -+ (TransformableDataTableViewCell*) tranformableCellWithSTring:(NSTableView *)tableView textToSet:(NSString*) textToSet owner:(id) owner; - -@end diff --git a/CoreDataUtil/MFLCellBuilder.m b/CoreDataUtil/MFLCellBuilder.m deleted file mode 100644 index 8cd459a..0000000 --- a/CoreDataUtil/MFLCellBuilder.m +++ /dev/null @@ -1,75 +0,0 @@ -// -// MFLCellBuilder.m -// CoreDataUtil -// -// Created by Chris Wilson on 6/25/12. -// Copyright (c) 2012 mFluent LLC. All rights reserved. -// - -#import "MFLCellBuilder.h" -#import "MFLConstants.h" -#import "MFLTextTableCellView.h" -#import "MFLButtonTableViewCell.h" -#import "TransformableDataTableViewCell.h" - -@implementation MFLCellBuilder - -#pragma mark - -#pragma mark Data Cell Helper - -+ (MFLTextTableCellView* ) textCellWithString:(NSTableView *)tableView textToSet:(NSString*) textToSet owner:(id) owner { - - MFLTextTableCellView* textCell = [tableView makeViewWithIdentifier:MFL_TEXT_CELL owner:owner]; - [[textCell infoField] setAlignment:NSLeftTextAlignment]; - [[textCell infoField] setTextColor:[NSColor blackColor]]; - [[textCell infoField] setStringValue:textToSet]; - [textCell setToolTip:textToSet]; - - return textCell; -} - -+ (MFLTextTableCellView* ) numberCellWithString:(NSTableView *)tableView textToSet:(NSString*) textToSet owner: (id) owner { - - MFLTextTableCellView* textCell = [tableView makeViewWithIdentifier:MFL_TEXT_CELL owner:owner]; - [[textCell infoField] setAlignment:NSRightTextAlignment]; - [[textCell infoField] setTextColor:[NSColor blackColor]]; - [[textCell infoField] setStringValue:textToSet]; - [textCell setToolTip:textToSet]; - - return textCell; -} - -+ (MFLTextTableCellView* ) nullCell:(NSTableView *)tableView owner: (id) owner { - - MFLTextTableCellView* textCell = [tableView makeViewWithIdentifier:MFL_TEXT_CELL owner:owner]; - [[textCell infoField] setAlignment:NSRightTextAlignment]; - [[textCell infoField] setTextColor:[NSColor lightGrayColor]]; - - [[textCell infoField] setStringValue:@"NULL"]; - - return textCell; -} - -+ (MFLButtonTableViewCell* ) objectCellWithString:(NSTableView *)tableView textToSet:(NSString*) textToSet owner:(id) owner { - - MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:owner]; - [[buttonCell infoField] setAlignment:NSRightTextAlignment]; - [[buttonCell infoField] setTextColor:[NSColor blackColor]]; - [[buttonCell infoField] setStringValue:textToSet]; - [buttonCell setToolTip:textToSet]; - - return buttonCell; -} - -+ (TransformableDataTableViewCell* ) tranformableCellWithSTring:(NSTableView *)tableView textToSet:(NSString*) textToSet owner:(id) owner { - - TransformableDataTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_TRANSFORM_CELL owner:owner]; - [[buttonCell infoField] setAlignment:NSRightTextAlignment]; - [[buttonCell infoField] setTextColor:[NSColor blackColor]]; - [[buttonCell infoField] setStringValue:textToSet]; - [buttonCell setToolTip:textToSet]; - - return buttonCell; -} - -@end diff --git a/CoreDataUtil/MFLMainWindowController.h b/CoreDataUtil/MFLMainWindowController.h index 6088f93..07afcf4 100644 --- a/CoreDataUtil/MFLMainWindowController.h +++ b/CoreDataUtil/MFLMainWindowController.h @@ -15,6 +15,14 @@ @class EntityTableView; @class EntityDataTableView; +typedef NS_ENUM(NSUInteger, EViewType) { + ViewTypeString = 0, + ViewTypeNumber, + ViewTypeDate, + ViewTypeLink, + ViewTypeTransformable, +}; + @interface MFLMainWindowController : NSWindowController @property (weak) IBOutlet EntityTableView *dataSourceList; diff --git a/CoreDataUtil/MFLMainWindowController.m b/CoreDataUtil/MFLMainWindowController.m index e07c64e..2311a30 100644 --- a/CoreDataUtil/MFLMainWindowController.m +++ b/CoreDataUtil/MFLMainWindowController.m @@ -12,15 +12,23 @@ #import "EntityDataTableView.h" #import "MFLTextTableCellView.h" #import "MFLEntityTableCellView.h" -#import "MFLButtonTableViewCell.h" -#import "TransformableDataTableViewCell.h" -#import "MFLCellBuilder.h" #import "OpenFileSheetController.h" #import "GetInfoSheetController.h" #import "FetchRequestInfoController.h" #import "ObjectInfoController.h" #import "MFLUtils.h" +// max length of text to display in cell +static const int MAX_TEXT_LENGTH = 255; + +@interface ViewData : NSObject +@property NSString *text; +@property EViewType viewType; +@end + +@implementation ViewData +@end + @interface OutlineViewNode : NSObject @property (strong) OutlineViewNode *parent; @property (strong) NSString *title; @@ -65,6 +73,9 @@ @interface MFLMainWindowController () @property (strong) OutlineViewNode *rootNode; @property NSDateFormatter *dateFormatter; +// map of row (NSNumber) to NSMutableDictionary (which is a map of column name to ViewData) +@property NSMutableDictionary *cachedRows; + @end @implementation MFLMainWindowController @@ -74,14 +85,11 @@ - (id)initWithWindow:(NSWindow *)window { self = [super initWithWindow:window]; if (self) { - self.sortType = Unsorted; } - return self; } - - (void) loadUserDefinedDateFormat { NSInteger dateStyleDefault = [[NSUserDefaults standardUserDefaults] integerForKey:DATE_STYLE_KEY_NAME]; if (dateStyleDefault == 0) { @@ -114,7 +122,6 @@ - (void) loadUserDefinedDateFormat { } } - - (void)windowDidLoad { [super windowDidLoad]; @@ -128,6 +135,8 @@ - (void)windowDidLoad [self.historySegmentedControl setEnabled:NO forSegment:1]; [self loadUserDefinedDateFormat]; + + self.cachedRows = [NSMutableDictionary new]; } #pragma mark - @@ -174,6 +183,9 @@ - (void) removeColumns { [self.entityContentTable removeTableColumn:[self.entityContentTable tableColumns][0]]; } + + // clear cache + [self.cachedRows removeAllObjects]; //NSLog(@"There are now %ld columns", [[self entityContentTable] numberOfColumns]); } @@ -252,6 +264,8 @@ - (void)onEntitySelected { NSTimeInterval startTime = [[NSDate date] timeIntervalSince1970]; [self.coreDataIntrospection clearEntityData]; [self.entityContentTable reloadData]; + + [self.entityContentTable beginUpdates]; [self removeColumns]; self.sortType = Unsorted; @@ -286,6 +300,8 @@ - (void)onEntitySelected { objectType:MFLObjectTypeFetchRequest]; } + [self.entityContentTable endUpdates]; + // allow main thread to return before calling reloadData again. user will see a faster table selection & an empty table view - then data will populate [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [self.entityContentTable reloadData]; @@ -322,7 +338,10 @@ - (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *) [self.coreDataIntrospection setDateStyle:self.dateStyle]; [self.coreDataIntrospection sortEntityData:[tableColumn identifier]]; } - + + // clear cache + [self.cachedRows removeAllObjects]; + [self.entityContentTable setIndicatorImage:[NSImage imageNamed:arrowImageName] inTableColumn:tableColumn]; [self.entityContentTable reloadData]; } @@ -376,215 +395,178 @@ - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row { } - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row -{ +{ if (tableView == [self dataSourceList]) { MFLEntityTableCellView* entityCell = [tableView makeViewWithIdentifier:MFL_ENTITY_CELL owner:self]; NSString* lblTxt = [self.coreDataIntrospection entityAtIndex:row]; - + [[entityCell label] setStringValue:lblTxt]; //[entityCell setDataCount:[NSString stringWithFormat:@"%ld", [self.coreDataIntrospection entityDataCountAtIndex:row]]]; [[entityCell countButton] setTitle: [NSString stringWithFormat:@"%ld", [self.coreDataIntrospection entityDataCountAtIndex:row]]]; //[[entityCell countButton] sizeToFit]; [[entityCell countButton] setEnabled:NO]; - return entityCell; } - else if (tableView == [self entityContentTable]) - { - id valueObj = [self getValueObjFromDataRows:tableView :row :tableColumn]; - if (valueObj == nil) - { - MFLTextTableCellView* textCell = [MFLCellBuilder nullCell:tableView owner:self]; - return textCell; - } - else if ([valueObj isKindOfClass:[NSString class]]) - { - NSString* cellText = [NSString stringWithFormat:@"%@", valueObj]; - if ([cellText hasPrefix:@"http"]) { - MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self]; - buttonCell.wantsLayer = YES; - [[buttonCell infoField] setTextColor:[NSColor blackColor]]; - [[buttonCell infoField] setStringValue: cellText]; - return buttonCell; - } - else { - MFLTextTableCellView* textCell = [MFLCellBuilder textCellWithString:tableView textToSet:cellText owner:self]; - return textCell; - } - } - else if ([valueObj isKindOfClass:[NSURL class]]) - { - NSURL* url = (NSURL*) valueObj; - NSString* cellText = [NSString stringWithFormat:@"%@", [url absoluteString]]; - MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self]; - buttonCell.wantsLayer = YES; - [[buttonCell infoField] setTextColor:[NSColor blackColor]]; - [[buttonCell infoField] setStringValue: cellText]; - return buttonCell; + + // -- entity table -- + + // check cache for view data + NSMutableDictionary *columnMap = self.cachedRows[@(row)]; + if (columnMap != nil) { + ViewData *viewData = columnMap[tableColumn.identifier]; + if (viewData != nil) { + return [self createCell:viewData.text withType:viewData.viewType]; } - else if ([valueObj isKindOfClass:[NSDate class]]) - { - [self setupDateFormatter]; - NSString *cellText = [self.dateFormatter stringFromDate:valueObj]; - MFLTextTableCellView* textCell = [MFLCellBuilder textCellWithString:tableView textToSet:cellText owner:self]; - return textCell; + } + + NSString *viewText = nil; + EViewType viewType = ViewTypeString; + + id valueObj = [self getValueObjFromDataRows:tableView :row :tableColumn]; + if (valueObj == nil) { + // do nothing.. + } + else if ([valueObj isKindOfClass:[NSString class]]) { + viewType = ViewTypeString; + viewText = valueObj; + if (viewText.length > MAX_TEXT_LENGTH) { + viewText = [viewText substringToIndex:MAX_TEXT_LENGTH]; } - else if ([valueObj isKindOfClass:[NSData class]]) - { - NSString* cellText = [NSString stringWithFormat:@"%ld", [valueObj length]]; - MFLTextTableCellView* textCell = [MFLCellBuilder numberCellWithString:tableView textToSet:cellText owner: self]; - textCell.wantsLayer = YES; - return textCell; + + if ([viewText hasPrefix:@"http"]) { + viewType = ViewTypeLink; } - else if ([valueObj isKindOfClass:[NSNumber class]]) - { - NSString* cellText; - NSNumber *number = valueObj; - // get 'type' of NSNumber to determine if this is a Boolean data type - if (strcmp(number.objCType, @encode(BOOL)) == 0) { - cellText = [NSString stringWithFormat:@"%@", number.boolValue ? @"YES" : @"NO"]; - } - else { - cellText = [NSString stringWithFormat:@"%@", valueObj]; - } - MFLTextTableCellView* textCell = [MFLCellBuilder numberCellWithString:tableView textToSet:cellText owner:self]; - textCell.wantsLayer = YES; - return textCell; + } + else if ([valueObj isKindOfClass:[NSNumber class]]) { + viewType = ViewTypeNumber; + NSNumber *number = valueObj; + // get 'type' of NSNumber to determine if this is a Boolean data type + if (strcmp(number.objCType, @encode(BOOL)) == 0) { + viewText = [NSString stringWithFormat:@"%@", number.boolValue ? @"YES" : @"NO"]; } - else if ([valueObj isKindOfClass:[NSManagedObject class]]) - { - NSString* cellText = [NSString stringWithFormat:@"%@", [[valueObj entity] name]]; - MFLButtonTableViewCell* buttonCell = [MFLCellBuilder objectCellWithString:tableView textToSet:cellText owner:self]; - buttonCell.wantsLayer = YES; - return buttonCell; + else { + viewText = [NSString stringWithFormat:@"%@", valueObj]; } - else if ([valueObj isKindOfClass:[NSSet class]]) - { - if ([valueObj count] > 0) - { - id obj = [valueObj anyObject]; - if ([obj isKindOfClass:[NSManagedObject class]]) { - NSManagedObject* object = obj; - NSString *cellText = [NSString stringWithFormat:@"%@[%ld]", [[object entity] name], [valueObj count]]; - - MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self]; - buttonCell.wantsLayer = YES; - [[buttonCell infoField] setAlignment:NSRightTextAlignment]; - [[buttonCell infoField] setTextColor:[NSColor blackColor]]; - [[buttonCell infoField] setStringValue: cellText]; - return buttonCell; - } else { - NSString *cellText = [NSString stringWithFormat:@"%@", valueObj]; - MFLTextTableCellView* textCell = [MFLCellBuilder textCellWithString:tableView textToSet:cellText owner:self]; - return textCell; - } - } - else // Empty NSSet - { - MFLTextTableCellView* textCell = [MFLCellBuilder nullCell:tableView owner:self]; - return textCell; + } + else if ([valueObj isKindOfClass:[NSDate class]]) { + viewType = ViewTypeDate; + [self setupDateFormatter]; + viewText = [self.dateFormatter stringFromDate:valueObj]; + } + else if ([valueObj isKindOfClass:[NSURL class]]) { + viewType = ViewTypeLink; + NSURL* url = (NSURL*) valueObj; + viewText = [NSString stringWithFormat:@"%@", [url absoluteString]]; + } + else if ([valueObj isKindOfClass:[NSData class]]) { + viewType = ViewTypeNumber; + viewText = [NSString stringWithFormat:@"%ld", [valueObj length]]; + } + else if ([valueObj isKindOfClass:[NSManagedObject class]]) { + viewText = [NSString stringWithFormat:@"%@", [[valueObj entity] name]]; + } + else if ([valueObj isKindOfClass:[NSSet class]]) { + if ([valueObj count] > 0) { + id obj = [valueObj anyObject]; + if ([obj isKindOfClass:[NSManagedObject class]]) { + viewType = ViewTypeLink; + NSManagedObject* object = obj; + viewText = [NSString stringWithFormat:@"%@[%ld]", [[object entity] name], [valueObj count]]; + } else { + viewText = [NSString stringWithFormat:@"%@", valueObj]; } } - else if ([valueObj isKindOfClass:[NSArray class]]) - { - if ([valueObj count] > 0) - { - id obj = [valueObj firstItem]; - if ([obj isKindOfClass:[NSManagedObject class]]) { - NSManagedObject* object = obj; - NSString *cellText = [NSString stringWithFormat:@"%@[%ld]", [[object entity] name], [valueObj count]]; - - MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self]; - buttonCell.wantsLayer = YES; - [[buttonCell infoField] setAlignment:NSRightTextAlignment]; - [[buttonCell infoField] setTextColor:[NSColor blackColor]]; - [[buttonCell infoField] setStringValue: cellText]; - return buttonCell; - } else { - NSString *cellText = [NSString stringWithFormat:@"%@", valueObj]; - MFLTextTableCellView* textCell = [MFLCellBuilder textCellWithString:tableView textToSet:cellText owner:self]; - textCell.wantsLayer = YES; - return textCell; - } - } - else // Empty NSArray - { - MFLTextTableCellView* textCell = [MFLCellBuilder nullCell:tableView owner:self]; - return textCell; + } + else if ([valueObj isKindOfClass:[NSArray class]]) { + if ([valueObj count] > 0) { + id obj = [valueObj firstItem]; + if ([obj isKindOfClass:[NSManagedObject class]]) { + viewType = ViewTypeLink; + NSManagedObject* object = obj; + viewText = [NSString stringWithFormat:@"%@[%ld]", [[object entity] name], [valueObj count]]; + } else { + viewText = [NSString stringWithFormat:@"%@", valueObj]; } } - else if ([valueObj isKindOfClass:[NSOrderedSet class]]) - { - if ([valueObj count] > 0) - { - id obj = [valueObj firstObject]; - if ([obj isKindOfClass:[NSManagedObject class]]) { - NSManagedObject* object = obj; - NSString *cellText = [NSString stringWithFormat:@"%@[%ld]", [[object entity] name], [valueObj count]]; - - MFLButtonTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_BUTTON_CELL owner:self]; - buttonCell.wantsLayer = YES; - [[buttonCell infoField] setAlignment:NSRightTextAlignment]; - [[buttonCell infoField] setTextColor:[NSColor blackColor]]; - [[buttonCell infoField] setStringValue: cellText]; - return buttonCell; - } else { - NSString *cellText = [NSString stringWithFormat:@"%@", valueObj]; - MFLTextTableCellView* textCell = [MFLCellBuilder textCellWithString:tableView textToSet:cellText owner:self]; - textCell.wantsLayer = YES; - return textCell; - } - } - else // Empty NSSet - { - MFLTextTableCellView* textCell = [MFLCellBuilder nullCell:tableView owner:self]; - return textCell; + } + else if ([valueObj isKindOfClass:[NSOrderedSet class]]) { + if ([valueObj count] > 0) { + id obj = [valueObj firstObject]; + if ([obj isKindOfClass:[NSManagedObject class]]) { + viewType = ViewTypeLink; + NSManagedObject* object = obj; + viewText = [NSString stringWithFormat:@"%@[%ld]", [[object entity] name], [valueObj count]]; + } else { + viewText = [NSString stringWithFormat:@"%@", valueObj]; } } - else if ([valueObj isKindOfClass:[NSDictionary class]]) - { - NSString* cellText = [NSString stringWithFormat:@"%@", @"NSDictionary Data"]; - TransformableDataTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_TRANSFORM_CELL owner:self]; - buttonCell.wantsLayer = YES; - [[buttonCell infoField] setAlignment:NSRightTextAlignment]; - [[buttonCell infoField] setTextColor:[NSColor blackColor]]; - [[buttonCell infoField] setStringValue: cellText]; - return buttonCell; - } - // Unhandled types of content - else - { - NSLog(@"Unknown content: %@", valueObj); - NSString* cellText = [NSString stringWithFormat:@"??? %@ ???", [valueObj class]]; - TransformableDataTableViewCell* buttonCell = [tableView makeViewWithIdentifier:MFL_TRANSFORM_CELL owner:self]; - buttonCell.wantsLayer = YES; - [[buttonCell infoField] setAlignment:NSRightTextAlignment]; - [[buttonCell infoField] setTextColor:[NSColor blackColor]]; - [[buttonCell infoField] setStringValue: cellText]; - return buttonCell; - } } - - return nil; + else if ([valueObj isKindOfClass:[NSDictionary class]]) { + viewType = ViewTypeTransformable; + viewText = [NSString stringWithFormat:@"%@", @"NSDictionary Data"]; + } + else { + NSLog(@"Unknown content: %@", valueObj); + viewText = [NSString stringWithFormat:@"??? %@ ???", [valueObj class]]; + } + + // cache text and type + if (columnMap == nil) { + columnMap = [NSMutableDictionary new]; + self.cachedRows[@(row)] = columnMap; + } + ViewData *viewData = [ViewData new]; + viewData.text = viewText; + viewData.viewType = viewType; + columnMap[tableColumn.identifier] = viewData; + + // create cell from text and type + return [self createCell:viewText withType:viewType]; +} + +- (NSTableCellView *)createCell:(NSString *)text withType:(EViewType)type { + // using different identifiers for view types to minimize changes to a cells layout for reuse + NSString *identifier; + if (type == ViewTypeLink) { + identifier = @"LINK"; + } + else if (type == ViewTypeTransformable) { + identifier = @"TRANSFORM"; + } + else { + identifier = @"TEXT"; + } + MFLTextTableCellView *textCell = [self.entityContentTable makeViewWithIdentifier:identifier owner:self]; + if (textCell == nil) { + NSLog(@"creating: %d", (int)type); + textCell = [MFLTextTableCellView new]; + textCell.identifier = identifier; + textCell.wantsLayer = YES; + } + + textCell.viewType = type; + textCell.text = text; + + return textCell; } - (void)setupDateFormatter { if (self.dateFormatter == nil) { self.dateFormatter = [[NSDateFormatter alloc] init]; - } - switch (self.dateStyle) { - case NSDateFormatterShortStyle: - [self.dateFormatter setDateFormat:@"M/d/YY h:mm a"]; - break; - case NSDateFormatterMediumStyle: - [self.dateFormatter setDateFormat:@"MM/dd/YY hh:mm a"]; - break; - default: - // use original formatting - [self.dateFormatter setDateStyle:self.dateStyle]; - [self.dateFormatter setTimeStyle:self.dateStyle]; - break; + switch (self.dateStyle) { + case NSDateFormatterShortStyle: + [self.dateFormatter setDateFormat:@"M/d/YY h:mm a"]; + break; + case NSDateFormatterMediumStyle: + [self.dateFormatter setDateFormat:@"MM/dd/YY hh:mm a"]; + break; + default: + // use original formatting + [self.dateFormatter setDateStyle:self.dateStyle]; + [self.dateFormatter setTimeStyle:self.dateStyle]; + break; + } } } @@ -1131,6 +1113,11 @@ - (IBAction) dateFormatItemSelected:(id)sender { } [[NSUserDefaults standardUserDefaults] setInteger:self.dateStyle forKey:DATE_STYLE_KEY_NAME]; + + // clear cache + [self.cachedRows removeAllObjects]; + + self.dateFormatter = nil; if (self.entityContentTable != nil) { [self.entityContentTable reloadData]; diff --git a/CoreDataUtil/MFLMainWindowController.xib b/CoreDataUtil/MFLMainWindowController.xib index c84380a..42d96d5 100644 --- a/CoreDataUtil/MFLMainWindowController.xib +++ b/CoreDataUtil/MFLMainWindowController.xib @@ -1,5 +1,5 @@ - + @@ -164,23 +164,14 @@ - + - - - - - - - - - - - - - @@ -209,23 +196,11 @@ - + - - - - - - - - - - - - - + @@ -241,19 +216,10 @@ - + - - - - - - - - - - - - - @@ -286,7 +248,7 @@ -