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 / link.c < prev    next >
C/C++ Source or Header  |  2000-10-26  |  15KB  |  657 lines

  1. /* -*-Mode:C; tab-width:4; indent-tabs-mode:t; c-file-style:"stroustrup";-*- */
  2. // $Id: link.c,v 1.13 2000/10/10 17:08:48 seagull_kamome Exp $
  3.  
  4. #include "MemoDB.h"
  5. #include "AddressDB.h"
  6. #include "MemoMain.h"
  7. #include "link.h"
  8. #include "task.h"
  9. #include "flat.h"
  10. #include "progect.h"
  11. #include "progectdb.h"
  12. #include "progectRsc.h"
  13.  
  14.  
  15.  
  16. /****************************************************************************
  17.  * Name : AddLinkRecord
  18.  * Desc : add a link record to the database
  19.  * In   :
  20.  *             -> database
  21.  *             -> uniqueID of the link
  22.  *             -> index of task to add a link to
  23.  *             -> type of link
  24.  *             -> name of the DB to link to
  25.  * Auth : lb, 22.09.2000
  26.  * Rem  : doesn't handle err codes
  27.  ***************************************************************************/
  28. Err AddLinkRecord(DmOpenRef dbP, UInt32 uniqueID, UInt16 *index, 
  29.     AppLinkType app, Char *dbName)
  30. {
  31.     MemHandle h;
  32.     TaskExtendedRecordType *p;
  33.     TaskExtendedRecordType task;
  34.     UInt32 size = sizeof(TaskExtendedRecordType);
  35.     Err Err = errNone;
  36.     UInt16 realIndex;
  37.     Boolean withDbName = false;
  38.  
  39.     // get a handle on a newly created record
  40.     // new one always comes after actual
  41.     if (DmNumRecords(dbP) == 0)
  42.     {
  43.         realIndex = 0;
  44.     }
  45.     else if (DmNumRecords(dbP) > 1 && TaskGetHasChild(dbP, gParentTask))
  46.     {
  47.         realIndex = TaskGetNextRelativeIndex(dbP, *index); // place of new one
  48.     }
  49.     else
  50.     {
  51.         realIndex = gParentTask + 1;
  52.     }
  53.  
  54.     if (!realIndex)
  55.     {
  56.         realIndex = dmMaxRecordIndex;
  57.     }
  58.  
  59.     // set the fields for a link record
  60.     task.attr.allBits = 0;
  61.     task.attr.bits.opened = 1;
  62.     task.format.allBits = 0;
  63.     task.format.bits.extendedType = 1;
  64.     task.fields.link.uniqueID = uniqueID;
  65.     task.fields.link.dbName = '\0';
  66.     switch (app)
  67.     {
  68.         case memoLink:
  69.             task.format.bits.isMemo = 1;
  70.             break;
  71.         case addressLink:
  72.             task.format.bits.isContact = 1;
  73.             break;
  74.         case progectLink:
  75.             task.format.bits.isProject = 1;
  76.             withDbName = true;
  77.             size += StrLen(dbName);
  78.             break;
  79.         default:
  80.             return pgError;
  81.             break;
  82.     }
  83.  
  84.     h = DmNewRecord(dbP, &realIndex, size);
  85.     if (!h)
  86.     {
  87.         DEBUG1("Not enough memory for a new task");
  88.         return pgError;
  89.     }
  90.  
  91.  
  92.     // retrieve info about user of previous index
  93.     // this sets : level, next
  94.     if (*index == 0 || !TaskGetHasChild(dbP, gParentTask))
  95.     {
  96.         // this is a first child
  97.         task.attr.bits.level = gRefLevel + 1;
  98.         TaskSetHasChild(dbP, gParentTask, true);
  99.     }
  100.     else
  101.     {
  102.         task.attr.bits.level = TaskGetLevel(dbP, *index);
  103.         task.attr.bits.hasPrev = 1;
  104.         task.attr.bits.hasNext = TaskGetHasNext(dbP, *index);
  105.             
  106.         // update hasNext field in previous
  107.         TaskSetHasNext(dbP, *index, true);
  108.     }
  109.  
  110.     // get a pointer on the record
  111.     p = MemHandleLock(h);
  112.  
  113.     // write the data
  114.     DmWrite(p, 0, &task, sizeof(TaskExtendedRecordType));
  115.     if (withDbName)
  116.         DmStrCopy(p, OffsetOf(TaskExtendedRecordType, fields.link.dbName), dbName);
  117.  
  118.     // unlock the pointer
  119.     MemHandleUnlock(h);
  120.  
  121.     // unlock the record
  122.     DmReleaseRecord(dbP, realIndex, true);
  123.  
  124.     *index = realIndex;
  125.  
  126.     return Err;
  127. } // Err AddLinkRecord(DmOpenRef dbP, UInt32 uniqueID, UInt16 *index, AppLinkType app)
  128.  
  129.  
  130.  
  131. /****************************************************************************
  132.  * Name : LinkCreateLinkTree
  133.  * Desc : create a tree from the memo database
  134.  * Parm : 
  135.  * Out  : pgErr
  136.  * Auth : lb, 12.09.2000
  137.  ***************************************************************************/
  138. pgErr LinkCreateLinkTree(DmOpenRef dbP, AppLinkType app)
  139. {
  140.     CurrentPrefsType saveCurrent = gCurrentPrefs;
  141.     Boolean restoreDBstate = false;
  142.     UInt16 cardNo = 0;
  143.     DmOpenRef linkDB, sourceDB;
  144.     UInt16 numRec, insPos, i;
  145.     UInt32 uniqueID;
  146.     LocalID dbID;
  147.     Char *linkDBname, *prepLinkDBname;
  148.  
  149.     switch (app)
  150.     {
  151.         case memoLink:
  152.             // open the memo db from memopad
  153.             MemoGetDatabase(&sourceDB, dmModeReadWrite);
  154.             linkDBname = "MemoDB";
  155.             prepLinkDBname = "lbPG-MemoDB";
  156.             break;
  157.         case addressLink:
  158.             // open the address db from address
  159.             AddrGetDatabase(&sourceDB, dmModeReadWrite);
  160.             linkDBname = "AddressDB";
  161.             prepLinkDBname = "lbPG-AddressDB";
  162.             break;
  163.         default:
  164.             return pgError;
  165.             break;
  166.     }
  167.  
  168.     // if a db is opened now, we must open it back when done
  169.     if (dbP)
  170.     {
  171.         restoreDBstate = true;
  172.         CloseDB(dbP);
  173.     }
  174.  
  175.     gParentTask = gRefLevel = 0;
  176.  
  177.     // if memodb exists, delete it
  178.     if ((dbID = DmFindDatabase(cardNo, prepLinkDBname)))
  179.     {
  180.         // remove it
  181.         DmDeleteDatabase(cardNo, dbID);
  182.     }
  183.  
  184.     // create a db for the memos
  185.     CreateDB(linkDBname);
  186.  
  187.     // open the link db (db with links to the memos)
  188.     dbID = DmFindDatabase(cardNo, prepLinkDBname);
  189.     linkDB = DmOpenDatabase(cardNo, dbID, dmModeReadWrite);
  190.  
  191.     gParentTask = gRefLevel = 0;
  192.     numRec = DmNumRecords(sourceDB);
  193.  
  194.     // add a link to each memo the the new link db
  195.     insPos = 0;
  196.     for (i = 0; i < numRec; i++)
  197.     {
  198.         UInt16 attr;
  199.         // get the memo's UniqueID
  200.         DmRecordInfo(sourceDB, i, &attr, &uniqueID, NULL);
  201.         // create the link if it's not deleted
  202.         if (! (attr & dmRecAttrDelete))
  203.             AddLinkRecord(linkDB, uniqueID, &insPos, app, NULL);
  204.     }
  205.  
  206.     // close both databases
  207.     DmCloseDatabase(sourceDB);
  208.     DmCloseDatabase(linkDB);
  209.  
  210.     // if we had a database, reopen it
  211.     if (restoreDBstate)
  212.     {
  213.         OpenDB(saveCurrent.openDBName, &gdbP);
  214.     }
  215.     return pgOK;
  216.  
  217. } // pgErr LinkCreateLinkTree(void)
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230. /***************************************************************************
  231.  ** LinkMaster support functions 
  232.  **************************************************************************/
  233. // TODO:
  234. //   1.Multiple link
  235. //
  236.  
  237.  
  238. /****************************************************************************
  239.  * Name : CheckLinkMaster
  240.  * Desc : Check to LinkMaster is available
  241.  * Parm : 
  242.  * Out  : true if available, otherwise false.
  243.  * Auth : seagull, 22.09.2000 JST
  244.  ***************************************************************************/
  245. static Boolean CheckLinkMaster(void)
  246. {
  247.     if (! LinkCheck())
  248.     {
  249.         MessageBox(StrLinkMasterIsNotAvailable);
  250.         return false;
  251.     }
  252.     return true;
  253. } // static Boolean CheckLinkMaster(void)
  254.  
  255.  
  256. /****************************************************************************
  257.  * Name : PublishToLinkMaster
  258.  * Desc : Publish bookbark to LinkMaster
  259.  * Parm : 
  260.  *             -> database pointer
  261.  *             -> index of the task
  262.  * Out  : 
  263.  * Auth : seagull, 22.09.2000 JST
  264.  ***************************************************************************/
  265. void PublishToLinkMaster(DmOpenRef dbP, UInt16 index)
  266. {
  267.     if (CheckLinkMaster())
  268.     {
  269.         Char* desc = TaskGetDescription(dbP, index);
  270.         LinkSimpleType* p = LinkSimpleNew(dbP, index, desc);
  271.         MemPtrFree(desc);
  272.  
  273.         // NOTE: LinkSimpleNew need index. that gots unique id from index.
  274.         LinkPublish((LinkInfoPtr)p);
  275.     }
  276. } // void PublishToLinkMaster(DmOpenPref dpP, UInt16 index)
  277.  
  278.  
  279.  
  280. /****************************************************************************
  281.  * Name : RequestLinkViaLinkMaster
  282.  * Desc : Request link info
  283.  * Parm : 
  284.  *             -> database pointer
  285.  *             -> index of the task
  286.  * Out  : 
  287.  * Auth : seagull, 22.09.2000 JST
  288.  ***************************************************************************/
  289. void RequestLinkViaLinkMaster(Char const* dbName, UInt16 index)
  290. {
  291.     if (CheckLinkMaster())
  292.     {
  293.         LinkSimplePtr info = MemPtrNew(sizeof(LinkSimpleType));
  294.         info->creator = CREATOR;
  295.         DmRecordInfo(gdbP, index, NULL, &info->record_id, NULL);
  296.         StrCopy(info->db_name, dbName);
  297.         LinkRequest((LinkInfoPtr)info);
  298.     }
  299. } // void RequestLinkViaLinkMaster(Char const* dbName, UInt16 index)
  300.  
  301.  
  302.  
  303.  
  304. /****************************************************************************
  305.  * Name : SetLinkMasterLink
  306.  * Desc : Store link info into record.
  307.  * Parm : 
  308.  *             -> LinkInfo of this task
  309.  *             -> LinkInfo of target info.
  310.  * Out  : 
  311.  * Auth : seagull, 22.09.2000 JST
  312.  * Mod  : lb, 26.09.2000
  313.  *             - use of task functions to modify format of task
  314.  ***************************************************************************/
  315. void SetLinkMasterLink(LinkSimplePtr p1, LinkInfoPtr p2)
  316. {
  317.     UInt16 index;
  318.     TaskFormatType format;
  319.  
  320.     DmFindRecordByID(gdbP, p1->record_id, &index);
  321.  
  322.     // NOTE: currently the subkey is must be zero.
  323.     TaskSetExtraChunk(gdbP, index, Extra_Link_LinkMaster, 0,
  324.                       p2, sizeof(LinkInfoType));
  325.  
  326.  
  327.     // Turn ON hasLink bit.
  328.     // same using task functions
  329.     format = TaskGetFormat(gdbP, index);
  330.     format.hasLink = true;
  331.     TaskSetFormat(gdbP, index, format);
  332. } // void SetLinkMasterLink(LinkSimplePtr p1, LinkInfoPtr p2)
  333.  
  334.  
  335.  
  336.  
  337.  
  338. /****************************************************************************
  339.  * Name : FollowLinkViaLinkMaster
  340.  * Desc : fllow link master link
  341.  * Parm : 
  342.  *             -> database name
  343.  *             -> uniq index
  344.  * Out  : 
  345.  * Auth : seagull, 22.09.2000 JST
  346.  ***************************************************************************/
  347. void FollowLinkViaLinkMaster(UInt16 index)
  348. {
  349.     LinkInfoType info;
  350.     UInt16 size = sizeof(info);
  351.     if (TaskGetExtraChunk(gdbP, index, Extra_Link_LinkMaster, 0x00,
  352.                           &info, &size) == pgOK && 
  353.         size == sizeof(info))
  354.     {
  355.         LinkFollow(&info);
  356.     }
  357. } // void FollowLinkViaLinkMaster(Char dbname, UInt16 index)
  358.  
  359.  
  360.  
  361. /****************************************************************************
  362.  * Name : RemoveLinkViaLinkMaster
  363.  * Desc : remove link info
  364.  * Parm : 
  365.  *             -> uniq index
  366.  * Out  : 
  367.  * Auth : seagull, 22.09.2000 JST
  368.  ***************************************************************************/
  369. void RemoveLinkViaLinkMaster(UInt16 index)
  370. {
  371.     TaskFormatType format = TaskGetFormat(gdbP, index);
  372.     if (format.hasLink)
  373.     {
  374.         TaskRemoveExtraChunk(gdbP, index, Extra_Link_LinkMaster, 0);
  375.  
  376.         // Turn OFF hasLink bit
  377.         format.hasLink = false;
  378.         TaskSetFormat(gdbP, index, format);
  379.     }
  380. } // void RemoveLinkViaLinkMaster(UInt16 index)
  381.  
  382.  
  383.  
  384.  
  385. /****************************************************************************
  386.  * Name : ExportToMemo
  387.  * Desc : export a project to MemoPad files
  388.  * In   : database
  389.  * Auth : lb, 21.09.2000
  390.  ***************************************************************************/
  391. pgErr ExportToMemo(DmOpenRef dbP, MemoExportOptionsType options)
  392. {
  393.     #define predesc 100
  394.     Char *buffer; // to store the text to export
  395.     MemoItemType memo;
  396.     UInt16 cnt = 0, i, numRec, offset = 0, index = dmMaxRecordIndex, tab, level;
  397.     Err err;
  398.     DmOpenRef memoDB;
  399.     UInt16 memoNb = 1;
  400.  
  401.     buffer = MemPtrNew(memoMaxLength);
  402.  
  403.     numRec = DmNumRecords(dbP);
  404.     
  405.     StrCopy(buffer, &gCurrentPrefs.openDBName[5]);
  406.     offset = StrLen(&gCurrentPrefs.openDBName[5]);
  407.     buffer[offset++] = (Char)chrLineFeed;
  408.     cnt = offset;
  409.  
  410.     // for each record
  411.     for (i = 1; i < numRec; i++)
  412.     {
  413.         Char* desc;
  414.  
  415.         // skip it if it's done and we don't want done tasks
  416.         if (!options.exportDone && 
  417.             (TaskGetCompleted(dbP, i) == 10 || 
  418.             TaskGetCompleted(dbP, i) == ACTION_OK))
  419.         {
  420.             continue;
  421.         }
  422.  
  423.         // skip it if it's not a terminal and we just want terminals
  424.         if (options.exportFlat && !FlatFilter(dbP, i))
  425.         {
  426.             continue;
  427.         }
  428.  
  429.         level = TaskGetLevel(dbP, i) - 1;
  430.         desc = TaskGetDescription(dbP, i);
  431.         cnt += StrLen(desc) + level;
  432.  
  433.         // control the length
  434.         if (cnt >= memoMaxLength - predesc)
  435.         {
  436.             // begin new memo
  437.             buffer[offset] = '\0';
  438.             // memorize it
  439.             err = MemoGetDatabase (&memoDB, dmModeReadWrite);
  440.             if (err)
  441.             {
  442.                 DEBUG1("Can't open memo database");
  443.                 return pgError;
  444.             }
  445.             memo.note = buffer;
  446.             err = MemoNewRecord (memoDB, &memo, &index);
  447.             if (err)
  448.             {
  449.                 DEBUG1("Can't create a new memo");
  450.                 return pgError;
  451.             }
  452.             DmCloseDatabase(memoDB);
  453.  
  454.             // reinit buffer
  455.             StrCopy(buffer, &gCurrentPrefs.openDBName[5]);
  456.             offset = StrLen(&gCurrentPrefs.openDBName[5]);
  457.             buffer[offset++] = ' ';
  458.             buffer[offset++] = '(';
  459.             StrIToA(gDebugVal, ++memoNb);
  460.             StrCopy(&buffer[offset], gDebugVal);
  461.             offset += StrLen(gDebugVal);
  462.             buffer[offset++] = ')';
  463.             buffer[offset++] = (Char)chrLineFeed;
  464.             cnt = offset;
  465.         }
  466.         // indent if not flat view
  467.         if (!options.exportFlat)
  468.         {
  469.             for (tab = 1; tab <= level; tab++)
  470.             {
  471.                 buffer[offset++] = chrHorizontalTabulation;
  472.             }
  473.         }
  474.         // export progress
  475.         if (options.exportProgress)
  476.         {
  477.             UInt8 progress = TaskGetCompleted(dbP, i);
  478.             if (progress > ACTION)
  479.             {
  480.                 if (progress == ACTION_OK)
  481.                 {
  482.                     StrCopy(&buffer[offset], "[x] ");
  483.                 }
  484.                 else
  485.                 {
  486.                     StrCopy(&buffer[offset], "[ ] ");
  487.                 }
  488.                 offset += 4;
  489.             }
  490.             else
  491.             {
  492.                 buffer[offset++] = '[';
  493.                 StrIToA(gDebugVal, progress * 10);
  494.                 StrCopy(&buffer[offset], gDebugVal);
  495.                 offset += StrLen(gDebugVal);
  496.                 buffer[offset++] = '%';
  497.                 buffer[offset++] = ']';
  498.                 buffer[offset++] = ' ';
  499.             }
  500.         }
  501.         // export priority
  502.         if (options.exportPriority)
  503.         {
  504.             UInt8 priority = TaskGetPriority(dbP, i);
  505.             if (priority > 0 && priority < 6)
  506.             {
  507.                 buffer[offset++] = '[';
  508.                 buffer[offset++] = priority + '0';
  509.                 buffer[offset++] = ']';
  510.                 buffer[offset++] = ' ';
  511.             }
  512.         }
  513.         // export due date
  514.         if (options.exportDueDate)
  515.         {
  516.             DateType date = TaskGetDueDate(dbP, i);
  517.             if (date.month != 0)
  518.             {
  519.                 DateToAscii(date.month, date.day, 
  520.                     date.year + YEAR_OFFSET, gDateFormat, gDebugVal);
  521.                 buffer[offset++] = '(';
  522.                 StrCopy(&buffer[offset], gDebugVal);
  523.                 offset += StrLen(&buffer[offset]);
  524.                 buffer[offset++] = ')';
  525.                 buffer[offset++] = ' ';
  526.                 
  527.             }
  528.         }
  529.  
  530.         // copy the description
  531.         StrCopy(&buffer[offset], desc);
  532.         MemPtrFree(desc);
  533.         offset += StrLen(&buffer[offset]);
  534.         // new line
  535.         buffer[offset] = (Char)chrLineFeed;
  536.         offset++;
  537.         cnt = offset;
  538.     }
  539.     buffer[offset] = '\0';
  540.     // memorize it
  541.     err = MemoGetDatabase (&memoDB, dmModeReadWrite);
  542.     if (err)
  543.     {
  544.         DEBUG1("Can't open memo database");
  545.         return pgError;
  546.     }
  547.     memo.note = buffer;
  548.     MemoNewRecord (memoDB, &memo, &index);
  549.     DmCloseDatabase(memoDB);
  550.     MemPtrFree(buffer);
  551.     
  552.     return pgOK;
  553.  
  554. } // pgErr ExportToMemo(DmOpenRef dbP, MemoExportOptionsType options)
  555.  
  556.  
  557.  
  558.  
  559.  
  560. /****************************************************************************
  561.  * Name : DirectLinkFollow
  562.  * Desc : follow a link
  563.  * In   : the linkfield info
  564.  * Auth : lb, 28.09.2000
  565.  ***************************************************************************/
  566. pgErr DirectLinkFollow(DmOpenRef dbP, UInt16 index)
  567. {
  568.     GoToParamsType *params;
  569.     TaskExtendedRecordType *p;
  570.     MemHandle h;
  571.     LocalID appID;
  572.     DmSearchStateType searchstate;
  573.     DmOpenRef linkDB;
  574.     UInt16 cardNo, attr;
  575.     UInt32 appNum = 0;
  576.     Err err;
  577.  
  578.     h = DmQueryRecord(dbP, index);
  579.     p = MemHandleLock(h);
  580.  
  581.     if (p->format.bits.isMemo)
  582.     {
  583.         MemoGetDatabase(&linkDB, dmModeReadWrite);
  584.         appNum = 'memo';
  585.     }
  586.     else if (p->format.bits.isContact)
  587.     {
  588.         AddrGetDatabase(&linkDB, dmModeReadWrite);
  589.         appNum = 'addr';
  590.     }
  591.     else
  592.     {
  593.         MemHandleUnlock(h);
  594.         DEBUG1("This link is not implemented");
  595.         return pgError;
  596.     }
  597.  
  598.     if (!linkDB)
  599.     {
  600.         DEBUG1("Can't open link database");
  601.         MemHandleUnlock(h);
  602.         return pgError;
  603.     }
  604.  
  605.     params = MemPtrNew(sizeof(GoToParamsType));
  606.     if (!params)
  607.     {
  608.         DEBUG1("No more memory for gotoparams");
  609.         MemHandleUnlock(h);
  610.         DmCloseDatabase(linkDB);
  611.         return pgError;
  612.     }
  613.  
  614.     params->searchStrLen = 0;
  615.     params->dbID = 0;
  616.     params->matchPos = params->matchFieldNum = params->matchCustom = 0;
  617.     err = DmFindRecordByID(linkDB, p->fields.link.uniqueID, ¶ms->recordNum);
  618.     MemHandleUnlock(h);
  619.  
  620.     if (err ||
  621.         DmRecordInfo(linkDB, params->recordNum, &attr, NULL, NULL) ||
  622.         (attr & dmRecAttrDelete))
  623.     {
  624.         MemPtrFree(params);
  625.         DmCloseDatabase(linkDB);
  626.         TaskRemove(dbP, index);
  627.         MessageBox(StrLinkNotValid);
  628.         FrmUpdateForm(FrmMain, frmRedrawUpdateCode);
  629.         return pgError;
  630.     }
  631.  
  632.     DmCloseDatabase(linkDB);
  633.  
  634.     MemPtrSetOwner(params, 0);
  635.  
  636.     DmGetNextDatabaseByTypeCreator(true, &searchstate,
  637.         'appl', appNum,
  638.         true, &cardNo, &appID);
  639.  
  640.     SysUIAppSwitch(0, appID, sysAppLaunchCmdGoTo, params);
  641.  
  642.     return pgOK;
  643.     
  644. } // pgErr DirectLinkFollow(DmOpenRef dbP, UInt16 index)
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.