Click here to Skip to main content
15,868,016 members
Articles / Programming Languages / XSLT
Article

TaskListManager

Rate me:
Please Sign up or sign in to vote.
1.03/5 (13 votes)
13 Mar 2008CPOL2 min read 50.4K   1.2K   31   14
In a cumbersome daily schedule, only tools like this can help us to be a little bit organized.

Introduction

TaskManager is a personal information manager (PIM). It's a tool for managing any kind of personal information such as tasks, events, contacts, favorites, and web links which can be browsed on the same form. It can be used as a mind stimulator, and a self-analysis and self-improvement tool.

In TaskManager, there is no database used; all the relevant information is stored in XML files. It can be one of the best examples of inter-operability of two XML files.

We need not to install a database for using this application.

Task_1.JPG

There are mainly three sections:

Task management: Alerts for pending tasks. Add, Remove, Edit, and Export Task List as HTML or Excel file. For adding or editing the task list, we need to click the Task button in the left pane.

Task_2.JPG

All pending tasks will be displayed as a tooltip in the tray icon. On clicking the tool tip, the user can display the main form.

Contacts management: View contacts as a tree view, easy navigation, adding and deleting contacts. Create groups for all the contacts.

Contacts.JPG

Internet Favorites: Fetching all the folders and links from Internet Explorer Favourite list and displaying it as a treeview. Navigation of the favourite node and displaying the page in a web browser of the same form. Once the application is installed, it will fetch the favourites at runtime.

Fav.JPG

Using the code

I have tried to make it self explanatory and hierarchal. The main classes are: TreeViewSerializer.cs, ContactForm.cs, and TaskManagerForm.cs.

The method below will take care of adding a task in the tasks table of the TaskList XML file.

C#
/// <summary>
/// Utility method to update the visual representation of
/// the tasks (the CheckedListBox) with a new or updated row.
/// </summary>
/// <param name="rowIndex">Index of modifed row, or -1 for new row</param>
/// <param name="row">Row object from the DataTable</param>
private void UpdateDisplayWithRow(int rowIndex, TasksDataSet.TasksRow row)
{
    string title, format = "{0} - Due: {1:d}";

    title = string.Format(format, row.TaskTitle, row.TaskDueDate);

    if (rowIndex == -1)
    {
        tasksCheckedListBox.Items.Add(title, row.TaskComplete);
    }
    else
    {
        // Remove the old value, add a new one, set the checkbox
        tasksCheckedListBox.Items.RemoveAt(rowIndex);
        tasksCheckedListBox.Items.Insert(rowIndex, title);
        tasksCheckedListBox.SetItemChecked(rowIndex, row.TaskComplete);
    }
}

/// <summary>
/// Loads the entries using XML deserialization
/// </summary>
public void LoadEntries()
{
    try
    {
        XmlSerializer s = new XmlSerializer(typeof(TasksDataSet));
        TextReader r = new StreamReader("TaskList.xml");
        ds = (TasksDataSet)s.Deserialize(r);
        r.Close();

    }
    catch
    {
        ds = new TasksDataSet();
    }

    foreach (TasksDataSet.TasksRow row in ds.Tasks)
    {
        UpdateDisplayWithRow(-1, row);
    }
}

/// <summary>
/// Saves the entries using XML serialization
/// </summary>
public void SaveEntries()
{
    try
    {
        XmlSerializer s = new XmlSerializer(typeof(TasksDataSet));
        TextWriter w = new StreamWriter("TaskList.xml");
        s.Serialize(w, ds);
        w.Close();
    }
    catch( Exception x )
    {
        appNotifyIcon.ShowBalloonTip(8000,
            "Bh@nu's - Task Manager",
            "Tasks could not be saved.\n" + x.Message, ToolTipIcon.Error);
    }
}

The CheckTaskDates() method will check the expiry of tasks in a task list. All the pending tasks will be displayed as a tooltip on the tray icon every minute.

C#
/// <summary>
/// Scans the list of tasks. Any incomplete tasks due
/// yesterday or earlier are appended to a buffer for
/// display in the tooltip.
/// </summary>
private void CheckTaskDates()
{
    // StringBuilder is more efficient than string concatentation
    StringBuilder buffer = new StringBuilder();

    // Iterate over each task in the DataSet
    foreach (TasksDataSet.TasksRow row in ds.Tasks)
    {
        // Compare date and completed flag
        if ((DateTime.Now.Date > row.TaskDueDate) && !row.TaskComplete)
        {
            buffer.Append(row.TaskTitle).Append(", Due: ");
            buffer.AppendFormat("{0:d}", row.TaskDueDate).Append('\n');
        }
    }

    // If the buffer is not empty, there is at least one
    // task to display
    if (buffer.Length > 0)
    {
        // Display an Info balloon tip for 8 seconds
        appNotifyIcon.ShowBalloonTip(8000, 
            "bh@nu's - Task Manager", 
            buffer.ToString(), ToolTipIcon.Info);
    }
}

