diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index e4b343aaf..2d422eb71 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -97,7 +97,6 @@ CPTableViewReverseSequentialColumnAutoresizingStyle = 3; CPTableViewLastColumnOnlyAutoresizingStyle = 4; CPTableViewFirstColumnOnlyAutoresizingStyle = 5; - #define NUMBER_OF_COLUMNS() (_tableColumns.length) #define UPDATE_COLUMN_RANGES_IF_NECESSARY() if (_dirtyTableColumnRangeIndex !== CPNotFound) [self _recalculateTableColumnRanges]; @@ -181,6 +180,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; unsigned _numberOfRows; CPIndexSet _groupRows; + // Persistence + CPString _autosaveName; + BOOL _autosaveTableColumns; CPTableHeaderView _headerView; _CPCornerView _cornerView; @@ -768,12 +770,11 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [self reloadDataForRowIndexes:_exposedRows columnIndexes:[CPIndexSet indexSetWithIndex:[_tableColumns indexOfObject:aColumn]]]; } -/*! - Moves the column and heading at a given index to a new given index. - @param columnIndex The current index of the column to move. - @param newIndex The new index for the moved column. +/* + @ignore + Same as moveColumn:toColumn: but doesn't trigger an autosave */ -- (void)moveColumn:(unsigned)fromIndex toColumn:(unsigned)toIndex +- (void)_moveColumn:(unsigned)fromIndex toColumn:(unsigned)toIndex { fromIndex = +fromIndex; toIndex = +toIndex; @@ -800,6 +801,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; [self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes]; } +/*! + Moves the column and heading at a given index to a new given index. + @param theColumnIndex The current index of the column to move. + @param theToIndex The new index for the moved column. +*/ +- (void)moveColumn:(int)theColumnIndex toColumn:(int)theToIndex +{ + [self _moveColumn:theColumnIndex toColumn:theToIndex]; + [self _autosave]; +} + /*! @ignore */ @@ -1689,13 +1701,94 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5; /*FIX ME: tableview header isn't rendered until you click the horizontal scroller (or scroll)*/ } -//Persistence -/* - * - autosaveName - * - autosaveTableColumns - * - setAutosaveName: - * - setAutosaveTableColumns: +- (void)setAutosaveName:(CPString)theAutosaveName +{ + if (_autosaveName === theAutosaveName) + return; + + _autosaveName = theAutosaveName; + + [self setAutosaveTableColumns:!!theAutosaveName]; + [self _restoreFromAutosave]; +} + +- (CPString)autosaveName +{ + return _autosaveName; +} + +- (void)setAutosaveTableColumns:(BOOL)shouldAutosave +{ + _autosaveTableColumns = shouldAutosave; +} + +- (BOOL)autosaveTableColumns +{ + return _autosaveTableColumns; +} + +- (CPString)_columnsKeyForAutosaveName:(CPString)theAutosaveName +{ + return @"CPTableView Columns " + theAutosaveName; +} + +- (BOOL)_autosaveEnabled +{ + return [self autosaveName] && [self autosaveTableColumns]; +} + +/*! + @ignore + Stores the tablecolumn setup in user defaults. + I believe Apple stores the entire encoded table column, + in our case that seems overkill since we need to store everything in a cookie. */ +- (void)_autosave +{ + if (![self _autosaveEnabled]) + return; + + var userDefaults = [CPUserDefaults standardUserDefaults], + autosaveName = [self autosaveName]; + + var columns = [self tableColumns], + columnsSetup = []; + + for (var i = 0; i < [columns count]; i++) + { + var column = [columns objectAtIndex:i]; + + var metaData = [CPDictionary dictionaryWithJSObject:{ + @"identifier": [column identifier], + @"width": [column width] + }] + + [columnsSetup addObject:metaData]; + } + + [userDefaults setObject:columnsSetup forKey:[self _columnsKeyForAutosaveName:autosaveName]]; +} + +- (void)_restoreFromAutosave +{ + if (![self _autosaveEnabled]) + return; + + var userDefaults = [CPUserDefaults standardUserDefaults], + autosaveName = [self autosaveName], + tableColumns = [userDefaults objectForKey:[self _columnsKeyForAutosaveName:autosaveName]]; + + for (var i = 0; i < [tableColumns count]; i++) + { + var metaData = [tableColumns objectAtIndex:i], + columnIdentifier = [metaData objectForKey:@"identifier"], + column = [self columnWithIdentifier:columnIdentifier], + tableColumn = [self tableColumnWithIdentifier:columnIdentifier]; + + [self _moveColumn:column toColumn:i]; + [tableColumn setWidth:[metaData objectForKey:@"width"]]; + } +} //Setting the Delegate:(id)aDelegate diff --git a/Tests/Manual/CPUserDefaults/AppController.j b/Tests/Manual/CPUserDefaults/AppController.j new file mode 100644 index 000000000..6d3c67e77 --- /dev/null +++ b/Tests/Manual/CPUserDefaults/AppController.j @@ -0,0 +1,49 @@ + +@import + + +@implementation AppController : CPObject +{ +} + +- (void)applicationDidFinishLaunching:(CPNotification)aNotification +{ + var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(50.0, 100.0, 400.0, 300.0) styleMask:CPTitledWindowMask], + contentView = [theWindow contentView]; + + var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 400.0, 300.0)], + tableView = [[CPTableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 400.0, 300.0)]; + + [scrollView setDocumentView:tableView]; + [scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + + var tableColumn1 = [[CPTableColumn alloc] initWithIdentifier:@"column1"]; + [[tableColumn1 headerView] setStringValue:@"Column 1"]; + [tableView addTableColumn:tableColumn1]; + + var tableColumn2 = [[CPTableColumn alloc] initWithIdentifier:@"column2"]; + [[tableColumn2 headerView] setStringValue:@"Column 2"]; + [tableView addTableColumn:tableColumn2]; + + var tableColumn3 = [[CPTableColumn alloc] initWithIdentifier:@"column3"]; + [[tableColumn3 headerView] setStringValue:@"Column 3"]; + [tableView addTableColumn:tableColumn3]; + + var tableColumn4 = [[CPTableColumn alloc] initWithIdentifier:@"column4"]; + [[tableColumn4 headerView] setStringValue:@"Column 4"]; + [tableView addTableColumn:tableColumn4]; + + var tableColumn5 = [[CPTableColumn alloc] initWithIdentifier:@"column5"]; + [[tableColumn5 headerView] setStringValue:@"Column 5"]; + [tableView addTableColumn:tableColumn5]; + + [scrollView setBackgroundColor:[CPColor blueColor]]; + [contentView addSubview:scrollView]; + + [tableView setAutosaveTableColumns:YES]; + [tableView setAutosaveName:@"myAutosaveName"]; + + [theWindow makeKeyAndOrderFront:self]; +} + +@end diff --git a/Tests/Manual/CPUserDefaults/Info.plist b/Tests/Manual/CPUserDefaults/Info.plist new file mode 100644 index 000000000..1378ea966 --- /dev/null +++ b/Tests/Manual/CPUserDefaults/Info.plist @@ -0,0 +1,12 @@ + + + + + CPApplicationDelegateClass + AppController + CPBundleName + CPUserDefaults + CPPrincipalClass + CPApplication + + diff --git a/Tests/Manual/CPUserDefaults/Jakefile b/Tests/Manual/CPUserDefaults/Jakefile new file mode 100644 index 000000000..8d336e3ff --- /dev/null +++ b/Tests/Manual/CPUserDefaults/Jakefile @@ -0,0 +1,93 @@ +/* + * Jakefile + * CPUserDefaults + * + * Created by You on October 13, 2010. + * Copyright 2010, Your Company All rights reserved. + */ + +var ENV = require("system").env, + FILE = require("file"), + JAKE = require("jake"), + task = JAKE.task, + FileList = JAKE.FileList, + app = require("cappuccino/jake").app, + configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug", + OS = require("os"); + +app ("CPUserDefaults", function(task) +{ + task.setBuildIntermediatesPath(FILE.join("Build", "CPUserDefaults.build", configuration)); + task.setBuildPath(FILE.join("Build", configuration)); + + task.setProductName("CPUserDefaults"); + task.setIdentifier("com.yourcompany.CPUserDefaults"); + task.setVersion("1.0"); + task.setAuthor("Your Company"); + task.setEmail("feedback @nospam@ yourcompany.com"); + task.setSummary("CPUserDefaults"); + task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**"))); + task.setResources(new FileList("Resources/**")); + task.setIndexFilePath("index.html"); + task.setInfoPlistPath("Info.plist"); + + if (configuration === "Debug") + task.setCompilerFlags("-DDEBUG -g"); + else + task.setCompilerFlags("-O"); +}); + +task ("default", ["CPUserDefaults"], function() +{ + printResults(configuration); +}); + +task ("build", ["default"]); + +task ("debug", function() +{ + ENV["CONFIGURATION"] = "Debug"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("release", function() +{ + ENV["CONFIGURATION"] = "Release"; + JAKE.subjake(["."], "build", ENV); +}); + +task ("run", ["debug"], function() +{ + OS.system(["open", FILE.join("Build", "Debug", "CPUserDefaults", "index.html")]); +}); + +task ("run-release", ["release"], function() +{ + OS.system(["open", FILE.join("Build", "Release", "CPUserDefaults", "index.html")]); +}); + +task ("deploy", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Deployment", "CPUserDefaults")); + OS.system(["press", "-f", FILE.join("Build", "Release", "CPUserDefaults"), FILE.join("Build", "Deployment", "CPUserDefaults")]); + printResults("Deployment") +}); + +task ("desktop", ["release"], function() +{ + FILE.mkdirs(FILE.join("Build", "Desktop", "CPUserDefaults")); + require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", "CPUserDefaults"), FILE.join("Build", "Desktop", "CPUserDefaults", "CPUserDefaults.app")); + printResults("Desktop") +}); + +task ("run-desktop", ["desktop"], function() +{ + OS.system([FILE.join("Build", "Desktop", "CPUserDefaults", "CPUserDefaults.app", "Contents", "MacOS", "NativeHost"), "-i"]); +}); + +function printResults(configuration) +{ + print("----------------------------"); + print(configuration+" app built at path: "+FILE.join("Build", configuration, "CPUserDefaults")); + print("----------------------------"); +} diff --git a/Tests/Manual/CPUserDefaults/Resources/spinner.gif b/Tests/Manual/CPUserDefaults/Resources/spinner.gif new file mode 100644 index 000000000..06dbc2bc2 Binary files /dev/null and b/Tests/Manual/CPUserDefaults/Resources/spinner.gif differ diff --git a/Tests/Manual/CPUserDefaults/index-debug.html b/Tests/Manual/CPUserDefaults/index-debug.html new file mode 100644 index 000000000..696b51c4b --- /dev/null +++ b/Tests/Manual/CPUserDefaults/index-debug.html @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + CPUserDefaults + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + diff --git a/Tests/Manual/CPUserDefaults/index.html b/Tests/Manual/CPUserDefaults/index.html new file mode 100644 index 000000000..52e03d3a7 --- /dev/null +++ b/Tests/Manual/CPUserDefaults/index.html @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + CPUserDefaults + + + + + + + + + + + + +
+
+ + + +
+
+ + + + diff --git a/Tests/Manual/CPUserDefaults/main.j b/Tests/Manual/CPUserDefaults/main.j new file mode 100644 index 000000000..de8321048 --- /dev/null +++ b/Tests/Manual/CPUserDefaults/main.j @@ -0,0 +1,18 @@ +/* + * AppController.j + * CPUserDefaults + * + * Created by You on October 13, 2010. + * Copyright 2010, Your Company All rights reserved. + */ + +@import +@import + +@import "AppController.j" + + +function main(args, namedArgs) +{ + CPApplicationMain(args, namedArgs); +}