home *** CD-ROM | disk | FTP | other *** search
- // -------------------------------------------------------------------------------------
- // BooleanFormatter.h
- // This software is without warranty of any kind. Use at your own risk.
- // -------------------------------------------------------------------------------------
-
- #import <objc/objc.h>
- #import <appkit/appkit.h>
- #import <mach/mach.h>
- #import <dbkit/dbkit.h>
- #import "BoolFormatter.h"
-
- // -------------------------------------------------------------------------------------
- // NXRect abbreviations
- #define X origin.x
- #define Y origin.y
- #define W size.width
- #define H size.height
-
- // -------------------------------------------------------------------------------------
- // drawCell image flags
- #define hideIMAGEMASK 1
- #define hideAltIMAGEMASK 2
- #define hideIMAGE ([drawCell tag] & hideIMAGEMASK)
- #define hideAltIMAGE ([drawCell tag] & hideAltIMAGEMASK)
- #define setHideIMAGE(X) [drawCell setTag:(hideAltIMAGE | ((X)? 0 : hideIMAGEMASK))];
- #define setHideAltIMAGE(X) [drawCell setTag:(hideIMAGE | ((X)? 0 : hideAltIMAGEMASK))];
-
- // -------------------------------------------------------------------------------------
- @implementation BoolFormatter
-
- // -------------------------------------------------------------------------------------
- // initialization
-
- /* init */
- - init
- {
-
- /* init */
- [super init];
- selectionMode = NX_HIGHLIGHTMODE;
- newValue = [[DBValue allocFromZone:[self zone]] init];
-
- /* drawing cell */
- drawCell = [[ButtonCell allocFromZone:[self zone]] initIconCell:""];
- [drawCell setBordered:NO];
- [drawCell setIconPosition:NX_ICONONLY];
- [drawCell setType:NX_TOGGLE];
- [drawCell setIcon:"NXswitch"];
- [drawCell setAltIcon:"NXswitchH"];
- [drawCell setTag:0];
-
- return self;
- }
-
- /* free */
- - free
- {
- [newValue free];
- [drawCell free];
- return[super free];
- }
-
- // -------------------------------------------------------------------------------------
- // set attributes
-
- /* set mode */
- - setMode:(int)newMode
- {
- selectionMode = newMode;
- return self;
- }
-
- /* return mode */
- - (int)mode
- {
- return selectionMode;
- }
-
- // -------------------------------------------------------------------------------------
- // images
-
- /* set unselected image */
- - setImage:anImage
- {
- setHideIMAGE(anImage);
- return [drawCell setImage:anImage];
- }
-
- /* return unselected image */
- - image
- {
- return hideIMAGE? (id)nil : [drawCell image];
- }
-
- /* set unselected image */
- - setIcon:(const char*)anIcon
- {
- setHideIMAGE(anIcon && *anIcon);
- return [drawCell setIcon:anIcon];
- }
-
- /* return unselected image */
- - (const char*)icon
- {
- return hideIMAGE? (char*)nil : [drawCell icon];
- }
-
- /* set selected image */
- - setAltImage:anImage
- {
- setHideAltIMAGE(anImage);
- return [drawCell setAltImage:anImage];
- }
-
- /* return selected image */
- - altImage
- {
- return hideAltIMAGE? (id)nil : [drawCell altImage];
- }
-
- /* set unselected image */
- - setAltIcon:(const char*)anIcon
- {
- setHideAltIMAGE(anIcon && *anIcon);
- return [drawCell setAltIcon:anIcon];
- }
-
- /* return unselected image */
- - (const char*)altIcon
- {
- return hideAltIMAGE? (char*)nil : [drawCell altIcon];
- }
-
- // -------------------------------------------------------------------------------------
- // drawing
-
- /* draw DBTableView field cell */
- - drawFieldAt:(u_int)row :(u_int)col inside:(NXRect*)frame inView:view
- withAttributes:(id <DBTableVectors>)ra :(id <DBTableVectors>)ca
- usePositions:(BOOL)ur :(BOOL)uc;
- {
- BOOL boolState;
-
- /* cache value and set state */
- [self getValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
- boolState = ([value isNull] || (*[value stringValue] == 'N'))? NO : YES;
- [drawCell setState:boolState];
-
- /* draw image (if there is an image to draw) */
- if (!((boolState && hideAltIMAGE) || (!boolState && hideIMAGE))) {
- [drawCell setAlignment:[(([ra formatter]==self)?ra:ca) contentAlignment]];
- [drawCell drawInside:frame inView:[NXApp focusView]];
- }
-
- return self;
- }
-
- // -------------------------------------------------------------------------------------
- // event monitoring
-
- /* grab mouse-down to check for toggle value */
- - mouseDown:(NXEvent*)e at:(int)row:(int)col inside:(NXRect*)frame inView:(View*)view
- withAttributes:(id <DBTableVectors>)ra:(id <DBTableVectors>)ca
- usePositions:(BOOL)ur:(BOOL)uc
- {
- id lv, vw;
-
- /* ignore if not a double click */
- if (e->data.mouse.click < 2) return (id)nil;
-
- if (selectionMode == NX_RADIOMODE) { // radio mode (not fully tested)
- int ndx;
-
- /* clear all other row values */
- [newValue setStringValue:"NO"];
- for (ndx = 0; ndx < [dataSource rowCount]; ndx++) {
- if (ndx == row) continue;
- [self getValueAt:ndx:col withAttributes:ra:ca usePositions:ur:uc];
- if ((*[value stringValue] != 'N') &&
- (![self setValueAt:ndx:col withAttributes:ra:ca usePositions:ur:uc]))
- return (id)nil;
- }
-
- /* get requested row value and re-set it to true */
- [self getValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
- if ([value isNull] || (*[value stringValue] == 'N')) {
- [newValue setStringValue:"YES"];
- [self setValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
- }
-
- } else { // list mode
-
- /* toggle value */
- [self getValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
- if ([value isNull] || (*[value stringValue] == 'N')) [newValue setStringValue:"YES"];
- else [newValue setStringValue:"NO"];
- [self setValueAt:row:col withAttributes:ra:ca usePositions:ur:uc];
-
- }
-
- /* redraw field (just tell DBTableView, if possible) */
- for (lv = (id)nil, vw = view; vw && (lv != vw); lv = vw, vw = [vw superview]) {
- if ([vw isKindOf:[DBTableView class]]) {
- u_int r = ur? row : (u_int)[ra identifier];
- [vw rowsChangedFrom:r to:r];
- return self;
- }
- }
-
- /* slow redraw */
- [self drawFieldAt:row:col inside:frame inView:view
- withAttributes:ra:ca usePositions:ur:uc];
- [view display];
- [[view window] flushWindow];
-
- return self;
- }
-
- // -------------------------------------------------------------------------------------
- // changing values
-
- /* set field value */
- - setValueAt:(int)row :(int)col
- withAttributes:(id <DBTableVectors>)ra :(id <DBTableVectors>)ca
- usePositions:(BOOL)ur :(BOOL)uc
- {
- u_int c = uc? col : (u_int)[ca identifier];
- u_int r = ur? row : (u_int)[ra identifier];
-
- /* rows only */
- if (ur && !uc) {
- if ([delegate respondsTo:@selector(formatterWillChangeValueFor:at:to:sender:)] &&
- ![delegate formatterWillChangeValueFor:(id)c at:r to:newValue sender:self])
- return (id)nil;
- [dataSource setValueFor:(id)c at:r from:newValue];
- if ([delegate respondsTo:@selector(formatterDidChangeValueFor:at:to:sender:)])
- [delegate formatterDidChangeValueFor:(id)c at:r to:newValue sender:self];
- return self;
- }
-
- /* columns only */
- if (!ur && uc) {
- if ([delegate respondsTo:@selector(formatterWillChangeValueFor:at:to:sender:)] &&
- ![delegate formatterWillChangeValueFor:(id)r at:c to:newValue sender:self])
- return (id)nil;
- [dataSource setValueFor:(id)r at:c from:newValue];
- if ([delegate respondsTo:@selector(formatterDidChangeValueFor:at:to:sender:)])
- [delegate formatterDidChangeValueFor:(id)r at:c to:newValue sender:self];
- return self;
- }
-
- /* default */
- if (![delegate formatterWillChangeValueFor:(id)r:(id)c to:newValue sender:self])
- return (id)nil;
- [dataSource setValueFor:(id)r:(id)c from:newValue];
- if ([delegate respondsTo:@selector(formatterDidChangeValueFor::to:sender:)])
- [delegate formatterDidChangeValueFor:(id)r:(id)c to:newValue sender:self];
-
- return self;
- }
-
- // -------------------------------------------------------------------------------------
- // archiving
-
- /* archive object to stream */
- - write:(NXTypedStream*) stream
- {
- [super write:stream];
- return self;
- }
-
- /* read object from stream */
- - read:(NXTypedStream*) stream
- {
- [super read:stream];
- return self;
- }
-
- @end
-