multi-device: update Ring account creation wizard
This patch implements multi-device support
- The account creation wizzard has now two options "Existing Ring
account" and "New Ring account".
"Existing Ring account": Allows for fetching a Ring account archive
from the DHT. Requires pin and password.
"New Ring account": This is the previously existing wizard. It was
modified to ask for a password which will be used to encrypt the
account archive. This password is then required for exporting the
account on the Ring.
- Creating a new Ring account with the "+" button now triggers the
account creation wizard.
Change-Id: I6840d968e52de014ab0aa9dd6f5bc1ab31f9e9ec
Tuleap: #958
diff --git a/src/AccountsVC.mm b/src/AccountsVC.mm
index 1557915..b62b623 100644
--- a/src/AccountsVC.mm
+++ b/src/AccountsVC.mm
@@ -38,6 +38,7 @@
#import "AccRingVC.h"
#import "AccDevicesVC.h"
#import "PathPasswordWC.h"
+#import "RingWizardWC.h"
@interface AccountsVC () <PathPasswordDelegate>
@@ -63,6 +64,7 @@
@property AccAdvancedVC* advancedVC;
@property AccSecurityVC* securityVC;
@property PathPasswordWC* passwordWC;
+@property RingWizardWC* wizard;
@end
@@ -79,6 +81,7 @@
@synthesize accountDetailsView;
@synthesize treeController;
@synthesize passwordWC;
+@synthesize wizard;
NSInteger const TAG_CHECK = 100;
NSInteger const TAG_NAME = 200;
@@ -164,18 +167,52 @@
[self.ringDevicesTabItem setView:self.devicesVC.view];
}
-- (IBAction)addAccount:(id)sender {
+- (void)createSIPAccount
+{
QModelIndex qIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
auto newAccName = [[NSString alloc] initWithFormat:@"%@ account",
- AccountModel::instance().protocolModel()->data(qIdx, Qt::DisplayRole).toString().toNSString(), nil];
+ AccountModel::instance().protocolModel()->data(qIdx, Qt::DisplayRole).toString().toNSString(), nil];
auto acc = AccountModel::instance().add([newAccName UTF8String], qIdx);
acc->setDisplayName(acc->alias());
AccountModel::instance().save();
}
-- (IBAction)protocolSelectedChanged:(id)sender {
+- (void)createRingAccount
+{
+ wizard = [[RingWizardWC alloc] initWithWindowNibName:@"RingWizard"];
+ [wizard showChooseWithCancelButton: YES];
+ // [wizard.window makeKeyAndOrderFront:self];
+#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9
+ [self.view.window beginSheet:wizard.window completionHandler:nil];
+#else
+ [NSApp beginSheet: wizard.window
+ modalForWindow: self.view.window
+ modalDelegate: self
+ didEndSelector: nil
+ contextInfo: nil];
+#endif
+ [wizard showWindow:self];
+}
+- (IBAction)addAccount:(id)sender
+{
+ QModelIndex qProtocolIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
+ auto protocol = qvariant_cast<Account::Protocol> (AccountModel::instance().protocolModel()->data( qProtocolIdx, Qt::UserRole));
+ switch (protocol){
+ case Account::Protocol::SIP:{
+ [self createSIPAccount];
+ break;
+ }
+ case Account::Protocol::RING:{
+ [self createRingAccount];
+ break;
+ }
+ }
+}
+
+- (IBAction)protocolSelectedChanged:(id)sender
+{
int index = [sender indexOfSelectedItem];
auto qIdx = AccountModel::instance().protocolModel()->index(index, 0);
AccountModel::instance().protocolModel()->selectionModel()->setCurrentIndex(qIdx, QItemSelectionModel::ClearAndSelect);
@@ -187,7 +224,6 @@
for(NSTabViewItem* item in configPanels.tabViewItems) {
[configPanels removeTabViewItem:item];
}
-
[configPanels insertTabViewItem:generalTabItem atIndex:0];
[configPanels insertTabViewItem:mediaTabItem atIndex:1];
[configPanels insertTabViewItem:advancedTabItem atIndex:2];
diff --git a/src/RingWizardChooseVC.h b/src/RingWizardChooseVC.h
new file mode 100644
index 0000000..acd19f0
--- /dev/null
+++ b/src/RingWizardChooseVC.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ * Author: Loïc Siret <loic.siret@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.
+ */
+#import <Cocoa/Cocoa.h>
+
+@class RingWizardWC;
+
+
+typedef NS_ENUM(NSInteger, WizardAction) {
+ WIZARD_ACTION_INVALID = -1,
+ WIZARD_ACTION_NEW = 0,
+ WIZARD_ACTION_LINK = 1,
+};
+
+@protocol RingWizardChooseDelegate <NSObject>
+
+- (void)didCompleteWithAction:(WizardAction)action;
+
+@end
+
+@interface RingWizardChooseVC : NSViewController
+
+@property (weak, nonatomic) id <RingWizardChooseDelegate> delegate;
+
+@property BOOL isCancelable;
+
+- (void)showCancelButton:(BOOL)showCancel;
+
+@end
+
diff --git a/src/RingWizardChooseVC.mm b/src/RingWizardChooseVC.mm
new file mode 100644
index 0000000..1658d1b
--- /dev/null
+++ b/src/RingWizardChooseVC.mm
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ * Author: Loïc Siret <loic.siret@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.
+ */
+
+#import "RingWizardChooseVC.h"
+
+@interface RingWizardChooseVC()
+
+@end
+
+@implementation RingWizardChooseVC
+
+@synthesize delegate;
+
+- (void)showCancelButton:(BOOL)showCancel{
+ self.isCancelable = showCancel;
+}
+
+- (IBAction)createRingAccount:(id)sender
+{
+ if ([self.delegate respondsToSelector:@selector(didCompleteWithAction:)]){
+ [delegate didCompleteWithAction:WizardAction::WIZARD_ACTION_NEW];
+ }
+}
+
+- (IBAction)linkExistingRingAccount:(id)sender
+{
+ if ([self.delegate respondsToSelector:@selector(didCompleteWithAction:)]){
+ [delegate didCompleteWithAction:WizardAction::WIZARD_ACTION_LINK];
+ }
+}
+
+- (IBAction)onCancel:(id)sender
+{
+ if ([self.delegate respondsToSelector:@selector(didCompleteWithAction:)]){
+ [delegate didCompleteWithAction:WIZARD_ACTION_INVALID];
+ }
+}
+
+@end
diff --git a/src/RingWizardLinkAccountVC.h b/src/RingWizardLinkAccountVC.h
new file mode 100644
index 0000000..bb8151c
--- /dev/null
+++ b/src/RingWizardLinkAccountVC.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ * Author: Loïc Siret <loic.siret@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.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@protocol RingWizardLinkDelegate <NSObject>
+- (void)didLinkAccountWithSuccess:(BOOL)success;
+@end
+
+@interface RingWizardLinkAccountVC : NSViewController
+@property (nonatomic, weak) NSWindowController <RingWizardLinkDelegate>* delegate;
+@property (nonatomic, weak) NSString* pinValue;
+@property (nonatomic, weak) NSString* passwordValue;
+
+- (void)show;
+@end
diff --git a/src/RingWizardLinkAccountVC.mm b/src/RingWizardLinkAccountVC.mm
new file mode 100644
index 0000000..a30a69f
--- /dev/null
+++ b/src/RingWizardLinkAccountVC.mm
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ * Author: Loïc Siret <loic.siret@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.
+ */
+
+#import "RingWizardLinkAccountVC.h"
+//Cocoa
+#import <AddressBook/AddressBook.h>
+#import <Quartz/Quartz.h>
+
+//Qt
+#import <QUrl>
+#import <QPixmap>
+
+//LRC
+#import <accountmodel.h>
+#import <protocolmodel.h>
+#import <profilemodel.h>
+#import <QItemSelectionModel>
+#import <account.h>
+#import <certificate.h>
+#import <profilemodel.h>
+#import <profile.h>
+#import <person.h>
+
+#import "Constants.h"
+
+@interface RingWizardLinkAccountVC ()
+
+@end
+
+@implementation RingWizardLinkAccountVC {
+ __unsafe_unretained IBOutlet NSView* initialContainer;
+ __unsafe_unretained IBOutlet NSTextField* pinField;
+ __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
+ __unsafe_unretained IBOutlet NSTextField* pinLabel;
+ __unsafe_unretained IBOutlet NSTextField* passwordLabel;
+ __unsafe_unretained IBOutlet NSButton* createButton;
+
+ __unsafe_unretained IBOutlet NSView* loadingContainer;
+ __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
+
+ __unsafe_unretained IBOutlet NSView* errorContainer;
+
+ Account* accountToCreate;
+ NSTimer* errorTimer;
+ QMetaObject::Connection stateChanged;
+}
+
+- (void)show
+{
+ [initialContainer setHidden:NO];
+ [loadingContainer setHidden:YES];
+ [errorContainer setHidden:YES];
+}
+
+- (void)showError
+{
+ [initialContainer setHidden:YES];
+ [loadingContainer setHidden:YES];
+ [errorContainer setHidden:NO];
+}
+- (void)showLoading
+{
+ [initialContainer setHidden:YES];
+ [loadingContainer setHidden:NO];
+ [progressBar startAnimation:nil];
+ [errorContainer setHidden:YES];
+}
+
+- (IBAction)importRingAccount:(id)sender
+{
+ [self showLoading];
+ if (auto profile = ProfileModel::instance().selectedProfile()) {
+ profile->person()->setFormattedName([NSFullUserName() UTF8String]);
+ profile->save();
+ }
+ accountToCreate = AccountModel::instance().add(QString::fromNSString(NSFullUserName()), Account::Protocol::RING);
+ accountToCreate->setArchivePin(QString::fromNSString(self.pinValue));
+ accountToCreate->setArchivePassword(QString::fromNSString(self.passwordValue));
+
+ [self setCallback];
+
+ [self performSelector:@selector(saveAccount) withObject:nil afterDelay:1];
+ [self registerDefaultPreferences];
+}
+
+- (IBAction)dismissViewWithError:(id)sender
+{
+ [self.delegate didLinkAccountWithSuccess:NO];
+}
+
+- (IBAction)back:(id)sender
+{
+ [self show];
+}
+
+/**
+ * Set default values for preferences
+ */
+- (void)registerDefaultPreferences
+{
+ // enable AutoStartup
+ LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
+ if (loginItemsRef == nil) return;
+ CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
+ LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
+ if (itemRef) CFRelease(itemRef);
+
+ // enable Notifications
+ [[NSUserDefaults standardUserDefaults] setBool:YES forKey:Preferences::Notifications];
+}
+
+- (void)saveAccount
+{
+ accountToCreate->setUpnpEnabled(YES); // Always active upnp
+ accountToCreate << Account::EditAction::SAVE;
+}
+
+- (void)setCallback
+{
+ errorTimer = [NSTimer scheduledTimerWithTimeInterval:30
+ target:self
+ selector:@selector(didLinkFailed) userInfo:nil
+ repeats:NO];
+
+ stateChanged = QObject::connect(&AccountModel::instance(),
+ &AccountModel::accountStateChanged,
+ [=](Account *account, const Account::RegistrationState state) {
+ switch(state){
+ case Account::RegistrationState::READY:
+ case Account::RegistrationState::TRYING:
+ case Account::RegistrationState::UNREGISTERED:{
+ accountToCreate<< Account::EditAction::RELOAD;
+ QObject::disconnect(stateChanged);
+ [errorTimer invalidate];
+ [self.delegate didLinkAccountWithSuccess:YES];
+ break;
+ }
+ case Account::RegistrationState::ERROR:
+ QObject::disconnect(stateChanged);
+ [errorTimer invalidate];
+ [self showError];
+ break;
+ case Account::RegistrationState::INITIALIZING:
+ case Account::RegistrationState::COUNT__:{
+ //DO Nothing
+ break;
+ }
+ }
+ });
+}
+
+
+- (void)didLinkFailed
+{
+ [self showError];
+}
+
+@end
diff --git a/src/RingWizardNewAccountVC.h b/src/RingWizardNewAccountVC.h
new file mode 100644
index 0000000..e6232f1
--- /dev/null
+++ b/src/RingWizardNewAccountVC.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ * Author: Loïc Siret <loic.siret@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.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@protocol RingWizardNewDelegate <NSObject>
+- (void)didCreateAccountWithSuccess:(BOOL)success;
+@end
+
+@interface RingWizardNewAccountVC : NSViewController
+
+@property (nonatomic, weak)NSWindowController <RingWizardNewDelegate>* delegate;
+
+@property (nonatomic, weak)NSString* alias;
+@property (nonatomic, weak)NSString* password;
+- (void)show;
+@end
diff --git a/src/RingWizardNewAccountVC.mm b/src/RingWizardNewAccountVC.mm
new file mode 100644
index 0000000..fbe3662
--- /dev/null
+++ b/src/RingWizardNewAccountVC.mm
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
+ * Author: Loïc Siret <loic.siret@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.
+ */
+
+#import "RingWizardNewAccountVC.h"
+
+
+//Cocoa
+#import <AddressBook/AddressBook.h>
+#import <Quartz/Quartz.h>
+
+//Qt
+#import <QUrl>
+#import <QPixmap>
+
+//LRC
+#import <accountmodel.h>
+#import <protocolmodel.h>
+#import <profilemodel.h>
+#import <QItemSelectionModel>
+#import <account.h>
+#import <certificate.h>
+#import <profilemodel.h>
+#import <profile.h>
+#import <person.h>
+
+#import "AppDelegate.h"
+#import "Constants.h"
+#import "views/NSImage+Extensions.h"
+#import "views/NSColor+RingTheme.h"
+
+@interface RingWizardNewAccountVC ()
+@end
+
+@implementation RingWizardNewAccountVC
+{
+ __unsafe_unretained IBOutlet NSButton* photoView;
+ __unsafe_unretained IBOutlet NSTextField* nicknameField;
+ __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
+ __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
+ __unsafe_unretained IBOutlet NSTextField* indicationLabel;
+ __unsafe_unretained IBOutlet NSTextField* passwordLabel;
+ __unsafe_unretained IBOutlet NSButton* createButton;
+ __unsafe_unretained IBOutlet NSButton* cancelButton;
+ Account* accountToCreate;
+ NSTimer* errorTimer;
+ QMetaObject::Connection stateChanged;
+}
+
+NSInteger const NICKNAME_TAG = 1;
+
+
+- (void)show
+{
+ AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+ [nicknameField setTag:NICKNAME_TAG];
+ [nicknameField setStringValue:NSFullUserName()];
+ [self controlTextDidChange:[NSNotification notificationWithName:@"PlaceHolder" object:nicknameField]];
+
+ NSData* imgData = [[[ABAddressBook sharedAddressBook] me] imageData];
+ if (imgData != nil) {
+ [photoView setImage:[[NSImage alloc] initWithData:imgData]];
+ } else
+ [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
+
+ [photoView setWantsLayer: YES];
+ photoView.layer.cornerRadius = photoView.frame.size.width / 2;
+ photoView.layer.masksToBounds = YES;
+}
+
+- (IBAction)editPhoto:(id)sender
+{
+ auto pictureTaker = [IKPictureTaker pictureTaker];
+
+ [pictureTaker beginPictureTakerSheetForWindow:[self.delegate window]
+ withDelegate:self
+ didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:)
+ contextInfo:nil];
+
+}
+
+- (void)pictureTakerDidEnd:(IKPictureTaker *) picker
+ returnCode:(NSInteger) code
+ contextInfo:(void*) contextInfo
+{
+ if (auto outputImage = [picker outputImage]) {
+ [photoView setImage:outputImage];
+ } else
+ [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
+}
+
+- (IBAction)createRingAccount:(id)sender
+{
+ [nicknameField setHidden:YES];
+ [progressBar setHidden:NO];
+ [createButton setHidden:YES];
+ [photoView setHidden:YES];
+ [passwordField setHidden:YES];
+ [passwordLabel setHidden:YES];
+ [cancelButton setHidden:YES];
+ [progressBar startAnimation:nil];
+ [indicationLabel setStringValue:NSLocalizedString(@"Just a moment...",
+ @"Indication for user")];
+
+ if ([self.alias isEqualToString:@""]) {
+ self.alias = NSLocalizedString(@"Unknown", @"Name used when user leave field empty");
+ }
+ accountToCreate = AccountModel::instance().add(QString::fromNSString(self.alias), Account::Protocol::RING);
+
+ accountToCreate->setAlias([self.alias UTF8String]);
+ accountToCreate->setDisplayName([self.alias UTF8String]);
+
+ if (auto profile = ProfileModel::instance().selectedProfile()) {
+ profile->person()->setFormattedName([self.alias UTF8String]);
+ QPixmap p;
+ auto smallImg = [NSImage imageResize:[photoView image] newSize:{100,100}];
+ if (p.loadFromData(QByteArray::fromNSData([smallImg TIFFRepresentation]))) {
+ profile->person()->setPhoto(QVariant(p));
+ }
+ profile->save();
+ }
+
+ QModelIndex qIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
+
+ [self setCallback];
+
+ [self performSelector:@selector(saveAccount) withObject:nil afterDelay:1];
+ [self registerDefaultPreferences];
+}
+
+/**
+ * Set default values for preferences
+ */
+- (void)registerDefaultPreferences
+{
+ // enable AutoStartup
+ LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
+ if (loginItemsRef == nil) return;
+ CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
+ LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
+ if (itemRef) CFRelease(itemRef);
+
+ // enable Notifications
+ [[NSUserDefaults standardUserDefaults] setBool:YES forKey:Preferences::Notifications];
+}
+
+- (void)saveAccount
+{
+ accountToCreate->setArchivePassword(QString::fromNSString(passwordField.stringValue));
+ accountToCreate->setUpnpEnabled(YES); // Always active upnp
+ accountToCreate << Account::EditAction::SAVE;
+}
+
+- (void)setCallback
+{
+ errorTimer = [NSTimer scheduledTimerWithTimeInterval:30
+ target:self
+ selector:@selector(didCreateFailed) userInfo:nil
+ repeats:NO];
+ stateChanged = QObject::connect(&AccountModel::instance(),
+ &AccountModel::accountStateChanged,
+ [=](Account *account, const Account::RegistrationState state) {
+ switch(state){
+ case Account::RegistrationState::READY:
+ case Account::RegistrationState::TRYING:
+ case Account::RegistrationState::UNREGISTERED:{
+ accountToCreate<< Account::EditAction::RELOAD;
+ QObject::disconnect(stateChanged);
+ [self.delegate didCreateAccountWithSuccess:YES];
+ break;
+ }
+ case Account::RegistrationState::ERROR:
+ QObject::disconnect(stateChanged);
+ [self.delegate didCreateAccountWithSuccess:NO];
+ break;
+ case Account::RegistrationState::INITIALIZING:
+ case Account::RegistrationState::COUNT__:{
+ //DO Nothing
+ break;
+ }
+ }
+ });
+}
+
+- (void)didCreateFailed
+{
+ [self.delegate didCreateAccountWithSuccess:NO];
+}
+
+- (IBAction)cancel:(id)sender
+{
+ [self.delegate didCreateAccountWithSuccess:NO];
+}
+
+#pragma mark - NSOpenSavePanelDelegate delegate methods
+
+- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError
+{
+ return YES;
+}
+
+-(void)controlTextDidChange:(NSNotification *)notif
+{
+ NSTextField* textField = [notif object];
+ // else it is NICKNAME_TAG field
+ NSString* alias = textField.stringValue;
+ if ([alias isEqualToString:@""]) {
+ alias = NSLocalizedString(@"Unknown", @"Name used when user leave field empty");
+ }
+ self.alias = alias;
+}
+
+@end
diff --git a/src/RingWizardWC.h b/src/RingWizardWC.h
index 885e314..b68c2c7 100644
--- a/src/RingWizardWC.h
+++ b/src/RingWizardWC.h
@@ -18,7 +18,15 @@
*/
#import <Cocoa/Cocoa.h>
+#import "RingWizardChooseVC.h"
+#import "RingWizardNewAccountVC.h"
+#import "RingWizardLinkAccountVC.h"
+@interface RingWizardWC : NSWindowController <NSWindowDelegate, NSPathControlDelegate,
+ NSOpenSavePanelDelegate, RingWizardChooseDelegate, RingWizardNewDelegate,
+ RingWizardLinkDelegate>
-@interface RingWizardWC : NSWindowController <NSWindowDelegate, NSPathControlDelegate, NSOpenSavePanelDelegate>
+- (void)showChooseWithCancelButton:(BOOL)showCancel;
+- (void)showNewAccountVC;
+- (void)showLinkAccountVC;
@end
diff --git a/src/RingWizardWC.mm b/src/RingWizardWC.mm
index 61650f0..373eb80 100644
--- a/src/RingWizardWC.mm
+++ b/src/RingWizardWC.mm
@@ -22,188 +22,149 @@
#import <AddressBook/AddressBook.h>
#import <Quartz/Quartz.h>
-//Qt
-#import <QUrl>
-#import <QPixmap>
-
-//LRC
-#import <accountmodel.h>
-#import <protocolmodel.h>
-#import <profilemodel.h>
-#import <QItemSelectionModel>
-#import <account.h>
-#import <certificate.h>
-#import <profilemodel.h>
-#import <profile.h>
-#import <person.h>
#import "AppDelegate.h"
#import "Constants.h"
#import "views/NSImage+Extensions.h"
#import "views/NSColor+RingTheme.h"
+#import "RingWizardNewAccountVC.h"
+#import "RingWizardLinkAccountVC.h"
+#import "RingWizardChooseVC.h"
+
+@interface RingWizardWC ()
+
+@property (retain, nonatomic)IBOutlet NSView* container;
+
+@end
@implementation RingWizardWC {
-
- __unsafe_unretained IBOutlet NSButton* photoView;
- __unsafe_unretained IBOutlet NSTextField* nicknameField;
- __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
- __unsafe_unretained IBOutlet NSTextField* indicationLabel;
- __unsafe_unretained IBOutlet NSButton* createButton;
-
- Account* accountToCreate;
+ IBOutlet RingWizardNewAccountVC* newAccountWC;
+ IBOutlet RingWizardLinkAccountVC* linkAccountWC;
+ IBOutlet RingWizardChooseVC* chooseActiontWC;
+ float initialHeight;
+ float currentHeight;
+ BOOL isCancelable;
}
-NSInteger const NICKNAME_TAG = 1;
-
-- (void)windowDidLoad {
+- (void)windowDidLoad
+{
[super windowDidLoad];
- [nicknameField setTag:NICKNAME_TAG];
-
[self.window setBackgroundColor:[NSColor ringGreyHighlight]];
+ chooseActiontWC = [[RingWizardChooseVC alloc] initWithNibName:@"RingWizardChoose" bundle:nil];
+ [chooseActiontWC setDelegate:self];
+ linkAccountWC = [[RingWizardLinkAccountVC alloc] initWithNibName:@"RingWizardLinkAccount" bundle:nil];
+ [linkAccountWC setDelegate:self];
+ newAccountWC = [[RingWizardNewAccountVC alloc] initWithNibName:@"RingWizardNewAccount" bundle:nil];
+ [newAccountWC setDelegate:self];
+ initialHeight = self.window.frame.size.height;
+ currentHeight = self.window.frame.size.height;
+ isCancelable = NO;
+ [self showView:chooseActiontWC.view];
+}
- AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
-
- if(![appDelegate checkForRingAccount]) {
- accountToCreate = AccountModel::instance().add(QString::fromNSString(NSFullUserName()), Account::Protocol::RING);
-
- [nicknameField setStringValue:NSFullUserName()];
- [self controlTextDidChange:[NSNotification notificationWithName:@"PlaceHolder" object:nicknameField]];
+- (void)removeSubviews
+{
+ while ([self.container.subviews count] > 0)
+ {
+ [[self.container.subviews firstObject] removeFromSuperview];
}
-
- NSData* imgData = [[[ABAddressBook sharedAddressBook] me] imageData];
- if (imgData != nil) {
- [photoView setImage:[[NSImage alloc] initWithData:imgData]];
- } else
- [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
-
- [photoView setWantsLayer: YES];
- photoView.layer.cornerRadius = photoView.frame.size.width / 2;
- photoView.layer.masksToBounds = YES;
}
-- (IBAction) editPhoto:(id)sender
+#define minHeight 135
+- (void)showView: (NSView*) view
{
- auto pictureTaker = [IKPictureTaker pictureTaker];
- [pictureTaker beginPictureTakerSheetForWindow:self.window
- withDelegate:self
- didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:)
- contextInfo:nil];
-}
-
-- (void) pictureTakerDidEnd:(IKPictureTaker *) picker
- returnCode:(NSInteger) code
- contextInfo:(void*) contextInfo
-{
- if (auto outputImage = [picker outputImage]) {
- [photoView setImage:outputImage];
- } else
- [photoView setImage:[NSImage imageNamed:@"default_user_icon"]];
-}
-
-- (IBAction)shareRingID:(id)sender {
- auto sharingServicePicker = [[NSSharingServicePicker alloc] initWithItems:[NSArray arrayWithObject:[nicknameField stringValue]]];
- [sharingServicePicker showRelativeToRect:[sender bounds]
- ofView:sender
- preferredEdge:NSMinYEdge];
-}
-
-- (IBAction)createRingAccount:(id)sender
-{
- [nicknameField setHidden:YES];
- [progressBar setHidden:NO];
- [createButton setHidden:YES];
- [photoView setHidden:YES];
- [progressBar startAnimation:nil];
- [indicationLabel setStringValue:NSLocalizedString(@"Just a moment...",
- @"Indication for user")];
-
- if (auto profile = ProfileModel::instance().selectedProfile()) {
- profile->person()->setFormattedName([[nicknameField stringValue] UTF8String]);
- QPixmap p;
- auto smallImg = [NSImage imageResize:[photoView image] newSize:{100,100}];
- if (p.loadFromData(QByteArray::fromNSData([smallImg TIFFRepresentation]))) {
- profile->person()->setPhoto(QVariant(p));
- }
- profile->save();
+ [self removeSubviews];
+ NSRect frame = [self.container frame];
+ frame.size.height = MAX(minHeight, view.bounds.size.height);
+ [view setFrame:frame];
+ [self.container setFrame:frame];
+ float size = 0;
+ NSView *container = self.window.contentView;
+ for (NSView *child in container.subviews){
+ size += child.frame.size.height;
}
-
- QModelIndex qIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
-
- [self setCallback];
-
- [self performSelector:@selector(saveAccount) withObject:nil afterDelay:1];
- [self registerDefaultPreferences];
-}
-
-/**
- * Set default values for preferences
- */
-- (void) registerDefaultPreferences
-{
- // enable AutoStartup
- LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
- if (loginItemsRef == nil) return;
- CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
- LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
- if (itemRef) CFRelease(itemRef);
-
- // enable Notifications
- [[NSUserDefaults standardUserDefaults] setBool:YES forKey:Preferences::Notifications];
-}
-
-- (void) saveAccount
-{
- accountToCreate->setUpnpEnabled(YES); // Always active upnp
- accountToCreate << Account::EditAction::SAVE;
-}
-
-- (void) setCallback
-{
- QObject::connect(&AccountModel::instance(),
- &AccountModel::accountStateChanged,
- [=](Account *account, const Account::RegistrationState state) {
- [self.window close];
- AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
- [appDelegate showMainWindow];
- });
-}
-
-- (IBAction)goToApp:(id)sender
-{
- [self.window close];
- AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
- [appDelegate showMainWindow];
-}
-
-#pragma mark - NSOpenSavePanelDelegate delegate methods
-
-- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError
-{
- return YES;
-}
-
-#pragma mark - NSTextFieldDelegate methods
-
--(void)controlTextDidChange:(NSNotification *)notif
-{
- NSTextField* textField = [notif object];
- // else it is NICKNAME_TAG field
- NSString* alias = textField.stringValue;
- if ([alias isEqualToString:@""]) {
- alias = NSLocalizedString(@"Unknown", @"Name used when user leave field empty");
+ if (currentHeight != size){
+ currentHeight = size;
+ NSRect frameWindows = self.window.frame;
+ frameWindows.size.height = currentHeight;
+ [self.window setFrame:frameWindows display:YES animate:YES];
}
- accountToCreate->setAlias([alias UTF8String]);
- accountToCreate->setDisplayName([alias UTF8String]);
+ [self.container addSubview:view];
+}
+
+- (void)showChooseWithCancelButton:(BOOL)showCancel
+{
+ [self showView: chooseActiontWC.view];
+ [chooseActiontWC showCancelButton:showCancel];
+ isCancelable = showCancel;
+}
+
+- (void)showNewAccountVC
+{
+ [self showView: newAccountWC.view];
+ [newAccountWC show];
+}
+
+- (void)showLinkAccountVC
+{
+ [self showView: linkAccountWC.view];
+ [linkAccountWC show];
}
# pragma NSWindowDelegate methods
- (void)windowWillClose:(NSNotification *)notification
{
- AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
- if ([appDelegate checkForRingAccount]) {
- [appDelegate showMainWindow];
+ if (!isCancelable){
+ AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+ if ([appDelegate checkForRingAccount]) {
+ [appDelegate showMainWindow];
+ }
+ }
+}
+
+#pragma - WizardChooseDelegate methods
+
+- (void)didCompleteWithAction:(WizardAction)action
+{
+ if (action == WIZARD_ACTION_LINK){
+ [self showLinkAccountVC];
+ } else if (action == WIZARD_ACTION_NEW){
+ [self showNewAccountVC];
+ } else {
+ [self.window close];
+ }
+
+}
+
+#pragma - WizardCreateAccountDelegate methods
+
+- (void)didCreateAccountWithSuccess:(BOOL)success
+{
+ if (success) {
+ [self.window close];
+ if (!isCancelable){
+ AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+ [appDelegate showMainWindow];
+ }
+ } else {
+ [self showChooseWithCancelButton:isCancelable];
+ }
+}
+
+#pragma - WizardLinkAccountDelegate methods
+
+- (void)didLinkAccountWithSuccess:(BOOL)success
+{
+ if (success) {
+ [self.window close];
+ if (!isCancelable){
+ AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
+ [appDelegate showMainWindow];
+ }
+ } else {
+ [self showChooseWithCancelButton:isCancelable];
}
}