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

Last change on this file was 53, checked in by Nicholas Riley, 21 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.