Annotation of Examples/IndexingKit/Ledger/LedgerController.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Controller for the Ledger Document.
                      3:  *
                      4:  * Author: Kris Younger, NeXT Systems Engineering
                      5:  * You may freely copy, distribute and reuse the code in this example.  
                      6:  * NeXT disclaims any warranty of any kind, expressed or implied, as to 
                      7:  * its fitness for any particular use.
                      8:  */
                      9: 
                     10: #import "LedgerController.h"
                     11: #import "Transaction.h"
                     12: #import <dbkit/dbkit.h>
                     13: #import "JFTableVectorConfiguration.h"
                     14: #import "JFTableViewLoader.h"
                     15: #import "KAYEditableFormatter.h"
                     16: #define XOFFSET 30.0   // Offset of subsequent windows
                     17: #define YOFFSET -30.0
                     18: 
                     19: @implementation LedgerController
                     20: 
                     21: - append:sender
                     22: {
                     23:     id                  newXaction;
                     24:     int                 handle;
                     25: 
                     26:     newXaction = [[Transaction alloc] init];
                     27:     [accountStore startTransaction];
                     28:     handle = [account addRecord:newXaction];
                     29:     [accountStore commitTransaction];
                     30:     if (sender != myFormatter) [self ping:sender];
                     31:     return self;
                     32: }
                     33: 
                     34: - appendThis:anObj
                     35: {
                     36:     int                 handle;
                     37: 
                     38:     [accountStore startTransaction];
                     39:     handle = [account addRecord:anObj];
                     40:     [accountStore commitTransaction];
                     41:     return self;
                     42: }
                     43: 
                     44: - commit:sender
                     45: {
                     46:     int                 r;
                     47:     id                  o;
                     48: 
                     49:     r = [tableView selectedRowAfter:DB_NoIndex];
                     50:     if (r != DB_NoIndex) {
                     51:        o = (Transaction *)[postingList objectAt:r];
                     52:        [accountStore startTransaction];
                     53:        [account replaceRecord:[o handle] with:o];
                     54:        [accountStore commitTransaction];
                     55:        if (r == ([postingList count] - 1)) {
                     56:            [self doBalance];
                     57:            if (sender != myFormatter) [self ping:self];
                     58:        } else
                     59:            [self doFullerBalance:self];
                     60:     };
                     61:     return self;
                     62: }
                     63: 
                     64: - copy:sender
                     65: {
                     66:     return self;
                     67: }
                     68: 
                     69: - cut:sender
                     70: {
                     71:     return self;
                     72: }
                     73: 
                     74: - paste:sender
                     75: {
                     76:     return self;
                     77: }
                     78: 
                     79: - selectAll:sender
                     80: {
                     81:     return self;
                     82: }
                     83: 
                     84: - initWith:aRecordManager named:(const char *)aName
                     85: {
                     86:     char                path[MAXPATHLEN + 1];
                     87:     int                 i;
                     88: 
                     89:     if ([[NXBundle mainBundle] getPath:path forResource:"LedgerController" ofType:"nib"]) {
                     90:        window = [NXApp loadNibFile:path owner:self];
                     91:     /*
                     92:      * Put the window offset from the previous document window... If no
                     93:      * previous window exists, or the main window is undetermined, then 
                     94:      */
                     95:        if ([[[NXApp mainWindow] delegate] respondsTo:@selector(isLedger)] == YES) {
                     96:            NXRect              winFrame, winLoc;
                     97: 
                     98:            [[NXApp mainWindow] getFrame:&winFrame];
                     99:            [[window class] getContentRect:&winLoc 
                    100:                forFrameRect:&winFrame style:[window style]];
                    101:            [window moveTo:NX_X(&winLoc) + XOFFSET:NX_Y(&winLoc) + YOFFSET];
                    102:        }
                    103: /* the tvLoader is an object which takes a list of objects and a list of configuration objects (see below) which work to load the tableview when it requests it. */
                    104:        tvLoader = [[JFTableViewLoader alloc] init];
                    105:        account = aRecordManager;
                    106:        accountName = aName;
                    107:        [account getBlock:&i andStore:&accountStore];
                    108:        [tvLoader setTableView:tableView];
                    109:        [[tableView setGridVisible:YES] setDelegate:self];
                    110:        [[tableView window] setTitle:accountName];
                    111: #ifdef NEVEREVER
                    112:                /* useful in making window positions sticky on the
                    113:                                 * desktop. */
                    114:        [[tableView window] setFrameAutosaveName:accountName];
                    115:        [[tableView window] setFrameUsingName:accountName];
                    116: #endif
                    117:        myFormatter = [[KAYEditableFormatter alloc] init];
                    118:        [myFormatter setController:self];
                    119:        [[tableView window] disableFlushWindow];
                    120:        [self buildConfigurationList];
                    121: /* go check out the method, it loads a list full of "bindings" binding a tableview column to an ivar inside of the Transaction object. essentially, letting us use a list of objects instead of a recordlist. */
                    122:        [tvLoader setConfigurationList:configList];
                    123:        [myFormatter setColumnLimit:[configList count] - 1];
                    124:        [[tableView window] reenableFlushWindow];
                    125:        [[tableView window] flushWindowIfNeeded];
                    126:        for (i = 0; i < [configList count]; i++) {
                    127:            [[tableView columnAt:i] setFormatter:myFormatter];
                    128:        };
                    129:        doFullBalance = NO;
                    130:     } else {
                    131:        NXRunAlertPanel("Oops!", "No LedgerController nib file", "OK", NULL, NULL);
                    132:        return nil;
                    133:     }
                    134:     return self;
                    135: }
                    136: 
                    137: - findPostings
                    138: {
                    139:     int                        handle;
                    140:     id                 config;
                    141:     IXPostingCursor    *cursor;
                    142:     BOOL               isValid;
                    143: 
                    144: /* since the Transaction objects are serialized by creation (handled in the main delegate), this method uses the attribute "tSerial" to get a sorted-ascending ordering. The postingList is what we use load the tableview */
                    145: 
                    146:     config = [[tableView columnAt:0] identifier];
                    147:     cursor = [account cursorForAttributeNamed:
                    148:        [[configList objectAt:(int)config] ivarName]];
                    149:     if (cursor == nil)
                    150:        cursor = [account cursorForAttributeNamed:"tSerial"];
                    151: 
                    152:     postingList = [postingList free];
                    153:     postingList = [[IXPostingList alloc] initWithSource:account];
                    154:     for (isValid = [cursor setFirst]; isValid; isValid = [cursor setNext])
                    155:        for (handle = [cursor setFirstHandle]; handle; handle = [cursor setNextHandle])
                    156:            [postingList addHandle:handle withWeight:0];
                    157: 
                    158:     [cursor free];
                    159:     return postingList;
                    160: }
                    161: 
                    162: - makeKey:sender
                    163: {
                    164:     [self doBalance];
                    165:     [self ping:self];
                    166:     return self;
                    167: }
                    168: 
                    169: - (const char *)accountName
                    170: {
                    171:     return accountName;
                    172: }
                    173: 
                    174: - doBalance
                    175: {
                    176:     double              cBalance = 0.0;
                    177:     char                buf[256];
                    178:     int                 i, k, h, m;
                    179:     id                  obj;
                    180: 
                    181:     postingList = [self findPostings];
                    182:     k = [postingList count];
                    183:     [accountStore startTransaction];
                    184:     if (((k - 2) <= 0) || (doFullBalance == YES)) {
                    185:        m = 0;
                    186:        cBalance = 0.0;
                    187:     } else {
                    188:        m = (k - 2);
                    189:        h = [postingList handleOfObjectAt:(m - 1)];
                    190:        obj = [account readRecord:h fromZone:[self zone]];
                    191:        strcpy(buf,[obj tBalance]);
                    192:        cBalance += atof(buf);
                    193:     };
                    194:     for (i = m; i < k; i++) {
                    195:        h = [postingList handleOfObjectAt:i];
                    196:        obj = [account readRecord:h fromZone:[self zone]];
                    197:        cBalance += [obj tAmount];
                    198:        sprintf(buf, "%.2f", cBalance);
                    199:        [obj setTBalance:buf];
                    200:        [account replaceRecord:[obj handle] with:obj];
                    201:        [obj free];
                    202:     }
                    203:     [accountStore commitTransaction];
                    204:     sprintf(buf, "%.2f", cBalance);
                    205:     [balanceTF setStringValue:buf];
                    206:     return self;
                    207: }
                    208: 
                    209: - doFullerBalance:sender
                    210: {
                    211:     doFullBalance = YES;
                    212:     [self doBalance];
                    213:     [self ping:self];
                    214:     doFullBalance = NO;
                    215: 
                    216:     return self;
                    217: }
                    218: 
                    219: - ping:sender
                    220: {
                    221: 
                    222:     [window makeKeyAndOrderFront:self];
                    223:     [[tableView window] disableFlushWindow];   /* DBTV ignores autodisplay */
                    224:     postingList = [self findPostings];
                    225:     [tvLoader setDataList:postingList];
                    226:     [tableView scrollRowToVisible:[tableView rowCount] - 1];
                    227:     [tableView editFieldAt:[tableView rowCount] - 1:0];
                    228:     [[tableView window] reenableFlushWindow];
                    229:     [[tableView window] flushWindowIfNeeded];
                    230:     return self;
                    231: }
                    232: 
                    233: - void:sender
                    234: {
                    235:     int                 r, h;
                    236:     id                  o, p;
                    237: 
                    238:     r = [tableView selectedRowAfter:DB_NoIndex];
                    239:     if (r != DB_NoIndex) {
                    240:        o = (Transaction *)[postingList objectAt:r];
                    241:        p = [[Transaction alloc] init];
                    242:        [accountStore startTransaction];
                    243:        h = [account addRecord:p];
                    244:        [p becomeVoided:o];
                    245:        [account replaceRecord:[o handle] with:o];
                    246:        [account replaceRecord:[p handle] with:p];
                    247:        [accountStore commitTransaction];
                    248:        [self doBalance];
                    249:        [self ping:self];
                    250:     };
                    251:     return self;
                    252: }
                    253: 
                    254: - closeAccount:sender
                    255: {
                    256:     [window performClose:self];
                    257:     return self;
                    258: }
                    259: 
                    260: - windowWillClose:sender
                    261: {
                    262:     return self;
                    263: }
                    264: 
                    265: - tableView:sender movedColumnFrom:(unsigned int)old to:(unsigned int)new
                    266: {
                    267:     if (new == 0) [self ping:self];
                    268:     return self;
                    269: }
                    270: 
                    271: - buildConfigurationList
                    272: {
                    273:     configList = [[List alloc] init];
                    274:     [configList addObject:[[JFTableVectorConfiguration alloc]
                    275:                           initDataClassName:"Transaction"
                    276:                           titleName:"Date"
                    277:                           ivarName:"tDate"]];
                    278:     [configList addObject:[[JFTableVectorConfiguration alloc]
                    279:                           initDataClassName:"Transaction"
                    280:                           titleName:"REF"
                    281:                           ivarName:"tNumber"]];
                    282:     [configList addObject:[[JFTableVectorConfiguration alloc]
                    283:                           initDataClassName:"Transaction"
                    284:                           titleName:"Description"
                    285:                           ivarName:"tMemo"]];
                    286:     [configList addObject:[[JFTableVectorConfiguration alloc]
                    287:                           initDataClassName:"Transaction"
                    288:                           titleName:"Debit"
                    289:                           ivarName:"tDebit"]];
                    290:     [configList addObject:[[JFTableVectorConfiguration alloc]
                    291:                           initDataClassName:"Transaction"
                    292:                           titleName:"Credit"
                    293:                           ivarName:"tCredit"]];
                    294:     [configList addObject:[[JFTableVectorConfiguration alloc]
                    295:                           initDataClassName:"Transaction"
                    296:                           titleName:"Balance"
                    297:                           ivarName:"tBalance"]];
                    298:     return self;
                    299: }
                    300: 
                    301: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.