Another important method is there in the ContactForm class. This method will take care of adding new contacts in two XML files along with its unique group and ID. One XML file will contain the treeview data and the other one will contain the details. I have made these two XML files for ease of displaying the treeview.

C#
private void btnUpdate_Click(object sender, System.EventArgs e)
{
    TreeViewSerialization.TreeViewSerializer objTreeViewSerializer = 
                    new TreeViewSerialization.TreeViewSerializer();
    //objTreeViewSerializer.SerializeTreeView(this.treeView_Contacts,
    //       Application.StartupPath + "\\..\\..\\bhanu.xml");
    objTreeViewSerializer.SerializeTreeView(this.treeView_Contacts, 
                          Application.StartupPath + "\\bhanu.xml");

    bool bAddNew = (m_iContactID == 0) ? true : false;

    bool bContinue = true;

    try
    {
        string sFullName = txt_Name.Text;
        string sCellPhone = txt_Cell.Text;
        string sHomePhone = txt_Home.Text;
        string sEmail = txt_Email.Text;
        string sEmail2 = txt_Email2.Text;
        string sAddress = txt_Address.Text;
        string sCity = txt_City.Text;
        string sState = cmb_State.Text;
        string sZip = txt_Zip.Text;
        string sBDay = dt_DateTimePicker.Value.ToLongDateString();

        if( sFullName == "" || sCellPhone == "" || 
            sHomePhone == "" || sEmail == "" || 
            sEmail2 == "" || sAddress == "" || 
            sCity == "" || sState == "" ||
            sZip == "" || sBDay == "" )
        {
            MessageBox.Show( "You must have valid data in each field before" + 
                             " you may\nadd this contact to your contact's list.", 
                             "Validation Error...", MessageBoxButtons.OK, 
                             MessageBoxIcon.Exclamation );
            bContinue = false;
        }

        if( bContinue )
        {
            if( bAddNew == true )
            {
                AddContact( m_XmlDocument, m_iNextID, sFullName, 
                    sCellPhone, sHomePhone, sEmail, sEmail2, sAddress,
                    sCity, sState, sZip, sBDay );
          
                AddContactToCombo( m_iNextID, sFullName );
          
                m_iNextID++;
            }
            else
            {
                UpdateContact( m_XmlDocument, m_iNextID, sFullName, 
                    sCellPhone, sHomePhone, sEmail, sEmail2, sAddress,
                    sCity, sState, sZip, sBDay );
            }
    
            m_XmlDocument.Save( m_sXmlFileName );
        }
    }
    catch( Exception exception )
    {
        MessageBox.Show( exception.Message );
    }
}

private void treeView_Contacts_AfterSelect(object sender, TreeViewEventArgs e)
{
    AddNewContact();
    if (treeView_Contacts.SelectedNode.Text == "Friends" || 
        treeView_Contacts.SelectedNode.Text == "Work")
    {
        return;
    }
    else
    {
        this.txt_Name.Text = this.treeView_Contacts.SelectedNode.Text;

        string strEmail = string.Empty;
        XmlDocument xmlContacts = new XmlDocument();

        xmlContacts.Load(Application.StartupPath +"\\My_Contacts.xml");
                
        foreach (XmlNode xmlItem in xmlContacts)
        {
            foreach (XmlNode newnode in xmlItem)
            {
                if (newnode["FullName"].InnerText == 
                    this.treeView_Contacts.SelectedNode.Text)
                {
                    this.txt_Email.Text = newnode["Email"].InnerText;
                    this.txt_City.Text = newnode["City"].InnerText;
                    this.txt_Home.Text = newnode["HomePhone"].InnerText;
                    this.txt_Zip.Text = newnode["ZipCode"].InnerText;
                    this.txt_Email2.Text = newnode["Email2"].InnerText;
                    this.txt_Address.Text = newnode["StreetAddress"].InnerText;
                    this.cmb_State.Text = newnode["State"].InnerText;
                    this.dt_DateTimePicker.Text = newnode["BDay"].InnerText;
                    this.txt_Cell.Text = newnode["CellPhone"].InnerText;

                }
            }
        }
    }
}

Displaying Internet Favorites is quite simple, and there are only a few methods for displaying the whole stuff. I'm writing those methods as it is.

C#
private bool LoadWebSitesTree()
{
    bool result = false;
    try
    {
        Cursor = Cursors.WaitCursor;
        string favFolderPath = 
          Environment.GetFolderPath(Environment.SpecialFolder.Favorites);

        // Disables any redrawing of the tree view till we are done
        tvWebSites.BeginUpdate();

        LoadFavFromFolder(new DirectoryInfo(favFolderPath), webSitesRootNode);
        LoadFavFromPath(favFolderPath, webSitesRootNode);

        result = true;
    }
    catch (Exception exp) 
    {
        //DebugLog.Instance.REPORT(exp); 
    }
    finally
    {
        Cursor = Cursors.Default;
        tvWebSites.EndUpdate();
    }

    return result;
}

