When I first released ToDoList more than 11 years ago it was as a consequence of exploring some UI ideas, the principal of which was using the non-client region of a tree-view control to draw attribute columns.

But while this satisfied my research goal it had a major drawback: The attribute columns could not move independently of the task titles meaning that if you displayed too many columns the task title got squeezed and some of the attribute columns might not be visible.

In addition there was no column reordering or resizing because I would have had to write this from scratch and that seemed too great an effort when the built-in Windows list-view gave you that for free. So I pushed the problem into the background and palmed-away questions as they came up.

Then sometime in 2012 I started to think about creating a Gantt plugin and I realised that the 'tree-part' and the 'bar-part' were going to have to be physically separate because the 'bar-part' was definitely going to need to scroll horizontally but that scrolling could not cause the 'tree-part' to be hidden. And I further realised that solving this might also provide the solution to Task-Tree attribute columns issue.

So I started work on a 'Tree-List-Syncer' whose primary goal was to synchronise the vertical scrolling of either a tree and a list or two lists, positioned side-by-side. Additionally the LHS widget had to hide its vertical scrollbar and instead respond to scroll events from the RHS widget.

The Gantt plugin was released with 6.7 in 2013 and proved successful as a solution yet it still took a couple more versions for me to summon up the courage to pull open the guts of the app to replace the Task-Tree and List-View. I think I was still hoping that the Gantt plugin would reveal a huge flaw in my approach so that I didn't have to do the work!

But here it is. Both the Task-Tree and List-View now have task attributes that can be scrolled horizontally without impacting the task titles. They are divided by a splitter bar (which can be effectively hidden in the preferences) giving total control over 'pane' widths. Attributes columns can be reordered and resized by dragging the column header dividers ala Explorer.

I do understand that some of you will find these changes upsetting but they had to made in order that other more important usability features could be included to keep ToDoList relevant.

Introduction

You know how it is - you start work on one project and halfway through, you find one or two side-projects crop up that have to be solved before you can continue on the original project.

This is one such project with the added twist that it too started its life as a side-project. Here's what happened:

<Cue wavy screen effect>

I can only imagine that the planets must have been in (mis-)alignment or something, because at one point a few months ago, I was suddenly fielding emails on four or five separate articles I had previously submitted to CodeProject, some asking for features and others for bug fixes.

Foolishly or otherwise, I largely agreed with all the points raised, and subsequently found myself with fourteen or fifteen separate issues to resolve.

The situation was also made worse because I was trying to use CodeProject to keep track of all the things I had agreed to do, meaning that I had to continuously trawl the comments section of each article to remind myself of what I was supposed to be working on.

It even got to the stage where I was worrying that I'd fail to deliver on something - silly I know, but there you are!

Keeping a list on paper was a definite step in the right direction, but since I do all my coding on the same machine, it seemed somewhat inelegant, and anyway, we all know what happens to crucial bits of paper left lying around on desks and such.

The next step was to hunt around on the web for a tool to meet the following requirements:

Simple interface

Support for hierarchical data

Numbered items/subitems

Open file format

Freeware

Simple, huh! not!

I will admit that I did not spend weeks searching, but I am still surprised at the general lack of software matching my needs.

On reflection, I think that the reason may be simple: people are so used to commercial software being 'feature-rich' that when they come to design software themselves, they (not unreasonably) think they too need to cram as much in as possible, often leading to software where a lot of essential functionality is hidden away in the menu bar.

So, surprise, surprise, I decided to write something myself.

However, it's fair to say that I did not originally intend to post it on CodeProject and am only really doing so because I had a heap of fun solving some very interesting problems and these are what I think make it worth it.

Using the Software

There's really very little I need to say here since every feature/function is explicitly visible in the interface.

Nevertheless, the following list of basic capabilities and omissions may go someway to answering any questions that arise:

Files are stored in XML format with .xml file extension.

Trying to load a non-tasklist file will generally fail (unless you read the code to see how to circumvent it).

The number of items/subitems is limited only by memory (although performance may be the deciding factor before you exhaust memory).

Marking a parent item as 'done' will also gray-out child items, but they are not disabled or automatically marked as 'done'.

An ellipsis (...) indicates that an item has sub-items.

All items can be expanded or collapsed (by double-clicking).

