]> git.saurik.com Git - winterboard.git/commitdiff
Finished integrating new code from DHowett for WinterBoardSettings.
authorJay Freeman (saurik) <saurik@saurik.com>
Sat, 29 Aug 2009 23:02:32 +0000 (23:02 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Sat, 29 Aug 2009 23:02:32 +0000 (23:02 +0000)
Application.mm
Library.mm
SearchResultsCheckmarkClear.png [new file with mode: 0644]
Settings.mm [new file with mode: 0644]
WinterBoardSettings.bundle/Info.plist [new file with mode: 0644]
WinterBoardSettings.bundle/Themes.png [new file with mode: 0644]
WinterBoardSettings.bundle/WinterBoard.plist [new file with mode: 0644]
WinterBoardSettings.plist [new file with mode: 0644]
control
make.sh
makefile

index 199695578001f4c4241dbca62bfa24eeb8a321f4..cd383d31d7984a878cc205eb3ad9324a977faecc 100644 (file)
@@ -1,5 +1,5 @@
 /* WinterBoard - Theme Manager for the iPhone
- * Copyright (C) 2008  Jay Freeman (saurik)
+ * Copyright (C) 2008-2009  Jay Freeman (saurik)
 */
 
 /*
 #import <CoreGraphics/CGGeometry.h>
 #import <UIKit/UIKit.h>
 
-#define _trace() NSLog(@"WE:_trace(%u)", __LINE__);
+#import <Preferences/PSRootController.h>
+#import <Preferences/PSViewController.h>
+#import <Preferences/PSSpecifier.h>
 
-static NSString *plist_;
-static NSMutableDictionary *settings_;
-static BOOL changed_;
+@interface UIApplication (Private)
+- (void) terminateWithSuccess;
+@end
 
-@interface WBThemeTableViewCell : UITableViewCell {
-    UILabel *label;
+@interface WBRootController : PSRootController {
+    PSViewController *_firstViewController;
 }
 
-@end
-
-@implementation WBThemeTableViewCell
+@property (readonly) PSViewController *firstViewController;
 
+- (void) setupRootListForSize:(CGSize)size;
+- (BOOL) popController;
 
 @end
 
-@interface WBApplication : UIApplication <
-    UITableViewDataSource,
-    UITableViewDelegate
-> {
-    UIWindow *window_;
-    UITableView *themesTable_;
-    NSMutableArray *themesArray_;
-}
+@implementation WBRootController
 
-@end
+@synthesize firstViewController = _firstViewController;
 
-@implementation WBApplication
+- (void) setupRootListForSize:(CGSize)size {
+    PSSpecifier *spec = [[PSSpecifier alloc] init];
+    [spec setTarget:self];
+    spec.name = @"WinterBoard";
 
-- (void) dealloc {
-    [window_ release];
-    [themesTable_ release];
-    [themesArray_ release];
-    [super dealloc];
-}
+    NSBundle *wbSettingsBundle = [NSBundle bundleWithPath:@"/System/Library/PreferenceBundles/WinterBoardSettings.bundle"];
+    [wbSettingsBundle load];
 
-- (void) applicationWillTerminate:(UIApplication *)application {
-    if (changed_) {
-        NSString *description = nil;
-        NSData *data = [NSPropertyListSerialization dataFromPropertyList:settings_ format:NSPropertyListBinaryFormat_v1_0 errorDescription:&description];
-        if (data == nil) {
-            NSLog(@"WB:Error:dataFromPropertyList:%@", description);
-            return;
-        }
-
-        NSError *error = nil;
-        if (![data writeToFile:plist_ options:NSAtomicWrite error:&error]) {
-            NSLog(@"WB:Error:writeToFile");
-            return;
-        }
-
-        unlink("/User/Library/Caches/com.apple.springboard-imagecache-icons");
-        unlink("/User/Library/Caches/com.apple.springboard-imagecache-icons.plist");
-
-        unlink("/User/Library/Caches/com.apple.springboard-imagecache-smallicons");
-        unlink("/User/Library/Caches/com.apple.springboard-imagecache-smallicons.plist");
-
-        system("killall SpringBoard");
-    }
-}
+    _firstViewController = [[[wbSettingsBundle principalClass] alloc] initForContentSize:size];
+    _firstViewController.rootController = self;
+    _firstViewController.parentController = self;
+    [_firstViewController viewWillBecomeVisible:spec];
 
-- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease];
-    NSMutableDictionary *theme = [themesArray_ objectAtIndex:[indexPath row]];
-    cell.text = [theme objectForKey:@"Name"];
-    cell.hidesAccessoryWhenEditing = NO;
-    NSNumber *active = [theme objectForKey:@"Active"];
-    BOOL inactive = active == nil || ![active boolValue];
-    cell.accessoryType = inactive ? UITableViewCellAccessoryNone : UITableViewCellAccessoryCheckmark;
-    return cell;
-}
+    [spec release];
 
-- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
-    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
-    NSMutableDictionary *theme = [themesArray_ objectAtIndex:[indexPath row]];
-    NSNumber *active = [theme objectForKey:@"Active"];
-    BOOL inactive = active == nil || ![active boolValue];
-    [theme setObject:[NSNumber numberWithBool:inactive] forKey:@"Active"];
-    cell.accessoryType = inactive ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
-    [themesTable_ deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:YES];
-    changed_ = YES;
+    [self pushController:_firstViewController];
 }
 
-- (NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
-    return [themesArray_ count];
+- (BOOL) popController {
+    // Pop the last controller = exit the application.
+    // The only time the last controller should pop is when the user taps Respring/Cancel.
+    // Which only gets displayed if the user has made changes.
+    if([self lastController] == _firstViewController)
+        [[UIApplication sharedApplication] terminateWithSuccess];
+    return [super popController];
 }
+@end
 
-- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
-    return UITableViewCellEditingStyleNone;
+@interface WBApplication : UIApplication {
+    WBRootController *_rootController;
 }
 
-- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
-    NSUInteger fromIndex = [fromIndexPath row];
-    NSUInteger toIndex = [toIndexPath row];
-    if (fromIndex == toIndex)
-        return;
-    NSMutableDictionary *theme = [[[themesArray_ objectAtIndex:fromIndex] retain] autorelease];
-    [themesArray_ removeObjectAtIndex:fromIndex];
-    [themesArray_ insertObject:theme atIndex:toIndex];
-    changed_ = YES;
+@end
+
+@implementation WBApplication
+
+- (void) dealloc {
+    [_rootController release];
+    [super dealloc];
 }
 
-- (BOOL) tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
-    return YES;
+- (void) applicationWillTerminate:(UIApplication *)application {
+    [_rootController.firstViewController suspend];
 }
 
 - (void) applicationDidFinishLaunching:(id)unused {
-    window_ = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
-    [window_ makeKeyAndVisible];
-
-    plist_ = [[NSString stringWithFormat:@"%@/Library/Preferences/com.saurik.WinterBoard.plist",
-        NSHomeDirectory()
-    ] retain];
-
-    settings_ = [[NSMutableDictionary alloc] initWithContentsOfFile:plist_];
-    if (settings_ == nil)
-        settings_ = [[NSMutableDictionary alloc] initWithCapacity:16];
-
-    themesArray_ = [settings_ objectForKey:@"Themes"];
-    if (themesArray_ == nil) {
-        if (NSString *theme = [settings_ objectForKey:@"Theme"]) {
-            themesArray_ = [[NSArray arrayWithObject:[[NSDictionary dictionaryWithObjectsAndKeys:
-                theme, @"Name",
-                [NSNumber numberWithBool:YES], @"Active",
-            nil] mutableCopy]] mutableCopy];
-
-            [settings_ removeObjectForKey:@"Theme"];
-        }
-
-        if (themesArray_ == nil)
-            themesArray_ = [NSMutableArray arrayWithCapacity:16];
-        [settings_ setObject:themesArray_ forKey:@"Themes"];
-    }
-
-    themesArray_ = [themesArray_ retain];
-
-    NSMutableSet *themesSet = [NSMutableSet setWithCapacity:32];
-    for (NSMutableDictionary *theme in themesArray_)
-        if (NSString *name = [theme objectForKey:@"Name"])
-            [themesSet addObject:name];
-
-    NSFileManager *manager = [NSFileManager defaultManager];
-
-    NSMutableArray *themes = [NSMutableArray arrayWithCapacity:32];
-    [themes addObjectsFromArray:[manager contentsOfDirectoryAtPath:@"/Library/Themes" error:NULL]];
-    [themes addObjectsFromArray:[manager contentsOfDirectoryAtPath:[NSString stringWithFormat:@"%@/Library/SummerBoard/Themes", NSHomeDirectory()] error:NULL]];
-
-    for (NSUInteger i(0), e([themes count]); i != e; ++i) {
-        NSString *theme = [themes objectAtIndex:i];
-        if ([theme hasSuffix:@".theme"])
-            [themes replaceObjectAtIndex:i withObject:[theme substringWithRange:NSMakeRange(0, [theme length] - 6)]];
-    }
-
-    for (NSUInteger i(0), e([themesArray_ count]); i != e; ++i) {
-        NSMutableDictionary *theme = [themesArray_ objectAtIndex:i];
-        NSString *name = [theme objectForKey:@"Name"];
-        if (name == nil || ![themes containsObject:name]) {
-            [themesArray_ removeObjectAtIndex:i];
-            --i; --e;
-        }
-    }
-
-    for (NSString *theme in themes) {
-        if ([themesSet containsObject:theme])
-            continue;
-        [themesSet addObject:theme];
-        [themesArray_ insertObject:[[NSDictionary dictionaryWithObjectsAndKeys:
-            theme, @"Name",
-            [NSNumber numberWithBool:NO], @"Active",
-        nil] mutableCopy] atIndex:0];
-    }
-
-    themesTable_ = [[UITableView alloc] initWithFrame:window_.bounds];
-    [window_ addSubview:themesTable_];
-
-    [themesTable_ setDataSource:self];
-    [themesTable_ setDelegate:self];
-
-    [themesTable_ setEditing:YES animated:NO];
-    themesTable_.allowsSelectionDuringEditing = YES;
-
-    [themesTable_ setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
+    UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
+    _rootController = [[WBRootController alloc] initWithTitle:@"WinterBoard" identifier:[[NSBundle mainBundle] bundleIdentifier]];
+    [window addSubview:_rootController.contentView];
+    [window makeKeyAndVisible];
 }
 
 @end
index 3e9e6c92649c05eede63dae6f0a0f035dc4ea428..9b32afc9e7448ce808e093f32c1f0e86dd52325c 100644 (file)
@@ -1,5 +1,5 @@
 /* WinterBoard - Theme Manager for the iPhone
- * Copyright (C) 2008  Jay Freeman (saurik)
+ * Copyright (C) 2008-2009  Jay Freeman (saurik)
 */
 
 /*
diff --git a/SearchResultsCheckmarkClear.png b/SearchResultsCheckmarkClear.png
new file mode 100644 (file)
index 0000000..4bd9491
Binary files /dev/null and b/SearchResultsCheckmarkClear.png differ
diff --git a/Settings.mm b/Settings.mm
new file mode 100644 (file)
index 0000000..38aa3c3
--- /dev/null
@@ -0,0 +1,352 @@
+/* WinterBoard - Theme Manager for the iPhone
+ * Copyright (C) 2009  Jay Freeman (saurik)
+*/
+
+/*
+ *        Redistribution and use in source and binary
+ * forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer in the documentation
+ *    and/or other materials provided with the
+ *    distribution.
+ * 3. The name of the author may not be used to endorse
+ *    or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import <Preferences/PSListController.h>
+#import <Preferences/PSSpecifier.h>
+#import <Preferences/PSTableCell.h>
+#import <UIKit/UINavigationButton.h>
+
+extern NSString *PSTableCellKey;
+extern "C" UIImage *_UIImageWithName(NSString *);
+
+static UIImage *checkImage;
+static UIImage *uncheckedImage;
+
+static BOOL settingsChanged;
+static NSMutableDictionary *_settings;
+static NSString *_plist;
+
+/* Theme Settings Controller {{{ */
+@interface WBSThemesController: PSViewController <UITableViewDelegate, UITableViewDataSource> {
+    UITableView *_tableView;
+    NSMutableArray *_themes;
+}
+
+@property (nonatomic, retain) NSMutableArray *themes;
+
++ (void) load;
+
+- (id) initForContentSize:(CGSize)size;
+- (id) view;
+- (id) navigationTitle;
+- (void) themesChanged;
+
+- (int) numberOfSectionsInTableView:(UITableView *)tableView;
+- (id) tableView:(UITableView *)tableView titleForHeaderInSection:(int)section;
+- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(int)section;
+- (id) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
+- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
+- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath;
+- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
+- (BOOL) tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath;
+- (BOOL) tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
+@end
+
+@implementation WBSThemesController
+
+@synthesize themes = _themes;
+
++ (void) load {
+    NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
+    checkImage = [_UIImageWithName(@"UIPreferencesBlueCheck.png") retain];
+    uncheckedImage = [[UIImage imageWithContentsOfFile:@"/System/Library/PreferenceBundles/WinterBoardSettings.bundle/SearchResultsCheckmarkClear.png"] retain];
+    [pool release];
+}
+
+- (id) initForContentSize:(CGSize)size {
+    if ((self = [super initForContentSize:size]) != nil) {
+        self.themes = [_settings objectForKey:@"Themes"];
+        if (!_themes) {
+            if (NSString *theme = [_settings objectForKey:@"Theme"]) {
+                self.themes = [NSMutableArray arrayWithObject:
+                         [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                            theme, @"Name",
+                                [NSNumber numberWithBool:YES], @"Active", nil]];
+                [_settings removeObjectForKey:@"Theme"];
+            }
+            if (!_themes)
+                self.themes = [NSMutableArray array];
+            [_settings setObject:_themes forKey:@"Themes"];
+        }
+
+        NSMutableArray *themesOnDisk([NSMutableArray array]);
+
+        [themesOnDisk
+            addObjectsFromArray:[[NSFileManager defaultManager]
+            contentsOfDirectoryAtPath:@"/Library/Themes" error:NULL]
+        ];
+
+        [themesOnDisk addObjectsFromArray:[[NSFileManager defaultManager]
+            contentsOfDirectoryAtPath:[NSString stringWithFormat:@"%@/Library/SummerBoard/Themes", NSHomeDirectory()]
+            error:NULL
+        ]];
+
+        for (int i = 0, count = [themesOnDisk count]; i < count; i++) {
+            NSString *theme = [themesOnDisk objectAtIndex:i];
+            if ([theme hasSuffix:@".theme"])
+                [themesOnDisk replaceObjectAtIndex:i withObject:[theme stringByDeletingPathExtension]];
+        }
+
+        NSMutableSet *themesSet([NSMutableSet set]);
+
+        for (int i = 0, count = [_themes count]; i < count; i++) {
+            NSDictionary *theme([_themes objectAtIndex:i]);
+            NSString *name([theme objectForKey:@"Name"]);
+
+            if (!name || ![themesOnDisk containsObject:name]) {
+                [_themes removeObjectAtIndex:i];
+                i--;
+                count--;
+            } else {
+                [themesSet addObject:name];
+            }
+        }
+
+        for (NSString *theme in themesOnDisk) {
+            if ([themesSet containsObject:theme])
+                continue;
+            [themesSet addObject:theme];
+
+            [_themes insertObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
+                    theme, @"Name",
+                    [NSNumber numberWithBool:NO], @"Active",
+            nil] atIndex:0];
+        }
+
+        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 480-64) style:UITableViewStyleGrouped];
+        [_tableView setDataSource:self];
+        [_tableView setDelegate:self];
+        [_tableView setEditing:YES];
+        [_tableView setAllowsSelectionDuringEditing:YES];
+        [self showLeftButton:@"WinterBoard" withStyle:1 rightButton:nil withStyle:0];
+    }
+    return self;
+}
+
+- (void) dealloc {
+    [_tableView release];
+    [_themes release];
+    [super dealloc];
+}
+
+- (id) navigationTitle {
+    return @"Themes";
+}
+
+- (id) view {
+    return _tableView;
+}
+
+- (void) themesChanged {
+    settingsChanged = YES;
+}
+
+/* UITableViewDelegate / UITableViewDataSource Methods {{{ */
+- (int) numberOfSectionsInTableView:(UITableView *)tableView {
+    return 1;
+}
+
+- (id) tableView:(UITableView *)tableView titleForHeaderInSection:(int)section {
+    return nil;
+}
+
+- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(int)section {
+    return _themes.count;
+}
+
+- (id) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ThemeCell"];
+    if (!cell) {
+        cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, 100, 100) reuseIdentifier:@"ThemeCell"] autorelease];
+        //[cell setTableViewStyle:UITableViewCellStyleDefault];
+    }
+
+    NSDictionary *theme([_themes objectAtIndex:indexPath.row]);
+    cell.text = [theme objectForKey:@"Name"];
+    cell.hidesAccessoryWhenEditing = NO;
+    NSNumber *active([theme objectForKey:@"Active"]);
+    BOOL inactive(active == nil || ![active boolValue]);
+    [cell setImage:(inactive ? uncheckedImage : checkImage)];
+    return cell;
+}
+
+- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
+    NSMutableDictionary *theme = [_themes objectAtIndex:indexPath.row];
+    NSNumber *active = [theme objectForKey:@"Active"];
+    BOOL inactive = active == nil || ![active boolValue];
+    [theme setObject:[NSNumber numberWithBool:inactive] forKey:@"Active"];
+    [cell setImage:(!inactive ? uncheckedImage : checkImage)];
+    [tableView deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:YES];
+    [self themesChanged];
+}
+
+- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
+    NSUInteger fromIndex = [fromIndexPath row];
+    NSUInteger toIndex = [toIndexPath row];
+    if (fromIndex == toIndex)
+        return;
+    NSMutableDictionary *theme = [[[_themes objectAtIndex:fromIndex] retain] autorelease];
+    [_themes removeObjectAtIndex:fromIndex];
+    [_themes insertObject:theme atIndex:toIndex];
+    [self themesChanged];
+}
+
+- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
+    return UITableViewCellEditingStyleNone;
+}
+
+- (BOOL) tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
+    return NO;
+}
+
+- (BOOL) tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
+    return YES;
+}
+/* }}} */
+@end
+/* }}} */
+
+@interface WBSettingsController: PSListController {
+}
+
+- (id) initForContentSize:(CGSize)size;
+- (void) dealloc;
+- (void) suspend;
+- (void) navigationBarButtonClicked:(int)buttonIndex;
+- (void) viewWillRedisplay;
+- (void) pushController:(id)controller;
+- (id) specifiers;
+- (void) settingsChanged;
+- (NSString *) title;
+- (void) setPreferenceValue:(id)value specifier:(PSSpecifier *)spec;
+- (id) readPreferenceValue:(PSSpecifier *)spec;
+
+@end
+
+@implementation WBSettingsController
+
+- (id) initForContentSize:(CGSize)size {
+    if ((self = [super initForContentSize:size]) != nil) {
+        _plist = [[NSString stringWithFormat:@"%@/Library/Preferences/com.saurik.WinterBoard.plist", NSHomeDirectory()] retain];
+        _settings = [([NSMutableDictionary dictionaryWithContentsOfFile:_plist] ?: [NSMutableDictionary dictionary]) retain];
+    } return self;
+}
+
+- (void) dealloc {
+    [_settings release];
+    [_plist release];
+    [super dealloc];
+}
+
+- (void) suspend {
+    if (!settingsChanged)
+        return;
+
+    NSData *data([NSPropertyListSerialization dataFromPropertyList:_settings format:NSPropertyListBinaryFormat_v1_0 errorDescription:NULL]);
+    if (!data)
+        return;
+    if (![data writeToFile:_plist options:NSAtomicWrite error:NULL])
+        return;
+
+    unlink("/User/Library/Caches/com.apple.springboard-imagecache-icons");
+    unlink("/User/Library/Caches/com.apple.springboard-imagecache-icons.plist");
+    unlink("/User/Library/Caches/com.apple.springboard-imagecache-smallicons");
+    unlink("/User/Library/Caches/com.apple.springboard-imagecache-smallicons.plist");
+    system("killall SpringBoard");
+}
+
+- (void) navigationBarButtonClicked:(int)buttonIndex {
+    if (!settingsChanged) {
+        [super navigationBarButtonClicked:buttonIndex];
+        return;
+    }
+
+    if (buttonIndex == 0)
+        settingsChanged = NO;
+
+    [self suspend];
+    [self.rootController popController];
+}
+
+- (void) viewWillRedisplay {
+    if (settingsChanged)
+        [self settingsChanged];
+    [super viewWillRedisplay];
+}
+
+- (void) pushController:(id)controller {
+    [self hideNavigationBarButtons];
+    [super pushController:controller];
+}
+
+- (id) specifiers {
+    if (!_specifiers)
+        _specifiers = [[self loadSpecifiersFromPlistName:@"WinterBoard" target:self] retain];
+    return _specifiers;
+}
+
+- (void) settingsChanged {
+    [self showLeftButton:@"Respring" withStyle:2 rightButton:@"Cancel" withStyle:0];
+    settingsChanged = YES;
+}
+
+- (NSString *) title {
+    return @"WinterBoard";
+}
+
+- (void) setPreferenceValue:(id)value specifier:(PSSpecifier *)spec {
+    if ([[spec propertyForKey:@"negate"] boolValue])
+        value = [NSNumber numberWithBool:(![value boolValue])];
+    [_settings setValue:value forKey:[spec propertyForKey:@"key"]];
+    [self settingsChanged];
+}
+
+- (id) readPreferenceValue:(PSSpecifier *)spec {
+    NSString *key([spec propertyForKey:@"key"]);
+    id defaultValue([spec propertyForKey:@"default"]);
+    id plistValue([_settings objectForKey:key]);
+    if (!plistValue)
+        return defaultValue;
+    if ([[spec propertyForKey:@"negate"] boolValue])
+        plistValue = [NSNumber numberWithBool:(![plistValue boolValue])];
+    return plistValue;
+}
+
+@end
diff --git a/WinterBoardSettings.bundle/Info.plist b/WinterBoardSettings.bundle/Info.plist
new file mode 100644 (file)
index 0000000..6a52fde
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//GNUstep//DTD plist 0.9//EN" "http://www.gnustep.org/plist-0_9.xml">
+<plist version="0.9">
+<dict>
+    <key>CFBundleDevelopmentRegion</key>
+    <string>en</string>
+    <key>CFBundleExecutable</key>
+    <string>WinterBoardSettings</string>
+    <key>CFBundleIdentifier</key>
+    <string>com.saurik.winterboard.settings</string>
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+    <key>CFBundlePackageType</key>
+    <string>BNDL</string>
+    <key>CFBundleShortVersionString</key>
+    <string>0.9</string>
+    <key>CFBundleSignature</key>
+    <string>????</string>
+    <key>CFBundleVersion</key>
+    <string>1.0</string>
+    <key>DTPlatformName</key>
+    <string>iphoneos</string>
+    <key>MinimumOSVersion</key>
+    <string>3.0</string>
+    <key>NSPrincipalClass</key>
+    <string>WBSettingsController</string>
+</dict>
+</plist>
diff --git a/WinterBoardSettings.bundle/Themes.png b/WinterBoardSettings.bundle/Themes.png
new file mode 100644 (file)
index 0000000..91dc70d
Binary files /dev/null and b/WinterBoardSettings.bundle/Themes.png differ
diff --git a/WinterBoardSettings.bundle/WinterBoard.plist b/WinterBoardSettings.bundle/WinterBoard.plist
new file mode 100644 (file)
index 0000000..d6b4f96
--- /dev/null
@@ -0,0 +1,37 @@
+{
+    items = (
+       {
+           cell = PSSwitchCell;
+           key = ArbitrarySetting;
+           label = "Arbitrary Switch 1";
+       },
+       {
+           cell = PSSwitchCell;
+           key = ArbitrarySettingTwo;
+           label = "Arbitrary Switch 2";
+           negate = 1;
+       },
+       {
+           cell = PSSwitchCell;
+           default = 1;
+           key = ArbitrarySettingThree;
+           label = "Arbitrary Switch 3";
+       },
+       {
+           cell = PSSwitchCell;
+           default = 0;
+           key = ArbitrarySettingFour;
+           label = "Arbitrary Switch 4";
+       },
+       {
+           cell = PSGroupCell;
+       },
+       {
+           cell = PSLinkCell;
+           detail = WBSThemesController;
+           icon = Themes.png;
+           label = Themes;
+       }
+    );
+    title = WinterBoard;
+}
diff --git a/WinterBoardSettings.plist b/WinterBoardSettings.plist
new file mode 100644 (file)
index 0000000..f0d8769
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>entry</key>
+       <dict>
+               <key>bundle</key>
+               <string>WinterBoardSettings</string>
+               <key>cell</key>
+               <string>PSLinkCell</string>
+               <key>isController</key>
+               <true/>
+               <key>icon</key>
+               <string>icon.png</string>
+               <key>label</key>
+               <string>WinterBoard</string>
+       </dict>
+</dict>
+</plist>
diff --git a/control b/control
index a6bd3b706b3f8ac8626beba5ae659dd3a120e4ec..9a72f53728cb2b821f76d5625f5ba26112e4c3d1 100644 (file)
--- a/control
+++ b/control
@@ -3,13 +3,13 @@ Priority: optional
 Section: System
 Maintainer: Jay Freeman (saurik) <saurik@saurik.com>
 Architecture: iphoneos-arm
