summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSMacOSX/DomainBrowser/iOS/CNDomainBrowserViewController.m
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSMacOSX/DomainBrowser/iOS/CNDomainBrowserViewController.m')
-rw-r--r--mDNSResponder/mDNSMacOSX/DomainBrowser/iOS/CNDomainBrowserViewController.m350
1 files changed, 350 insertions, 0 deletions
diff --git a/mDNSResponder/mDNSMacOSX/DomainBrowser/iOS/CNDomainBrowserViewController.m b/mDNSResponder/mDNSMacOSX/DomainBrowser/iOS/CNDomainBrowserViewController.m
new file mode 100644
index 00000000..b8c9e65c
--- /dev/null
+++ b/mDNSResponder/mDNSMacOSX/DomainBrowser/iOS/CNDomainBrowserViewController.m
@@ -0,0 +1,350 @@
+/*
+ *
+ * Copyright (c) 2016 Apple Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "CNDomainBrowserViewController.h"
+#import "_CNDomainBrowser.h"
+#import "CNDomainBrowserPathUtils.h"
+#import <AssertMacros.h>
+
+#define LocalizedStringFromTableInMyBundle(key, table, comment) \
+ NSLocalizedStringFromTableInBundle(key, table, [NSBundle bundleForClass: [self class]], comment)
+
+
+@interface CNTableViewController()
+@property (copy) NSArray * pathArray;
+@property (assign) NSInteger selectionIndex;
+@end
+
+@implementation CNTableViewController
+
+- (instancetype)initWithStyle:(UITableViewStyle)style
+{
+ if (self = [super initWithStyle: style])
+ {
+ _selectionIndex = NSNotFound;
+ _pathArray = [NSArray array];
+ }
+ return self;
+}
+
+@end
+
+@interface CNDomainBrowserViewController ()
+
+@property _CNDomainBrowser * bonjour;
+
+@property (strong) NSMutableDictionary * instanceInfoStrings;
+@property (strong) NSMutableDictionary * instanceStatusViews;
+
+@end
+
+@implementation CNDomainBrowserViewController
+
+- (instancetype)initWithStyle:(UITableViewStyle)style
+{
+ if (self = [super initWithStyle: style])
+ {
+ [self commonInit];
+ }
+ return(self);
+}
+
+- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ if (self = [super initWithNibName: nibNameOrNil bundle: nibBundleOrNil])
+ {
+ [self commonInit];
+ }
+ return(self);
+}
+
+- (nullable instancetype)initWithCoder:(NSCoder *)coder
+{
+ if (self = [super initWithCoder: coder])
+ {
+ [self commonInit];
+ }
+ return(self);
+}
+
+- (void)commonInit
+{
+ self.bonjour = [[_CNDomainBrowser alloc] initWithDelegate: (id<_CNDomainBrowserDelegate>)self];
+ self.bonjour.browseRegistration = _browseRegistration;
+ self.bonjour.ignoreLocal = _ignoreLocal;
+ self.instanceInfoStrings = [NSMutableDictionary dictionary];
+ self.instanceStatusViews = [NSMutableDictionary dictionary];
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear: animated];
+ NSArray * pathArray = DNSDomainToDomainPath(_selectedDNSDomain);
+ if ((self.isMovingToParentViewController || self.isBeingPresented) && (pathArray.count > 1))
+ {
+ [self updateUIToDomainPathArray: pathArray];
+ }
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.tableView.allowsMultipleSelectionDuringEditing = NO;
+ self.tableView.dataSource = (id<UITableViewDataSource>)self;
+ self.tableView.delegate = (id<UITableViewDelegate>)self;
+
+ self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: LocalizedStringFromTableInMyBundle(@"_dnsBrowser.browsedomains.cancel", @"DomainBrowser", nil)
+ style: UIBarButtonItemStylePlain
+ target: self
+ action: @selector(cancelAction:)];
+
+}
+
+- (void)updateUIToDomainPathArray:(NSArray *)newPathArray
+{
+ if (newPathArray.count > 1)
+ {
+ CNTableViewController * controller = nil;
+ NSMutableArray * newSubPathArray = [NSMutableArray array];
+ for (NSString * nextPathComponent in newPathArray)
+ {
+ BOOL animate = NO;//(newPathArray.count == ++count);
+ controller = [self pushNewBrowseController: newSubPathArray.lastObject animated: animate];
+ controller.pathArray = newSubPathArray;
+ [newSubPathArray addObject: nextPathComponent];
+ }
+ }
+}
+
+- (IBAction)cancelAction:(id)sender
+{
+ (void)sender; // Unused
+ [self.navigationController dismissViewControllerAnimated: YES completion: nil];
+}
+
+- (CNTableViewController *)pushNewBrowseController:(NSString *)title animated:(BOOL)animated
+{
+ CNTableViewController *tvc = [[CNTableViewController alloc] initWithStyle: self.tableView.style];
+ tvc.title = title;
+ tvc.clearsSelectionOnViewWillAppear = NO;
+ tvc.tableView.dataSource = (id<UITableViewDataSource>)self;
+ tvc.tableView.delegate = (id<UITableViewDelegate>)self;
+ [self.navigationController pushViewController: tvc animated: animated];
+ return(tvc);
+}
+
+- (CNTableViewController *)controllerForTableView:(UITableView *)tableView
+{
+ CNTableViewController * result = nil;
+
+ for (CNTableViewController * next in self.navigationController.viewControllers)
+ {
+ if ([next isKindOfClass: [CNTableViewController class]] && next.tableView == tableView)
+ {
+ result = next;
+ break;
+ }
+ }
+
+ return(result);
+}
+
+- (NSArray *)selectedPathArrayForTableView:(UITableView *)tableView includeSelectedRow:(BOOL)includeSelection
+{
+ NSMutableArray * pathArray = [NSMutableArray array];
+ CNTableViewController * controller = [self controllerForTableView: tableView];
+
+ [pathArray addObjectsFromArray: controller.pathArray];
+
+ if (includeSelection && controller.selectionIndex != NSNotFound)
+ {
+ NSArray * rowArray = [[self.bonjour subDomainsAtDomainPath: pathArray] sortedArrayUsingComparator: ^(id obj1, id obj2) {
+ return (NSComparisonResult)[ obj1[_CNSubDomainKey_subPath] compare: obj2[_CNSubDomainKey_subPath]];
+ }];
+ if (controller.selectionIndex < (NSInteger)rowArray.count)
+ {
+ [pathArray addObject: rowArray[controller.selectionIndex][_CNSubDomainKey_subPath]];
+ }
+ }
+
+ return(pathArray);
+}
+
+- (void)plusButtonPressed:(UIControl *)button withEvent:(UIEvent *)event
+{
+ UITableView * tableView = ((UITableViewController *)self.navigationController.topViewController).tableView;
+ NSIndexPath * indexPath = [tableView indexPathForRowAtPoint: [[[event touchesForView: button] anyObject] locationInView: tableView]];
+ if (indexPath != nil && self.delegate)
+ {
+ [self controllerForTableView: tableView].selectionIndex = indexPath.row;
+ NSArray * pathArray = [self selectedPathArrayForTableView: ((CNTableViewController *)self.navigationController.topViewController).tableView includeSelectedRow: YES];
+ _selectedDNSDomain = DomainPathToDNSDomain(pathArray);
+ [self.navigationController dismissViewControllerAnimated: YES completion: ^{
+ if ([self.delegate respondsToSelector: @selector(domainBrowserDomainSelected:)])
+ {
+ [self.delegate domainBrowserDomainSelected: _selectedDNSDomain];
+ }
+ }];
+ }
+}
+
+#pragma mark - Public Methods
+
+- (void)setIgnoreLocal:(BOOL)ignoreLocal
+{
+ _ignoreLocal = ignoreLocal;
+ self.bonjour.ignoreLocal = _ignoreLocal;
+}
+
+- (void)setBrowseRegistration:(BOOL)browseRegistration
+{
+ _browseRegistration = browseRegistration;
+ self.bonjour.browseRegistration = _browseRegistration;
+}
+
+- (NSString *)defaultDNSDomain
+{
+ return(DomainPathToDNSDomain(self.bonjour.defaultDomainPath));
+}
+
+- (NSArray *)flattenedDNSDomains
+{
+ return(self.bonjour.flattenedDNSDomains);
+}
+
+- (void)startBrowse
+{
+ [self.bonjour startBrowser];
+}
+
+- (void)stopBrowse
+{
+ [self.bonjour stopBrowser];
+}
+
+- (BOOL)isBrowsing
+{
+ return(self.bonjour.isBrowsing);
+}
+
+#pragma mark - TableView Delegates
+
+- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ (void)tableView; // Unused
+ (void)indexPath; // Unused
+ return UITableViewAutomaticDimension;
+}
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ (void)tableView; // Unused
+ return(1);
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+ (void)section; // Unused
+ return([self.bonjour subDomainsAtDomainPath: [self selectedPathArrayForTableView: tableView includeSelectedRow: NO]].count);
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ UITableViewCell *cell = nil;
+
+ static NSString *MyIdentifier = @"browse_cell_id";
+ cell = [tableView dequeueReusableCellWithIdentifier: MyIdentifier];
+ if (!cell)
+ {
+ cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: MyIdentifier];
+ }
+
+ // Get the name
+ NSMutableArray * pathArray = [NSMutableArray arrayWithArray: [self selectedPathArrayForTableView: tableView includeSelectedRow: NO]];
+ NSArray * rowArray = [[self.bonjour subDomainsAtDomainPath: pathArray] sortedArrayUsingComparator: ^(id obj1, id obj2) {
+ return (NSComparisonResult)[ obj1[_CNSubDomainKey_subPath] compare: obj2[_CNSubDomainKey_subPath]];
+ }];
+ if (indexPath.row < (NSInteger)rowArray.count)
+ {
+ NSDictionary * item = [rowArray objectAtIndex: indexPath.row];
+ NSString *val = item[_CNSubDomainKey_subPath];
+ cell.textLabel.text = val;
+
+ // Set selection
+ BOOL selected = ([self controllerForTableView: tableView].selectionIndex == indexPath.row);
+ if (selected) [tableView selectRowAtIndexPath: indexPath animated: NO scrollPosition: UITableViewScrollPositionNone];
+
+ // Make Default domain bold
+ if ([item[_CNSubDomainKey_defaultFlag] boolValue]) cell.textLabel.font = [UIFont boldSystemFontOfSize: [UIFont labelFontSize]];
+ else cell.textLabel.font = nil;
+
+ // See if it's a leaf
+ [pathArray addObject: val];
+ cell.accessoryType = [self.bonjour subDomainsAtDomainPath: pathArray].count ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
+
+ // Add the "+" button
+ UIButton * plus = [UIButton buttonWithType: UIButtonTypeContactAdd];
+ [plus addTarget: self action: @selector(plusButtonPressed:withEvent:) forControlEvents: UIControlEventTouchUpInside];
+ plus.userInteractionEnabled = YES;
+ [cell.contentView addSubview: plus];
+
+ plus.translatesAutoresizingMaskIntoConstraints = NO;
+ [plus.widthAnchor constraintEqualToConstant: plus.frame.size.width].active = YES;
+ [plus.heightAnchor constraintEqualToConstant: plus.frame.size.height].active = YES;
+ [plus.centerYAnchor constraintEqualToAnchor: cell.layoutMarginsGuide.centerYAnchor].active = YES;
+ [plus.trailingAnchor constraintEqualToAnchor: cell.layoutMarginsGuide.trailingAnchor constant: -20].active = YES;
+ }
+
+ return(cell);
+}
+
+- (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ UITableViewCell * cell = [tableView cellForRowAtIndexPath: indexPath];
+ return((cell.accessoryType == UITableViewCellAccessoryNone) ? nil : indexPath);
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ UITableViewCell * cell = [tableView cellForRowAtIndexPath: indexPath];
+ if (cell.accessoryType != UITableViewCellAccessoryNone)
+ {
+ // Push next
+ CNTableViewController * controller = [self controllerForTableView: tableView];
+ NSArray * lastpathArray = controller.pathArray;
+ controller.selectionIndex = indexPath.row;
+ NSString * title = cell.textLabel.text;
+ controller = [self pushNewBrowseController: title animated: YES];
+ controller.pathArray = [lastpathArray arrayByAddingObject: title];
+ }
+ [tableView deselectRowAtIndexPath: indexPath animated: YES];
+}
+
+#pragma mark - _CNDomainBrowser Delegates
+
+- (void)bonjourBrowserDomainUpdate:(NSArray *)defaultDomainPath
+{
+ _selectedDNSDomain = DomainPathToDNSDomain(defaultDomainPath);
+ [((UITableViewController *)self.navigationController.topViewController).tableView reloadData];
+ if ([self.delegate respondsToSelector: @selector(bonjourBrowserDomainUpdate:)])
+ {
+ [self.delegate bonjourBrowserDomainUpdate: _selectedDNSDomain];
+ }
+}
+
+@end