@@ -203,7 +203,7 @@ @interface ModelContainer : NSObject
203
203
204
204
#pragma mark -
205
205
206
- @interface SPRuleFilterController () <NSRuleEditorDelegate >
206
+ @interface SPRuleFilterController () <NSRuleEditorDelegate , NSTextFieldDelegate >
207
207
208
208
@property (readwrite , assign , nonatomic ) CGFloat preferredHeight;
209
209
@@ -223,6 +223,7 @@ - (BOOL)_focusOnFieldInSubtree:(NSDictionary *)dict;
223
223
- (void )_resize ;
224
224
- (void )openContentFilterManagerForFilterType : (NSString *)filterType ;
225
225
- (IBAction )filterTable : (id )sender ;
226
+ - (IBAction )resetFilter : (id )sender ;
226
227
- (IBAction )_menuItemInRuleEditorClicked : (id )sender ;
227
228
- (void )_pretendPlayRuleEditorForCriteria : (NSMutableArray *)criteria displayValues : (NSMutableArray *)displayValues inRow : (NSInteger )row ;
228
229
- (void )_ensureValidOperatorCache : (ColumnNode *)col ;
@@ -346,8 +347,8 @@ - (void)setColumns:(NSArray *)dataColumns;
346
347
// make the rule editor reload the criteria
347
348
[filterRuleEditor reloadCriteria ];
348
349
349
- // disable UI if no criteria exist
350
- [self setEnabled: ([columns count ] != 0 ) ];
350
+ // disable UI if no criteria exist (enable otherwise)
351
+ [self setEnabled: YES ];
351
352
}
352
353
353
354
- (NSInteger )ruleEditor : (NSRuleEditor *)editor numberOfChildrenForCriterion : (nullable id )criterion withRowType : (NSRuleEditorRowType )rowType
@@ -495,6 +496,8 @@ - (id)ruleEditor:(NSRuleEditor *)editor displayValueForCriterion:(id)criterion i
495
496
[textField sizeToFit ];
496
497
[textField setTarget: self ];
497
498
[textField setAction: @selector (_textFieldAction: )];
499
+ [textField setDelegate: self ]; // see -control:textView:doCommandBySelector:
500
+ [textField setToolTip: NSLocalizedString(@" Enter the value to apply the filter condition with.\n Press ↩ to apply the filter or ⇧⌫ to remove this rule." , @" table content : rule filter editor : text input field : tooltip" )];
498
501
if ([node initialValue ]) [textField setStringValue: [node initialValue ]];
499
502
NSRect frame = [textField frame ];
500
503
// adjust width, to make the field wider
@@ -513,6 +516,37 @@ - (id)ruleEditor:(NSRuleEditor *)editor displayValueForCriterion:(id)criterion i
513
516
return nil ;
514
517
}
515
518
519
+ - (BOOL )control : (NSControl *)control textView : (NSTextView *)textView doCommandBySelector : (SEL )commandSelector
520
+ {
521
+ // if the user presses shift+backspace or shift+delete we'll try to remove the whole rule
522
+ NSEvent *event = [NSApp currentEvent ];
523
+ if (
524
+ ( commandSelector == @selector (deleteBackward: ) || commandSelector == @selector (deleteForward: ) ) &&
525
+ [event type ] == NSKeyDown &&
526
+ ([event modifierFlags ] & NSEventModifierFlagDeviceIndependentFlagsMask) == NSEventModifierFlagShift
527
+ ) {
528
+ NSInteger row = [filterRuleEditor rowForDisplayValue: control];
529
+
530
+ if (row != NSNotFound ) {
531
+ // we'll do the actual processing async, because we are currently in the stack of the object which will be dropped by this action.
532
+ // so we want the delegate method to have finished first, just to be safe
533
+ SPMainLoopAsync (^{
534
+ // if we are about to remove the only row in existance, treat it as a reset instead
535
+ if ([[_modelContainer model ] count ] == 1 ) {
536
+ [self resetFilter: nil ];
537
+ }
538
+ else {
539
+ [filterRuleEditor removeRowAtIndex: row];
540
+ [self filterTable: nil ]; // trigger a new filtering for convenience. I don't know if that is always the preferred approach...
541
+ }
542
+ });
543
+ return YES ;
544
+ }
545
+ }
546
+
547
+ return NO ;
548
+ }
549
+
516
550
- (IBAction )_textFieldAction : (id )sender
517
551
{
518
552
// if the action was caused by pressing return or enter, trigger filtering
@@ -652,6 +686,13 @@ - (IBAction)filterTable:(id)sender
652
686
if (target && action) [target performSelector: action withObject: self ];
653
687
}
654
688
689
+ - (IBAction )resetFilter : (id )sender
690
+ {
691
+ [[_modelContainer mutableArrayValueForKey: @" model" ] removeAllObjects ];
692
+ [self addFilterExpression ];
693
+ if (target && action) [target performSelector: action withObject: nil ];
694
+ }
695
+
655
696
- (void )_resize
656
697
{
657
698
// The situation with the sizing is a bit f'ed up:
@@ -939,9 +980,10 @@ - (BOOL)isEnabled
939
980
940
981
- (void )setEnabled : (BOOL )_enabled
941
982
{
942
- enabled = _enabled;
943
- [filterButton setEnabled: _enabled];
944
- [filterRuleEditor setEnabled: _enabled];
983
+ enabled = _enabled && [columns count ] != 0 ;
984
+ [filterButton setEnabled: enabled];
985
+ [resetButton setEnabled: enabled];
986
+ [filterRuleEditor setEnabled: enabled];
945
987
}
946
988
947
989
- (NSString *)sqlWhereExpressionWithBinary : (BOOL )isBINARY error : (NSError **)err
0 commit comments