Annotation of Examples/IndexingKit/Ledger/LedgerController.m, revision 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.