Added TOTP Column to entry table view

This commit is contained in:
Michael Starke
2022-11-23 16:16:15 +01:00
parent 69ec359e87
commit 05ba068632

View File

@@ -67,6 +67,7 @@ NSString *const MPEntryTableAttachmentColumnIdentifier = @"MPEntryTableAttachmen
NSString *const MPEntryTableCreatedColumnIdentifier = @"MPEntryTableCreatedColumnIdentifier"; NSString *const MPEntryTableCreatedColumnIdentifier = @"MPEntryTableCreatedColumnIdentifier";
NSString *const MPEntryTableModfiedColumnIdentifier = @"MPEntryTableModfiedColumnIdentifier"; NSString *const MPEntryTableModfiedColumnIdentifier = @"MPEntryTableModfiedColumnIdentifier";
NSString *const MPEntryTableHistoryColumnIdentifier = @"MPEntryTableHistoryColumnIdentifier"; NSString *const MPEntryTableHistoryColumnIdentifier = @"MPEntryTableHistoryColumnIdentifier";
NSString *const MPEntryTableTOTPColumnIdentifier = @"MPEntryTableTOTPColumnIdentifier";
NSString *const _MPTableImageCellView = @"ImageCell"; NSString *const _MPTableImageCellView = @"ImageCell";
NSString *const _MPTableStringCellView = @"StringCell"; NSString *const _MPTableStringCellView = @"StringCell";
@@ -82,6 +83,8 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
@property (weak) IBOutlet NSTableView *entryTable; @property (weak) IBOutlet NSTableView *entryTable;
@property (assign) MPDisplayMode displayMode; @property (assign) MPDisplayMode displayMode;
@property (nonatomic, assign) BOOL totpColumnHidden;
@property (strong) NSTimer *totpUpdateTimer;
/* Constraints */ /* Constraints */
@@ -103,6 +106,7 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) { if(self) {
_isDisplayingContextBar = NO; _isDisplayingContextBar = NO;
_totpColumnHidden = NO;
_displayMode = MPDisplayModeEntries; _displayMode = MPDisplayModeEntries;
_entryArrayController = [[NSArrayController alloc] init]; _entryArrayController = [[NSArrayController alloc] init];
_dataSource = [[MPEntryTableDataSource alloc] init]; _dataSource = [[MPEntryTableDataSource alloc] init];
@@ -161,6 +165,8 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
NSTableColumn *modifiedColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableModfiedColumnIdentifier]; NSTableColumn *modifiedColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableModfiedColumnIdentifier];
NSTableColumn *historyColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableHistoryColumnIdentifier]; NSTableColumn *historyColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableHistoryColumnIdentifier];
NSTableColumn *indexColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableIndexColumnIdentifier]; NSTableColumn *indexColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableIndexColumnIdentifier];
NSTableColumn *totpTableColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableTOTPColumnIdentifier];
notesColumn.minWidth = 40.0; notesColumn.minWidth = 40.0;
attachmentsColumn.minWidth = 40.0; attachmentsColumn.minWidth = 40.0;
createdColumn.minWidth = 40.0; createdColumn.minWidth = 40.0;
@@ -173,6 +179,7 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
[self.entryTable addTableColumn:modifiedColumn]; [self.entryTable addTableColumn:modifiedColumn];
[self.entryTable addTableColumn:createdColumn]; [self.entryTable addTableColumn:createdColumn];
[self.entryTable addTableColumn:historyColumn]; [self.entryTable addTableColumn:historyColumn];
[self.entryTable addTableColumn:totpTableColumn];
[self.entryTable addTableColumn:indexColumn]; [self.entryTable addTableColumn:indexColumn];
parentColumn.identifier = MPEntryTableParentColumnIdentifier; parentColumn.identifier = MPEntryTableParentColumnIdentifier;
@@ -195,6 +202,7 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
parentColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:parentTitleKeyPath ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]; parentColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:parentTitleKeyPath ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
modifiedColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:timeInfoModificationTimeKeyPath ascending:YES selector:@selector(compare:)]; modifiedColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:timeInfoModificationTimeKeyPath ascending:YES selector:@selector(compare:)];
createdColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:timeInfoCreationTimeKeyPath ascending:YES selector:@selector(compare:)]; createdColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:timeInfoCreationTimeKeyPath ascending:YES selector:@selector(compare:)];
totpTableColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(timeOTP)) ascending:YES selector:@selector(compare:)];
indexColumn.headerCell.stringValue = @""; indexColumn.headerCell.stringValue = @"";
indexColumn.headerToolTip = NSLocalizedString(@"ENTRY_INDEX_COLUMN_TOOLTIP", "Tooltip displayed on the index header cell"); indexColumn.headerToolTip = NSLocalizedString(@"ENTRY_INDEX_COLUMN_TOOLTIP", "Tooltip displayed on the index header cell");
@@ -208,6 +216,7 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
createdColumn.headerCell.stringValue = NSLocalizedString(@"CREATED", "Creating date column title"); createdColumn.headerCell.stringValue = NSLocalizedString(@"CREATED", "Creating date column title");
modifiedColumn.headerCell.stringValue = NSLocalizedString(@"MODIFIED", "Modification date column title"); modifiedColumn.headerCell.stringValue = NSLocalizedString(@"MODIFIED", "Modification date column title");
historyColumn.headerCell.stringValue = NSLocalizedString(@"HISTORY", "History count column title"); historyColumn.headerCell.stringValue = NSLocalizedString(@"HISTORY", "History count column title");
totpTableColumn.headerCell.stringValue = NSLocalizedString(@"TOPT", "TOTP column title");
[self.entryTable bind:NSContentBinding toObject:self.entryArrayController withKeyPath:NSStringFromSelector(@selector(arrangedObjects)) options:nil]; [self.entryTable bind:NSContentBinding toObject:self.entryArrayController withKeyPath:NSStringFromSelector(@selector(arrangedObjects)) options:nil];
[self.entryTable bind:NSSortDescriptorsBinding toObject:self.entryArrayController withKeyPath:NSStringFromSelector(@selector(sortDescriptors)) options:nil]; [self.entryTable bind:NSSortDescriptorsBinding toObject:self.entryArrayController withKeyPath:NSStringFromSelector(@selector(sortDescriptors)) options:nil];
@@ -232,6 +241,7 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
if(parentIndex != 1) { if(parentIndex != 1) {
[self.entryTable moveColumn:parentIndex toColumn:1]; [self.entryTable moveColumn:parentIndex toColumn:1];
} }
[self _updateTOTPTimer];
} }
- (void)setDisplayClearTextPasswords:(BOOL)displayClearTextPasswords { - (void)setDisplayClearTextPasswords:(BOOL)displayClearTextPasswords {
@@ -261,6 +271,11 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
[self.contextBarViewController registerNotificationsForDocument:document]; [self.contextBarViewController registerNotificationsForDocument:document];
} }
- (void)setTotpColumnHidden:(BOOL)toptColumnVisible {
_totpColumnHidden = toptColumnVisible;
[self _updateTOTPTimer];
}
#pragma mark NSTableViewDelgate #pragma mark NSTableViewDelgate
- (void)_tableDidScroll:(NSNotification *)notification { - (void)_tableDidScroll:(NSNotification *)notification {
@@ -292,6 +307,7 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
BOOL isCreatedColumn = [tableColumn.identifier isEqualToString:MPEntryTableCreatedColumnIdentifier]; BOOL isCreatedColumn = [tableColumn.identifier isEqualToString:MPEntryTableCreatedColumnIdentifier];
BOOL isModifedColumn = [tableColumn.identifier isEqualToString:MPEntryTableModfiedColumnIdentifier]; BOOL isModifedColumn = [tableColumn.identifier isEqualToString:MPEntryTableModfiedColumnIdentifier];
BOOL isHistoryColumn = [tableColumn.identifier isEqualToString:MPEntryTableHistoryColumnIdentifier]; BOOL isHistoryColumn = [tableColumn.identifier isEqualToString:MPEntryTableHistoryColumnIdentifier];
BOOL isTOPTColumn = [tableColumn.identifier isEqualToString:MPEntryTableTOTPColumnIdentifier];
NSTableCellView *view = nil; NSTableCellView *view = nil;
BOOL displayClearTextPasswords = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyDisplayClearTextPasswordsInEntryList]; BOOL displayClearTextPasswords = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyDisplayClearTextPasswordsInEntryList];
@@ -415,6 +431,10 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
NSStringFromSelector(@selector(password))]; NSStringFromSelector(@selector(password))];
[view.textField bind:NSValueBinding toObject:view withKeyPath:passwordKeyPath options:nil]; [view.textField bind:NSValueBinding toObject:view withKeyPath:passwordKeyPath options:nil];
} }
else if(isTOPTColumn) {
NSString *TOTPKeyPath = [NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(objectValue)), NSStringFromSelector(@selector(timeOTP))];
[view.textField bind:NSValueBinding toObject:view withKeyPath:TOTPKeyPath options:nil];
}
} }
return view; return view;
} }
@@ -678,6 +698,7 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
[headerMenu addItemWithTitle:NSLocalizedString(@"MODIFIED", "Menu item to toggle display of modified date column in entry table") action:NULL keyEquivalent:@""]; [headerMenu addItemWithTitle:NSLocalizedString(@"MODIFIED", "Menu item to toggle display of modified date column in entry table") action:NULL keyEquivalent:@""];
[headerMenu addItemWithTitle:NSLocalizedString(@"CREATED", "Menu item to toggle display of created date column in entry table") action:NULL keyEquivalent:@""]; [headerMenu addItemWithTitle:NSLocalizedString(@"CREATED", "Menu item to toggle display of created date column in entry table") action:NULL keyEquivalent:@""];
[headerMenu addItemWithTitle:NSLocalizedString(@"HISTORY", "Menu item to toggle display of history count column in entry table") action:NULL keyEquivalent:@""]; [headerMenu addItemWithTitle:NSLocalizedString(@"HISTORY", "Menu item to toggle display of history count column in entry table") action:NULL keyEquivalent:@""];
[headerMenu addItemWithTitle:NSLocalizedString(@"TOTP", "Menu item to toggle display of TOTP count column in entry table") action:NULL keyEquivalent:@""];
NSArray *identifier = @[ MPEntryTableTitleColumnIdentifier, NSArray *identifier = @[ MPEntryTableTitleColumnIdentifier,
MPEntryTableUserNameColumnIdentifier, MPEntryTableUserNameColumnIdentifier,
@@ -687,7 +708,8 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
MPEntryTableAttachmentColumnIdentifier, MPEntryTableAttachmentColumnIdentifier,
MPEntryTableModfiedColumnIdentifier, MPEntryTableModfiedColumnIdentifier,
MPEntryTableCreatedColumnIdentifier, MPEntryTableCreatedColumnIdentifier,
MPEntryTableHistoryColumnIdentifier ]; MPEntryTableHistoryColumnIdentifier,
MPEntryTableTOTPColumnIdentifier];
NSDictionary *options = @{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName }; NSDictionary *options = @{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName };
for(NSMenuItem *item in headerMenu.itemArray) { for(NSMenuItem *item in headerMenu.itemArray) {
@@ -696,6 +718,8 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
[item bind:NSValueBinding toObject:column withKeyPath:NSHiddenBinding options:options]; [item bind:NSValueBinding toObject:column withKeyPath:NSHiddenBinding options:options];
} }
NSTableColumn *totpColumn = [self.entryTable tableColumnWithIdentifier:MPEntryTableTOTPColumnIdentifier];
[self bind:NSStringFromSelector(@selector(totpColumnHidden)) toObject:totpColumn withKeyPath:NSHiddenBinding options:nil]; // double binding works?
[headerMenu addItem:[NSMenuItem separatorItem]]; [headerMenu addItem:[NSMenuItem separatorItem]];
NSMenuItem *showPasswordsItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SHOW_CLEAR_TEXT_PASSWORDS", "Menu item to toggle display type of passwords") action:NULL keyEquivalent:@""]; NSMenuItem *showPasswordsItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SHOW_CLEAR_TEXT_PASSWORDS", "Menu item to toggle display type of passwords") action:NULL keyEquivalent:@""];
@@ -707,6 +731,21 @@ NSString *const _MPTableMonoSpacedStringCellView = @"MonospacedStringCell";
self.entryTable.headerView.menu = headerMenu; self.entryTable.headerView.menu = headerMenu;
} }
- (void)_updateTOTPTimer {
if(self.totpColumnHidden) {
[self.totpUpdateTimer invalidate];
self.totpUpdateTimer = nil;
return;
}
__weak MPEntryViewController *welf = self;
self.totpUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSLog(@"Update TOTP Column Content");
NSIndexSet *columnIndex = [NSIndexSet indexSetWithIndex:[welf.entryTable columnWithIdentifier:MPEntryTableTOTPColumnIdentifier]];
NSIndexSet *rowIndexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,welf.entryTable.numberOfRows)];
[welf.entryTable reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndex];
}];
}
#pragma mark Actions #pragma mark Actions
- (void)copyPassword:(id)sender { - (void)copyPassword:(id)sender {
NSArray *nodes = self.currentTargetNodes; NSArray *nodes = self.currentTargetNodes;