예제 #1
0
        public void checkTagsExists(string categories)
        {
            string[] cats = categories.Split(ThisAddIn.CATEGORY_SEPERATOR[0]);
            foreach (string cat in cats)
            {
                string tcat = cat.Trim();
                if (tcat.Equals("") || tcat == null)
                {
                    continue;
                }

                // If the category doesn't exist in Outlook, add it.
                if (Globals.ThisAddIn.app.Session.Categories[tcat] == null)
                {
                    Outlook.Category ocat = Globals.ThisAddIn.app.Session.Categories.Add(tcat);
                    ocat.Color = Outlook.OlCategoryColor.olCategoryColorNone;
                }

                // If the category doesn't exist in the DB, add it.
                if (!allCategories.Contains(tcat))
                {
                    SqlCommand cmd = getSqlCommand("INSERT INTO Tags(tag) VALUES (@tag)");
                    cmd.Parameters.AddWithValue("@tag", tcat);
                    cmd.ExecuteNonQuery();
                    allCategories.Add(tcat);
                }
            }
        }
예제 #2
0
 public static void AddCategory(String tagName, Outlook.Application application)
 {
     Outlook.Categories categories = application.Session.Categories;
     if (!CategoryExists(tagName, application))
     {
         Outlook.Category category = categories.Add(tagName);
     }
 }
예제 #3
0
 private Outlook.Category EnsureOutlookCategoryExists(string categoryName)
 {
     Outlook.Category outlookCategory = this.OutlookCategories[categoryName];
     if (outlookCategory == null)
     {
         outlookCategory = this.OutlookCategories.Add(categoryName, Outlook.OlCategoryColor.olCategoryColorDarkRed);
     }
     return(outlookCategory);
 }
예제 #4
0
        private void AddACategory()
        {
            Outlook.Categories categories =
                Application.Session.Categories;
            string categorie = Localisation.getInstance().getString(
                Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName,
                "ARCHIVED_CATEGORY"
                );

            if (!CategoryExists(categorie))
            {
                Outlook.Category category = categories.Add(categorie,
                                                           Outlook.OlCategoryColor.olCategoryColorGreen);
            }
        }
예제 #5
0
 public static bool CategoryExists(string categoryName, Outlook.Application application)
 {
     try
     {
         Outlook.Category category = application.Session.Categories[categoryName];
         if (category != null)
         {
             return(true);
         }
         else
         {
             return(false);
         }
     }
     catch { return(false); }
 }
예제 #6
0
 public static void EnsureCategoryExists(String tag, Outlook.Application application)
 {
     Outlook.Categories categories = application.Session.Categories;
     Outlook.Category   match      = null;
     foreach (Outlook.Category category in categories)
     {
         if (category.Name.Equals(tag))
         {
             match = category;
         }
     }
     if (null == match)
     {
         throw new TagServicesException("Tried to add nonexistent category mailItem as per tag " + tag);
     }
 }
예제 #7
0
 private static bool CategoryExists(string categoryName)
 {
     try
     {
         Outlook.Category category =
             ThisAddIn.zmiennaDoSettinngs.Session.Categories[categoryName];
         if (category != null)
         {
             return(true);
         }
         else
         {
             return(false);
         }
     }
     catch { return(false); }
 }
예제 #8
0
 private bool CategoryExists(string categoryName)
 {
     try
     {
         Outlook.Category category =
             Application.Session.Categories[categoryName];
         if (category != null)
         {
             return(true);
         }
         else
         {
             return(false);
         }
     }
     catch { return(false); }
 }
        /// <summary>
        /// Get the Outlook category name for a given category colour.
        /// If category not yet used, new one added of the form "OGCS [colour]"
        /// </summary>
        /// <param name="olCategory">The Outlook category to search by</param>
        /// <param name="categoryName">Optional: The Outlook category name to also search by</param>
        /// <returns>The matching category name</returns>
        public String FindName(Outlook.OlCategoryColor olCategory, String categoryName = null)
        {
            if (olCategory == Outlook.OlCategoryColor.olCategoryColorNone)
            {
                return("");
            }

            Outlook.Category failSafeCategory = null;
            foreach (Outlook.Category category in this.categories)
            {
                if (category.Color == olCategory)
                {
                    if (categoryName == null)
                    {
                        if (category.Name.StartsWith("OGCS "))
                        {
                            return(category.Name);
                        }
                    }
                    else
                    {
                        if (category.Name == categoryName)
                        {
                            return(category.Name);
                        }
                        if (category.Name.StartsWith("OGCS "))
                        {
                            failSafeCategory = category;
                        }
                    }
                }
            }

            if (failSafeCategory != null)
            {
                log.Warn("Failed to find Outlook category " + olCategory.ToString() + " with name '" + categoryName + "'");
                log.Debug("Using category with name \"" + failSafeCategory.Name + "\" instead.");
                return(failSafeCategory.Name);
            }

            log.Debug("Did not find Outlook category " + olCategory.ToString() + (categoryName == null ? "" : " \"" + categoryName + "\""));
            Outlook.Category newCategory = categories.Add("OGCS " + FriendlyCategoryName(olCategory), olCategory);
            log.Info("Added new Outlook category \"" + newCategory.Name + "\" for " + newCategory.Color.ToString());
            return(newCategory.Name);
        }
