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.
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.
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.
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.
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.
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
{
tasksCheckedListBox.Items.RemoveAt(rowIndex);
tasksCheckedListBox.Items.Insert(rowIndex, title);
tasksCheckedListBox.SetItemChecked(rowIndex, row.TaskComplete);
}
}
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);
}
}
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.
private void CheckTaskDates()
{
StringBuilder buffer = new StringBuilder();
foreach (TasksDataSet.TasksRow row in ds.Tasks)
{
if ((DateTime.Now.Date > row.TaskDueDate) && !row.TaskComplete)
{
buffer.Append(row.TaskTitle).Append(", Due: ");
buffer.AppendFormat("{0:d}", row.TaskDueDate).Append('\n');
}
}
if (buffer.Length > 0)
{
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.
private void btnUpdate_Click(object sender, System.EventArgs e)
{
TreeViewSerialization.TreeViewSerializer objTreeViewSerializer =
new TreeViewSerialization.TreeViewSerializer();
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.
private bool LoadWebSitesTree()
{
bool result = false;
try
{
Cursor = Cursors.WaitCursor;
string favFolderPath =
Environment.GetFolderPath(Environment.SpecialFolder.Favorites);
tvWebSites.BeginUpdate();
LoadFavFromFolder(new DirectoryInfo(favFolderPath), webSitesRootNode);
LoadFavFromPath(favFolderPath, webSitesRootNode);
result = true;
}
catch (Exception 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)
{
}
}
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)
{
}
}
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)
{
}
finally
{
try { if (reader != null) reader.Close(); }
catch (Exception exp)
{
}
}
return strURL;
}
ToDo
- Printing support in task grid.
- User name and password collection after authentication.
- Text decoration.
Cheers!!!