Initial commit

This commit is contained in:
shiftcmdk
2019-07-28 18:48:02 +02:00
commit 7956264aa1
39 changed files with 2985 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
#import <Preferences/PSViewController.h>
#import "../Model/AAAlertInfo.h"
#import "AADeleteDelegate.h"
@interface AAAlertOverviewController : PSViewController
@property (nonatomic, retain) UITableView *tableView;
@property (nonatomic, retain) AAAlertInfo *alertInfo;
@property (nonatomic, retain) NSMutableDictionary<NSString *, NSString *> *appsDict;
@property (nonatomic, assign) id<AADeleteDelegate> deleteDelegate;
@end

View File

@@ -0,0 +1,324 @@
#import "AAAlertOverviewController.h"
@interface AAAlertOverviewController () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, retain) NSArray<NSString *> *visibleSections;
@property (nonatomic, retain) NSMutableArray<NSString *> *sortedBundleIDs;
@end
@interface UIImage ()
+(id)_applicationIconImageForBundleIdentifier:(id)arg1 format:(int)arg2 scale:(double)arg3;
@end
@implementation AAAlertOverviewController
extern "C" CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
-(void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"Alert Details";
UIBarButtonItem *trashItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemTrash
target:self
action:@selector(deleteAlert:)
] autorelease];
self.navigationItem.rightBarButtonItem = trashItem;
self.tableView = [[[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped] autorelease];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"TitleCell"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"MessageCell"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"ActionCell"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"SelectedActionCell"];
NSMutableArray *sections = [NSMutableArray array];
if (self.alertInfo.actions.count > 0) {
[sections addObject:@"Actions"];
}
if (self.alertInfo.customAppActions.count == 0) {
[sections addObject:@"SelectedAction"];
}
if (self.alertInfo.textFieldValues.count > 0) {
[sections addObject:@"TextFields"];
}
if (self.alertInfo.customAppActions.count > 0) {
[sections addObject:@"CustomAppActions"];
self.sortedBundleIDs = [NSMutableArray arrayWithArray:[[self.alertInfo.customAppActions allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
NSString *firstName;
if (self.appsDict[obj1]) {
firstName = self.appsDict[obj1];
} else {
firstName = obj1;
}
NSString *secondName;
if (self.appsDict[obj2]) {
secondName = self.appsDict[obj2];
} else {
secondName = obj2;
}
return [firstName compare:secondName options:NSCaseInsensitiveSearch];
}]];
}
self.visibleSections = sections;
}
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.tableView.frame = self.view.bounds;
}
-(void)postDeleteNotificationAndPopViewController {
CFNotificationCenterPostNotification(
CFNotificationCenterGetDistributedCenter(),
(CFStringRef)[NSString stringWithFormat:@"com.shiftcmdk.autoalerts.delete.%@", self.alertInfo.identifier],
NULL,
NULL,
YES
);
if (self.deleteDelegate) {
[self.deleteDelegate didDelete];
}
[self.navigationController popViewControllerAnimated:YES];
}
-(void)deleteAlert:(UIBarButtonItem *)sender {
UIAlertController *deleteAlert = [UIAlertController alertControllerWithTitle:@"Delete alert" message:@"Do you really want to delete this automated alert?" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
[self postDeleteNotificationAndPopViewController];
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[deleteAlert addAction:deleteAction];
[deleteAlert addAction:cancelAction];
[self presentViewController:deleteAlert animated:YES completion:nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2 + self.visibleSections.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section > 1) {
NSString *identifier = self.visibleSections[section - 2];
if ([identifier isEqual:@"Actions"]) {
return self.alertInfo.actions.count;
}
if ([identifier isEqual:@"SelectedAction"]) {
return 1;
}
if ([identifier isEqual:@"TextFields"]) {
return self.alertInfo.textFieldValues.count;
}
if ([identifier isEqual:@"CustomAppActions"]) {
return self.alertInfo.customAppActions.count;
}
return 0;
}
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if (indexPath.section == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:@"TitleCell" forIndexPath:indexPath];
cell.textLabel.text = self.alertInfo.title;
cell.textLabel.numberOfLines = 0;
} else if (indexPath.section == 1) {
cell = [tableView dequeueReusableCellWithIdentifier:@"MessageCell" forIndexPath:indexPath];
cell.textLabel.text = self.alertInfo.message;
cell.textLabel.numberOfLines = 0;
} else {
NSString *identifier = self.visibleSections[indexPath.section - 2];
if ([identifier isEqual:@"Actions"]) {
cell = [tableView dequeueReusableCellWithIdentifier:@"ActionCell" forIndexPath:indexPath];
cell.textLabel.text = self.alertInfo.actions[indexPath.row];
} else if ([identifier isEqual:@"SelectedAction"]) {
cell = [tableView dequeueReusableCellWithIdentifier:@"SelectedActionCell" forIndexPath:indexPath];
int selectedAction = self.alertInfo.selectedAction;
NSString *actionString;
if (selectedAction == 0) {
actionString = @"No Action";
} else if (selectedAction == 1) {
actionString = @"Dismiss";
} else {
actionString = self.alertInfo.actions[selectedAction - 2];
}
cell.textLabel.text = actionString;
} else if ([identifier isEqual:@"TextFields"]) {
cell = [tableView dequeueReusableCellWithIdentifier:@"TextFieldCell"];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"TextFieldCell"] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat:@"Text Field %i", (int)indexPath.row + 1];
cell.detailTextLabel.text = self.alertInfo.textFieldValues[indexPath.row];
} else if ([identifier isEqual:@"CustomAppActions"]) {
cell = [tableView dequeueReusableCellWithIdentifier:@"AppCell"];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"AppCell"] autorelease];
}
NSString *bundleID = self.sortedBundleIDs[indexPath.row];
UIImage *icon = [UIImage _applicationIconImageForBundleIdentifier:bundleID format:0 scale:[UIScreen mainScreen].scale];
cell.imageView.image = icon;
cell.textLabel.text = self.appsDict[bundleID] ? self.appsDict[bundleID] : bundleID;
int selectedAction = [self.alertInfo.customAppActions[bundleID] intValue];
NSString *actionString;
if (selectedAction == 0) {
actionString = @"No Action";
} else if (selectedAction == 1) {
actionString = @"Dismiss";
} else {
actionString = self.alertInfo.actions[selectedAction - 2];
}
cell.detailTextLabel.text = actionString;
} else {
cell = [[[UITableViewCell alloc] init] autorelease];
}
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
switch (section) {
case 0:
return @"Title";
case 1:
return @"Message";
default: {
NSString *identifier = self.visibleSections[section - 2];
if ([identifier isEqual:@"Actions"]) {
return @"Actions";
}
if ([identifier isEqual:@"SelectedAction"]) {
return @"Selected action";
}
if ([identifier isEqual:@"TextFields"]) {
return @"Text fields";
}
if ([identifier isEqual:@"CustomAppActions"]) {
return @"App specific settings";
}
return nil;
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return indexPath.section > 1 && [self.visibleSections[indexPath.section - 2] isEqual:@"CustomAppActions"];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSString *bundleID = self.sortedBundleIDs[indexPath.row];
[self.sortedBundleIDs removeObjectAtIndex:indexPath.row];
[self.alertInfo.customAppActions removeObjectForKey:bundleID];
if (self.alertInfo.customAppActions.count > 0) {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[NSString stringWithFormat:@"%@", self.alertInfo.title] forKey:@"title"];
[dict setObject:[NSString stringWithFormat:@"%@", self.alertInfo.message] forKey:@"message"];
[dict setObject:self.alertInfo.actions forKey:@"actions"];
[dict setObject:self.alertInfo.textFieldValues forKey:@"textfieldvalues"];
[dict setObject:[NSNumber numberWithInt:self.alertInfo.textFieldValues.count] forKey:@"textfieldcount"];
[dict setObject:[NSNumber numberWithInt:self.alertInfo.selectedAction] forKey:@"selectedaction"];
[dict setObject:self.alertInfo.customAppActions forKey:@"customappactions"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
NSString *jsonString = [[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] autorelease];
CFNotificationCenterPostNotification(
CFNotificationCenterGetDistributedCenter(),
(CFStringRef)[NSString stringWithFormat:@"com.shiftcmdk.autoalerts.save.%@ %@", self.alertInfo.bundleID, jsonString],
NULL,
NULL,
YES
);
} else {
[self postDeleteNotificationAndPopViewController];
}
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
-(void)dealloc {
[self.tableView removeFromSuperview];
self.tableView = nil;
self.alertInfo = nil;
self.visibleSections = nil;
self.appsDict = nil;
self.sortedBundleIDs = nil;
[super dealloc];
}
@end

View File

@@ -0,0 +1,11 @@
#import "../Model/AAAlertInfo.h"
@interface AAApp: NSObject
-(id)initWithBundleID:(NSString *)bundleID name:(NSString *)name infos:(NSMutableArray<AAAlertInfo *> *)infos;
@property (nonatomic, copy) NSString *bundleID;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) NSMutableArray<AAAlertInfo *> *infos;
@end

View File

@@ -0,0 +1,24 @@
#import "AAApp.h"
@implementation AAApp
-(id)initWithBundleID:(NSString *)bundleID name:(NSString *)name infos:(NSMutableArray<AAAlertInfo *> *)infos {
if (self = [super init]) {
self.bundleID = bundleID;
self.name = name;
self.infos = infos;
}
return self;
}
-(void)dealloc {
self.bundleID = nil;
self.name = nil;
self.infos = nil;
[super dealloc];
}
@end

View File

@@ -0,0 +1,12 @@
#import <Preferences/PSViewController.h>
#import "AAApp.h"
#import "AADeleteDelegate.h"
@interface AAAppOverviewController : PSViewController
@property (nonatomic, retain) UITableView *tableView;
@property (nonatomic, retain) AAApp *app;
@property (nonatomic, retain) NSMutableDictionary<NSString *, NSString *> *appsDict;
@property (nonatomic, assign) id<AADeleteDelegate> deleteDelegate;
@end

View File

@@ -0,0 +1,160 @@
#import "AAAppOverviewController.h"
#import "AAAlertOverviewController.h"
#import "AADeleteDelegate.h"
@interface AAAppOverviewController () <UITableViewDelegate, UITableViewDataSource, AADeleteDelegate>
@property (nonatomic, assign) BOOL shouldDelete;
@property (nonatomic, retain) NSIndexPath *selectedIndexPath;
@end
@implementation AAAppOverviewController
extern "C" CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
-(void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = self.app.name;
self.tableView = [[[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped] autorelease];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
self.shouldDelete = NO;
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.shouldDelete && self.selectedIndexPath) {
if (self.app.infos.count == 1) {
[self.app.infos removeObjectAtIndex:self.selectedIndexPath.row];
if (self.deleteDelegate) {
[self.deleteDelegate didDelete];
}
[self.navigationController popViewControllerAnimated:YES];
} else {
[self.app.infos removeObjectAtIndex:self.selectedIndexPath.row];
[self.tableView deleteRowsAtIndexPaths:@[self.selectedIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
self.shouldDelete = NO;
self.selectedIndexPath = nil;
}
}
}
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.tableView.frame = self.view.bounds;
}
-(void)didDelete {
self.shouldDelete = YES;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.app.infos.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AlertOverviewCell"];
AAAlertInfo *info = [self.app.infos objectAtIndex:indexPath.row];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"AlertOverviewCell"] autorelease];
}
cell.textLabel.text = info.title;
cell.detailTextLabel.text = info.message;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
return @"Automated alerts";
}
return nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedIndexPath = indexPath;
AAAlertOverviewController *ctrl = [[[AAAlertOverviewController alloc] init] autorelease];
ctrl.alertInfo = [self.app.infos objectAtIndex:indexPath.row];
ctrl.appsDict = self.appsDict;
ctrl.deleteDelegate = self;
[self.navigationController pushViewController:ctrl animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
UIAlertController *deleteAlert = [UIAlertController alertControllerWithTitle:@"Delete alert" message:@"Do you really want to delete this automated alert?" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
CFNotificationCenterPostNotification(
CFNotificationCenterGetDistributedCenter(),
(CFStringRef)[NSString stringWithFormat:@"com.shiftcmdk.autoalerts.delete.%@", self.app.infos[indexPath.row].identifier],
NULL,
NULL,
YES
);
[self.app.infos removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
if (self.deleteDelegate && self.app.infos.count == 0) {
[self.deleteDelegate didDelete];
[self.navigationController popViewControllerAnimated:YES];
}
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[deleteAlert addAction:deleteAction];
[deleteAlert addAction:cancelAction];
[self presentViewController:deleteAlert animated:YES completion:nil];
}
}
-(void)dealloc {
[self.tableView removeFromSuperview];
self.tableView = nil;
self.app = nil;
self.appsDict = nil;
self.selectedIndexPath = nil;
[super dealloc];
}
@end

View File

@@ -0,0 +1,5 @@
@protocol AADeleteDelegate <NSObject>
-(void)didDelete;
@end

View File

@@ -0,0 +1,7 @@
#import <Preferences/PSViewController.h>
@interface AARootListController : PSViewController
@property (nonatomic, retain) UITableView *tableView;
@end

View File

@@ -0,0 +1,295 @@
#include "AARootListController.h"
#import "../AAAlertManager.h"
#import "AAApp.h"
#import "AAAppOverviewController.h"
@interface LSApplicationProxy: NSObject
@property (nonatomic,readonly) NSString * bundleIdentifier;
-(id)localizedName;
@property (nonatomic,readonly) NSString * primaryIconName;
@property (setter=_setInfoDictionary:,nonatomic,copy) id _infoDictionary;
@end
@interface LSApplicationWorkspace : NSObject
+(id)defaultWorkspace;
-(id)allInstalledApplications;
-(id)allApplications;
@end
@interface UIImage ()
+(id)_applicationIconImageForBundleIdentifier:(id)arg1 format:(int)arg2 scale:(double)arg3;
@end
@interface AARootListController () <UITableViewDelegate, UITableViewDataSource, AADeleteDelegate>
@property (nonatomic, retain) NSMutableArray<AAApp *> *apps;
@property (nonatomic, retain) NSMutableDictionary<NSString *, NSString *> *appsDict;
@property (nonatomic, assign) BOOL shouldDelete;
@property (nonatomic, retain) NSIndexPath *selectedIndexPath;
@end
@implementation AARootListController
extern "C" CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
-(id)init {
if (self = [super init]) {
self.navigationItem.title = @"AutoAlerts";
[[AAAlertManager sharedManager] initialize];
}
return self;
}
-(void)viewDidLoad {
[super viewDidLoad];
self.tableView = [[[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped] autorelease];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"AppCell"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"EnabledCell"];
self.navigationItem.title = @"AutoAlerts";
self.apps = [NSMutableArray array];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSArray<LSApplicationProxy *> *apps = [[%c(LSApplicationWorkspace) defaultWorkspace] allApplications];
NSMutableDictionary<NSString *, NSString *> *theAppsDict = [NSMutableDictionary dictionary];
for (LSApplicationProxy *app in apps) {
theAppsDict[app.bundleIdentifier] = [app localizedName];
}
NSArray<AAAlertInfo *> *allAlerts = [[AAAlertManager sharedManager] allAlerts];
NSMutableDictionary<NSString *, NSMutableArray *> *alertsDict = [NSMutableDictionary dictionary];
for (AAAlertInfo *info in allAlerts) {
NSMutableArray *arr = alertsDict[info.bundleID];
if (arr) {
[arr addObject:info];
} else {
alertsDict[info.bundleID] = [NSMutableArray arrayWithObject:info];
}
}
NSMutableArray<AAApp *> *appEntries = [NSMutableArray array];
for (NSString *key in alertsDict) {
NSString *name;
if (theAppsDict[key] && theAppsDict[key].length > 0) {
name = theAppsDict[key];
} else if ([key isEqual:@"com.apple.springboard"]) {
name = @"SpringBoard";
} else {
name = key;
}
NSSortDescriptor *titleSort = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES];
NSSortDescriptor *messageSort = [NSSortDescriptor sortDescriptorWithKey:@"message" ascending:YES];
NSMutableArray *sortedInfos = [NSMutableArray arrayWithArray:[alertsDict[key] sortedArrayUsingDescriptors:@[titleSort, messageSort]]];
AAApp *app = [[[AAApp alloc] initWithBundleID:key name:name infos:sortedInfos] autorelease];
[appEntries addObject:app];
}
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
NSMutableArray *tempApps = [NSMutableArray arrayWithArray:[appEntries sortedArrayUsingDescriptors:@[sort]]];
NSMutableArray *indexPaths = [NSMutableArray array];
for (int i = 0; i < tempApps.count; i++) {
[indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:1]];
}
dispatch_async(dispatch_get_main_queue(), ^{
self.apps = tempApps;
self.appsDict = theAppsDict;
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
});
});
self.shouldDelete = NO;
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.shouldDelete && self.selectedIndexPath) {
[self.apps removeObjectAtIndex:self.selectedIndexPath.row];
[self.tableView deleteRowsAtIndexPaths:@[self.selectedIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
self.shouldDelete = NO;
self.selectedIndexPath = nil;
}
}
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.tableView.frame = self.view.bounds;
}
-(void)didDelete {
self.shouldDelete = YES;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return 1;
}
return self.apps.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"EnabledCell" forIndexPath:indexPath];
cell.textLabel.text = @"Enabled";
UISwitch *switchView = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
[switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
NSUserDefaults *defaults = [[[NSUserDefaults alloc] initWithSuiteName:@"com.shiftcmdk.autoalertspreferences"] autorelease];
switchView.on = [defaults objectForKey:@"enabled"] == nil || [defaults boolForKey:@"enabled"];
cell.accessoryView = switchView;
return cell;
} else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AppCell" forIndexPath:indexPath];
AAApp *app = [self.apps objectAtIndex:indexPath.row];
UIImage *icon = [UIImage _applicationIconImageForBundleIdentifier:app.bundleID format:0 scale:[UIScreen mainScreen].scale];
cell.imageView.image = icon;
cell.textLabel.text = app.name;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedIndexPath = indexPath;
AAAppOverviewController *ctrl = [[[AAAppOverviewController alloc] init] autorelease];
ctrl.app = [self.apps objectAtIndex:indexPath.row];
ctrl.appsDict = self.appsDict;
ctrl.deleteDelegate = self;
[self pushController:ctrl animate:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
return @"General";
}
if (section == 1) {
return @"Apps";
}
return nil;
}
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
if (section == 0) {
return @"Apps may need to be restarted after enabling or disabling this option.";
}
if (section == 1) {
return @"Apps with automated alerts will appear here.";
}
return nil;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return indexPath.section == 1;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
UIAlertController *deleteAlert = [UIAlertController alertControllerWithTitle:@"Delete alerts" message:[NSString stringWithFormat:@"Do you really want to delete all automated alerts for %@?", self.apps[indexPath.row].name] preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
CFNotificationCenterPostNotification(
CFNotificationCenterGetDistributedCenter(),
(CFStringRef)[NSString stringWithFormat:@"com.shiftcmdk.autoalerts.deletewithbundleid.%@", self.apps[indexPath.row].bundleID],
NULL,
NULL,
YES
);
[self.apps removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[deleteAlert addAction:deleteAction];
[deleteAlert addAction:cancelAction];
[self presentViewController:deleteAlert animated:YES completion:nil];
}
}
-(void)switchChanged:(UISwitch *)sender {
NSUserDefaults *defaults = [[[NSUserDefaults alloc] initWithSuiteName:@"com.shiftcmdk.autoalertspreferences"] autorelease];
[defaults setBool:sender.isOn forKey:@"enabled"];
CFNotificationCenterPostNotification(
CFNotificationCenterGetDistributedCenter(),
(CFStringRef)@"com.shiftcmdk.autoalerts.toggle",
NULL,
NULL,
YES
);
}
-(void)dealloc {
[self.tableView removeFromSuperview];
self.tableView = nil;
self.apps = nil;
self.appsDict = nil;
self.selectedIndexPath = nil;
[super dealloc];
}
@end

