/// <summary> /// Apply all rules to the specified message /// </summary> /// <param name="message">Message to which rules are applied</param> internal void ApplyRules(CIXMessage message) { foreach (RuleGroup ruleGroup in ruleGroups) { ApplyRule(ruleGroup, message); } }
/// <summary> /// Returns whether the message being edited matches the specified CIXMessage. /// </summary> public bool Matches(CIXMessage message) { if (_message == null || message == null) { return(false); } return(_message.CommentID == message.CommentID && _message.TopicID == message.TopicID); }
/// <summary> /// Find an existing message editor that matches the requested message. /// </summary> public static CIXMessageEditor Get(CIXMessage message) { if (_modelessList == null) { _modelessList = new List <CIXMessageEditor>(); return(null); } return(_modelessList.FirstOrDefault(editor => editor.Matches(message))); }
/// <summary> /// Expands recognised tags in theString based on the object values. /// </summary> private string ExpandTags(string theString, CIXMessage message, bool cond) { bool hasOneTag = false; int tagStartIndex = 0; while ((tagStartIndex = theString.IndexOf('$', tagStartIndex)) >= 0) { int tagEndIndex = theString.IndexOf('$', tagStartIndex + 1); if (tagEndIndex < 0) { break; } int tagLength = (tagEndIndex - tagStartIndex) + 1; string tagName = theString.Substring(tagStartIndex + 1, tagLength - 2); string tagSelName = string.Format("tag{0}", tagName); Type messageType = typeof(TaggedMessage); MethodInfo method = messageType.GetMethod(tagSelName); string replacementString = (string)method.Invoke(message, new object[] { message, this }); if (replacementString == null) { theString = theString.Substring(0, tagStartIndex) + theString.Substring(tagEndIndex + 1); } else { theString = theString.Substring(0, tagStartIndex) + replacementString + theString.Substring(tagEndIndex + 1); hasOneTag = true; if (!string.IsNullOrEmpty(replacementString)) { cond = false; } tagStartIndex += replacementString.Length; } } return((cond && hasOneTag) ? string.Empty : theString); }
/// <summary> /// Initialises a new instance of the <see cref="CIXMessageEditor"/> class. /// </summary> /// <param name="message">The CIXMessage to display in the editor</param> /// <param name="addSignature">True if a signature should be added</param> public CIXMessageEditor(CIXMessage message, bool addSignature) { InitializeComponent(); AddSignature = addSignature; _message = message; }
public void TestForumsFastSync() { string databasePath = Path.GetTempFileName(); CIX.Init(databasePath); Folder forumFolder = new Folder { ParentID = -1, Name = "cix.beta", Unread = 0, UnreadPriority = 0 }; CIX.FolderCollection.Add(forumFolder); Folder topicFolder = new Folder { Name = "cixreader", ParentID = forumFolder.ID, Unread = 0, UnreadPriority = 0 }; CIX.FolderCollection.Add(topicFolder); // Seed message as fast sync doesn't work on empty topics CIXMessage seedMessage = new CIXMessage { RemoteID = 1, Author = "CIX", Body = "Seed message", CommentID = 0 }; topicFolder.Messages.Add(seedMessage); string userSyncData = Resource1.UserSyncData; DateTime sinceDate = default(DateTime); FolderCollection.AddMessages(Utilities.GenerateStreamFromString(userSyncData), ref sinceDate, true, false); // On completion, verify that there are no duplicates in the topic List <CIXMessage> messages = topicFolder.Messages.OrderBy(fld => fld.RemoteID).ToList(); int lastMessageID = -1; foreach (CIXMessage cixMessage in messages) { Assert.AreNotEqual(cixMessage.RemoteID, 0); Assert.AreNotEqual(cixMessage.RemoteID, lastMessageID); Assert.AreNotEqual(cixMessage.ID, 0); lastMessageID = cixMessage.RemoteID; } // Verify that specific messages are marked read CIXMessage message = topicFolder.Messages.MessageByID(2323); Assert.IsNotNull(message); Assert.IsFalse(message.Unread); // Verify that specific messages are marked unread message = topicFolder.Messages.MessageByID(2333); Assert.IsNotNull(message); Assert.IsTrue(message.Unread); // Verify the total unread on the folder and globally Assert.AreEqual(topicFolder.Unread, 1); Assert.AreEqual(topicFolder.UnreadPriority, 6); Assert.AreEqual(CIX.FolderCollection.TotalUnread, 1); Assert.AreEqual(CIX.FolderCollection.TotalUnreadPriority, 6); }
/// <summary> /// Returns the message address. /// </summary> public static string tagLink(this CIXMessage message, StyleController styleController) { return(string.Format("cix:{0}/{1}:{2}", message.Forum.Name, message.Topic.Name, message.RemoteID)); }
/// <summary> /// Apply the specified rule group to the message. On completion, the flags /// in the message will be adjusted as per the rule. /// <para> /// The caller must persist both the message and the associated folder back /// to the database if the function returns true since both will likely have /// been altered. /// </para> /// </summary> /// <param name="ruleGroup">Rule group to apply</param> /// <param name="message">CIXMessage to which rule is applied</param> /// <returns>True if the rule changed the message, false otherwise</returns> internal static bool ApplyRule(RuleGroup ruleGroup, CIXMessage message) { bool changed = false; try { Func <CIXMessage, bool> evaluateCriteria = ruleGroup.Criteria.Compile(); if (ruleGroup.active && evaluateCriteria(message)) { bool isUnread = message.Unread; bool isClear = ruleGroup.actionCode.HasFlag(RuleActionCodes.Clear); if (ruleGroup.actionCode.HasFlag(RuleActionCodes.Unread)) { if (!message.ReadLocked) { message.Unread = !isClear; if (isUnread != message.Unread) { message.ReadPending = true; Folder folder = CIX.FolderCollection[message.TopicID]; folder.Unread += message.Unread ? 1 : -1; if (folder.Unread < 0) { folder.Unread = 0; } if (message.Priority) { folder.UnreadPriority += message.Unread ? 1 : -1; if (folder.UnreadPriority < 0) { folder.UnreadPriority = 0; } } folder.MarkReadRangePending = !message.IsPseudo; changed = true; } } } if (ruleGroup.actionCode.HasFlag(RuleActionCodes.Priority)) { bool oldPriority = message.Priority; message.Priority = !isClear; changed = message.Priority != oldPriority; if (changed && message.Unread) { Folder folder = CIX.FolderCollection[message.TopicID]; folder.UnreadPriority += message.Priority ? 1 : -1; if (folder.UnreadPriority < 0) { folder.UnreadPriority = 0; } } } if (ruleGroup.actionCode.HasFlag(RuleActionCodes.Ignored)) { message.Ignored = !isClear; if (message.Ignored && message.Unread) { message.Unread = false; message.ReadPending = true; Folder folder = CIX.FolderCollection[message.TopicID]; folder.Unread -= 1; if (message.Priority) { folder.UnreadPriority -= 1; if (folder.UnreadPriority < 0) { folder.UnreadPriority = 0; } } folder.MarkReadRangePending = true; changed = true; } } if (ruleGroup.actionCode.HasFlag(RuleActionCodes.Flag)) { bool oldStarred = message.Starred; message.Starred = !isClear; if (oldStarred != message.Starred) { message.StarPending = true; changed = true; } } } } catch (Exception e) { LogFile.WriteLine("Error: Exception processing rule \"{0}\" : {1}", ruleGroup.title, e.Message); } return(changed); }
/// <summary> /// Returns the message author. /// </summary> public static string tagAuthor(this CIXMessage message, StyleController styleController) { return(styleController.StringFromTag(message.Author)); }
/// <summary> /// Returns the message body. /// </summary> public static string tagBody(this CIXMessage message, StyleController styleController) { return(styleController.HtmlFromTag(message.Body)); }
/// <summary> /// Returns the message comment ID. /// </summary> public static string tagCommentID(this CIXMessage message, StyleController styleController) { return(message.CommentID > 0 ? string.Format("{0}", message.CommentID) : string.Empty); }
/// <summary> /// Returns the message remote ID. /// </summary> public static string tagID(this CIXMessage message, StyleController styleController) { return(string.Format("{0}", message.RemoteID)); }
/// <summary> /// Return the string representing the unformatted body /// </summary> public static string UnformattedText(this CIXMessage message) { return(message.Body); }
/// <summary> /// Return true if the message is a draft. /// </summary> public override bool CanContain(CIXMessage message) { return(Comparator(message)); }
/// <summary> /// Display the message editor window. /// </summary> private void CIXMessageEditor_Load(object sender, EventArgs e) { bool isReply = _message.CommentID > 0; string forumName = string.Empty; string topicName = string.Empty; Editor = nmMessage; // Restore the form width, height and state from the last time it // was invoked. this.RestoreFromSettings(); Folder folder = _message.Topic; if (folder != null) { Folder parentFolder = folder.ParentFolder; if (parentFolder != null) { forumName = parentFolder.Name; } topicName = folder.Name; } if (isReply && folder != null) { string replyName = string.Empty; isReply = false; CIXMessage parentMessage = folder.Messages.MessageByID(_message.CommentID); if (parentMessage != null) { replyName = parentMessage.Author; Mugshot mugshot = Mugshot.MugshotForUser(replyName, true); nmReplyImage.Image = mugshot.RealImage; nmReplyUsername.Text = string.Format(Resources.ReplyEditorTitle, replyName); nmReplyText.Text = parentMessage.Body; // Make the full body available as a tooltip. nmBodyTooltip.SetToolTip(nmReplyText, parentMessage.Body); isReply = true; } Text = string.Format(Resources.ReplyTitle, replyName, forumName, topicName); } else { Text = string.Format(Resources.NewMessageTitle, forumName, topicName); } if (!isReply) { nmReplyPanel.Visible = false; nmMessage.Top -= nmReplyPanel.Height; nmMessage.Height += nmReplyPanel.Height; } // Load signature list ReloadSignaturesList(nmSignatureList); // Add any existing message with signature. LoadMessage(forumName, _message.Body); nmMessage.Font = UI.GetFont(UI.Forums.font, UI.Forums.fontsize); _wasPending = _message.IsPending; _message.PostPending = false; MessageEditorCollection.Add(this); EnableSendButton(); }
/// <summary> /// Returns whether the folder can contain the specified message. /// </summary> public virtual bool CanContain(CIXMessage message) { return(true); }
/// <summary> /// Returns the message date. /// </summary> public static string tagDate(this CIXMessage message, StyleController styleController) { return(styleController.DateFromTag(message.Date)); }
/// <summary> /// Returns the message subject. /// </summary> public static string tagSubject(this CIXMessage message, StyleController styleController) { return(styleController.StringFromTag(message.Subject.FirstNonBlankLine())); }
/// <summary> /// Returns the message reply. /// </summary> public static string tagInReplyTo(this CIXMessage message, StyleController styleController) { return(message.CommentID > 0 ? string.Format("cix:{0}/{1}:{2}", message.Forum.Name, message.Topic.Name, message.CommentID) : string.Empty); }
/// <summary> /// Initialises a new instance of the <see cref="InboxMessageEditor"/> class and /// populates it with data from the specified CIX message. /// </summary> public InboxMessageEditor(CIXMessage message) { InitializeComponent(); _messageToUse = message; }
/// <summary> /// Topic folders can contain all messages. /// </summary> public override bool CanContain(CIXMessage message) { return(message.TopicID == ID); }