Top-level items and sub-items are created using different toolbar buttons.

There are task-specific context-menus.

The previously open tasklists are re-opened on startup.

The tasklist is automatically saved when closing the software or minimizing it to the system tray.

The priority of a task is shown as a grayscale box to the left of the item.

Points of Interest

Here's where we come to the side-projects I was talking about, the first two of which I intend to work up into follow-up articles.

They are:

The 'ordered' tree control, which incorporates a non-client gutter for displaying the item numbers.

The idea stemmed from research I did into alternative designs for a tree-list control, which did not solve it by creating a hybrid control incorporating a tree and a list.

The hybrid control seems such an obvious solution that I suspect few people have stopped to question it, but it has still always struck me as looking far too much like hard work to be truly elegant ('square pegs' and 'round holes' spring to mind).

One possible idea is to implement the 'list' portion entirely in the non-client area of the tree. I.e., shift the right hand client edge to the left and then render the list portion in the resulting non-client area.

Whilst I've yet to get round to building a proof of concept, it was nevertheless this ongoing mental debate which prompted me to try to solve the requirement for numbered items and subitems by rendering the item/subitem numbers in the non-client area.

Without going into too much detail (as this will subsequently be an article of its own), this is how I got it to work:

Handle TVM_INSERTITEM and TVM_DELETEITEM to know exactly when items are added and removed.

In these handlers recalculate the width of the gutter required to display the widest 'dotted' item/subitem number. (Note: this is not necessarily simply the deepest subitem.)

Handle WM_NCCALCSIZE when it does, and offset the left border by the required gutter width.

Handle WM_NCPAINT for painting the numbers.

This is necessarily an over-simplification, but it captures the essence of the solution, and all that essentially remains is lots of fiddling about to ensure the non-client area gets redrawn at the the right times to stay synchronized with the client area.

Embedding .RC control definition data directly in a .cpp file to break the dependency on binary resources (a.k.a. 'Runtime Dialogs').

This is an idea that has been floating about for quite some time and which has only recently gelled into a workable solution.

