blob: b8295a24629390b57d861c9efee11015f85f9f7c [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
Kateryna Kostiuke3503842018-12-12 16:39:45 -050021//lrc
Kateryna Kostiuk67735232018-05-10 15:05:32 -040022#import <api/datatransfermodel.h>
Kateryna Kostiuk6db52802019-08-12 17:56:38 -040023#import <api/avmodel.h>
kkostiuk3037dab2021-04-08 09:35:32 -040024#import <api/newaccountmodel.h>
Alexandre Lisione4041492015-03-20 18:20:43 -040025
Alexandre Lision3d4143a2015-06-10 14:27:49 -040026#if ENABLE_SPARKLE
27#import <Sparkle/Sparkle.h>
28#endif
29
Alexandre Lisionc65310c2015-04-23 16:44:23 -040030#import "Constants.h"
Kateryna Kostiuk4138db12018-06-08 15:52:18 -040031#import "utils.h"
Alexandre Lisionc65310c2015-04-23 16:44:23 -040032
Alexandre Lision261f1b92016-04-04 12:35:34 -040033@interface GeneralPrefsVC () {
Alexandre Lision261f1b92016-04-04 12:35:34 -040034 __unsafe_unretained IBOutlet NSButton* startUpButton;
35 __unsafe_unretained IBOutlet NSButton* toggleAutomaticUpdateCheck;
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -040036 __unsafe_unretained IBOutlet NSButton* alwaysRecording;
37 __unsafe_unretained IBOutlet NSButton* recordPreview;
Alexandre Lision261f1b92016-04-04 12:35:34 -040038 __unsafe_unretained IBOutlet NSPopUpButton* checkIntervalPopUp;
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -040039 __unsafe_unretained IBOutlet NSStackView* sparkleContainer;
Kateryna Kostiuk67735232018-05-10 15:05:32 -040040 __unsafe_unretained IBOutlet NSButton *downloadFolder;
Kateryna Kostiuk74fe20c2018-06-14 12:05:53 -040041 __unsafe_unretained IBOutlet NSTextField *downloadFolderLabel;
Kateryna Kostiuk6db52802019-08-12 17:56:38 -040042 __unsafe_unretained IBOutlet NSButton *recordingFolder;
43 __unsafe_unretained IBOutlet NSTextField *recordingFolderLabel;
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -040044 __unsafe_unretained IBOutlet NSStackView *generalStackView;
45 __unsafe_unretained IBOutlet NSStackView *conversationStackView;
46 __unsafe_unretained IBOutlet NSStackView *recordingFolderStackView;
47 __unsafe_unretained IBOutlet NSSlider *qualitySlider;
48 __unsafe_unretained IBOutlet NSTextField *qualityLabel;
Alexandre Lision261f1b92016-04-04 12:35:34 -040049}
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050050@end
51
Alexandre Lision4de68ce2015-04-24 18:22:49 -040052@implementation GeneralPrefsVC
Alexandre Lisione4041492015-03-20 18:20:43 -040053
Kateryna Kostiuk6db52802019-08-12 17:56:38 -040054@synthesize avModel;
kkostiuk3037dab2021-04-08 09:35:32 -040055@synthesize accountModel;
Kateryna Kostiuk67735232018-05-10 15:05:32 -040056
kkostiuke486b3c2021-03-30 11:12:32 -040057-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountModel:( lrc::api::NewAccountModel*) accountModel avModel: (lrc::api::AVModel*)avModel {
Kateryna Kostiuk67735232018-05-10 15:05:32 -040058 if (self = [self initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
59 {
kkostiuk3037dab2021-04-08 09:35:32 -040060 self.accountModel = accountModel;
Kateryna Kostiuk6db52802019-08-12 17:56:38 -040061 self.avModel = avModel;
Kateryna Kostiuk67735232018-05-10 15:05:32 -040062 }
63 return self;
64}
65
Alexandre Lisione4041492015-03-20 18:20:43 -040066- (void)loadView
67{
68 [super loadView];
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -040069 CGFloat heightToReduice = 0;
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +020070 [startUpButton setState:[self isLaunchAtStartup]];
Alexandre Lision3d4143a2015-06-10 14:27:49 -040071#if ENABLE_SPARKLE
72 [sparkleContainer setHidden:NO];
73 SUUpdater *updater = [SUUpdater sharedUpdater];
74 [toggleAutomaticUpdateCheck bind:@"value" toObject:updater withKeyPath:@"automaticallyChecksForUpdates" options:nil];
75
76 [checkIntervalPopUp bind:@"enabled" toObject:updater withKeyPath:@"automaticallyChecksForUpdates" options:nil];
77 [checkIntervalPopUp bind:@"selectedTag" toObject:updater withKeyPath:@"updateCheckInterval" options:nil];
78#else
79 [sparkleContainer setHidden:YES];
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -040080 heightToReduice += (sparkleContainer.frame.size.height + 25);
Alexandre Lision3d4143a2015-06-10 14:27:49 -040081#endif
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -040082 [alwaysRecording setState: avModel->getAlwaysRecord()];
83 [recordPreview setState: avModel->getRecordPreview()];
84 [qualitySlider setDoubleValue: avModel->getRecordQuality()];
85 [qualityLabel setIntValue:avModel->getRecordQuality()];
Kateryna Kostiuk74fe20c2018-06-14 12:05:53 -040086 if (appSandboxed()) {
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -040087 [recordingFolderStackView setHidden:YES];
88 [conversationStackView setHidden:YES];
89 heightToReduice += (downloadFolder.frame.size.height + recordingFolder.frame.size.height + 25);
90 } else {
kkostiuk3037dab2021-04-08 09:35:32 -040091 if (accountModel) {
92 downloadFolder.title = [self.accountModel->downloadDirectory.toNSString() lastPathComponent];
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -040093 }
94 if (avModel) {
95 auto name1 = avModel->getRecordPath();
Kateryna Kostiukc867eb92020-03-08 13:15:17 -040096 auto name = avModel->getRecordPath().toNSString();
97 recordingFolder.title = [avModel->getRecordPath().toNSString() lastPathComponent];
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -040098 }
Kateryna Kostiuk74fe20c2018-06-14 12:05:53 -040099 }
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -0400100 auto frame = self.view.frame;
101 frame.size.height -= heightToReduice;
102 self.view.frame = frame;
Alexandre Lisione4041492015-03-20 18:20:43 -0400103}
104
Kateryna Kostiuk67735232018-05-10 15:05:32 -0400105- (IBAction)changeDownloadFolder:(id)sender {
106
107 NSOpenPanel *panel = [NSOpenPanel openPanel];
108 [panel setAllowsMultipleSelection:NO];
109 [panel setCanChooseDirectories:YES];
110 [panel setCanChooseFiles:NO];
Kateryna Kostiuk4138db12018-06-08 15:52:18 -0400111 panel.delegate = self;
Kateryna Kostiuk67735232018-05-10 15:05:32 -0400112 if ([panel runModal] != NSFileHandlingPanelOKButton) return;
113 if ([[panel URLs] lastObject] == nil) return;
114 NSString * path = [[[[panel URLs] lastObject] path] stringByAppendingString:@"/"];
kkostiuk3037dab2021-04-08 09:35:32 -0400115 self.accountModel->downloadDirectory = QString::fromNSString(path);
116 downloadFolder.title = [self.accountModel->downloadDirectory.toNSString() lastPathComponent];
Kateryna Kostiuk67735232018-05-10 15:05:32 -0400117 [[NSUserDefaults standardUserDefaults] setObject:path forKey:Preferences::DownloadFolder];
118}
119
Kateryna Kostiuk6db52802019-08-12 17:56:38 -0400120- (IBAction)changeRecordingFolder:(id)sender {
121 NSOpenPanel *panel = [NSOpenPanel openPanel];
122 [panel setAllowsMultipleSelection:NO];
123 [panel setCanChooseDirectories:YES];
124 [panel setCanChooseFiles:NO];
125 panel.delegate = self;
126 if ([panel runModal] != NSFileHandlingPanelOKButton) return;
127 if ([[panel URLs] lastObject] == nil) return;
128 NSString * path = [[[[panel URLs] lastObject] path] stringByAppendingString:@"/"];
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400129 avModel->setRecordPath(QString::fromNSString(path));
130 recordingFolder.title = [avModel->getRecordPath().toNSString() lastPathComponent];
Kateryna Kostiuk6db52802019-08-12 17:56:38 -0400131 [[NSUserDefaults standardUserDefaults] setObject:path forKey:Preferences::DownloadFolder];
132}
133
Kateryna Kostiukbeb9bae2019-08-21 17:59:16 -0400134- (IBAction)alwaysRecording:(id)sender {
135 avModel->setAlwaysRecord([sender state]);
136}
137
138- (IBAction)recordPreview:(id)sender {
139 avModel->setRecordPreview([sender state]);
140}
141
142- (IBAction)setRecordingQuality:(NSSlider*)sender {
143 avModel->setRecordQuality([sender intValue]);
144}
145
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200146#pragma mark - Startup API
147
148// MIT license by Brian Dunagan
149- (BOOL)isLaunchAtStartup {
150 // See if the app is currently in LoginItems.
151 LSSharedFileListItemRef itemRef = [self itemRefInLoginItems];
152 // Store away that boolean.
153 BOOL isInList = itemRef != nil;
154 // Release the reference if it exists.
155 if (itemRef != nil) CFRelease(itemRef);
156
157 return isInList;
158}
159
160- (IBAction)toggleLaunchAtStartup:(id)sender {
161 // Toggle the state.
162 BOOL shouldBeToggled = ![self isLaunchAtStartup];
163 // Get the LoginItems list.
164 LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
165 if (loginItemsRef == nil) return;
166 if (shouldBeToggled) {
167 // Add the app to the LoginItems list.
Alexandre Lision81c97212015-06-17 15:51:53 -0400168 CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200169 LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
170 if (itemRef) CFRelease(itemRef);
171 }
172 else {
173 // Remove the app from the LoginItems list.
174 LSSharedFileListItemRef itemRef = [self itemRefInLoginItems];
175 LSSharedFileListItemRemove(loginItemsRef,itemRef);
176 if (itemRef != nil) CFRelease(itemRef);
177 }
178 CFRelease(loginItemsRef);
179}
180
181- (LSSharedFileListItemRef)itemRefInLoginItems {
182 LSSharedFileListItemRef itemRef = nil;
Alexandre Lision81c97212015-06-17 15:51:53 -0400183 CFURLRef itemUrl = nil;
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200184
185 // Get the app's URL.
Alexandre Lision81c97212015-06-17 15:51:53 -0400186 auto appUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200187 // Get the LoginItems list.
188 LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
189 if (loginItemsRef == nil) return nil;
190 // Iterate over the LoginItems.
Alexandre Lision81c97212015-06-17 15:51:53 -0400191 NSArray *loginItems = (__bridge_transfer NSArray *)LSSharedFileListCopySnapshot(loginItemsRef, nil);
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200192 for (int currentIndex = 0; currentIndex < [loginItems count]; currentIndex++) {
193 // Get the current LoginItem and resolve its URL.
Alexandre Lision81c97212015-06-17 15:51:53 -0400194 LSSharedFileListItemRef currentItemRef = (__bridge LSSharedFileListItemRef)[loginItems objectAtIndex:currentIndex];
195 if (LSSharedFileListItemResolve(currentItemRef, 0, &itemUrl, NULL) == noErr) {
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200196 // Compare the URLs for the current LoginItem and the app.
Alexandre Lision81c97212015-06-17 15:51:53 -0400197 if ([(__bridge NSURL *)itemUrl isEqual:appUrl]) {
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200198 // Save the LoginItem reference.
199 itemRef = currentItemRef;
200 }
201 }
202 }
203 // Retain the LoginItem reference.
204 if (itemRef != nil) CFRetain(itemRef);
205 // Release the LoginItems lists.
Alexandre Lision1ad5a2f2015-05-27 14:21:45 +0200206 CFRelease(loginItemsRef);
207
208 return itemRef;
209}
210
Kateryna Kostiuk4138db12018-06-08 15:52:18 -0400211#pragma mark - NSOpenSavePanelDelegate delegate methods
212
213- (BOOL) panel:(id)sender shouldEnableURL:(NSURL*)url {
Kateryna Kostiuk74fe20c2018-06-14 12:05:53 -0400214 return YES;
Kateryna Kostiuk4138db12018-06-08 15:52:18 -0400215}
216
Alexandre Lision4a7b95e2015-02-20 10:06:43 -0500217@end