blob: 0e7e51f0b348d383f640d24da7c60f2ae18c794d [file] [log] [blame]
Alexandre Lision8521baa2015-03-13 11:08:00 -04001/*
Alexandre Lision9fe374b2016-01-06 10:17:31 -05002 * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
Alexandre Lision8521baa2015-03-13 11:08:00 -04003 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Alexandre Lision8521baa2015-03-13 11:08:00 -040018 */
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050019#import "GeneralPrefsVC.h"
20
Alexandre Lisione4041492015-03-20 18:20:43 -040021#import <categorizedhistorymodel.h>
22
Alexandre Lision3d4143a2015-06-10 14:27:49 -040023#if ENABLE_SPARKLE
24#import <Sparkle/Sparkle.h>
25#endif
26
Alexandre Lisionc65310c2015-04-23 16:44:23 -040027#import "Constants.h"
28
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050029@interface GeneralPrefsVC ()
Alexandre Lisionaa03df42016-01-26 09:39:25 -050030@property (unsafe_unretained) IBOutlet NSTextField* historyChangedLabel;
31@property (unsafe_unretained) IBOutlet NSButton* startUpButton;
32@property (unsafe_unretained) IBOutlet NSButton* toggleAutomaticUpdateCheck;
33@property (unsafe_unretained) IBOutlet NSPopUpButton* checkIntervalPopUp;
34@property (unsafe_unretained) IBOutlet NSView* sparkleContainer;
35@property (unsafe_unretained) IBOutlet NSTextField* historyTextField;
36@property (unsafe_unretained) IBOutlet NSStepper* historyStepper;
37@property (unsafe_unretained) IBOutlet NSButton* historySwitch;
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050038
39@end
40
Alexandre Lision4de68ce2015-04-24 18:22:49 -040041@implementation GeneralPrefsVC
Alexandre Lisione4041492015-03-20 18:20:43 -040042@synthesize historyChangedLabel;
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +020043@synthesize startUpButton;
Alexandre Lision3d4143a2015-06-10 14:27:49 -040044@synthesize toggleAutomaticUpdateCheck;
45@synthesize checkIntervalPopUp;
46@synthesize sparkleContainer;
Alexandre Lisionaa03df42016-01-26 09:39:25 -050047@synthesize historyTextField;
48@synthesize historyStepper;
49@synthesize historySwitch;
Alexandre Lisione4041492015-03-20 18:20:43 -040050
51- (void)loadView
52{
53 [super loadView];
Alexandre Lisionc65310c2015-04-23 16:44:23 -040054 [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:Preferences::HistoryLimit options:NSKeyValueObservingOptionNew context:NULL];
Alexandre Lision4de68ce2015-04-24 18:22:49 -040055
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +020056 [startUpButton setState:[self isLaunchAtStartup]];
57
Alexandre Lisionaa03df42016-01-26 09:39:25 -050058 int historyLimit = CategorizedHistoryModel::instance().historyLimit();
59 [historyTextField setStringValue:[NSString stringWithFormat:@"%d", historyLimit]];
60 [historyStepper setIntValue:historyLimit];
61
62 BOOL limited = CategorizedHistoryModel::instance().isHistoryLimited();
63 [historySwitch setState:limited];
64 [historyStepper setEnabled:limited];
65 [historyTextField setEnabled:limited];
Alexandre Lision3d4143a2015-06-10 14:27:49 -040066#if ENABLE_SPARKLE
67 [sparkleContainer setHidden:NO];
68 SUUpdater *updater = [SUUpdater sharedUpdater];
69 [toggleAutomaticUpdateCheck bind:@"value" toObject:updater withKeyPath:@"automaticallyChecksForUpdates" options:nil];
70
71 [checkIntervalPopUp bind:@"enabled" toObject:updater withKeyPath:@"automaticallyChecksForUpdates" options:nil];
72 [checkIntervalPopUp bind:@"selectedTag" toObject:updater withKeyPath:@"updateCheckInterval" options:nil];
73#else
74 [sparkleContainer setHidden:YES];
75#endif
76
Alexandre Lisione4041492015-03-20 18:20:43 -040077}
78
Alexandre Lision81c97212015-06-17 15:51:53 -040079- (void) dealloc
80{
81 [[NSUserDefaults standardUserDefaults] removeObserver:self forKeyPath:Preferences::HistoryLimit];
Alexandre Lision81c97212015-06-17 15:51:53 -040082}
83
Alexandre Lisione4041492015-03-20 18:20:43 -040084- (IBAction)clearHistory:(id)sender {
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040085 CategorizedHistoryModel::instance().clearAllCollections();
Alexandre Lisione4041492015-03-20 18:20:43 -040086 [historyChangedLabel setHidden:NO];
87}
88
Alexandre Lisionaa03df42016-01-26 09:39:25 -050089- (IBAction)toggleHistory:(id)sender {
90 CategorizedHistoryModel::instance().setHistoryLimited([sender state]);
91 int historyLimit = CategorizedHistoryModel::instance().historyLimit();
92 [historyTextField setStringValue:[NSString stringWithFormat:@"%d", historyLimit]];
93 [historyStepper setIntValue:historyLimit];
94 [historyChangedLabel setHidden:NO];
95 [historyStepper setEnabled:[sender state]];
96 [historyTextField setEnabled:[sender state]];
97}
98
Alexandre Lisione4041492015-03-20 18:20:43 -040099// KVO handler
100-(void)observeValueForKeyPath:(NSString *)aKeyPath ofObject:(id)anObject
101 change:(NSDictionary *)aChange context:(void *)aContext
102{
Alexandre Lisionaa03df42016-01-26 09:39:25 -0500103 if ([aKeyPath isEqualToString:Preferences::HistoryLimit]) {
104 CategorizedHistoryModel::instance().setHistoryLimit([[aChange objectForKey: NSKeyValueChangeNewKey] integerValue]);
Alexandre Lision4de68ce2015-04-24 18:22:49 -0400105 [historyChangedLabel setHidden:NO];
Alexandre Lision4de68ce2015-04-24 18:22:49 -0400106 }
Alexandre Lisione4041492015-03-20 18:20:43 -0400107}
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500108
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200109#pragma mark - Startup API
110
111// MIT license by Brian Dunagan
112- (BOOL)isLaunchAtStartup {
113 // See if the app is currently in LoginItems.
114 LSSharedFileListItemRef itemRef = [self itemRefInLoginItems];
115 // Store away that boolean.
116 BOOL isInList = itemRef != nil;
117 // Release the reference if it exists.
118 if (itemRef != nil) CFRelease(itemRef);
119
120 return isInList;
121}
122
123- (IBAction)toggleLaunchAtStartup:(id)sender {
124 // Toggle the state.
125 BOOL shouldBeToggled = ![self isLaunchAtStartup];
126 // Get the LoginItems list.
127 LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
128 if (loginItemsRef == nil) return;
129 if (shouldBeToggled) {
130 // Add the app to the LoginItems list.
Alexandre Lision81c97212015-06-17 15:51:53 -0400131 CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200132 LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
133 if (itemRef) CFRelease(itemRef);
134 }
135 else {
136 // Remove the app from the LoginItems list.
137 LSSharedFileListItemRef itemRef = [self itemRefInLoginItems];
138 LSSharedFileListItemRemove(loginItemsRef,itemRef);
139 if (itemRef != nil) CFRelease(itemRef);
140 }
141 CFRelease(loginItemsRef);
142}
143
144- (LSSharedFileListItemRef)itemRefInLoginItems {
145 LSSharedFileListItemRef itemRef = nil;
Alexandre Lision81c97212015-06-17 15:51:53 -0400146 CFURLRef itemUrl = nil;
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200147
148 // Get the app's URL.
Alexandre Lision81c97212015-06-17 15:51:53 -0400149 auto appUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200150 // Get the LoginItems list.
151 LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
152 if (loginItemsRef == nil) return nil;
153 // Iterate over the LoginItems.
Alexandre Lision81c97212015-06-17 15:51:53 -0400154 NSArray *loginItems = (__bridge_transfer NSArray *)LSSharedFileListCopySnapshot(loginItemsRef, nil);
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200155 for (int currentIndex = 0; currentIndex < [loginItems count]; currentIndex++) {
156 // Get the current LoginItem and resolve its URL.
Alexandre Lision81c97212015-06-17 15:51:53 -0400157 LSSharedFileListItemRef currentItemRef = (__bridge LSSharedFileListItemRef)[loginItems objectAtIndex:currentIndex];
158 if (LSSharedFileListItemResolve(currentItemRef, 0, &itemUrl, NULL) == noErr) {
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200159 // Compare the URLs for the current LoginItem and the app.
Alexandre Lision81c97212015-06-17 15:51:53 -0400160 if ([(__bridge NSURL *)itemUrl isEqual:appUrl]) {
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200161 // Save the LoginItem reference.
162 itemRef = currentItemRef;
163 }
164 }
165 }
166 // Retain the LoginItem reference.
167 if (itemRef != nil) CFRetain(itemRef);
168 // Release the LoginItems lists.
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200169 CFRelease(loginItemsRef);
170
171 return itemRef;
172}
173
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500174@end