예제 #10
0
        /// <summary>
        /// Get the Outlook category name for a given category colour.
        /// If category not yet used, new one added of the form "OGCS [colour]"
        /// </summary>
        /// <param name="olCategory">The Outlook category to search by</param>
        /// <returns>The matching category name</returns>
        public String FindName(Outlook.OlCategoryColor olCategory)
        {
            if (olCategory == Outlook.OlCategoryColor.olCategoryColorNone)
            {
                return("");
            }

            foreach (Outlook.Category category in this.categories)
            {
                if (category.Color == olCategory && category.Name.StartsWith("OGCS "))
                {
                    return(category.Name);
                }
            }

            Outlook.Category newCategory = categories.Add("OGCS " + FriendlyCategoryName(olCategory), olCategory);
            return(newCategory.Name);
        }
예제 #11
0
        public bool TryAddCategory(int projectId, int tagId, string categoryName)
        {
            if (this.IsInvalidCategoryName(categoryName))
            {
                return(false);
            }

            Outlook.Category outlookCategory = this.EnsureOutlookCategoryExists(categoryName);

            CategoryList categoryList = new CategoryList(Properties.Settings.Default.CategoriesString, this.OutlookCategories);

            categoryList.AddOrUpdate(new Category(categoryName, projectId, tagId, outlookCategory));

            Properties.Settings.Default.CategoriesString = categoryList.ItemsAsXmlString;
            Properties.Settings.Default.Save();

            return(true);
        }
