Пример #1
0
        /// <summary>
        /// Handle the Send button. At this point we assume there are valid recipients and something
        /// in the message body. We really ought to do some validation of the recipient names here.
        /// </summary>
        /// <param name="sender">The new message form</param>
        /// <param name="e">Event arguments</param>
        private void nmSend_Click(object sender, EventArgs e)
        {
            if (_currentConversation == null)
            {
                _currentConversation = new InboxConversation
                {
                    Subject = nmSubject.Text,
                    Author  = CIX.Username,
                    Date    = DateTime.UtcNow.UTCToGMTBST()
                };
            }
            if (_currentMessage == null)
            {
                _currentMessage = new InboxMessage
                {
                    Author         = (_currentConversation.ID > 0) ? CIX.Username : nmRecipients.Text,
                    Body           = nmMessage.Text,
                    ConversationID = _currentConversation.ID,
                    Date           = DateTime.UtcNow.UTCToGMTBST()
                };

                CIX.ConversationCollection.Add(_currentConversation, _currentMessage);
            }

            DialogResult = DialogResult.OK;
            Close();
        }
Пример #2
0
        /// <summary>
        /// Handle the conversation being deleted from the client.
        /// </summary>
        private void OnConversationDeleted(object sender, InboxEventArgs args)
        {
            Platform.UIThread(this, delegate
            {
                InboxConversation conversation = args.Conversation;
                int selectedRow      = SelectedRow;
                bool deletingCurrent = (selectedRow != -1) && (conversation == _conversations[selectedRow]);

                _conversations.Remove(conversation);

                InitialiseList();
                RefreshList();

                if (deletingCurrent)
                {
                    if (selectedRow == _conversations.Count)
                    {
                        --selectedRow;
                    }
                    if (selectedRow < 0)
                    {
                        ShowEmptyMessage();
                    }
                    else
                    {
                        SelectedRow = selectedRow;
                    }
                }
            });
        }
Пример #3
0
        /// <summary>
        /// Draw the full thread for the selected conversation. The users current scroll position is not altered
        /// unless resetScrollPosition is true in which case we scroll so that the last message is visible.
        ///
        /// Drawing the thread also optionally marks the conversation as read and triggers an update on the server.
        /// </summary>
        /// <param name="conversation">The conversation to draw</param>
        private void ShowMessage(InboxConversation conversation)
        {
            inboxMessagePane.BeginUpdate();
            inboxMessagePane.Items.Clear();
            if (conversation != null)
            {
                InboxItem lastItem = null;

                foreach (InboxMessage message in conversation.Messages)
                {
                    InboxItem item = new InboxItem(inboxMessagePane, lastItem != null)
                    {
                        ID             = message.RemoteID,
                        Image          = Mugshot.MugshotForUser(message.Author, true).RealImage,
                        ItemColour     = SystemColors.Window,
                        FullDateString = _showFullDate,
                        Message        = message,
                        Font           = _bodyFont
                    };
                    inboxMessagePane.Items.Add(item);
                    lastItem = item;
                }
                inboxMessagePane.SelectedItem = lastItem;
            }
            inboxMessagePane.EndUpdate(null);
        }
