discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

List of GNUstep fixes


From: Andreas Höschler
Subject: List of GNUstep fixes
Date: Fri, 25 Nov 2005 14:59:11 +0100

Dear all,

we are currently in the process of establishing a stable desktop environment for Solaris based on GNUstep (a mission critical business application and some utility apps). It seems that Window Maker is no option right now (focus problems discussed on the list). So we are stuck to JDS (not optimal but ok for now). In order to stabilize things we did the following changes to GNUstep so far. Please feel free to comment on these changes and/or integrate them in the official GNUstep tree (we have no write access to cvs). We will from time to time repost this list whenever essential changes have been addded (in the hope this is usefull to someone). If there is a better target channel for this please let me know.

Best regards,

Andreas

base

NSCalendarDate
Don't raise exceptions here, return nil instead, otherwise creating dates from invalid strings (NSDateFormatter tries this often) leads to crashes.

- (id) initWithYear: (int)year
month: (unsigned int)month
day: (unsigned int)day
hour: (unsigned int)hour
minute: (unsigned int)minute
second: (unsigned int)second
timeZone: (NSTimeZone *)aTimeZone
{
unsigned int c;
NSTimeInterval s;
NSTimeInterval oldOffset;
NSTimeInterval newOffset;

if (month < 1 || month > 12)
{
[self dealloc]; return nil;
// NSWarnMLog(@"invalid month given - %u", month);
}
c = lastDayOfGregorianMonth(month, year);
if (day < 1 || day > c)
{
[self dealloc]; return nil;
// NSWarnMLog(@"invalid day given - %u", day);
}
if (hour > 23)
{
[self dealloc]; return nil;
// NSWarnMLog(@"invalid hour given - %u", hour);
}
if (minute > 59)
{
[self dealloc]; return nil;
// NSWarnMLog(@"invalid minute given - %u", minute);
}
if (second > 59)
{
[self dealloc]; return nil;
// NSWarnMLog(@"invalid second given - %u", second);
}

// Calculate date as GMT
s = GSTime(day, month, year, hour, minute, second, 0);

// Assign time zone detail
if (aTimeZone == nil)
{
_time_zone = localTZ; // retain is a no-op for the local timezone.
}
else
{
_time_zone = RETAIN(aTimeZone);
}
if (_calendar_format == nil)
{
_calendar_format = cformat;
}
_seconds_since_ref = s;

/*
* Adjust date so it is correct for time zone.
*/
oldOffset = offset(_time_zone, self);
s -= oldOffset;
_seconds_since_ref = s;

/*
* See if we need to adjust for daylight savings time
*/
newOffset = offset(_time_zone, self);
if (oldOffset != newOffset)
{
s -= (newOffset - oldOffset);
_seconds_since_ref = s;
oldOffset = offset(_time_zone, self);
/*
* If the adjustment puts us in another offset, we must be in the
* non-existent period at the start of daylight savings time.
*/
if (oldOffset != newOffset)
{
NSWarnMLog(@"init non-existent time at start of daylight savings");
}
}

return self;
}

NSDateFormatter

- (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString**)error
{
NSCalendarDate *d = [NSCalendarDate dateWithString:string calendarFormat:_dateFormat];
if (d == nil)
{
if (_allowsNaturalLanguage)
{
d = [NSCalendarDate dateWithNaturalLanguageString:string];
}
if (d == nil)
{
if (error) *error = @"Couldn't convert to date";
return NO;
}
}
if (anObject) *anObject = d;
return YES;
}

NSNumberFormatter

- (BOOL)getObjectValue:(id*)anObject forString:(NSString *)string errorDescription:(NSString**)error
{
NSNumber *result = nil;
if (string)
{
NSRange thousandSeparatorRange = [string rangeOfString:@","];
NSRange decimalSeparatorRange = [string rangeOfString:@"."];
if (thousandSeparatorRange.length > 0 && decimalSeparatorRange.length > 0)
{
if (thousandSeparatorRange.location > decimalSeparatorRange.location)
string = [string stringAfterRemovingAllOccurancesOfString:@"."];
else
string = [string stringAfterRemovingAllOccurancesOfString:@","];
}
string = [string stringAfterReplacingAllOccurancesOfString:@"," withString:@"."];
result = [NSNumber numberWithDouble:[string doubleValue]];
}
if (result)
{
if (anObject) *anObject = result;
if (error) *error = nil;
return YES;
}
else
{
if (anObject) *anObject = nil;
if (error) *error = nil;
return NO;
}
}

gui

NSApplication

- (void)abortModal
{
[self stopModalWithCode:NSRunAbortedResponse];
}

NSTabView

- (NSSize)minimumSize
{
switch (_type)
{
case NSTopTabsBezelBorder:
return NSMakeSize(2, 19.5);
case NSNoTabsBezelBorder:
return NSMakeSize(2, 3);
case NSBottomTabsBezelBorder:
return NSMakeSize(2, 16);
default:
return NSZeroSize;
}
}

NSTableView
Simply nice to have.

@interface NSTableView (GNUstepFix)

- (void)selectPreviousRow;
- (void)selectNextRow;

@end

@implementation NSTableView (GNUstepFix)

- (void)keyDown:(NSEvent *)theEvent
{
NSString *string = [theEvent characters];

if ([string length] > 0)
{
if ([string characterAtIndex:0] == NSDownArrowFunctionKey)
{
[self selectNextRow];
}
else if ([string characterAtIndex:0] == NSUpArrowFunctionKey)
{
[self selectPreviousRow];
}
else [super keyDown:theEvent];
}
else [super keyDown:theEvent];
}

