source: trunk/Cocoa/Pester/Source/NJRIntervalField.m @ 355

Last change on this file since 355 was 355, checked in by Nicholas Riley, 14 years ago

English.lproj/MainMenu.nib: Modernize menu and alarm set dialog
layout. Use keyed archiving (10.2+) nib format.

Info-Pester.plist: Moved from old PBX project.

NJRFSObjectSelector.m: Bug fixes from code sent to Joey: remove
incorrect usage of tryToPerform:with:; fix logic error in menu
construction. Work around Cocoa's deciding that the menu font size
needs adjustment when it doesn't - so the menu font size now matches
the button font size, though the position is still off. Don't pop up
a menu if we're disabled. Use IconRefs? for menu icons, though not
(yet) for the button icon.

NJRHistoryTrackingComboBox.m: Remove item height adjustment
workaround; it now makes the items too tall.

NJRHotKey.m: Add a missing [super dealloc] caught by current GCC.

NJRHotKeyField.m: Add a missing [super dealloc] caught by current GCC.

NJRHotKeyManager.m: Add a missing [super dealloc] caught by current
GCC.

NJRIntervalField.m: Fix some type errors.

NJRQTMediaPopUpButton.m: Replace SoundFileManager? SPI usage, which
doesn't work in Leopard anyway, with manual enumeration of system
sounds. Start migration to QTKit. Use IconRefs? for menu icons.

NJRReadMeController.m: Change source encoding to UTF-8.

NJRSoundManager.m: Fix a type error.

NJRVoicePopUpButton.m: Change source encoding to UTF-8.

NSMenuItem-NJRExtensions.[hm]: Code from ICeCoffEE to use IconRefs? for
menu item icons.

PSAlarm.m: Change source encoding to UTF-8.

PSAlarms.m: Fix a signedness mismatch.

PSAlarmsController.m: Change source encoding to UTF-8.

PSAlarmSetController.m: Set keyboard focus after unchecking "Do
script:" and "Play" checkboxes.

PSAlerts.m: Add a missing [super dealloc] caught by current GCC. Fix
a memory leak in property list serialization.

PSPowerManager.[hm]: There's now API for scheduling wakeups; use it
(the old code asserted on startup). To fix: removing scheduled
wakeup. Fix a small type-checking error.

PSPreferencesController.m: Add a missing [super dealloc] caught by
current GCC.

PSScriptAlert.m: Change source encoding to UTF-8.

PSTimeDateEditor.m: Fix a tiny, and one-time, memory leak.

PSTimer.m: Update for new PSPowerManager API.

Pester.pbproj: Deleted; now supporting OS X 10.4+ (up from 10.1,
aiee.)

Pester.xcodeproj: Xcode 2.4+ project, upgraded targets, etc.

SoundFileManager?.h: Deleted; this SPI no longer exists in Leopard and
possibly earlier.

