home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Examples / IndexingKit / Ledger / LedgerController.m < prev    next >
Encoding:
Text File  |  1993-02-16  |  8.1 KB  |  302 lines

  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
  302.