예제 #12
0
 private void AddACategory()
 {
     Outlook.Categories categories =
         Application.Session.Categories;
     if (!CategoryExists("Onbekend mail adress"))
     {
         Outlook.Category category = categories.Add("Onbekend mail adress",
                                                    Outlook.OlCategoryColor.olCategoryColorDarkRed);
     }
     if (!CategoryExists("none"))
     {
         Outlook.Category category = categories.Add("none",
                                                    Outlook.OlCategoryColor.olCategoryColorNone);
     }
     if (!CategoryExists("Automatisch gearchiveerd"))
     {
         Outlook.Category category = categories.Add("Automatisch gearchiveerd",
                                                    Outlook.OlCategoryColor.olCategoryColorGreen);
     }
 }
        private void InitializeCategoryGallery()
        {
            galleryCategory.Items.Clear();

            Outlook.Categories categories = Globals.ThisAddIn.Application.ActiveExplorer().Session.Categories;

            // ensure we have a "WFM for Outlook" category to tag
            try
            {
                if (categories[Options.CONFIG_MESSAGE_SUBJECT] == null)
                {
                    Outlook.Category wfmCategory = categories.Add(Options.CONFIG_MESSAGE_SUBJECT, Outlook.OlCategoryColor.olCategoryColorYellow);
                }
            } catch (Exception e) {
                MessageBox.Show($"Failed to initialize a default category: {e}");
            }

            var dropdownItem = this.Factory.CreateRibbonDropDownItem();

            dropdownItem.Label = "None";
            dropdownItem.Tag   = string.Empty;
            galleryCategory.Items.Clear();
            galleryCategory.Items.Add(dropdownItem);
            galleryCategory.SelectedItem = dropdownItem;

            foreach (Outlook.Category cat in categories)
            {
                dropdownItem       = this.Factory.CreateRibbonDropDownItem();
                dropdownItem.Label = cat.Name;
                dropdownItem.Tag   = cat.CategoryID;
                galleryCategory.Items.Add(dropdownItem);
                if (Globals.ThisAddIn.userOptions.categoryName == cat.Name)
                {
                    galleryCategory.SelectedItem = dropdownItem;
                }
            }
        }
        /// <summary>
        /// Get the Outlook category name for a given category colour.
        /// If category not yet used, new one added of the form "OGCS [colour]"
        /// </summary>
        /// <param name="olCategory">The Outlook category to search by</param>
        /// <param name="categoryName">Optional: The Outlook category name to also search by</param>
        /// <param name="createMissingCategory">Optional: Create unused category colour?</param>
        /// <returns>The matching category name</returns>
        public String FindName(Outlook.OlCategoryColor?olCategory, String categoryName = null, Boolean createMissingCategory = true)
        {
            if (olCategory == null || olCategory == Outlook.OlCategoryColor.olCategoryColorNone)
            {
                return("");
            }

            Outlook.Category failSafeCategory = null;
            foreach (Outlook.Category category in this.categories)
            {
                try {
                    if (category.Color == olCategory)
                    {
                        if (categoryName == null)
                        {
                            if (category.Name.StartsWith("OGCS "))
                            {
                                return(category.Name);
                            }
                            else if (!createMissingCategory)
                            {
                                return(category.Name);
                            }
                        }
                        else
                        {
                            if (category.Name == categoryName)
                            {
                                return(category.Name);
                            }
                            if (category.Name.StartsWith("OGCS "))
                            {
                                failSafeCategory = category;
                            }
                        }
                    }
                } catch (System.Runtime.InteropServices.COMException ex) {
                    if (OGCSexception.GetErrorCode(ex, 0x0000FFFF) == "0x00004005")   //The operation failed.
                    {
                        log.Warn("It seems a category has been manually removed in Outlook.");
                        OutlookOgcs.Calendar.Instance.IOutlook.RefreshCategories();
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            if (failSafeCategory != null)
            {
                log.Warn("Failed to find Outlook category " + olCategory.ToString() + " with name '" + categoryName + "'");
                log.Debug("Using category with name \"" + failSafeCategory.Name + "\" instead.");
                return(failSafeCategory.Name);
            }

            log.Debug("Did not find Outlook category " + olCategory.ToString() + (categoryName == null ? "" : " \"" + categoryName + "\""));
            String newCategoryName = "OGCS " + FriendlyCategoryName(olCategory);

            if (!createMissingCategory)
            {
                createMissingCategory = System.Windows.Forms.OgcsMessageBox.Show("There is no matching Outlook category.\r\nWould you like to create one of the form '" + newCategoryName + "'?",
                                                                                 "Create new Outlook category?", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes;
            }
            if (createMissingCategory)
            {
                Outlook.Category newCategory = categories.Add(newCategoryName, olCategory);
                log.Info("Added new Outlook category \"" + newCategory.Name + "\" for " + newCategory.Color.ToString());
                return(newCategory.Name);
            }
            return("");
        }
        /// <summary>
        /// Retrieves tasks for all selected stores
        /// </summary>
        private void RetrieveTasks()
        {
            List <OLTaskItem> tasks = new List <OLTaskItem>();

            foreach (Outlook.Store store in Globals.ThisAddIn.Application.Session.Stores)
            {
                if (Properties.Settings.Default.Accounts != null && Properties.Settings.Default.Accounts.Contains(store.DisplayName))
                {
                    Outlook.Folder todoFolder = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderToDo) as Outlook.Folder;
                    tasks.AddRange(this.RetrieveTasksForFolder(todoFolder));
                    // TODO: Shared calendars?
                }
            }

            if (!this.ShowCompletedTasks)
            {
                tasks = tasks.Where(t => !t.Completed).ToList();
            }

            // We need to sort them because they may come from different accounts already ordered
            // Applies sorting by due date
            tasks.Sort(CompareTasks);

            //Outlook.Folder todoFolder =
            //    Globals.ThisAddIn.Application.Session.GetDefaultFolder(
            //    Outlook.OlDefaultFolders.olFolderToDo)
            //    as Outlook.Folder;
            //this.RetrieveTasksForFolder(todoFolder);

            int sameDay = -1; // startRange.Day;

            List <ListViewItem> lstCol = new List <ListViewItem>();
            ListViewGroup       grp    = null;

            tasks.ForEach(t =>
            {
                if (t.DueDate.Day != sameDay)
                {
                    string groupHeaderText = t.DueDate.ToShortDateString();
                    if (t.DueDate.Year == Constants.NullYear)
                    {
                        groupHeaderText = "No due date";
                    }
                    if (this.ShowFriendlyGroupHeaders)
                    {
                        int daysDiff = (int)(t.DueDate.Date - DateTime.Today).TotalDays;
                        switch (daysDiff)
                        {
                        case -1:
                            groupHeaderText = Constants.Yesterday + ": " + groupHeaderText;
                            break;

                        case 0:
                            groupHeaderText = Constants.Today + ": " + groupHeaderText;
                            break;

                        case 1:
                            groupHeaderText = Constants.Tomorrow + ": " + groupHeaderText;
                            break;

                        default:
                            break;
                        }
                    }
                    if (this.ShowDayNames && t.DueDate.Year != Constants.NullYear)
                    {
                        groupHeaderText += " (" + t.DueDate.ToString("dddd") + ")";
                    }
                    grp = new ListViewGroup(groupHeaderText, HorizontalAlignment.Left);
                    this.lstTasks.Groups.Add(grp);
                    sameDay = t.DueDate.Day;
                }
                ;

                ListViewItem current = new ListViewItem(new string[] { String.Format("{0} {1}", t.DueDate.ToShortTimeString(), t.TaskSubject), "***" });
                current.SubItems.Add(t.TaskSubject);

                // current.Font = new Font(this.Font, FontStyle.Bold);
                // current.UseItemStyleForSubItems = false;

                current.ToolTipText = String.Format("Task Subject: {0}", t.TaskSubject);
                if (t.StartDate.Year != Constants.NullYear)
                {
                    current.ToolTipText += Environment.NewLine + String.Format("Start Date: {0}", t.StartDate.ToShortDateString());
                }
                if (t.Reminder.Year != Constants.NullYear)
                {
                    current.ToolTipText += Environment.NewLine + String.Format("Reminder Time: {0}", t.Reminder.ToString());
                }
                if (t.DueDate.Year != Constants.NullYear)
                {
                    current.ToolTipText += Environment.NewLine + String.Format("Due Date: {0}", t.DueDate.ToShortDateString());
                }
                current.ToolTipText += Environment.NewLine + String.Format("In Folder: {0}", t.FolderName);

                t.Categories.ForEach(cat =>
                {
                    Outlook.Category c = Globals.ThisAddIn.Application.Session.Categories[cat] as Outlook.Category;
                    if (c != null)
                    {
                        current.ToolTipText += Environment.NewLine + " - " + c.Name;
                    }
                });

                current.Tag   = t;
                current.Group = grp;
                lstCol.Add(current);
            });

            this.lstTasks.Items.Clear();
            this.lstTasks.Items.AddRange(lstCol.ToArray());
        }
        /// <summary>
        /// Retrieve all appointments for the current configurations for all selected stores
        /// </summary>
        private void RetrieveAppointments()
        {
            List <Outlook.AppointmentItem> appts = new List <Outlook.AppointmentItem>();

            foreach (Outlook.Store store in Globals.ThisAddIn.Application.Session.Stores)
            {
                if (Properties.Settings.Default.Accounts != null && Properties.Settings.Default.Accounts.Contains(store.DisplayName))
                {
                    Outlook.Folder calFolder = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
                    appts.AddRange(this.RetrieveAppointmentsForFolder(calFolder));
                    // TODO: Shared calendars?
                }
            }
            // We need to sort them because they may come from different accounts already ordered
            appts.Sort(CompareAppointments);

            // Get the Outlook folder for the calendar to retrieve the appointments
            //Outlook.Folder calFolder =
            //    Globals.ThisAddIn.Application.Session.GetDefaultFolder(
            //    Outlook.OlDefaultFolders.olFolderCalendar)
            //    as Outlook.Folder;
            //List<Outlook.AppointmentItem> appts = this.RetrieveAppointmentsForFolder(calFolder);

            // Highlight dates with appointments in the current calendar
            this.apptCalendar.BoldedDates = appts.Select <Outlook.AppointmentItem, DateTime>(a => a.Start.Date).Distinct().ToArray();

            // Now display the actual appointments below the calendar
            DateTime startRange = this.apptCalendar.SelectedDate;

            if (!this.ShowPastAppointments && startRange.Date == DateTime.Today)
            {
                startRange = startRange.Add(DateTime.Now.TimeOfDay);
            }
            DateTime endRange = startRange.AddDays((int)this.NumDays);

            // Get items in range
            var lstItems = appts.Where(a => a.Start >= startRange && a.Start <= endRange);

            int sameDay = -1; // startRange.Day;

            List <ListViewItem> lstCol = new List <ListViewItem>();
            ListViewGroup       grp    = null;

            lstItems.ToList().ForEach(i =>
            {
                if (i.Start.Day != sameDay)
                {
                    string groupHeaderText = i.Start.ToShortDateString();
                    if (this.ShowFriendlyGroupHeaders)
                    {
                        int daysDiff = (int)(i.Start.Date - DateTime.Today).TotalDays;
                        switch (daysDiff)
                        {
                        case -1:
                            groupHeaderText = Constants.Yesterday + ": " + groupHeaderText;
                            break;

                        case 0:
                            groupHeaderText = Constants.Today + ": " + groupHeaderText;
                            break;

                        case 1:
                            groupHeaderText = Constants.Tomorrow + ": " + groupHeaderText;
                            break;

                        default:
                            break;
                        }
                    }
                    if (this.ShowDayNames)
                    {
                        groupHeaderText += " (" + i.Start.ToString("dddd") + ")";
                    }
                    grp = new ListViewGroup(groupHeaderText, HorizontalAlignment.Left);
                    this.lstAppointments.Groups.Add(grp);
                    sameDay = i.Start.Day;
                }
                ;
                string loc = "-"; // TODO: If no second line is specified, the tile is stretched to only one line
                if (!String.IsNullOrEmpty(i.Location))
                {
                    loc = i.Location;
                }
                ListViewItem current = new ListViewItem(new string[] { String.Format("{0} {1}", i.Start.ToShortTimeString(), i.Subject), loc });
                current.SubItems.Add(i.Subject);

                // current.Font = new Font(this.Font, FontStyle.Bold);
                // current.UseItemStyleForSubItems = false;

                current.ToolTipText = String.Format("{0} - {1}  {2}", i.Start.ToShortTimeString(), i.End.ToShortTimeString(), i.Subject);

                if (!String.IsNullOrEmpty(i.Categories))
                {
                    string[] allCats = i.Categories.Split(new char[] { ',' });
                    if (allCats != null && allCats.Length != 0)
                    {
                        List <string> cs = allCats.Select(cat => cat.Trim()).ToList();
                        cs.ForEach(cat =>
                        {
                            Outlook.Category c = Globals.ThisAddIn.Application.Session.Categories[cat] as Outlook.Category;
                            if (c != null)
                            {
                                current.ToolTipText += Environment.NewLine + " - " + c.Name;
                            }
                        });
                    }
                }

                current.Tag   = i;
                current.Group = grp;
                switch (i.BusyStatus)
                {
                case Outlook.OlBusyStatus.olBusy:
                    current.ForeColor = Color.Purple;
                    break;

                case Outlook.OlBusyStatus.olFree:
                    break;

                case Outlook.OlBusyStatus.olOutOfOffice:
                    current.ForeColor = Color.Brown;
                    break;

                case Outlook.OlBusyStatus.olTentative:
                    break;

                case Outlook.OlBusyStatus.olWorkingElsewhere:
                    break;

                default:
                    break;
                }

                lstCol.Add(current);
            });

            this.lstAppointments.Items.Clear();
            this.lstAppointments.Items.AddRange(lstCol.ToArray());

            this.apptCalendar.ShowWeekNumbers = this.ShowWeekNumbers;
            this.apptCalendar.UpdateCalendar();
        }
        private void lstTasks_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            e.DrawBackground(); // To avoid repainting (making font "grow")
            OLTaskItem task = e.Item.Tag as OLTaskItem;

            // Color catColor = Color.Empty;
            List <Color> catColors = new List <Color>();

            Font itemFont = this.Font;

            task.Categories.ForEach(cat =>
            {
                Outlook.Category c = Globals.ThisAddIn.Application.Session.Categories[cat] as Outlook.Category;
                if (c != null)
                {
                    catColors.Add(TranslateCategoryColor(c.Color));
                }
            });
            int categoriesRectangleWidth = 30;
            int horizontalSpacing        = 2;

            Rectangle totalRectangle      = e.Bounds;
            Rectangle subjectRectangle    = totalRectangle; subjectRectangle.Height = this.FontHeight;
            Rectangle categoriesRectangle = totalRectangle; categoriesRectangle.Width = categoriesRectangleWidth; categoriesRectangle.Height = this.FontHeight; categoriesRectangle.Offset(10, this.FontHeight);
            Rectangle reminderRectangle   = totalRectangle; reminderRectangle.Height = this.FontHeight; reminderRectangle.Offset(0, this.FontHeight);

            if (task.Categories.Count != 0)
            {
                reminderRectangle.Offset(categoriesRectangleWidth + horizontalSpacing * 4, 0);
            }

            bool  selected = e.State.HasFlag(ListViewItemStates.Selected);
            Color back     = Color.Empty;

            if (selected)
            {
                back = Color.LightCyan;
            }
            using (Brush br = new SolidBrush(back))
                e.Graphics.FillRectangle(br, totalRectangle);

            StringFormat rightFormat = new StringFormat();

            rightFormat.Alignment     = StringAlignment.Far;
            rightFormat.LineAlignment = StringAlignment.Near;
            StringFormat leftFormat = new StringFormat();

            leftFormat.Alignment     = StringAlignment.Near;
            leftFormat.LineAlignment = StringAlignment.Near;

            Brush colorBrush = new SolidBrush(this.ForeColor);

            if (catColors.Count != 0)
            {
                int catWidth = categoriesRectangle.Width / catColors.Count;
                // int catWidth = categoriesRectangle.Width / 3; // TODO: This looks nicer, but more than 3 won't fit
                Rectangle catRect = categoriesRectangle; catRect.Width = catWidth;
                // catColors.ForEach(cc =>
                catColors.Take(3).ToList().ForEach(cc =>
                {
                    // e.Graphics.FillEllipse(new SolidBrush(cc), catRect);
                    e.Graphics.FillRectangle(new SolidBrush(cc), catRect);
                    // e.Graphics.FillRectangle(new SolidBrush(cc), catRect.Left, catRect.Top, catWidth, this.FontHeight);
                    catRect.Offset(catWidth, 0);
                });
            }
            Font mainFont = new Font(this.Font, FontStyle.Bold);
            Font subFont  = this.Font;

            if (task.Completed)
            {
                mainFont = new Font(this.Font, FontStyle.Bold | FontStyle.Strikeout);
                subFont  = new Font(this.Font, FontStyle.Strikeout);
            }
            e.Graphics.DrawString(task.TaskSubject, mainFont, colorBrush, subjectRectangle, leftFormat);
            if (task.Reminder.Year != Constants.NullYear)
            {
                e.Graphics.DrawImage(Properties.Resources.Alert_16xSM, reminderRectangle.Left, reminderRectangle.Top);
                e.Graphics.DrawString(task.Reminder.ToString(), subFont, colorBrush, reminderRectangle.Left + Properties.Resources.Alert_16xSM.Width + horizontalSpacing, reminderRectangle.Top, leftFormat);
            }
            else if (task.StartDate.Year != Constants.NullYear)
            {
                e.Graphics.DrawImage(Properties.Resources.CurrentRow_15x14, reminderRectangle.Left, reminderRectangle.Top);
                e.Graphics.DrawString(task.StartDate.ToShortDateString(), subFont, colorBrush, reminderRectangle.Left + Properties.Resources.CurrentRow_15x14.Width + horizontalSpacing, reminderRectangle.Top, leftFormat);
            }
        }
        /// <summary>
        /// Method to custom draw the list items
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">DrawListViewItemEventArgs</param>
        private void lstAppointments_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            e.DrawBackground(); // To avoid repainting (making font "grow")
            Outlook.AppointmentItem appt = e.Item.Tag as Outlook.AppointmentItem;

            // Color catColor = Color.Empty;
            List <Color> catColors = new List <Color>();

            Font itemFont = this.Font;

            if (!String.IsNullOrEmpty(appt.Categories))
            {
                string[] allCats = appt.Categories.Split(new char[] { ',' });
                if (allCats != null && allCats.Length != 0)
                {
                    List <string> cs = allCats.Select(cat => cat.Trim()).ToList();
                    cs.ForEach(cat =>
                    {
                        Outlook.Category c = Globals.ThisAddIn.Application.Session.Categories[cat] as Outlook.Category;
                        if (c != null)
                        {
                            catColors.Add(TranslateCategoryColor(c.Color));
                        }
                    });
                }
            }
            int startRectangleWidth      = 65;
            int categoriesRectangleWidth = 55;
            int horizontalSpacing        = 5;

            Rectangle totalRectangle      = e.Bounds;
            Rectangle startRectangle      = totalRectangle; startRectangle.Width = startRectangleWidth;
            Rectangle statusRectangle     = totalRectangle; statusRectangle.Width = horizontalSpacing * 2; statusRectangle.Offset(startRectangleWidth + horizontalSpacing, 0);
            Rectangle subjectRectangle    = totalRectangle; subjectRectangle.Height = this.FontHeight; subjectRectangle.Offset(startRectangleWidth + horizontalSpacing * 4, 0);
            Rectangle categoriesRectangle = totalRectangle; categoriesRectangle.Width = categoriesRectangleWidth; categoriesRectangle.Height = this.FontHeight; categoriesRectangle.Offset(10, this.FontHeight);
            Rectangle locationRectangle   = totalRectangle; locationRectangle.Height = this.FontHeight; locationRectangle.Offset(startRectangleWidth + horizontalSpacing * 4, this.FontHeight);
            bool      selected            = e.State.HasFlag(ListViewItemStates.Selected);
            Color     back = Color.Empty;

            if (selected)
            {
                back = Color.LightCyan;
            }
            using (Brush br = new SolidBrush(back))
                e.Graphics.FillRectangle(br, totalRectangle);

            StringFormat rightFormat = new StringFormat();

            rightFormat.Alignment     = StringAlignment.Far;
            rightFormat.LineAlignment = StringAlignment.Near;
            StringFormat leftFormat = new StringFormat();

            leftFormat.Alignment     = StringAlignment.Near;
            leftFormat.LineAlignment = StringAlignment.Near;

            Brush colorBrush = new SolidBrush(this.ForeColor);

            e.Graphics.DrawString(appt.Start.ToShortTimeString(), this.Font, colorBrush, startRectangle, rightFormat);

            Color statusColor = Color.LightBlue;
            Brush statusBrush = new SolidBrush(Color.Transparent);

            switch (appt.BusyStatus)
            {
            case Outlook.OlBusyStatus.olBusy:
                statusBrush = new SolidBrush(statusColor);
                break;

            case Outlook.OlBusyStatus.olFree:
                break;

            case Outlook.OlBusyStatus.olOutOfOffice:
                statusBrush = new SolidBrush(Color.Purple);     // TODO: Figure this out
                break;

            case Outlook.OlBusyStatus.olTentative:
                statusBrush = new HatchBrush(HatchStyle.BackwardDiagonal, statusColor, this.BackColor);
                break;

            case Outlook.OlBusyStatus.olWorkingElsewhere:
                statusBrush = new HatchBrush(HatchStyle.DottedDiamond, statusColor, this.BackColor);
                break;

            default:
                break;
            }
            // Let's draw the status with a custom brush
            e.Graphics.FillRectangle(statusBrush, statusRectangle);
            e.Graphics.DrawRectangle(new Pen(statusColor), statusRectangle);

            if (catColors.Count != 0)
            {
                // int catWidth = categoriesRectangle.Width / catColors.Count;
                int       catWidth = categoriesRectangle.Width / 3; // TODO: This looks nicer, but more than 3 won't fit
                Rectangle catRect  = categoriesRectangle; catRect.Width = catWidth;
                // catColors.ForEach(cc =>
                catColors.Take(3).ToList().ForEach(cc =>
                {
                    e.Graphics.FillEllipse(new SolidBrush(cc), catRect);
                    catRect.Offset(catWidth, 0);
                });
            }

            //e.Graphics.FillRectangle(new SolidBrush(catColor), subjectRectangle);
            e.Graphics.DrawString(appt.Subject, new Font(this.Font, FontStyle.Bold), colorBrush, subjectRectangle, leftFormat);
            //e.Graphics.FillRectangle(new SolidBrush(catColor), locationRectangle);
            e.Graphics.DrawString(appt.Location, this.Font, colorBrush, locationRectangle, leftFormat);
        }