blob: be650e389eed7682976bab743ce8b884a555c124 [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 Lisionb9f3f942016-07-23 14:29:33 -040019#import <SystemConfiguration/SystemConfiguration.h>
Kateryna Kostiukd5aded72020-11-06 17:03:42 -050020#import <CoreFoundation/CoreFoundation.h>
21#import <IOKit/pwr_mgt/IOPMLib.h>
Alexandre Lisionb9f3f942016-07-23 14:29:33 -040022
Alexandre Lision5855b6a2015-02-03 11:31:05 -050023#import "AppDelegate.h"
24
Kateryna Kostiuke3503842018-12-12 16:39:45 -050025//lrc
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040026#import <api/lrc.h>
Kateryna Kostiuk23222fe2018-11-16 14:28:02 -050027#import <api/newaccountmodel.h>
Kateryna Kostiuke3503842018-12-12 16:39:45 -050028#import <api/behaviorcontroller.h>
29#import <api/conversation.h>
30#import <api/newcallmodel.h>
Kateryna Kostiukabf4e272017-04-18 14:18:00 -040031
Alexandre Lision745e4d62015-03-22 20:03:10 -040032
Alexandre Lision3d4143a2015-06-10 14:27:49 -040033#if ENABLE_SPARKLE
34#import <Sparkle/Sparkle.h>
35#endif
36
Alexandre Lisionc65310c2015-04-23 16:44:23 -040037#import "Constants.h"
Alexandre Lision745e4d62015-03-22 20:03:10 -040038#import "RingWizardWC.h"
Alexandre Lision62005312016-01-28 15:55:16 -050039#import "DialpadWC.h"
Kateryna Kostiuke3503842018-12-12 16:39:45 -050040#import "utils.h"
Alexandre Lision745e4d62015-03-22 20:03:10 -040041
Alexandre Lision3d4143a2015-06-10 14:27:49 -040042#if ENABLE_SPARKLE
43@interface AppDelegate() <SUUpdaterDelegate>
44#else
Alexandre Lision745e4d62015-03-22 20:03:10 -040045@interface AppDelegate()
Alexandre Lision3d4143a2015-06-10 14:27:49 -040046#endif
Alexandre Lision745e4d62015-03-22 20:03:10 -040047
48@property RingWindowController* ringWindowController;
49@property RingWizardWC* wizard;
Alexandre Lision62005312016-01-28 15:55:16 -050050@property DialpadWC* dialpad;
Alexandre Lisionb9f3f942016-07-23 14:29:33 -040051@property (nonatomic, strong) dispatch_queue_t scNetworkQueue;
52@property (nonatomic, assign) SCNetworkReachabilityRef currentReachability;
Adrien Béraud022b57a2018-09-15 15:49:07 -040053@property (strong) id activity;
Alexandre Lision745e4d62015-03-22 20:03:10 -040054
55@end
56
Kateryna Kostiuke3503842018-12-12 16:39:45 -050057NSString * const MESSAGE_NOTIFICATION = @"message_notification_type";
58NSString * const CALL_NOTIFICATION = @"call_notification_type";
59NSString * const CONTACT_REQUEST_NOTIFICATION = @"contact_request_notification_type";
60
61NSString * const ACCOUNT_ID = @"account_id_notification_info";
62NSString * const CALL_ID = @"call_id_notification_info";
63NSString * const CONVERSATION_ID = @"conversation_id_notification_info";
64NSString * const CONTACT_URI = @"contact_uri_notification_info";
65NSString * const NOTIFICATION_TYPE = @"contact_type_notification_info";
66
Kateryna Kostiukd5aded72020-11-06 17:03:42 -050067IOPMAssertionID assertionID = 0;
68BOOL sleepDisabled = false;
Kateryna Kostiuke3503842018-12-12 16:39:45 -050069
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040070@implementation AppDelegate {
Alexandre Lision5855b6a2015-02-03 11:31:05 -050071
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040072std::unique_ptr<lrc::api::Lrc> lrc;
73}
Andreas Traczyke4d6e782018-03-22 17:51:30 -040074
Alexandre Lision5855b6a2015-02-03 11:31:05 -050075- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
Kateryna Kostiuk0bc4c592018-06-05 13:35:19 -040076
77 // hide "Check for update" menu item when sparkle is disabled
78 NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
79 NSMenu *ringMenu = [[mainMenu itemAtIndex:0] submenu];
80 NSMenuItem *updateItem = [ringMenu itemAtIndex:1];
81#if ENABLE_SPARKLE
82 updateItem.hidden = false;
83#else
84 updateItem.hidden = true;
85#endif
86
Kateryna Kostiuk353ca3f2019-01-08 12:02:40 -050087#ifndef NDEBUG
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050088 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
Kateryna Kostiuk353ca3f2019-01-08 12:02:40 -050089#else
90 [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
91#endif
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050092
Alexandre Lisione4041492015-03-20 18:20:43 -040093 [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
94
Edric Milaret81315412015-05-13 15:14:56 -040095 NSAppleEventManager* appleEventManager = [NSAppleEventManager sharedAppleEventManager];
96 [appleEventManager setEventHandler:self andSelector:@selector(handleQuitEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
Kateryna Kostiuk85a334e2018-12-03 15:54:19 -050097
98 dispatch_queue_t queue = NULL;
99 queue = dispatch_queue_create("scNetworkReachability", DISPATCH_QUEUE_SERIAL);
100 [self setScNetworkQueue:queue];
101 [self beginObservingReachabilityStatus];
102 NSActivityOptions options = NSActivitySuddenTerminationDisabled | NSActivityAutomaticTerminationDisabled | NSActivityBackground;
103 self.activity = [[NSProcessInfo processInfo] beginActivityWithOptions:options reason:@"Receiving calls and messages"];
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400104 lrc = std::make_unique<lrc::api::Lrc>();
Alexandre Lision745e4d62015-03-22 20:03:10 -0400105 if([self checkForRingAccount]) {
Kateryna Kostiuk0c0801e2019-07-18 20:10:51 -0400106 [self setRingtonePath];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400107 [self showMainWindow];
108 } else {
109 [self showWizard];
110 }
Alexandre Lisione4041492015-03-20 18:20:43 -0400111 [self connect];
Alexandre Lisionb9f3f942016-07-23 14:29:33 -0400112}
113
114- (void) beginObservingReachabilityStatus
115{
116 SCNetworkReachabilityRef reachabilityRef = NULL;
117
118 void (^callbackBlock)(SCNetworkReachabilityFlags) = ^(SCNetworkReachabilityFlags flags) {
Kateryna Kostiuk9217e292019-08-13 13:22:45 -0400119 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
Kateryna Kostiuk44432012018-11-28 09:39:10 -0500120 lrc->connectivityChanged();
Kateryna Kostiuk9217e292019-08-13 13:22:45 -0400121 });
Alexandre Lisionb9f3f942016-07-23 14:29:33 -0400122 };
123
124 SCNetworkReachabilityContext context = {
125 .version = 0,
126 .info = (void *)CFBridgingRetain(callbackBlock),
127 .release = CFRelease
128 };
129
130 reachabilityRef = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, "test");
131 if (SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context)){
132 if (!SCNetworkReachabilitySetDispatchQueue(reachabilityRef, [self scNetworkQueue]) ){
133 // Remove our callback if we can't use the queue
134 SCNetworkReachabilitySetCallback(reachabilityRef, NULL, NULL);
135 }
136 [self setCurrentReachability:reachabilityRef];
137 }
138}
139
140- (void) endObsvervingReachabilityStatusForHost:(NSString *)__unused host
141{
142 // Un-set the dispatch queue
143 if (SCNetworkReachabilitySetDispatchQueue([self currentReachability], NULL) ){
144 SCNetworkReachabilitySetCallback([self currentReachability], NULL, NULL);
145 }
146}
147
Kateryna Kostiukd5aded72020-11-06 17:03:42 -0500148- (void) disableScreenSleep
149{
150 if (sleepDisabled) {
151 return;
152 }
153 CFStringRef reasonForActivity= CFSTR("Prevent display sleep during calls");
154 sleepDisabled = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &assertionID) == kIOReturnSuccess;
155}
156
157- (void) restoreScreenSleep {
158 auto calls = [self getActiveCalls];
159
160 if (!sleepDisabled || !calls.empty()) {
161 return;
162 }
163 IOPMAssertionRelease(assertionID);
164 sleepDisabled = false;
165}
166
Alexandre Lisionb9f3f942016-07-23 14:29:33 -0400167static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkConnectionFlags flags, void* info)
168{
169 void (^callbackBlock)(SCNetworkReachabilityFlags) = (__bridge id)info;
170 callbackBlock(flags);
Alexandre Lisione4041492015-03-20 18:20:43 -0400171}
172
173- (void) connect
174{
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500175 QObject::connect(&lrc->getBehaviorController(),
176 &lrc::api::BehaviorController::newTrustRequest,
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400177 [self] (const QString& accountId, const QString& contactUri) {
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400178 BOOL shouldNotify = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::ContactRequestNotifications];
179 if(!shouldNotify) {
180 return;
181 }
182 NSUserNotification* notification = [[NSUserNotification alloc] init];
183 auto contactModel = lrc->getAccountModel()
184 .getAccountInfo(accountId).contactModel.get();
185 NSString* name = contactModel->getContact(contactUri)
186 .registeredName.isEmpty() ?
187 contactUri.toNSString():
188 contactModel->getContact(contactUri).registeredName.toNSString();
189 NSString* localizedMessage =
190 NSLocalizedString(@"Send you a contact request",
191 @"Notification message");
Alexandre Lision0f66bd32016-01-18 11:30:45 -0500192
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400193 NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
194 userInfo[ACCOUNT_ID] = accountId.toNSString();
195 userInfo[CONTACT_URI] = contactUri.toNSString();
196 userInfo[NOTIFICATION_TYPE] = CONTACT_REQUEST_NOTIFICATION;
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500197
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400198 [notification setTitle: name];
199 notification.informativeText = localizedMessage;
200 [notification setSoundName:NSUserNotificationDefaultSoundName];
201 [notification setUserInfo: userInfo];
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500202
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400203 [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500204
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400205 });
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500206
207 QObject::connect(&lrc->getBehaviorController(),
208 &lrc::api::BehaviorController::showIncomingCallView,
Kateryna Kostiuka7b909c2020-10-19 11:46:26 -0400209 [self] (const QString& accountId,
210 const QString& convUid) {
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400211 BOOL shouldNotify = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::CallNotifications];
212 if(!shouldNotify) {
213 return;
214 }
Kateryna Kostiuka7b909c2020-10-19 11:46:26 -0400215 auto convModel = lrc->getAccountModel().getAccountInfo(accountId).conversationModel.get();
216 auto conversationOpt = getConversationFromUid(convUid, *convModel);
217 if (!conversationOpt.has_value()) { return; }
kkostiukf81c6372021-01-11 18:51:28 -0500218 lrc::api::conversation::Info& conversation = *conversationOpt;
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400219 bool isIncoming = false;
Kateryna Kostiuka7b909c2020-10-19 11:46:26 -0400220 auto callModel = lrc->getAccountModel().getAccountInfo(accountId).callModel.get();
221 if(callModel->hasCall(conversation.callId)) {
222 isIncoming = !callModel->getCall(conversation.callId).isOutgoing;
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400223 }
224 if(!isIncoming) {
225 return;
226 }
Kateryna Kostiuka7b909c2020-10-19 11:46:26 -0400227 NSString* name = bestIDForConversation(conversation, *lrc->getAccountModel().getAccountInfo(accountId).conversationModel.get());
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400228 NSUserNotification* notification = [[NSUserNotification alloc] init];
Alexandre Lision0f66bd32016-01-18 11:30:45 -0500229
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400230 NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
231 userInfo[ACCOUNT_ID] = accountId.toNSString();
Kateryna Kostiuka7b909c2020-10-19 11:46:26 -0400232 userInfo[CALL_ID] = conversation.callId.toNSString();
233 userInfo[CONVERSATION_ID] = conversation.uid.toNSString();
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400234 userInfo[NOTIFICATION_TYPE] = CALL_NOTIFICATION;
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500235
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400236 NSString* localizedTitle = [NSString stringWithFormat:
237 NSLocalizedString(@"Incoming call from %@", @"Incoming call from {Name}"),
238 name];
239 // try to activate action button
240 @try {
241 [notification setValue:@YES forKey:@"_showsButtons"];
242 }
243 @catch (NSException *exception) {
244 NSLog(@"Action button not activable on notification");
245 }
246 [notification setUserInfo: userInfo];
247 [notification setOtherButtonTitle:NSLocalizedString(@"Refuse", @"Button Action")];
248 [notification setActionButtonTitle:NSLocalizedString(@"Accept", @"Button Action")];
249 [notification setTitle:localizedTitle];
250 [notification setSoundName:NSUserNotificationDefaultSoundName];
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500251
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400252 [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
253 });
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500254
255 QObject::connect(&lrc->getBehaviorController(),
256 &lrc::api::BehaviorController::newUnreadInteraction,
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400257 [self] (const QString& accountId, const QString& conversation,
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500258 uint64_t interactionId, const lrc::api::interaction::Info& interaction) {
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400259 BOOL shouldNotify = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::MessagesNotifications];
260 if(!shouldNotify) {
261 return;
262 }
263 NSUserNotification* notification = [[NSUserNotification alloc] init];
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500264
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400265 NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
266 userInfo[ACCOUNT_ID] = accountId.toNSString();
267 userInfo[CONVERSATION_ID] = conversation.toNSString();
268 userInfo[NOTIFICATION_TYPE] = MESSAGE_NOTIFICATION;
269 NSString* name = interaction.authorUri.toNSString();
Kateryna Kostiuka7b909c2020-10-19 11:46:26 -0400270 auto convOpt = getConversationFromUid(conversation, *lrc->getAccountModel()
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400271 .getAccountInfo(accountId)
Kateryna Kostiuk3541ae22020-08-17 12:26:14 -0400272 .conversationModel.get());
Kateryna Kostiuka7b909c2020-10-19 11:46:26 -0400273 if (convOpt.has_value()) {
kkostiukf81c6372021-01-11 18:51:28 -0500274 lrc::api::conversation::Info& conversation = *convOpt;
Kateryna Kostiuka7b909c2020-10-19 11:46:26 -0400275 name = bestIDForConversation(conversation, *lrc->getAccountModel().getAccountInfo(accountId).conversationModel.get());
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400276 }
277 NSString* localizedTitle = [NSString stringWithFormat:
278 NSLocalizedString(@"Incoming message from %@",@"Incoming message from {Name}"),
279 name];
Alexandre Lision0f66bd32016-01-18 11:30:45 -0500280
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400281 [notification setTitle:localizedTitle];
282 [notification setSoundName:NSUserNotificationDefaultSoundName];
283 [notification setSubtitle:interaction.body.toNSString()];
284 [notification setUserInfo:userInfo];
Alexandre Lision0f66bd32016-01-18 11:30:45 -0500285
Kateryna Kostiuk146cb9e2020-08-11 14:29:26 -0400286 [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
287 });
Alexandre Lisione4041492015-03-20 18:20:43 -0400288}
289
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500290- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDismissAlert:(NSUserNotification *)alert {
291 // check if user click refuse on incoming call notifications
292 if(alert.activationType != NSUserNotificationActivationTypeNone) {
293 return;
Alexandre Lision34607032016-02-08 16:16:49 -0500294 }
Alexandre Lision34607032016-02-08 16:16:49 -0500295
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500296 auto info = alert.userInfo;
297 if(!info) {
298 return;
299 }
300 NSString* identifier = info[NOTIFICATION_TYPE];
301 NSString* callId = info[CALL_ID];
302 NSString* accountId = info[ACCOUNT_ID];
303 if(!identifier || !callId || !accountId) {
304 return;
305 }
306 if([identifier isEqualToString: CALL_NOTIFICATION]) {
307 auto accountInfo = &lrc->getAccountModel().getAccountInfo([accountId UTF8String]);
308 if (accountInfo == nil)
309 return;
310 auto* callModel = accountInfo->callModel.get();
311 callModel->hangUp([callId UTF8String]);
312 }
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500313}
314
Alexandre Lision34607032016-02-08 16:16:49 -0500315- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
316{
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500317 auto info = notification.userInfo;
318 if(!info) {
319 return;
320 }
321 NSString* identifier = info[NOTIFICATION_TYPE];
322 if([identifier isEqualToString: CALL_NOTIFICATION]) {
323 if(notification.activationType == NSUserNotificationActivationTypeActionButtonClicked
324 || notification.activationType == NSUserNotificationActivationTypeContentsClicked) {
325 NSString* callId = info[CALL_ID];
326 NSString* accountId = info[ACCOUNT_ID];
327 NSString *conversationId = info[CONVERSATION_ID];
328 auto accountInfo = &lrc->getAccountModel().getAccountInfo([accountId UTF8String]);
329 if (accountInfo == nil)
330 return;
331 auto* callModel = accountInfo->callModel.get();
332 callModel->accept([callId UTF8String]);
Alexandre Lision34607032016-02-08 16:16:49 -0500333 [self.ringWindowController.window deminiaturize:self];
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500334 [_ringWindowController showCall:callId forAccount:accountId forConversation:conversationId];
335 }
336 } else if(notification.activationType == NSUserNotificationActivationTypeContentsClicked) {
337 [self.ringWindowController.window deminiaturize:self];
338 if([identifier isEqualToString: MESSAGE_NOTIFICATION]) {
339 NSString* accountId = info[ACCOUNT_ID];
340 NSString *conversationId = info[CONVERSATION_ID];
341 [_ringWindowController showConversation:conversationId forAccount:accountId];
342 } else if([identifier isEqualToString: CONTACT_REQUEST_NOTIFICATION]) {
343 NSString* accountId = info[ACCOUNT_ID];
344 NSString *contactUri = info[CONTACT_URI];
345 [_ringWindowController showContactRequestFor:accountId contactUri: contactUri];
Alexandre Lision34607032016-02-08 16:16:49 -0500346 }
347 }
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500348 [[NSUserNotificationCenter defaultUserNotificationCenter] removeAllDeliveredNotifications];
Alexandre Lision34607032016-02-08 16:16:49 -0500349}
350
Alexandre Lision745e4d62015-03-22 20:03:10 -0400351- (void) showWizard
352{
Alexandre Lision745e4d62015-03-22 20:03:10 -0400353 if(self.wizard == nil) {
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400354 self.wizard = [[RingWizardWC alloc] initWithNibName:@"RingWizard" bundle: nil accountmodel: &lrc->getAccountModel()];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400355 }
Alexandre Lision76d59692016-01-20 18:06:05 -0500356 [self.wizard.window makeKeyAndOrderFront:self];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400357}
358
359- (void) showMainWindow
360{
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400361 if(self.ringWindowController == nil) {
Kateryna Kostiukf6317422018-09-27 17:08:20 -0400362 self.ringWindowController = [[RingWindowController alloc] initWithWindowNibName:@"RingWindow" bundle: nil accountModel:&lrc->getAccountModel() dataTransferModel:&lrc->getDataTransferModel() behaviourController:&lrc->getBehaviorController() avModel: &lrc->getAVModel()];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400363 }
Kateryna Kostiuk465cfbe2018-06-05 16:13:05 -0400364 [[NSApplication sharedApplication] removeWindowsItem:self.wizard.window];
Kateryna Kostiukb0db48e2019-01-10 16:03:55 -0500365 self.wizard = nil;
Alexandre Lision745e4d62015-03-22 20:03:10 -0400366 [self.ringWindowController.window makeKeyAndOrderFront:self];
367}
368
Alexandre Lision62005312016-01-28 15:55:16 -0500369- (void) showDialpad
370{
371 if (self.dialpad == nil) {
372 self.dialpad = [[DialpadWC alloc] initWithWindowNibName:@"Dialpad"];
373 }
374 [self.dialpad.window makeKeyAndOrderFront:self];
375}
376
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400377-(QVector<QString>) getActiveCalls {
Kateryna Kostiuk5d90c3b2019-07-18 12:03:52 -0400378 return lrc->activeCalls();
379}
Alexandre Lision62005312016-01-28 15:55:16 -0500380
Kateryna Kostiuk1705a5a2020-08-26 09:48:00 -0400381-(QVector<QString>)getConferenceSubcalls:(QString)confId {
382 return lrc->getConferenceSubcalls(confId);
383}
384
Kateryna Kostiuk0c0801e2019-07-18 20:10:51 -0400385-(void)setRingtonePath {
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400386 QStringList accounts = lrc->getAccountModel().getAccountList();
Kateryna Kostiuk0c0801e2019-07-18 20:10:51 -0400387 NSFileManager *fileManager = [NSFileManager defaultManager];
388 for (auto account: accounts) {
389 lrc::api::account::ConfProperties_t accountProperties = lrc->getAccountModel().getAccountConfig(account);
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400390 NSString *ringtonePath = accountProperties.Ringtone.ringtonePath.toNSString();
Kateryna Kostiuk0c0801e2019-07-18 20:10:51 -0400391 if (![fileManager fileExistsAtPath: ringtonePath]) {
392 accountProperties.Ringtone.ringtonePath = [defaultRingtonePath() UTF8String];
393 lrc->getAccountModel().setAccountConfig(account, accountProperties);
394 }
395 }
396}
397
Alexandre Lision745e4d62015-03-22 20:03:10 -0400398- (BOOL) checkForRingAccount
399{
Kateryna Kostiuk23222fe2018-11-16 14:28:02 -0500400 return !lrc->getAccountModel().getAccountList().empty();
Alexandre Lision745e4d62015-03-22 20:03:10 -0400401}
402
Alexandre Lision18e1fcd2015-08-04 14:38:42 -0400403-(void)applicationWillFinishLaunching:(NSNotification *)aNotification
404{
405 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
406 [appleEventManager setEventHandler:self
407 andSelector:@selector(handleGetURLEvent:withReplyEvent:)
408 forEventClass:kInternetEventClass andEventID:kAEGetURL];
409}
410
Alexandre Lision745e4d62015-03-22 20:03:10 -0400411- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
412{
413 if([self checkForRingAccount]) {
414 [self showMainWindow];
415 } else {
416 [self showWizard];
417 }
418 return YES;
419}
420
Edric Milaret81315412015-05-13 15:14:56 -0400421- (void)handleQuitEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
422{
Kateryna Kostiuk0c0344a2018-07-27 10:35:01 -0400423 [[NSApplication sharedApplication] terminate:self];
Edric Milaret81315412015-05-13 15:14:56 -0400424}
425
426-(void)applicationWillTerminate:(NSNotification *)notification
427{
Alexandre Lision76d59692016-01-20 18:06:05 -0500428 [self cleanExit];
429}
430
431- (void) cleanExit
432{
Adrien Béraud022b57a2018-09-15 15:49:07 -0400433 if (self.activity != nil) {
434 [[NSProcessInfo processInfo] endActivity:self.activity];
435 self.activity = nil;
Andreas Traczyke4d6e782018-03-22 17:51:30 -0400436 }
Alexandre Lision76d59692016-01-20 18:06:05 -0500437 [self.wizard close];
438 [self.ringWindowController close];
Kateryna Kostiuk26526f22019-08-13 13:20:21 -0400439 lrc.reset();
Edric Milaret81315412015-05-13 15:14:56 -0400440}
441
Alexandre Lision3d4143a2015-06-10 14:27:49 -0400442#if ENABLE_SPARKLE
443
Alexandre Lision76d59692016-01-20 18:06:05 -0500444#pragma mark - Sparkle delegate
Alexandre Lision3d4143a2015-06-10 14:27:49 -0400445
446- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update
447{
448 [NSApp activateIgnoringOtherApps:YES];
449}
450
451- (BOOL)updaterMayCheckForUpdates:(SUUpdater *)bundle
452{
453 return YES;
454}
455
456- (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater
457{
458 return YES;
459}
460
461- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error
462{
463 NSLog(@"Error:%@", error.localizedDescription);
464}
465
466#endif
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500467@end