Пример #4
0
        /// <summary>
        /// Draw the row.
        /// </summary>
        private void DrawSubItem(object sender, DrawListViewSubItemEventArgs args)
        {
            InboxConversation message = args.Item.Tag as InboxConversation;

            if (message != null)
            {
                DrawRectElements elements = ComputeDrawRectElements(args.Graphics, message, args.Bounds);

                Color textColor = UI.Forums.HeaderFooterColour;
                if (args.Item.Selected)
                {
                    args.DrawFocusRectangle(elements.BoundaryRect);
                    textColor = UI.Forums.SelectionTextColour;
                }

                // Draw the selection around the control.
                using (Pen edgePen = new Pen(args.Item.Selected ? UI.Forums.SelectionColour : BackColor))
                {
                    Color fillColour = args.Item.Selected ? UI.Forums.SelectionColour : UI.Forums.RootColour;
                    using (Brush backBrush = new SolidBrush(fillColour))
                    {
                        args.Graphics.FillRoundedRectangle(edgePen, backBrush, elements.BoundaryRect);
                    }
                }

                using (Brush textBrush = new SolidBrush(textColor))
                {
                    // Draw read image
                    Image readImage = ReadImageForMessage(message);
                    args.Graphics.DrawImage(readImage, elements.ReadRect);

                    // Draw author name
                    args.Graphics.DrawString(message.Author, _font, textBrush, elements.AuthorRect);

                    // Draw separator
                    const string separatorChar = "•";
                    args.Graphics.DrawString(separatorChar, _font, textBrush, elements.Separator1Rect);

                    // Draw date
                    string dateString = (_showFullDate)
                        ? message.Date.ToString("d MMM yyyy") + " " + message.Date.ToShortTimeString()
                        : message.Date.FriendlyString(true);
                    args.Graphics.DrawString(dateString, _font, textBrush, elements.DateRect);

                    // Draw ID field
                    string idString = (message.IsDraft)
                        ? "Draft"
                        : message.RemoteID.ToString(CultureInfo.InvariantCulture);
                    args.Graphics.DrawString(idString, _font, textBrush, elements.IDRect);

                    // Another separator
                    args.Graphics.DrawString(separatorChar, _font, textBrush, elements.Separator2Rect);

                    // Draw subject line
                    string subjectLine = message.Subject;
                    args.Graphics.DrawString(subjectLine, _font, textBrush, elements.SubjectRect, new StringFormat(StringFormatFlags.NoWrap));
                }
            }
        }
Пример #5
0
 /// <summary>
 /// Go to the next priority unread message.
 /// </summary>
 private void GoToNextPriorityUnread(InboxConversation conversation)
 {
     if (conversation != null && conversation.UnreadCount > 0)
     {
         conversation.MarkRead();
     }
     FoldersTree.NextUnread(FolderOptions.NextUnread | FolderOptions.Priority);
 }
Пример #6
0
 /// <summary>
 /// Return the appropriate read icon for this message based on its unread and priority state
 /// </summary>
 private static Image ReadImageForMessage(InboxConversation conversation)
 {
     if (conversation.LastError)
     {
         return(Resources.Error1);
     }
     return((conversation.UnreadCount > 0) ? Resources.UnreadMessage : Resources.ReadMessage);
 }
Пример #7
0
 /// <summary>
 /// This event is fired when a new conversation is added to the list of conversations.
 /// </summary>
 private void OnConversationAdded(object sender, InboxEventArgs args)
 {
     Platform.UIThread(this, delegate
     {
         InboxConversation selectedMessage = SelectedMessage;
         SortConversations();
         RestoreSelection(selectedMessage);
     });
 }
Пример #8
0
 /// <summary>
 /// Reload the mail folder list
 /// </summary>
 private void RefreshList()
 {
     if (_conversations.Count > 0)
     {
         InboxConversation savedMessage = SelectedMessage;
         inboxConversations.RedrawItems(0, _conversations.Count - 1, false);
         RestoreSelection(savedMessage);
     }
 }
Пример #9
0
 /// <summary>
 /// Put the selection back on the specified conversation.
 /// </summary>
 /// <param name="conversation">The message to select</param>
 private void RestoreSelection(InboxConversation conversation)
 {
     if (_conversations.Count == 0)
     {
         ShowEmptyMessage();
     }
     else if (conversation != null)
     {
         SelectedRow = _conversations.IndexOf(conversation);
     }
 }
Пример #10
0
 /// <summary>
 /// Mark a conversation as read if we previously has unread messages. This also triggers
 /// a server update and redraws the inbox list item to remove the unread count badge.
 /// </summary>
 /// <param name="conversation">Conversation to mark read</param>
 private static void MarkConversationAsRead(InboxConversation conversation)
 {
     if (conversation.UnreadCount > 0)
     {
         conversation.MarkRead();
     }
     else
     {
         conversation.MarkUnread();
     }
 }