-Version: 0.9.2993-1
+Version: 0.9.3017-1
 Description: more powerful, open-source SummerBoard
 Name: WinterBoard
-Depends: mobilesubstrate (>= 0.9.2958-1), killall
+Depends: mobilesubstrate (>= 0.9.2958-1), killall, preferenceloader
 Provides: theme-manager
-Conflicts: com.modmyifone.winterboardicon
-Replaces: com.modmyifone.winterboardicon
+Conflicts: com.modmyifone.winterboardicon, winterboardsettings, themesettings
+Replaces: com.modmyifone.winterboardicon, winterboardsettings, themesettings
 Author: Jay Freeman (saurik) <saurik@saurik.com>
 Depiction: http://cydia.saurik.com/info/winterboard/
 Homepage: http://www.saurik.com/id/9
diff --git a/make.sh b/make.sh
index 1d3f271ce4819c78a653072e62e48ee3b0f57eeb..3ba4fcb1f52321bb529499020e8729d0e0001b57 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -3,5 +3,4 @@ set -e
 export PKG_ARCH=${PKG_ARCH-iphoneos-arm}
 PATH=/apl/n42/pre/bin:$PATH /apl/tel/exec.sh com.saurik.winterboard make "$@"
 export CODESIGN_ALLOCATE=$(which arm-apple-darwin9-codesign_allocate)