private void LoadFavFromFolder(DirectoryInfo curDirInfo, TreeNode curNode)
{
    try
    {
        TreeNode newNode;

        foreach (DirectoryInfo dirInfo in curDirInfo.GetDirectories())
        {
            if (curNode == null)
                newNode = tvWebSites.Nodes.Add(dirInfo.Name);
            else
                newNode = curNode.Nodes.Add(dirInfo.Name);

            if (dirInfo.GetDirectories().Length == 0)
                LoadFavFromPath(dirInfo.FullName, newNode);
            else
                LoadFavFromFolder(dirInfo, newNode);
        }
    }
    catch (Exception exp) 
    { 
        //DebugLog.Instance.REPORT(exp); 
    }
}

private void LoadFavFromPath(string curPath, TreeNode curNode)
{
    try
    {
        DirectoryInfo curDirInfo = new DirectoryInfo(curPath);

        foreach (FileInfo objFile in curDirInfo.GetFiles("*.url"))
        {
            TreeNode newNode = new TreeNode();

            string fileName = objFile.FullName;
            newNode.Tag = GetURLValue(fileName);
            newNode.Text = Path.GetFileNameWithoutExtension(fileName);
            newNode.ImageIndex = 2;
            newNode.SelectedImageIndex = 2;

            if (curNode == null)
                tvWebSites.Nodes.Add(newNode);
            else
                curNode.Nodes.Add(newNode);
        }
    }
    catch (Exception exp) 
    { 
        //DebugLog.Instance.REPORT(exp); 
    }
}

//    Reading favorites file as INI file getting the value of URL=
private string GetURLValue(string fileName)
{
    string strURL = null;
    StreamReader reader = null;
    try
    {
        reader = new StreamReader(fileName);
        string fileLine;
        int iIndex = -1;
        while ((fileLine = reader.ReadLine()) != null)
        {
            if (fileLine != null)
            {
                if ((iIndex = fileLine.IndexOf("URL=")) >= 0)
                {
                    strURL = fileLine.Substring(iIndex + 4);
                    break;
                }
            }
        }
    }
    catch (Exception exp) 
    { 
        //DebugLog.Instance.REPORT(exp); 
    }
    finally
    {
        try { if (reader != null) reader.Close(); }
        catch (Exception exp) 
        { 
            //DebugLog.Instance.REPORT(exp);
        }
    }

    return strURL;
}

ToDo

  1. Printing support in task grid.
  2. User name and password collection after authentication.
  3. Text decoration.

Cheers!!!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
India India
"In the attitude of silence the soul finds the path in an clearer light, and what is elusive and deceptive resolves itself into crystal clearness. My life is a long and arduous quest after knowledge & Truth."
I'm playing with all ancient and new Microsoft Technologies since last two and half years.

Comments and Discussions

 
QuestionVista Gadget?????? Pin
Tarzaan1-Feb-09 20:19
Tarzaan1-Feb-09 20:19 
I do not think this is a vista gadget example so why is it here in the first place????

I was looking for something on Gadgets and this one is a windows app. a bit misleading...

I request you to change the Section it is posted under. It may help a few guys in the future.

Prashant Atal
GeneralNot too bad Pin
Cem Onvar8-Jul-08 3:00
Cem Onvar8-Jul-08 3:00 
GeneralRe: Not too bad Pin
Bh@nu14-Jan-09 23:05
Bh@nu14-Jan-09 23:05 
Generalerror Pin
djsoul13-Mar-08 10:28
djsoul13-Mar-08 10:28 
GeneralRe: error Pin
Bh@nu13-Mar-08 18:51
Bh@nu13-Mar-08 18:51 
GeneralRe: error Pin
djsoul14-Mar-08 0:33
djsoul14-Mar-08 0:33 
QuestionAdvanced? Pin
B.Tanner13-Mar-08 9:12
B.Tanner13-Mar-08 9:12 
AnswerRe: Advanced? Pin
Bh@nu13-Mar-08 18:29
Bh@nu13-Mar-08 18:29 
GeneralWrong section Pin
NormDroid13-Mar-08 2:33
professionalNormDroid13-Mar-08 2:33 
GeneralRe: Wrong section Pin
Justin Perez13-Mar-08 2:58
Justin Perez13-Mar-08 2:58 
GeneralRe: Wrong section Pin
NormDroid13-Mar-08 3:10
professionalNormDroid13-Mar-08 3:10 
GeneralRe: Wrong section Pin
Justin Perez13-Mar-08 3:15
Justin Perez13-Mar-08 3:15 
GeneralRe: Wrong section Pin
NormDroid13-Mar-08 3:23
professionalNormDroid13-Mar-08 3:23 
GeneralRe: Wrong section Pin
Bh@nu13-Mar-08 3:51
Bh@nu13-Mar-08 3:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.