blob: e8bbb73ce4a1f87566cee938dc7e754cae9d60a6 [file] [log] [blame]
/*
* Copyright (C) 2015-2019 Savoir-faire Linux Inc.
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
* Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
//cocoa
#import <Quartz/Quartz.h>
#import <AVFoundation/AVFoundation.h>
//Qt
#import <QSize>
#import <QtMacExtras/qmacfunctions.h>
#import <QPixmap>
#import <qstring.h>
//LRC
#import <api/lrc.h>
#import <api/newaccountmodel.h>
#import <api/newdevicemodel.h>
#import <interfaces/pixmapmanipulatori.h>
#import "AccSipGeneralVC.h"
#import "views/NSColor+RingTheme.h"
#import "views/NSImage+Extensions.h"
#import "Constants.h"
@interface AccSipGeneralVC ()
@property (unsafe_unretained) IBOutlet NSButton* photoView;
@property (unsafe_unretained) IBOutlet NSImageView* addProfilePhotoImage;
@property (unsafe_unretained) IBOutlet NSTextField* displayNameField;
@property (unsafe_unretained) IBOutlet NSTextField* userNameField;
@property (unsafe_unretained) IBOutlet NSSecureTextField* passwordField;
@property (unsafe_unretained) IBOutlet NSTextField* proxyField;
@property (unsafe_unretained) IBOutlet NSTextField* voicemailField;
@property (unsafe_unretained) IBOutlet NSTextField* serverField;
@property (unsafe_unretained) IBOutlet NSButton* removeAccountButton;
@property (unsafe_unretained) IBOutlet NSButton* editAccountButton;
@property QString selectedAccountID;
@end
@implementation AccSipGeneralVC
//Tags for views
typedef NS_ENUM(NSInteger, TagViews) {
DISPLAYNAME = 100
};
@synthesize accountModel;
@synthesize delegate;
@synthesize photoView,addProfilePhotoImage,displayNameField, userNameField, passwordField,proxyField,voicemailField, serverField, removeAccountButton, editAccountButton;
-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountmodel:(lrc::api::NewAccountModel*) accountModel
{
if (self = [self initWithNibName: nibNameOrNil bundle:nibBundleOrNil])
{
self.accountModel= accountModel;
}
return self;
}
-(void)viewDidLoad {
[super viewDidLoad];
[[self view] setAutoresizingMask: NSViewMinXMargin | NSViewMaxXMargin];
[addProfilePhotoImage setWantsLayer: YES];
[self setEditingMode:NO];
[self updateView];
}
- (void)pictureTakerDidEnd:(IKPictureTaker *) picker
returnCode:(NSInteger) code
contextInfo:(void*) contextInfo
{
//do nothing when editing canceled
if (code == 0) {
return;
}
if (auto outputImage = [picker outputImage]) {
NSData* imageData = [outputImage TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData: imageData];
NSDictionary *properties = [[NSDictionary alloc] init];
imageData = [imageRep representationUsingType:NSPNGFileType properties: properties];
NSString * dataString = [imageData base64EncodedStringWithOptions:0];
self.accountModel->setAvatar(self.selectedAccountID, QString::fromNSString(dataString));
[self updateAvatar];
} else if(!photoView.image) {
[photoView setBordered:YES];
[addProfilePhotoImage setHidden:NO];
}
}
-(void)updateAvatar {
const auto& account = accountModel->getAccountInfo(self.selectedAccountID);
@autoreleasepool {
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:account.profileInfo.avatar.toNSString() options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSImage *image = [[NSImage alloc] initWithData:imageData];
if(image) {
[photoView setBordered:NO];
[photoView setImage: [image roundCorners: image.size.height * 0.5]];
[addProfilePhotoImage setHidden:YES];
} else {
[photoView setImage:nil];
[photoView setBordered:YES];
[addProfilePhotoImage setHidden:NO];
}
}
}
#pragma mark - NSTextFieldDelegate methods
- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor
{
return YES;
}
- (IBAction)triggerAdwancedSettings: (NSButton *)sender {
[self.view.window makeFirstResponder:nil];
[self.delegate triggerAdvancedOptions];
}
- (void) setSelectedAccount:(const QString&) account {
self.selectedAccountID = account;
[self updateView];
}
-(void)updateView {
const auto& account = accountModel->getAccountInfo(self.selectedAccountID);
[self updateAvatar];
NSString* displayName = account.profileInfo.alias.toNSString();
[displayNameField setStringValue:displayName];
NSMutableAttributedString *colorTitle = [[NSMutableAttributedString alloc] initWithAttributedString:[removeAccountButton attributedTitle]];
NSRange titleRange = NSMakeRange(0, [colorTitle length]);
[colorTitle addAttribute:NSForegroundColorAttributeName value:[NSColor errorColor] range:titleRange];
[removeAccountButton setAttributedTitle:colorTitle];
lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
[passwordField setStringValue: accountProperties.password.toNSString()];
[proxyField setStringValue: accountProperties.routeset.toNSString()];
[userNameField setStringValue: accountProperties.username.toNSString()];
[serverField setStringValue: accountProperties.hostname.toNSString()];
[voicemailField setStringValue: accountProperties.mailbox.toNSString()];
self.accountEnabled = account.enabled;
}
#pragma mark - Actions
- (IBAction)editPhoto:(id)sender
{
auto pictureTaker = [IKPictureTaker pictureTaker];
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
if (@available(macOS 10.14, *)) {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)
{
[pictureTaker setValue:0 forKey:IKPictureTakerAllowsVideoCaptureKey];
}
if(authStatus == AVAuthorizationStatusNotDetermined)
{
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if(!granted){
[pictureTaker setValue:0 forKey:IKPictureTakerAllowsVideoCaptureKey];
}
}];
}
}
#endif
[pictureTaker beginPictureTakerSheetForWindow:[self.view window]
withDelegate:self
didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
- (IBAction)enableAccount: (NSButton *)sender {
const auto& account = accountModel->getAccountInfo(self.selectedAccountID);
self.accountModel->setAccountEnabled(self.selectedAccountID, !account.enabled);
self.accountEnabled = account.enabled;
}
- (IBAction)removeAccount:(id)sender
{
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:@"OK"];
[alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Button Action")];
[alert setMessageText: NSLocalizedString(@"Remove account",
@"Remove account alert title")];
[alert setInformativeText:NSLocalizedString(@"By clicking \"OK\" you will remove this account on this device! This action can not be undone. Also, your registered name can be lost.",
@"Remove account alert message")];
if ([alert runModal] == NSAlertFirstButtonReturn) {
self.accountModel->removeAccount(self.selectedAccountID);
}
}
- (IBAction)changeEditingMode:(id)sender
{
if([userNameField isEditable]) {
[self setEditingMode:NO];
[self saveAccount];
return;
}
[self setEditingMode:YES];
}
-(void) setEditingMode:(BOOL) shouldEdit {
[userNameField setEditable:shouldEdit];
[passwordField setEditable:shouldEdit];
[proxyField setEditable:shouldEdit];
[voicemailField setEditable:shouldEdit];
[serverField setEditable:shouldEdit];
[userNameField setDrawsBackground:!shouldEdit];
[passwordField setDrawsBackground:!shouldEdit];
[proxyField setDrawsBackground:!shouldEdit];
[voicemailField setDrawsBackground:!shouldEdit];
[serverField setDrawsBackground:!shouldEdit];
[userNameField setBezeled:shouldEdit];
[passwordField setBezeled:shouldEdit];
[proxyField setBezeled:shouldEdit];
[voicemailField setBezeled:shouldEdit];
[serverField setBezeled:shouldEdit];
if(shouldEdit) {
[serverField setBezelStyle:NSTextFieldSquareBezel];
[userNameField setBezelStyle:NSTextFieldSquareBezel];
[passwordField setBezelStyle:NSTextFieldSquareBezel];
[proxyField setBezelStyle:NSTextFieldSquareBezel];
[voicemailField setBezelStyle:NSTextFieldSquareBezel];
[userNameField becomeFirstResponder];
[editAccountButton setTitle:NSLocalizedString(@"Done", @"Edit Sip Account Action")];
return;
}
[editAccountButton setTitle:NSLocalizedString(@"Edit Account", @"Edit Sip Account Action")];
[self.view resignFirstResponder];
}
-(void) saveAccount {
lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
accountProperties.hostname = QString::fromNSString(serverField.stringValue);
accountProperties.password = QString::fromNSString(passwordField.stringValue);
accountProperties.username = QString::fromNSString(userNameField.stringValue);
accountProperties.routeset = QString::fromNSString(proxyField.stringValue);
accountProperties.mailbox = QString::fromNSString(voicemailField.stringValue);
self.accountModel->setAccountConfig(self.selectedAccountID, accountProperties);
}
#pragma mark - NSTextFieldDelegate delegate methods
-(void)controlTextDidEndEditing:(NSNotification *)notification
{
NSTextField* textField = [notification object];
if (textField.tag != DISPLAYNAME) {
return;
}
NSString* displayName = textField.stringValue;
self.accountModel->setAlias(self.selectedAccountID, QString::fromNSString(displayName));
lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
self.accountModel->setAccountConfig(self.selectedAccountID, accountProperties);
}
@end