/// <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; }
/// <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); } }
/// <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(); }
/// <summary> /// Go to the next unread message. /// </summary> private void GoToNextUnread(InboxConversation conversation) { if (conversation != null && conversation.UnreadCount > 0) { conversation.MarkRead(); } FoldersTree.NextUnread(FolderOptions.NextUnread); }
/// <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(new[] { '\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.Count()) { 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.Count(); }; printDoc.Print(); } catch (Exception e) { MessageBox.Show(string.Format(Resources.PrintError, e.Message), Resources.Error, MessageBoxButtons.OK); } } }
/// <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; }
/// <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; } }
/// <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; }
/// <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(); } }
/// <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); }