File size: 7.2 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 (multiplierTag <= 0) continue;
41        if (((int)interval % multiplierTag) == 0) {
42            NSFormatter *formatter = [self formatter];
43            int intervalValue = interval / multiplierTag;
44            if (formatter != nil) {
45                id ignored;
46                if (![formatter getObjectValue: &ignored forString: [formatter stringForObjectValue: [NSNumber numberWithInt: intervalValue]] errorDescription: NULL]) return NO;
47            }
48            [self setIntValue: intervalValue];
49            [intervalUnits selectItem: i];
50            return YES;
51        }
52    }
53    return NO;
54}
55
56- (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)range replacementString:(NSString *)string;
57{
58    unsigned length = [string length];
59    if (length != 0) {
60        unichar c;
61        int tag = -1;
62        c = [string characterAtIndex: length - 1];
63        switch (c) {
64            case 's': case 'S': tag = 1; break;
65            case 'm': case 'M': tag = 60; break;
66            case 'h': case 'H': tag = 60 * 60; break;
67            case 'u': case 'U': tag = -2; break;
68            default: break;
69        }
70        if (tag != -1) {
71            int itemIndex = [intervalUnits indexOfItemWithTag: tag];
72            if (itemIndex != -1) {
73                [intervalUnits selectItemAtIndex: itemIndex];
74                [[intervalUnits menu] performActionForItemAtIndex: itemIndex];
75            }
76            if (tag < 0) return NO; // don't send update
77        }
78    }
79    return [super textView: textView shouldChangeTextInRange: range replacementString: string];
80}
81
82- (void)handleDidFailToFormatString:(NSString *)string errorDescription:(NSString *)error label:(NSString *)label;
83{
84    NSString *alertMessage = nil;
85    NSString *alternateButtonString = nil;
86    NSNumber *proposedValue = nil;
87    NSDictionary *contextInfo;
88
89    NSString *alertInformation = [NSString localizedStringWithFormat:
90        NSLocalizedString(@"The %@ field must be set to a value between %@ and %@.",
91                          @"Informative text for alert posed by text field when invalid value entered"),
92        label, [[self formatter] minimum], [[self formatter] maximum]];
93    NSString *defaultButtonString = NSLocalizedString(@"Edit", @"Name of Edit button");
94    NSString *otherButtonString = NSLocalizedString(@"Cancel", @"Name of Cancel button");
95
96    if ([error isEqualToString:
97        NSLocalizedStringFromTableInBundle(@"Fell short of minimum", @"Formatter",
98                                           [NSBundle bundleForClass:[NSFormatter class]],
99                                           @"Presented when user value smaller than minimum")]) {
100        proposedValue = [[self formatter] minimum];
101        alertMessage = [NSString stringWithFormat:
102            NSLocalizedString(@"%@ is too small for the %@ field.",
103                              @"Message text for alert posed by numeric field when too-small value entered"),
104            string, label];
105        alternateButtonString = [NSString localizedStringWithFormat:
106            NSLocalizedString(@"Set to %@",
107                              @"Name of alternate button for alert posed by numeric field when too-small value entered"),
108            proposedValue];
109    } else if ([error isEqualToString:
110        NSLocalizedStringFromTableInBundle(@"Maximum exceeded", @"Formatter",
111                                           [NSBundle bundleForClass:[NSFormatter class]],
112                                           @"Presented when user value larger than maximum")]) {
113        proposedValue = [[self formatter] maximum];
114        alertMessage = [NSString stringWithFormat:
115            NSLocalizedString(@"%@ is too large for the %@ field.",
116                              @"Message text for alert posed by numeric field when too-large value entered"),
117            string, label];
118        alternateButtonString = [NSString localizedStringWithFormat:
119            NSLocalizedString(@"Set to %@",
120                              @"Name of alternate button for alert posed by numeric field when too-large value entered"),
121            proposedValue];
122    } else if ([error isEqualToString:
123        NSLocalizedStringFromTableInBundle(@"Invalid number", @"Formatter",
124                                           [NSBundle bundleForClass:[NSFormatter class]],
125                                           @"Presented when user typed illegal characters: no valid object")]) {
126        alertMessage = [NSString stringWithFormat:
127            NSLocalizedString(@"%@ is not a valid entry for the %@ field.",
128                              @"Message text for alert posed by text field when invalid value entered"),
129            string, label];
130        alternateButtonString = nil;
131    }
132
133    contextInfo = [NSDictionary dictionaryWithObject: proposedValue forKey: @"proposedValue"];
134    [contextInfo retain];
135    NSBeep();
136    NSBeginAlertSheet(alertMessage, defaultButtonString, alternateButtonString, otherButtonString, [self window],
137                      self, @selector(validationFailedSheetDidEnd:returnCode:contextInfo:), NULL, contextInfo,
138                      alertInformation);
139}
140
141- (void)_propagateValidationChange;
142{
143    NSText *fieldEditor = [self currentEditor];
144    NSDictionary *userInfo = nil;
145    if (fieldEditor != nil) userInfo = [NSDictionary dictionaryWithObject: fieldEditor forKey: @"NSFieldEditor"];
146    [[NSNotificationCenter defaultCenter] postNotificationName: NSControlTextDidChangeNotification object: self userInfo: userInfo];
147    [self selectText: self];
148}
149
150- (void)validationFailedSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
151    // modal delegate callback method for NSBeginAlertSheet() function; called in the above method
152    if (returnCode == NSAlertOtherReturn) { // cancel
153        [self abortEditing]; // abort edit session and reinstate original value
154        [self _propagateValidationChange];
155    } else if (returnCode == NSAlertAlternateReturn) { // set to min/max/default value
156        [self setObjectValue: [(NSDictionary *)contextInfo objectForKey: @"proposedValue"]];
157        [self validateEditing];
158        [self _propagateValidationChange];
159    }
160    [(NSDictionary *)contextInfo release];
161}
162
163@end
Note: See TracBrowser for help on using the repository browser.