The problem, put simply, is that if you want to take advantage of the resource editor in Visual Studio (and who doesn't), then you very quickly find yourself stuck with having to load dialog templates from resources compiled into the binary file.

This further means that if you want to make use of a dialog across multiple projects, then either you need to copy and paste the dialog template between project .RC files, or you need to build the dialog into a DLL from which it can be accessed.

'Runtime Dialogs' (a snappy title I coined myself) is a solution that neatly sidesteps both the nuisance of copying dialog resources between resource files and the extra work (and maintenance) involved in packaging dialogs in DLLs.

And it works like this:

First, you design your dialog template in the resource editor, create a CDialog derived class using class wizard, and wire up all the controls just as you normally would.

Next, you #include "runtimedlg.h" and change all instances of CDialog to CRuntimeDlg.

Then, you cut and paste the control definition section from the appropriate section in the .RC file and embed it directly in the dialog's .cpp file as a static string (with a bit of tweaking to handle double quotes and such like).

Finally, in the constructor of your dialog, you simply call CRuntimeDlg::AddRCControls(...) passing the control definitions as a string.

And CRuntimeDlg takes care of the rest including, if required, auto-sizing the dialog to suit the control layout.

I'm certainly not suggesting that this is a 'win-win' solution for all situations but it certainly has merits in its closer coupling of dialog template to dialog code which makes sharing dialogs across multiple projects a breeze.

P.S.: In case it's not clear here, I used CRuntimeDlg to create CToDoCtrl which encapsulates the ordered tree together with the priority, date and comments controls as a single simple-to-instantiate control.

This is possibly the most satisfying aspect of the whole project because it was completely unexpected.

What I mean is that, until recently, my knowledge of DOM and XMLDOM was virtually non-existent, as it's only since I've become more interested in the presentation of AbstractSpoon that I've been forced to get to grips with the various implementations of DOM and XMLDOM out there.

I'm pleased to say that the code on my site works under IE 6.0, Netscape 7.1, and Mozilla, although custom code was required to achieve this.

Generic MFC Classes that may prove Useful to You

The following table lists a wide range of utility classes written for this project. They can all be included in any MFC project provided you include any class dependencies too. Feel free to ask any questions relating to these specific classes and how to use them.

Adds support for recognizing urls, clicking them and setting custom url callbacks

CWinClasses

Encapsulates the ::GetClassName Win32 functions

CXmlFile, CXmlItem

Non-Unicode class for reading and writing xml files

CXmlFileEx

Adds encryption capabilities to CXmlFile

CXmlFile, IEncryption

* CSubclassWnd was originally written by Paul DiLascia for MSJ magazine. The version I use has been heavily extended to suit my specific needs. The classes that depend on it here need this extended version.

Further Work

Whilst this tool was originally intended for my personal use only, it is now a 'community' project, so if you find it useful and want to make suggestions for enhancements or bug fixes, then post below.

History

7.0.13 (04 Feb 2016) - Mostly likely the last update of 7.0

Fixed uneven task row heights on Windows XP 64-bit

Fixed incorrect strike-through in Find Tasks dialog for incomplete parent tasks having all their subtasks completed

Fixed doubled-up Help Menu separator on XP

Fixed translation 'Cleanup' button not saving changes

Fixed XML encoding for Unicode tasklists

Fixed tasklist tab-bar resize bug after double-clicking on titlebar

7.0.12.1 (20 Jan 2016)

Fixed loading of Ansi tasklists

7.0.12 (14 Jan 2016)

Fixed bug where pasting a text fragment from Firefox would display the wrong source URL

Fixed List View selection render artifacts in full screen when resizing the title pane

Fixed inability to tab to Status field after making the field 'read-only'

Comments and Discussions

Hi Dan, Just wondering whether you have thought any more about multi-state flags. I am just setting up plans for the year using 6.6a5, and updating columns and user defined attributes. One thing I was really keen on was multi-state flags.

I think this could be achieved in two ways: - A flag attribute that cycles through several states, each state having a unique 'icon' and name, defined as a list in the custom attribute. Cycle by clicking the task grid. Sortable. - An icon attribute type that has a defined icon set. The icons would be defined as a list in the custom attribute. Change in the bottom bar. Sortable.

Any plans in this regard at all? At the moment I am having to set up multiple custom flags, and this will cause issues when sorting (as there are only 3 sorting paraments available in multi-sort.zajchapp

I might try to extend the custom attributes in 6.6 to support 'flag-lists' that support clicking to cycle thru the items.It will probably be a fairly limited implementation just to get things started, and if it gets too complicated then I will move it to 6.7.

I've had a look and, to avoid compatibility issues, I would prefer to add an entirely new attribute type: Flag (multi-value).

This will ensure that I do not break any existing attributes, but means that it will have to wait until 6.7 because it will require UI changes.

To support actual images instead of text, I will use a simple protocol like 'img:<name>' that can be inserted in the 'default list data' widget. I will also add a button for the user to browse images from the task icon dialog.

This is probably pushing the boat out a bit far but if you don't ask...

Also very useful would be the ability to choose to show (or not) the multi-state flag values (or at least the image names) in a drop down list in the edit and filter bars (e.g. like the status attribute). That way you could filter on the flag values.

Further, having the ability to set the order of the flags in the attribute definition is going to be important. Automatically sorting these by alphabetical order will be less useful.

Also very useful would be the ability to choose to show (or not) the multi-state flag values (or at least the image names) in a drop down list in the edit

Indeed, it occurred to me when think about this that other 'Single-selection-fixed-list' attributes (eg. priority/status/allocby) could also be treated like multi-value Flag attributes in the task-tree such that repeated clicking would cycle thru the items.

So what you are asking for is simply the corollary of this, to display multi-value flags as if they were just fixed droplists.

Thinking a bit more, perhaps I don't need a new attribute type at all, just extend the 'single-selection-fixed-list' attribute to support images, and support 'click-cycling'.

zajchapp wrote:

having the ability to set the order of the flags in the attribute definition is going to be important

It's my intention not to sort 'fixed-content' lists since the user can do that when they specify the list data. 'Dynamic-content' will remain sorted so that new items can be more easily found when scanning the list.

Thinking a bit more, perhaps I don't need a new attribute type at all, just extend the 'single-selection-fixed-list' attribute to support images, and support 'click-cycling'.

This is great news, as this is what I was actually after (if I understand you correctly).

For instance, I am keen to use this for replacing the status attribute - therefore the Task grid would have icons instead of words (more visual, less space used), and you would be able to cycle through the statuses. I assume it wouldn't be possible to add icons to the current built in attributes like status?

Some columns in the task tree respond to double-clicking (task icon, file-link, recurrence, reminders, dependencies) and others to single-clicking with a cursor changes (time-tracking, flag).

There is no obvious logic to this, so I propose to change all such editing (including list-cycling) to be single-click /cursor. This is actually better than double-clicking because the 'hand' cursor indicates that an edit action is possible, and therefore prompts the user to explore the UI.

I would agree with your thinking.I guess the only concern I have would be that you would need to be more careful where you click on the grid when selecting tasks. Safest would then be to always click on the title, rather than the rest of the grid, to prevent accidentally opening a dialog. At the moment, most of the grid is 'safe'. Might be worth asking more broadly on that one.

PS: Icon column seems to be single click already, not double click.PPS: I didn't realise you could double click the other attributes (e.g. recurrence).

Once this is all in place, it will enable better management of projects in my opinion. For instance, it will allow easy 'traffic light" reporting. E.g. attributes such as cost, scope, schedule could have 3 icons - green light, amber light, and red light (on track, at risk, behind). Great for visual assessment of the status of a project - or several projects - over a bunch of attributes.

Sorry, a bit of a throwaway comment about a specific use. And possibly not core to what TDL tries to achieve.

When reporting on projects to sponsors / managers etc, there are often a set of key parameters reported on. These cover the key aspects of a project, such as scope, cost, risk, benefit etc... This is also often used when reporting on the status of multiple projects in a project portfolio.

A simple, visual mechanism used to report on the state of a project is the traffic light system - green is good, amber shows risk, and red indicates a serious issue.

My thinking is that with the icon sets, TDL will be able to be used for reporting on a list of projects. Each of the aspects will be a custom attribute. Each of the attributes could have 3 icons assigned - green, amber, and red traffic lights. This would probably be a tasklist with a list of projects, providing a high level summary of the state of all projects. Perhaps you would also include some of the major phases as sub-tasks. Combining this with the Gantt chart, would be great for managing a portfolio of projects.

The only concern would be that it would probably need to be a separate tasklist to the project tasklist, as the columns needed for the portfolio would be different to those of the project. There may be >10 key aspects of a project in the portfolio. Being able to hide certain columns would of course solve this...

Will this approach still allow a selection box in the filter and edit bars?

Yes and Yes.

zajchapp wrote:

Does this change the implementation date?

It will be available for the first Dev Release of 6.7. Indeed, the implementation of the edit field is already done, I just need to add support for filtering on custom attributes, which could be quite involved so this aspect may follow in a later Dev Release.

I am a "power user" of ToDoList and like it very much. In fact, I have used it so much that I think I have reached some type of limit! Is there actually a limit on the file size or number of tasks?

The file size is up to 8MB and there are thousands of tasks. It has been taking around 45 seconds to save the file and it always says "Not Responding" after about 10 seconds when saving, but then "comes back" when done saving.

About a month a ago, I reported that my tasks sometime disappear from view (when marked as "complete"), but now something else is happening:

Recently I have noticed that some tasks have literally disappeared (by themselves). I know I did not delete them accidently and I am not sure exactly when/how they disappear (so I cannot tell you how to recreate how to make it happen), but I can send you my TDL file, if you want.

Any help or advise you can give would be greatly appreaciated, as I just recently switched to using ToDoList for my projects at work and want to continue to use it. Thanks!

Actually I am not totally sure that this issue is due to the size of the TDL file. That is just a guess on my part.

However, I am definitely experiencing a bunch of sub-tasks disappearing in random places at random times (not sure why). Also, something that started to happen again is that suddenly, all of inheritable columns for all of my tasks get cleared out and are just blank. I reported this once before, and thought it stopped happening, but it started again. Maybe this is related to the "disappearing tasks" problem?

Anyway, It seems like I may be the only one having this problem, so that is strange. I already sent my preferences file. Any help with this would be appreciated, since nothing I am trying is helping and I am out of ideas. Thanks!

Thanks for working on this, Dan. I really appreciate it and I know you are committed to making ToDoList the best it can be for everybody.

I am (and will be) continuing to use ToDoList because I have transferred all my tasks to it (was using TimeTo, Stickies & paper) and it works great for me. However, it's a little scary with these strange, seemingly random, things happening.

Since it seems like I am the only one having this issue, I wouldn't be surprised if it is something I did wrong. I hope you can, eventually, find out what's happening to my tasks. If you need any more files or info, please let me know. Thanks!

Sorry about the delayed response. No, they didn't get archived. Automatic archiving is not turned on.

Some tasks actually disappeared for some reason. I can't tell why/when this happens because I am probably not finding out they are missing right away after it happens.

I am currently using version 6.5.10 and I haven't noticed any missing tasks lately, but I can't be sure this isn't still happening.

I need to go to my backup files and try to restore some missing tasks, somehow, but I was hoping to confirm the issue no longer exists first (otherwise things might disappear again). If you have any ideas or anything I can try to figure this out, I would appreciate it. I mentioned that my TDL file was getting big, but I really don't know if that has anything to do with it. I will keep an eye on the size of the TDL file to try and determine if tasks are still disappearing or not. Thanks!

I've been using 6.6 since alpha 1. My main task list, which I started in alpha 3, is at version 664, has 192 tasks, and is 540 KB. The two alpha features that I've used are

Quote:

Calculate a parent task's due date as being the latest of its subtasks' due dates Calculate a parent task's start date as being the earliest/latest of its subtasks' start dates

And they are working fine.

I'm in TDL off and on about 8 hours a day, sorting, filtering, switching between the views, and switching between fullscreen comments, the fullscreen tasklist, and the split-screen. I write or add to lengthy rich-text comments that include tables, formatting, and links. I use the timer when working on tasks and log the time. I export to .csv and use many of the other features besides. I've lost no data, TDL is stable, and I'm able to keep track of everything that I'm working on in a 6-month multi-phase project. So, I think 6.6 is definitely ready for beta.

Hello DanI am using 6.6 release 5.I have posted in another thread the problem related to the task inheritance.Here is the description of the problem:The task inheritance doesn't work when the display language is set to Russian.When i am back to english language, it works.

To reproduce the error please follow the steps:1. Change the display language to Russian.2. Restart the application3. Menu Инструменты>Настройки>Атрибуты наследования(Menu Tools>Prefferences>Inheritable attributes)Set/remove the flag to Tags. Click OK to close the settings window.4. Open the settings window and chech the Tags flag. The changes from 3. has not been applied.

ToDoList is really great for me. The only feature that I really feel that is missing is aligning tasks in Right-To-Left instead of the current state Left-To-Right.I'll be glad if you'll add it to the features list.

I'm currently experimenting with a new control I've created which synchronises a tree and list together and has the capability to swap the list and tree. This will demo first in the new Gantt view, and if it's a success then I will rewrite the current tree and list views to use it. But that's a little time off (~6 months).

Let's suppose that i have the following tree:-Project 1--task1 (start date: today)--task2 (start date: today)--task3 (start date: tomorrow)--task4-Project 2--task1(start date: today)--task2(start date: today)--task3 (start date: tomorrow)--task4In calendar view, i want to show only the top task (task1) from each project.Is this possible?

Not sure if this helps but...I have often wanted to represent only certain tasks in a hierarchy. The way I worked around this was to use a tag that I would filter on prior to viewing / exporting.For instance, when exporting to GanttProject, I use a Tag "showinGantt" to filter on prior to export. This Tag is obviously set for those tasks I want to review in the Gantt. I usually exclude the smaller tasks, as I am only looking at things fairly broadly.I am thinking of using this approach for the built-in Gantt and Calendar tabs.zajchapp

The example above would mean the task would only show up Monday to Friday from 9 to 5. Business-Calls e.g. would meet those validity times.

It would help to keep the tasklist lean and to present only relevant (do-able) tasks at any given time. To maximize flexibility and different workhours for each day of the week the Time span could made editable for each day. I guess it would make sense to define & save up to 5 such Validityzones in the Prefs and simply assign tasks to those zones!

Showing up and vanishing of tasks would have to work automatically. If one had to set a filter and to remember when to set it would not make sense!