/// <summary> /// Actually sends log message to <see cref="TargetRichTextBox"/> /// </summary> /// <param name="logMessage">a message to send</param> /// <param name="rule">matching coloring rule</param> /// <param name="logEvent">original logEvent</param> /// <returns>true if the message was actually sent (i.e. <see cref="TargetRichTextBox"/> is not null and not disposed, and no exception happened during message send)</returns> private bool DoSendMessageToTextbox(string logMessage, RichTextBoxRowColoringRule rule, LogEventInfo logEvent) { RichTextBox textbox = TargetRichTextBox; try { if (textbox != null && !textbox.IsDisposed) { if (textbox.InvokeRequired) { textbox.BeginInvoke(new DelSendTheMessageToRichTextBox(SendTheMessageToRichTextBox), logMessage, rule, logEvent); } else { SendTheMessageToRichTextBox(logMessage, rule, logEvent); } return(true); } } catch (Exception ex) { InternalLogger.Warn(ex.ToString()); if (LogManager.ThrowExceptions) { throw; } } return(false); }
/// <summary> /// Log message to RichTextBox. /// </summary> /// <param name="logEvent">The logging event.</param> protected override void Write(LogEventInfo logEvent) { RichTextBox textbox = TargetRichTextBox; if (textbox == null || textbox.IsDisposed) { //no last logged textbox lastLoggedTextBoxControl = null; if (AllowAccessoryFormCreation) { CreateAccessoryForm(); } else if (messageRetention == RichTextBoxTargetMessageRetentionStrategy.None) { InternalLogger.Trace("Textbox for target {0} is {1}, skipping logging", this.Name, textbox == null? "null" : "disposed"); return; } } string logMessage = Layout.Render(logEvent); RichTextBoxRowColoringRule matchingRule = FindMatchingRule(logEvent); bool messageSent = DoSendMessageToTextbox(logMessage, matchingRule, logEvent); if (messageSent) { //remember last logged text box lastLoggedTextBoxControl = textbox; } switch (messageRetention) { case RichTextBoxTargetMessageRetentionStrategy.None: break; case RichTextBoxTargetMessageRetentionStrategy.All: StoreMessage(logMessage, matchingRule, logEvent); break; case RichTextBoxTargetMessageRetentionStrategy.OnlyMissed: if (!messageSent) { StoreMessage(logMessage, matchingRule, logEvent); } break; default: HandleError("Unexpected retention strategy {0}", messageRetention); break; } }
/// <summary> /// Stores a new message in internal queue, if it exists. Removes overflowing messages. /// </summary> /// <param name="logMessage">a message to store</param> /// <param name="rule">a corresponding coloring rule</param> /// <param name="logEvent">original LogEvent</param> private void StoreMessage(string logMessage, RichTextBoxRowColoringRule rule, LogEventInfo logEvent) { lock (messageQueueLock) { if (messageQueue == null) { return; } if (MaxLines > 0) { while (messageQueue.Count >= MaxLines) { messageQueue.Dequeue(); } } messageQueue.Enqueue(new MessageInfo(logMessage, rule, logEvent)); } }
internal MessageInfo(string message, RichTextBoxRowColoringRule rule, LogEventInfo logEvent) { this.Message = message; this.Rule = rule; this.LogEvent = logEvent; }
private void SendTheMessageToRichTextBox(string logMessage, RichTextBoxRowColoringRule rule, LogEventInfo logEvent) { RichTextBox textBox = TargetRichTextBox; int startIndex = textBox.Text.Length; textBox.SelectionStart = startIndex; textBox.SelectionBackColor = GetColorFromString(rule.BackgroundColor, textBox.BackColor); textBox.SelectionColor = GetColorFromString(rule.FontColor, textBox.ForeColor); textBox.SelectionFont = new Font(textBox.SelectionFont, textBox.SelectionFont.Style ^ rule.Style); textBox.AppendText(logMessage + "\n"); textBox.SelectionLength = textBox.Text.Length - textBox.SelectionStart; // find word to color foreach (RichTextBoxWordColoringRule wordRule in WordColoringRules) { MatchCollection matches = wordRule.CompiledRegex.Matches(textBox.Text, startIndex); foreach (Match match in matches) { textBox.SelectionStart = match.Index; textBox.SelectionLength = match.Length; textBox.SelectionBackColor = GetColorFromString(wordRule.BackgroundColor, textBox.BackColor); textBox.SelectionColor = GetColorFromString(wordRule.FontColor, textBox.ForeColor); textBox.SelectionFont = new Font(textBox.SelectionFont, textBox.SelectionFont.Style ^ wordRule.Style); } } if (SupportLinks) { object linkInfoObj; lock (logEvent.Properties) { logEvent.Properties.TryGetValue(RichTextBoxLinkLayoutRenderer.LinkInfo.PropertyName, out linkInfoObj); } if (linkInfoObj != null) { RichTextBoxLinkLayoutRenderer.LinkInfo linkInfo = (RichTextBoxLinkLayoutRenderer.LinkInfo)linkInfoObj; bool linksAdded = false; textBox.SelectionStart = startIndex; textBox.SelectionLength = textBox.Text.Length - textBox.SelectionStart; string addedText = textBox.SelectedText; MatchCollection matches = linkAddRegex.Matches(addedText); //only access regex after checking SupportLinks, as it assures the initialization for (int i = matches.Count - 1; i >= 0; --i) //backwards order, so the string positions are not affected { Match match = matches[i]; string linkText = linkInfo.GetValue(match.Value); if (linkText != null) { textBox.SelectionStart = startIndex + match.Index; textBox.SelectionLength = match.Length; FormHelper.ChangeSelectionToLink(textBox, linkText, LinkPrefix + logEvent.SequenceID); linksAdded = true; } } if (linksAdded) { linkedEvents[logEvent.SequenceID] = logEvent; } } } //remove some lines if there above the max if (MaxLines > 0) { //find the last line by reading the textbox var lastLineWithContent = textBox.Lines.LastOrDefault(f => !string.IsNullOrEmpty(f)); if (lastLineWithContent != null) { char lastChar = lastLineWithContent.Last(); var visibleLineCount = textBox.GetLineFromCharIndex(textBox.Text.LastIndexOf(lastChar)); var tooManyLines = (visibleLineCount - MaxLines) + 1; if (tooManyLines > 0) { textBox.SelectionStart = 0; textBox.SelectionLength = textBox.GetFirstCharIndexFromLine(tooManyLines); if (SupportLinks) { string selectedRtf = textBox.SelectedRtf; //only access regex after checking SupportLinks, as it assures the initialization foreach (Match match in linkRemoveRtfRegex.Matches(selectedRtf)) { int id; if (int.TryParse(match.Groups[1].Value, out id)) { lock (linkedEventsLock) { linkedEvents.Remove(id); } } } } textBox.SelectedRtf = "{\\rtf1\\ansi}"; } } } if (AutoScroll) { textBox.Select(textBox.TextLength, 0); textBox.ScrollToCaret(); } }