Пример #11
0
 /// <summary>
 /// Locate and select the first unread mail message after the given row.
 /// </summary>
 private bool FirstUnreadAfterRow(int row, FolderOptions options)
 {
     while (row < _conversations.Count)
     {
         InboxConversation conversation = _conversations[row];
         if ((options & FolderOptions.NextUnread) == FolderOptions.NextUnread && conversation.UnreadCount > 0)
         {
             SelectedRow = row;
             break;
         }
         row++;
     }
     return(row != _conversations.Count);
 }
Пример #12
0
        /// <summary>
        /// Return the text string for the specified action.
        /// </summary>
        public override string TitleForAction(ActionID id)
        {
            if (SelectedMessage != null)
            {
                InboxConversation conversation = SelectedMessage;
                switch (id)
                {
                case ActionID.Read:
                    return(conversation.UnreadCount > 0 ? Resources.AsRead : Resources.AsUnread);

                case ActionID.Withdraw:
                    return(Resources.Delete);
                }
            }
            return(null);
        }
Пример #13
0
        /// <summary>
        /// Action the specified ID with the given conversation.
        /// </summary>
        /// <param name="id">An action ID</param>
        /// <param name="conversation">A selected conversation, or null</param>
        private void Action(ActionID id, InboxConversation conversation)
        {
            switch (id)
            {
            case ActionID.NewMessage:
                FoldersTree.MainForm.Address = "cixmail:";
                break;

            case ActionID.Print:
                Print(conversation);
                break;

            case ActionID.Profile:
            case ActionID.AuthorImage:
                FoldersTree.MainForm.Address = string.Format("cixuser:{0}", conversation.Author);
                break;

            case ActionID.Withdraw:
                conversation.MarkDelete();
                break;

            case ActionID.PageMessage:
            case ActionID.NextUnread:
                GoToNextUnread(conversation);
                break;

            case ActionID.NextPriorityUnread:
                GoToNextPriorityUnread(conversation);
                break;

            case ActionID.Edit:
            case ActionID.Reply:
            {
                InboxMessageEditor newMessageWnd = new InboxMessageEditor(conversation);
                newMessageWnd.Show();
                break;
            }

            case ActionID.Read:
                MarkConversationAsRead(conversation);
                break;

            case ActionID.SelectAll:
                SelectAll();
                break;
            }
        }
