These are random notes about the software that might provide some insight into how it works. Please post a note to Discussions if any point should be expanded.
- Since there is an AllocatedBy field, the SafeTask has a corresponding AllocatedTo field. The XML has this as a generic PERSON array though the UI does call it "Allocated To".
- Categories are sorted in the .tdl file, so they are represented as a SortedSet<String>. While Dependencies are not, so they are represented as a List<String>. AllocatedTo is also sorted.
- A SortedSet of Tags is maintained at the list level. Categories are in a SortedSet only at the task level. This is according to the TDL schema, not a limitation of the library. Tags added to a task must have an existing entry in the list. This is not the
case for Categories.
- Related to above, it's not required to first have a tasklist before creating SafeTasks. Applying a SafeTaskList to a new SafeTask is optional. However, some operations will throw an exception if no list is available. For example, since we don't want to
add a task to include a tag which is not defined at the list level, an attempt to add such a tag will throw an exception if a list is not first defined for the task, or if the tag is not defined in the defined list. An attempt to add a category does not fail
since no check needs to be made of the parent list. Similarly, adding a CustomAttribute to a SafeTask will fail if no SafeTaskList has been defined for that task object.
- To eliminate the issue above you can create new tasks using the SafeTaskList method GetNewTask, which inserts a reference to itself into the new SafeTask that is returned. That method by default will use the NextUniqueID to assign an ID to the task. However,
if there is a chance that the ID will not be added, or if the task is being used for other purposes, the method allows an optional Boolean parameter to avoid assigning the ID.
- The XML refers to estimate fields as both "Estimate" and "Est". The SafeTask refers to all fields with the full "Estimate" name.
- The TDL UI refers to "Completed" and "Compl. Time" for the date/time when a task was finished. The XML uses DoneDate, so the SafeTask also uses DoneDate.
- The concept of having a setter on a calculated field may be questioned. The idea here is that you don't like the setter, don't use it. If you do want to use it, be sure you do the calculation properly. Otherwise leave the calculation to ToDoList. We need
to come back to this because TDL doesn't calculate values until data changes in TDL and a .tdl updated with the library may leave calculated values incorrect until such an event is triggered.
- SafeTask IDs are nullable Integers. Apps are allowed to change task IDs, but not allowed to null the value of an existing ID. The ID may be assigned in the SafeTask constructor if a SafeTaskList is passed in and the optional useNextUniqueID value is true
(default). If no list is associated with a new task or if useNextUniqueID is false, the initial ID value is left as null.
- Apps are not allowed to null the last modified timestamp.
- The creation date can only be set for new tasks created with the no-argument constructor. An app cannot set the creation date for tasks read from a .tdl file.
- Names of people, categories, and status codes are not checked for validity.
- Task Recurrences are complex in nature, but the concept is supported by a very simple XML mechanism - a single tag with a few properties. A lot of classes have been created to support the concept in a type-safe manner. Enums are used to ensure invalid data
doesn't creep in. Each recurrence type has been conceptualized as a series of related classes which help the developer to implement concepts with as little chance of error as possible. This at the cost of some complexity but I'm doing my best to ensure it's
all logical, as consistent as possible, and easy to follow.
- The xsd.exe tool generates an array of TASKRECURRENCE objects because recurrence is implemented in the XML as a node with its own attributes. It has no idea that we only use this node once. Compare this to PERSON and CATEGORY where we do have multiple nodes
requiring an array. The SafeTask class handles this transparently, exposing a singular Recurrence property and then just operating on array element 0 in the underlying code.