-/apl/tel/util/ldid -S WinterBoard WinterBoard.dylib UIImages
 make package
index 6ac64bbbaa3a672741b5ebce6b6cb88435e60e90..3c2600484658b97bf439fa292addfa42e5843f71 100644 (file)
--- a/makefile
+++ b/makefile
@@ -4,19 +4,26 @@ else
 target := $(PKG_TARG)-
 endif
 
-all: WinterBoard WinterBoard.dylib UIImages
+all: WinterBoard WinterBoard.dylib UIImages WinterBoardSettings
 
 clean:
        rm -f WinterBoard WinterBoard.dylib UIImages
 
+WinterBoardSettings: Settings.mm makefile
+       $(target)g++ -dynamiclib -g0 -O2 -Wall -o $@ $(filter %.mm,$^) -framework UIKit -framework CoreFoundation -framework Foundation -lobjc -framework CoreGraphics -framework Preferences -F$(PKG_ROOT)/System/Library/PrivateFrameworks
+       ldid -S $@
+
 WinterBoard.dylib: Library.mm makefile ../mobilesubstrate/substrate.h
        $(target)g++ -dynamiclib -g0 -O2 -Wall -o $@ $(filter %.mm,$^) -framework CoreFoundation -framework Foundation -lobjc -init _WBInitialize -I/apl/inc/iPhoneOS-2.0 -framework CoreGraphics -framework GraphicsServices -framework Celestial -I../mobilesubstrate -L../mobilesubstrate -lsubstrate -framework UIKit -F$(PKG_ROOT)/System/Library/PrivateFrameworks