- (void)selectPreviousRow
{
int selectedRow = [self selectedRow];
if (selectedRow > 0)
[self selectRow:(selectedRow - 1) byExtendingSelection:NO];
}

- (void)selectNextRow
{
int numberOfRows = [self numberOfRows];
int selectedRow = [self selectedRow];
if (selectedRow < numberOfRows - 1)
[self selectRow:(selectedRow + 1) byExtendingSelection:NO];
}

@end

NSTextField
This fix makes sure, that objectValue is valid, when the delegate method is called (which is the case on MacOSX).

- (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)command
{
if (sel_eq (command, @selector(insertNewline:)))
{
[self validateEditing];
}
if (_delegate && [_delegate respondsToSelector: @selector(control:textView:doCommandBySelector:)])
{
return [_delegate control:self textView:textView doCommandBySelector:command];
}

return NO;
}

Check whether delegate does implement didFailToFormatString:.
- (void)validateEditing
{
if (_text_object)
{
NSFormatter *formatter;
NSString *string;

formatter = [_cell formatter];
string = AUTORELEASE ([[_text_object text] copy]);

if (formatter == nil)
{
[_cell setStringValue: string];
}
else
{
id newObjectValue;
NSString *error;

if ([formatter getObjectValue: &newObjectValue
forString: string
errorDescription: &error] == YES)
{
[_cell setObjectValue: newObjectValue];
}
else
{
SEL sel = @selector(control:didFailToFormatString:errorDescription:);
if ([_delegate respondsToSelector:sel] && [_delegate control:self didFailToFormatString:string errorDescription: error] == YES)
{
[_cell setStringValue: string];
}
}
}
}
}


I don't remember whatI changed in this method, but that's how it works
- (void) textDidChange: (NSNotification *)aNotification
{
NSDictionary *d;
NSFormatter *formatter;


d = [NSDictionary dictionaryWithObject: [aNotification object]
forKey: @"NSFieldEditor"];
[nc postNotificationName: NSControlTextDidChangeNotification
object: self
userInfo: d];


formatter = [_cell formatter];
if (formatter != nil)
{
/*
* FIXME: This part needs heavy interaction with the yet to finish
* text system.
*
*/
NSString *partialString;
NSString *newString = nil;
NSString *error = nil;
BOOL wasAccepted;


partialString = [_text_object string];
wasAccepted = [formatter isPartialStringValid: partialString
newEditingString: &newString
errorDescription: &error];


if (wasAccepted == NO)
{
SEL sel = @selector(control:didFailToValidatePartialString:errorDescription:);
if ([_delegate respondsToSelector:sel])
[_delegate control:self
didFailToValidatePartialString: partialString
errorDescription: error];
}


if (newString != nil)
{
NSLog (@"Unimplemented: should set string to %@", newString);
// FIXME ! This would reset editing !
//[_text_object setString: newString];
}
else
{
if (wasAccepted == NO)
{
// FIXME: Need to delete last typed character (?!)
NSLog (@"Unimplemented: should delete last typed character");
}
}


}
}


NSCell

- (void)setStringValue:(NSString *)aString
{
NSString *string = aString;

/* We warn about nil for compatibiliy with MacOS X, which refuses
nil. */
if (string == nil)
{
NSDebugMLLog (@"MacOSXCompatibility",
@"Attempt to use nil as string value");
}

[self setType: NSTextCellType];
_cell.contents_is_attributed_string = NO;

if (_formatter == nil)
{
ASSIGN (_contents, string);
ASSIGN (_objectValue, string); // <-- changed
_cell.has_valid_object_value = YES; // <--- changed
}
else
{
id newObjectValue;


if ([_formatter getObjectValue: &newObjectValue
forString: string
errorDescription: NULL] == YES)
{
[self setObjectValue: newObjectValue];
}
else
{
_cell.has_valid_object_value = NO;
ASSIGN (_contents, string);
}
}

}

NSBrowserCell

- (void)setType:(NSCellType)aType
{
[super setType: aType];
}

- (void)drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView *)controlView
{
...
if (cell_image)
{
NSSize size;;
NSPoint position;

size.height = cellFrame.size.height;
size.width = size.height;

position.x = NSMinX(title_rect);
position.y = NSMinY(title_rect);

if ([controlView isFlipped]) position.y += size.height;

NSImage *temp = [[NSImage alloc] initWithSize:size];
[temp lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation: NSImageInterpolationHigh];
[temp unlockFocus];

[cell_image setSize:size];
[cell_image setScalesWhenResized:YES];
[cell_image compositeToPoint:position operation:NSCompositeSourceOver];

[temp release];

title_rect.origin.x += size.width + 4;
title_rect.size.width -= size.width + 4;
}
...
}

NSPopUpButtonCell

- (void)synchronizeTitleAndSelectedItem
{
int index;

if (!_pbcFlags.usesItemFromMenu) return;

if ([_menu numberOfItems] == 0)
{
index = -1;
}
else if (_pbcFlags.pullsDown)
{
index = 0;
}
else
{
index = [[_menu menuRepresentation] highlightedItemIndex];
if (index < 0) index = [self indexOfSelectedItem];
// if (index < 0) index = 0; // <--------------- this is bad
}

if ((index >= 0) && ([_menu numberOfItems] > index))
{
NSMenuItem *anItem;


// This conversion is needed as [setMenuItem:] expects an NSMenuItem
anItem = (NSMenuItem *)[_menu itemAtIndex: index];
[self setMenuItem: anItem];
}
else
{
[self setMenuItem: nil];
}
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]