home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / palmos / progect-src-0.20.tar.gz / progect-src-0.20.tar / progect-0.20 / progect.c < prev    next >
C/C++ Source or Header  |  2000-10-26  |  117KB  |  4,833 lines

  1. /* -*-Mode:C; tab-width:4; indent-tabs-mode:t; c-file-style:"stroustrup";-*- */
  2. /* Main code for Project */
  3. //#define ERROR_CHECK_LEVEL 2
  4. #include <PalmOS.h>
  5. #include <DateGlue.h>
  6. #include <TxtGlue.h>
  7. #include <FntGlue.h>
  8. #include <TsmGlue.h>
  9. #include <WinGlue.h>
  10.  
  11. #include "link.h"
  12. #include "task.h"
  13. #include "progectdb.h"
  14. #include "progectRsc.h"
  15. #include "progect.h"
  16. #include "flat.h"
  17. #include "btm.h"
  18.  
  19.  
  20. // icon support
  21. #include "icon.h"
  22. // ToDo export support
  23. #include "ToDoDB.h"
  24. // Memo linking support
  25. #include "MemoDB.h"
  26. // address linking support
  27. #include "AddressDB.h"
  28.  
  29. // Doc export support
  30. #include "doc.h"
  31.  
  32. // not used yet
  33. typedef enum {tblRedrawAll, tblRedrawTable, tblUpdateRedrawAll, 
  34.     tblUpdateRedrawTable} redrawTableType;
  35.  
  36. // prototypes
  37.  
  38. // events
  39. void           ProgressHandleEvent(void) UISECT;
  40. void           PriorityHandleEvent(EventPtr e) UISECT;
  41. UInt16         SelectRange(void) UISECT;
  42. Boolean        FrmMainMenuHandleEvent(EventPtr e) UISECT;
  43. Boolean        FrmMainCtlSelectHandleEvent(EventPtr e) UISECT;
  44. Boolean        FrmMainKeyDownHandleEvent(EventPtr e) UISECT;
  45. static Boolean FrmMainHandleEvent (EventPtr e) UISECT;
  46. static void    UpdateIconButton(void) UISECT;
  47. static Boolean FrmTaskEditHandleEvent (EventPtr e) UISECT;
  48. static Boolean FrmProjectListHandleEvent (EventPtr e) UISECT;
  49. Boolean        HandleChooseNameButtonOK(void) UISECT;
  50. static Boolean FrmChooseNameHandleEvent (EventPtr e) UISECT;
  51. static Boolean FrmProjectPropertiesHandleEvent (EventPtr e) UISECT;
  52. static Boolean FrmMemoExportPropertiesHandleEvent (EventPtr e) UISECT;
  53. Boolean        EditMenuHandleEvent(UInt16 menuid, FieldPtr fld) UISECT;
  54. void           FrmNoteEditUpdateScroll(void) UISECT;
  55. void           FrmNoteEditScrollPage(WinDirectionType direction) UISECT;
  56. static Boolean FrmNoteEditHandleEvent (EventPtr e) UISECT;
  57. Boolean        FrmFlatCtlSelectHandleEvent(EventPtr e) UISECT;
  58. void           ProjectFlatTableUpdate(void) UISECT;
  59. static Boolean FrmFlatHandleEvent (EventPtr e) UISECT;
  60. static Boolean FrmFlatFilterHandleEvent (EventPtr e) UISECT;
  61. static Boolean FrmDirectLinkHandleEvent (EventPtr e) UISECT;
  62. static Boolean FrmDisplayPropertiesHandleEvent (EventPtr e) UISECT;
  63. static Boolean FrmTaskDefaultsHandleEvent (EventPtr e) UISECT;
  64.  
  65. static Boolean ApplicationHandleEvent(EventPtr e);
  66. static UInt16 StartApplication(void);
  67. static void StopApplication(void);
  68. static void EventLoop(void);
  69. UInt32 PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags);
  70. static void Search(FindParamsPtr findParams);
  71.  
  72. // icons
  73. #define IconNum 13
  74. MemHandle gIconHandle[IconNum]; // to hold handles to the bitmaps
  75.  
  76.  
  77. // Globals
  78.  
  79. OSCaps_t OSCaps = {
  80.     false, false, false, false, false, false,
  81.     0, 0, 0, false
  82. };
  83.  
  84.  
  85. DmOpenRef gdbP = NULL; // actual database
  86. DmOpenRef gClip = NULL; // clipboard database
  87. UInt16 gActualTask = 0; // selected task
  88. UInt16 gLastSelected = 0; // last selected task
  89. UInt32 gFlatOffset = 0; // flat view offset of first item
  90. TaskType gEmptyTask = {{{0, 0, 0, 0, 0, 0}}, 
  91.     {{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}},
  92.     6, 0, {0, 0, 0}, "", ""};
  93. DateType gNoDate = {0, 0, 0};
  94. Char gDateStr[10]; // to store a date string
  95. UInt8 gLevelOffset = 0; // for horizontal scroll and subtree viewing
  96. UInt16 gParentTask = 0; // the parent of all tasks for viewing purposes only
  97. UInt8 gRefLevel = 0; // level of gParentTask;
  98. Int16 gLastDownX, gLastDownY;
  99. TablePtr gTable; // main form table
  100. LocalID gdbID = 0; // id of opened database (set by OpenDB and CloseDB)
  101. Char* namesData = NULL; // used by list selector
  102. Char** names = NULL; // used by list selector
  103. // used for date differences calculations
  104. UInt8 gLimits[] = { 0, 1, 2, 3, 4, 5, 6, 7, 14, 21, 28 }; // UInt8 is to saving memory.
  105. DateType gToday;
  106. UInt32 gTodayDays; // to speed up day comparaisons calculations
  107. UInt16 gCurrentSelection = 0; // current selection in project list
  108. Char* docName; // use by FrmChooseName
  109. UInt8 ChooseNameFunction = ChooseNameCreate;
  110.  
  111. // Preferences
  112. DateFormatType gDateFormat; // actual date format (from palm, StartApplication)
  113. ProjectPrefsType gProjectPrefs = 
  114. {
  115.     18,    // format
  116.     0,         // reserved
  117.     false,    // hideDoneTasks
  118.     true,     // displayDueDates
  119.     true,     // displayPriorities
  120.     false,  // displayYear
  121.     false,  // useFatherStatus
  122.     true,    // autoSyncToDo
  123.     true,     // flatHideDone
  124.     2,         // flatDated (0 = no, 1 = yes, 2 = not used)
  125.     3,         // flatMinPriority
  126.     true,     // flatOr
  127.     true,      // flatMin
  128.     0,         // boldMinPriority
  129.     0,      // boldMinDays
  130.     false,  // strikeDoneTasks
  131.     false,  // hideDoneProgress
  132.     false,  // hideProgress
  133.     // taskDefaults
  134.     {{{0, 0, 0, 0, 0, 0}}, {{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}},
  135.     6, 0, {0, 0, 0}, "", ""},
  136.     noSort, // flatSorted
  137.     0,      // flatDateLimit
  138.     true    // completionDate
  139. };
  140. CurrentPrefsType gCurrentPrefs; // current prefs, used to restore applic state
  141. SavedPrefsType gSavedPrefs = {true}; // saved prefs, used to restore global 
  142.                                      // application prefs
  143. MemoExportOptionsType gMemoExportPrefs =
  144.     {
  145.         true,  // exportDone;
  146.         true,  // exportProgress;
  147.         true,  // exportDueDate;
  148.         true,  // exportPriority;
  149.         false, // exportNote;
  150.         false  // exportOnlyTerminals;
  151.     };
  152.  
  153.  
  154. static UInt16 wVerticalLines[11];
  155.  
  156.  
  157. /****************************************************************************
  158.  * Name : GetObjectPtr
  159.  * Desc : get a pointer to an object of the current form
  160.  * Parm : 
  161.  *             -> ID of object to get a pointer to
  162.  * Out  : ptr
  163.  * Auth : lb, 06.08.2000
  164.  ***************************************************************************/
  165. MemPtr GetObjectPtr(UInt16 ObjID)
  166. {
  167.     FormPtr frm = FrmGetActiveForm();
  168.     return FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, ObjID));
  169. } // MemPtr GetObjectPtr(UInt16 ObjID)
  170.  
  171.  
  172.  
  173. /****************************************************************************
  174.  * Name : Today
  175.  * Desc : return today's date
  176.  * Parm : 
  177.  * Out  : today's date
  178.  * Auth : lb, 06.08.2000
  179.  ***************************************************************************/
  180. DateType Today(void)
  181. {
  182.     DateType date;
  183.  
  184.     DateSecondsToDate(TimGetSeconds(), &date);
  185.     return date;
  186. } // DateType Today(void)
  187.  
  188.  
  189.  
  190. /****************************************************************************
  191.  * Name : DateInLimit
  192.  * Desc : return true if passed date is within limit
  193.  * Parm : 
  194.  *             -> date to test
  195.  *             -> offset in limits tab
  196.  * Out  : date is in limit
  197.  * Auth : lb, 04.10.2000, from a modified version of seagull's original code
  198.  ***************************************************************************/
  199. Boolean DateInLimit(DateType date, UInt8 offset)
  200. {
  201.     static UInt8 limits[] = { 0, 0, 1, 2, 3, 4, 5, 6, 7, 14, 21, 28 }; // UInt8 is to saving memory.
  202.     UInt32 days = DateToDays(date);
  203.     Boolean overdue = (days < gTodayDays);
  204.     UInt32 diff = days > gTodayDays ? 
  205.         days - gTodayDays : gTodayDays - days;
  206.  
  207.     if (!offset)
  208.         return false;
  209.  
  210.     return ((diff < (UInt32)limits[offset]) || overdue);
  211. } // Boolean DateInLimit(DateType date, UInt8 offset)
  212.  
  213.  
  214.  
  215. /****************************************************************************
  216.  * Name : PrintDueDate
  217.  * Desc : print the date at given y pos
  218.  * Parm : 
  219.  *             -> the record
  220.  *             -> the y position
  221.  *             <-> the x position (in = right pos, out = left pos)
  222.  * Out  : 
  223.  * Auth : lb, 29.08.2000
  224.  ***************************************************************************/
  225. void PrintDueDate(TaskRecordType *p, UInt16 *datePos, UInt16 y)
  226. {
  227.     Char dateStrMem[10]; // complete date + '!' + '\0'
  228.     Char* dateStr = dateStrMem;
  229.     UInt16 dateLen;
  230.  
  231.     DateToAscii(p->dueDate.month, p->dueDate.day, 
  232.         p->dueDate.year + YEAR_OFFSET, gDateFormat, dateStrMem); // start 1904
  233.  
  234.     // calc the date length
  235.     if (!gProjectPrefs.displayYear)
  236.     {
  237.         switch(gDateFormat)
  238.         {
  239.             case dfYMDWithSlashes:
  240.             case dfYMDWithDots:
  241.             case dfYMDWithDashes:
  242.                 dateStr += 3;
  243.                 break;
  244.             default:
  245.                 dateStr[StrLen(dateStr) - 3] = '\0';
  246.                 break;
  247.         }
  248.     }
  249.  
  250.     dateLen = StrLen(dateStr);
  251.  
  252.     if (gTodayDays > DateToDays(p->dueDate))
  253.     {
  254.         // if the task is completed, don't write the !
  255.         if (p->completed != 10 && p->completed != ACTION_OK)
  256.         {
  257.             dateStr[dateLen++] = '!';
  258.             dateStr[dateLen] = '\0';
  259.         }
  260.     }
  261.  
  262.     *datePos -= FntCharsWidth(dateStr, dateLen);
  263.  
  264.     WinDrawChars(dateStr, dateLen, *datePos, y); // just draw days and month
  265. } // void PrintDueDate(TaskRecordType *p, UInt16 &datePos, UInt16 y)
  266.  
  267.  
  268.  
  269. /****************************************************************************
  270.  * Name : SetFormTitle
  271.  * Desc : set the title of the given form
  272.  * Parm : 
  273.  * Out  : 
  274.  * Auth : lb, 31.08.2000
  275.  ***************************************************************************/
  276. void SetFormTitle (FormPtr frm, Char *title)
  277. {
  278.     Char titleArray[33];
  279.     UInt8 i;
  280.     // if prepended, skip prepend
  281.     if (StrStr(title, gPrepend) == title)
  282.     {
  283.         title += 5;
  284.     }
  285.     for (i = 0; i < 32 && *title; i++)
  286.     {
  287.         titleArray[i] = *title++;
  288.     }
  289.     titleArray[i] = '\0';
  290.     FrmCopyTitle(frm, titleArray);
  291. } // void SetFormTitle (FormPtr frm, Char *title)
  292.  
  293.  
  294.  
  295. /****************************************************************************
  296.  * Name : DrawTruncText
  297.  * Desc : draw a text, trunc if too long
  298.  * Parm :
  299.  *             -> string to draw
  300.  *             -> x and y pos to draw
  301.  *             -> x limit
  302.  * Out  : -
  303.  * Auth : lb, 12.09.2000
  304.  ***************************************************************************/
  305. void DrawTruncText(Char *c, UInt16 x, UInt16 y, UInt16 limit)
  306. {
  307.     Char * ptr = StrChr (c, linefeedChr);
  308.     UInt16 titleLen = (ptr == NULL ? StrLen (c) : (UInt16) (ptr - c));
  309.  
  310.     if (OSCaps.ver32)
  311.         // best choise. complete nationalized. and got wide screen.
  312.         WinDrawTruncChars(c, titleLen, x, y, limit);
  313.     else if (OSCaps.ver30)
  314.     {   // 99% nationalized. and lost screen width.
  315.         Int16 length = titleLen;
  316.         Int16 len = length;
  317.         Int16 width = limit;
  318.         Boolean fitInWidth = false;
  319.         FntCharsInWidth(c, &width, &len, &fitInWidth);
  320.         if (fitInWidth)
  321.             WinDrawChars(c, length, x, y);
  322.         else
  323.         {
  324.             width = limit - TxtGlueCharWidth('.');
  325.             len = length;
  326.             fitInWidth = false;
  327.             FntCharsInWidth(c, &width, &len, &fitInWidth);
  328.             
  329.             WinDrawChars(c, len, x, y);
  330.             WinDrawChars("...", 3, x + width, y);
  331.         }
  332.     }
  333.     else
  334.     {   // 0% nationalized. but best fit with many PalmOS versions.
  335.         Char *string = c;
  336.         UInt16 textWidth = 0;
  337.         Boolean trunc = false;
  338.         
  339.         while (*c && *c != linefeedChr)
  340.         {
  341.             textWidth += FntCharWidth(*c);
  342.             if (textWidth > limit)
  343.             {
  344.                 trunc = true;
  345.                 break;
  346.             }
  347.             c++;
  348.         }
  349.         // now textwidth is in chars !!!
  350.         textWidth = (UInt16)(c - string);
  351.         WinDrawChars(string, textWidth, x, y);
  352.         if (trunc)
  353.             WinDrawChars("...", 3, 
  354.                          x + FntCharsWidth(string, textWidth), y);
  355.     }
  356. } // void DrawTruncText(Char *c, UInt16 x, UInt16 y, UInt16 limit)
  357.  
  358.  
  359.  
  360. /****************************************************************************
  361.  * Name : ProjectDrawExtendedItemDesc
  362.  * Desc : draw an item desription
  363.  * Parm :
  364.  *             -> pointer to the item
  365.  *             -> x and y pos to draw
  366.  * Out  : -
  367.  * Auth : lb, 12.09.2000
  368.  ***************************************************************************/
  369. void ProjectDrawExtendedItemDesc(TaskExtendedRecordType *p, UInt16 x, UInt16 y)
  370. {
  371.     UInt16 datePos = 160;
  372.     UInt8 textPos = 0;
  373.     UInt16 limit;
  374.     Char* pDesc = NULL;
  375.  
  376.     // draw note icon (if a note exist)
  377.     if (p->format.bits.hasNote)
  378.     {
  379.         datePos -= 6;
  380.         FntSetFont(symbolFont);
  381.         WinGlueDrawChar(symbolNote, datePos, y);
  382.         FntSetFont(stdFont);
  383.         datePos--;
  384.     }
  385.  
  386.     // draw link-via icon
  387.     if (p->format.bits.hasLink)
  388.     {
  389.         MemHandle h = gIconHandle[BtmLinkMaster - BtmOffset];
  390.         BitmapPtr bitmap = (BitmapPtr)MemHandleLock(h);
  391.         datePos -= 8;
  392.         WinDrawBitmap(bitmap, datePos, y + 2);
  393.         MemHandleUnlock(h);
  394.         datePos--;
  395.     }
  396.  
  397.     x += textPos;
  398.     limit = datePos - x - 7;
  399.  
  400.     //
  401.     // draw attached icon
  402.     //
  403.     {
  404.         UInt16 iconid;
  405.         UInt16 size = sizeof(iconid);
  406.         if (pgOK == TaskGetExtraChunkByTaskPtr(p, Extra_Icon, 0,
  407.                                                &iconid, &size) &&
  408.             size == sizeof(iconid) &&
  409.             iconid < getNumIconsLoaded() )
  410.         {
  411.             drawIcon(iconid, x, y);
  412.             x += getIconWidth(iconid) + 2;
  413.         }
  414.     }
  415.  
  416.     // draw the description (truncated)
  417.     pDesc = TaskGetDescriptionByTaskPtr(p);
  418.     FntSetFont(stdFont);
  419.  
  420.     // if it's a direct link, and the destination is not existing anymore,
  421.     // nothing to print.
  422.     if (pDesc)
  423.     {
  424.         DrawTruncText(pDesc, x, y, limit);
  425.         MemPtrFree(pDesc);
  426.     }
  427. } // void ProjectDrawExtendedItemDesc(TaskRecordType *p, UInt16 x, UInt16 y)
  428.  
  429.  
  430.  
  431. /****************************************************************************
  432.  * Name : ProjectDrawItemDesc
  433.  * Desc : draw an item desription
  434.  * Parm :
  435.  *             -> pointer to the item
  436.  *             -> x and y pos to draw
  437.  * Out  : -
  438.  * Auth : lb, 12.09.2000
  439.  ***************************************************************************/
  440. void ProjectDrawItemDesc(TaskRecordType *p, UInt16 x, UInt16 y)
  441. {
  442.     UInt16 datePos = 160;
  443.     UInt8 textPos = 0;
  444.     UInt16 limit;
  445.     RectangleType rectBounds;
  446.  
  447.     // draw note icon (if a note exist)
  448.     if (p->format.bits.hasNote)
  449.     {
  450.         datePos -= 6;
  451.         FntSetFont(symbolFont);
  452.         WinGlueDrawChar(symbolNote, datePos, y);
  453.         datePos--;
  454.     }
  455.  
  456.     // draw link-via icon
  457.     if (p->format.bits.hasLink)
  458.     {
  459.         MemHandle h = gIconHandle[BtmLinkMaster - BtmOffset];
  460.         BitmapPtr bitmap = (BitmapPtr)MemHandleLock(h);
  461.         datePos -= 8;
  462.         WinDrawBitmap(bitmap, datePos, y + 2);
  463.         MemHandleUnlock(h);
  464.         datePos--;
  465.     }
  466.  
  467.     // draw the due date
  468.     // if no date, don't try to print a date
  469.     // if DisplayDueDates if false, don't print the date (preference)
  470.     if (p->dueDate.month != 0 && gProjectPrefs.displayDueDates)
  471.     {
  472.         FntSetFont(stdFont);
  473.         PrintDueDate(p, &datePos, y);
  474.     }
  475.  
  476.     //
  477.     // draw progresses
  478.     //
  479.     if (!((gProjectPrefs.hideDoneProgress == true && 
  480.          (p->completed == ACTION_OK || p->completed == 10)) ||
  481.          gProjectPrefs.hideProgress))
  482.     {
  483.         // draw progress item
  484.         if (p->completed > ACTION)
  485.         {
  486.             if (OSCaps.ver32 || p->completed == ACTION_NO)
  487.             {
  488.                 FntSetFont(symbol11Font);
  489.                 WinGlueDrawChar( (p->completed == ACTION_OK) ? 
  490.                     symbolCheckboxOn : symbolCheckboxOff, x - 3, y);
  491.                 FntSetFont(stdFont);
  492.             }
  493.             else
  494.             {
  495.                 // get ToDo link icon
  496.                 MemHandle h = gIconHandle[BtmCheckedBox - BtmOffset];
  497.                 BitmapPtr bitmap = (BitmapPtr)MemHandleLock(h);
  498.                 
  499.                 // draw it
  500.                 WinDrawBitmap(bitmap, x - 2, y);
  501.                 MemHandleUnlock(h);
  502.             }
  503.         }
  504.         else
  505.         {
  506.             // draw progress bar
  507.             RctSetRectangle(&rectBounds, x - 1, y + 4, 10, 3);
  508.             WinDrawRectangleFrame(simpleFrame, &rectBounds);
  509.             RctSetRectangle(&rectBounds, x - 1, y + 4, p->completed, 3);
  510.             WinDrawRectangle(&rectBounds, 0);
  511.         }
  512.         textPos += 13;
  513.  
  514.         if (gProjectPrefs.displayPriorities && p->priority > 0 && 
  515.             p->priority < 6)
  516.         {
  517.             FntSetFont(stdFont);
  518.             WinGlueDrawChar('[', x + 12, y);
  519.             FntSetFont(boldFont);
  520.             WinGlueDrawChar(p->priority + '0', x + 15, y);
  521.             FntSetFont(stdFont);
  522.             WinGlueDrawChar(']', x + 22, y);
  523.             textPos += 13;
  524.         }
  525.     }
  526.  
  527.     // High priority task draw bold font.
  528.     //  I wish color to red.
  529.     FntSetFont(stdFont); // Initialy
  530.     if (p->completed != ACTION_OK && p->completed != 10) // don't hilight done task
  531.     {
  532.         if (p->priority > 0 && p->priority <= gProjectPrefs.boldMinPriority)
  533.             FntSetFont(boldFont);
  534.         else if (p->format.bits.hasDueDate && gProjectPrefs.boldMinDays != 0 &&
  535.             p->dueDate.month != 0)
  536.         {
  537.             if (DateInLimit(p->dueDate, gProjectPrefs.boldMinDays))
  538.                 FntSetFont(boldFont);
  539.         }
  540.     }
  541.  
  542.     x += textPos;
  543.  
  544.     //
  545.     // draw attached icon
  546.     //
  547.     {
  548.         UInt16 iconid;
  549.         UInt16 size = sizeof(iconid);
  550.         if (pgOK == TaskGetExtraChunkByTaskPtr((TaskExtendedRecordType*)p,
  551.                                                Extra_Icon, 0,
  552.                                                &iconid, &size) &&
  553.             size == sizeof(iconid) &&
  554.             iconid < getNumIconsLoaded() )
  555.         {
  556.             drawIcon(iconid, x, y + 6 - getIconHeight(iconid) / 2);
  557.             x += getIconWidth(iconid) + 2;
  558.         }
  559.     }
  560.  
  561.     // draw the description (truncated)
  562.     limit = datePos - x; // - 7;
  563.  
  564.     DrawTruncText(&p->description, x, y, limit);
  565.  
  566.     // strike out done tasks
  567.     //  but, I needs gray color or gray pattern ...
  568.     if (gProjectPrefs.strikeDoneTasks &&
  569.         (p->completed == 10 || p->completed == ACTION_OK) )
  570.     {
  571.         WinDrawLine(x, y + 6, x + limit, y + 6);
  572.     }
  573.     
  574.     // resume to default. (to safety)
  575.     FntSetFont(stdFont);
  576.  
  577. } // void ProjectDrawItemDesc(TaskRecordType *p, UInt16 x, UInt16 y)
  578.  
  579.  
  580.  
  581. /****************************************************************************
  582.  * Name : ProjectItemDraw
  583.  * Desc : callback to draw the project table
  584.  * In   : not called by the user, it's a callback
  585.  * Out  : -
  586.  * Auth : lb, 31.07.2000
  587.  * Mod  : lb, 06.08.2000
  588.  *               support for date right aligning
  589.  ***************************************************************************/
  590. void ProjectItemDraw(MemPtr table, UInt16 row, UInt16 column, RectanglePtr bounds)
  591. {
  592.     BitmapPtr bitmap;
  593.     UInt16 bitmapId = 0;
  594.     MemHandle h, taskH;
  595.     UInt16 i, id, x;
  596.     UInt16 y = row*11 + 15;
  597.     TaskRecordType *p;
  598.     FormType *frm;
  599.     RectangleType rectBounds;
  600.     UInt8 level;
  601.  
  602.     id = TblGetItemInt(table, row, column);
  603.  
  604.     frm = FrmGetActiveForm();
  605.  
  606.     // erase the row
  607.     RctSetRectangle(&rectBounds, 0, y, 160, 11);
  608.     WinEraseRectangle(&rectBounds, 0);
  609.  
  610.     // don't do anything more if id is -1
  611.     if (id == -1) return;
  612.  
  613.     // get the task
  614.     taskH = DmQueryRecord(gdbP, id);
  615.     p = MemHandleLock(taskH);
  616.  
  617.     // get its level
  618.     level = gCurrentPrefs.view == flatView ? 1 : (p->attr.bits.level);
  619.  
  620.     if (gCurrentPrefs.view == flatView)
  621.     {
  622.         // extended task can't link to ToDo. because it's buggy.
  623.         if (! p->format.bits.extendedType)
  624.         {
  625.             // get ToDo link icon
  626.             h = gIconHandle[
  627.                 (p->format.bits.hasToDo? BtmLinkOn: BtmLinkOff) - BtmOffset];
  628.             bitmap = (BitmapPtr)MemHandleLock(h);
  629.             
  630.             // draw it
  631.             WinDrawBitmap(bitmap, 1, y + 2);
  632.             MemHandleUnlock(h);
  633.         }
  634.         x = 13;
  635.     }
  636. #if 0
  637.     // test implement... but this is BAD idea...
  638.     else if (gProjectPrefs.nIndentWidth <= 1)
  639.     {   // for short or very short indent
  640.         x = (level - gRefLevel - 1) * 2;
  641.  
  642.         if (p->attr.bits.hasChild || gProjectPrefs.nIndentWidth == 1)
  643.         {
  644.             h = gIconHandle[(p->attr.bits.opened? BtmMinusAlone : BtmPlusAlone) - BtmOffset];
  645.             bitmap = (BitmapPtr)MemHandleLock(h);
  646.             if (p->attr.bits.hasChild)
  647.                 WinDrawBitmap(bitmap, x, y);
  648.             x += bitmap->width + 1;
  649.             MemHandleUnlock(h);
  650.         }
  651.     }
  652. #endif
  653.     else
  654.     {
  655.         // one bitmap per level of the task
  656.         for (i = gRefLevel + 1; i <= level; i++)
  657.         {
  658.             // choose the good icon (final icon)
  659.             if (i == level)
  660.             {
  661.                 if (p->attr.bits.hasChild)
  662.                     bitmapId =
  663.                         (p->attr.bits.opened)? BtmMinusAlone: BtmPlusAlone;
  664.                 else if (p->attr.bits.hasPrev)
  665.                     bitmapId =
  666.                         (p->attr.bits.hasNext)? BtmItemMiddle: BtmItemBottom;
  667.                 else 
  668.                     bitmapId = 
  669.                         (p->attr.bits.hasNext)? BtmItemFirst: BtmItemAlone;
  670.             }
  671.             else
  672.             {
  673.                 if (!(p->attr.bits.hasPrev) && i == level - 1)
  674.                     bitmapId = (wVerticalLines[row] & (1 << (i - 1))) ? 
  675.                         BtmItemChild : BtmItemChildNo;
  676.                 // if there is a bitmap to draw
  677.                 // init bitmapId to BtmNull if prev of level i has no next
  678.                 else 
  679.                     bitmapId = (wVerticalLines[row] & (1 << (i - 1))) ?
  680.                         BtmItemNo: BtmNull;
  681.             }
  682.  
  683.             if (bitmapId != BtmNull)
  684.             {
  685.                 // ok, draw this icon
  686.                 // retreive the good bitmap
  687.                 h = gIconHandle[bitmapId - BtmOffset];
  688.                 bitmap = (BitmapPtr)MemHandleLock(h);
  689.  
  690.                 // draw it
  691.                 WinDrawBitmap(bitmap, (i - 1 - gRefLevel) * 11, y);
  692.                 MemHandleUnlock(h);
  693.             }
  694.         }
  695.         // time optimizations
  696.         // TODO : recalc these
  697.         x = (level - gRefLevel) * 11 + 2;
  698.     }
  699.  
  700.     // write the item description (with priority, due date, progress bar...)
  701.     if (p->format.bits.extendedType)
  702.     {
  703.         ProjectDrawExtendedItemDesc((TaskExtendedRecordType*)p, x, y);
  704.     }
  705.     else
  706.     {
  707.         ProjectDrawItemDesc(p, x, y);
  708.     }
  709.  
  710.     MemHandleUnlock(taskH);
  711.  
  712. } // static void ProjectItemDraw(MemPtr table, UInt16 row, UInt16 column, RectanglePtr bounds)
  713.  
  714.  
  715.  
  716. /*
  717.  * Table init
  718.  */
  719. void ProjectTableInit(void)
  720. {
  721.     TablePtr table;
  722.     UInt16 numRows;
  723.     UInt16 i;
  724.  
  725.     table = GetObjectPtr(ProjectTable);
  726.     numRows = TblGetNumberOfRows(table);
  727.  
  728.     for (i = 0; i < numRows; i++)
  729.     {
  730.         TblSetItemStyle(table, i, 0, customTableItem);
  731.         TblSetItemInt(table, i, 0, i + 1); // begin at task 1, never display task 0
  732.     }
  733.  
  734.     TblSetColumnUsable(table, 0, true);
  735.     TblSetCustomDrawProcedure(table, 0, (TableDrawItemFuncPtr)ProjectItemDraw);
  736.     TblSetItemInt(table, 0, 0, gCurrentPrefs.topTask);
  737. } // static void ProjectTableInit(void)
  738.  
  739.  
  740.  
  741. void ProjectTableEmpty(void)
  742. {
  743.     TablePtr table;
  744.     UInt16 numRows;
  745.     UInt16 i;
  746.  
  747.     table = GetObjectPtr(ProjectTable);
  748.     numRows = TblGetNumberOfRows(table);
  749.  
  750.     for (i = 0; i < numRows; i++)
  751.     {
  752.         // fill with empty items
  753.         TblSetItemInt(table, i, 0, -1);
  754.         TblSetRowSelectable(table, i, false);
  755.         wVerticalLines[i] = 0;
  756.     }
  757. }
  758.  
  759.  
  760.  
  761. void ProjectTableUpdate(void)
  762. {
  763.     TablePtr table;
  764.     UInt16 numRows;
  765.     UInt16 i;
  766.     Int32 next;
  767.     UInt8 level;
  768.  
  769.     table = GetObjectPtr(ProjectTable);
  770.     numRows = TblGetNumberOfRows(table);
  771.  
  772.     // need to set the first one selectable for when we come back of an empty
  773.     // subview
  774.     TblSetRowSelectable(table, 0, true);
  775.  
  776.     // special case, db empty (just task 0)
  777.     if (DmNumRecords(gdbP) == 1)
  778.     {
  779.         ProjectTableEmpty();
  780.         return;
  781.     }
  782.  
  783.     // special case, the first row's item is -1, check
  784.     if (TblGetItemInt(table, 0, 0) == -1 || 
  785.         TblGetItemInt(table, 0, 0) >= DmNumRecords(gdbP))
  786.     {
  787.         if (gParentTask + 1 < DmNumRecords(gdbP) &&     
  788.             TaskGetLevel(gdbP, gParentTask + 1) > gRefLevel)
  789.         {
  790.             TblSetItemInt(table, 0, 0, gParentTask + 1);
  791.             TblSetRowSelectable(table, 0, true);
  792.         }
  793.         else
  794.         {
  795.             ProjectTableEmpty();
  796.             return;
  797.         }
  798.     }
  799.  
  800.     // first item change if it is now invisible
  801.     while (gProjectPrefs.hideDoneTasks && (next = TblGetItemInt(table, 0, 0)) != -1 && TaskGetIsDone(gdbP, next))
  802.     {
  803.         next = TaskGetNextRelativeIndex(gdbP, next);
  804.         if (next == 0)
  805.         {
  806.             ProjectTableEmpty();
  807.             return;
  808.         }
  809.         TblSetItemInt(table, 0, 0, next);
  810.         TblSetRowSelectable(table, 0, true);
  811.     }
  812.  
  813.     if (TaskGetLevel(gdbP, TblGetItemInt(table, 0, 0)) <= gRefLevel)
  814.     {
  815.         ProjectTableEmpty();
  816.         return;
  817.     }
  818.  
  819.     
  820.     //
  821.     // calc vertical line for first row.
  822.     //
  823.     next = TblGetItemInt(table, 0, 0);
  824.     level = TaskGetLevel(gdbP, next);
  825.     wVerticalLines[0] = TaskGetHasNext(gdbP, next)? (1 << (level - 1)) : 0;
  826.     for (i = gRefLevel + 1; i < level; i++)
  827.     {
  828.         UInt16 prev;
  829.         if ( ( !TaskGetHasPrev(gdbP, next) && i == level - 1 && TaskGetHasNext(gdbP, next - 1) ) || 
  830.              ( (prev = TaskGetPrevIndexByLevel(gdbP, next, i)) != dmMaxRecordIndex && TaskGetHasNext(gdbP, prev) ) )
  831.             wVerticalLines[0] |= 1 << (i - 1);
  832.     }
  833.     
  834.  
  835.     // other items
  836.     for (i = 1; i < numRows; i++)
  837.     {
  838.         // get the previous item
  839.         next = TblGetItemInt(table, i-1, 0);
  840.  
  841.         if (next != -1)
  842.         {
  843.             // if he is not opened
  844.             if (TaskGetHasChild(gdbP, next) && !TaskIsOpened(gdbP, next))
  845.             {
  846.                 // get the next
  847.                 next = TaskGetNextRelativeIndex(gdbP, next);
  848.                 if (next == 0)
  849.                     next = -1;
  850.             }
  851.             else
  852.             {
  853.                 // just go to the next
  854.                 next++;
  855.  
  856.                 // if it's past the last record
  857.                 if (next >= DmNumRecords(gdbP))
  858.                     next = -1;
  859.             }
  860.  
  861.             // if he must not be drawn
  862.             while (gProjectPrefs.hideDoneTasks && next > 0 && TaskGetIsDone(gdbP, next))
  863.                 next = TaskGetNextRelativeIndex(gdbP, next);
  864.             if (next <= 0)
  865.                 next = -1;
  866.  
  867.             // if we are drawing a subtree, stop when we reach the last child
  868.             if (gParentTask != 0 && next != -1)
  869.             {    
  870.                 UInt8 levA;
  871.                 if ((levA = TaskGetLevel(gdbP, next)) <= (gRefLevel) ||
  872.                     (  levA == gRefLevel + 1 &&
  873.                        TaskGetFatherIndex(gdbP, next) != gParentTask)  )
  874.                     next = -1;
  875.             }
  876.  
  877.         }
  878.  
  879.         // calc vertical line.
  880.         if (next == -1)
  881.             wVerticalLines[i] = 0;
  882.         else 
  883.         {
  884.             UInt16 mask = 1 << (TaskGetLevel(gdbP, next) - 1);
  885.             if (TaskGetHasNext(gdbP, next))
  886.                 wVerticalLines[i] = wVerticalLines[i - 1] | mask;
  887.             else
  888.                 wVerticalLines[i] = wVerticalLines[i - 1] & ~mask;
  889.         }
  890.  
  891.         TblSetItemInt(table, i, 0, next);
  892.         TblSetRowSelectable(table, i, next == -1 ? false : true);
  893.     }
  894.     gCurrentPrefs.topTask = TblGetItemInt(table, 0, 0);
  895. } // void ProjectTableUpdate(void)
  896.  
  897.  
  898.  
  899. /****************************************************************************
  900.  * Name : Scroll
  901.  * Desc : update the form to scroll up or down
  902.  * Parm : 
  903.  *             -> scroll type (scrollUp, scrollDown)
  904.  *             -> scroll step
  905.  * Out  : 
  906.  * Auth : lb, 02.08.2000
  907.  * Mod  : lb, 18.08.2000
  908.  *             fixed scroll up bug that displayed father in sub view
  909.  ***************************************************************************/
  910. void Scroll(scrollType s, UInt8 step)
  911. {
  912.     UInt16 value;
  913.     TablePtr table;
  914.  
  915.     table = GetObjectPtr(ProjectTable);
  916.  
  917.     switch (s)
  918.     {
  919.         case scrollDown:
  920.             if ((value = TblGetItemInt(table, step, 0)) != -1)
  921.             {
  922.                 TblSetItemInt(table, 0, 0, value);
  923.                 //FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  924.                 ProjectTableUpdate();
  925.             }
  926.             else
  927.             {
  928.                 step--;
  929.                 while (step > 0)
  930.                 {
  931.                     if ((value = TblGetItemInt(table, step, 0)) != -1)
  932.                     {
  933.                         TblSetItemInt(table, 0, 0, value);
  934.                         //FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  935.                         ProjectTableUpdate();
  936.                         break;
  937.                     }
  938.                     step--;
  939.                 }
  940.             }
  941.             break;
  942.  
  943.         case scrollUp:
  944.             value = TblGetItemInt(table, 0, 0);
  945.             if (value == -1)
  946.                 return;
  947.             if (value > step + gParentTask)
  948.             {
  949.                 UInt8 count = step;
  950.                 while (value > gParentTask + 1 && count)
  951.                 {
  952.                     value--;
  953.                     if (TaskIsVisible(gdbP, value))
  954.                     {
  955.                         count--;
  956.                     }
  957.                     else
  958.                     {
  959.                         if (gProjectPrefs.hideDoneTasks)
  960.                             value--;
  961.                         else
  962.                             value = TaskGetFatherIndex(gdbP, value);
  963.                         if (value == gParentTask)
  964.                         {
  965.                             value = gParentTask + 1;
  966.                         }
  967.                         if (TaskIsVisible(gdbP, value))
  968.                         {
  969.                             count--;
  970.                         }
  971.                     }
  972.                 }
  973.                 TblSetItemInt(table, 0, 0, value);
  974.                 //FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  975.                 ProjectTableUpdate();
  976.             }
  977.             else
  978.             {
  979.                 TblSetItemInt(table, 0, 0, gParentTask + 1); // never display task 0
  980.                 ProjectTableUpdate();
  981.                 //FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  982.             }
  983.             break;
  984.  
  985.         case scrollTop:
  986.             if (TaskGetHasChild(gdbP, gParentTask))
  987.                 TblSetItemInt(table, 0, 0, gParentTask + 1);
  988.             else
  989.                 TblSetItemInt(table, 0, 0, -1);
  990.             // update done in Btn_Sub
  991.             //FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  992.             break;
  993.  
  994.         default:
  995.             break;
  996.     }
  997. } // void Scroll(scrollType s, UInt8 step)
  998.  
  999.  
  1000.  
  1001. /****************************************************************************
  1002.  * Name : FrmTaskEditUpdateDateTrigger
  1003.  * Desc : update the date trigger
  1004.  * Parm : 
  1005.  *             -> trigger pointer
  1006.  *             -> date to print
  1007.  * Out  : 
  1008.  * Auth : lb, 06.08.2000
  1009.  ***************************************************************************/
  1010. void FrmTaskEditUpdateDateTrigger(MemPtr trigger, DateType p)
  1011. {
  1012.     Char* date;
  1013.  
  1014.     date = (Char*)CtlGetLabel(trigger);
  1015.  
  1016.     if (p.month == 0)
  1017.     {
  1018.         StrCopy(date, "No date");
  1019.     }
  1020.     else
  1021.     {
  1022.         DateToAscii(p.month, p.day, p.year + YEAR_OFFSET, gDateFormat, date);
  1023.     }
  1024.  
  1025.     CtlSetLabel(trigger, date);
  1026. } // void FrmTaskEditUpdateDateTrigger(MemPtr trigger, DateType p)
  1027.  
  1028.  
  1029.  
  1030. /****************************************************************************
  1031.  * Name : SelectActualTask
  1032.  * Desc : select the tbl case of gActualTask. Move the screen if necessary
  1033.  *           expand a branch if necessary
  1034.  * Parm : 
  1035.  *             -> move (must the actual task be on screen)
  1036.  * Out  : 
  1037.  * Auth : lb, 09.08.2000
  1038.  ***************************************************************************/
  1039. void SelectActualTask(Boolean move)
  1040. {
  1041.     TablePtr table = GetObjectPtr(ProjectTable);
  1042.     UInt8 i = 0, numRows = TblGetNumberOfRows(table);
  1043.  
  1044.     gLastSelected = 0;
  1045.     TblUnhighlightSelection(table);
  1046.  
  1047.     if (gActualTask == 0)
  1048.         return;
  1049.  
  1050.     // ensure the branch is expanded
  1051.     if (move && !TaskIsVisible(gdbP, gActualTask))
  1052.             TaskMakeVisible(gdbP, gActualTask);
  1053.  
  1054.     // is actual task on screen ?
  1055.     while (i < numRows && TblGetItemInt(table, i, 0) != gActualTask)
  1056.     {
  1057.         i++;
  1058.     }
  1059.  
  1060.     if (i == numRows && move)
  1061.     {
  1062.         TblSetItemInt(table, 0, 0, gActualTask);
  1063.         // center it
  1064.         Scroll(scrollUp, 5);
  1065.         // where is it now
  1066.         i = 0;
  1067.         while (i < numRows && TblGetItemInt(table, i, 0) != gActualTask)
  1068.         {
  1069.             i++;
  1070.         }
  1071.     }
  1072.     if (i != numRows)
  1073.     {
  1074.         TblSelectItem(table, i, 0);
  1075.         gLastSelected = gActualTask;
  1076.     }
  1077.     else
  1078.     {
  1079.         gLastSelected = gActualTask = 0;
  1080.     }
  1081. } // void SelectActualTask(Boolean move)
  1082.  
  1083.  
  1084.  
  1085. /****************************************************************************
  1086.  * Name : InitFrmTaskEdit
  1087.  * Desc : init the form to edit the actual selected task
  1088.  * Parm : 
  1089.  * Out  : 
  1090.  * Auth : lb, 03.08.2000
  1091.  ***************************************************************************/
  1092. void InitFrmTaskEdit(void)
  1093. {
  1094.     FieldPtr fld = GetObjectPtr(TaskDesc);
  1095.     MemHandle h;
  1096.     TaskRecordType *p;
  1097.     MemHandle textH = FldGetTextHandle(fld);
  1098.     Char *textP;
  1099.     UInt16 l;
  1100.     UInt8 priority, value;
  1101.     DateType dueDate;
  1102.  
  1103.     // if there's already a handle, destroy it
  1104.     if (textH)
  1105.     {
  1106.         FldSetTextHandle(fld, NULL);
  1107.         MemHandleFree(textH);
  1108.     }
  1109.  
  1110.     h = DmQueryRecord(gdbP, gActualTask);
  1111.     p = MemHandleLock(h);
  1112.     l = StrLen(&p->description);
  1113.     textH = MemHandleNew(l+1);
  1114.     textP = MemHandleLock(textH);
  1115.     StrCopy(textP, &p->description);
  1116.     MemHandleUnlock(h);
  1117.     MemHandleUnlock(textH);
  1118.     FldSetTextHandle(fld, textH);
  1119.  
  1120.     // see if we're synchronized with a ToDo
  1121.     if (TaskGetFormat(gdbP, gActualTask).hasToDo)
  1122.     {
  1123.         pgErr err;
  1124.         // check the status in ToDo and update this task
  1125.         err = TaskGetToDoStatus(gdbP, gActualTask, &value, &priority, &dueDate);
  1126.         if (err == pgOK)
  1127.         {
  1128.             TaskSetCompleted(gdbP, gActualTask, value);
  1129.             TaskSetDueDate(gdbP, gActualTask, dueDate);
  1130.             TaskSetPriority(gdbP, gActualTask, priority);
  1131.             CtlSetValue(GetObjectPtr(Chk_Edit_ToDo_Link), 1);
  1132.         }
  1133.     }
  1134.  
  1135.     // get the action value and set it on the form
  1136.     CtlSetValue(GetObjectPtr(Chk_Edit_Action), TaskGetActionState(gdbP, gActualTask));
  1137.  
  1138.     // get the date and set the selector trigger
  1139.     FrmTaskEditUpdateDateTrigger(GetObjectPtr(Pop_Due_Date), TaskGetDueDate(gdbP, gActualTask));
  1140.  
  1141.     // get the priority and set it on the form
  1142.     priority = TaskGetPriority(gdbP, gActualTask);
  1143.     // to be compatible with not initialised db
  1144.     if (priority > 0 && priority < 7)
  1145.     {
  1146.         CtlSetValue(GetObjectPtr(Btn_Priority_X + priority - 1), true);
  1147.     }
  1148.  
  1149.  
  1150.     // initialize category popup trigger
  1151.     {
  1152.         UInt16 attr;
  1153.         Char* name = (Char*)CtlGetLabel(GetObjectPtr(Pop_Category));
  1154.         DmRecordInfo(gdbP, gActualTask, &attr, NULL, NULL);
  1155.         CategoryGetName(gdbP, (attr & dmRecAttrCategoryMask), name);
  1156.         CategorySetTriggerLabel(GetObjectPtr(Pop_Category), name);
  1157.     }
  1158.  
  1159. } // void InitFrmTaskEdit(void)
  1160.  
  1161.  
  1162.  
  1163. /****************************************************************************
  1164.  * Name : CleanUpFrmTaskEdit
  1165.  * Desc : clean up the form, save the work done
  1166.  * Parm : 
  1167.  * Out  : 
  1168.  * Auth : lb, 03.08.2000
  1169.  ***************************************************************************/
  1170. void CleanUpFrmTaskEdit(void)
  1171. {
  1172.     FieldPtr fld = GetObjectPtr(TaskDesc);
  1173.     MemHandle h, hNew;
  1174.     TaskRecordType *p, *pNew;
  1175.     MemHandle textH = FldGetTextHandle(fld);
  1176.     Char *textP, *note;
  1177.     UInt32 uniqueID;
  1178.     UInt16 index = dmMaxRecordIndex;
  1179.     UInt16 attr;
  1180.     TaskFormatType format;
  1181.     UInt32 noteSize = 0;
  1182.     MemPtr extraBlock = NULL;
  1183.     UInt32 extraSize;
  1184.  
  1185.     note = TaskGetNote(gdbP, gActualTask);
  1186.     if (note)
  1187.         noteSize = StrLen(note);
  1188.  
  1189.     extraSize = TaskGetExtraBlock(gdbP, gActualTask, NULL);
  1190.  
  1191.     if (extraSize)
  1192.     {
  1193.         extraBlock = MemPtrNew(extraSize);
  1194.         TaskGetExtraBlock(gdbP, gActualTask, extraBlock);
  1195.     }
  1196.  
  1197.     FldCompactText(fld);
  1198.     textP = MemHandleLock(textH);
  1199.  
  1200.     // create a new record at last position, this is easier to update the note
  1201.     hNew = DmNewRecord(gdbP, &index,
  1202.         TaskRecordTypeSize + StrLen(textP) + noteSize + extraSize);
  1203.  
  1204.     if (!hNew)
  1205.     {
  1206.         MessageBox(StrNoMemorySpaces);
  1207.         MemHandleUnlock(textH);
  1208.         return;
  1209.     }
  1210.  
  1211.     h = DmQueryRecord(gdbP, gActualTask);
  1212.     p = MemHandleLock(h);
  1213.     pNew = MemHandleLock(hNew);
  1214.  
  1215.     DmWrite(pNew, 0, p, sizeof(TaskRecordType) - 1);
  1216.  
  1217.     DmStrCopy(pNew, OffsetOf(TaskRecordType, description), textP);
  1218.     DmStrCopy(pNew, 
  1219.         OffsetOf(TaskRecordType, description) + StrLen(&pNew->description) + 1, 
  1220.         &p->description + StrLen(&p->description) + 1);
  1221.     // clean the newTask bit
  1222.     format = p->format.bits;
  1223.     format.newTask = 0;
  1224.     DmWrite(pNew, OffsetOf(TaskRecordType, format), &format, sizeof(UInt16));
  1225.  
  1226.     if (extraSize)
  1227.     {
  1228.         DmWrite(pNew,
  1229.             OffsetOf(TaskRecordType, description) + StrLen(&pNew->description)
  1230.             + StrLen(note) + 2,
  1231.             extraBlock, extraSize);
  1232.         
  1233.         MemPtrFree(extraBlock);
  1234.     }
  1235.  
  1236.     MemHandleUnlock(hNew);
  1237.     MemHandleUnlock(h);
  1238.     MemHandleUnlock(textH);
  1239.     DmReleaseRecord(gdbP, DmNumRecords(gdbP) - 1, true);
  1240.  
  1241.     // to allow sync
  1242.     // get the unique ID of original task
  1243.     DmRecordInfo(gdbP, gActualTask, &attr, &uniqueID, NULL);
  1244.     // delete original task
  1245.     DmRemoveRecord(gdbP, gActualTask);
  1246.     // move the new task to the good index
  1247.     DmMoveRecord(gdbP, DmNumRecords(gdbP) - 1, gActualTask);
  1248.     // set the unique ID of the new task
  1249.     DmSetRecordInfo(gdbP, gActualTask, &attr, &uniqueID);
  1250. } // void CleanUpFrmTaskEdit(void)
  1251.  
  1252.  
  1253.  
  1254. /****************************************************************************
  1255.  * Name : InitFrmNoteEdit
  1256.  * Desc : init the form to edit the actual selected task
  1257.  * Parm : 
  1258.  * Out  : 
  1259.  * Auth : lb, 22.08.2000
  1260.  ***************************************************************************/
  1261. void InitFrmNoteEdit(void)
  1262. {
  1263.     FieldPtr fld = GetObjectPtr(TaskNote);
  1264.     MemHandle textH = FldGetTextHandle(fld);
  1265.     Char *textP;
  1266.     UInt16 l;
  1267.     Char *note;
  1268.     FormPtr frm = FrmGetActiveForm();
  1269.  
  1270.     // get the name of db, set it in titlebar
  1271.     if (StrStr(gCurrentPrefs.openDBName, gPrepend) == gCurrentPrefs.openDBName)
  1272.     {
  1273.         // without prepanding chars
  1274.         FrmCopyTitle(frm, &gCurrentPrefs.openDBName[5]);
  1275.     }
  1276.     else
  1277.     {
  1278.         // old name format support (without prepanding)
  1279.         FrmCopyTitle(frm, gCurrentPrefs.openDBName);
  1280.     }
  1281.  
  1282.     // if there's already a handle, destroy it
  1283.     if (textH)
  1284.     {
  1285.         FldSetTextHandle(fld, NULL);
  1286.         MemHandleFree(textH);
  1287.     }
  1288.  
  1289.     note = TaskGetNote(gdbP, gActualTask);
  1290.     // if there's a description already
  1291.     if (note)
  1292.     {
  1293.         l = StrLen(note);
  1294.         textH = MemHandleNew(l+1);
  1295.         textP = MemHandleLock(textH);
  1296.  
  1297.         // could change as we allocated memory
  1298.         note = TaskGetNote(gdbP, gActualTask);
  1299.         StrCopy(textP, note);
  1300.         MemHandleUnlock(textH);
  1301.         FldSetTextHandle(fld, textH);
  1302.     }
  1303.     else
  1304.     {
  1305.         // set as empty string.
  1306.         char* p;
  1307.         textH = MemHandleNew(1);
  1308.         p = MemHandleLock(textH);
  1309.         *p = '\0';
  1310.         MemHandleUnlock(textH);
  1311.         FldSetTextHandle(fld, textH);
  1312.     }
  1313.  
  1314. } // void InitFrmNoteEdit(void)
  1315.  
  1316.  
  1317.  
  1318. /****************************************************************************
  1319.  * Name : CleanUpFrmNoteEdit
  1320.  * Desc : clean up the form, save the work done
  1321.  * Parm : 
  1322.  * Out  : 
  1323.  * Auth : lb, 22.08.2000
  1324.  ***************************************************************************/
  1325. void CleanUpFrmNoteEdit(void)
  1326. {
  1327.     FieldPtr fld = GetObjectPtr(TaskNote);
  1328.     MemHandle textH = FldGetTextHandle(fld);
  1329.     Char *textP;
  1330.  
  1331.     FldCompactText(fld);
  1332.  
  1333.     textP = MemHandleLock(textH);
  1334.  
  1335.     TaskSetNote(gdbP, gActualTask, textP);
  1336.  
  1337.     MemHandleUnlock(textH);
  1338.     
  1339.     // set texthandle as NULL, or it'll be destroyed by the close event
  1340.     FldSetTextHandle(fld, NULL);
  1341.     MemHandleFree(textH);
  1342. } // void CleanUpFrmNoteEdit(void)
  1343.  
  1344.  
  1345.  
  1346. /****************************************************************************
  1347.  * Name : FrmProjectListInit
  1348.  * Desc : init FrmProjectList
  1349.  * Parm : 
  1350.  * Out  : 
  1351.  * Auth : lb, 08.08.2000
  1352.  * Rem  : no error handling
  1353.  ***************************************************************************/
  1354. void FrmProjectListInit(void)
  1355. {
  1356.     UInt16 num = 0;
  1357.     DmSearchStateType stateInfo;
  1358.     LocalID dbID;
  1359.     ListPtr listP;
  1360.     UInt16 cardNo = 0;
  1361.     UInt16 offset = 0;
  1362.     //DmOpenRef projDB = NULL;
  1363.     //const Char *projDBName = "ProjectsDB";
  1364.  
  1365.     listP = GetObjectPtr(Lst_Project_List);
  1366.     //LstSetSelection(listP, -1);
  1367.     LstEraseList(listP);
  1368.     
  1369.     // project link tree creation
  1370.     //CreateDB(projDBName); // this is possible as no DB is open yet
  1371.     //OpenDB(projDBName, &projDB);
  1372.     
  1373.     // search the number of databases
  1374.     // begin the search
  1375.     if (DmGetNextDatabaseByTypeCreator(true, &stateInfo, 'DATA', CREATOR, 
  1376.         false, &cardNo, &dbID) == errNone)
  1377.     {
  1378.         //UInt16 index;
  1379.         num++;
  1380.         //index = num;
  1381.         //AddLinkRecord(projDB, 0, &index, );
  1382.         // continue the search
  1383.         while (DmGetNextDatabaseByTypeCreator(false, &stateInfo, 'DATA', CREATOR, 
  1384.             false, &cardNo, &dbID) == errNone)
  1385.         {
  1386.             num++;
  1387.         }
  1388.     }
  1389.     //else
  1390.     //{
  1391.         // nothing to initialize if there's no database
  1392.         //return;
  1393.     //}
  1394.  
  1395.     // deallocate old lists if necessary
  1396.     if (namesData)
  1397.     {
  1398.         MemPtrFree(namesData);
  1399.     }
  1400.     if (names)
  1401.     {
  1402.         MemPtrFree(names);
  1403.     }
  1404.  
  1405.     // allocate enough space for the names (+1 for NULL, used by GlobalFlat)
  1406.     namesData = MemPtrNew(num * 32);
  1407.     names = MemPtrNew((num+1)*sizeof(char*));
  1408.     names[num] = NULL; // terminate names array
  1409.     num = 0;
  1410.  
  1411.     // get the names in our array
  1412.     // initial name
  1413.     if (DmGetNextDatabaseByTypeCreator(true, &stateInfo, 'DATA', CREATOR, 
  1414.         false, &cardNo, &dbID) == errNone)
  1415.     {
  1416.         DmDatabaseInfo(cardNo, dbID, namesData, NULL, NULL, NULL, NULL, NULL,
  1417.             NULL, NULL, NULL, NULL, NULL);
  1418.  
  1419.         // if the name is prepended (new databases since V0.10)
  1420.         if (StrStr(namesData, gPrepend) == namesData)
  1421.         {
  1422.             MemMove(namesData, namesData + StrLen(gPrepend),
  1423.                     StrLen(namesData+StrLen(gPrepend)) + 1);
  1424.         }
  1425.         names[num++] = namesData;
  1426.         offset += StrLen(namesData) + 1;
  1427.  
  1428.         while (DmGetNextDatabaseByTypeCreator(false, &stateInfo,
  1429.                                               'DATA', CREATOR,
  1430.             false, &cardNo, &dbID) == errNone)
  1431.         {
  1432.             DmDatabaseInfo(cardNo, dbID, &namesData[offset], NULL, NULL, NULL, 
  1433.                 NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  1434.             // if the name is prepended (new databases since V0.10)
  1435.             if (StrStr(&namesData[offset], gPrepend) == &namesData[offset])
  1436.             {
  1437.                 MemMove(&namesData[offset],
  1438.                         &namesData[offset] + StrLen(gPrepend), 
  1439.                         StrLen(&namesData[offset]+StrLen(gPrepend)) + 1);
  1440.             }
  1441.             names[num++] = &namesData[offset];
  1442.             offset += StrLen(&namesData[offset]) + 1;
  1443.         }
  1444.     }
  1445.  
  1446.     // set the names in the list
  1447.     LstSetListChoices(listP, names, num);
  1448.  
  1449.     // draw the list
  1450.     LstDrawList(listP);
  1451.  
  1452.     // if the list is empty, deselect it
  1453.     if (num == 0)
  1454.     {
  1455.         LstSetSelection(listP, -1);
  1456.     }
  1457.  
  1458. } // void FrmProjectListInit(void)
  1459.  
  1460.  
  1461.  
  1462. /****************************************************************************
  1463.  * Name : FrmProjectListCleanUp
  1464.  * Desc : clean up the form
  1465.  * Parm : 
  1466.  * Out  : 
  1467.  * Auth : lb, 08.08.2000
  1468.  ***************************************************************************/
  1469. void FrmProjectListCleanUp(void)
  1470. {
  1471.     
  1472. } // void FrmProjectListCleanUp(void)
  1473.  
  1474.  
  1475.  
  1476. /****************************************************************************
  1477.  * Name : MessageBox
  1478.  * Desc : display a message for the user, just OK
  1479.  * Parm :
  1480.  *             -> message id
  1481.  * Out  : 
  1482.  * Auth : lb, 11.09.2000
  1483.  ***************************************************************************/
  1484. void MessageBox(UInt16 id)
  1485. {
  1486.   MemHandle h;
  1487.   char* p;
  1488.   UInt16 respond;
  1489.  
  1490.   h = DmGetResource('tSTR', id);
  1491.   p = MemHandleLock(h);
  1492.  
  1493.   respond = FrmCustomAlert(AltEmpty, p, "", "");
  1494.  
  1495.   MemHandleUnlock(h);
  1496.   DmReleaseResource(h);
  1497.  
  1498. } // void MessageBox(UInt16 id)
  1499.  
  1500.  
  1501.  
  1502. /****************************************************************************
  1503.  * Name : GetLastInSub
  1504.  * Desc : return the last index of the parent's sub
  1505.  * Parm :
  1506.  *             -> parent
  1507.  * Out  : 
  1508.  * Auth : lb, 21.10.2000
  1509.  ***************************************************************************/
  1510. UInt16 GetLastInSub(UInt16 parent)
  1511. {
  1512.     UInt16 i = parent + 1;
  1513.     UInt8 refLevel = (parent == 1 ? 0 : TaskGetLevel(gdbP, parent));
  1514.     while (i < DmNumRecords(gdbP) - 1 && 
  1515.         TaskGetLevel(gdbP, i) > refLevel)
  1516.     {
  1517.         i++;
  1518.     }
  1519.     return i - 1;
  1520. } // UInt16 GetLastInSub(UInt16 parent)
  1521.  
  1522.  
  1523.  
  1524. /****************************************************************************
  1525.  * Name : ConfirmCustom
  1526.  * Desc : display a custom confirmation message
  1527.  * Parm :
  1528.  *             -> action id (StrActionDelete || StrActionResetDates
  1529.  *             -> message id
  1530.  * Out  : button pressed
  1531.  * Auth : seagull, 09.09.2000
  1532.  * Mod  : burgbach, 21.10.2000 -> custom message (not only delete messages)
  1533.  ***************************************************************************/
  1534. UInt16 ConfirmCustom(UInt16 idAction, UInt16 id)
  1535. {
  1536.   MemHandle h1, h2;
  1537.   char *p1, *p2;
  1538.   UInt16 respond;
  1539.  
  1540.   h1 = DmGetResource('tSTR', idAction);
  1541.   h2 = DmGetResource('tSTR', id);
  1542.   p1 = MemHandleLock(h1);
  1543.   p2 = MemHandleLock(h2);
  1544.  
  1545.   respond = FrmCustomAlert(AltConfirmCustom, p1, p2, "");
  1546.  
  1547.   MemHandleUnlock(h1);
  1548.   DmReleaseResource(h1);
  1549.   MemHandleUnlock(h2);
  1550.   DmReleaseResource(h2);
  1551.  
  1552.   return respond;
  1553. } // UInt16 ConfirmCustom(UInt16 idAction, UInt16 id)
  1554.  
  1555.  
  1556.  
  1557. /****************************************************************************
  1558.  * Name : ProgressHandleEvent
  1559.  * Desc : update the progress of the actualtask
  1560.  * Parm :
  1561.  * Out  : 
  1562.  * Auth : burgbach, 19.10.2000
  1563.  ***************************************************************************/
  1564. void ProgressHandleEvent(void)
  1565. {
  1566.     // only for leaves
  1567.     // not for directlink types
  1568.     TaskFormatType format;
  1569.  
  1570.     if (!gActualTask)
  1571.         return;
  1572.  
  1573.     format = TaskGetFormat(gdbP, gActualTask);
  1574.     if (!TaskGetHasChild(gdbP, gActualTask) && 
  1575.         !format.isMemo && !format.isContact && !format.isAppointement &&
  1576.         !format.isToDo)
  1577.     {
  1578.         if (TaskGetActionState(gdbP, gActualTask))
  1579.         {
  1580.             TaskSetCompleted(gdbP, gActualTask, 
  1581.                 TaskGetCompleted(gdbP, gActualTask) == ACTION_OK ? 
  1582.                 ACTION_NO : ACTION_OK );
  1583.             if (format.hasToDo)
  1584.             {
  1585.                 TaskSetToDoStatus(gdbP, gActualTask, toDoComplete,
  1586.                     TaskGetCompleted(gdbP, gActualTask), 0,
  1587.                     gNoDate);
  1588.                 // record completion date (always for ToDo linked tasks)
  1589.                 if (TaskGetIsDone(gdbP, gActualTask))
  1590.                     TaskSetToDoStatus(gdbP, gActualTask, toDoDueDate,
  1591.                         0, 0,
  1592.                         gToday);
  1593.             }
  1594.         }
  1595.         else
  1596.         {
  1597.             Int16 TInt16;
  1598.             ListPtr listP = GetObjectPtr(Lst_Percent);
  1599.             LstSetSelection(listP, 
  1600.                 TaskGetCompleted(gdbP, gActualTask));
  1601.  
  1602.             TInt16 = LstPopupList(listP);
  1603.             if (TInt16 != -1)
  1604.             {
  1605.                 TaskSetCompleted(gdbP, gActualTask, TInt16);
  1606.             }
  1607.         }
  1608.  
  1609.         // record completion date
  1610.         if (TaskGetIsDone(gdbP, gActualTask) && gProjectPrefs.completionDate)
  1611.             TaskSetDueDate(gdbP, gActualTask, gToday);
  1612.  
  1613.         // update fathers
  1614.         if (TaskGetLevel(gdbP, gActualTask) > 1)
  1615.         {
  1616.             TaskCalcCompleted(gdbP, 
  1617.                 TaskGetFatherIndex(gdbP, gActualTask));
  1618.         }
  1619.         FrmUpdateForm(FrmGetActiveFormID(), frmRedrawUpdateCode);
  1620.     }
  1621. }
  1622.  
  1623.  
  1624.  
  1625. /****************************************************************************
  1626.  * Name : PriorityHandleEvent
  1627.  * Desc : update the priority of the actualtask
  1628.  * Parm :
  1629.  * Out  : 
  1630.  * Auth : burgbach, 19.10.2000
  1631.  ***************************************************************************/
  1632. void PriorityHandleEvent(EventPtr e)
  1633. {
  1634.     Coord lx, ly;
  1635.     // edit it in place
  1636.     Int16 TInt16;
  1637.     ListPtr listP = GetObjectPtr(Lst_Priority);
  1638.     TaskFormatType format;
  1639.  
  1640.     format = TaskGetFormat(gdbP, gActualTask);
  1641.     if (format.isMemo || format.isContact || format.isAppointement ||
  1642.         format.isToDo)
  1643.     {
  1644.         return;
  1645.     }
  1646.  
  1647.     // init lx and ly depending on the active form
  1648.     if (FrmGetActiveFormID() == FrmFlat)
  1649.     {
  1650.         lx = 25;
  1651.         ly = 15 + e->data.tblSelect.row * 11;
  1652.     }
  1653.     else
  1654.     {
  1655.         lx = 4 + (1 + TaskGetLevel(gdbP, gActualTask) - 
  1656.             gRefLevel) * 11;
  1657.         ly = 15 + e->data.tblSelect.row * 11;
  1658.     }
  1659.  
  1660.     LstSetSelection(listP, 
  1661.         TaskGetPriority(gdbP, gActualTask) - 1);
  1662.     ly -= (TaskGetPriority(gdbP, gActualTask) - 1) * 11;
  1663.     // don't get out the screen
  1664.     ly = ly < 1 ? 1 : ly;
  1665.     ly = ly > 103 ? 103 : ly;
  1666.     LstSetPosition(listP, lx, ly);
  1667.     TInt16 = LstPopupList(listP);
  1668.     if (TInt16 != -1)
  1669.     {
  1670.         TaskSetPriority(gdbP, gActualTask, TInt16 + 1);
  1671.         FrmUpdateForm(FrmGetActiveFormID(), frmRedrawUpdateCode);
  1672.     }
  1673.     if (TaskGetFormat(gdbP, gActualTask).hasToDo)
  1674.     {
  1675.         TaskSetToDoStatus(gdbP, gActualTask, toDoPriority,
  1676.             0, TaskGetPriority(gdbP, gActualTask),
  1677.             gNoDate);
  1678.     }
  1679. } // void PriorityHandleEvent(EventPtr e)
  1680.  
  1681.  
  1682.  
  1683. /****************************************************************************
  1684.  * Name : SelectRange
  1685.  * Desc : popup a user form to ask for subview or all
  1686.  * Parm :
  1687.  * Out  : Btn_Sub_All or Btn_Sub_Sub or Btn_Sub_Cancel
  1688.  * Auth : burgbach, 21.10.2000
  1689.  ***************************************************************************/
  1690. UInt16 SelectRange(void)
  1691. {
  1692.     UInt16 temp = Btn_Sub_All;
  1693.  
  1694.     if (gParentTask) // if actual subview is not the total view
  1695.     {
  1696.         FormPtr frmSub = FrmInitForm(FrmSubOrAll);
  1697.         temp = FrmDoDialog(frmSub);
  1698.         FrmDeleteForm(frmSub);
  1699.     }
  1700.  
  1701.     return temp;
  1702. } // UInt16 SelectRange(void)
  1703.  
  1704.  
  1705.  
  1706. Boolean FrmMainMenuHandleEvent(EventPtr e)
  1707. {
  1708.     FormPtr frm;
  1709.  
  1710.     frm = FrmGetActiveForm();
  1711.  
  1712.     switch(e->data.menu.itemID) {
  1713.         case MenuMainNewTask:
  1714.             MessageBox(StrNewTask);
  1715.             break;
  1716.         case MenuMainTop:
  1717.             gActualTask = gParentTask + 1;
  1718.             SelectActualTask(true);
  1719.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1720.             break;
  1721.         case MenuMainBottom:
  1722.             if (gRefLevel == 0)
  1723.                 gActualTask = DmNumRecords(gdbP) - 1;
  1724.             else
  1725.             {
  1726.                 gActualTask = GetLastInSub(gParentTask);
  1727.             }
  1728.             SelectActualTask(true);
  1729.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1730.             break;
  1731.         case MenuMainRepair:
  1732.             TaskRepairTree(gdbP, 0, 0);
  1733.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1734.             break;
  1735.         case MenuMainReInit:
  1736.             switch (SelectRange())
  1737.             {
  1738.                 case Btn_Sub_All:
  1739.                     if (ConfirmCustom(StrActionDelete, StrAllTasks) == 0)
  1740.                     {
  1741.                         while (DmNumRecords(gdbP) > 1)
  1742.                         {
  1743.                             TaskRemove(gdbP, 1);
  1744.                         }
  1745.                         gParentTask = gRefLevel = 0;
  1746.                         // erase the up button
  1747.                         CtlHideControl(GetObjectPtr(Btn_Sub_Up));
  1748.                         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1749.                     }
  1750.                     break;
  1751.                 case Btn_Sub_Sub:
  1752.                     if (ConfirmCustom(StrActionDelete, 
  1753.                         StrAllDoneTasksInThisView) == 0)
  1754.                     {
  1755.                         TaskRemoveChildren(gdbP, gParentTask);
  1756.                         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1757.                     }
  1758.                     break;
  1759.                 default:
  1760.                     break;
  1761.             }
  1762.             break;
  1763.         case MenuMainSyncToDo:
  1764.                 TaskSyncAll();
  1765.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1766.             break;
  1767.         case MenuMainResetDates:
  1768.             FrmPopupForm(FrmSetReset);
  1769.             break;
  1770.         case MenuMainDeleteChildren:
  1771.             if (gActualTask && TaskGetHasChild(gdbP, gActualTask))
  1772.             {
  1773.                 if (ConfirmCustom(StrActionDelete, 
  1774.                     StrAllChildrenOfSelectedTask) == 0)
  1775.                 {
  1776.                     TaskRemoveChildren(gdbP, gActualTask);
  1777.                     FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1778.                 }
  1779.             }
  1780.             break;
  1781.         case MenuMainDeleteTask:
  1782.             if (gActualTask)
  1783.             {
  1784.                 if (TaskGetHasChild(gdbP, gActualTask))
  1785.                 {
  1786.                     if (ConfirmCustom(StrActionDelete, StrTaskAndChildren) == 0)
  1787.                     {
  1788.                         // remember the father
  1789.                         UInt16 father = 
  1790.                             TaskGetFatherIndex(gdbP, gActualTask);
  1791.                         // remove the task
  1792.                         TaskRemove(gdbP, gActualTask);
  1793.                         // if father isn't a father anymore
  1794.                         if (father != 0 && !TaskGetHasChild(gdbP, father))
  1795.                         {
  1796.                             // set its precentage to 0%
  1797.                             TaskSetCompleted(gdbP, father, 0);
  1798.                             // find his father
  1799.                             father = TaskGetFatherIndex(gdbP, father);
  1800.                         }
  1801.                         // if it exists, calc its percentage
  1802.                         if (father != 0)
  1803.                         {
  1804.                             TaskCalcCompleted(gdbP, father);
  1805.                         }
  1806.                         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1807.                     }
  1808.                 }
  1809.                 else
  1810.                 {
  1811.                     Boolean deleteOK = true;
  1812.                     if (gSavedPrefs.deleteWarn)
  1813.                     {
  1814.                         // get the description for the warning
  1815.                         char* desc = TaskGetDescription(gdbP, gActualTask);
  1816.                         if (FrmCustomAlert(AltConfirmDelete, desc, "", "") != 0)
  1817.                             deleteOK = false;
  1818.                         MemPtrFree(desc);
  1819.                     }
  1820.                     if (deleteOK)
  1821.                     {
  1822.                         // remember the father
  1823.                         UInt16 father = 
  1824.                             TaskGetFatherIndex(gdbP, gActualTask);
  1825.                         // remove the task
  1826.                         TaskRemove(gdbP, gActualTask);
  1827.                         // if father isn't a father anymore
  1828.                         if (father != 0 && !TaskGetHasChild(gdbP, father))
  1829.                         {
  1830.                             // set its precentage to 0%
  1831.                             TaskSetCompleted(gdbP, father, 0);
  1832.                             // find his father
  1833.                             father = TaskGetFatherIndex(gdbP, father);
  1834.                         }
  1835.                         // if it exists, calc its percentage
  1836.                         if (father != 0)
  1837.                         {
  1838.                             TaskCalcCompleted(gdbP, father);
  1839.                         }
  1840.                         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1841.                     }
  1842.                 }
  1843.             }
  1844.             break;
  1845.         case MenuMainDeleteDoneTask:
  1846.             switch (SelectRange())
  1847.             {
  1848.                 case Btn_Sub_All:
  1849.                     if (ConfirmCustom(StrActionDelete, StrAllDoneTasks) == 0)
  1850.                     {
  1851.                         // to be sure the percentages are correct
  1852.                         TaskCalcCompletedAll(gdbP);
  1853.                         TaskRemoveDone(gdbP);
  1854.                         TaskCalcCompletedAll(gdbP);
  1855.                         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1856.                     }
  1857.                     break;
  1858.                 case Btn_Sub_Sub:
  1859.                     if (ConfirmCustom(StrActionDelete, 
  1860.                         StrAllDoneTasksInThisView) == 0)
  1861.                     {
  1862.                         // to be sure the percentages are correct
  1863.                         TaskCalcCompletedAll(gdbP);
  1864.                         TaskRemoveDoneChildren(gdbP, gParentTask);
  1865.                         TaskCalcCompletedAll(gdbP);
  1866.                         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1867.                     }
  1868.                     break;
  1869.                 default:
  1870.                     break;
  1871.             }
  1872.             break;
  1873.         case MenuMainExpandAll:
  1874.             TaskExpand(gdbP, 0);
  1875.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1876.             break;
  1877.         case MenuMainCollapseAll:
  1878.             TaskCollapse(gdbP, 0);
  1879.             Scroll(scrollTop, 0);
  1880.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1881.             break;
  1882.         case MenuMainExpandOne:
  1883.             TaskExpand(gdbP, gActualTask);
  1884.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1885.             break;
  1886.         case MenuMainCollapseOne:
  1887.             TaskCollapse(gdbP, gActualTask);
  1888.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1889.             break;
  1890.         case MenuMainPreferences:
  1891.             FrmPopupForm(FrmProjectProperties);
  1892.             break;
  1893.         case MenuMainDisplayPreferences:
  1894.             FrmPopupForm(FrmDisplayProperties);
  1895.             break;
  1896.         case MenuMainFlatFilter:
  1897.             FrmPopupForm(FrmFlatFilter);
  1898.             break;
  1899.         case MenuMainClose:
  1900.             FrmGotoForm(FrmProjectList);
  1901.             CloseDB(gdbP);
  1902.             gActualTask = gLastSelected = 0;
  1903.             break;
  1904.         case MenuMainViewSub:
  1905.             break;
  1906.         case MenuMainViewAll:
  1907.             gParentTask = 0;
  1908.             gRefLevel = 0;
  1909.             // erase the up button
  1910.             CtlHideControl(GetObjectPtr(Btn_Sub_Up));
  1911.             SetFormTitle(frm, gCurrentPrefs.openDBName);
  1912.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1913.             break;
  1914.         case MenuEditCut:
  1915.             if (gActualTask)
  1916.             {
  1917.                 TaskToClipboard(gdbP, gActualTask, true);
  1918.                 TaskRemove(gdbP, gActualTask);
  1919.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1920.             }
  1921.             break;
  1922.         case MenuEditCopy:
  1923.             if (gActualTask)
  1924.             {
  1925.                 TaskToClipboard(gdbP, gActualTask, true);
  1926.             }
  1927.             break;
  1928.         case MenuEditCopyChildren:
  1929.             if (gActualTask && TaskGetHasChild(gdbP, gActualTask))
  1930.             {
  1931.                 TaskToClipboard(gdbP, gActualTask, false);
  1932.             }
  1933.             break;
  1934.         case MenuEditPaste:
  1935.             if (gActualTask || DmNumRecords(gdbP) == 1 ||
  1936.                 !TaskGetHasChild(gdbP, gParentTask))
  1937.             {
  1938.                 if (!gActualTask)
  1939.                 {
  1940.                     TaskFromClipboard(gdbP, gParentTask, true);
  1941.                 }
  1942.                 else
  1943.                 {
  1944.                     TaskFromClipboard(gdbP, gActualTask, false);
  1945.                 }
  1946.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1947.             }
  1948.             break;
  1949.         case MenuEditPasteAsChildren:
  1950.             if (gActualTask)
  1951.             {
  1952.                 TaskFromClipboard(gdbP, gActualTask, true);
  1953.             }
  1954.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1955.             break;
  1956.         case MenuEditAddNote:
  1957.             if (gActualTask)
  1958.             {
  1959.                 FrmPopupForm(FrmNoteEdit);
  1960.             }
  1961.             break;
  1962.         case MenuNewLink:
  1963.             if (gActualTask)
  1964.             {
  1965.                 FrmPopupForm(FrmDirectLink);
  1966.             }
  1967.             else
  1968.             {
  1969.                 MessageBox(StrSelectTask);
  1970.             }
  1971.             break;
  1972.         case MenuMainTaskDefaults:
  1973.             FrmPopupForm(FrmTaskDefaults);
  1974.             break;
  1975.         case MenuProjectListAbout:
  1976.             FrmCustomAlert(ProgectAbout, VERSION, "", "");
  1977.             break;
  1978.         case MenuMainMemoExport:
  1979.             FrmPopupForm(FrmMemoExportProperties);
  1980.             break;
  1981.         case MenuPublishLinkMaster:
  1982.             if (gActualTask > 0)
  1983.                 PublishToLinkMaster(gdbP, gActualTask);
  1984.             break;
  1985.         case MenuLinkViaLinkMaster:
  1986.             if (gActualTask > 0)
  1987.                 RequestLinkViaLinkMaster(gCurrentPrefs.openDBName, gActualTask);
  1988.             break;
  1989.         case MenuRemoveLinkViaLinkMaster:
  1990.             if (gActualTask > 0)
  1991.             {
  1992.                 RemoveLinkViaLinkMaster(gActualTask);
  1993.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  1994.             }
  1995.             break;
  1996.     }
  1997.     return true;
  1998. } // Boolean FrmMainMenuHandleEvent(EventPtr e)
  1999.  
  2000.  
  2001.  
  2002. Boolean FrmMainCtlSelectHandleEvent(EventPtr e)
  2003. {
  2004.     FormPtr frm;
  2005.     
  2006.     frm = FrmGetActiveForm();
  2007.  
  2008.     switch(e->data.ctlSelect.controlID) {
  2009.         case Btn_Left:
  2010.             if (gActualTask)
  2011.             {
  2012.                 TaskToLeft(gdbP, gActualTask);
  2013.                 // TODO verify how to bypass this one
  2014.                 ProjectTableUpdate();
  2015.                 SelectActualTask(true);
  2016.             }
  2017.             break;
  2018.         case Btn_Right:
  2019.             if (gActualTask)
  2020.             {
  2021.                 TaskToRight(gdbP, gActualTask);
  2022.                 SelectActualTask(true);
  2023.             }
  2024.             break;
  2025.         case Btn_Up:
  2026.             if (gActualTask)
  2027.             {
  2028.                 TaskUp(gdbP, gActualTask);
  2029.                 SelectActualTask(true);
  2030.             }
  2031.             break;
  2032.         case Btn_Down:
  2033.             if (gActualTask)
  2034.             {
  2035.                 TaskDown(gdbP, gActualTask);
  2036.                 SelectActualTask(true);
  2037.             }
  2038.             break;
  2039.         case Btn_Sub:
  2040.             // New, be able to see the sub of a terminal task
  2041.             if (gActualTask)
  2042.             {
  2043.                 char* p;
  2044.                 gParentTask = gActualTask;
  2045.                 gRefLevel = TaskGetLevel(gdbP, gParentTask);
  2046.                 Scroll(scrollTop, 0);
  2047.                 gActualTask = 0;
  2048.                 // show the up button
  2049.                 CtlShowControl(GetObjectPtr(Btn_Sub_Up));
  2050.                 // update the titlebar
  2051.                 p = TaskGetDescription(gdbP, gParentTask);
  2052.                 SetFormTitle(frm, p);
  2053.                 MemPtrFree(p);
  2054.                 if (TaskGetHasChild(gdbP, gParentTask))
  2055.                 {
  2056.                     gActualTask = gParentTask + 1;
  2057.                     SelectActualTask(true);
  2058.                 }
  2059.             }
  2060.             break;
  2061.         case Btn_Sub_Up:
  2062.             TblSetItemInt(gTable, 0, 0, gParentTask);
  2063.             gParentTask = TaskGetFatherIndex(gdbP, gParentTask);
  2064.             if (!gParentTask)
  2065.             {
  2066.                 gRefLevel = 0;
  2067.             }
  2068.             else
  2069.             {
  2070.                 gRefLevel = TaskGetLevel(gdbP, gParentTask);
  2071.             }
  2072.  
  2073.             //this is done by the next update
  2074.             //if (gActualTask)
  2075.             //{
  2076.                 //ProjectTableUpdate();
  2077.                 //SelectActualTask(false);
  2078.             //}
  2079.             // if we're at top level
  2080.             if (!gParentTask)
  2081.             {
  2082.                 // erase the up button
  2083.                 CtlHideControl(GetObjectPtr(Btn_Sub_Up));
  2084.                 SetFormTitle(frm, gCurrentPrefs.openDBName);
  2085.             }
  2086.             else
  2087.             {
  2088.                 char* p = TaskGetDescription(gdbP, gParentTask);
  2089.                 SetFormTitle(frm, p);
  2090.                 MemPtrFree(p);
  2091.             }
  2092.             break;
  2093.         case Btn_Done:
  2094.             FrmGotoForm(FrmProjectList);
  2095.             CloseDB(gdbP);
  2096.             gActualTask = gLastSelected = gRefLevel = gParentTask = 0;
  2097.             break;
  2098.         case Btn_Main_Hierarchical:
  2099.             break;
  2100.         case Btn_Main_Flat:
  2101.             FrmGotoForm(FrmFlat);
  2102.             break;
  2103.         default:
  2104.             break;
  2105.     }
  2106.     FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2107.     return true;
  2108. } // Boolean FrmMainCtlSelectHandleEvent(EventPtr e)
  2109.  
  2110.  
  2111.  
  2112. Boolean FrmMainKeyDownHandleEvent(EventPtr e)
  2113. {
  2114.     switch (e->data.keyDown.chr)
  2115.     {
  2116.         case vchrPageDown:
  2117.             Scroll(scrollDown, 5);
  2118.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2119.             break;
  2120.         case vchrPageUp:
  2121.             Scroll(scrollUp, 5);
  2122.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2123.             break;
  2124.         case chrSpace:
  2125.             TaskToRight(gdbP, gActualTask);
  2126.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2127.             break;
  2128.         case chrBackspace:
  2129.             TaskToLeft(gdbP, gActualTask);
  2130.             SelectActualTask(true);
  2131.             FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2132.             break;
  2133.         case chrLeftArrow:
  2134.             if (gActualTask)
  2135.             {
  2136.                 TaskUp(gdbP, gActualTask);
  2137.                 SelectActualTask(true);
  2138.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2139.             }
  2140.             break;
  2141.         case chrRightArrow:
  2142.             if (gActualTask)
  2143.             {
  2144.                 TaskDown(gdbP, gActualTask);
  2145.                 SelectActualTask(true);
  2146.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2147.             }
  2148.             break;
  2149.         case chrUpArrow:
  2150.             if (gActualTask > gParentTask + 1)
  2151.             {
  2152.                 UInt16 prev = gActualTask - 1;
  2153.                 while (prev > gParentTask && !TaskIsVisible(gdbP, prev))
  2154.                     prev--;
  2155.                 if (prev > gParentTask)
  2156.                 {
  2157.                     gActualTask = prev;
  2158.                     SelectActualTask(true);
  2159.                     FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2160.                 }
  2161.             }
  2162.             break;
  2163.         case chrDownArrow:
  2164.             if ((gActualTask + 1 < DmNumRecords(gdbP)) &&
  2165.                 TaskGetLevel(gdbP, gActualTask + 1) > gRefLevel)
  2166.             {
  2167.                 UInt16 next = gActualTask + 1, numRec = DmNumRecords(gdbP);
  2168.                 while (next < numRec && !TaskIsVisible(gdbP, next))
  2169.                     next++;
  2170.                 if (next < numRec)
  2171.                 {
  2172.                     gActualTask = next;
  2173.                     SelectActualTask(true);
  2174.                     FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2175.                 }
  2176.             }
  2177.             break;
  2178.         case chrPlusSign:
  2179.             if (gActualTask)
  2180.             {
  2181.                 TaskSetOpened(gdbP, gActualTask, true);
  2182.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2183.             }
  2184.             break;
  2185.         case chrHyphenMinus:
  2186.             if (gActualTask && TaskGetHasChild(gdbP, gActualTask))
  2187.             {
  2188.                 TaskSetOpened(gdbP, gActualTask, false);
  2189.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2190.             }
  2191.             break;
  2192.         default:
  2193.             // keyDown is alnum, then create a new task
  2194.             if (TxtGlueCharIsAlNum(e->data.keyDown.chr))
  2195.             {
  2196.                 if (gActualTask || DmNumRecords(gdbP) == 1 ||
  2197.                     !TaskGetHasChild(gdbP, gParentTask))
  2198.                 {
  2199.                     TaskType NewTask = gEmptyTask;
  2200.                     Char firstChar[2];
  2201.                     firstChar[0] = 
  2202.                         (Char)TxtGlueUpperChar(e->data.keyDown.chr);
  2203.                     firstChar[1] = '\0';
  2204.                     NewTask.description = firstChar;
  2205.  
  2206.                     // special case when there's no existing task
  2207.                     if (DmNumRecords(gdbP) == 1 || 
  2208.                         !TaskGetHasChild(gdbP, gParentTask))
  2209.                     {
  2210.                         gActualTask = gParentTask;
  2211.                     }
  2212.                     AddRecord(gdbP, &NewTask, &gActualTask);
  2213.  
  2214.                     // recalc fathers progressbar
  2215.                     if (TaskGetLevel(gdbP, gActualTask) > 1)
  2216.                     {
  2217.                         TaskCalcCompleted(gdbP, 
  2218.                             TaskGetFatherIndex(gdbP, gActualTask));
  2219.                     }
  2220.                     FrmPopupForm(FrmTaskEdit);
  2221.                     SelectActualTask(true);
  2222.                     FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2223.                 }
  2224.             }
  2225.             // keydown is tab or return, create a new subtask 
  2226.             // (space is treaded already)
  2227.             if (TxtGlueCharIsSpace(e->data.keyDown.chr))
  2228.             {
  2229.                 if (gActualTask)
  2230.                 {
  2231.                     if (e->data.keyDown.chr == chrCarriageReturn ||
  2232.                         e->data.keyDown.chr == chrLineFeed)
  2233.                     {
  2234.                         AddRecordSub(gdbP, &gEmptyTask, &gActualTask);
  2235.                         // recalc fathers progressbar
  2236.                         if (TaskGetLevel(gdbP, gActualTask) > 1)
  2237.                         {
  2238.                             TaskCalcCompleted(gdbP, 
  2239.                                 TaskGetFatherIndex(gdbP, gActualTask));
  2240.                         }
  2241.                         FrmPopupForm(FrmTaskEdit);
  2242.                         SelectActualTask(true);
  2243.                         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2244.                     } 
  2245.                     else if (e->data.keyDown.chr == chrHorizontalTabulation)
  2246.                     {
  2247.                         // edit the task (keyboard shortcut)
  2248.                         FrmPopupForm(FrmTaskEdit);
  2249.                         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2250.                     }
  2251.                 }
  2252.             }
  2253.             break;
  2254.     }
  2255.     return true;
  2256. } // Boolean FrmMainKeyDownHandleEvent(EventPtr e)
  2257.  
  2258.  
  2259.  
  2260. static Boolean FrmMainHandleEvent (EventPtr e)
  2261. {
  2262.     Boolean handled = false;
  2263.     FormPtr frm;
  2264.     Int16 x;
  2265.     TaskFormatType format;
  2266.     
  2267.     frm = FrmGetActiveForm();
  2268.     gTable = GetObjectPtr(ProjectTable);
  2269.  
  2270.     switch (e->eType) {
  2271.     case frmUpdateEvent:
  2272.         switch(e->data.frmUpdate.updateCode)
  2273.         {
  2274.             case frmRedrawUpdateCode:
  2275.                 ProjectTableUpdate();
  2276.                 FrmDrawForm(frm);
  2277.                 SelectActualTask(false);
  2278.                 handled = true;
  2279.                 break;
  2280.             default:
  2281.                 break;
  2282.         }
  2283.         break;
  2284.  
  2285.     case frmOpenEvent:
  2286.         gCurrentPrefs.view = normalView;
  2287.         ProjectTableInit();
  2288.         ProjectTableUpdate();
  2289.         SetFormTitle(frm, gCurrentPrefs.openDBName);
  2290.         FrmDrawForm(frm);
  2291.         SelectActualTask(true); // show on screen.
  2292.         gTable = GetObjectPtr(ProjectTable);
  2293.         CtlSetValue(GetObjectPtr(Btn_Main_Hierarchical), true);
  2294.         if (gRefLevel)
  2295.         {
  2296.             Char *p;
  2297.             // show the up button
  2298.             CtlShowControl(GetObjectPtr(Btn_Sub_Up));
  2299.             // update the titlebar
  2300.             p = TaskGetDescription(gdbP, gParentTask);
  2301.             SetFormTitle(frm, p);
  2302.             MemPtrFree(p);
  2303.             if (TaskGetHasChild(gdbP, gParentTask))
  2304.             {
  2305.                 gActualTask = gParentTask + 1;
  2306.                 SelectActualTask(true);
  2307.             }
  2308.         }
  2309.         handled = true;
  2310.         break;
  2311.  
  2312.     case menuEvent:
  2313.         MenuEraseStatus(NULL);
  2314.         handled = FrmMainMenuHandleEvent(e);
  2315.         break;
  2316.  
  2317.     // remember the screen coords
  2318.     case tblEnterEvent:
  2319.         gLastDownX = e->screenX;
  2320.         gLastDownY = e->screenY;
  2321.         // deselect all
  2322.         gActualTask = 0;
  2323.         break;
  2324.  
  2325.     case ctlSelectEvent:
  2326.         handled = FrmMainCtlSelectHandleEvent(e);
  2327.         break;
  2328.  
  2329.     case ctlRepeatEvent:
  2330.         switch (e->data.ctlRepeat.controlID)
  2331.         {
  2332.             case Btn_Scroll_Up:
  2333.                 Scroll(scrollUp, 1);
  2334.                 break;
  2335.             case Btn_Scroll_Down:
  2336.                 Scroll(scrollDown, 1);
  2337.                 break;
  2338.             default:
  2339.                 break;
  2340.         }
  2341.         // not handled, or I don't get the repeated event
  2342.         //handled = true;
  2343. //        FrmUpdateForm(FrmMain, wUpdateCode);
  2344.         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2345.         break;
  2346.  
  2347.     case tblSelectEvent:
  2348.         gActualTask = TblGetItemInt(gTable, e->data.tblSelect.row, 0);
  2349.         if (gActualTask == -1)
  2350.             gActualTask = 0;
  2351.  
  2352.         format = TaskGetFormat(gdbP, gActualTask);
  2353.  
  2354.         x = gLastDownX / 11 + 1 - TaskGetLevel(gdbP, gActualTask) + gRefLevel;
  2355.         if (gActualTask) // this is for all the switch
  2356.         switch (x)
  2357.         {
  2358.             case 0:
  2359.                 /**************************************************************
  2360.                  * Code for open buttons
  2361.                  *************************************************************/
  2362.                 TaskToggleIsOpened(gdbP, gActualTask);
  2363.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2364.                 break;
  2365.             case 1:
  2366.                 /**************************************************************
  2367.                  * Code for progress buttons
  2368.                  *************************************************************/
  2369.                  ProgressHandleEvent();
  2370.                  break;
  2371.             default:
  2372.                 //////////////////////////////////////////////////////////////
  2373.                 // Code for note or follow link
  2374.                 //////////////////////////////////////////////////////////////
  2375.                 if (gLastDownX > 153 && format.hasNote)
  2376.                 {
  2377.                     FrmPopupForm(FrmNoteEdit);
  2378.                 }
  2379.                 else if (gLastDownX > (153 - (format.hasNote? 8 : 0))
  2380.                     && format.hasLink)
  2381.                 {
  2382.                     FollowLinkViaLinkMaster(gActualTask);
  2383.                 }
  2384.                 // if a priority is visible
  2385.                 else if (x == 2 && TaskGetPriority(gdbP, gActualTask) != 6 && 
  2386.                     gProjectPrefs.displayPriorities)
  2387.                 {
  2388.                     PriorityHandleEvent(e);
  2389.                 }
  2390.                 // edit text if click on the right side
  2391.                 else if (x > 0)
  2392.                 {
  2393.                     if (gLastSelected == gActualTask)
  2394.                     {
  2395.                         if (format.isMemo || format.isContact)
  2396.                         {
  2397.                             DirectLinkFollow(gdbP, gActualTask);
  2398.                         }
  2399.                         else
  2400.                         {
  2401.                             FrmPopupForm(FrmTaskEdit);
  2402.                         }
  2403.                     }
  2404.                     else
  2405.                     {
  2406.                         gLastSelected = gActualTask;
  2407.                     }
  2408.                 }
  2409.                 else
  2410.                 {
  2411.                     // left part
  2412.                     // nothing to do for now
  2413.                 }
  2414.                 break;
  2415.         }
  2416.         handled = true;
  2417.         break;
  2418.  
  2419.     // TODO : put this '5' in prefs (scroll step)
  2420.     case keyDownEvent:
  2421.         handled = FrmMainKeyDownHandleEvent(e);
  2422.         break;
  2423.  
  2424.     default:
  2425.         break;
  2426.     }
  2427.  
  2428.     return handled;
  2429. } // static Boolean FrmMainHandleEvent (EventPtr e)
  2430.  
  2431.  
  2432.  
  2433. static void UpdateIconButton(void)
  2434. {
  2435.     FormPtr frm = FrmGetActiveForm();
  2436.     UInt16 iconid;
  2437.     UInt16 size = sizeof(iconid);
  2438.     if (!TaskGetExtraChunk(gdbP, gActualTask, Extra_Icon, 0,
  2439.                                   &iconid, &size) &&
  2440.                                   size == sizeof(iconid) &&
  2441.                                   iconid < getNumIconsLoaded() )
  2442.     {
  2443.         Coord x, y;
  2444.         CtlSetLabel(GetObjectPtr(Btn_SelectIcon), "");
  2445.         FrmGetObjectPosition(frm, 
  2446.             FrmGetObjectIndex(frm, Btn_SelectIcon),
  2447.             &x, &y);
  2448.         drawIcon(iconid, x + 10, y + 2);
  2449.     }
  2450.     else
  2451.     {
  2452.         MemHandle h;
  2453.         char* p;
  2454.  
  2455.         h = DmGetResource('tSTR', StrIconButton);
  2456.         p = MemHandleLock(h);
  2457.  
  2458.         CtlSetLabel(GetObjectPtr(Btn_SelectIcon), p);
  2459.  
  2460.         MemHandleUnlock(h);
  2461.         DmReleaseResource(h);
  2462.     }
  2463. }
  2464.  
  2465.  
  2466.  
  2467. static Boolean FrmTaskEditHandleEvent (EventPtr e)
  2468. {
  2469.     Boolean handled = false;
  2470.     FormPtr frm;
  2471.     DateType date;
  2472.     
  2473.     frm = FrmGetActiveForm();
  2474.  
  2475.     switch (e->eType) {
  2476.     case frmOpenEvent:
  2477.         TaskSave(gActualTask);
  2478.         InitFrmTaskEdit();
  2479.         FrmDrawForm(frm);
  2480.         UpdateIconButton();
  2481.         FrmSetFocus(frm, FrmGetObjectIndex(frm, TaskDesc));
  2482.         handled = true;
  2483.         break;
  2484.     
  2485.     case frmCloseEvent:
  2486.         CleanUpFrmTaskEdit();
  2487.         TaskRemoveSaved();
  2488.         // link the todo
  2489.         if (CtlGetValue(GetObjectPtr(Chk_Edit_ToDo_Link)))
  2490.         {
  2491.             TaskPublishToDo(gdbP, gActualTask);
  2492.         }
  2493.         else
  2494.         {
  2495.             TaskRemoveHasToDo(gdbP, gActualTask);
  2496.         }
  2497.         TaskUpdateToDo(gdbP, gActualTask);
  2498.         break;
  2499.  
  2500.     case frmUpdateEvent:
  2501.         switch(e->data.frmUpdate.updateCode)
  2502.         {
  2503.             case frmTaskEditReturnFromIconSelect:
  2504.                 FrmDrawForm(frm);
  2505.                 UpdateIconButton();
  2506.             case frmTaskEditReturnFromNote:
  2507.                 FrmSetFocus(frm, FrmGetObjectIndex(frm, TaskDesc));
  2508.                 handled = true;
  2509.                 break;
  2510.         }
  2511.         break;
  2512.  
  2513.     case menuEvent:
  2514.         handled = EditMenuHandleEvent(e->data.menu.itemID, 
  2515.             GetObjectPtr(TaskDesc));
  2516.         break;
  2517.  
  2518.     case ctlSelectEvent:
  2519.         switch(e->data.ctlSelect.controlID) {
  2520.             case Pop_Due_Date:
  2521.                 switch (LstPopupList(GetObjectPtr(Lst_Date)))
  2522.                 {
  2523.                     case 0: // today
  2524.                         TaskSetDueDate(gdbP, gActualTask, gToday);
  2525.                         break;
  2526.                     case 1: // tomorrow
  2527.                         date = gToday;
  2528.                         DateAdjust(&date, 1);
  2529.                         TaskSetDueDate(gdbP, gActualTask, date);
  2530.                         break;
  2531.                     case 2: // in one week
  2532.                         date = gToday;
  2533.                         DateAdjust(&date, 7);
  2534.                         TaskSetDueDate(gdbP, gActualTask, date);
  2535.                         break;
  2536.                     case 3: // no date
  2537.                         TaskSetDueDate(gdbP, gActualTask, gNoDate);
  2538.                         break;
  2539.                     case 4: // choose date
  2540.                         TaskInputDueDate(gdbP, gActualTask);
  2541.                         break;
  2542.                     default:
  2543.                         break;
  2544.                 }
  2545.                 date = TaskGetDueDate(gdbP, gActualTask);
  2546.                 FrmTaskEditUpdateDateTrigger(GetObjectPtr(Pop_Due_Date), date);
  2547.                 handled = true;
  2548.                 break;
  2549.             case Pop_Category:
  2550.                 {
  2551.                     UInt16 attr;
  2552.                     UInt16 categ;
  2553.                     Char* name = (Char*)CtlGetLabel(GetObjectPtr(Pop_Category));
  2554.                     DmRecordInfo(gdbP, gActualTask, &attr, NULL, NULL);
  2555.                     categ = attr & dmRecAttrCategoryMask;
  2556.                     CategorySelect(gdbP, frm, Pop_Category, Lst_Category, false,
  2557.                                    &categ, name,
  2558.                                    1, categoryDefaultEditCategoryString);
  2559.                     attr &= ~dmRecAttrCategoryMask;
  2560.                     attr |= categ & dmRecAttrCategoryMask;
  2561.                     DmSetRecordInfo(gdbP, gActualTask, &attr, NULL);
  2562.                     CtlSetLabel(GetObjectPtr(Pop_Category), name);
  2563.                 }
  2564.                 handled = true;
  2565.                 break;
  2566.  
  2567.             case Btn_Edit_Note:
  2568.                 CleanUpFrmTaskEdit();
  2569.                 FrmPopupForm(FrmNoteEdit);
  2570.                 handled = true;
  2571.                 break;
  2572.  
  2573.             case Btn_Edit_Ok:
  2574.                 CleanUpFrmTaskEdit();
  2575.                 TaskRemoveSaved();
  2576.                 // link the todo
  2577.                 if (CtlGetValue(GetObjectPtr(Chk_Edit_ToDo_Link)))
  2578.                 {
  2579.                     TaskPublishToDo(gdbP, gActualTask);
  2580.                 }
  2581.                 else
  2582.                 {
  2583.                     TaskRemoveHasToDo(gdbP, gActualTask);
  2584.                 }
  2585.                 TaskUpdateToDo(gdbP, gActualTask);
  2586.                 FrmReturnToForm(0);
  2587.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2588.                 handled = true;
  2589.                 break;
  2590.  
  2591.             case Btn_Edit_Cancel:
  2592.                 CleanUpFrmTaskEdit();
  2593.                 TaskGetSaved(gActualTask);
  2594.                 if (TaskGetFormat(gdbP, gActualTask).newTask)
  2595.                 {
  2596.                     TaskRemove(gdbP, gActualTask);
  2597.                 }
  2598.                 FrmReturnToForm(0);
  2599.                 if (! OSCaps.ver35)
  2600.                     FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2601.                 handled = true;
  2602.                 break;
  2603.  
  2604.             case Chk_Edit_Action:
  2605.                 if (CtlGetValue(GetObjectPtr(Chk_Edit_ToDo_Link)))
  2606.                 {
  2607.                     CtlSetValue(GetObjectPtr(Chk_Edit_Action), true);
  2608.                     TaskSetActionState(gdbP, gActualTask, true);
  2609.                 }
  2610.                 else
  2611.                 {
  2612.                     TaskSetActionState(gdbP, gActualTask, 
  2613.                         CtlGetValue(GetObjectPtr(Chk_Edit_Action)));
  2614.                 }
  2615.                 handled = true;
  2616.                 break;
  2617.  
  2618.             case Btn_SelectIcon:
  2619.                 if (getNumIconsLoaded() != 0)
  2620.                 {
  2621.                     CleanUpFrmTaskEdit();
  2622.                     FrmPopupForm(FrmIconSelect);
  2623.                 }
  2624.                 handled = true;
  2625.                 break;
  2626.  
  2627.             case Chk_Edit_ToDo_Link:
  2628.                 // real job is done by OK button
  2629.                 CtlSetValue(GetObjectPtr(Chk_Edit_Action), true);
  2630.                 TaskSetActionState(gdbP, gActualTask, true);
  2631.                 handled = true;
  2632.                 break;
  2633.  
  2634.             case Btn_Priority_1:
  2635.             case Btn_Priority_2:
  2636.             case Btn_Priority_3:
  2637.             case Btn_Priority_4:
  2638.             case Btn_Priority_5:
  2639.             case Btn_Priority_No:
  2640.                 TaskSetPriority(gdbP, gActualTask, e->data.ctlSelect.controlID - Btn_Priority_X + 1);
  2641.                 handled = true;
  2642.  
  2643.             default:
  2644.                 break;
  2645.         }
  2646.         break;
  2647.  
  2648.     case keyDownEvent:
  2649.         switch (e->data.keyDown.chr)
  2650.         {
  2651.             // on return, close form
  2652.             case chrCarriageReturn:
  2653.             case chrLineFeed:
  2654.                 CleanUpFrmTaskEdit();
  2655.                 TaskRemoveSaved();
  2656.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  2657.                 FrmReturnToForm(0);
  2658.                 handled = true;
  2659.                 break;
  2660.             case chrHorizontalTabulation:
  2661.                 {
  2662.                     UInt8 priority;
  2663.                     // get the priority and set it on the form
  2664.                     priority = TaskGetPriority(gdbP, gActualTask);
  2665.                     CtlSetValue(GetObjectPtr(Btn_Priority_X + priority - 1), 
  2666.                         false);
  2667.                     priority++;
  2668.                     if (priority > 6)
  2669.                         priority = 1;
  2670.                     TaskSetPriority(gdbP, gActualTask, priority);
  2671.                     CtlSetValue(GetObjectPtr(Btn_Priority_X + priority - 1), 
  2672.                         true);
  2673.                 }
  2674.                 handled = true;
  2675.                 break;
  2676.             default:
  2677.                 break;
  2678.         }
  2679.         break;
  2680.  
  2681.     default:
  2682.         break;
  2683.     }
  2684.  
  2685.     return handled;
  2686. } // static Boolean FrmTaskEditHandleEvent (EventPtr e)
  2687.  
  2688.  
  2689.  
  2690. static Boolean FrmProjectListHandleEvent (EventPtr e)
  2691. {
  2692.     Boolean handled = false;
  2693.     FormPtr frm;
  2694.     ListPtr listP;
  2695.  
  2696.     static UInt16 nLastSelectedProject = noListSelection;
  2697.  
  2698.     frm = FrmGetActiveForm();
  2699.  
  2700.     switch (e->eType) {
  2701.     case frmUpdateEvent:
  2702.         switch(e->data.frmUpdate.updateCode)
  2703.         {
  2704.             case frmRedrawUpdateCode:
  2705.                 FrmDrawForm(frm);
  2706.                 FrmProjectListInit();
  2707.                 handled = true;
  2708.                 break;
  2709.             default:
  2710.                 break;
  2711.         }
  2712.         break;
  2713.  
  2714.     case frmOpenEvent:
  2715.         LstNewList((void**)&frm, Lst_Project_List, 1, 18, 158, 121, 0, 11, 0);
  2716.         FrmDrawForm(frm);
  2717.         FrmProjectListInit();
  2718.         nLastSelectedProject = LstGetSelection(GetObjectPtr(Lst_Project_List));
  2719.         handled = true;
  2720.         break;
  2721.     
  2722.     case frmCloseEvent:
  2723.         FrmRemoveObject(&frm, FrmGetObjectIndex(frm, Lst_Project_List));
  2724.         // deallocate old lists if necessary
  2725.         if (namesData)
  2726.         {
  2727.             MemPtrFree(namesData);
  2728.             namesData = NULL;
  2729.         }
  2730.         if (names)
  2731.         {
  2732.             MemPtrFree(names);
  2733.             names = NULL;
  2734.         }
  2735.         // handled = true ??
  2736.         break;
  2737.  
  2738.     case menuEvent:
  2739.         MenuEraseStatus(NULL);
  2740.  
  2741.         switch(e->data.menu.itemID) {
  2742.             case MenuProjectListAbout:
  2743.                 FrmCustomAlert(ProgectAbout, VERSION, "", "");
  2744.                 break;
  2745.             case MenuProjectListDuplicate:
  2746.                 listP = GetObjectPtr(Lst_Project_List);
  2747.                 // if we have a selection
  2748.                 if (LstGetSelection(listP) != noListSelection)
  2749.                 {
  2750.                     ChooseNameFunction = ChooseNameDuplicate;
  2751.                     FrmPopupForm(FrmChooseName);
  2752.                 }
  2753.                 else
  2754.                 {
  2755.                     DEBUG1("Please select a project to duplicate first");
  2756.                 }
  2757.                 break;
  2758.         }
  2759.         handled = true;
  2760.         break;
  2761.  
  2762.     case ctlSelectEvent:
  2763.         switch(e->data.ctlSelect.controlID) {
  2764.             case Btn_List_Open:
  2765.                 listP = GetObjectPtr(Lst_Project_List);
  2766.                 // if we have a selection
  2767.                 if (listP && LstGetSelection(listP) != noListSelection)
  2768.                 {
  2769.                     OpenDB(LstGetSelectionText(listP, LstGetSelection(listP)), &gdbP);
  2770.                     FrmGotoForm(FrmMain);
  2771.                 }
  2772.                 handled = true;
  2773.                 break;
  2774.             case Btn_List_New:
  2775.                 ChooseNameFunction = ChooseNameCreate;
  2776.                 FrmPopupForm(FrmChooseName);
  2777.                 handled = true;
  2778.                 break;
  2779.             case Btn_List_Del:
  2780.                 listP = GetObjectPtr(Lst_Project_List);
  2781.                 // if we have a selection
  2782.                 if (LstGetSelection(listP) != noListSelection)
  2783.                 {
  2784.                     if (FrmCustomAlert(
  2785.                         AltConfirmDelete, LstGetSelectionText(listP, LstGetSelection(listP)), "", "") == 0)
  2786.                     {
  2787.                         RemoveDB(LstGetSelectionText(listP, LstGetSelection(listP)));
  2788.                         FrmUpdateForm(FrmProjectList, frmRedrawUpdateCode);
  2789.                     }
  2790.                 }
  2791.                 handled = true;
  2792.                 break;
  2793.             case Btn_List_Rename:
  2794.                 listP = GetObjectPtr(Lst_Project_List);
  2795.                 // if we have a selection
  2796.                 if (LstGetSelection(listP) != noListSelection)
  2797.                 {
  2798.                     ChooseNameFunction = ChooseNameRename;
  2799.                     gCurrentSelection = LstGetSelection(listP);
  2800.                     FrmPopupForm(FrmChooseName);
  2801.                 }
  2802.                 handled = true;
  2803.             default:
  2804.                 break;
  2805.         }
  2806.         break;
  2807.  
  2808.     case lstSelectEvent:
  2809.         if (nLastSelectedProject == e->data.lstSelect.selection
  2810.             && e->data.lstSelect.selection != noListSelection)
  2811.         {
  2812.             OpenDB(LstGetSelectionText(e->data.lstSelect.pList, e->data.lstSelect.selection), &gdbP);
  2813.             FrmGotoForm(FrmMain);
  2814.             return true;
  2815.         }
  2816.         nLastSelectedProject = e->data.lstSelect.selection;
  2817.         break;
  2818.  
  2819.     case keyDownEvent:
  2820.         switch (e->data.keyDown.chr)
  2821.         {
  2822.             default:
  2823.                 break;
  2824.         }
  2825.         break;
  2826.  
  2827.     default:
  2828.         break;
  2829.     }
  2830.  
  2831.     return handled;
  2832. } // static Boolean FrmProjectListHandleEvent (EventPtr e)
  2833.  
  2834.  
  2835.  
  2836. Boolean HandleChooseNameButtonOK(void)
  2837. {
  2838.     FormPtr frm;
  2839.     Char DBName[dmDBNameLength];
  2840.     Err err;
  2841.     Boolean handled = false;
  2842.     FieldPtr fldPtr = GetObjectPtr(Fld_Project_Name);
  2843.     Char *name = FldGetTextPtr(fldPtr);
  2844.     
  2845.     frm = FrmGetActiveForm();
  2846.  
  2847.     if (FldDirty(fldPtr)) {
  2848.         switch (ChooseNameFunction)
  2849.         {
  2850.             case ChooseNameCreate:
  2851.                 if (*name) {
  2852.                     UInt16 attr;
  2853.                     StrNCopy(DBName, name, dmDBNameLength);
  2854.                     err = CreateDB(DBName);
  2855.                     if (err) {
  2856.                         FrmCustomAlert(AltAlreadyExists, name, NULL, NULL);
  2857.                         FldSetSelection(fldPtr, 0, StrLen(name));
  2858.                         break;
  2859.                     }
  2860.                     // to get gdbID (without manually prepending)
  2861.                     OpenDB(DBName, &gdbP); 
  2862.                     // Backup by default
  2863.                     DmDatabaseInfo(0, gdbID, NULL, &attr, NULL, NULL, NULL, 
  2864.                         NULL, NULL, NULL, NULL, NULL, NULL);
  2865.                     attr = attr | dmHdrAttrBackup;
  2866.                     DmSetDatabaseInfo(0, gdbID, NULL, &attr, NULL, NULL, NULL, 
  2867.                         NULL, NULL, NULL, NULL, NULL, NULL);
  2868.                     CloseDB(gdbP);
  2869.                 } else
  2870.                     break;
  2871.                 FrmReturnToForm(FrmProjectList);
  2872.                 FrmUpdateForm(FrmProjectList, frmRedrawUpdateCode);
  2873.                 handled = true;
  2874.                 break;
  2875.             case ChooseNameRename:
  2876.                 if (*name)
  2877.                 {
  2878.                     FormPtr listFrm = FrmGetFormPtr(FrmProjectList);
  2879.                     ListPtr listP = FrmGetObjectPtr(listFrm, 
  2880.                         FrmGetObjectIndex(listFrm, Lst_Project_List));
  2881.  
  2882.                     StrNCopy(DBName, name, dmDBNameLength);
  2883.                     err = RenameDB(LstGetSelectionText(listP, 
  2884.                         LstGetSelection(listP)), DBName);
  2885.                     if (err) {
  2886.                         FrmCustomAlert(AltAlreadyExists, name, NULL, NULL);
  2887.                         FldSetSelection(fldPtr, 0, StrLen(name));
  2888.                         break;
  2889.                     }
  2890.                 } else
  2891.                     break;
  2892.                 FrmReturnToForm(FrmProjectList);
  2893.                 FrmUpdateForm(FrmProjectList, frmRedrawUpdateCode);
  2894.                 handled = true;
  2895.                 break;
  2896.             case ChooseNameDuplicate:
  2897.                 if (*name)
  2898.                 {
  2899.                     Char srcName[32];
  2900.                     FormPtr listFrm = FrmGetFormPtr(FrmProjectList);
  2901.                     ListPtr listP = FrmGetObjectPtr(listFrm, 
  2902.                         FrmGetObjectIndex(listFrm, Lst_Project_List));
  2903.  
  2904.                     StrNCopy(DBName, name, dmDBNameLength);
  2905.                     StrCopy(srcName, 
  2906.                         LstGetSelectionText(listP, LstGetSelection(listP)));
  2907.                     err = DuplicateDB(srcName, DBName);
  2908.                     if (err) {
  2909.                         FrmCustomAlert(AltAlreadyExists, name, NULL, NULL);
  2910.                         FldSetSelection(fldPtr, 0, StrLen(name));
  2911.                         break;
  2912.                     }
  2913.                 } else
  2914.                     break;
  2915.                 FrmReturnToForm(FrmProjectList);
  2916.                 FrmUpdateForm(FrmProjectList, frmRedrawUpdateCode);
  2917.                 handled = true;
  2918.                 break;
  2919.             default:
  2920.                 break;
  2921.         }
  2922.     }
  2923.  
  2924.     if (ChooseNameFunction == ChooseNameDoc)
  2925.     {
  2926.         if (*name)
  2927.         {
  2928.             switch (SelectRange())
  2929.             {
  2930.                 case Btn_Sub_All:
  2931.                     ExportToDoc(0, name, 
  2932.                         1, DmNumRecords(gdbP) - 1);
  2933.                     break;
  2934.                 case Btn_Sub_Sub:
  2935.                     ExportToDoc(0, name,
  2936.                         gParentTask, GetLastInSub(gParentTask));
  2937.                     break;
  2938.                 default:
  2939.                     break;
  2940.             }
  2941.         }
  2942.         handled = true;
  2943.         FrmReturnToForm(0);
  2944.     }
  2945.     return handled;
  2946. } // void HandleCreateNewButtonOK(void)
  2947.  
  2948.  
  2949.  
  2950. static Boolean FrmChooseNameHandleEvent (EventPtr e)
  2951. {
  2952.     Boolean handled = false;
  2953.     FormPtr frm;
  2954.     
  2955.     frm = FrmGetActiveForm();
  2956.  
  2957.     switch (e->eType) {
  2958.     case frmOpenEvent:
  2959.         if (ChooseNameFunction == ChooseNameRename)
  2960.         {
  2961.             FieldPtr fldPtr = GetObjectPtr(Fld_Project_Name);
  2962.             FldSetSelection(fldPtr, 0, 0);
  2963.             FldInsert(fldPtr, names[gCurrentSelection], 
  2964.                 StrLen(names[gCurrentSelection]));
  2965.             FldSetSelection(fldPtr, 0, StrLen(names[gCurrentSelection]));
  2966.             FldSetDirty(fldPtr, false);
  2967.         }
  2968.         if (ChooseNameFunction == ChooseNameDoc) 
  2969.         {
  2970.             FieldPtr fldPtr = GetObjectPtr(Fld_Project_Name);
  2971.             FldSetSelection(fldPtr, 0, 0);
  2972.             FldInsert(fldPtr, gCurrentPrefs.openDBName + 5, 
  2973.                 StrLen(gCurrentPrefs.openDBName + 5));
  2974.             FldSetSelection(fldPtr, 0, StrLen(gCurrentPrefs.openDBName + 5));
  2975.             FldSetDirty(fldPtr, false);
  2976.         }
  2977.         FrmDrawForm(frm);
  2978.         FrmSetFocus(frm, FrmGetObjectIndex(frm, Fld_Project_Name));
  2979.         handled = true;
  2980.         break;
  2981.     
  2982.     case frmCloseEvent:
  2983.         // handled = true ??
  2984.         break;
  2985.  
  2986.     case menuEvent:
  2987.         handled = true;
  2988.         break;
  2989.  
  2990.     case ctlSelectEvent:
  2991.         switch(e->data.ctlSelect.controlID) {
  2992.             case Btn_Choose_Name_Ok:
  2993.                 handled = HandleChooseNameButtonOK();
  2994.                 break;
  2995.             case Btn_Choose_Name_Cancel:
  2996.                 FrmReturnToForm(0);
  2997.                 handled = true;
  2998.                 break;
  2999.             default:
  3000.                 break;
  3001.         }
  3002.         break;
  3003.  
  3004.     case keyDownEvent:
  3005.         switch (e->data.keyDown.chr)
  3006.         {
  3007.             case chrCarriageReturn:
  3008.             case chrLineFeed:
  3009.                 HandleChooseNameButtonOK();
  3010.                 handled = true;
  3011.                 break;
  3012.             default:
  3013.                 break;
  3014.         }
  3015.         break;
  3016.  
  3017.     default:
  3018.         break;
  3019.     }
  3020.  
  3021.     return handled;
  3022. } // static Boolean FrmChooseNameHandleEvent (EventPtr e)
  3023.  
  3024.  
  3025.  
  3026. static Boolean FrmFlatFilterHandleEvent (EventPtr e)
  3027. {
  3028.     Boolean handled = false;
  3029.     FormPtr frm;
  3030.     Int16 TInt16;
  3031.     ListPtr listP = NULL;
  3032.     
  3033.     frm = FrmGetActiveForm();
  3034.  
  3035.     switch (e->eType) {
  3036.     case frmOpenEvent:
  3037.         // set the controls based on the actual prefs
  3038.         CtlSetValue(GetObjectPtr(Chk_Flat_Hide), 
  3039.             gProjectPrefs.flatHideDone);
  3040.         CtlSetValue(GetObjectPtr(Btn_No_Date + gProjectPrefs.flatDated), true);
  3041.         CtlSetValue(GetObjectPtr(Btn_Min + !gProjectPrefs.flatMin), true);
  3042.         CtlSetValue(GetObjectPtr(
  3043.             Btn_Priority_X + gProjectPrefs.flatMinPriority - 1)
  3044.             , true);
  3045.         CtlSetValue(GetObjectPtr(Btn_And + gProjectPrefs.flatOr), true);
  3046.         CtlSetValue(GetObjectPtr(Btn_No_Sort + gProjectPrefs.flatSorted), true);
  3047.  
  3048.         LstSetSelection(GetObjectPtr(List_DaysToBold), 
  3049.             gProjectPrefs.flatDateLimit);
  3050.  
  3051.         CtlSetLabel(GetObjectPtr(Pop_DaysToBold),
  3052.             LstGetSelectionText(GetObjectPtr(List_DaysToBold),
  3053.             gProjectPrefs.flatDateLimit) );
  3054.  
  3055.         FrmDrawForm(frm);
  3056.         handled = true;
  3057.         break;
  3058.     
  3059.     case frmCloseEvent:
  3060.         // handled = true ??
  3061.         break;
  3062.  
  3063.     case menuEvent:
  3064.         handled = true;
  3065.         break;
  3066.  
  3067.     case ctlSelectEvent:
  3068.         switch(e->data.ctlSelect.controlID) {
  3069.             case Pop_DaysToBold:
  3070.                 listP = GetObjectPtr(e->data.ctlSelect.controlID + 1);
  3071.                 TInt16 = LstPopupList(listP);
  3072.                 if (TInt16 != -1)
  3073.                 {
  3074.                     CtlSetLabel(GetObjectPtr(e->data.ctlSelect.controlID),
  3075.                         LstGetSelectionText(listP, TInt16));
  3076.                 }
  3077.                 handled = true;
  3078.                 break;
  3079.                 
  3080.             case Btn_Prop_Ok:
  3081.                 // modify the prefs
  3082.                 gProjectPrefs.flatHideDone = 
  3083.                     CtlGetValue(GetObjectPtr(Chk_Flat_Hide));
  3084.                 gProjectPrefs.flatDated = 
  3085.                     FrmGetObjectId(frm, FrmGetControlGroupSelection(frm, 3)) -
  3086.                     Btn_No_Date;
  3087.  
  3088.                 gProjectPrefs.flatMinPriority =
  3089.                     FrmGetObjectId(frm, FrmGetControlGroupSelection(frm, 1)) -
  3090.                     Btn_Priority_X + 1;
  3091.  
  3092.                 gProjectPrefs.flatOr =
  3093.                     FrmGetObjectId(frm, FrmGetControlGroupSelection(frm, 2)) -
  3094.                     Btn_And;
  3095.  
  3096.                 gProjectPrefs.flatMin =
  3097.                     !(FrmGetObjectId(frm, FrmGetControlGroupSelection(frm, 4)) -
  3098.                     Btn_Min);
  3099.  
  3100.                 gProjectPrefs.flatSorted =
  3101.                     FrmGetObjectId(frm, FrmGetControlGroupSelection(frm, 5)) -
  3102.                     Btn_No_Sort;
  3103.  
  3104.                 gProjectPrefs.flatDateLimit = 
  3105.                     LstGetSelection(GetObjectPtr(List_DaysToBold));
  3106.  
  3107.                 if (gCurrentPrefs.view == flatView)
  3108.                 {
  3109.                     // reconstruct the list
  3110.                     FlatCreateList(gdbP);
  3111.                     FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  3112.                 }
  3113.                 // fall through
  3114.             case Btn_Prop_Cancel:
  3115.                 // return to caller without modifying the prefs
  3116.                 FrmReturnToForm(0);
  3117.                 handled = true;
  3118.                 break;
  3119.             default:
  3120.                 break;
  3121.         }
  3122.         break;
  3123.  
  3124.     case keyDownEvent:
  3125.         break;
  3126.  
  3127.     default:
  3128.         break;
  3129.     }
  3130.  
  3131.     return handled;
  3132. } // static Boolean FrmFlatFilterHandleEvent (EventPtr e)
  3133.  
  3134.  
  3135.  
  3136. static Boolean FrmDirectLinkHandleEvent (EventPtr e)
  3137. {
  3138.     Boolean handled = false;
  3139.     FormPtr frm;
  3140.     //ListPtr listP;
  3141.     
  3142.     frm = FrmGetActiveForm();
  3143.  
  3144.     switch (e->eType) {
  3145.     case frmOpenEvent:
  3146.         FrmDrawForm(frm);
  3147.         LstDrawList(GetObjectPtr(Lst_Link_Type));
  3148.         CtlSetLabel(GetObjectPtr(Sel_Link_To), "---");
  3149.         handled = true;
  3150.         break;
  3151.     
  3152.     case frmCloseEvent:
  3153.         break;
  3154.  
  3155.     case frmUpdateEvent:
  3156.         switch(e->data.frmUpdate.updateCode)
  3157.         {
  3158.             default:
  3159.                 break;
  3160.         }
  3161.         break;
  3162.  
  3163.     case ctlSelectEvent:
  3164.         switch(e->data.ctlSelect.controlID) {
  3165.             case Sel_Link_To:
  3166.                 switch(LstGetSelection(GetObjectPtr(Lst_Link_Type)))
  3167.                 {
  3168.                     case 0:
  3169.                         LinkCreateLinkTree(gdbP, memoLink);
  3170.                         break;
  3171.                     case 1:
  3172.                         LinkCreateLinkTree(gdbP, addressLink);
  3173.                         break;
  3174.                     case 2:
  3175.                         DEBUG1("Not implemented yet");
  3176.                         break;
  3177.                 }
  3178.                 handled = true;
  3179.                 break;
  3180.  
  3181.             case Btn_Ok:
  3182.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  3183.                 // fall down
  3184.             case Btn_Cancel:
  3185.                 FrmReturnToForm(0);
  3186.                 handled = true;
  3187.                 break;
  3188.  
  3189.             default:
  3190.                 break;
  3191.         }
  3192.         break;
  3193.  
  3194.     case keyDownEvent:
  3195.         switch (e->data.keyDown.chr)
  3196.         {
  3197.             // on return, close form
  3198.             case chrCarriageReturn:
  3199.             case chrLineFeed:
  3200.                 FrmReturnToForm(0);
  3201.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  3202.                 handled = true;
  3203.                 break;
  3204.             default:
  3205.                 break;
  3206.         }
  3207.         break;
  3208.  
  3209.     default:
  3210.         break;
  3211.     }
  3212.  
  3213.     return handled;
  3214. } // static Boolean FrmDirectLinkHandleEvent (EventPtr e)
  3215.  
  3216.  
  3217.  
  3218. static Boolean FrmProjectPropertiesHandleEvent (EventPtr e)
  3219. {
  3220.     Boolean handled = false;
  3221.     FormPtr frm;
  3222.     UInt16 attr;
  3223.     
  3224.     frm = FrmGetActiveForm();
  3225.  
  3226.     switch (e->eType) {
  3227.     case frmOpenEvent:
  3228.         // set the controls based on the actual prefs
  3229.         CtlSetValue(GetObjectPtr(Chk_Prop_Hide), 
  3230.             gProjectPrefs.hideDoneTasks);
  3231.         CtlSetValue(GetObjectPtr(Chk_Prop_Display_Due_Dates),     
  3232.             gProjectPrefs.displayDueDates);
  3233.         CtlSetValue(GetObjectPtr(Chk_Prop_Display_Priorities), 
  3234.             gProjectPrefs.displayPriorities);
  3235.         CtlSetValue(GetObjectPtr(Chk_Prop_Display_Year), 
  3236.             gProjectPrefs.displayYear);
  3237.         CtlSetValue(GetObjectPtr(Chk_Prop_Delete_Warn), 
  3238.             gSavedPrefs.deleteWarn);
  3239.         CtlSetValue(GetObjectPtr(Chk_Prop_Father_Status), 
  3240.             gProjectPrefs.useFatherStatus);
  3241.         CtlSetValue(GetObjectPtr(Chk_Prop_Auto_Sync_ToDo), 
  3242.             gProjectPrefs.autoSyncToDo);
  3243.         CtlSetValue(GetObjectPtr(Chk_Prop_Comp_Date), 
  3244.             gProjectPrefs.completionDate);
  3245.         // read database attr
  3246.         DmDatabaseInfo(0, gdbID, NULL, &attr, NULL, NULL, NULL, NULL, NULL, 
  3247.             NULL, NULL, NULL, NULL);
  3248.         CtlSetValue(GetObjectPtr(Chk_Prop_Save_DB), attr & dmHdrAttrBackup);
  3249.         FrmDrawForm(frm);
  3250.         handled = true;
  3251.         break;
  3252.     
  3253.     case frmCloseEvent:
  3254.         // handled = true ??
  3255.         break;
  3256.  
  3257.     case menuEvent:
  3258.         handled = true;
  3259.         break;
  3260.  
  3261.     case ctlSelectEvent:
  3262.         switch(e->data.ctlSelect.controlID) {
  3263.             case Btn_Prop_Ok:
  3264.                 // modify the prefs
  3265.                 gProjectPrefs.hideDoneTasks = 
  3266.                     CtlGetValue(GetObjectPtr(Chk_Prop_Hide));
  3267.                 gProjectPrefs.displayDueDates = 
  3268.                     CtlGetValue(GetObjectPtr(Chk_Prop_Display_Due_Dates));
  3269.                 gProjectPrefs.displayPriorities = 
  3270.                     CtlGetValue(GetObjectPtr(Chk_Prop_Display_Priorities));
  3271.                 gProjectPrefs.displayYear = 
  3272.                     CtlGetValue(GetObjectPtr(Chk_Prop_Display_Year));
  3273.                 gProjectPrefs.useFatherStatus = 
  3274.                     CtlGetValue(GetObjectPtr(Chk_Prop_Father_Status));
  3275.                 gProjectPrefs.autoSyncToDo = 
  3276.                     CtlGetValue(GetObjectPtr(Chk_Prop_Auto_Sync_ToDo));
  3277.                 gSavedPrefs.deleteWarn = 
  3278.                     CtlGetValue(GetObjectPtr(Chk_Prop_Delete_Warn));
  3279.                 gProjectPrefs.completionDate = 
  3280.                     CtlGetValue(GetObjectPtr(Chk_Prop_Comp_Date));
  3281.                 // read database attr
  3282.                 DmDatabaseInfo(0, gdbID, NULL, &attr, NULL, NULL, NULL, NULL, 
  3283.                     NULL, NULL, NULL, NULL, NULL);
  3284.                 attr = attr | CtlGetValue(GetObjectPtr(Chk_Prop_Save_DB)) ? 
  3285.                     dmHdrAttrBackup : 0;
  3286.                 DmSetDatabaseInfo(0, gdbID, NULL, &attr, NULL, NULL, NULL, 
  3287.                     NULL, NULL, NULL, NULL, NULL, NULL);
  3288.                 // return to caller
  3289.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  3290.                 // fall through
  3291.             case Btn_Prop_Cancel:
  3292.                 // return to caller without modifying the prefs
  3293.                 FrmReturnToForm(0);
  3294.                 handled = true;
  3295.                 break;
  3296.             default:
  3297.                 break;
  3298.         }
  3299.         break;
  3300.  
  3301.     case keyDownEvent:
  3302.         break;
  3303.  
  3304.     default:
  3305.         break;
  3306.     }
  3307.  
  3308.     return handled;
  3309. } // static Boolean FrmProjectPropertiesHandleEvent (EventPtr e)
  3310.  
  3311.  
  3312.  
  3313. static Boolean FrmMemoExportPropertiesHandleEvent (EventPtr e)
  3314. {
  3315.     Boolean handled = false;
  3316.     FormPtr frm;
  3317.     
  3318.     frm = FrmGetActiveForm();
  3319.  
  3320.     switch (e->eType) {
  3321.     case frmOpenEvent:
  3322.         // set the controls based on the actual prefs
  3323.         CtlSetValue(GetObjectPtr(Chk_Exp_Done), 
  3324.             gMemoExportPrefs.exportDone);
  3325.         CtlSetValue(GetObjectPtr(Chk_Exp_Due_Dates),     
  3326.             gMemoExportPrefs.exportDueDate);
  3327.         CtlSetValue(GetObjectPtr(Chk_Exp_Priorities), 
  3328.             gMemoExportPrefs.exportPriority);
  3329.         CtlSetValue(GetObjectPtr(Chk_Exp_Progress), 
  3330.             gMemoExportPrefs.exportProgress);
  3331.         CtlSetValue(GetObjectPtr(Chk_Exp_Note), 
  3332.             gMemoExportPrefs.exportNote);
  3333.         CtlSetValue(GetObjectPtr(Chk_Exp_Flat), 
  3334.             gMemoExportPrefs.exportFlat);
  3335.         FrmDrawForm(frm);
  3336.         handled = true;
  3337.         break;
  3338.     
  3339.     case frmCloseEvent:
  3340.         // handled = true ??
  3341.         break;
  3342.  
  3343.     case menuEvent:
  3344.         handled = true;
  3345.         break;
  3346.  
  3347.     case ctlSelectEvent:
  3348.         switch(e->data.ctlSelect.controlID) {
  3349.             case Btn_ToMemo:
  3350.             case Btn_ToDoc:
  3351.                 // modify the prefs
  3352.                 gMemoExportPrefs.exportDone = 
  3353.                     CtlGetValue(GetObjectPtr(Chk_Exp_Done));
  3354.                 gMemoExportPrefs.exportDueDate = 
  3355.                     CtlGetValue(GetObjectPtr(Chk_Exp_Due_Dates));
  3356.                 gMemoExportPrefs.exportPriority = 
  3357.                     CtlGetValue(GetObjectPtr(Chk_Exp_Priorities));
  3358.                 gMemoExportPrefs.exportProgress = 
  3359.                     CtlGetValue(GetObjectPtr(Chk_Exp_Progress));
  3360.                 gMemoExportPrefs.exportNote = 
  3361.                     CtlGetValue(GetObjectPtr(Chk_Exp_Note));
  3362.                 gMemoExportPrefs.exportFlat = 
  3363.                     CtlGetValue(GetObjectPtr(Chk_Exp_Flat));
  3364.  
  3365.                 if (e->data.ctlSelect.controlID == Btn_ToMemo)
  3366.                 {
  3367.                     if (ExportToMemo(gdbP, gMemoExportPrefs))
  3368.                         DEBUG1("Problem during export");
  3369.                     else
  3370.                         DEBUG1("Ok");
  3371.                 }
  3372.                 else
  3373.                 {
  3374.                     ChooseNameFunction = ChooseNameDoc;
  3375.                     FrmPopupForm(FrmChooseName);
  3376.                 }
  3377.  
  3378.                 // fall through
  3379.             case Btn_Cancel:
  3380.                 FrmReturnToForm(0);
  3381.                 handled = true;
  3382.                 break;
  3383.             default:
  3384.                 break;
  3385.         }
  3386.         break;
  3387.  
  3388.     default:
  3389.         break;
  3390.     }
  3391.  
  3392.     return handled;
  3393. } // static Boolean FrmMemoExportPropertiesHandleEvent (EventPtr e)
  3394.  
  3395.  
  3396.  
  3397. static Boolean FrmSetResetHandleEvent (EventPtr e)
  3398. {
  3399.     Boolean handled = false;
  3400.     FormPtr frm;
  3401.     UInt16 first, last, i, idRange;
  3402.     
  3403.     frm = FrmGetActiveForm();
  3404.  
  3405.     switch (e->eType) {
  3406.     case frmOpenEvent:
  3407.         // set the controls based on the actual prefs
  3408.         CtlSetValue(GetObjectPtr(Chk_Reset_Dates), false);
  3409.         CtlSetValue(GetObjectPtr(Chk_Reset_Progress), false);
  3410.         CtlSetValue(GetObjectPtr(Chk_Reset_Priority), false);
  3411.         CtlSetValue(GetObjectPtr(Chk_ToDo_Unlink), false);
  3412.         CtlSetValue(GetObjectPtr(Chk_ToDo_Link), false);
  3413.         FrmDrawForm(frm);
  3414.         handled = true;
  3415.         break;
  3416.     
  3417.     case frmCloseEvent:
  3418.         // handled = true ??
  3419.         break;
  3420.  
  3421.     case menuEvent:
  3422.         handled = true;
  3423.         break;
  3424.  
  3425.     case ctlSelectEvent:
  3426.         switch(e->data.ctlSelect.controlID) {
  3427.             case Btn_Ok:
  3428.                 switch (SelectRange())
  3429.                 {
  3430.                     case Btn_Sub_All:
  3431.                         first = 1;
  3432.                         last = DmNumRecords(gdbP);
  3433.                         idRange = StrAllTasks;
  3434.                         break;
  3435.                     case Btn_Sub_Sub:
  3436.                         first = gParentTask + 1;
  3437.                         last = GetLastInSub(gParentTask) + 1;
  3438.                         idRange = StrAllTasksInThisSubview;
  3439.                         break;
  3440.                     default:
  3441.                         return true;
  3442.                         break;
  3443.                 }
  3444.                 if (ConfirmCustom(StrActionModify, idRange))
  3445.                     return true;
  3446.                 // modify the prefs
  3447.                 for (i = first; i < last; i++)
  3448.                 {
  3449.                     if (CtlGetValue(GetObjectPtr(Chk_Reset_Dates)))
  3450.                         TaskSetDueDate(gdbP, i, gNoDate);
  3451.  
  3452.                     if (CtlGetValue(GetObjectPtr(Chk_Reset_Progress)))
  3453.                         TaskSetCompleted(gdbP, i,
  3454.                         TaskGetActionState(gdbP, i) ? ACTION_NO : 0);
  3455.  
  3456.                     if (CtlGetValue(GetObjectPtr(Chk_Reset_Priority)))
  3457.                         TaskSetPriority(gdbP, i, 6);
  3458.  
  3459.                     if (CtlGetValue(GetObjectPtr(Chk_ToDo_Unlink)) &&
  3460.                         TaskGetFormat(gdbP, i).hasToDo)
  3461.                         TaskRemoveHasToDo(gdbP, i);
  3462.  
  3463.                     if (CtlGetValue(GetObjectPtr(Chk_ToDo_Link)) &&
  3464.                         !TaskGetHasChild(gdbP, i))
  3465.                     {
  3466.                         UInt8 comp = TaskGetCompleted(gdbP, i);
  3467.                         if (comp < ACTION)
  3468.                             TaskSetCompleted(gdbP, i, 
  3469.                             comp == 10 ? ACTION_OK : ACTION_NO);
  3470.                         TaskPublishToDo(gdbP, i);
  3471.                         if (TaskGetPriority(gdbP, i) == 6)
  3472.                             TaskSetPriority(gdbP, i, 5);
  3473.                     }
  3474.  
  3475.                     TaskUpdateToDo(gdbP, i);
  3476.                 }
  3477.                 FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  3478.  
  3479.                 // fall through
  3480.             case Btn_Cancel:
  3481.                 FrmReturnToForm(0);
  3482.                 handled = true;
  3483.                 break;
  3484.             default:
  3485.                 break;
  3486.         }
  3487.         break;
  3488.  
  3489.     default:
  3490.         break;
  3491.     }
  3492.  
  3493.     return handled;
  3494. } // static Boolean FrmSetResetHandleEvent (EventPtr e)
  3495.  
  3496.  
  3497.  
  3498.  
  3499.  
  3500. //
  3501. // Event handler for display property dialog.
  3502. //
  3503. static Boolean FrmDisplayPropertiesHandleEvent (EventPtr e)
  3504. {
  3505.     Int16 TInt16;
  3506.     ListPtr listP;
  3507.     Boolean handled = false;
  3508.  
  3509.     switch (e->eType) {
  3510.         case frmOpenEvent:
  3511.             LstSetSelection(GetObjectPtr(List_PriorityToBold), 
  3512.                 gProjectPrefs.boldMinPriority);
  3513.  
  3514.             CtlSetLabel(GetObjectPtr(Pop_PriorityToBold),
  3515.                 LstGetSelectionText(GetObjectPtr(List_PriorityToBold),
  3516.                 gProjectPrefs.boldMinPriority) );
  3517.  
  3518.             LstSetSelection(GetObjectPtr(List_DaysToBold), 
  3519.                 gProjectPrefs.boldMinDays);
  3520.  
  3521.             CtlSetLabel(GetObjectPtr(Pop_DaysToBold),
  3522.                 LstGetSelectionText(GetObjectPtr(List_DaysToBold),
  3523.                 gProjectPrefs.boldMinDays) );
  3524.  
  3525.             CtlSetValue(GetObjectPtr(Chk_StrikeDoneTasks), 
  3526.                 gProjectPrefs.strikeDoneTasks);
  3527.  
  3528.             CtlSetValue(GetObjectPtr(Chk_HideDoneProgress), 
  3529.                 gProjectPrefs.hideDoneProgress);
  3530.  
  3531.             CtlSetValue(GetObjectPtr(Chk_HideAllProgress), 
  3532.                 gProjectPrefs.hideProgress);
  3533.  
  3534.             FrmDrawForm(FrmGetActiveForm());
  3535.             handled = true;
  3536.             break;
  3537.  
  3538.         case menuEvent:
  3539.             handled = true;
  3540.  
  3541.         case ctlSelectEvent:
  3542.             switch(e->data.ctlSelect.controlID) {
  3543.                 case Pop_PriorityToBold:
  3544.                 case Pop_DaysToBold:
  3545.  
  3546.                     listP = GetObjectPtr(e->data.ctlSelect.controlID + 1);
  3547.                     TInt16 = LstPopupList(listP);
  3548.                     if (TInt16 != -1)
  3549.                     {
  3550.                         CtlSetLabel(GetObjectPtr(e->data.ctlSelect.controlID),
  3551.                             LstGetSelectionText(listP, TInt16));
  3552.                     }
  3553.                     handled = true;
  3554.                     break;
  3555.  
  3556.                 case Btn_Ok:
  3557.                     gProjectPrefs.boldMinPriority = 
  3558.                         LstGetSelection(GetObjectPtr(List_PriorityToBold));
  3559.  
  3560.                     gProjectPrefs.boldMinDays = 
  3561.                         LstGetSelection(GetObjectPtr(List_DaysToBold));
  3562.  
  3563.                     gProjectPrefs.strikeDoneTasks = 
  3564.                         CtlGetValue(GetObjectPtr(Chk_StrikeDoneTasks));
  3565.  
  3566.                     gProjectPrefs.hideDoneProgress = 
  3567.                         CtlGetValue(GetObjectPtr(Chk_HideDoneProgress));
  3568.  
  3569.                     gProjectPrefs.hideProgress = 
  3570.                         CtlGetValue(GetObjectPtr(Chk_HideAllProgress));
  3571.  
  3572.                     FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  3573.                     // fall down
  3574.  
  3575.                 case Btn_Cancel: // return to caller without modifying the prefs
  3576.                     FrmReturnToForm(0);
  3577.                     handled = true;
  3578.                     break;
  3579.             }
  3580.  
  3581.         default:
  3582.             break;
  3583.         }
  3584.  
  3585.     return handled;
  3586. } // static Boolean FrmDisplayPropertiesHandleEvent (EventPtr e)
  3587.  
  3588.  
  3589.  
  3590.  
  3591.  
  3592.  
  3593. /* this function from oreilly's palm programming book */
  3594. Boolean EditMenuHandleEvent(UInt16 menuid, FieldPtr fld)
  3595. {
  3596.     switch (menuid) {
  3597.         case MenuEditUndo:
  3598.         case MenuEditCut:
  3599.         case MenuEditCopy:
  3600.         case MenuEditPaste:
  3601.         case MenuEditSelectAll:
  3602.             if (!fld)
  3603.                 return false;
  3604.  
  3605.             if (menuid==MenuEditUndo)
  3606.                 FldUndo(fld);
  3607.             else if (menuid==MenuEditCut)
  3608.                 FldCut(fld);
  3609.             else if (menuid==MenuEditCopy)
  3610.                 FldCopy(fld);
  3611.             else if (menuid==MenuEditPaste)
  3612.                 FldPaste(fld);
  3613.             else if (menuid==MenuEditSelectAll)
  3614.                 FldSetSelection(fld, 0, FldGetTextLength(fld));
  3615.  
  3616.             return true;
  3617.  
  3618.         case MenuEditKeyboard:
  3619.             SysKeyboardDialog(kbdDefault);
  3620.             return true;
  3621.  
  3622.         case MenuEditGraffiti:
  3623.             SysGraffitiReferenceDialog(referenceDefault);
  3624.             return true;
  3625.         
  3626.         default:
  3627.             return false;
  3628.     };
  3629. } // Boolean EditMenuHandleEvent(UInt16 menuid)
  3630.  
  3631.  
  3632.  
  3633. void FrmNoteEditUpdateScroll(void)
  3634. {
  3635.     UInt16 textHeight, fieldHeight, scrollPos, maxValue;
  3636.     FieldPtr fld = GetObjectPtr(TaskNote);
  3637.     ScrollBarPtr bar = GetObjectPtr(Scr_Note_Edit);
  3638.  
  3639.     FldGetScrollValues(fld, &scrollPos, &textHeight, &fieldHeight);
  3640.  
  3641.     if (textHeight > fieldHeight)
  3642.         maxValue = (textHeight - fieldHeight) + FldGetNumberOfBlankLines (fld);
  3643.     else if (scrollPos)
  3644.         maxValue = scrollPos;
  3645.     else
  3646.         maxValue = 0;
  3647.  
  3648.     SclSetScrollBar (bar, scrollPos, 0, maxValue, fieldHeight-1);
  3649. } // void FrmNoteEditUpdateScroll(void)
  3650.  
  3651.  
  3652.  
  3653. void FrmNoteEditScrollPage(WinDirectionType direction)
  3654. {
  3655.     UInt16 textHeight, fieldHeight, scrollPos, maxValue;
  3656.     FieldPtr fld = GetObjectPtr(TaskNote);
  3657.     ScrollBarPtr bar = GetObjectPtr(Scr_Note_Edit);
  3658.     UInt16 step = 10;
  3659.  
  3660.     FldGetScrollValues(fld, &scrollPos, &textHeight, &fieldHeight);
  3661.     switch (direction)
  3662.     {
  3663.         case winUp:
  3664.             if (scrollPos - step < 0)
  3665.             {
  3666.                 step = scrollPos;
  3667.                 scrollPos = 0;
  3668.             }
  3669.             else
  3670.                 scrollPos -= step;
  3671.             break;
  3672.         case winDown:
  3673.             if (scrollPos + step > textHeight)
  3674.             {
  3675.                 step = textHeight - scrollPos;
  3676.                 scrollPos = textHeight;
  3677.             }
  3678.             else
  3679.                 scrollPos += step;
  3680.             break;
  3681.         default:
  3682.             break;
  3683.     }
  3684.  
  3685.     FldScrollField(fld, step, direction);
  3686.  
  3687.     FldGetScrollValues(fld, &scrollPos, &textHeight, &fieldHeight);
  3688.  
  3689.     if (textHeight > fieldHeight)
  3690.         maxValue = textHeight - fieldHeight;
  3691.     else if (scrollPos)
  3692.         maxValue = scrollPos;
  3693.     else
  3694.         maxValue = 0;
  3695.  
  3696.     SclSetScrollBar (bar, scrollPos, 0, maxValue, 
  3697.         fieldHeight-1);
  3698. } // void FrmNoteEditScrollPage(void)
  3699.  
  3700.  
  3701.  
  3702. static Boolean FrmNoteEditHandleEvent (EventPtr e)
  3703. {
  3704.     Boolean handled = false;
  3705.     FormPtr frm;
  3706.     MemHandle h;
  3707.     TaskRecordType *p;
  3708.  
  3709.     frm = FrmGetActiveForm();
  3710.  
  3711.     switch (e->eType) {
  3712.     case frmOpenEvent:
  3713.         InitFrmNoteEdit();
  3714.         h = DmQueryRecord(gdbP, gActualTask);
  3715.         p = MemHandleLock(h);
  3716.         SetFormTitle(frm, (Char*)&p->description);
  3717.         MemHandleUnlock(h);
  3718.         FrmDrawForm(frm);
  3719.         // set the focus
  3720.         FrmSetFocus(frm, FrmGetObjectIndex(frm, TaskNote));
  3721.         FrmNoteEditUpdateScroll();
  3722.         handled = true;
  3723.         break;
  3724.     
  3725.     case frmCloseEvent:
  3726.         CleanUpFrmNoteEdit(); // save the note !!!
  3727.         // handled = true ??
  3728.         break;
  3729.  
  3730.     case menuEvent:
  3731.         handled = EditMenuHandleEvent(e->data.menu.itemID, 
  3732.             GetObjectPtr(TaskNote));
  3733.         break;
  3734.  
  3735.     case ctlSelectEvent:
  3736.         switch(e->data.ctlSelect.controlID) {
  3737.             case Btn_Note_Ok:
  3738.                 // save
  3739.                 CleanUpFrmNoteEdit();
  3740.             case Btn_Note_Cancel:
  3741.                 // return to caller
  3742.                 FrmUpdateForm(FrmTaskEdit, frmTaskEditReturnFromNote);
  3743.                 FrmReturnToForm(0);
  3744.                 handled = true;
  3745.                 break;
  3746.             case Btn_Note_Delete:
  3747.                 if (ConfirmCustom(StrActionDelete, StrThisNote) == 0)
  3748.                 {
  3749.                     FieldPtr fld = GetObjectPtr(TaskNote);
  3750.                     MemHandle textH = FldGetTextHandle(fld);
  3751.                     Char* textP;
  3752.  
  3753.                     textP = MemHandleLock(textH);
  3754.                     StrCopy(textP, "\0");
  3755.                     MemHandleUnlock(textH);
  3756.                     FldCompactText(fld);
  3757.                     // save
  3758.                     CleanUpFrmNoteEdit();
  3759.                     // return to caller
  3760.                            FrmUpdateForm(FrmTaskEdit, frmTaskEditReturnFromNote);
  3761.                     FrmReturnToForm(0);
  3762.                     handled = true;
  3763.                 }
  3764.                 break;
  3765.                 
  3766.             default:
  3767.                 break;
  3768.         }
  3769.         break;
  3770.  
  3771.     case keyDownEvent:
  3772.         switch (e->data.keyDown.chr)
  3773.         {
  3774.             case vchrPageDown:
  3775.                 FrmNoteEditScrollPage(winDown);
  3776.                 handled = true;
  3777.                 break;
  3778.             case vchrPageUp:
  3779.                 FrmNoteEditScrollPage(winUp);
  3780.                 handled = true;
  3781.                 break;
  3782.             default:
  3783.                 break;
  3784.         }
  3785.         break;
  3786.  
  3787.     case fldChangedEvent:
  3788.         FrmNoteEditUpdateScroll();
  3789.         handled = true;
  3790.         break;
  3791.  
  3792.     case sclRepeatEvent:
  3793.         FldScrollField(GetObjectPtr(TaskNote), 
  3794.             abs(e->data.sclRepeat.value - e->data.sclRepeat.newValue), 
  3795.             e->data.sclRepeat.value > e->data.sclRepeat.newValue ?
  3796.             winUp : winDown);
  3797.         break;
  3798.  
  3799.     default:
  3800.         break;
  3801.     }
  3802.  
  3803.     return handled;
  3804. } // static Boolean FrmNoteEditHandleEvent (EventPtr e)
  3805.  
  3806.  
  3807.  
  3808. Boolean FrmFlatCtlSelectHandleEvent(EventPtr e)
  3809. {
  3810.     FormPtr frm;
  3811.     
  3812.     frm = FrmGetActiveForm();
  3813.  
  3814.     switch(e->data.ctlSelect.controlID) {
  3815.         case Btn_Done:
  3816.             FrmGotoForm(FrmProjectList);
  3817.             CloseDB(gdbP);
  3818.             gActualTask = gLastSelected = gRefLevel = gParentTask = 0;
  3819.             break;
  3820.         case Btn_Main_Hierarchical:
  3821.             FrmGotoForm(FrmMain);
  3822.             break;
  3823.         case Btn_Main_Flat:
  3824.             FrmPopupForm(FrmFlatFilter);
  3825.             break;
  3826.         default:
  3827.             break;
  3828.     }
  3829.     FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  3830.     return true;
  3831. } // Boolean FrmFlatCtlSelectHandleEvent(EventPtr e)
  3832.  
  3833.  
  3834.  
  3835. void ProjectFlatTableUpdate(void)
  3836. {
  3837.     TablePtr table;
  3838.     UInt16 numRows;
  3839.     UInt16 i, index;
  3840.     UInt16 cardNo = 0;
  3841.     LocalID sortInfoID;
  3842.     UInt32 *p;
  3843.     UInt32 size = 0;
  3844.  
  3845.     table = GetObjectPtr(ProjectTable);
  3846.     numRows = TblGetNumberOfRows(table);
  3847.  
  3848.     // get the sort info block
  3849.     DmDatabaseInfo(cardNo, gdbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
  3850.         NULL, &sortInfoID, NULL, NULL);
  3851.  
  3852.     p = MemLocalIDToLockedPtr(sortInfoID, cardNo);
  3853.     size = MemPtrSize(p) / sizeof(UInt32);
  3854.  
  3855.     // if gdbP contains at least one task, there is at least one terminal task
  3856.     // special case, db empty (just task 0)
  3857.     if ((DmNumRecords(gdbP) == 1) || (*p == 0))
  3858.     {
  3859.         ProjectTableEmpty();
  3860.         MemPtrUnlock(p);
  3861.         return;
  3862.     }
  3863.  
  3864.     if (gFlatOffset >= size)
  3865.         gFlatOffset = size - 1;
  3866.  
  3867.     // first item
  3868.     DmFindRecordByID(gdbP, p[gFlatOffset], &index);
  3869.     if (index)
  3870.         TblSetItemInt(table, 0, 0, index);
  3871.     else
  3872.         TblSetItemInt(table, 0, 0, -1);
  3873.  
  3874.     // first item change if it is now invisible
  3875.     // TODO
  3876.  
  3877.     // other items
  3878.     // TODO : end detection code, etc...
  3879.     for (i = 1; i < numRows; i++)
  3880.     {
  3881.         if (gFlatOffset + i >= size)
  3882.             TblSetItemInt(table, i, 0, -1);
  3883.         else
  3884.         {
  3885.             DmFindRecordByID(gdbP, p[gFlatOffset + i], &index);
  3886.             if (index)
  3887.                 TblSetItemInt(table, i, 0, index);
  3888.             else
  3889.                 TblSetItemInt(table, i, 0, -1);
  3890.         }
  3891.     }
  3892.     MemPtrUnlock(p);
  3893.     gCurrentPrefs.topTask = TblGetItemInt(table, 0, 0);
  3894. } // void ProjectFlatTableUpdate(void)
  3895.  
  3896.  
  3897.  
  3898. Boolean FrmFlatKeyDownHandleEvent(EventPtr e)
  3899. {
  3900.     switch (e->data.keyDown.chr)
  3901.     {
  3902.         case vchrPageDown:
  3903.             gFlatOffset += 5;
  3904.             FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  3905.             break;
  3906.         case vchrPageUp:
  3907.             if (gFlatOffset < 5)
  3908.                 gFlatOffset = 0;
  3909.             else
  3910.                 gFlatOffset -= 5;
  3911.             FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  3912.             break;
  3913.         // this code don't work well at all !
  3914.         // no time to correct yet
  3915. //        case chrUpArrow:
  3916. //            if (gActualTask)
  3917. //            {
  3918. //                UInt16 prev = gActualTask - 1;
  3919. //                while (prev && !FlatFilter(gdbP, prev))
  3920. //                    prev--;
  3921. //                if (prev)
  3922. //                {
  3923. //                    gActualTask = prev;
  3924. //                    SelectActualTask(true);
  3925. //                    FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  3926. //                }
  3927. //            }
  3928. //            break;
  3929. //        case chrDownArrow:
  3930. //            if ((gActualTask + 1 < DmNumRecords(gdbP)))
  3931. //            {
  3932. //                UInt16 next = gActualTask + 1, numRec = DmNumRecords(gdbP);
  3933. //                while (next < numRec && !FlatFilter(gdbP, next))
  3934. //                    next++;
  3935. //                if (next < numRec)
  3936. //                {
  3937. //                    gActualTask = next;
  3938. //                    SelectActualTask(true);
  3939. //                    FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  3940. //                }
  3941. //            }
  3942. //            break;
  3943.         default:
  3944.             break;
  3945.     }
  3946.     return true;
  3947. } // Boolean FrmFlatKeyDownHandleEvent(EventPtr e)
  3948.  
  3949.  
  3950.  
  3951. static Boolean FrmFlatHandleEvent (EventPtr e)
  3952. {
  3953.     Boolean handled = false;
  3954.     FormPtr frm;
  3955.     Int16 x;
  3956.     TaskFormatType format;
  3957.     
  3958.     frm = FrmGetActiveForm();
  3959.     gTable = GetObjectPtr(ProjectTable);
  3960.  
  3961.     switch (e->eType) {
  3962.     case frmUpdateEvent:
  3963.         switch(e->data.frmUpdate.updateCode)
  3964.         {
  3965.             case frmRedrawUpdateCode:
  3966.                 ProjectFlatTableUpdate();
  3967.                 FrmDrawForm(frm);
  3968.                 SelectActualTask(false);
  3969.                 handled = true;
  3970.                 break;
  3971.             default:
  3972.                 break;
  3973.         }
  3974.         break;
  3975.  
  3976.     case frmOpenEvent:
  3977.         gCurrentPrefs.view = flatView;
  3978.         ProjectTableInit();
  3979.         SetFormTitle(frm, gCurrentPrefs.openDBName);
  3980.         FlatCreateList(gdbP);
  3981.         ProjectFlatTableUpdate();
  3982.         FrmDrawForm(frm);
  3983.         gTable = GetObjectPtr(ProjectTable);
  3984.         gParentTask = 0;
  3985.         gRefLevel = 0;
  3986.         CtlSetValue(GetObjectPtr(Btn_Main_Flat), true);
  3987.         handled = true;
  3988.         break;
  3989.  
  3990.     case menuEvent:
  3991.         MenuEraseStatus(NULL);
  3992.         switch(e->data.menu.itemID) {
  3993.             case MenuMainPreferences:
  3994.                 FrmPopupForm(FrmProjectProperties);
  3995.                 break;
  3996.             case MenuMainDisplayPreferences:
  3997.                 FrmPopupForm(FrmDisplayProperties);
  3998.                 break;
  3999.             case MenuMainFlatFilter:
  4000.                 FrmPopupForm(FrmFlatFilter);
  4001.                 break;
  4002.             case MenuPublishLinkMaster:
  4003.                 if (gActualTask > 0)
  4004.                     PublishToLinkMaster(gdbP, gActualTask);
  4005.                 break;
  4006.             case MenuLinkViaLinkMaster:
  4007.                 if (gActualTask > 0)
  4008.                     RequestLinkViaLinkMaster(gCurrentPrefs.openDBName, gActualTask);
  4009.                 break;
  4010.             case MenuRemoveLinkViaLinkMaster:
  4011.                 if (gActualTask > 0)
  4012.                     RemoveLinkViaLinkMaster(gActualTask);
  4013.                 break;
  4014.             case MenuEditAddNote:
  4015.                 if (gActualTask)
  4016.                 {
  4017.                     FrmPopupForm(FrmNoteEdit);
  4018.                 }
  4019.                 break;
  4020.             case MenuLinkAll:
  4021.                 FlatLinkAll(gdbP, true);
  4022.                 FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  4023.                 break;
  4024.             case MenuUnlinkAll:
  4025.                 FlatLinkAll(gdbP, false);
  4026.                 FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  4027.                 break;
  4028.         }
  4029.         handled = true;
  4030.         break;
  4031.  
  4032.     // remember the screen coords
  4033.     case tblEnterEvent:
  4034.         gLastDownX = e->screenX;
  4035.         gLastDownY = e->screenY;
  4036.         // deselect all
  4037.         gActualTask = 0;
  4038.         break;
  4039.  
  4040.     case ctlSelectEvent:
  4041.         handled = FrmFlatCtlSelectHandleEvent(e);
  4042.         break;
  4043.  
  4044.     case ctlRepeatEvent:
  4045.         switch (e->data.ctlRepeat.controlID)
  4046.         {
  4047.             case Btn_Scroll_Up:
  4048.                 if (gFlatOffset > 0)
  4049.                     gFlatOffset--;
  4050.                 break;
  4051.             case Btn_Scroll_Down:
  4052.                     gFlatOffset++;
  4053.                 break;
  4054.             default:
  4055.                 break;
  4056.         }
  4057.         FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  4058.         break;
  4059.  
  4060.     case tblSelectEvent:
  4061.         gActualTask = TblGetItemInt(gTable, e->data.tblSelect.row, 0);
  4062.         if (gActualTask == -1)
  4063.             gActualTask = 0;
  4064.         format = TaskGetFormat(gdbP, gActualTask);
  4065.         x = gLastDownX/11;
  4066.         if (gActualTask) // this is for all the switch
  4067.         switch (x)
  4068.         {
  4069.             case 0:
  4070.                 /**************************************************************
  4071.                  * Code for ToDo Link
  4072.                  *************************************************************/
  4073.                 if (! format.extendedType)
  4074.                 {
  4075.                     if (format.hasToDo)
  4076.                         TaskRemoveHasToDo(gdbP, gActualTask);
  4077.                     else
  4078.                     {
  4079.                         UInt8 comp = TaskGetCompleted(gdbP, gActualTask);
  4080.                         if (comp < ACTION)
  4081.                         {
  4082.                             TaskSetCompleted(gdbP, gActualTask,
  4083.                                 comp == 10 ? ACTION_OK : ACTION_NO);
  4084.                         }
  4085.                         TaskPublishToDo(gdbP, gActualTask);
  4086.                     }
  4087.                     FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  4088.                 }
  4089.                 break;
  4090.             case 1:
  4091.                 /**************************************************************
  4092.                  * Code for progress buttons
  4093.                  *************************************************************/
  4094.                 ProgressHandleEvent();
  4095.                 break;
  4096.             default:
  4097.                 //////////////////////////////////////////////////////////////
  4098.                 // Code for note
  4099.                 //////////////////////////////////////////////////////////////
  4100.                 if (gLastDownX > 153 && format.hasNote)
  4101.                 {
  4102.                     FrmPopupForm(FrmNoteEdit);
  4103.                 }
  4104.                 else if (gLastDownX > (153 - (format.hasNote? 8 : 0))
  4105.                     && format.hasLink)
  4106.                 {
  4107.                     FollowLinkViaLinkMaster(gActualTask);
  4108.                 }
  4109.                 // if a priority is visible
  4110.                 else if (x == 2)
  4111.                 {
  4112.                     PriorityHandleEvent(e);
  4113.                 }
  4114.                 // edit text if click on the right side
  4115.                 else if (x > 0)
  4116.                 {
  4117.                     if (gLastSelected == gActualTask)
  4118.                     {
  4119.                         FrmPopupForm(FrmTaskEdit);
  4120.                     }
  4121.                     else
  4122.                     {
  4123.                         gLastSelected = gActualTask;
  4124.                     }
  4125.                 }
  4126.                 else
  4127.                 {
  4128.                     // left part
  4129.                     // nothing to do for now
  4130.                 }
  4131.                 break;
  4132.         }
  4133.         handled = true;
  4134.         break;
  4135.  
  4136.     // TODO : put this '5' in prefs (scroll step)
  4137.     case keyDownEvent:
  4138.         handled = FrmFlatKeyDownHandleEvent(e);
  4139.         break;
  4140.  
  4141.     default:
  4142.         break;
  4143.     }
  4144.  
  4145.     return handled;
  4146. } // static Boolean FrmFlatHandleEvent (EventPtr e)
  4147.  
  4148.  
  4149.  
  4150. static Boolean FrmTaskDefaultsHandleEvent (EventPtr e)
  4151. {
  4152.     Boolean handled = false;
  4153.     FormPtr frm;
  4154.     
  4155.     frm = FrmGetActiveForm();
  4156.  
  4157.     switch (e->eType) {
  4158.     case frmOpenEvent:
  4159.         FrmDrawForm(frm);
  4160.         // some older releases modified these fields, resulting in initial
  4161.         // corrupted notes
  4162.         gEmptyTask.note = "";
  4163.         gEmptyTask.description = "";
  4164.         gProjectPrefs.taskDefaults.note = "";
  4165.         gProjectPrefs.taskDefaults.description = "";
  4166.         // get the action value and set it on the form
  4167.         CtlSetValue(GetObjectPtr(Chk_Edit_Action), 
  4168.             gEmptyTask.completed);
  4169.  
  4170.         // to be compatible with not initialised db
  4171.         if (gEmptyTask.priority > 0 && gEmptyTask.priority < 7)
  4172.         {
  4173.             CtlSetValue(GetObjectPtr(Btn_Priority_X + gEmptyTask.priority - 1),
  4174.                 true);
  4175.         }
  4176.  
  4177.         handled = true;
  4178.         break;
  4179.     
  4180.     case ctlSelectEvent:
  4181.         switch(e->data.ctlSelect.controlID) {
  4182.             case Btn_Edit_Ok:
  4183.                 gProjectPrefs.taskDefaults = gEmptyTask;
  4184.                 FrmReturnToForm(0);
  4185.                 handled = true;
  4186.                 break;
  4187.  
  4188.             case Btn_Edit_Cancel:
  4189.                 gEmptyTask = gProjectPrefs.taskDefaults;
  4190.                 FrmReturnToForm(0);
  4191.                 handled = true;
  4192.                 break;
  4193.  
  4194.             case Chk_Edit_Action:
  4195.                 gEmptyTask.completed = gEmptyTask.completed > 10 ?
  4196.                     0 : ACTION_NO;
  4197.                 break;
  4198.  
  4199.             case Btn_Priority_1:
  4200.             case Btn_Priority_2:
  4201.             case Btn_Priority_3:
  4202.             case Btn_Priority_4:
  4203.             case Btn_Priority_5:
  4204.             case Btn_Priority_No:
  4205.                 gEmptyTask.priority = e->data.ctlSelect.controlID - 
  4206.                     Btn_Priority_X + 1;
  4207.  
  4208.             default:
  4209.                 break;
  4210.         }
  4211.         break;
  4212.  
  4213.     default:
  4214.         break;
  4215.     }
  4216.  
  4217.     return handled;
  4218. } // static Boolean FrmTaskDefaultsHandleEvent (EventPtr e)
  4219.  
  4220.  
  4221.  
  4222. static Boolean ApplicationHandleEvent(EventPtr e)
  4223. {
  4224.      if (e->eType == frmLoadEvent)
  4225.      {
  4226.          UInt16  formId = e->data.frmLoad.formID;
  4227.  
  4228.          struct tag_HandlerMap {
  4229.              UInt16 id;
  4230.              Boolean (*proc)(EventPtr e);
  4231.          };
  4232.          static struct tag_HandlerMap hm[] = {
  4233.              { FrmMain,              FrmMainHandleEvent },
  4234.              { FrmTaskEdit,          FrmTaskEditHandleEvent },
  4235.              { FrmProjectList,       FrmProjectListHandleEvent },
  4236.              { FrmChooseName,        FrmChooseNameHandleEvent },
  4237.              { FrmProjectProperties, FrmProjectPropertiesHandleEvent },
  4238.              { FrmDisplayProperties, FrmDisplayPropertiesHandleEvent },
  4239.              { FrmNoteEdit,          FrmNoteEditHandleEvent },
  4240.              { FrmFlat,              FrmFlatHandleEvent },
  4241.              { FrmFlatFilter,        FrmFlatFilterHandleEvent },
  4242.             { FrmDirectLink,        FrmDirectLinkHandleEvent },
  4243.             { FrmTaskDefaults,        FrmTaskDefaultsHandleEvent },
  4244.             { FrmMemoExportProperties, FrmMemoExportPropertiesHandleEvent },
  4245.             { FrmIconSelect,        FrmIconSelectHandleEvent },
  4246.             { FrmSetReset,            FrmSetResetHandleEvent },
  4247.              { 0, NULL }
  4248.          };
  4249.          static struct tag_HandlerMap* p;
  4250.  
  4251.          for (p = hm; p->proc != NULL && p->id != formId; p++)
  4252.              ;
  4253.          if (p->proc != NULL)
  4254.          {
  4255.              FormPtr frm = FrmInitForm(formId);
  4256.              FrmSetActiveForm(frm);
  4257.              FrmSetEventHandler(frm, p->proc);
  4258.              return true;
  4259.          }
  4260.      }
  4261.    
  4262.      return false;
  4263. } // static Boolean ApplicationHandleEvent(EventPtr e)
  4264.  
  4265.  
  4266.  
  4267. /* Get preferences, open (or create) app database */
  4268. static UInt16 StartApplication(void)
  4269. {
  4270.     UInt8 i;
  4271.  
  4272.     //
  4273.     // get PalmOS features and settings.
  4274.     //
  4275.  
  4276.     // Detect PalmOS version to know OS features
  4277.     UInt32 version;
  4278.     if (! FtrGet(sysFtrCreator, sysFtrNumROMVersion, &version))
  4279.     {
  4280. #define ver(a,b) sysMakeROMVersion(a, b, 0, sysROMStageRelease, 0)
  4281.         OSCaps.ver30 = (version >= ver(3, 0));
  4282.         OSCaps.ver31 = (version >= ver(3, 1));
  4283.         OSCaps.ver32 = (version >= ver(3, 2));
  4284.         OSCaps.ver33 = (version >= ver(3, 3));
  4285.         OSCaps.ver34 = (version >= ver(3, 4));
  4286.         OSCaps.ver35 = (version >= ver(3, 5));
  4287. #undef ver
  4288.     }
  4289.     // NOTE: for test only..
  4290.     WinScreenMode(winScreenModeGetDefaults,
  4291.                   &OSCaps.nScreenWidth, &OSCaps.nScreenHeight,
  4292.                   &OSCaps.nScreenDepth, &OSCaps.enableColor);
  4293.  
  4294.     // load icon data
  4295.     initializeIcon();
  4296.  
  4297.     // get date format
  4298.     gDateFormat = PrefGetPreference(prefDateFormat);
  4299.     gToday = Today();
  4300.     gTodayDays = DateToDays(gToday);
  4301.  
  4302.     // init the icons handles array
  4303.     for (i = 0; i < IconNum; i++)
  4304.     {
  4305.         gIconHandle[i] = (MemHandle)DmGetResource('Tbmp', BtmOffset + i);
  4306.     }
  4307.  
  4308.     // read the current prefs
  4309.     if (!LoadAppPrefs(false))
  4310.     {
  4311.         gCurrentPrefs.openDB = false;
  4312.         gCurrentPrefs.topTask = -1;
  4313.         gActualTask = 0;
  4314.         gParentTask = 0;
  4315.         gRefLevel = 0;
  4316.     }
  4317.     else
  4318.     {
  4319.         gActualTask = gCurrentPrefs.actualTask;
  4320.         gParentTask = gCurrentPrefs.parentTask;
  4321.         gRefLevel = gCurrentPrefs.refLevel;
  4322.     }
  4323.  
  4324.     // read the global prefs
  4325.     LoadAppPrefs(true);
  4326.  
  4327.     return 0;
  4328. } // static UInt16 StartApplication(void)
  4329.  
  4330.  
  4331.  
  4332. /* Save preferences, close forms, close app database */
  4333. static void StopApplication(void)
  4334. {
  4335.     UInt8 i;
  4336.     gCurrentPrefs.actualTask = gActualTask;
  4337.     gCurrentPrefs.parentTask = gParentTask;
  4338.     gCurrentPrefs.refLevel = gRefLevel;
  4339.  
  4340.     SaveAppPrefs(false); // current prefs
  4341.     SaveAppPrefs(true);  // saved prefs
  4342.  
  4343.     FrmSaveAllForms();
  4344.     FrmCloseAllForms();
  4345.     if (gdbP)
  4346.     {
  4347.         CloseDB(gdbP);
  4348.         gdbP = NULL;
  4349.     }
  4350.  
  4351.     // release the icons handles array
  4352.     for (i = 0; i < IconNum; i++)
  4353.     {
  4354.         DmReleaseResource(gIconHandle[i]);
  4355.     }
  4356.  
  4357.     // clear the clipboard
  4358.     NewClipboard();
  4359.     CloseClipboard();
  4360. } // static void StopApplication(void)
  4361.  
  4362. /* The main event loop */
  4363. static void EventLoop(void)
  4364. {
  4365.     Err err;
  4366.     EventType e;
  4367.  
  4368.     do {
  4369.         EvtGetEvent(&e, evtWaitForever);
  4370.         if (! SysHandleEvent (&e))
  4371.             if (! MenuHandleEvent (NULL, &e, &err))
  4372.                 if (! ApplicationHandleEvent (&e))
  4373.                     FrmDispatchEvent (&e);
  4374.     } while (e.eType != appStopEvent);
  4375. } // static void EventLoop(void)
  4376.  
  4377.  
  4378.  
  4379. static void switchView(viewType view)
  4380. {
  4381.     gCurrentPrefs.view = view;
  4382.     switch (view)
  4383.     {
  4384.     case normalView:
  4385.         FrmGotoForm(FrmMain);
  4386.         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  4387.         break;
  4388.     case flatView:
  4389.         FrmGotoForm(FrmFlat);
  4390.         FrmUpdateForm(FrmFlat, frmRedrawUpdateCode);
  4391.         break;
  4392.     default:
  4393.         break;
  4394.     }
  4395. }
  4396.  
  4397.  
  4398. /****************************************************************************
  4399.  * Name : GoToItem
  4400.  * Desc : open database and select task specified by gotoparams.
  4401.  * Parm : 
  4402.  *             -> item info
  4403.  *             -> just launching now?
  4404.  * Out  : 
  4405.  * Auth : seagull, 22.09.2000 JST
  4406.  ***************************************************************************/
  4407. static void GoToItem(GoToParamsPtr gotoparams, Boolean launchapp)
  4408. {
  4409.     UInt16 recordNum = gotoparams->recordNum;
  4410.     if (! launchapp)
  4411.     { // app is now on running.
  4412.         UInt32 uniqueID;
  4413.         if (gdbP)
  4414.         {
  4415.             UInt16 cardNo;
  4416.             LocalID dbID;
  4417.             DmOpenDatabaseInfo(gdbP, &dbID, 0, 0, &cardNo, 0);
  4418.             if (cardNo == gotoparams->dbCardNo && dbID == gotoparams->dbID)
  4419.             { // require same database
  4420.                 DmRecordInfo(gdbP, recordNum, NULL, &uniqueID, NULL);
  4421.                 FrmCloseAllForms();
  4422.                 DmFindRecordByID(gdbP, uniqueID, &recordNum);
  4423.             }
  4424.             else
  4425.             { // switch to other database
  4426.                 FrmCloseAllForms();
  4427.                 CloseDB(gdbP);
  4428.                 OpenDBByID(gotoparams->dbCardNo, gotoparams->dbID, &gdbP);
  4429.                 if (! gdbP)
  4430.                 {
  4431.                     FrmGotoForm(FrmProjectList);
  4432.                     return;
  4433.                 }
  4434.             }
  4435.         }
  4436.     }
  4437.  
  4438.     // OK, the database was opened successflly. select view and record.
  4439.     //  NOTE: ummm..I want a view for link published time, not a last selected.
  4440.     gLastSelected = gActualTask = recordNum;
  4441.  
  4442.     switchView(gCurrentPrefs.view);
  4443. } // static void GoToItem(GoToParamsPtr gotoparams, Boolean launchapp)
  4444.  
  4445.  
  4446.  
  4447. /* Main entry point; it is unlikely you will need to change this except to
  4448.    handle other launch command codes */
  4449. UInt32 PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
  4450. {
  4451.     Err err;
  4452.  
  4453.     if (cmd == sysAppLaunchCmdNormalLaunch ||
  4454.         cmd == sysAppLaunchCmdOpenDB ||
  4455.         cmd == linkAppLaunchFollowLink ||
  4456.         cmd == linkAppLaunchReturnLink ||
  4457.         cmd == linkAppLaunchRequestLink )
  4458.     {
  4459.            err = StartApplication();
  4460.         if (err) return err;
  4461.  
  4462.         //
  4463.         // Open database (,and goto item)
  4464.         //
  4465.         if (cmd == sysAppLaunchCmdNormalLaunch ||
  4466.             cmd == linkAppLaunchRequestLink)
  4467.         {
  4468.             if (gCurrentPrefs.openDB && ! OpenDB(gCurrentPrefs.openDBName, &gdbP))
  4469.                 switchView(gCurrentPrefs.view);
  4470.             else
  4471.                 FrmGotoForm(FrmProjectList);
  4472.         }
  4473.         else if (cmd == sysAppLaunchCmdOpenDB)
  4474.         {
  4475.             SysAppLaunchCmdOpenDBType* db = (SysAppLaunchCmdOpenDBType*)cmdPBP;
  4476.             err = OpenDBByID(db->cardNo, db->dbID, &gdbP);
  4477.             if (err) return err;  // Failed to open that database.
  4478.             switchView(gCurrentPrefs.view);
  4479.         }
  4480.         else if (cmd == linkAppLaunchFollowLink)
  4481.         {
  4482.             GoToParamsPtr gotoparams = LinkSimpleToGoToParams((LinkSimplePtr)cmdPBP);
  4483.             if (gotoparams)
  4484.             {
  4485.                 err = OpenDBByID(gotoparams->dbCardNo, gotoparams->dbID, &gdbP);
  4486.                 if (!err)
  4487.                     GoToItem(gotoparams, false);
  4488.                 MemPtrFree(gotoparams);
  4489.             }
  4490.             else return 0;
  4491.         }
  4492.         else if (cmd == linkAppLaunchReturnLink)
  4493.         {
  4494.             LinkSimplePtr p1 = (LinkSimplePtr)cmdPBP;
  4495.             LinkInfoPtr p2 = (LinkInfoPtr)((LinkInfoPtr)cmdPBP + 1);
  4496.             if (! OpenDB(p1->db_name, &gdbP))
  4497.             {
  4498.                 SetLinkMasterLink(p1, p2);
  4499.                 DmFindRecordByID(gdbP, p1->record_id, &gActualTask);
  4500.                 switchView(gCurrentPrefs.view);
  4501.             }
  4502.             else
  4503.                 FrmGotoForm(FrmProjectList);
  4504.         }
  4505.  
  4506.         EventLoop();
  4507.         StopApplication();
  4508.     }
  4509.     else if (cmd == linkAppLaunchFollowLinkSubCall)
  4510.     {
  4511.         GoToParamsPtr gotoparams;
  4512.         if (launchFlags & sysAppLaunchFlagNewGlobals)
  4513.         {
  4514.             gotoparams = LinkSimpleToGoToParams((LinkSimplePtr)cmdPBP);
  4515.             if (gotoparams)
  4516.             {
  4517.                 GoToItem(gotoparams, false);
  4518.                 MemPtrFree(gotoparams);
  4519.             }
  4520.         }
  4521.         else
  4522.         {
  4523.             DmSearchStateType state;
  4524.             UInt16 card;
  4525.             LocalID db;
  4526.  
  4527.             if (DmGetNextDatabaseByTypeCreator(true, &state, sysFileTApplication,
  4528.                                                CREATOR, false, &card, &db) == 0)
  4529.                 SysUIAppSwitch(card, db, linkAppLaunchFollowLink, cmdPBP);
  4530.         }
  4531.     }
  4532.     else if (cmd == sysAppLaunchCmdFind)
  4533.     {
  4534.         Search ((FindParamsPtr)cmdPBP);
  4535.         // open first database
  4536.         // if it doesn't exist
  4537.         //         findParams->more = false;
  4538.         //         exit
  4539.         // while we've got a database
  4540.         //         scan each record
  4541.         //         search for the next database
  4542.         // exit
  4543.         return 0;
  4544.     }
  4545.     else if (cmd == sysAppLaunchCmdGoTo)
  4546.     {
  4547.         GoToParamsPtr gotoparams = (GoToParamsPtr)cmdPBP;
  4548.         Boolean launched = launchFlags & sysAppLaunchFlagNewGlobals;
  4549.         if (launched)
  4550.         {
  4551.             err = StartApplication();
  4552.             if (err) return err;
  4553.             err = OpenDBByID(gotoparams->dbCardNo, gotoparams->dbID, &gdbP);
  4554.             if (! err)
  4555.             {
  4556.                 GoToItem(gotoparams, launched);
  4557.                 EventLoop();
  4558.                 StopApplication();
  4559.             }
  4560.         }
  4561.         else GoToItem(gotoparams, launched);
  4562.     }
  4563. //    else
  4564. //        return sysErrParamErr;
  4565.  
  4566.     return 0;
  4567. } // UInt32 PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
  4568.  
  4569.  
  4570.  
  4571. /*
  4572.  * based on MemoMain.c from Palm
  4573.  * adapted by L. Burgbacher for Progect
  4574.  */
  4575. static void DrawProjectTitle (Char * memo, Int16 x, Int16 y, Int16 width)
  4576. {
  4577.     Char * ptr = StrChr (memo, linefeedChr);
  4578.     UInt16 titleLen = (ptr == NULL ? StrLen (memo) : (UInt16) (ptr - memo));
  4579.     if (FntWidthToOffset (memo, titleLen, width, NULL, NULL) == titleLen)
  4580.         {
  4581.         WinDrawChars (memo, titleLen, x, y);
  4582.         }
  4583.     else
  4584.         {
  4585.         Int16 titleWidth;
  4586.         titleLen = FntWidthToOffset (memo, titleLen, width - FntCharWidth (chrEllipsis), NULL, &titleWidth);
  4587.         WinDrawChars (memo, titleLen, x, y);
  4588.         WinDrawChar (chrEllipsis, x + titleWidth, y);
  4589.         }
  4590. }
  4591.  
  4592.  
  4593.  
  4594. /*
  4595.  * based on MemoMain.c from Palm
  4596.  * adapted by L. Burgbacher for Progect
  4597.  */
  4598. static void Search(FindParamsPtr findParams)
  4599. {
  4600.     UInt16 pos;
  4601.     Char * header;
  4602.     UInt16 recordNum;
  4603.     MemHandle h;
  4604.     MemHandle headerStringH;
  4605.     RectangleType r;
  4606.     Boolean done;
  4607.     Boolean match;
  4608.     DmOpenRef dbP;
  4609.     DmSearchStateType searchState;
  4610.     Err err;
  4611.     UInt16 cardNo = 0;
  4612.     LocalID dbID, currentDbID;
  4613.     TaskRecordType *p;
  4614.     UInt32 longPos;
  4615.     UInt16 matchLength;
  4616.     Char searchDbName[] = "lbPG-GlobalSearch";
  4617.     LocalID searchID = 0;
  4618.     LocalID *IDPtr = NULL;
  4619.     DmOpenRef searchDb = NULL;
  4620.     Boolean firstTime = true;
  4621.  
  4622.     // if this is a continuation, find the last opened database
  4623.     if (findParams->continuation)
  4624.     {
  4625.         searchID = DmFindDatabase(cardNo, searchDbName);
  4626.  
  4627.         if (!searchID)
  4628.         {
  4629.             // this denotes a problem...
  4630.             findParams->more = false;
  4631.             return;
  4632.         }
  4633.  
  4634.         searchDb = DmOpenDatabase(cardNo, searchID, dmModeReadWrite);
  4635.  
  4636.         if (!searchDb)
  4637.         {
  4638.             // this denotes a problem...
  4639.             findParams->more = false;
  4640.             return;
  4641.         }
  4642.  
  4643.         h = DmQueryRecord(searchDb, 0);
  4644.         if (h)
  4645.         {
  4646.             currentDbID = *(LocalID*)(MemHandleLock(h));
  4647.             MemHandleUnlock(h);
  4648.             DmCloseDatabase(searchDb);
  4649.         }
  4650.         else
  4651.         {
  4652.             findParams->more = false;
  4653.             DmCloseDatabase(searchDb);
  4654.             DmDeleteDatabase(cardNo, searchID);
  4655.             return;
  4656.         }
  4657.  
  4658.     }
  4659.     else
  4660.     {
  4661.         // init currentDbID for first time
  4662.         DmGetNextDatabaseByTypeCreator (true, &searchState, 'DATA',
  4663.                     CREATOR, false, &cardNo, ¤tDbID);
  4664.     }
  4665.     
  4666.     // find the actual searched db
  4667.     while (dbID != currentDbID)
  4668.     {
  4669.         // Find the application's data file.
  4670.         err = DmGetNextDatabaseByTypeCreator (firstTime, &searchState, 'DATA',
  4671.                     CREATOR, false, &cardNo, &dbID);
  4672.         firstTime = false;
  4673.         if (err)
  4674.         {
  4675.             findParams->more = false;
  4676.             if (searchID)
  4677.                 DmDeleteDatabase(cardNo, searchID);
  4678.             return;
  4679.         }
  4680.     }
  4681.  
  4682.    // Open the first database.
  4683.    dbP = DmOpenDatabase(cardNo, dbID, findParams->dbAccesMode);
  4684.    if (!dbP)
  4685.        {
  4686.         findParams->more = false;
  4687.         if (searchID)
  4688.             DmDeleteDatabase(cardNo, searchID);
  4689.           return;
  4690.        }
  4691.  
  4692.     // Display the heading line.
  4693.     headerStringH = DmGetResource('tSTR', StrFindHeader);
  4694.     header = MemHandleLock(headerStringH);
  4695.     done = FindDrawHeader(findParams, header);
  4696.        MemHandleUnlock(headerStringH);   
  4697.        DmReleaseResource(headerStringH);   
  4698.        if (done) 
  4699.       goto Exit;
  4700.  
  4701.     // Search the memos for the "find" string.
  4702.     recordNum = findParams->recordNum;
  4703.     while (true)
  4704.         {
  4705.         // Because applications can take a long time to finish a find when
  4706.         // the result may be on the screen or for other reasons, users like
  4707.         // to be able to stop the find.  Stop the find if an event is pending.
  4708.         // This stops if the user does something with the device.  Because
  4709.         // this call slows winDown the search we perform it every so many 
  4710.         // records instead of every record.  The response time should still
  4711.         // be Int16 without introducing much extra work to the search.
  4712.         if ((recordNum & 0x000f) == 0 &&            // every 16th record
  4713.             EvtSysEventAvail(true))
  4714.             {
  4715.             // Stop the search process.
  4716.             findParams->more = true;
  4717.             break;
  4718.             }
  4719.  
  4720.         h = DmQueryRecord(dbP, recordNum);
  4721.  
  4722.         // Have we run out of records?
  4723.         while (!h)
  4724.         {
  4725.             // search the next database
  4726.             err = DmGetNextDatabaseByTypeCreator (false, &searchState, 'DATA',
  4727.                         CREATOR, false, &cardNo, &dbID);
  4728.             if (err)
  4729.             {
  4730.                 findParams->more = false;
  4731.                 if (searchID)
  4732.                     DmDeleteDatabase(cardNo, searchID);
  4733.                 break;
  4734.             }
  4735.                DmCloseDatabase(dbP);
  4736.  
  4737.            dbP = DmOpenDatabase(cardNo, dbID, findParams->dbAccesMode);
  4738.            if (!dbP)
  4739.             {
  4740.               findParams->more = false;
  4741.                 if (searchID)
  4742.                     DmDeleteDatabase(cardNo, searchID);
  4743.               break;
  4744.             }
  4745.  
  4746.             recordNum = 1;
  4747.             findParams->recordNum = 1;
  4748.             h = DmQueryRecord(dbP, recordNum);
  4749.         }
  4750.  
  4751.         if (!h) break;
  4752.  
  4753.         p = MemHandleLock(h);
  4754.          
  4755.         // don't treat extended types yet.
  4756.         if (p->format.bits.extendedType)
  4757.         {
  4758.             recordNum++;
  4759.             MemHandleUnlock(h);
  4760.             continue;
  4761.         }
  4762.  
  4763.         // Search for the string passed,  if it's found display the title
  4764.         // of the project.
  4765. //        match = TxtGlueFindString (&(p->description), findParams->strToFind, &longPos, &matchLength);
  4766.         match = TxtFindString(&(p->description), findParams->strToFind, &longPos, &matchLength);
  4767.         pos = longPos;
  4768.         if (match)
  4769.             {
  4770.             // Add the match to the find paramter block,  if there is no room to
  4771.             // display the match the following function will return true.
  4772.             done = FindSaveMatch (findParams, recordNum, pos, 0, matchLength, cardNo, dbID);
  4773.  
  4774.             if (!done)
  4775.                 {
  4776.                     Char dbname[32];
  4777.                 // Get the bounds of the region where we will draw the results.
  4778.                 FindGetLineBounds (findParams, &r);
  4779.                 DmDatabaseInfo(cardNo, dbID, dbname, NULL, NULL, NULL, NULL, 
  4780.                     NULL, NULL, NULL, NULL, NULL, NULL);
  4781.                 
  4782.                 // Display the title of the description.
  4783.                 DrawProjectTitle (&dbname[5], r.topLeft.x+1, r.topLeft.y, 
  4784.                     r.extent.x-2);
  4785.     
  4786.                 findParams->lineNumber++;
  4787.                 }
  4788.  
  4789.             }
  4790.         
  4791.         MemHandleUnlock(h);
  4792.         if (done) break;
  4793.  
  4794.         recordNum++;
  4795.         }
  4796.  
  4797. Exit:
  4798.     if (dbP)
  4799.         DmCloseDatabase (dbP);    
  4800.     if (findParams->more)
  4801.     {
  4802.         // create the searchdatabase and init it
  4803.         err = DmCreateDatabase(cardNo, searchDbName, CREATOR, 'SRCH', false);
  4804.         if ((err == dmErrAlreadyExists) || !err)
  4805.         {
  4806.             UInt16 index = 0;
  4807.             searchID = DmFindDatabase(cardNo, searchDbName);
  4808.  
  4809.             if (!searchID) return;
  4810.  
  4811.             searchDb = DmOpenDatabase(cardNo, searchID, dmModeReadWrite);
  4812.  
  4813.             if (!searchDb) return;
  4814.  
  4815.             while (DmNumRecords(searchDb))
  4816.             {
  4817.                 DmRemoveRecord(searchDb, 0);
  4818.             }
  4819.  
  4820.             h = DmNewRecord(searchDb, &index, sizeof(LocalID));
  4821.             if (h)
  4822.                 IDPtr = MemHandleLock(h);
  4823.             if (IDPtr)
  4824.             {
  4825.                 DmWrite(IDPtr, 0, &dbID, sizeof(LocalID));
  4826.                 MemHandleUnlock(h);
  4827.                 DmReleaseRecord(searchDb, index, true);
  4828.             }
  4829.             DmCloseDatabase(searchDb);
  4830.         }
  4831.     }
  4832. }
  4833.