View File

@@ -0,0 +1,13 @@
include $(THEOS)/makefiles/common.mk
BUNDLE_NAME = AutoAlertsPreferences
AutoAlertsPreferences_FILES = AARootListController.xm ../Model/AAAlertInfo.m ../AAAlertManager.m ../AACoreDataStack.m AAApp.m AAAppOverviewController.xm AAAlertOverviewController.xm
AutoAlertsPreferences_INSTALL_PATH = /Library/PreferenceBundles
AutoAlertsPreferences_FRAMEWORKS = UIKit
AutoAlertsPreferences_PRIVATE_FRAMEWORKS = Preferences
include $(THEOS_MAKE_PATH)/bundle.mk
internal-stage::
$(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END)
$(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/AutoAlertsPreferences.plist$(ECHO_END)

View File

@@ -0,0 +1,24 @@
<?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>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>AutoAlertsPreferences</string>
<key>CFBundleIdentifier</key>
<string>com.shiftcmdk.autoalertspreferences</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSPrincipalClass</key>
<string>AARootListController</string>
</dict>
</plist>

View File

@@ -0,0 +1,17 @@
<?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>items</key>
<array>
<dict>
<key>cell</key>
<string>PSGroupCell</string>
<key>label</key>
<string>AutoAlerts</string>
</dict>
</array>
<key>title</key>
<string>AutoAlerts</string>
</dict>
</plist>

View File

@@ -0,0 +1,21 @@
<?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>AutoAlertsPreferences</string>
<key>cell</key>
<string>PSLinkCell</string>
<key>detail</key>
<string>AARootListController</string>
<key>icon</key>
<string>icon.png</string>
<key>isController</key>
<true/>
<key>label</key>
<string>AutoAlerts</string>
</dict>
</dict>
</plist>