blob: 6a05a1bc38637cb4b202c18ac370d3348eeeb3fd [file] [log] [blame]
Alexandre Lision8521baa2015-03-13 11:08:00 -04001/*
2 * Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
3 * 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.
18 *
19 * Additional permission under GNU GPL version 3 section 7:
20 *
21 * If you modify this program, or any covered work, by linking or
22 * combining it with the OpenSSL project's OpenSSL library (or a
23 * modified version of that library), containing parts covered by the
24 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
25 * grants you additional permission to convey the resulting work.
26 * Corresponding Source for a non-source form of such a combination
27 * shall include the source code for the parts of OpenSSL used as well
28 * as that of the covered work.
29 */
Alexandre Lision5855b6a2015-02-03 11:31:05 -050030#import "AppDelegate.h"
31
Alexandre Lisione4041492015-03-20 18:20:43 -040032#import <callmodel.h>
Edric Milaret81315412015-05-13 15:14:56 -040033#import <qapplication.h>
Alexandre Lision745e4d62015-03-22 20:03:10 -040034#import <accountmodel.h>
35#import <protocolmodel.h>
36#import <QItemSelectionModel>
37#import <account.h>
38
Alexandre Lision3d4143a2015-06-10 14:27:49 -040039#if ENABLE_SPARKLE
40#import <Sparkle/Sparkle.h>
41#endif
42
Alexandre Lisionc65310c2015-04-23 16:44:23 -040043#import "Constants.h"
Alexandre Lision745e4d62015-03-22 20:03:10 -040044#import "RingWizardWC.h"
45
Alexandre Lision3d4143a2015-06-10 14:27:49 -040046#if ENABLE_SPARKLE
47@interface AppDelegate() <SUUpdaterDelegate>
48#else
Alexandre Lision745e4d62015-03-22 20:03:10 -040049@interface AppDelegate()
Alexandre Lision3d4143a2015-06-10 14:27:49 -040050#endif
Alexandre Lision745e4d62015-03-22 20:03:10 -040051
52@property RingWindowController* ringWindowController;
53@property RingWizardWC* wizard;
54
55@end
56
Alexandre Lision5855b6a2015-02-03 11:31:05 -050057@implementation AppDelegate
58
59- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
Alexandre Lision4a7b95e2015-02-20 10:06:43 -050060 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
61
Alexandre Lisione4041492015-03-20 18:20:43 -040062 [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
63
Edric Milaret81315412015-05-13 15:14:56 -040064 NSAppleEventManager* appleEventManager = [NSAppleEventManager sharedAppleEventManager];
65 [appleEventManager setEventHandler:self andSelector:@selector(handleQuitEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
66
Alexandre Lision745e4d62015-03-22 20:03:10 -040067 if([self checkForRingAccount]) {
68 [self showMainWindow];
69 } else {
70 [self showWizard];
71 }
Alexandre Lisione4041492015-03-20 18:20:43 -040072 [self connect];
73}
74
75- (void) connect
76{
77 QObject::connect(CallModel::instance(),
78 &CallModel::incomingCall,
79 [=](Call* call) {
Alexandre Lisionc65310c2015-04-23 16:44:23 -040080 BOOL shouldComeToForeground = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::WindowBehaviour];
81 BOOL shouldNotify = [[NSUserDefaults standardUserDefaults] boolForKey:Preferences::Notifications];
Alexandre Lisione4041492015-03-20 18:20:43 -040082 if(shouldComeToForeground)
83 [NSApp activateIgnoringOtherApps:YES];
84
85 if(shouldNotify) {
86 [self showIncomingNotification:call];
87 }
88 });
89}
90
91- (void) showIncomingNotification:(Call*) call{
92 NSUserNotification *notification = [[NSUserNotification alloc] init];
93 notification.title = @"Incoming call", call->peerName();
94 //notification.informativeText = @"A notification";
95 notification.soundName = NSUserNotificationDefaultSoundName;
96
97 [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
Alexandre Lision5855b6a2015-02-03 11:31:05 -050098}
99
Alexandre Lision745e4d62015-03-22 20:03:10 -0400100/**
101 * click in MainMenu "Setup Ring"
102 */
103- (IBAction)showWizard:(id)sender {
104 [self showWizard];
105}
106
107- (void) showWizard
108{
109 NSLog(@"Showing wizard");
110 if(self.wizard == nil) {
111 self.wizard = [[RingWizardWC alloc] initWithWindowNibName:@"RingWizard"];
112 }
113 [self.wizard.window orderFront:self];
114}
115
116- (void) showMainWindow
117{
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400118 if(self.ringWindowController == nil) {
Alexandre Lision745e4d62015-03-22 20:03:10 -0400119 self.ringWindowController = [[RingWindowController alloc] initWithWindowNibName:@"RingWindow"];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400120 }
121
122 self.wizard = nil;
Alexandre Lision745e4d62015-03-22 20:03:10 -0400123
124 [self.ringWindowController.window makeKeyAndOrderFront:self];
125}
126
127- (BOOL) checkForRingAccount
128{
Alexandre Lisiona1f07bf2015-07-28 10:30:55 -0400129 BOOL foundRingAcc = NO;
Alexandre Lision745e4d62015-03-22 20:03:10 -0400130 for (int i = 0 ; i < AccountModel::instance()->rowCount() ; ++i) {
131 QModelIndex idx = AccountModel::instance()->index(i);
132 Account* acc = AccountModel::instance()->getAccountByModelIndex(idx);
133 if(acc->protocol() == Account::Protocol::RING) {
Alexandre Lisiona1f07bf2015-07-28 10:30:55 -0400134 if (acc->displayName().isEmpty())
135 acc->setDisplayName(acc->alias());
136 foundRingAcc = YES;
Alexandre Lision745e4d62015-03-22 20:03:10 -0400137 }
138 }
Alexandre Lisiona1f07bf2015-07-28 10:30:55 -0400139 return foundRingAcc;
Alexandre Lision745e4d62015-03-22 20:03:10 -0400140}
141
Alexandre Lision18e1fcd2015-08-04 14:38:42 -0400142-(void)applicationWillFinishLaunching:(NSNotification *)aNotification
143{
144 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
145 [appleEventManager setEventHandler:self
146 andSelector:@selector(handleGetURLEvent:withReplyEvent:)
147 forEventClass:kInternetEventClass andEventID:kAEGetURL];
148}
149
150/**
151 * Recognized patterns:
152 * - ring:<hash>
153 * - ring://<hash>
154 */
155- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
156{
157 NSString* query = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
158 NSURL* url = [[NSURL alloc] initWithString:query];
159 NSString* ringID = [url host];
160 if (!ringID) {
161 //not a valid NSURL, try to parse query directly
162 ringID = [query substringFromIndex:@"ring:".length];
163 }
164
165 // check for a valid ring hash
166 NSCharacterSet *hexSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789abcdefABCDEF"];
167 BOOL valid = [[ringID stringByTrimmingCharactersInSet:hexSet] isEqualToString:@""];
168
169 if(valid && ringID.length == 40) {
170 Call* c = CallModel::instance()->dialingCall();
171 c->setDialNumber(QString::fromNSString([NSString stringWithFormat:@"ring:%@",ringID]));
172 c << Call::Action::ACCEPT;
173 } else {
174 NSAlert *alert = [[NSAlert alloc] init];
175 [alert addButtonWithTitle:@"OK"];
176 [alert setMessageText:@"Error"];
177 [alert setInformativeText:@"ringID cannot be read from this URL."];
178 [alert setAlertStyle:NSWarningAlertStyle];
179 [alert runModal];
180 }
181}
182
Alexandre Lision745e4d62015-03-22 20:03:10 -0400183- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
184{
185 if([self checkForRingAccount]) {
186 [self showMainWindow];
187 } else {
188 [self showWizard];
189 }
190 return YES;
191}
192
Edric Milaret81315412015-05-13 15:14:56 -0400193- (void)handleQuitEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
194{
195 delete CallModel::instance()->QObject::parent();
196 [[NSApplication sharedApplication] terminate:self];
197}
198
199-(void)applicationWillTerminate:(NSNotification *)notification
200{
201 delete CallModel::instance()->QObject::parent();
202 [[NSApplication sharedApplication] terminate:self];
203}
204
Alexandre Lision3d4143a2015-06-10 14:27:49 -0400205#if ENABLE_SPARKLE
206
207#pragma mark -
208#pragma mark Sparkle delegate
209
210- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update
211{
212 [NSApp activateIgnoringOtherApps:YES];
213}
214
215- (BOOL)updaterMayCheckForUpdates:(SUUpdater *)bundle
216{
217 return YES;
218}
219
220- (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater
221{
222 return YES;
223}
224
225- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error
226{
227 NSLog(@"Error:%@", error.localizedDescription);
228}
229
230#endif
Alexandre Lision5855b6a2015-02-03 11:31:05 -0500231@end