Пример #14
0
        /// <summary>
        /// Handle click on read icons on an item to change the read state of
        /// the conversation.
        /// </summary>
        private void OnMouseDown(object sender, MouseEventArgs mouseEventArgs)
        {
            ListViewItem item = inboxConversations.GetItemAt(mouseEventArgs.Location.X, mouseEventArgs.Location.Y);

            if (item != null)
            {
                if (item.Index >= 0 && item.Index < _conversations.Count)
                {
                    InboxConversation message  = _conversations[item.Index];
                    DrawRectElements  elements = ComputeDrawRectElements(inboxConversations.CreateGraphics(), message, item.Bounds);

                    if (elements.ReadRect.Contains(mouseEventArgs.Location))
                    {
                        Action(ActionID.Read, message);
                    }
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Display a directory of forums filtered by the given search string. If the search string is
        /// empty then all forums are displayed.
        /// </summary>
        /// <param name="searchString">A search string</param>
        public override void FilterViewByString(string searchString)
        {
            _currentFilterString = searchString.Trim().ToLower();
            InboxConversation selectedMessage = SelectedMessage;

            _conversations = new List <InboxConversation>(CIX.ConversationCollection.AllConversations);

            bool _isFiltering = !string.IsNullOrEmpty(_currentFilterString);

            if (_isFiltering)
            {
                _conversations = _conversations.Where(msg => msg.Author.Contains(_currentFilterString) || msg.Subject.Contains(_currentFilterString)).ToList();
            }

            InitialiseList();
            RefreshList();

            RestoreSelection(selectedMessage);
        }
Пример #16
0
        /// <summary>
        /// Redisplay the selected message.
        /// </summary>
        private void DisplaySelectedRow(bool center)
        {
            int newSelection = SelectedRow;

            if (newSelection >= 0)
            {
                if (center)
                {
                    CentreSelection();
                }

                InboxConversation message        = _conversations[newSelection];
                string            messageAddress = String.Format("cixmailbox:inbox:{0}", message.RemoteID);
                FoldersTree.MainForm.AddBacktrack(messageAddress, message.UnreadCount > 0);

                ShowMessage(message);
                FoldersTree.MainForm.RunEvent(EventID.MessageSelected, message);
                inboxConversations.Focus();
            }
        }
Пример #17
0
        /// <summary>
        /// Display the directory for the specified CategoryFolder
        /// </summary>
        public override bool ViewFromFolder(FolderBase folder, Address address, FolderOptions options)
        {
            if (folder != _currentFolder)
            {
                _currentFolder = folder;
                SortConversations();
            }

            // If an address is specified then it refers to a conversation ID that
            // needs to be selected. If it is not found, the first message is selected
            // instead.
            if (address != null && address.Scheme == "cixmailbox")
            {
                int selectedID;

                Int32.TryParse(address.Data, out selectedID);

                int selectedIndex;
                for (selectedIndex = 0; selectedIndex < _conversations.Count; ++selectedIndex)
                {
                    InboxConversation conversation = _conversations[selectedIndex];
                    if (conversation.RemoteID == selectedID)
                    {
                        break;
                    }
                }
                if (selectedIndex == _conversations.Count)
                {
                    selectedIndex = 0;
                }
                SelectedRow = selectedIndex;
                if (address.Unread)
                {
                    SelectedMessage.MarkUnread();
                }
                return(true);
            }

            // If options are specified then search for the next unread
            // in the list otherwise set the initial selection to something
            // useful.
            if (options == 0 && SelectedRow == -1)
            {
                SetInitialSelection();
            }
            else
            {
                int row = inboxConversations.SearchRow;
                if (row < 0 || options.HasFlag(FolderOptions.Reset))
                {
                    row = 0;
                }
                else if (_conversations.Count > 0)
                {
                    InboxConversation conversation = _conversations[row];
                    if (conversation.UnreadCount > 0)
                    {
                        conversation.MarkRead();
                    }
                }
                if (!FirstUnreadAfterRow(row, options))
                {
                    inboxConversations.SearchRow = 0;
                    return(false);
                }
            }

            FoldersTree.SetTopicName(_currentFolder.FullName);

            ActiveControl = inboxConversations;
            inboxConversations.Focus();
            return(true);
        }
Пример #18
0
        /// <summary>
        /// Compute the display rectangles for the various field elements of the given message
        /// </summary>
        private DrawRectElements ComputeDrawRectElements(Graphics graphics, InboxConversation message, Rectangle bounds)
        {
            DrawRectElements drawRectElements = new DrawRectElements();
            Rectangle        drawRect         = bounds;

            drawRect.Inflate(-2, -2);

            // The rectangle for the selection and focus
            drawRectElements.BoundaryRect = drawRect;

            drawRect.Y      = drawRect.Y + (drawRect.Height - _font.Height) / 2;
            drawRect.X     += 4;
            drawRect.Width -= 4;

            // Compute Read image rectangle
            Image     readImage = ReadImageForMessage(message);
            Rectangle imageRect = new Rectangle(drawRect.X, bounds.Y + (bounds.Height - readImage.Height) / 2, readImage.Width, readImage.Height);

            drawRectElements.ReadRect = imageRect;

            drawRect.X     += readImage.Width + 4;
            drawRect.Width -= readImage.Width + 4;

            // Compute author name rectangle
            SizeF idSize = graphics.MeasureString(message.Author, _font);

            drawRectElements.AuthorRect = drawRect;

            drawRect.X     += (int)idSize.Width + 4;
            drawRect.Width -= (int)idSize.Width + 4;

            // Compute first separator rectangle
            const string separatorChar = "•";

            idSize = graphics.MeasureString(separatorChar, _font);

            drawRectElements.Separator1Rect = drawRect;

            drawRect.X     += (int)idSize.Width + 4;
            drawRect.Width -= (int)idSize.Width + 4;

            // Compute date field rectangle
            string dateString = (_showFullDate)
                ? message.Date.ToString("d MMM yyyy") + " " + message.Date.ToShortTimeString()
                : message.Date.FriendlyString(true);

            idSize = graphics.MeasureString(dateString, _font);

            drawRectElements.DateRect = drawRect;

            drawRect.X     += (int)idSize.Width + 4;
            drawRect.Width -= (int)idSize.Width + 4;

            // Compute ID field rectangle
            string idString = (message.IsDraft)
                ? "Draft"
                : message.RemoteID.ToString(CultureInfo.InvariantCulture);

            idSize = graphics.MeasureString(idString, _font);

            drawRectElements.IDRect = drawRect;

            drawRect.X     += (int)idSize.Width + 4;
            drawRect.Width -= (int)idSize.Width + 4;

            // Compute second separator rectangle
            idSize = graphics.MeasureString(separatorChar, _font);
            drawRectElements.Separator2Rect = drawRect;

            // Compute subject line rectangle
            drawRect.X     += (int)idSize.Width + 4;
            drawRect.Width -= (int)idSize.Width + 8;

            drawRectElements.SubjectRect = drawRect;

            return(drawRectElements);
        }
Пример #19
0
 /// <summary>
 /// Initialises a new instance of the <see cref="InboxMessageEditor"/> class and
 /// populates it with data from the specified conversation.
 /// </summary>
 public InboxMessageEditor(InboxConversation conversation)
 {
     InitializeComponent();
     _currentConversation = conversation;
 }
Пример #20
0
        /// <summary>
        /// Print the current conversation.
        /// </summary>
        private void Print(InboxConversation conversation)
        {
            Font printFont = new Font("Arial", 10);

            PrintDocument printDoc = new PrintDocument
            {
                PrinterSettings     = FoldersTree.MainForm.PrintDocument.PrinterSettings,
                DefaultPageSettings = FoldersTree.MainForm.PrintDocument.DefaultPageSettings
            };

            PrintDialog pdi = new PrintDialog
            {
                Document    = printDoc,
                UseEXDialog = true
            };

            if (pdi.ShowDialog() == DialogResult.OK)
            {
                StringBuilder       convText = new StringBuilder();
                List <InboxMessage> thread   = conversation.Messages.ToList();

                convText.AppendFormat(Resources.PrintMailSubject, conversation.Subject);
                convText.AppendLine();
                convText.AppendFormat(Resources.PrintMailDate, conversation.Date);
                convText.AppendLine();
                convText.AppendLine();
                foreach (InboxMessage message in thread)
                {
                    convText.AppendFormat(Resources.PrintMailFrom, message.Author);
                    convText.AppendLine();
                    convText.AppendLine();
                    convText.AppendLine(message.Body);
                }

                string[] lines     = convText.ToString().Split('\n');
                int      lineIndex = 0;
                try
                {
                    printDoc.PrintPage += (sender, ev) =>
                    {
                        float leftMargin = ev.MarginBounds.Left;
                        float topMargin  = ev.MarginBounds.Top;

                        // Print each line of the file.
                        float yPos = topMargin;
                        while (lineIndex < lines.Length)
                        {
                            string line = lines[lineIndex];
                            SizeF  sf   = ev.Graphics.MeasureString(line, printFont, ev.MarginBounds.Width);
                            if (yPos + sf.Height > ev.MarginBounds.Bottom)
                            {
                                break;
                            }
                            using (Brush textBrush = new SolidBrush(SystemColors.ControlText))
                            {
                                ev.Graphics.DrawString(line, printFont, textBrush, new RectangleF(new PointF(leftMargin, yPos), sf), new StringFormat());
                            }
                            yPos += (sf.Height > 0) ? sf.Height : printFont.GetHeight(ev.Graphics);
                            ++lineIndex;
                        }

                        // If more lines exist, print another page.
                        ev.HasMorePages = lineIndex < lines.Length;
                    };
                    printDoc.Print();
                }
                catch (Exception e)
                {
                    MessageBox.Show(string.Format(Resources.PrintError, e.Message), Resources.Error, MessageBoxButtons.OK);
                }
            }
        }