+       ldid -S $@
 
 UIImages: UIImages.mm makefile
        $(target)g++ -g0 -O2 -Wall -Werror -o $@ $(filter %.mm,$^) -framework UIKit -framework Foundation -framework CoreFoundation -lobjc -I/apl/inc/iPhoneOS-2.0
+       ldid -S $@
 
 WinterBoard: Application.mm makefile
-       $(target)g++ -g0 -O2 -Wall -Werror -o $@ $(filter %.mm,$^) -framework UIKit -framework Foundation -framework CoreFoundation -lobjc -framework CoreGraphics -I/apl/sdk
+       $(target)g++ -g0 -O2 -Wall -Werror -o $@ $(filter %.mm,$^) -framework UIKit -framework Foundation -framework CoreFoundation -lobjc -framework CoreGraphics -I/apl/sdk -framework Preferences -F$(PKG_ROOT)/System/Library/PrivateFrameworks
+       ldid -S $@
 
 package:
        rm -rf winterboard
@@ -24,10 +31,16 @@ package:
        mkdir -p winterboard/Applications/WinterBoard.app
        mkdir -p winterboard/Library/Themes
        mkdir -p winterboard/Library/MobileSubstrate/DynamicLibraries
+       mkdir -p winterboard/Library/PreferenceLoader/Preferences
+       mkdir -p winterboard/System/Library/PreferenceBundles
+       cp -a WinterBoardSettings.plist winterboard/Library/PreferenceLoader/Preferences
+       cp -a WinterBoardSettings.bundle winterboard/System/Library/PreferenceBundles
+       cp -a Icon-Small.png winterboard/System/Library/PreferenceBundles/WinterBoardSettings.bundle/icon.png
+       cp -a SearchResultsCheckmarkClear.png WinterBoardSettings winterboard/System/Library/PreferenceBundles/WinterBoardSettings.bundle
        ln -s /Applications/WinterBoard.app/WinterBoard.dylib winterboard/Library/MobileSubstrate/DynamicLibraries
        cp -a WinterBoard.plist winterboard/Library/MobileSubstrate/DynamicLibraries
        cp -a *.theme winterboard/Library/Themes
-       find winterboard/Library/Themes -name .svn | while read -r line; do rm -rf "$${line}"; done
+       find winterboard -name .svn | while read -r line; do rm -rf "$${line}"; done
        cp -a control preinst prerm winterboard/DEBIAN
        cp -a Test.sh Icon-Small.png icon.png WinterBoard.dylib WinterBoard UIImages Info.plist winterboard/Applications/WinterBoard.app
        dpkg-deb -b winterboard winterboard_$(shell grep ^Version: control | cut -d ' ' -f 2)_iphoneos-arm.deb