source: releases/Pester/1.1a5/Source/NJRIntervalField.m@ 665

Last change on this file since 665 was 53, checked in by Nicholas Riley, 22 years ago

Updated for Pester 1.1a5 (very limited release).

Pester 1.1a4 was never released.

File size: 6.8 KB
Line 
1//
2// NJRIntervalField.m
3// Pester
4//
5// Created by Nicholas Riley on Wed Dec 25 2002.
6// Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9#import "NJRIntervalField.h"
10
11// XXX much implementation borrowed from DockCam, then factored; should replace DockCam interval selector with a NJRIntervalField at some point
12
13@implementation NJRIntervalField
14
15- (NSTimeInterval)interval;
16{
17 NSText *editor = [self currentEditor];
18 id obj = nil;
19
20 if (editor != nil) {
21 NSString *stringValue = [editor string];
22 if (![[self formatter] getObjectValue: &obj forString: stringValue errorDescription: NULL])
23 return 0;
24 } else {
25 obj = self;
26 }
27
28 return [obj intValue] * [[intervalUnits selectedItem] tag];
29}
30
31- (BOOL)setInterval:(NSTimeInterval)interval;
32{
33 // we assume that the tags are in ascending order in the array
34 NSEnumerator *e = [[intervalUnits itemArray] reverseObjectEnumerator];
35 NSMenuItem *i;
36 int multiplierTag;
37
38 while ( (i = [e nextObject]) != nil) {
39 multiplierTag = [i tag];
40 if (((int)interval % multiplierTag) == 0) {
41 NSFormatter *formatter = [self formatter];
42 int intervalValue = interval / multiplierTag;
43 if (formatter != nil) {
44 id ignored;
45 if (![formatter getObjectValue: &ignored forString: [formatter stringForObjectValue: [NSNumber numberWithInt: intervalValue]] errorDescription: NULL]) return NO;
46 }
47 [self setIntValue: intervalValue];
48 [intervalUnits selectItem: i];
49 return YES;
50 }
51 }
52 return NO;
53}
54
55- (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)range replacementString:(NSString *)string;
56{
57 unsigned length = [string length];
58 if (length != 0) {
59 unichar c;
60 int tag = -1;
61 c = [string characterAtIndex: length - 1];
62 switch (c) {
63 case 's': case 'S': tag = 1; break;
64 case 'm': case 'M': tag = 60; break;
65 case 'h': case 'H': tag = 60 * 60; break;
66 default: break;
67 }
68 if (tag != -1) [intervalUnits selectItemAtIndex: [intervalUnits indexOfItemWithTag: tag]];
69 }
70 return [super textView: textView shouldChangeTextInRange: range replacementString: string];
71}
72
73- (void)handleDidFailToFormatString:(NSString *)string errorDescription:(NSString *)error label:(NSString *)label;
74{
75 NSString *alertMessage;
76 NSString *alternateButtonString;
77 NSDecimalNumber *proposedValue;
78 NSDictionary *contextInfo;
79
80 NSString *alertInformation = [NSString localizedStringWithFormat:
81 NSLocalizedString(@"The %@ field must be set to a value between %@ and %@.",
82 @"Informative text for alert posed by text field when invalid value entered"),
83 label, [[self formatter] minimum], [[self formatter] maximum]];
84 NSString *defaultButtonString = NSLocalizedString(@"Edit", @"Name of Edit button");
85 NSString *otherButtonString = NSLocalizedString(@"Cancel", @"Name of Cancel button");
86
87 if ([error isEqualToString:
88 NSLocalizedStringFromTableInBundle(@"Fell short of minimum", @"Formatter",
89 [NSBundle bundleForClass:[NSFormatter class]],
90 @"Presented when user value smaller than minimum")]) {
91 proposedValue = [[self formatter] minimum];
92 alertMessage = [NSString stringWithFormat:
93 NSLocalizedString(@"Ò%@Ó is too small for the %@ field.",
94 @"Message text for alert posed by numeric field when too-small value entered"),
95 string, label];
96 alternateButtonString = [NSString localizedStringWithFormat:
97 NSLocalizedString(@"Set to %@",
98 @"Name of alternate button for alert posed by numeric field when too-small value entered"),
99 proposedValue];
100 } else if ([error isEqualToString:
101 NSLocalizedStringFromTableInBundle(@"Maximum exceeded", @"Formatter",
102 [NSBundle bundleForClass:[NSFormatter class]],
103 @"Presented when user value larger than maximum")]) {
104 proposedValue = [[self formatter] maximum];
105 alertMessage = [NSString stringWithFormat:
106 NSLocalizedString(@"Ò%@Ó is too large for the %@ field.",
107 @"Message text for alert posed by numeric field when too-large value entered"),
108 string, label];
109 alternateButtonString = [NSString localizedStringWithFormat:
110 NSLocalizedString(@"Set to %@",
111 @"Name of alternate button for alert posed by numeric field when too-large value entered"),
112 proposedValue];
113 } else if ([error isEqualToString:
114 NSLocalizedStringFromTableInBundle(@"Invalid number", @"Formatter",
115 [NSBundle bundleForClass:[NSFormatter class]],
116 @"Presented when user typed illegal characters: no valid object")]) {
117 alertMessage = [NSString stringWithFormat:
118 NSLocalizedString(@"Ò%@Ó is not a valid entry for the %@ field.",
119 @"Message text for alert posed by text field when invalid value entered"),
120 string, label];
121 alternateButtonString = nil;
122 }
123
124 contextInfo = [NSDictionary dictionaryWithObject: proposedValue forKey: @"proposedValue"];
125 [contextInfo retain];
126 NSBeep();
127 NSBeginAlertSheet(alertMessage, defaultButtonString, alternateButtonString, otherButtonString, [self window],
128 self, @selector(validationFailedSheetDidEnd:returnCode:contextInfo:), NULL, contextInfo,
129 alertInformation);
130}
131
132- (void)_propagateValidationChange;
133{
134 NSText *fieldEditor = [self currentEditor];
135 NSDictionary *userInfo = nil;
136 if (fieldEditor != nil) userInfo = [NSDictionary dictionaryWithObject: fieldEditor forKey: @"NSFieldEditor"];
137 [[NSNotificationCenter defaultCenter] postNotificationName: NSControlTextDidChangeNotification object: self userInfo: userInfo];
138 [self selectText: self];
139}
140
141- (void)validationFailedSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
142 // modal delegate callback method for NSBeginAlertSheet() function; called in the above method
143 if (returnCode == NSAlertOtherReturn) { // cancel
144 [self abortEditing]; // abort edit session and reinstate original value
145 [self _propagateValidationChange];
146 } else if (returnCode == NSAlertAlternateReturn) { // set to min/max/default value
147 [self setObjectValue: [(NSDictionary *)contextInfo objectForKey: @"proposedValue"]];
148 [self validateEditing];
149 [self _propagateValidationChange];
150 }
151 [(NSDictionary *)contextInfo release];
152}
153
154@end
Note: See TracBrowser for help on using the repository browser.