From 45f1f548fbb133f0292b0403bef8c03d057dec0d Mon Sep 17 00:00:00 2001 From: Alexandre Lision <alexandre.lision@savoirfairelinux.com> Date: Thu, 25 Aug 2016 15:16:17 -0400 Subject: [PATCH] multi-device: add ability to export Ring account This patch adds a Devices panel for Ring accounts. This panel contains the list of devices linked with this Ring account, and the possibility to export the Ring account on the DHT to setup a new device Change-Id: I7281b03d4376fbfc2d74c4e520b8cd0726b9166d Tuleap: #959 --- CMakeLists.txt | 8 +- src/AccDevicesVC.h | 26 +++ src/AccDevicesVC.mm | 134 ++++++++++++ src/AccountsVC.mm | 14 +- src/ExportPasswordWC.h | 45 ++++ src/ExportPasswordWC.mm | 138 ++++++++++++ ui/Base.lproj/AccDevices.xib | 123 +++++++++++ ui/Base.lproj/Accounts.xib | 13 +- ui/Base.lproj/ExportPasswordWindow.strings | 45 ++++ ui/Base.lproj/ExportPasswordWindow.xib | 241 +++++++++++++++++++++ ui/en.lproj/ExportPasswordWindow.strings | 39 ++++ 11 files changed, 820 insertions(+), 6 deletions(-) create mode 100644 src/AccDevicesVC.h create mode 100644 src/AccDevicesVC.mm create mode 100644 src/ExportPasswordWC.h create mode 100644 src/ExportPasswordWC.mm create mode 100644 ui/Base.lproj/AccDevices.xib create mode 100644 ui/Base.lproj/ExportPasswordWindow.strings create mode 100644 ui/Base.lproj/ExportPasswordWindow.xib create mode 100644 ui/en.lproj/ExportPasswordWindow.strings diff --git a/CMakeLists.txt b/CMakeLists.txt index 37fc1843..5ce87048 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,10 @@ SET(ringclient_CONTROLLERS src/LoadingWCDelegate.h src/AbstractLoadingWC.h src/AbstractLoadingWC.mm + src/AccDevicesVC.mm + src/AccDevicesVC.h + src/ExportPasswordWC.mm + src/ExportPasswordWC.h ) SET(ringclient_BACKENDS @@ -196,9 +200,11 @@ SET(ringclient_XIBS RingWizard CertificateWindow PathPasswordWindow + ExportPasswordWindow PersonLinker Broker - Conversation) + Conversation + AccDevices) # Icons # This part tells CMake where to find and install the file itself diff --git a/src/AccDevicesVC.h b/src/AccDevicesVC.h new file mode 100644 index 00000000..3ae4c2d3 --- /dev/null +++ b/src/AccDevicesVC.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2016 Savoir-faire Linux Inc. + * Author: Alexandre Lision <alexandre.lision@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> +#import <account.h> +@interface AccDevicesVC : NSViewController + +@property Account* account; + +@end diff --git a/src/AccDevicesVC.mm b/src/AccDevicesVC.mm new file mode 100644 index 00000000..a712e88b --- /dev/null +++ b/src/AccDevicesVC.mm @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2016 Savoir-faire Linux Inc. + * Author: Alexandre Lision <alexandre.lision@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 "AccDevicesVC.h" + +//Qt +#import <qitemselectionmodel.h> + +//LRC +#import <accountmodel.h> +#import <ringdevicemodel.h> +#import <account.h> + +#import "QNSTreeController.h" +#import "ExportPasswordWC.h" + +@interface AccDevicesVC () <ExportPasswordDelegate> + +@property QNSTreeController* devicesTreeController; +@property ExportPasswordWC* passwordWC; + +@property (unsafe_unretained) IBOutlet NSOutlineView* deviceDetailsView; + +@end + +@implementation AccDevicesVC + +@synthesize passwordWC; + +NSInteger const TAG_NAME = 100; +NSInteger const TAG_DEVICE_IDS = 200; + +- (void)awakeFromNib +{ + NSLog(@"INIT Devices VC"); + + QObject::connect(AccountModel::instance().selectionModel(), + &QItemSelectionModel::currentChanged, + [=](const QModelIndex ¤t, const QModelIndex &previous) { + if(!current.isValid()) + return; + [self loadAccount]; + }); +} + + +- (void)loadAccount +{ + auto account = AccountModel::instance().selectedAccount(); + self.devicesTreeController = [[QNSTreeController alloc] initWithQModel:(QAbstractItemModel*)account->ringDeviceModel()]; + [self.devicesTreeController setAvoidsEmptySelection:NO]; + [self.devicesTreeController setChildrenKeyPath:@"children"]; + + [self.deviceDetailsView bind:@"content" toObject:self.devicesTreeController withKeyPath:@"arrangedObjects" options:nil]; + [self.deviceDetailsView bind:@"sortDescriptors" toObject:self.devicesTreeController withKeyPath:@"sortDescriptors" options:nil]; + [self.deviceDetailsView bind:@"selectionIndexPaths" toObject:self.devicesTreeController withKeyPath:@"selectionIndexPaths" options:nil]; +} + +- (IBAction)startExportOnRing:(id)sender +{ + NSButton* btbAdd = (NSButton *) sender; + + self.account = AccountModel::instance().selectedAccount(); + [self showPasswordPrompt]; +} +#pragma mark - Export methods + +- (void)showPasswordPrompt +{ + auto account = AccountModel::instance().selectedAccount(); + passwordWC = [[ExportPasswordWC alloc] initWithDelegate:self actionCode:1]; + [passwordWC setAccount: account]; +#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9 + [self.view.window beginSheet:passwordWC.window completionHandler:nil]; +#else + [NSApp beginSheet: passwordWC.window + modalForWindow: self.view.window + modalDelegate: self + didEndSelector: nil + contextInfo: nil]; +#endif +} + + +#pragma mark - NSOutlineViewDelegate methods + +- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item +{ + return YES; +} + +- (NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item +{ + return [outlineView makeViewWithIdentifier:@"HoverRowView" owner:nil]; +} + +- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item +{ + NSTableView* result = [outlineView makeViewWithIdentifier:@"DeviceView" owner:self]; + + QModelIndex qIdx = [self.devicesTreeController toQIdx:((NSTreeNode*)item)]; + if(!qIdx.isValid()) + return result; + + NSTextField* nameLabel = [result viewWithTag:TAG_NAME]; + NSTextField* deviceIDLabel = [result viewWithTag:TAG_DEVICE_IDS]; + + auto account = AccountModel::instance().selectedAccount(); + + NSString* string = account->ringDeviceModel()->data(qIdx,Qt::DisplayRole).toString().toNSString(); + + [nameLabel setStringValue:account->alias().toNSString()]; + [deviceIDLabel setStringValue:string]; + + return result; +} + +@end diff --git a/src/AccountsVC.mm b/src/AccountsVC.mm index c6d14e5c..1557915a 100644 --- a/src/AccountsVC.mm +++ b/src/AccountsVC.mm @@ -36,6 +36,7 @@ #import "AccAdvancedVC.h" #import "AccSecurityVC.h" #import "AccRingVC.h" +#import "AccDevicesVC.h" #import "PathPasswordWC.h" @interface AccountsVC () <PathPasswordDelegate> @@ -48,6 +49,7 @@ @property (retain) IBOutlet NSTabViewItem *advancedTabItem; @property (retain) IBOutlet NSTabViewItem *securityTabItem; @property (retain) IBOutlet NSTabViewItem *ringTabItem; +@property (retain) IBOutlet NSTabViewItem *ringDevicesTabItem; @property QNSTreeController *treeController; @property (assign) IBOutlet NSOutlineView *accountsListView; @@ -55,6 +57,7 @@ @property (unsafe_unretained) IBOutlet NSButton* exportAccountButton; @property AccRingVC* ringVC; +@property AccDevicesVC* devicesVC; @property AccGeneralVC* generalVC; @property AccMediaVC* audioVC; @property AccAdvancedVC* advancedVC; @@ -71,6 +74,7 @@ @synthesize advancedTabItem; @synthesize securityTabItem; @synthesize ringTabItem; +@synthesize ringDevicesTabItem; @synthesize accountsListView; @synthesize accountDetailsView; @synthesize treeController; @@ -153,6 +157,11 @@ NSInteger const TAG_TYPE = 400; [[self.ringVC view] setFrame:[self.ringTabItem.view frame]]; [[self.ringVC view] setBounds:[self.ringTabItem.view bounds]]; [self.ringTabItem setView:self.ringVC.view]; + + self.devicesVC = [[AccDevicesVC alloc] initWithNibName:@"AccDevices" bundle:nil]; + [[self.devicesVC view] setFrame:[self.ringDevicesTabItem.view frame]]; + [[self.devicesVC view] setBounds:[self.ringDevicesTabItem.view bounds]]; + [self.ringDevicesTabItem setView:self.devicesVC.view]; } - (IBAction)addAccount:(id)sender { @@ -193,8 +202,9 @@ NSInteger const TAG_TYPE = 400; } [configPanels insertTabViewItem:ringTabItem atIndex:0]; - [configPanels insertTabViewItem:mediaTabItem atIndex:1]; - [configPanels insertTabViewItem:advancedTabItem atIndex:2]; + [configPanels insertTabViewItem:ringDevicesTabItem atIndex:1]; + [configPanels insertTabViewItem:mediaTabItem atIndex:2]; + [configPanels insertTabViewItem:advancedTabItem atIndex:3]; } - (IBAction)exportAccount:(id)sender diff --git a/src/ExportPasswordWC.h b/src/ExportPasswordWC.h new file mode 100644 index 00000000..3a6560cd --- /dev/null +++ b/src/ExportPasswordWC.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 Savoir-faire Linux Inc. + * Author: Alexandre Lision <alexandre.lision@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> + +#import <account.h> + +#import "LoadingWCDelegate.h" +#import "AbstractLoadingWC.h" + +@protocol ExportPasswordDelegate <LoadingWCDelegate> + +@optional +- (void)didCompleteWithPin:(NSString*) path Password:(NSString*) password; +- (void)didStartWithPassword:(NSString*) password; + +@end + +@interface ExportPasswordWC : AbstractLoadingWC + +/** + * password string contained in passwordField. + * This is a KVO method to bind the text with the OK Button + * if password.length is > 0, button is enabled, otherwise disabled + */ +@property (retain) NSString* password; +@property (assign) Account* account; + +@end diff --git a/src/ExportPasswordWC.mm b/src/ExportPasswordWC.mm new file mode 100644 index 00000000..f9b914c6 --- /dev/null +++ b/src/ExportPasswordWC.mm @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2016 Savoir-faire Linux Inc. + * Author: Alexandre Lision <alexandre.lision@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 "ExportPasswordWC.h" + +//LRC +#import <account.h> + +//Ring +#import "views/ITProgressIndicator.h" +@interface ExportPasswordWC() <NSTextFieldDelegate>{ + __unsafe_unretained IBOutlet NSSecureTextField* passwordField; + __unsafe_unretained IBOutlet NSTextField* resultField; + __unsafe_unretained IBOutlet NSTextField* errorField; + __unsafe_unretained IBOutlet ITProgressIndicator* progressIndicator; +} +@end + +@implementation ExportPasswordWC { + struct { + unsigned int didStart:1; + unsigned int didComplete:1; + } delegateRespondsTo; +} + +@synthesize account; +QMetaObject::Connection accountConnection; + + +#pragma mark - Initialize +- (id)initWithDelegate:(id <ExportPasswordDelegate>) del actionCode:(NSInteger) code +{ + return [super initWithWindowNibName:@"ExportPasswordWindow" delegate:del actionCode:code]; +} + +- (void)windowDidLoad +{ + [super windowDidLoad]; +} + +- (void)setDelegate:(id <ExportPasswordDelegate>)aDelegate +{ + if (super.delegate != aDelegate) { + [super setDelegate: aDelegate]; + delegateRespondsTo.didStart = [aDelegate respondsToSelector:@selector(didStartWithPassword:)]; + delegateRespondsTo.didComplete = [aDelegate respondsToSelector:@selector(didCompleteWithPin:Password:)]; + } +} + +- (void)showError:(NSString*) errorMessage +{ + [errorField setStringValue:errorMessage]; + [super showError]; +} + +- (void)showLoading +{ + [progressIndicator setNumberOfLines:30]; + [progressIndicator setWidthOfLine:2]; + [progressIndicator setLengthOfLine:5]; + [progressIndicator setInnerMargin:20]; + [super showLoading]; +} + +#pragma mark - Events Handlers +- (IBAction)completeAction:(id)sender +{ + // Check to avoid exporting an old account (not supported by daemon) + if (account->needsMigration()) { + [self showError:NSLocalizedString(@"You have to migrate your account before exporting", @"Error shown to user")]; + } else { + NSString* password = passwordField.stringValue; + [self showLoading]; + QObject::disconnect(accountConnection); + accountConnection = QObject::connect(account, + &Account::exportOnRingEnded, + [=](Account::ExportOnRingStatus status,const QString &pin) { + NSLog(@"Export ended!"); + switch (status) { + case Account::ExportOnRingStatus::SUCCESS:{ + NSString *nsPin = pin.toNSString(); + NSLog(@"Export ended with Success, pin is %@",nsPin); + [resultField setAttributedStringValue:[self formatPinMessage:nsPin]]; + [self showFinal]; + } + break; + case Account::ExportOnRingStatus::WRONG_PASSWORD:{ + NSLog(@"Export ended with Wrong Password"); + [self showError:NSLocalizedString(@"Export ended with Wrong Password", @"Error shown to the user" )]; + } + break; + case Account::ExportOnRingStatus::NETWORK_ERROR:{ + NSLog(@"Export ended with NetworkError!"); + [self showError:NSLocalizedString(@"A network error occured during the export", @"Error shown to the user" )]; + } + break; + default:{ + NSLog(@"Export ended with Unknown status!"); + [self showError:NSLocalizedString(@"An error occured during the export", @"Error shown to the user" )]; + } + break; + } + }); + account->exportOnRing(QString::fromNSString(password)); + } +} + +//TODO: Move String formatting to a dedicated Utility Classes +- (NSAttributedString *)formatPinMessage:(NSString*) pin +{ + NSMutableAttributedString* hereIsThePin = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"Your generated pin:","Title shown to user to concat with Pin")]; + NSMutableAttributedString* thePin = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@" %@\n", pin]]; + [thePin beginEditing]; + NSRange range = NSMakeRange(0, [thePin length]); + [thePin addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Helvetica-Bold" size:12.0] range:range]; + [hereIsThePin appendAttributedString:thePin]; + NSMutableAttributedString* infos = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"This pin and the account password should be entered on your new device within 5 minutes. On most client, this is done from \"Existing Ring account\" menu. You may generate a new pin at any moment.","Infos on how to use the pin")]; + [hereIsThePin appendAttributedString:infos]; + + return hereIsThePin; +} + +@end diff --git a/ui/Base.lproj/AccDevices.xib b/ui/Base.lproj/AccDevices.xib new file mode 100644 index 00000000..5db46b33 --- /dev/null +++ b/ui/Base.lproj/AccDevices.xib @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="15G1004" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/> + </dependencies> + <objects> + <customObject id="-2" userLabel="File's Owner" customClass="AccDevicesVC"> + <connections> + <outlet property="deviceDetailsView" destination="20b-Ji-RbX" id="A3A-w9-0m5"/> + <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/> + </connections> + </customObject> + <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> + <customView id="Hz6-mo-xeY"> + <rect key="frame" x="0.0" y="0.0" width="576" height="389"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <subviews> + <scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="57" horizontalPageScroll="10" verticalLineScroll="57" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Cn2-3f-RfE"> + <rect key="frame" x="20" y="20" width="536" height="219"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <clipView key="contentView" ambiguous="YES" id="5RD-uP-uce"> + <rect key="frame" x="0.0" y="0.0" width="536" height="219"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" autosaveColumns="NO" rowHeight="55" rowSizeStyle="automatic" viewBased="YES" outlineTableColumn="Sv0-5z-dC2" id="20b-Ji-RbX" customClass="RingOutlineView"> + <rect key="frame" x="0.0" y="0.0" width="536" height="219"/> + <autoresizingMask key="autoresizingMask"/> + <size key="intercellSpacing" width="3" height="2"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/> + <tableColumns> + <tableColumn width="533" minWidth="40" maxWidth="1000" id="Sv0-5z-dC2"> + <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border"> + <font key="font" metaFont="smallSystem"/> + <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/> + </tableHeaderCell> + <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" id="eNP-Qg-jM1"> + <font key="font" metaFont="system"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/> + <prototypeCellViews> + <tableCellView identifier="DeviceView" id="V2l-Lf-B1r"> + <rect key="frame" x="1" y="1" width="533" height="50"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <textField verticalHuggingPriority="750" tag="200" translatesAutoresizingMaskIntoConstraints="NO" id="mif-hy-cnh" userLabel="Status label"> + <rect key="frame" x="38" y="6" width="38" height="14"/> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" placeholderString="Status" id="mAD-1Z-aYB"> + <font key="font" metaFont="smallSystem"/> + <color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <textField verticalHuggingPriority="750" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="UbS-VO-lii" userLabel="Name label"> + <rect key="frame" x="38" y="26" width="208" height="21"/> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" placeholderString="Name" id="w62-Jz-2tu"> + <font key="font" metaFont="system" size="17"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + </subviews> + <constraints> + <constraint firstItem="UbS-VO-lii" firstAttribute="top" secondItem="V2l-Lf-B1r" secondAttribute="top" constant="3" id="1UM-xz-ZNR"/> + <constraint firstItem="mif-hy-cnh" firstAttribute="leading" secondItem="V2l-Lf-B1r" secondAttribute="leading" constant="40" id="CQT-Fu-bgB"/> + <constraint firstAttribute="trailing" secondItem="UbS-VO-lii" secondAttribute="trailing" constant="289" id="YkQ-XF-ydv"/> + <constraint firstItem="UbS-VO-lii" firstAttribute="top" secondItem="V2l-Lf-B1r" secondAttribute="top" constant="3" id="hCv-J7-Ivx"/> + <constraint firstItem="mif-hy-cnh" firstAttribute="top" secondItem="UbS-VO-lii" secondAttribute="bottom" constant="6" id="lKI-61-ssq"/> + <constraint firstItem="mif-hy-cnh" firstAttribute="top" secondItem="UbS-VO-lii" secondAttribute="bottom" constant="6" id="vWW-7c-2Hk"/> + <constraint firstItem="UbS-VO-lii" firstAttribute="leading" secondItem="V2l-Lf-B1r" secondAttribute="leading" constant="40" id="yh9-rt-7e7"/> + </constraints> + </tableCellView> + <customView identifier="HoverRowView" id="lBd-rL-ixN" customClass="HoverTableRowView"> + <rect key="frame" x="1" y="53" width="533" height="55"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + </customView> + </prototypeCellViews> + </tableColumn> + </tableColumns> + <connections> + <outlet property="delegate" destination="-2" id="Q8m-cE-QXK"/> + </connections> + </outlineView> + </subviews> + </clipView> + <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="xKj-nZ-7Mx"> + <rect key="frame" x="0.0" y="-16" width="0.0" height="16"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="eiD-YY-HVN"> + <rect key="frame" x="-16" y="0.0" width="16" height="0.0"/> + <autoresizingMask key="autoresizingMask"/> + </scroller> + </scrollView> + <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="K8a-3i-BoE"> + <rect key="frame" x="18" y="310" width="540" height="54"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Use the same Ring account on multiple devices." id="kMd-iv-UAy"> + <font key="font" metaFont="system"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hbO-OT-jpc"> + <rect key="frame" x="220" y="274" width="136" height="32"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <buttonCell key="cell" type="push" title="Add new device" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="uDY-qB-G0I"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="startExportOnRing:" target="-2" id="6cr-RZ-7Wi"/> + </connections> + </button> + </subviews> + <point key="canvasLocation" x="377" y="270.5"/> + </customView> + </objects> +</document> diff --git a/ui/Base.lproj/Accounts.xib b/ui/Base.lproj/Accounts.xib index ea72abea..ee7b8906 100644 --- a/ui/Base.lproj/Accounts.xib +++ b/ui/Base.lproj/Accounts.xib @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> <dependencies> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9532"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/> </dependencies> <objects> <customObject id="-2" userLabel="File's Owner" customClass="AccountsVC"> @@ -14,6 +14,7 @@ <outlet property="generalTabItem" destination="tPR-Ac-N5Y" id="39S-pz-1Xs"/> <outlet property="mediaTabItem" destination="lxr-my-vH8" id="BhJ-cS-yVi"/> <outlet property="protocolList" destination="rZv-qd-BGe" id="yU0-6C-Vt1"/> + <outlet property="ringDevicesTabItem" destination="cT1-A5-rbj" id="Sql-e4-mD8"/> <outlet property="ringTabItem" destination="1HC-kF-Jun" id="FJZ-2g-Y1i"/> <outlet property="securityTabItem" destination="Vp5-yV-ScC" id="FDx-0T-3t9"/> <outlet property="view" destination="Hz6-mo-xeY" id="eBn-rZ-84z"/> @@ -59,6 +60,12 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> </view> </tabViewItem> + <tabViewItem label="Devices" identifier="" id="cT1-A5-rbj"> + <view key="view" id="Ey1-5D-Zou"> + <rect key="frame" x="10" y="33" width="576" height="565"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + </view> + </tabViewItem> </tabViewItems> <connections> <outlet property="delegate" destination="-2" id="hfK-WK-DJT"/> @@ -71,7 +78,7 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" autosaveColumns="NO" rowHeight="55" rowSizeStyle="automatic" viewBased="YES" outlineTableColumn="eOe-f3-q88" id="jXv-6I-P9R" customClass="RingOutlineView"> - <rect key="frame" x="0.0" y="0.0" width="250" height="500"/> + <rect key="frame" x="0.0" y="0.0" width="250" height="0.0"/> <autoresizingMask key="autoresizingMask"/> <size key="intercellSpacing" width="3" height="2"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> diff --git a/ui/Base.lproj/ExportPasswordWindow.strings b/ui/Base.lproj/ExportPasswordWindow.strings new file mode 100644 index 00000000..10cd6259 --- /dev/null +++ b/ui/Base.lproj/ExportPasswordWindow.strings @@ -0,0 +1,45 @@ + +/* Class = "BindingConnection"; ibShadowedIsNilPlaceholder = "Password..."; ObjectID = "5cX-yS-4Sl"; */ +"5cX-yS-4Sl.ibShadowedIsNilPlaceholder" = "Password..."; + +/* Class = "BindingConnection"; ibShadowedMultipleValuesPlaceholder = "Password..."; ObjectID = "5cX-yS-4Sl"; */ +"5cX-yS-4Sl.ibShadowedMultipleValuesPlaceholder" = "Password..."; + +/* Class = "BindingConnection"; ibShadowedNoSelectionPlaceholder = "Password..."; ObjectID = "5cX-yS-4Sl"; */ +"5cX-yS-4Sl.ibShadowedNoSelectionPlaceholder" = "Password..."; + +/* Class = "BindingConnection"; ibShadowedNotApplicablePlaceholder = "Password..."; ObjectID = "5cX-yS-4Sl"; */ +"5cX-yS-4Sl.ibShadowedNotApplicablePlaceholder" = "Password..."; + +/* Class = "NSTextFieldCell"; title = "To add a new device to your Ring account, you export your account on the Ring. This will generate a pin that must be entered on your new device within 5 minutes of its generation."; ObjectID = "859-10-HEb"; */ +"859-10-HEb.title" = "To add a new device to your Ring account, you export your account on the Ring. This will generate a pin that must be entered on your new device within 5 minutes of its generation."; + +/* Class = "NSWindow"; title = "Window"; ObjectID = "QvC-M9-y7g"; */ +"QvC-M9-y7g.title" = "Window"; + +/* Class = "NSTextFieldCell"; placeholderString = "error label"; ObjectID = "Ua9-fG-r6k"; */ +"Ua9-fG-r6k.placeholderString" = "error label"; + +/* Class = "NSButtonCell"; title = "OK"; ObjectID = "VN1-A3-RIh"; */ +"VN1-A3-RIh.title" = "OK"; + +/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "cSU-aD-OwX"; */ +"cSU-aD-OwX.title" = "Cancel"; + +/* Class = "NSButtonCell"; title = "OK"; ObjectID = "cre-OL-lZy"; */ +"cre-OL-lZy.title" = "OK"; + +/* Class = "NSTextFieldCell"; placeholderString = "error label"; ObjectID = "e7n-Ev-bK7"; */ +"e7n-Ev-bK7.placeholderString" = "error label"; + +/* Class = "NSButtonCell"; title = "OK"; ObjectID = "rW5-Il-5YD"; */ +"rW5-Il-5YD.title" = "OK"; + +/* Class = "NSTextFieldCell"; title = "Password"; ObjectID = "vwh-K9-3O9"; */ +"vwh-K9-3O9.title" = "Password"; + +/* Class = "NSTextFieldCell"; title = "Adding new device"; ObjectID = "wmv-sA-Mlh"; */ +"wmv-sA-Mlh.title" = "Adding new device"; + +/* Class = "NSSecureTextFieldCell"; placeholderString = "Password..."; ObjectID = "xqz-Uz-hqU"; */ +"xqz-Uz-hqU.placeholderString" = "Password..."; diff --git a/ui/Base.lproj/ExportPasswordWindow.xib b/ui/Base.lproj/ExportPasswordWindow.xib new file mode 100644 index 00000000..c2631f2e --- /dev/null +++ b/ui/Base.lproj/ExportPasswordWindow.xib @@ -0,0 +1,241 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="15G1004" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/> + <capability name="Aspect ratio constraints" minToolsVersion="5.1"/> + </dependencies> + <objects> + <customObject id="-2" userLabel="File's Owner" customClass="ExportPasswordWC"> + <connections> + <outlet property="errorContainer" destination="ty1-sj-tT6" id="eEy-Cr-yiw"/> + <outlet property="errorField" destination="G1N-th-ZtP" id="3Qf-fy-ie3"/> + <outlet property="finalContainer" destination="srJ-1d-Sbs" id="BP0-xw-uwV"/> + <outlet property="initialContainer" destination="xUT-yB-g8Q" id="CZQ-jg-fnH"/> + <outlet property="passwordField" destination="vej-Z8-dOm" id="Ff0-Rb-Al6"/> + <outlet property="progressContainer" destination="AGJ-1n-ZWv" id="1i0-bR-eog"/> + <outlet property="progressIndicator" destination="Ovf-4O-7LZ" id="3ak-Ju-PkY"/> + <outlet property="resultField" destination="M0M-Fg-Znl" id="Y5c-jF-Tij"/> + <outlet property="window" destination="QvC-M9-y7g" id="bos-rN-Jgz"/> + </connections> + </customObject> + <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> + <window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g"> + <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/> + <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> + <rect key="contentRect" x="196" y="240" width="410" height="191"/> + <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/> + <view key="contentView" id="EiT-Mj-1SZ"> + <rect key="frame" x="0.0" y="0.0" width="410" height="191"/> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="AGJ-1n-ZWv"> + <rect key="frame" x="15" y="15" width="380" height="166"/> + <subviews> + <customView hidden="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ovf-4O-7LZ" customClass="ITProgressIndicator"> + <rect key="frame" x="155" y="48" width="70" height="70"/> + <constraints> + <constraint firstAttribute="width" constant="70" id="CYq-9V-MRO"/> + <constraint firstAttribute="height" constant="70" id="oZI-2d-W12"/> + </constraints> + </customView> + </subviews> + <constraints> + <constraint firstItem="Ovf-4O-7LZ" firstAttribute="centerY" secondItem="AGJ-1n-ZWv" secondAttribute="centerY" id="4ka-be-3Bb"/> + <constraint firstItem="Ovf-4O-7LZ" firstAttribute="width" secondItem="AGJ-1n-ZWv" secondAttribute="height" multiplier="35:83" id="Ntl-ue-3m3"/> + <constraint firstItem="Ovf-4O-7LZ" firstAttribute="centerX" secondItem="AGJ-1n-ZWv" secondAttribute="centerX" id="teu-Ra-LR8"/> + </constraints> + </customView> + <customView translatesAutoresizingMaskIntoConstraints="NO" id="xUT-yB-g8Q"> + <rect key="frame" x="15" y="10" width="380" height="171"/> + <subviews> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Bcr-Pl-Fz9"> + <rect key="frame" x="45" y="39" width="63" height="17"/> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Password" id="vwh-K9-3O9"> + <font key="font" metaFont="system"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <secureTextField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vej-Z8-dOm"> + <rect key="frame" x="113" y="36" width="210" height="22"/> + <secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Password..." drawsBackground="YES" usesSingleLineMode="YES" id="xqz-Uz-hqU"> + <font key="font" metaFont="system"/> + <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> + <allowedInputSourceLocales> + <string>NSAllRomanInputSourcesLocaleIdentifier</string> + </allowedInputSourceLocales> + </secureTextFieldCell> + <connections> + <binding destination="-2" name="value" keyPath="self.password" id="5cX-yS-4Sl"> + <dictionary key="options"> + <bool key="NSContinuouslyUpdatesValue" value="YES"/> + <string key="NSMultipleValuesPlaceholder">Password...</string> + <string key="NSNoSelectionPlaceholder">Password...</string> + <string key="NSNotApplicablePlaceholder">Password...</string> + <string key="NSNullPlaceholder">Password...</string> + </dictionary> + </binding> + <outlet property="delegate" destination="-2" id="UEj-AI-SPU"/> + </connections> + </secureTextField> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YR8-e7-f8B"> + <rect key="frame" x="45" y="142" width="280" height="17"/> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Adding new device" id="wmv-sA-Mlh"> + <font key="font" metaFont="systemBold"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oXB-Be-LaB"> + <rect key="frame" x="327" y="-7" width="59" height="32"/> + <buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="rW5-Il-5YD"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + <string key="keyEquivalent" base64-UTF8="YES"> +DQ +</string> + </buttonCell> + <connections> + <action selector="completeAction:" target="-2" id="4me-jZ-4mk"/> + <binding destination="-2" name="enabled" keyPath="self.password.length" id="KN4-nF-wwM"/> + </connections> + </button> + <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="Qx0-KE-jEl"> + <rect key="frame" x="18" y="66" width="344" height="68"/> + <constraints> + <constraint firstAttribute="height" constant="68" id="g34-vr-Zas"/> + </constraints> + <textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="justified" id="859-10-HEb"> + <font key="font" metaFont="system"/> + <string key="title">To add a new device to your Ring account, you export your account on the Ring. This will generate a pin that must be entered on your new device within 5 minutes of its generation.</string> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Yf1-T3-fOf"> + <rect key="frame" x="237" y="-7" width="82" height="32"/> + <buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="cSU-aD-OwX"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + <string key="keyEquivalent" base64-UTF8="YES"> +Gw +</string> + </buttonCell> + <connections> + <action selector="cancelPressed:" target="-2" id="bIl-jp-gRS"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstItem="vej-Z8-dOm" firstAttribute="top" secondItem="Qx0-KE-jEl" secondAttribute="bottom" constant="8" id="12Q-Te-DMO"/> + <constraint firstItem="YR8-e7-f8B" firstAttribute="leading" secondItem="xUT-yB-g8Q" secondAttribute="leading" constant="47" id="86W-iT-c6E"/> + <constraint firstItem="YR8-e7-f8B" firstAttribute="trailing" secondItem="vej-Z8-dOm" secondAttribute="trailing" id="97f-vZ-ehW"/> + <constraint firstAttribute="trailing" secondItem="Qx0-KE-jEl" secondAttribute="trailing" constant="20" id="FV8-cW-4Ua"/> + <constraint firstItem="Qx0-KE-jEl" firstAttribute="leading" secondItem="xUT-yB-g8Q" secondAttribute="leading" constant="20" id="GL9-b9-rHs"/> + <constraint firstItem="oXB-Be-LaB" firstAttribute="leading" secondItem="Yf1-T3-fOf" secondAttribute="trailing" constant="20" id="Ghk-zq-b9T"/> + <constraint firstItem="Bcr-Pl-Fz9" firstAttribute="baseline" secondItem="vej-Z8-dOm" secondAttribute="baseline" id="MM1-gt-2Ln"/> + <constraint firstItem="Qx0-KE-jEl" firstAttribute="top" secondItem="YR8-e7-f8B" secondAttribute="bottom" constant="8" id="OPG-g5-b8f"/> + <constraint firstItem="YR8-e7-f8B" firstAttribute="top" secondItem="xUT-yB-g8Q" secondAttribute="top" constant="12" id="T0q-sr-B1c"/> + <constraint firstItem="vej-Z8-dOm" firstAttribute="leading" secondItem="Bcr-Pl-Fz9" secondAttribute="trailing" constant="7" id="ibU-NT-KTl"/> + <constraint firstAttribute="bottom" secondItem="Yf1-T3-fOf" secondAttribute="bottom" id="kKt-h2-PSf"/> + <constraint firstItem="Bcr-Pl-Fz9" firstAttribute="top" secondItem="Qx0-KE-jEl" secondAttribute="bottom" constant="10" id="md2-cC-e45"/> + <constraint firstAttribute="trailing" secondItem="oXB-Be-LaB" secondAttribute="trailing" id="nc0-bc-HZy"/> + <constraint firstItem="Qx0-KE-jEl" firstAttribute="top" secondItem="YR8-e7-f8B" secondAttribute="bottom" constant="8" symbolic="YES" id="sQ9-yl-Dxe"/> + <constraint firstAttribute="trailing" secondItem="YR8-e7-f8B" secondAttribute="trailing" constant="57" id="slS-SE-ulf"/> + <constraint firstAttribute="bottom" secondItem="oXB-Be-LaB" secondAttribute="bottom" id="upQ-xH-MIe"/> + <constraint firstItem="YR8-e7-f8B" firstAttribute="leading" secondItem="Bcr-Pl-Fz9" secondAttribute="leading" id="wF5-CT-zPE"/> + </constraints> + </customView> + <customView hidden="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ty1-sj-tT6"> + <rect key="frame" x="15" y="10" width="380" height="171"/> + <subviews> + <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G1N-th-ZtP"> + <rect key="frame" x="-2" y="0.0" width="384" height="132"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" alignment="left" placeholderString="error label" id="e7n-Ev-bK7"> + <font key="font" metaFont="system"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cxh-K7-1eh"> + <rect key="frame" x="327" y="-7" width="59" height="32"/> + <buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="VN1-A3-RIh"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + <string key="keyEquivalent" base64-UTF8="YES"> +DQ +</string> + </buttonCell> + <connections> + <action selector="cancelPressed:" target="-2" id="JTp-N4-Tb8"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstAttribute="trailing" secondItem="cxh-K7-1eh" secondAttribute="trailing" id="OrO-VW-3Xw"/> + <constraint firstAttribute="bottom" secondItem="cxh-K7-1eh" secondAttribute="bottom" id="tLl-Ru-JDw"/> + <constraint firstItem="cxh-K7-1eh" firstAttribute="width" secondItem="ty1-sj-tT6" secondAttribute="height" multiplier="47:171" id="xxl-WJ-uWd"/> + </constraints> + </customView> + <customView hidden="YES" translatesAutoresizingMaskIntoConstraints="NO" id="srJ-1d-Sbs"> + <rect key="frame" x="15" y="10" width="380" height="171"/> + <subviews> + <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="M0M-Fg-Znl"> + <rect key="frame" x="-2" y="0.0" width="384" height="132"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" alignment="left" placeholderString="finish label" id="ezj-X9-NQd"> + <font key="font" metaFont="system"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> + <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="I5i-KQ-7yI"> + <rect key="frame" x="327" y="-7" width="59" height="32"/> + <buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="dfD-AK-f3R"> + <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> + <font key="font" metaFont="system"/> + <string key="keyEquivalent" base64-UTF8="YES"> +DQ +</string> + </buttonCell> + <connections> + <action selector="cancelPressed:" target="-2" id="NWs-SH-M68"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstItem="I5i-KQ-7yI" firstAttribute="width" secondItem="srJ-1d-Sbs" secondAttribute="height" multiplier="47:171" id="1kj-gX-F60"/> + <constraint firstAttribute="trailing" secondItem="I5i-KQ-7yI" secondAttribute="trailing" id="L4m-3f-iAH"/> + <constraint firstAttribute="bottom" secondItem="I5i-KQ-7yI" secondAttribute="bottom" id="OA3-eH-jPg"/> + </constraints> + </customView> + </subviews> + <constraints> + <constraint firstAttribute="trailing" secondItem="xUT-yB-g8Q" secondAttribute="trailing" constant="15" id="0cz-Qg-8O3"/> + <constraint firstAttribute="bottom" secondItem="ty1-sj-tT6" secondAttribute="bottom" constant="10" id="1bi-Qk-WJf"/> + <constraint firstItem="xUT-yB-g8Q" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="10" id="80V-3H-yhe"/> + <constraint firstItem="ty1-sj-tT6" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="15" id="JfP-nv-HzG"/> + <constraint firstItem="srJ-1d-Sbs" firstAttribute="leading" secondItem="xUT-yB-g8Q" secondAttribute="leading" id="LX2-ln-cMG"/> + <constraint firstItem="ty1-sj-tT6" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="10" id="WRY-iS-AnI"/> + <constraint firstItem="srJ-1d-Sbs" firstAttribute="trailing" secondItem="xUT-yB-g8Q" secondAttribute="trailing" id="X7E-dC-Irw"/> + <constraint firstItem="AGJ-1n-ZWv" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="15" id="fQD-sb-Ef1"/> + <constraint firstItem="xUT-yB-g8Q" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="15" id="hyR-9O-NC2"/> + <constraint firstAttribute="trailing" secondItem="ty1-sj-tT6" secondAttribute="trailing" constant="15" id="kMD-cN-UU3"/> + <constraint firstAttribute="bottom" secondItem="xUT-yB-g8Q" secondAttribute="bottom" constant="10" id="p1f-f1-8dd"/> + <constraint firstAttribute="trailing" secondItem="AGJ-1n-ZWv" secondAttribute="trailing" constant="15" id="pRc-7V-4dD"/> + <constraint firstItem="srJ-1d-Sbs" firstAttribute="top" secondItem="xUT-yB-g8Q" secondAttribute="top" id="uGQ-Kt-GUW"/> + <constraint firstItem="AGJ-1n-ZWv" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="10" id="xBv-N5-u4V"/> + <constraint firstAttribute="bottom" secondItem="AGJ-1n-ZWv" secondAttribute="bottom" constant="15" id="xtD-fH-ddM"/> + </constraints> + </view> + <connections> + <outlet property="delegate" destination="-2" id="3wn-SC-48D"/> + </connections> + <point key="canvasLocation" x="-420" y="-196.5"/> + </window> + <userDefaultsController representsSharedInstance="YES" id="2A5-Q9-edp"/> + </objects> +</document> diff --git a/ui/en.lproj/ExportPasswordWindow.strings b/ui/en.lproj/ExportPasswordWindow.strings new file mode 100644 index 00000000..4ee23625 --- /dev/null +++ b/ui/en.lproj/ExportPasswordWindow.strings @@ -0,0 +1,39 @@ + +/* Class = "BindingConnection"; ibShadowedIsNilPlaceholder = "Password..."; ObjectID = "5cX-yS-4Sl"; */ +"5cX-yS-4Sl.ibShadowedIsNilPlaceholder" = "Password..."; + +/* Class = "BindingConnection"; ibShadowedMultipleValuesPlaceholder = "Password..."; ObjectID = "5cX-yS-4Sl"; */ +"5cX-yS-4Sl.ibShadowedMultipleValuesPlaceholder" = "Password..."; + +/* Class = "BindingConnection"; ibShadowedNoSelectionPlaceholder = "Password..."; ObjectID = "5cX-yS-4Sl"; */ +"5cX-yS-4Sl.ibShadowedNoSelectionPlaceholder" = "Password..."; + +/* Class = "BindingConnection"; ibShadowedNotApplicablePlaceholder = "Password..."; ObjectID = "5cX-yS-4Sl"; */ +"5cX-yS-4Sl.ibShadowedNotApplicablePlaceholder" = "Password..."; + +/* Class = "NSTextFieldCell"; title = "To add a new device to your Ring account, you export your account on the Ring. This will generate a pin that must be entered on your new device within 5 minutes of its generation."; ObjectID = "859-10-HEb"; */ +"859-10-HEb.title" = "To add a new device to your Ring account, you export your account on the Ring. This will generate a pin that must be entered on your new device within 5 minutes of its generation."; + +/* Class = "NSWindow"; title = "Window"; ObjectID = "QvC-M9-y7g"; */ +"QvC-M9-y7g.title" = "Window"; + +/* Class = "NSButtonCell"; title = "OK"; ObjectID = "VN1-A3-RIh"; */ +"VN1-A3-RIh.title" = "OK"; + +/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "cSU-aD-OwX"; */ +"cSU-aD-OwX.title" = "Cancel"; + +/* Class = "NSTextFieldCell"; placeholderString = "error label"; ObjectID = "e7n-Ev-bK7"; */ +"e7n-Ev-bK7.placeholderString" = "error label"; + +/* Class = "NSButtonCell"; title = "OK"; ObjectID = "rW5-Il-5YD"; */ +"rW5-Il-5YD.title" = "OK"; + +/* Class = "NSTextFieldCell"; title = "Password"; ObjectID = "vwh-K9-3O9"; */ +"vwh-K9-3O9.title" = "Password"; + +/* Class = "NSTextFieldCell"; title = "Adding new device"; ObjectID = "wmv-sA-Mlh"; */ +"wmv-sA-Mlh.title" = "Adding new device"; + +/* Class = "NSSecureTextFieldCell"; placeholderString = "Password..."; ObjectID = "xqz-Uz-hqU"; */ +"xqz-Uz-hqU.placeholderString" = "Password..."; -- GitLab