📄 flat.c
字号:
/* -*-Mode:C; tab-width:4; indent-tabs-mode:t; c-file-style:"stroustrup";-*- */#include "flat.h"#include "task.h"#include "progect.h"#include "progectdb.h"#include "progectRsc.h"#include "xb.h"/**************************************************************************** * Name : FlatFilter * Desc : tell if a task can go to the flat list * Parm : * -> db * -> index * <- true if can go * Out : pgErr * Auth : lb, 07.09.2000 * Mod : lb, 25.09.2000 * added overdue and by date filtering ***************************************************************************/Boolean FlatFilter(DmOpenRef dbP, UInt16 index){ UInt8 priority, completed; Boolean dateOK = false; Boolean priorityOK = false; DateType date; UInt16 attr; // only terminal tasks if (TaskGetHasChild(dbP, index)) return false; completed = TaskGetCompleted(dbP, index); if (completed == 10) { if (gProjectPrefs.flatHideDone) return false; } DmRecordInfo(dbP, index, &attr, NULL, NULL); attr &= dmRecAttrCategoryMask; if (! (gProjectPrefs.flatCategories & (0x8000 >> attr))) return false; date = TaskGetDueDate(dbP, index); if (date.month != 0) { // with date dateOK = (gProjectPrefs.flatDated == 0); if (gProjectPrefs.flatDateLimit) { if (!DateInLimit(date, gProjectPrefs.flatDateLimit)) { dateOK = false; } } } else { // without date dateOK = gProjectPrefs.flatDated == 1; } priority = TaskGetPriority(dbP, index); if (gProjectPrefs.flatMin) { priorityOK = (priority <= gProjectPrefs.flatMinPriority); if (priority == 0 && gProjectPrefs.flatMinPriority != 6) priorityOK = false; } else { priorityOK = (priority == gProjectPrefs.flatMinPriority); // backward compatible if (priority == 0 && gProjectPrefs.flatMinPriority == 6) priorityOK = true; } if (gProjectPrefs.flatOr) return gProjectPrefs.flatDated == 2 ? priorityOK : dateOK || priorityOK; else return gProjectPrefs.flatDated == 2 ? priorityOK : dateOK && priorityOK;} // Boolean FlatFilter(DmOpenRef dbP, UInt16 index)/**************************************************************************** * Name : FlatCreateList * Desc : Create a flat list (remove the old one if it exists) * Parm : * -> db to add a list * Out : pgErr * Auth : lb, 07.09.2000 ***************************************************************************/pgErr FlatCreateList(DmOpenRef dbP){ UInt16 cardNo; LocalID dbID, sortInfoID, oldSortInfoID = 0; MemHandle h; MemPtr p; UInt32 size = 0; UInt32 offset = 0; UInt32 uniqueID; UInt16 numRec = PgNumRecords(dbP); UInt16 i; // get the sort info ID DmOpenDatabaseInfo(dbP, &dbID, NULL, NULL, &cardNo, NULL); DmDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &sortInfoID, NULL, NULL); if (sortInfoID) oldSortInfoID = sortInfoID; // count the terminal tasks for (i = 1; i < numRec; i++) { if (FlatFilter(dbP, i)) size++; } size *= sizeof(UInt32); // UniqueID stored here as UInt32 if (size == 0) // no tasks pass filtering { UInt32 zero = 0; h = DmNewHandle(dbP, sizeof(UInt32)); sortInfoID = MemHandleToLocalID(h); // set this handle in the db DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &sortInfoID, NULL, NULL); p = MemHandleLock(h); DmWrite(p, 0, &zero, sizeof(UInt32)); } else { // get a new handle for the list h = DmNewHandle(dbP, size); if (!h) { DEBUG1("Cannot allocate memory for the flat list. Free some memory before retrying."); return pgError; } sortInfoID = MemHandleToLocalID(h); // set this handle in the db DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &sortInfoID, NULL, NULL); p = MemHandleLock(h); // store the terminal task's UniqueID for (i = 1; i < numRec; i++) { if (FlatFilter(dbP, i)) { // get the uniqueID of the task DmRecordInfo(dbP, i, NULL, &uniqueID, NULL); // store it DmWrite(p, offset, &uniqueID, sizeof(UInt32)); offset += sizeof(UInt32); } } } // release the handle MemHandleUnlock(h); if (oldSortInfoID) { h = MemLocalIDToGlobal(oldSortInfoID, cardNo); if (h) MemHandleFree(h); } if (gProjectPrefs.flatSorted) FlatSort(dbP); return pgOK;} // pgErr FlatCreateList(DmOpenRef dbP)/**************************************************************************** * Name : FlatCreateGlobalList * Desc : Create a flat list from all projects * Parm : * Out : pgErr * Auth : lb, 21.10.2000 * Rem : MUST be called from FrmProjectList, because it needs an initialized * namesData array ***************************************************************************/#if 0pgErr FlatCreateGlobalList(void){ UInt16 cardNo; LocalID dbID, sortInfoID, oldSortInfoID = 0; MemHandle h; MemPtr p; UInt32 size = 0, offset = 0, uniqueID; UInt16 numRec, i; UInt16 numDB = 0; // get the sort info ID DmOpenDatabaseInfo(dbP, &dbID, NULL, NULL, &cardNo, NULL); DmDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &sortInfoID, NULL, NULL); if (sortInfoID) oldSortInfoID = sortInfoID; // count the terminal tasks that pass the filter for (i = 1; i < numRec; i++) { if (FlatFilter(dbP, i)) size++; } size *= sizeof(UInt32) + sizeof(UInt16); // UniqueID stored here as UInt32 // DB stored as index in the list if (size == 0) // no tasks pass filtering { UInt32 zero = 0; h = DmNewHandle(dbP, sizeof(UInt32)); sortInfoID = MemHandleToLocalID(h); // set this handle in the db DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &sortInfoID, NULL, NULL); p = MemHandleLock(h); DmWrite(p, 0, &zero, sizeof(UInt32)); } else { // get a new handle for the list h = DmNewHandle(dbP, size); if (!h) { DEBUG1("Cannot allocate memory for the flat list. Free some memory before retrying."); return pgError; } sortInfoID = MemHandleToLocalID(h); // set this handle in the db DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &sortInfoID, NULL, NULL); p = MemHandleLock(h); // store the terminal task's UniqueID for (i = 1; i < numRec; i++) { if (FlatFilter(dbP, i)) { // get the uniqueID of the task DmRecordInfo(dbP, i, NULL, &uniqueID, NULL); // store it DmWrite(p, offset, &uniqueID, sizeof(UInt32)); offset += sizeof(UInt32); } } } // release the handle MemHandleUnlock(h); if (oldSortInfoID) { h = MemLocalIDToGlobal(oldSortInfoID, cardNo); if (h) MemHandleFree(h); } if (gProjectPrefs.flatSorted) FlatSort(dbP); return pgOK;} // pgErr FlatCreateGlobalList(void)#endif/**************************************************************************** * Name : FlatSort * Desc : sort the flat view array * Parm : * -> db * Out : pgErr * Auth : lb, 21.09.2000 ***************************************************************************/pgErr FlatSort(DmOpenRef dbP){ UInt16 cardNo = 0; LocalID sortInfoID; UInt32 *p; // get the sort info block DmDatabaseInfo(cardNo, gdbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &sortInfoID, NULL, NULL); // nothing to sort if (!sortInfoID) return pgOK; p = MemLocalIDToLockedPtr(sortInfoID, cardNo); Sort(dbP, p); MemPtrUnlock(p); return pgOK;} // pgErr FlatSort(DmOpenRef dbP)/**************************************************************************** * Name : sort * Desc : sort an array of pointers to tasks * Parm : * -> db * -> pointer to the array * Out : pgErr * Auth : lb, 21.09.2000 * Rem : bubble to test * TODO : insertion sort, or quick sort ***************************************************************************/pgErr Sort(DmOpenRef dbP, UInt32 *p){ UInt16 nbItems = MemPtrSize(p) / sizeof(UInt32); UInt16 i = 0, j; Boolean finished = false; MemPtr temp; TaskExtendedRecordType **sortArray; UInt32 a, b; UInt16 index; UInt16 debug = 0; // empty or one-item list, just return if (nbItems < 2) return pgOK; sortArray = MemPtrNew(nbItems * sizeof(MemPtr)); if (!sortArray) { DEBUG1("Not enough memory to sort"); return pgError; } // fill the array for (i = 0; i < nbItems; i++) { DmFindRecordByID(dbP, p[i], &index); sortArray[i] = MemHandleLock(DmQueryRecord(dbP, index)); } i = 0; while (i < nbItems - 1 && !finished) { finished = true; for (j = 0; j < nbItems - 1 - i; j++) { if (CmpTasks(sortArray[j], sortArray[j+1]) == -1) { // swap temp = sortArray[j]; sortArray[j] = sortArray[j+1]; sortArray[j+1] = temp; a = p[j]; b = p[j+1]; DmWrite(p, j * sizeof(UInt32), &b, sizeof(UInt32)); DmWrite(p, (j+1) * sizeof(UInt32), &a, sizeof(UInt32)); finished = false; debug++; } } i++; } // unlock all for (i = 0; i < nbItems; i++) { MemPtrUnlock(sortArray[i]); } MemPtrFree(sortArray); return pgOK;} // pgErr Sort(DmOpenRef dbP, UInt32 *p)/**************************************************************************** * Name : CmpTasks * Desc : compares two tasks * Parm : * -> pointers to the array * Out : -1 : a comes after b * 1 : a comes before b * 0 : a equal b * Auth : lb, 21.09.2000 ***************************************************************************/Int16 CmpTasks(TaskExtendedRecordType *a, TaskExtendedRecordType *b){ Int16 result; TaskStandardFields *ta, *tb; ta = StdFields(a); tb = StdFields(b); if (gProjectPrefs.flatSorted == sortDateFirst) { result = CmpDate(ta, tb); if (result == 0) result = CmpPriority(ta, tb); } else { result = CmpPriority(ta, tb); if (result == 0) result = CmpDate(ta, tb); } return result;} // Int16 CmpTasks(TaskExtendedRecordType *a, TaskExtendedRecordType *b)/**************************************************************************** * Name : CmpDate * Desc : compares the dates of two pointed tasks * Parm : * -> pointers to the tasks * Out : -1 : a comes after b * 1 : a comes before b * 0 : a equal b * Auth : lb, 21.09.2000 ***************************************************************************/Int16 CmpDate(TaskStandardFields *a, TaskStandardFields *b){ // a and/or b have no date if (a->dueDate.month == 0 || b->dueDate.month == 0) { if (a->dueDate.month == 0 && b->dueDate.month == 0) { return 0; } else if (a->dueDate.month == 0) { return -1; } else { return 1; } } // both have a date if (a->dueDate.year == b->dueDate.year) { if (a->dueDate.month == b->dueDate.month) { if (a->dueDate.day == b->dueDate.day) { return 0; } else { return a->dueDate.day < b->dueDate.day ? 1 : -1; } } else { return a->dueDate.month < b->dueDate.month ? 1 : -1; } } else { return a->dueDate.year < b->dueDate.year ? 1 : -1; }} // Int16 CmpDate(TaskStandardFields *a, TaskStandardFields *b)/**************************************************************************** * Name : CmpPriority * Desc : compares the priorities of two pointed tasks * Parm : * -> pointers to the tasks * Out : -1 : a comes after b * 1 : a comes before b * 0 : a equal b * Auth : lb, 21.09.2000 ***************************************************************************/Int16 CmpPriority(TaskStandardFields *a, TaskStandardFields *b){ if (a->priority == b->priority) { return 0; } else { if (a->priority == 6 || a->priority == 0) return -1; if (b->priority == 6 || b->priority == 0) return 1; return a->priority < b->priority ? 1 : -1; }} // Int16 CmpPriority(TaskStandardFields *a, TaskStandardFields *b)/**************************************************************************** * Name : FlatLinkAll * Desc : ToDo (un)link all tasks in the flatview * Parm : * -> db * -> link (true = link, false = unlink) * Out : * Auth : lb, 22.10.2000 ***************************************************************************/void FlatLinkAll(DmOpenRef dbP, Boolean link){ UInt16 i, index; UInt16 cardNo = 0; LocalID sortInfoID; UInt32 *p; UInt32 size = 0; // get the sort info block DmDatabaseInfo(cardNo, gdbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &sortInfoID, NULL, NULL); p = MemLocalIDToLockedPtr(sortInfoID, cardNo); size = MemPtrSize(p) / sizeof(UInt32); // if gdbP contains at least one task, there is at least one terminal task // special case, db empty (just task 0) if ((PgNumRecords(dbP) == 1) || (*p == 0)) { MemPtrUnlock(p); return; } for (i = 0; i < size; i++) { DmFindRecordByID(dbP, p[i], &index); if (index) { // if hasToDo != link if (TaskGetFormat(dbP, index).hasToDo != link) { if (link) { TaskSetType(dbP, index, actionType); TaskSetCompleted(dbP, index, ACTION_NOT_DONE, true); TaskPublishToDo(dbP, index); } else { TaskRemoveHasToDo(dbP, index); } } } } MemPtrUnlock(p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -