home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 4 / AACD04.ISO / AACD / Utilities / OHAC / source / OHAC.e
Text File  |  1999-09-20  |  26KB  |  832 lines

  1. /* $VER: OHAC 1.3 (20.9.99) by J. Tierney
  2.  
  3.   OHAC (Oh Heck, Another Calendar!) v1.3
  4.   Began:  04/29/99
  5.  
  6.  
  7. - 1.3
  8.   (9/20/99)
  9.     - The reset button's text is now "Today".
  10.     - resetcal() now displays "Today." (w/ a period).
  11.     - "Set Today" & "Reset Today" menu items.
  12.       - New procs:  settoday(), resettoday().
  13.     - Removed an unneeded line in dayreport().
  14.     - The "Today" button now has 3 functions:
  15.       - Today       - Jump to the currently set "today".
  16.       - SHIFT Today - Set the currently displayed date as "today".
  17.       - ALT Today   - Reset "today" to the current system date.
  18.     - New startup option:  SETTODAY.
  19.  
  20. - 1.2a
  21.   (6/20/99)
  22.     - Year inc/decrement gadgets.
  23.       - New proc:  incyear().
  24.  
  25.   (6/19/99)
  26.     - LEFTEDGE and TOPEDGE are (again) initialized to -1.  Fixed the
  27.      EasyGUI-JJT centering problem with a few Max()'s.
  28.  
  29. - 1.2
  30.   (6/17/99)
  31.     - LEFTEDGE and TOPEDGE are initialized to 0.  EasyGUI-JJT doesn't properly
  32.      center windows if WIDTH/HEIGHT <> 0.
  33.  
  34.   (6/16/99)
  35.     - Using a new EasyGUI-JJT.m.
  36.       - EG_WIDTH and EG_HEIGHT tags.
  37.       - No longer necessary (or desirable) to initialize the WIDTH and HEIGHT
  38.        opts to -1.
  39.       - datemenu() now uses guihandle.menutrigger (the "data" arg is no longer
  40.        the menuitem).
  41.  
  42.   (6/10/99)
  43.     - Renamed MENUDATE arg to DATEMENU.
  44.  
  45.   (6/8/99)
  46.     - Discovered the docs for the calendar gadget :-), so it can now be resized
  47.      vertically, too.
  48.     - New arg:  HEIGHT (saw that one comming, didn't ya?).
  49.     - New error message:  STR_ERRCAL.
  50.  
  51.   (6/7/99)
  52.     - Reorganized source.
  53.  
  54.   (6/6/99)
  55.     - diskfont.library is no longer required.  initfontreq() and loadfont()
  56.      take this into account.
  57.     - loadfont() reverts to the screen's font if the requested font can't be
  58.      opened.
  59.     - Localized the change-font releates strings.
  60.     - Optimized localize().
  61.       - New proc:  locassignstrs().
  62.       - Removed catsetstr() and nocatsetstr().
  63.     - EXPERIMENTAL:  Using ooresourcestack12.
  64.  
  65.   (6/5/99)
  66.     - Bug fix:  GetProgramName() returns path, but wbarg.name doesn't.
  67.     - Removed the string-length check in parsedate().  This allows MENUDATEs
  68.      to have additional text (eg "01.01.2000 - Y2K").
  69.     - Removed a useless bit of code from main().
  70.     - The WIDTH arg is back.  I switched from using easyguiA() to guiinitA()
  71.      and doing a sizewin() afterwards.
  72.     - "Change Font" menu option.
  73.       - New procs:  initfontreq(), chngfont().
  74.  
  75.   (6/4/99)
  76.     - Snapshot is back (and done).  :-)
  77.     - Removed a couple NM_BARLABELS.
  78.  
  79.   (6/1/99)
  80.     - Adding Iconify feature.
  81.  
  82.   (5/31/99)
  83.     - Using new date format:  dd.mm.yyyy.  The seperator char doesn't matter,
  84.      and each field will revert to the current setting if it isn't valid.
  85.      Ex:  25.12.???? will = Dec 25, this year.
  86.     - Switched to EasyGUI-JJT.m - I changed the menu func to pass the menuitem
  87.      to the action func.
  88.     - Adding user-defined Date menu.
  89.       - New procs:  copydatestrs(), makemenus(), datemenu().
  90.     - The SHOWDATE arg is added to the Date menu (right after "Today").
  91.  
  92.   (5/28/99)
  93.     - Got the EG_FONT tag working (it's necessary to first open the font;
  94.      EasyGUI won't).
  95.       - New procs:  fixfontname() & loadfont().
  96.     - Added the EG_TOP and EG_LEFT tags.  There aren't any tags to set the
  97.      width or height.  Ha!
  98.     - Removed WIDTH arg (see above) and snaphot (see above).  :-)
  99.     - The SHOWDATE arg works.  Uses dd-mm-yy format.
  100.       - New proc:  parsedate().
  101.       - Day report now accepts a NIL gui arg, and will just set g_tmpstr.
  102.     - PUBSCREEN arg works.
  103.     - Screen-jump feature.
  104.       - New proc:  jumpscr().
  105.  
  106.   (5/27/99)
  107.     - Planning to add snaphot and iconify features.  ...& parseargs().
  108.     - Changed localize() to get month names and "Today" from default Locale.
  109.  
  110.   (5/25/99)
  111.     - Using OOResourceStack11.m.
  112.     - Localizing...
  113.  
  114.   (5/24/99)
  115.     - Optimized openlibs().
  116.     - Planning to localize...
  117.  
  118. - 1.1
  119.   (5/13/99)
  120.     - Bug fix:  usgn_less() never returned the result.  D'oh!.
  121.     - Menus!  "About" and "Quit".
  122.     - ezreq().
  123.     - Error reporting.
  124.  
  125.   (5/6/99)
  126.     - Replaced calls to Div() in day report with utility.library's UdivMod32().
  127.      Allows for the maximum amount of years (1978 - 2113).
  128.  
  129.   (5/5/99)
  130.     - Using usgn_less in dayreport().  Allows max year of 2066.
  131.  
  132.   - Thank You, God!!!
  133.  
  134. */
  135.  
  136. OPT LARGE
  137.  
  138. MODULE 'dos/dos',
  139.        'dos/rdargs',
  140.        'exec/io',
  141.        'graphics/text',
  142.        'intuition/intuition',
  143.        'intuition/screens',
  144.        'asl',
  145.        'diskfont',
  146.        'icon',
  147.        'locale',
  148.        'timer',
  149.        'utility',
  150.        'utility/date',
  151.        'utility/tagitem',
  152.        'wb',
  153.        'workbench/startup',
  154.        'workbench/workbench',
  155.        'devices/inputevent',
  156.        'devices/timer',
  157.        'libraries/asl',
  158.        'libraries/gadtools',
  159.        'libraries/locale',
  160.        'tools/EasyGUI-JJT',
  161.        'plugins/calendar',
  162.        'other/oolist',
  163.        'other/oostring',
  164.        'other/ooresourcestack12'
  165.  
  166.  
  167. CONST SECSINDAY = 86400, MAXPUBSCRNAME = MAXPUBSCREENNAME + 1,
  168.       SHIFT = IEQUALIFIER_LSHIFT OR IEQUALIFIER_RSHIFT,
  169.       ALT = IEQUALIFIER_LALT OR IEQUALIFIER_RALT
  170.  
  171.  
  172. ENUM OK=0, QUIT, ER_TIMER, ER_ARGS,
  173.  
  174.      RA_X=0, RA_Y, RA_W, RA_H,
  175.      RA_PUBSCR,
  176.      RA_FONT, RA_FSIZE,
  177.      RA_DATE, RA_TODAY, RA_ICONIFY, RA_ICONIMG,
  178.      RA_USRDATES,
  179.      RA_COUNT,
  180.  
  181.      STR_TXTCREDIT=0,
  182.      STR_TXTDAY, STR_TXTDAYS, STR_TXTAGO, STR_TXTAWAY,
  183.      STR_TXTJAN, STR_TXTFEB, STR_TXTMAR, STR_TXTAPR, STR_TXTMAY, STR_TXTJUN,
  184.      STR_TXTJUL, STR_TXTAUG, STR_TXTSEP, STR_TXTOCT, STR_TXTNOV, STR_TXTDEC,
  185.      STR_TXTTODAY, STR_TXTTODAY2,
  186.  
  187.      STR_REQERROR=50, STR_REQWARN, STR_REQABOUT, STR_REQFONT,
  188.  
  189.      STR_ERRMEM=75, STR_ERRGUI, STR_ERRBIG, STR_ERRTIMER, STR_ERRARGS,
  190.      STR_ERRICONIFY, STR_ERRMPORT, STR_ERRAPICON, STR_ERRCAL,
  191.  
  192.      STR_GADOK=125, STR_GADRESET,
  193.  
  194.      STR_MNUPROJ=175,
  195.        STR_MNUJUMP, STR_MNUICONIFY, STR_MNUFONT, STR_MNUSNAP, STR_MNUABOUT,
  196.        STR_MNUQUIT,
  197.      STR_MNUDATES,
  198.        STR_MNUDATESET, STR_MNUDATERESET,
  199.  
  200.      STR_COUNT
  201.  
  202.  
  203. DEF timerbase, g_timerio:timerequest, g_time:timeval, g_date:clockdata,
  204.     g_locale=NIL, g_catalog=NIL, g_stringlist[STR_COUNT]:LIST,
  205.     g_args[RA_COUNT]:ARRAY OF LONG,
  206.     g_font, g_txtattr:textattr,
  207.     g_gui:PTR TO guihandle,
  208.     g_cal:PTR TO calendar, g_caldate:clockdata,
  209.     gad_month, gad_year, gad_text, g_menudata, g_usermenucnt,
  210.     g_tmpstr[80]:STRING,
  211.     g_ohacname[256]:STRING,
  212.     g_iconifyicon:PTR TO diskobject, g_fontreq=NIL:PTR TO fontrequester
  213.  
  214.  
  215. PROC main() HANDLE
  216.   DEF str, endprg
  217.  
  218.   initresourcelist()
  219.   openlibs([{aslbase}, 'asl.library', 36, FALSE,
  220.                        {diskfontbase}, 'diskfont.library', 0, FALSE,
  221.                        {localebase}, 'locale.library', 38, FALSE,
  222.                        {iconbase}, 'icon.library', 36, TRUE,
  223.                        {utilitybase}, 'utility.library', 0, TRUE,
  224.                        {workbenchbase}, 'workbench.library', 36, TRUE,
  225.                        0])
  226.   parseargs(g_args)
  227.   localize()
  228.   opentimer()
  229.   initfontreq()
  230.   loadfont(g_args[RA_FONT], g_args[RA_FSIZE])
  231.  
  232.   syncdate(g_date)
  233.   parsedate(g_args[RA_TODAY], g_date)
  234.   syncdate(g_caldate)
  235.   parsedate(g_args[RA_DATE], g_caldate)
  236.   NEW g_cal.calendar(g_caldate, TRUE, TRUE)
  237.   g_menudata:=makemenus(g_args[RA_USRDATES], g_usermenucnt)
  238.  
  239.   IF g_args[RA_ICONIFY] THEN iconify(NIL)
  240.   dayreport(NIL)
  241.   makegui()
  242.  
  243.   REPEAT
  244.     Wait(g_gui.sig)
  245.     endprg:=guimessage(g_gui)
  246.   UNTIL endprg >= 0
  247.  
  248.   EXCEPT DO
  249.     IF exception > QUIT
  250.       SELECT exception
  251.         CASE "MEM"
  252.           str:=STR_ERRMEM
  253.         CASE "GT"
  254.           str:='Unable to open gadtools.library.'
  255.         CASE "GUI"
  256.           str:=STR_ERRGUI
  257.         CASE "bigg"
  258.           str:=STR_ERRBIG
  259.         CASE "cal"
  260.           str:=STR_ERRCAL
  261.         CASE ER_TIMER
  262.           str:=STR_ERRTIMER
  263.         DEFAULT
  264.           str:=NIL
  265.       ENDSELECT
  266.       IF str THEN ezreq(0, g_stringlist[STR_REQERROR], g_stringlist[str])
  267.     ENDIF
  268.  
  269.     cleangui(g_gui)
  270.     END g_cal
  271.     freeresourcelist()
  272. ENDPROC
  273.  
  274. PROC parseargs(argary:PTR TO LONG) HANDLE
  275.   DEF wb:PTR TO wbstartup, warg:PTR TO wbarg, freefunc=NIL,
  276.       info:PTR TO diskobject, rdargs, rdopts[RA_COUNT]:ARRAY OF LONG,
  277.       i, cd
  278.  
  279.   FOR i:=0 TO RA_COUNT - 1
  280.     argary[i]:=NIL
  281.     rdopts[i]:=NIL
  282.   ENDFOR
  283.   argary[RA_X]:=-1
  284.   argary[RA_Y]:=-1
  285.  
  286.   IF wbmessage
  287.     wb:=wbmessage
  288.     i:=IF wb.numargs > 1 THEN 1 ELSE 0
  289.     warg:=wb.arglist[i]
  290.     cd:=CurrentDir(warg.lock)
  291.     StringF(g_ohacname, 'PROGDIR:\s', warg.name)
  292.     IF (info:=GetDiskObject(warg.name))
  293.       freefunc:=`FreeDiskObject(info)
  294.  
  295.       FOR i:=0 TO 4
  296.         IF (rdargs:=FindToolType(info.tooltypes, ListItem(['LEFTEDGE', 'TOPEDGE', 'WIDTH', 'HEIGHT', 'FONTSIZE'], i)))
  297.           argary[ListItem([RA_X, RA_Y, RA_W, RA_H, RA_FSIZE], i)]:=Val(rdargs) AND $FFFF
  298.         ENDIF
  299.       ENDFOR
  300.  
  301.       FOR i:=0 TO 3
  302.         rdopts[ListItem([RA_PUBSCR, RA_FONT, RA_DATE, RA_TODAY, RA_ICONIMG], i)]:=FindToolType(info.tooltypes, ListItem(['PUBSCREEN', 'FONT', 'SHOWDATE', 'SETTODAY', 'ICONIFIEDIMAGE'], i))
  303.       ENDFOR
  304.  
  305.       rdopts[RA_ICONIFY]:=FindToolType(info.tooltypes, 'ICONIFY')
  306.  
  307.       i, g_usermenucnt:=copydatestrs(info.tooltypes, TRUE)
  308.       argary[RA_USRDATES]:=i
  309.     ENDIF
  310.     CurrentDir(cd)
  311.   ELSE
  312.     GetProgramName(g_ohacname, 256)
  313.     IF (rdargs:=ReadArgs('X=LEFTEDGE/K/N,Y=TOPEDGE/K/N,W=WIDTH/K/N,H=HEIGHT/K/N,'+
  314.                          'PS=PUBSCREEN/K,F=FONT/K,FS=FONTSIZE/K/N,'+
  315.                          'SD=SHOWDATE/K,ST=SETTODAY/K,I=ICONIFY/S,IMG=ICONIFIEDIMAGE/K,'+
  316.                          'DM=DATEMENU/K/M', rdopts, NIL))
  317.       freefunc:=`FreeArgs(rdargs)
  318.  
  319.       FOR i:=0 TO 4
  320.         cd:=ListItem([RA_X, RA_Y, RA_W, RA_H, RA_FSIZE], i)
  321.         IF rdopts[cd] THEN argary[cd]:=Long(rdopts[cd])
  322.       ENDFOR
  323.  
  324.       i, g_usermenucnt:=copydatestrs(rdopts[RA_USRDATES], FALSE)
  325.       argary[RA_USRDATES]:=i
  326.     ENDIF
  327.   ENDIF
  328.  
  329.   FOR i:=0 TO 2
  330.     cd:=ListItem([RA_DATE, RA_TODAY, RA_ICONIMG], i)
  331.     IF rdopts[cd] THEN argary[cd]:=clonestr(rdopts[cd])
  332.   ENDFOR
  333.  
  334.   argary[RA_PUBSCR]:=LockPubScreen(rdopts[RA_PUBSCR])
  335.   addresource(`UnlockPubScreen(NIL, g_args[RA_PUBSCR]))
  336.   ScreenToFront(argary[RA_PUBSCR])
  337.  
  338.   IF rdopts[RA_FONT] THEN argary[RA_FONT]:=fixfontname(rdopts[RA_FONT])
  339.   argary[RA_ICONIFY]:=IF rdopts[RA_ICONIFY] THEN TRUE ELSE NIL
  340.  
  341.   EXCEPT DO
  342.     IF freefunc THEN Eval(freefunc)
  343.     ReThrow()
  344. ENDPROC
  345.  
  346. PROC copydatestrs(strarray:PTR TO LONG, ttlist)
  347.   DEF estrlist=NIL, estr, str, i=0, laststr, strcount
  348.  
  349.   IF strarray
  350.     WHILE (str:=strarray[i++])
  351.  
  352.       IF ttlist
  353.         str:=IF StrCmp(str, 'DATEMENU=', 9) THEN str + 9 ELSE NIL
  354.       ENDIF
  355.  
  356.       IF str
  357.         estr:=clonestr(str, TRIM_BOTH)
  358.         IF estrlist THEN Link(laststr, estr) ELSE estrlist:=estr
  359.         laststr:=estr
  360.         INC strcount
  361. ->        WriteF('\s\n', str)
  362.       ENDIF
  363.     ENDWHILE
  364.   ENDIF
  365. ENDPROC estrlist, strcount
  366.  
  367. PROC localize()
  368.   DEF i
  369.  
  370.   IF localebase
  371.     g_locale:=OpenLocale(NIL)
  372.     addresource(`CloseCatalog(g_locale))
  373.     g_catalog:=OpenCatalogA(NIL, 'ohac.catalog', NIL)
  374.     addresource(`CloseCatalog(g_catalog))
  375.   ENDIF
  376.  
  377.   FOR i:=0 TO 12
  378.     g_stringlist[STR_TXTJAN + i]:=IF g_locale THEN GetLocaleStr(g_locale, MON_1 + i) ELSE ListItem(['January',
  379.                                                                                                     'February',
  380.                                                                                                     'March',
  381.                                                                                                     'April',
  382.                                                                                                     'May',
  383.                                                                                                     'June',
  384.                                                                                                     'July',
  385.                                                                                                     'August',
  386.                                                                                                     'September',
  387.                                                                                                     'October',
  388.                                                                                                     'November',
  389.                                                                                                     'December'], i)
  390.   ENDFOR
  391.   g_stringlist[STR_TXTTODAY]:=IF g_locale THEN GetLocaleStr(g_locale, TODAYSTR) ELSE 'Today'
  392.   g_stringlist[STR_TXTTODAY2]:=clonestr(StringF(g_tmpstr, '\s.', g_stringlist[STR_TXTTODAY]))
  393.  
  394.   locassignstrs(STR_TXTCREDIT, ['', -> '\nEnglish translation by J. Tierney\n<jtierney@cyberlink-inc.com>',
  395.                                 'day',
  396.                                 'days',
  397.                                 'ago',
  398.                                 'away'])
  399.  
  400.   locassignstrs(STR_REQERROR, ['OHAC Error:',
  401.                                'OHAC Warning:',
  402.                                'About:',
  403.                                'OHAC Font:'])
  404.  
  405.   locassignstrs(STR_ERRMEM, ['Unable to allocate memory.',
  406.                              'GUI creation failed.',
  407.                              'GUI\as minimum size is too large for this screen.',
  408.                              'Unable to open timer.device.',
  409.                              'Bad args.',
  410.                              'Unable to iconify:',
  411.                              'Unable to open a message port.',
  412.                              'AppIcon creation failed.',
  413.                              'Unable to create calendar gadget.'])
  414.  
  415.   locassignstrs(STR_GADOK, ['Okay', 'Reset'])
  416.  
  417.   locassignstrs(STR_MNUPROJ, ['Project',
  418.                               'Next PubScreen',
  419.                               'Iconify',
  420.                               'Change Font...',
  421.                               'Snapshot',
  422.                               'About...',
  423.                               'Quit',
  424.                               'Dates',
  425.                               'Set Today',
  426.                               'Reset Today'])
  427. ENDPROC
  428.  
  429. PROC locassignstrs(from, strlist:PTR TO LONG)
  430.   DEF defstr, i, li=0
  431.  
  432.   FOR i:=from TO from + ListLen(strlist) - 1
  433.     defstr:=strlist[li++]
  434.     g_stringlist[i]:=IF g_catalog THEN GetCatalogStr(g_catalog, i, defstr) ELSE defstr
  435.   ENDFOR
  436. ENDPROC
  437.  
  438. PROC opentimer()
  439.   NEW g_timerio
  440.   IF OpenDevice('timer.device', UNIT_MICROHZ, g_timerio, NIL) THEN Raise(ER_TIMER)
  441.   timerbase:=g_timerio.io.device
  442.   addresource(`CloseDevice(g_timerio))
  443. ENDPROC
  444.  
  445. PROC initfontreq()
  446.   IF (aslbase <> NIL) AND (diskfontbase <> NIL)
  447.     g_fontreq:=AllocAslRequest(ASL_FONTREQUEST, [ASLFO_SLEEPWINDOW, TRUE,
  448.                                                  ASLFO_TITLETEXT, g_stringlist[STR_REQFONT],
  449.                                                  ASLFO_MAXHEIGHT, 96,
  450.                                                  TAG_DONE])
  451.     addresource(`FreeAslRequest(g_fontreq))
  452.   ENDIF
  453. ENDPROC
  454.  
  455. PROC fixfontname(name)
  456.   DEF fontname, l
  457.  
  458.   l:=StrLen(name) + 5
  459.   fontname:=String(l)
  460.  
  461.   StrCopy(fontname, name)
  462.   IF InStr(fontname, '.font') = -1 THEN StrAdd(fontname, '.font')
  463. ENDPROC fontname
  464.  
  465. PROC loadfont(fname, fsize)
  466.   DEF scrn:PTR TO screen
  467.  
  468.   IF (fname <> NIL) AND (fsize <> NIL) AND (diskfontbase <> NIL)
  469.     g_txtattr.name:=clonestr(fname)
  470.     g_txtattr.ysize:=fsize
  471.     g_font:=OpenDiskFont(g_txtattr)
  472.   ENDIF
  473.   IF g_font = NIL
  474.     -> * Fall back to screen's font.
  475.     scrn:=g_args[RA_PUBSCR]
  476.     g_txtattr.name:=clonestr(scrn.font.name)
  477.     g_txtattr.ysize:=scrn.font.ysize
  478.     g_font:=OpenFont(g_txtattr)
  479.   ENDIF
  480. ENDPROC
  481.  
  482. PROC makemenus(strlist, strcount)
  483.   DEF menus:PTR TO newmenu, mi, size, nms
  484.  
  485.   mi:=14
  486.   nms:=SIZEOF newmenu
  487.  
  488.   size:=mi + 2 + strcount
  489.   NEW menus[size]
  490.   CopyMem([NM_TITLE,  0, g_stringlist[STR_MNUPROJ],     0, 0, 0, 0,
  491.             NM_ITEM, 0, g_stringlist[STR_MNUJUMP],    'J', 0, 0, {jumpscr},
  492.             NM_ITEM, 0, g_stringlist[STR_MNUICONIFY], 'I', 0, 0, {iconify},
  493.             NM_ITEM, 0, g_stringlist[STR_MNUFONT],      0, 0, 0, {chngfont},
  494.             NM_ITEM, 0, g_stringlist[STR_MNUSNAP],      0, 0, 0, {snapshot},
  495.             NM_ITEM, 0, NM_BARLABEL,   0, 0, 0, 0,
  496.             NM_ITEM, 0, g_stringlist[STR_MNUABOUT],   '?', 0, 0, {about},
  497.             NM_ITEM, 0, NM_BARLABEL,   0, 0, 0, 0,
  498.             NM_ITEM, 0, g_stringlist[STR_MNUQUIT],    'Q', 0, 0, {quit},
  499.            NM_TITLE,  0, g_stringlist[STR_MNUDATES],    0, 0, 0, 0,
  500.             NM_ITEM, 0, g_stringlist[STR_MNUDATESET],   0, 0, 0, {settoday},
  501.             NM_ITEM, 0, g_stringlist[STR_MNUDATERESET], 0, 0, 0, {resettoday},
  502.             NM_ITEM, 0, NM_BARLABEL,   0, 0, 0, 0,
  503.             NM_ITEM, 0, g_stringlist[STR_TXTTODAY],     0, 0, 0, {resetcal}]:newmenu, menus[0], mi * nms)
  504.  
  505.   IF g_args[RA_DATE]
  506.     CopyMem([NM_ITEM, 0, g_args[RA_DATE], 0, 0, 0, {datemenu}]:newmenu, menus[mi++], nms)
  507.   ENDIF
  508.  
  509.   WHILE strlist
  510.     CopyMem([NM_ITEM, 0, strlist, 0, 0, 0, {datemenu}]:newmenu, menus[mi++], nms)
  511.     strlist:=Next(strlist)
  512.   ENDWHILE
  513.  
  514.   CopyMem([NM_END, 0, 0, 0, 0, 0, 0]:newmenu, menus[mi], nms)
  515. ENDPROC menus
  516.  
  517. PROC makegui()
  518.   g_gui:=guiinitA('OHAC v1.3',
  519.     [ROWS,
  520.       [COLS,
  521.         gad_month:=[CYCLE, {setmonth}, NIL, [g_stringlist[STR_TXTJAN],
  522.                                              g_stringlist[STR_TXTFEB],
  523.                                              g_stringlist[STR_TXTMAR],
  524.                                              g_stringlist[STR_TXTAPR],
  525.                                              g_stringlist[STR_TXTMAY],
  526.                                              g_stringlist[STR_TXTJUN],
  527.                                              g_stringlist[STR_TXTJUL],
  528.                                              g_stringlist[STR_TXTAUG],
  529.                                              g_stringlist[STR_TXTSEP],
  530.                                              g_stringlist[STR_TXTOCT],
  531.                                              g_stringlist[STR_TXTNOV],
  532.                                              g_stringlist[STR_TXTDEC], 0], g_caldate.month - 1],
  533.         gad_year:=[INTEGER, {setyear}, NIL, g_caldate.year, 6],
  534.         [BUTTON, {incyear}, '<', 0],
  535.         [BUTTON, {incyear}, '>', 1]
  536.       ],
  537.       [SPACE],
  538.       [SPACE],
  539.       [PLUGIN, {dayreport}, g_cal],
  540.       [COLS,
  541.         gad_text:=[TEXT, g_tmpstr, NIL, TRUE, 2],
  542.         [BUTTON, {resetcal}, g_stringlist[STR_TXTTODAY]]
  543.       ]
  544.     ], [EG_MENU, g_menudata,
  545.         EG_LEFT, g_args[RA_X],
  546.         EG_TOP, g_args[RA_Y],
  547.         EG_WIDTH, g_args[RA_W],
  548.         EG_HEIGHT, g_args[RA_H],
  549.         EG_FONT, g_txtattr,
  550.         EG_SCRN, g_args[RA_PUBSCR],
  551.         TAG_DONE])
  552. ENDPROC
  553.  
  554. PROC ezreq(win, title, bodytext, buttons=NIL, arglist=NIL)
  555.   DEF choice
  556.  
  557.   choice:=EasyRequestArgs(win, [SIZEOF easystruct,
  558.                                 NIL,
  559.                                 title,
  560.                                 bodytext,
  561.                                 IF buttons THEN buttons ELSE g_stringlist[STR_GADOK]]:easystruct, NIL, arglist)
  562. ENDPROC choice
  563.  
  564. PROC long2ints(num)  -> ***  Splits a LONG into 2 INTs (high and low).
  565.   DEF intptr:PTR TO INT, hi, lo
  566.  
  567.   intptr:={num}
  568.   hi:=intptr[] AND $FFFF
  569.   lo:=intptr[1] AND $FFFF
  570. ENDPROC hi, lo
  571.  
  572. PROC usgn_less(a, b)
  573.   DEF ahi, alo, bhi, blo, result
  574.  
  575.   ahi, alo:=long2ints(a)
  576.   bhi, blo:=long2ints(b)
  577.  
  578.   result:=IF ahi = bhi THEN alo < blo ELSE ahi < bhi
  579. ENDPROC result
  580.  
  581. PROC syncdate(date:PTR TO clockdata)
  582.   GetSysTime(g_time)
  583. /*
  584.   Amiga2Date($8FFFFFFF, date)
  585.   WriteF('\d\n', date.year)
  586. */
  587.   Amiga2Date(g_time.secs, date)
  588.   date.sec:=0
  589.   date.min:=0
  590.   date.hour:=0
  591. ENDPROC
  592.  
  593. PROC parsedate(datestr, date:PTR TO clockdata)
  594.   DEF dstr[11]:ARRAY OF CHAR, n, ok
  595.  
  596.   IF datestr
  597.     AstrCopy(dstr, datestr, 11)
  598.     dstr[2]:=0
  599.     dstr[5]:=0
  600.  
  601.     n, ok:=Val(dstr)
  602.     IF ok THEN date.mday:=Bounds(n, 1, 31)
  603.     n, ok:=Val(dstr + 3)
  604.     IF ok THEN date.month:=Bounds(n, 1, 12)
  605.     n, ok:=Val(dstr + 6)
  606.     IF ok THEN date.year:=Bounds(n, 1978, 2113)
  607.   ENDIF
  608. ENDPROC
  609.  
  610.  
  611. /* --- Gadget procs --- */
  612.  
  613. PROC setmonth(gui, month)
  614.   g_cal.date.month:=month + 1
  615.   g_cal.setdate()
  616.   dayreport(gui)
  617. ENDPROC
  618.  
  619. PROC setyear(gui, year)
  620.   year:=Bounds(year, 1978, 2113)
  621.   setinteger(gui, gad_year, year)
  622.   g_cal.date.year:=year
  623.   g_cal.setdate()
  624.   dayreport(gui)
  625. ENDPROC
  626.  
  627. PROC incyear(inc, gui)
  628.   DEF year
  629.  
  630.   year:=g_cal.date.year + IF inc THEN 1 ELSE -1
  631.   IF (year > 1977) AND (year < 2114)
  632.     g_cal.date.year:=year
  633.     setinteger(gui, gad_year, year)
  634.     g_cal.setdate()
  635.     dayreport(gui)
  636.   ENDIF
  637. ENDPROC
  638.  
  639. PROC dayreport(gui, day=0)
  640.   DEF cal, real, diff, past
  641.  
  642.   real:=Date2Amiga(g_date)
  643.   cal:=Date2Amiga(g_caldate)
  644.  
  645.   IF cal = real
  646.     StrCopy(g_tmpstr, g_stringlist[STR_TXTTODAY2])
  647.   ELSE
  648.     past:=usgn_less(cal, real)
  649.     diff:=UdivMod32(IF past THEN real - cal ELSE cal - real, SECSINDAY)
  650.     StringF(g_tmpstr, '\d \s \s.', diff, IF diff > 1 THEN g_stringlist[STR_TXTDAYS] ELSE g_stringlist[STR_TXTDAY], IF past THEN g_stringlist[STR_TXTAGO] ELSE g_stringlist[STR_TXTAWAY])
  651.   ENDIF
  652.  
  653.   IF gui THEN settext(gui, gad_text, g_tmpstr)
  654. ENDPROC
  655.  
  656. PROC resetcal(qual, d, gui)
  657.   IF qual AND SHIFT    -> *** g_date = Displayed date.
  658.     g_date.mday:=g_caldate.mday
  659.     g_date.month:=g_caldate.month
  660.     g_date.year:=g_caldate.year
  661.   ELSEIF qual AND ALT  -> *** g_date = Actual date.
  662.     resettoday(gui)
  663.     RETURN
  664.   ELSE                 -> *** Jump to g_date.
  665.     g_caldate.mday:=g_date.mday
  666.     g_caldate.month:=g_date.month
  667.     g_caldate.year:=g_date.year
  668.  
  669.     setcycle(gui, gad_month, g_date.month - 1)
  670.     setinteger(gui, gad_year, g_date.year)
  671.     g_cal.setdate()
  672.   ENDIF
  673.  
  674.   settext(gui, gad_text, g_stringlist[STR_TXTTODAY2])
  675. ENDPROC
  676.  
  677.  
  678. /*  --- Menu procs --- */
  679.  
  680. PROC jumpscr(gui)
  681.   DEF psname[MAXPUBSCRNAME]:ARRAY OF CHAR, pslock
  682.  
  683.   IF NextPubScreen(g_args[RA_PUBSCR], psname)
  684.     IF (pslock:=LockPubScreen(psname))
  685.       UnlockPubScreen(NIL, g_args[RA_PUBSCR])
  686.       closewin(gui)
  687.       changescreen(gui, pslock)
  688.       g_args[RA_PUBSCR]:=pslock
  689.       openwin(gui)
  690.       ScreenToFront(pslock)
  691.     ENDIF
  692.   ENDIF
  693. ENDPROC
  694.  
  695. PROC iconify(gui)
  696.   DEF mport, amsg:PTR TO appmessage, aicon,
  697.       iname, done
  698.  
  699.   IF (mport:=CreateMsgPort())
  700.     IF gui THEN closewin(gui)
  701.  
  702.     IF g_iconifyicon = NIL
  703.       IF g_args[RA_ICONIMG]
  704.         done:=InStr(iname, '.info')
  705.         iname:=StrCopy(g_tmpstr, g_args[RA_ICONIMG], done)
  706.       ELSE
  707.         iname:=g_ohacname
  708.       ENDIF
  709.  
  710.       g_iconifyicon:=GetDiskObjectNew(iname)
  711.       addresource(`FreeDiskObject(g_iconifyicon))
  712.     ENDIF
  713.  
  714.     IF (aicon:=AddAppIconA(NIL, NIL, 'OHAC', mport, NIL, g_iconifyicon, NIL))
  715.       REPEAT
  716.         WaitPort(mport)
  717.         WHILE (amsg:=GetMsg(mport))
  718.           done:=amsg.numargs = 0
  719.           ReplyMsg(amsg)
  720.         ENDWHILE
  721.       UNTIL done
  722.  
  723.       RemoveAppIcon(aicon)
  724.     ELSE
  725.       ezreq(NIL, g_stringlist[STR_REQERROR], '\s\n\s', NIL, [g_stringlist[STR_ERRICONIFY], g_stringlist[STR_ERRAPICON]])
  726.     ENDIF
  727.  
  728.     IF gui THEN openwin(gui)
  729.  
  730.     WHILE (amsg:=GetMsg(mport)) DO ReplyMsg(amsg)
  731.     DeleteMsgPort(mport)
  732.   ELSE
  733.     ezreq(NIL, g_stringlist[STR_REQERROR], '\s\n\s', NIL, [g_stringlist[STR_ERRICONIFY], g_stringlist[STR_ERRMPORT]])
  734.   ENDIF
  735. ENDPROC
  736.  
  737. PROC chngfont(gui:PTR TO guihandle) HANDLE
  738.   DEF newfont=NIL
  739.  
  740.   IF g_fontreq
  741.     IF AslRequest(g_fontreq, [ASLFO_WINDOW, gui.wnd,
  742.                               TAG_DONE])
  743.  
  744.       IF newfont:=OpenDiskFont(g_fontreq.attr)
  745.         closewin(gui)
  746.         changefont(gui, g_fontreq.attr)
  747.         openwin(gui)
  748.       ENDIF
  749.     ENDIF
  750.   ENDIF
  751.  
  752.   EXCEPT DO
  753.     IF exception
  754.       IF exception = "bigg"
  755.         ezreq(0, g_stringlist[STR_REQERROR], g_stringlist[STR_ERRBIG])
  756.         CloseFont(newfont)
  757.         makegui()
  758.       ELSE
  759.         ReThrow()
  760.       ENDIF
  761.     ELSEIF newfont
  762.       replacestr(g_txtattr.name, g_fontreq.attr.name)
  763.       g_txtattr.ysize:=g_fontreq.attr.ysize
  764.       CloseFont(g_font)
  765.       g_font:=newfont
  766.     ENDIF
  767. ENDPROC
  768.  
  769. PROC snapshot(gui:PTR TO guihandle)
  770.   DEF icon:PTR TO diskobject,
  771.       oldttlist:PTR TO LONG, newttlist[100]:ARRAY OF LONG, ttstr,
  772.       xstr[15]:STRING, ystr[15]:STRING, wstr[15]:STRING, hstr[15]:STRING,
  773.       i=0, ii=4, li
  774.  
  775.   StringF(xstr, 'LEFTEDGE=\d', gui.wnd.leftedge)
  776.   StringF(ystr, 'TOPEDGE=\d', gui.wnd.topedge)
  777.   StringF(wstr, 'WIDTH=\d', gui.wnd.width)
  778.   StringF(hstr, 'HEIGHT=\d', gui.wnd.height)
  779.   icon:=GetDiskObjectNew(g_ohacname)
  780.  
  781.   newttlist[0]:=xstr
  782.   newttlist[1]:=ystr
  783.   newttlist[2]:=wstr
  784.   newttlist[3]:=hstr
  785.   IF (oldttlist:=icon.tooltypes)
  786.     WHILE (ttstr:=oldttlist[i++])
  787.       IF ForAll({li}, ['LEFTEDGE', 'TOPEDGE', 'WIDTH', 'HEIGHT'], `InStr(ttstr, li)) THEN newttlist[ii++]:=ttstr
  788.     ENDWHILE
  789.   ENDIF
  790.   newttlist[ii]:=0
  791.  
  792.   icon.tooltypes:=newttlist
  793.   PutDiskObject(g_ohacname, icon)
  794.  
  795.   icon.tooltypes:=oldttlist
  796.   FreeDiskObject(icon)
  797. ENDPROC
  798.  
  799. PROC about(gui:PTR TO guihandle)
  800.   /* Text is space-padded to avoid problems w/ MCP's auto-centering. */
  801.   ezreq(gui.wnd, g_stringlist[STR_REQABOUT], '         OHAC  v1.3         \n'+
  802.                                              '(Oh Heck, Another Calendar!)\n\n'+
  803.                                              '       by J. Tierney        \n'+
  804.                                              ' jtierney@cyberlink-inc.com \n\n'+
  805.                                              '       Public Domain        '+
  806.                                              '\n\s', NIL, [g_stringlist[STR_TXTCREDIT]])
  807. ENDPROC
  808.  
  809. PROC quit() IS Raise(QUIT)
  810.  
  811. PROC datemenu(gui:PTR TO guihandle)
  812.   parsedate(gui.menutrigger.itemfill::intuitext.itext, g_caldate)
  813.  
  814.   setcycle(gui, gad_month, g_caldate.month - 1)
  815.   setinteger(gui, gad_year, g_caldate.year)
  816.   g_cal.setdate()
  817.   dayreport(gui)
  818. ENDPROC
  819.  
  820. PROC settoday(gui)
  821.   resetcal(SHIFT, 0, gui)
  822. ENDPROC
  823.  
  824. PROC resettoday(gui)
  825.   syncdate(g_date)
  826.   dayreport(gui)
  827. ENDPROC
  828.  
  829.  
  830. CHAR '$VER: OHAC 1.3 (20.9.99) by J. Tierney', 0
  831.  
  832.