diff --git a/ProfilesManager/Base.lproj/Localizable.strings b/ProfilesManager/Base.lproj/Localizable.strings index 419e993..b99fd03 100644 --- a/ProfilesManager/Base.lproj/Localizable.strings +++ b/ProfilesManager/Base.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Confirm Delete Opration" = "Confirm Delete Opration"; "Delete this profie item permanently,can't rollback!" = "Delete this profie item permanently,can't rollback!"; "Warning" = "Warning"; -"are you sure move item to trash?" = "are you sure move item to trash?"; +"Are you sure delete selected items from disk? After delete operation can't rollback!" = "Are you sure delete selected items from disk? After delete operation can't rollback!"; +"Are you sure move selected items to trash?" = "Are you sure move selected items to trash?" "Export" = "Export"; "Beautify Filename" = "Beautify Filename"; diff --git a/ProfilesManager/Controller/ProfilesManagerViewController.h b/ProfilesManager/Controller/ProfilesManagerViewController.h index 1474214..6042fee 100755 --- a/ProfilesManager/Controller/ProfilesManagerViewController.h +++ b/ProfilesManager/Controller/ProfilesManagerViewController.h @@ -24,5 +24,6 @@ NSString *_searchWord; } @property (weak) IBOutlet DragOutlineView *treeView; +@property (weak) IBOutlet NSTextField *statusLabel; - (void)loadProfileFilesWithSearchWord:(NSString*)searchWord; @end diff --git a/ProfilesManager/Controller/ProfilesManagerViewController.m b/ProfilesManager/Controller/ProfilesManagerViewController.m index 5f4582b..ea2d720 100755 --- a/ProfilesManager/Controller/ProfilesManagerViewController.m +++ b/ProfilesManager/Controller/ProfilesManagerViewController.m @@ -27,6 +27,21 @@ static NSString *kColumnIdentifierCreateDate = @"creationDate"; @implementation ProfilesManagerViewController +//获取sandbox之外的路径 +NSString *RealHomeDirectory() { + // struct passwd *pw = getpwuid(getuid()); + // assert(pw); + // return [NSString stringWithUTF8String:pw->pw_dir]; + // + NSString *home = NSHomeDirectory(); + NSArray *pathArray = [home componentsSeparatedByString:@"/"]; + NSString *absolutePath; + if ([pathArray count] > 2) { + absolutePath = [NSString stringWithFormat:@"/%@/%@", [pathArray objectAtIndex:1], [pathArray objectAtIndex:2]]; + } + return absolutePath; +} + - (void)viewDidLoad { [super viewDidLoad]; @@ -39,6 +54,7 @@ - (void)viewDidLoad { // [self.treeView sizeLastColumnToFit]; //app第一次运行Column 最后一行自动宽等比增减,否则会有滚动条 [self.treeView sizeToFit]; + self.treeView.allowsMultipleSelection = YES; [self loadProfileFilesWithSearchWord:_searchWord]; //drag file @@ -63,20 +79,6 @@ - (void)viewDidLoad { }]; } -//获取sandbox之外的路径 -NSString *RealHomeDirectory() { - // struct passwd *pw = getpwuid(getuid()); - // assert(pw); - // return [NSString stringWithUTF8String:pw->pw_dir]; - // - NSString *home = NSHomeDirectory(); - NSArray *pathArray = [home componentsSeparatedByString:@"/"]; - NSString *absolutePath; - if ([pathArray count] > 2) { - absolutePath = [NSString stringWithFormat:@"/%@/%@", [pathArray objectAtIndex:1], [pathArray objectAtIndex:2]]; - } - return absolutePath; -} - (void)loadProfileFilesWithSearchWord:(NSString*)searchWord { _searchWord = searchWord; @@ -99,19 +101,19 @@ - (void)loadProfileFilesWithSearchWord:(NSString*)searchWord { } } } - ProfilesNode *node = [[ProfilesNode alloc]initWithRootNode:nil originInfo:provisions key:@"Mobile Provisions"]; _rootNode = node; [self.treeView reloadData]; - + [self updateStatus]; + for (NSTableColumn *tableColumn in self.treeView.tableColumns ) { NSSortDescriptor *sortStates = [NSSortDescriptor sortDescriptorWithKey:tableColumn.identifier - ascending:NO comparator:^(id obj1, id obj2) { - return [obj1 compare:obj2]; - }]; + ascending:NO comparator:^(id obj1, id obj2) { + return [obj1 compare:obj2]; + }]; [tableColumn setSortDescriptorPrototype:sortStates]; } - + } @@ -157,17 +159,18 @@ - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTabl - (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item{ NSInteger selectedRow = [outlineView clickedRow]; -// [outlineView setNeedsDisplayInRect:[outlineView rectOfRow:selectedRow]]; + // [outlineView setNeedsDisplayInRect:[outlineView rectOfRow:selectedRow]]; NSLog(@"select is %zd",selectedRow); return YES; } - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(NSTextFieldCell*)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item { - + ProfilesNode *realItem = item ?: _rootNode; - + if ([outlineView parentForItem:item] == nil) { + if ([[tableColumn identifier] isEqualToString:kColumnIdentifierType]) { cell.textColor = [NSColor blackColor]; }else{ @@ -188,7 +191,18 @@ - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(NSTextFieldCel [cell setMenu:nil]; } } - + + if(cell.highlighted){ + if ([[tableColumn identifier] isEqualToString:kColumnIdentifierDetal]) { + if ([realItem.detail isEqualToString:@"Expired"] ||[realItem.detail isEqualToString:@"过期"] ) { + cell.textColor = [NSColor redColor]; + }else{ + cell.textColor = [NSColor whiteColor]; + } + }else{ + cell.textColor = [NSColor whiteColor]; + } + } } @@ -213,10 +227,12 @@ - (void)outlineView:(NSOutlineView *)outlineView sortDescriptorsDidChange:(NSArr // sortedArray = [currChildren sortedArrayUsingDescriptors:sortDescriptors]; // _rootNode.childrenNodes = sortedArray; // [outlineView reloadData]; -//} - + //} + +} +- (void)outlineViewSelectionDidChange:(NSNotification *)notification{ + [self updateStatus]; } - #pragma mark - #pragma mark NSMenuDelegate - (void)rightMouseDown:(NSEvent *)theEvent { @@ -257,7 +273,7 @@ - (void)menuWillOpen:(NSMenu *)menu NSMenuItem *gotoItemName = [menu itemWithTag:1002]; if (!gotoItemName) { - gotoItemName = [[NSMenuItem alloc] initWithTitle:JKLocalizedString(@"Show in Finder",nil) action:@selector(gotoClick:) keyEquivalent:@""]; + gotoItemName = [[NSMenuItem alloc] initWithTitle:JKLocalizedString(@"Show in Finder",nil) action:@selector(showInFinder:) keyEquivalent:@""]; [gotoItemName setTarget:self]; [gotoItemName setTag:1002]; [menu addItem:gotoItemName]; @@ -286,14 +302,14 @@ - (void)menuWillOpen:(NSMenu *)menu [exportItem setTag:1003]; [menu addItem:exportItem]; } -// NSMenuItem *renameItem = [menu itemWithTag:1004]; -// if (!renameItem) -// { -// renameItem = [[NSMenuItem alloc] initWithTitle:JKLocalizedString(@"Beautify Filename",nil) action:@selector(renameItemClick:) keyEquivalent:@""]; -// [renameItem setTarget:self]; -// [renameItem setTag:1004]; -// [menu addItem:renameItem]; -// } + // NSMenuItem *renameItem = [menu itemWithTag:1004]; + // if (!renameItem) + // { + // renameItem = [[NSMenuItem alloc] initWithTitle:JKLocalizedString(@"Beautify Filename",nil) action:@selector(renameItemClick:) keyEquivalent:@""]; + // [renameItem setTarget:self]; + // [renameItem setTag:1004]; + // [menu addItem:renameItem]; + // } } if(menu == _mainMenu){ NSMenuItem *refreshItem = [menu itemWithTag:2000]; @@ -327,43 +343,93 @@ - (void)menuWillOpen:(NSMenu *)menu #pragma mark - #pragma mark Operation +- (void)updateStatus{ + if([self selectedRowIndexes].count >0){ + self.statusLabel.stringValue = [NSString stringWithFormat:@"%@ of %@ items selected",[@([self selectedRowIndexes].count) stringValue],[@([_rootNode.childrenNodes count]) stringValue]]; + }else{ + self.statusLabel.stringValue = [NSString stringWithFormat:@"%@ items",[@([_rootNode.childrenNodes count]) stringValue]]; + } +} +- (NSIndexSet *)selectedRowIndexes{ + NSIndexSet *selectedRowIndexes = [self.treeView selectedRowIndexes]; + //多选 + if (selectedRowIndexes.count == 0) { + //直接右键 + NSInteger index = [self.treeView clickedRow]; + if (index >-1){ + selectedRowIndexes = [NSIndexSet indexSetWithIndex:index]; + } + } + return selectedRowIndexes; +} +- (NSArray *)activateFileURLs{ + NSArray *selectedItems = [_rootNode.childrenNodes objectsAtIndexes:[self selectedRowIndexes]]; + NSMutableArray *activateFileURLs = [NSMutableArray array]; + for (ProfilesNode *node in selectedItems) { + if ([node.filePath length] > 0) + { + [activateFileURLs addObject:[NSURL fileURLWithPath:node.filePath]]; + } + } + return activateFileURLs; +} - (void)deleteItemClick:(id)sender { - NSInteger index = [self.treeView clickedRow]; - ProfilesNode *node = [self.treeView itemAtRow:index]; + NSIndexSet *selectedRowIndexes = [self selectedRowIndexes]; + NSArray *selectedItems = [_rootNode.childrenNodes objectsAtIndexes:selectedRowIndexes]; - iAlert *alert = [iAlert alertWithTitle:[NSString stringWithFormat:@"%@,%@",JKLocalizedString(@"Confirm Delete Opration",nil),node.type] message:JKLocalizedString(@"Delete this profie item permanently,can't rollback!",nil) style:NSAlertStyleWarning]; + NSMutableArray *selectedItemNames = [NSMutableArray array]; + for (ProfilesNode *node in selectedItems) { + [selectedItemNames addObject:node.type?:node.filePath]; + } + + iAlert *alert = [iAlert alertWithTitle:JKLocalizedString(@"Are you sure delete selected items from disk? After delete operation can't rollback!",nil) message:[selectedItemNames componentsJoinedByString:@",\n"] style:NSAlertStyleWarning]; [alert addCommonButtonWithTitle:JKLocalizedString(@"Ok", nil) handler:^(iAlertItem *item) { - NSLog(@"deleteItem inde%zd",index); - if (index == -1) return; - + [self.treeView beginUpdates]; - [self.treeView removeItemsAtIndexes:[NSIndexSet indexSetWithIndex:index] inParent:nil withAnimation:NSTableViewAnimationEffectFade]; + [self.treeView removeItemsAtIndexes:selectedRowIndexes inParent:nil withAnimation:NSTableViewAnimationEffectFade]; [self.treeView endUpdates]; - [self deleteProfile:node.filePath option:YES]; -// [self loadProfileFilesWithSearchWord:_searchWord]; + for (ProfilesNode *node in selectedItems) { + if([self deleteProfile:node.filePath option:YES]){ + NSMutableArray *temp = [_rootNode.childrenNodes mutableCopy]; + [temp removeObject:node]; + _rootNode.childrenNodes = temp; + } + } + [self updateStatus]; }]; [alert addButtonWithTitle:JKLocalizedString(@"Cancle", nil)]; [alert show:self.view.window]; } - (void)moveTrashItemClick:(id)sender{ - NSInteger index = [self.treeView clickedRow]; - ProfilesNode *node = [self.treeView itemAtRow:index]; + NSIndexSet *selectedRowIndexes = [self selectedRowIndexes]; + NSArray *selectedItems = [_rootNode.childrenNodes objectsAtIndexes:selectedRowIndexes]; + + NSMutableArray *selectedItemNames = [NSMutableArray array]; + for (ProfilesNode *node in selectedItems) { + [selectedItemNames addObject:node.type?:node.filePath]; + } + + iAlert *alert = [iAlert alertWithTitle:JKLocalizedString(@"Are you sure move selected items to trash?",nil) message:[selectedItemNames componentsJoinedByString:@",\n"] style:NSAlertStyleWarning]; - iAlert *alert = [iAlert alertWithTitle:JKLocalizedString(@"Warning",nil) message:JKLocalizedString(@"are you sure move item to trash?",nil) style:NSAlertStyleWarning]; [alert addCommonButtonWithTitle:JKLocalizedString(@"Ok", nil) handler:^(iAlertItem *item) { - NSLog(@"move to trash inde%zd",index); - if (index == -1) return; - [self.treeView beginUpdates]; - [self.treeView removeItemsAtIndexes:[NSIndexSet indexSetWithIndex:index] inParent:nil withAnimation:NSTableViewAnimationEffectFade]; + [self.treeView removeItemsAtIndexes:selectedRowIndexes inParent:nil withAnimation:NSTableViewAnimationEffectFade]; [self.treeView endUpdates]; - [self deleteProfile:node.filePath option:NO]; - [self loadProfileFilesWithSearchWord:_searchWord]; + for (ProfilesNode *node in selectedItems) { + if([self deleteProfile:node.filePath option:NO]){ + NSMutableArray *temp = [_rootNode.childrenNodes mutableCopy]; + [temp removeObject:node]; + _rootNode.childrenNodes = temp; + } + } + [self updateStatus]; + +// [self loadProfileFilesWithSearchWord:_searchWord]; }]; [alert addButtonWithTitle:JKLocalizedString(@"Cancle", nil)]; @@ -371,19 +437,11 @@ - (void)moveTrashItemClick:(id)sender{ } -//goto -- (void)gotoClick:(id)sender +//showInFinder +- (void)showInFinder:(id)sender { - NSInteger index = [self.treeView clickedRow]; - if (index == -1) return; - ProfilesNode *node = [self.treeView itemAtRow:index]; - if ([node.filePath length] > 0) - { - //打开文件 - //[[NSWorkspace sharedWorkspace] openFile:node.filePath]; - // 打开文件夹 - [[NSWorkspace sharedWorkspace] selectFile:node.filePath inFileViewerRootedAtPath:@""]; - } + NSArray *activateFileURLs =[self activateFileURLs]; + [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:activateFileURLs]; } ////beautify filename //- (void)renameItemClick:(id)sender{ @@ -480,12 +538,11 @@ - (void)exportCerItemClick:(id)sender #pragma mark --filemanager //delete and move -- (BOOL)deleteProfile:(NSString*)filePath option:(BOOL)totle{ +- (BOOL)deleteProfile:(NSString*)filePath option:(BOOL)completely { NSError *error; BOOL result = NO; - if (totle) { + if (completely) { result = [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]; - }else{ result = [[NSFileManager defaultManager] mr_moveFileAtPathToTrash:filePath error:&error]; } diff --git a/ProfilesManager/Controller/ProfilesManagerViewController.xib b/ProfilesManager/Controller/ProfilesManagerViewController.xib index 30e906c..decb4df 100755 --- a/ProfilesManager/Controller/ProfilesManagerViewController.xib +++ b/ProfilesManager/Controller/ProfilesManagerViewController.xib @@ -8,6 +8,7 @@ + @@ -19,13 +20,13 @@ - + - + - - + + @@ -105,8 +106,8 @@ - + + + + + + + + + + + - - - - + + + + + + + diff --git a/ProfilesManager/Info.plist b/ProfilesManager/Info.plist index 5807bf8..a233cdd 100755 --- a/ProfilesManager/Info.plist +++ b/ProfilesManager/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.1 + 2.2 CFBundleSignature ???? CFBundleVersion diff --git a/ProfilesManager/en.lproj/Localizable.strings b/ProfilesManager/en.lproj/Localizable.strings index 4bb9765..9dd1fe6 100644 --- a/ProfilesManager/en.lproj/Localizable.strings +++ b/ProfilesManager/en.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Confirm Delete Opration" = "Confirm Delete Opration"; "Delete this profie item permanently,can't rollback!" = "Delete this profie item permanently,can't rollback!"; "Warning" = "Warning"; -"are you sure move item to trash?" = "are you sure move item to trash?"; +"Are you sure delete selected items from disk? After delete operation can't rollback!" = "Are you sure delete selceted items from disk? After delete operation can't rollback!"; +"Are you sure move selected items to trash?" = "Are you sure move selected items to trash?"; "Export" = "Export"; "Beautify Filename" = "Beautify Filename"; diff --git a/ProfilesManager/zh-Hans.lproj/Localizable.strings b/ProfilesManager/zh-Hans.lproj/Localizable.strings index 415e790..8c4e4c3 100644 --- a/ProfilesManager/zh-Hans.lproj/Localizable.strings +++ b/ProfilesManager/zh-Hans.lproj/Localizable.strings @@ -19,6 +19,7 @@ "Confirm Delete Opration" = "确认删除操作"; "Delete this profie item permanently,can't rollback!" = "完全删除这个profie文件,不可回滚!"; "Warning" = "警告"; -"are you sure move item to trash?" = "确定将此profie文件移动到废纸篓么?"; +"Are you sure delete selected items from disk? After delete operation can't rollback!" = "确定将选中的所有文件从磁盘删除? 删除之后不可回滚!"; +"Are you sure move selected items to trash?" = "确定将选中的所有文件移动到废纸篓么?"; "Export" = "导出"; "Beautify Filename" = "美化文件名"; diff --git a/README.md b/README.md index 3d9470e..8d83a7b 100755 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ iOS Provisioning Profiles, .mobileprovision files manager tool for mac - drag into and look ipa profile or plist directly 拖入ipa快速查看描述文件与info.plist信息 - simple full text search filter 全文搜索后过滤描述文件 - click header sort 点击头部排序 +- multi-select opration such show in finder and delete 多选操作,例如在访达中显示和删除 +- click reset button,reset window frame and position 点击重置按钮重置window大小与位置 ## Download APP https://github.com/shaojiankui/ProfilesManager/releases diff --git a/demo.jpg b/demo.jpg index f342854..b5160b5 100644 Binary files a/demo.jpg and b/demo.jpg differ