blob: a20c063b38aa5e14df5bcb2016624879fe8258f1 [file] [log] [blame]
Alexandre Lision8521baa2015-03-13 11:08:00 -04001/*
Alexandre Lision61d78a42015-10-06 11:22:47 -04002 * Copyright (C) 2015 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 Lision5855b6a2015-02-03 11:31:05 -050019#import "AppDelegate.h"
20
Alexandre Lisione4041492015-03-20 18:20:43 -040021#import <callmodel.h>
Edric Milaret81315412015-05-13 15:14:56 -040022#import <qapplication.h>
Alexandre Lision745e4d62015-03-22 20:03:10 -040023#import <accountmodel.h>
24#import <protocolmodel.h>
25#import <QItemSelectionModel>
26#import <account.h>
27
Alexandre Lision3d4143a2015-06-10 14:27:49 -040028#if ENABLE_SPARKLE
29#import <Sparkle/Sparkle.h>
30#endif
31
Alexandre Lisionc65310c2015-04-23 16:44:23 -040032#import "Constants.h"
Alexandre Lision745e4d62015-03-22 20:03:10 -040033#import "RingWizardWC.h"
34
Alexandre Lision3d4143a2015-06-10 14:27:49 -040035#if ENABLE_SPARKLE
36@interface AppDelegate() <SUUpdaterDelegate>
37#else
Alexandre Lision745e4d62015-03-22 20:03:10 -040038@interface AppDelegate()
Alexandre Lision3d4143a2015-06-10 14:27:49 -040039#endif
Alexandre Lision745e4d62015-03-22 20:03:10 -040040
41@property RingWindowController* ringWindowController;
42@property RingWizardWC* wizard;
43
44@end
45
Alexandre Lision5855b6a2015-02-03 11:31:05 -050046@implementation AppDelegate
47
48- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050049 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
50
Alexandre Lisione4041492015-03-20 18:20:43 -040051 [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
52
Edric Milaret81315412015-05-13 15:14:56 -040053 NSAppleEventManager* appleEventManager = [NSAppleEventManager sharedAppleEventManager];
54 [appleEventManager setEventHandler:self andSelector:@selector(handleQuitEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
55
Alexandre Lision745e4d62015-03-22 20:03:10 -040056 if([self checkForRingAccount]) {
57 [self showMainWindow];
58 } else {
59 [self showWizard];
60 }
Alexandre Lisione4041492015-03-20 18:20:43 -040061 [self connect];
62}
63
64- (void) connect
65{
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040066 QObject::connect(&CallModel::instance(),
Alexandre Lisione4041492015-03-20 18:20:43 -040067 &CallModel::incomingCall,
68 [=](Call* call) {
Alexandre Lisionc65310c2015-04-23 16:44:23 -040069 BOOL shouldComeToForeground = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::WindowBehaviour];
70 BOOL shouldNotify = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::Notifications];
Alexandre Lision61d78a42015-10-06 11:22:47 -040071 if (shouldComeToForeground) {
Alexandre Lisione4041492015-03-20 18:20:43 -040072 [NSApp activateIgnoringOtherApps:YES];
Alexandre Lision61d78a42015-10-06 11:22:47 -040073 if ([self.ringWindowController.window isMiniaturized]) {
74 [self.ringWindowController.window deminiaturize:self];
75 }
76 }
Alexandre Lisione4041492015-03-20 18:20:43 -040077
78 if(shouldNotify) {
79 [self showIncomingNotification:call];
80 }
81 });
82}
83
84- (void) showIncomingNotification:(Call*) call{
85 NSUserNotification *notification = [[NSUserNotification alloc] init];
86 notification.title = @"Incoming call", call->peerName();
87 //notification.informativeText = @"A notification";
88 notification.soundName = NSUserNotificationDefaultSoundName;
89
90 [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
Alexandre Lision5855b6a2015-02-03 11:31:05 -050091}
92
Alexandre Lision745e4d62015-03-22 20:03:10 -040093/**
94 * click in MainMenu "Setup Ring"
95 */
96- (IBAction)showWizard:(id)sender {
97 [self showWizard];
98}
99
100- (void) showWizard
101{
102 NSLog(@"Showing wizard");
103 if(self.wizard == nil) {
104 self.wizard = [[RingWizardWC alloc] initWithWindowNibName:@"RingWizard"];
105 }
106 [self.wizard.window orderFront:self];
107}
108
109- (void) showMainWindow
110{
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400111 if(self.ringWindowController == nil) {
Alexandre Lision745e4d62015-03-22 20:03:10 -0400112 self.ringWindowController = [[RingWindowController alloc] initWithWindowNibName:@"RingWindow"];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400113 }
114
115 self.wizard = nil;
Alexandre Lision745e4d62015-03-22 20:03:10 -0400116
117 [self.ringWindowController.window makeKeyAndOrderFront:self];
118}
119
120- (BOOL) checkForRingAccount
121{
Alexandre Lisiona1f07bf2015-07-28 10:30:55 -0400122 BOOL foundRingAcc = NO;
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400123 for (int i = 0 ; i < AccountModel::instance().rowCount() ; ++i) {
124 QModelIndex idx = AccountModel::instance().index(i);
125 Account* acc = AccountModel::instance().getAccountByModelIndex(idx);
Alexandre Lision745e4d62015-03-22 20:03:10 -0400126 if(acc->protocol() == Account::Protocol::RING) {
Alexandre Lisiona1f07bf2015-07-28 10:30:55 -0400127 if (acc->displayName().isEmpty())
128 acc->setDisplayName(acc->alias());
129 foundRingAcc = YES;
Alexandre Lision745e4d62015-03-22 20:03:10 -0400130 }
131 }
Alexandre Lisiona1f07bf2015-07-28 10:30:55 -0400132 return foundRingAcc;
Alexandre Lision745e4d62015-03-22 20:03:10 -0400133}
134
Alexandre Lision18e1fcd2015-08-04 14:38:42 -0400135-(void)applicationWillFinishLaunching:(NSNotification *)aNotification
136{
137 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
138 [appleEventManager setEventHandler:self
139 andSelector:@selector(handleGetURLEvent:withReplyEvent:)
140 forEventClass:kInternetEventClass andEventID:kAEGetURL];
141}
142
143/**
144 * Recognized patterns:
145 * - ring:<hash>
146 * - ring://<hash>
147 */
148- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
149{
150 NSString* query = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
151 NSURL* url = [[NSURL alloc] initWithString:query];
152 NSString* ringID = [url host];
153 if (!ringID) {
154 //not a valid NSURL, try to parse query directly
155 ringID = [query substringFromIndex:@"ring:".length];
156 }
157
158 // check for a valid ring hash
159 NSCharacterSet *hexSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789abcdefABCDEF"];
160 BOOL valid = [[ringID stringByTrimmingCharactersInSet:hexSet] isEqualToString:@""];
161
162 if(valid && ringID.length == 40) {
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400163 Call* c = CallModel::instance().dialingCall();
Alexandre Lision18e1fcd2015-08-04 14:38:42 -0400164 c->setDialNumber(QString::fromNSString([NSString stringWithFormat:@"ring:%@",ringID]));
165 c << Call::Action::ACCEPT;
166 } else {
167 NSAlert *alert = [[NSAlert alloc] init];
168 [alert addButtonWithTitle:@"OK"];
169 [alert setMessageText:@"Error"];
170 [alert setInformativeText:@"ringID cannot be read from this URL."];
171 [alert setAlertStyle:NSWarningAlertStyle];
172 [alert runModal];
173 }
174}
175
Alexandre Lision745e4d62015-03-22 20:03:10 -0400176- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
177{
178 if([self checkForRingAccount]) {
179 [self showMainWindow];
180 } else {
181 [self showWizard];
182 }
183 return YES;
184}
185
Edric Milaret81315412015-05-13 15:14:56 -0400186- (void)handleQuitEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
187{
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400188 delete CallModel::instance().QObject::parent();
Edric Milaret81315412015-05-13 15:14:56 -0400189 [[NSApplication sharedApplication] terminate:self];
190}
191
192-(void)applicationWillTerminate:(NSNotification *)notification
193{
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400194 delete CallModel::instance().QObject::parent();
Edric Milaret81315412015-05-13 15:14:56 -0400195 [[NSApplication sharedApplication] terminate:self];
196}
197
Alexandre Lision3d4143a2015-06-10 14:27:49 -0400198#if ENABLE_SPARKLE
199
200#pragma mark -
201#pragma mark Sparkle delegate
202
203- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update
204{
205 [NSApp activateIgnoringOtherApps:YES];
206}
207
208- (BOOL)updaterMayCheckForUpdates:(SUUpdater *)bundle
209{
210 return YES;
211}
212
213- (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater
214{
215 return YES;
216}
217
218- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error
219{
220 NSLog(@"Error:%@", error.localizedDescription);
221}
222
223#endif
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500224@end