//
// SubmitPanelController.m
// Perforce
//
// Created by Adam Czubernat on 10.07.2013.
// Copyright (c) 2013 Perforce Software, Inc. All rights reserved.
//
#import "SubmitPanelController.h"
#import "P4Workspace.h"
#import "P4ChangelistItem.h"
static NSString *lastMessage;
@interface SubmitPanelController () <NSTableViewDataSource, NSTableViewDelegate, NSTextViewDelegate, P4ItemDelegate> {
P4Item *root;
NSMutableArray *items;
NSMutableSet *selectedItems;
NSMutableArray *selectedPaths;
__weak IBOutlet NSView *submitView;
__weak IBOutlet NSView *progressView;
__weak IBOutlet NSTableView *tableView;
__weak IBOutlet NSProgressIndicator *tableIndicator;
__unsafe_unretained NSTextView *descriptionTextView;
__weak IBOutlet NSTextField *fileCountLabel;
__weak IBOutlet NSButton *submitButton;
__weak IBOutlet NSProgressIndicator *progressIndicator;
__weak IBOutlet NSTextField *progressLabel;
__weak IBOutlet NSImageView *successImageView;
}
- (void)reload;
- (void)updateCount;
- (void)validateSubmit;
- (void)setItem:(P4ChangelistItem *)item selected:(BOOL)selected;
- (IBAction)checkmarkPressed:(id)sender;
- (IBAction)checkmarkHeaderPressed:(id)sender;
- (IBAction)cancelPressed:(id)sender;
- (IBAction)submitPressed:(id)sender;
@end
@implementation SubmitPanelController
- (void)windowDidLoad {
[super windowDidLoad];
[submitButton setEnabled:NO];
fileCountLabel.stringValue = @"";
descriptionTextView.string = lastMessage ? : @"";
[tableView setSortDescriptors:@[ [NSSortDescriptor
sortDescriptorWithKey:
@"remotePath.stringByDeletingLastPathComponent"
ascending:YES] ]];
[self setPresentedView:submitView];
[self reload];
[P4ChangelistItem addObserver:self];
}
- (void)dealloc {
[P4ChangelistItem removeObserver:self];
}
#pragma mark - Private
- (void)reload {
root = nil;
items = nil;
selectedItems = nil;
[tableView reloadData];
[tableIndicator startAnimation:nil];
root = [[P4ChangelistItem alloc] init];
[root children]; // Load children
}
- (void)updateCount {
fileCountLabel.stringValue = [NSString stringWithFormat:@"Selected %ld / %ld",
selectedItems.count, items.count];
}
- (void)validateSubmit {
BOOL enable = descriptionTextView.string.length && selectedItems.count;
[submitButton setEnabled:enable];
}
- (void)setItem:(P4ChangelistItem *)item selected:(BOOL)selected {
if (selected) {
[selectedPaths addObject:item.remotePath];
[selectedItems addObject:item];
} else {
[selectedPaths removeObject:item.remotePath];
[selectedItems removeObject:item];
}
NSInteger row = [items indexOfObjectIdenticalTo:item];
[tableView reloadDataForRowsFromIndex:row toIndex:row];
}
#pragma mark - Public
- (void)selectPaths:(NSArray *)paths {
NSAssert(!paths || [[paths lastObject] hasPrefix:@"//"], @"Selecting local paths to submit");
selectedPaths = [paths mutableCopy];
if (items)
[self reload];
}
#pragma mark - P4Item delegate
- (void)itemDidLoad:(id)item {
if (item != root)
return;
NSInteger visibleRow = 0;
selectedItems = [NSMutableSet set];
items = [root.children mutableCopy];
[items sortUsingDescriptors:[tableView sortDescriptors]];
if (selectedPaths) {
// Select items from paths
NSArray *selected = [items filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:
@"remotePath IN %@"
" OR metadata.movedFile IN %@", // Check moved files
selectedPaths, selectedPaths]];
[selectedItems addObjectsFromArray:selected];
// Get first selected row
if (selected.count)
visibleRow = [items indexOfObjectIdenticalTo:[selected objectAtIndex:0]];
} else {
// Select all
selectedItems = [NSMutableSet setWithArray:items];
}
[self updateCount];
[self validateSubmit];
[tableView reloadData];
[tableIndicator stopAnimation:nil];
[tableView scrollRowToVisible:visibleRow];
}
- (void)itemDidInvalidate:(id)item {
}
- (void)item:(id)item didFailWithError:(NSError *)error {
}
#pragma mark - TableView data source
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return items.count;
}
- (NSView *)tableView:(NSTableView *)table viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSString *identifier = tableColumn.identifier;
P4ChangelistItem *item = [items objectAtIndex:row];
NSTableCellView *cell = [tableView makeViewWithIdentifier:identifier owner:self];
if ([identifier isEqualToString:@"checkmark"]) {
NSButton *checkmark = [cell viewWithTag:1];
NSAssert(checkmark, @"Submit panel cell should have checkmark with tag=1");
checkmark.state = [selectedItems containsObject:item];
} else if ([identifier isEqualToString:@"filename"]) {
cell.textField.stringValue = [item name];
cell.imageView.image = item.icon;
} else if ([identifier isEqualToString:@"path"]) {
NSString *path = [item remotePath];
cell.textField.stringValue = [path stringByDeletingLastPathComponent];
} else if ([identifier isEqualToString:@"action"]) {
NSString *action = item.status;
cell.textField.stringValue = action;
}
return cell;
}
- (void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)oldDescriptors {
[items sortUsingDescriptors:[tableView sortDescriptors]];
[tableView reloadData];
}
#pragma mark - TextView delegate
- (void)textDidChange:(NSNotification *)notification {
lastMessage = descriptionTextView.string;
[self validateSubmit];
}
#pragma mark - Actions
- (IBAction)checkmarkPressed:(NSButton *)sender {
BOOL selected = sender.state;
NSInteger row = [tableView rowForView:sender];
P4ChangelistItem *child = [items objectAtIndex:row];
// Add or remove from selected list
[self setItem:child selected:selected];
// Select moved counterpart
if ([child.status hasPrefix:@"move/"]) {
P4ChangelistItem *moved = [[items filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:
@"metadata.movedFile == %@",
child.remotePath]] lastObject];
[self setItem:moved selected:selected];
}
[self updateCount];
[self validateSubmit];
}
- (IBAction)checkmarkHeaderPressed:(NSButton *)sender {
if (sender.state)
[selectedItems addObjectsFromArray:items];
else
[selectedItems removeAllObjects];
[tableView reloadData];
[self updateCount];
[self validateSubmit];
}
- (IBAction)cancelPressed:(id)sender {
[self dismiss];
}
- (IBAction)submitPressed:(id)sender {
NSString *description = descriptionTextView.string;
[self setPresentedView:progressView animated:YES];
[progressIndicator startAnimation:nil];
[[P4Workspace sharedInstance]
submitFiles:[[selectedItems allObjects] valueForKey:@"remotePath"]
message:description
receive:^(P4Operation *operation) {
PSLogm(@"%.2f, %@", operation.progress, operation.progressDescription);
}
response:^(P4Operation *operation, NSArray *response) {
[progressIndicator stopAnimation:nil];
if (operation.errors) {
if (![operation errorsWithCode:P4ErrorSessionExpired])
[[NSAlert alertWithError:operation.error]
beginSheetModalForWindow:self.window.parentWindow
modalDelegate:nil
didEndSelector:nil
contextInfo:NULL];
[self dismiss];
} else {
lastMessage = nil;
[successImageView setHidden:NO];
progressLabel.stringValue = @"Success!";
PSLog(@"%@", response);
[self dismissAfter:2.0f];
}
}];
}
@end
# |
Change |
User |
Description |
Committed |
|
#1
|
10691 |
DWishR |
Populate //guest/DWishR/piper/.... |
|
|
//guest/perforce_software/piper/Perforce/Classes/WindowControllers/SubmitPanelController.m |
#1
|
8919 |
Matt Attaway |
Initial add of Piper, a lightweight Perforce client for artists and designers. |
|
|