Ejemplo n.º 1
0
        public void AddMessage(MessageModel msg, bool addLinebreak, bool showTimestamps)
        {
            #if MSG_DEBUG
            Trace.Call(msg, addLinebreak);
            #endif

            if (msg == null) {
                throw new ArgumentNullException("msg");
            }

            var buffer = Buffer;
            var iter = buffer.EndIter;
            var startMark = new Gtk.TextMark(null, true);
            buffer.AddMark(startMark, iter);

            var senderPrefixWidth = GetSenderPrefixWidth(msg);
            Gtk.TextTag indentTag = null;
            if (senderPrefixWidth != 0) {
                // TODO: re-use text tags that have the same indent width
                indentTag = new Gtk.TextTag(null) {
                    Indent = -senderPrefixWidth
                };
                _MessageTextTagTable.Add(indentTag);
            }

            if (showTimestamps) {
                var msgTimeStamp = msg.TimeStamp.ToLocalTime();
                if (_LastMessage != null) {
                    var lastMsgTimeStamp = _LastMessage.TimeStamp.ToLocalTime();
                    var span = msgTimeStamp.Date - lastMsgTimeStamp.Date;
                    if (span.Days > 0) {
                        var dayLine = new MessageBuilder().
                            AppendEventPrefix();
                        if (span.Days > 1) {
                            dayLine.AppendText(_("Day changed from {0} to {1}"),
                                               lastMsgTimeStamp.ToShortDateString(),
                                               msgTimeStamp.ToShortDateString());
                        } else {
                            dayLine.AppendText(_("Day changed to {0}"),
                                               msgTimeStamp.ToLongDateString());
                        }
                        dayLine.AppendText("\n");
                        var dayLineMsg = dayLine.ToMessage().ToString();
                        Buffer.InsertWithTags(ref iter, dayLineMsg, EventTag);
                    }
                }

                string timestamp = null;
                try {
                    string format = (string)Frontend.UserConfig["Interface/Notebook/TimestampFormat"];
                    if (!String.IsNullOrEmpty(format)) {
                        timestamp = msgTimeStamp.ToString(format);
                    }
                } catch (FormatException e) {
                    timestamp = "Timestamp Format ERROR: " + e.Message;
                }

                if (timestamp != null) {
                    timestamp = String.Format("{0} ", timestamp);
                    buffer.Insert(ref iter, timestamp);

                    // apply timestamp width to indent tag
                    if (indentTag != null) {
                        indentTag.Indent -= GetPangoWidth(timestamp);
                    }
                }
            }

            var msgStartMark = new Gtk.TextMark(null, true);
            buffer.AddMark(msgStartMark, iter);

            bool hasHighlight = false;
            foreach (MessagePartModel msgPart in msg.MessageParts) {
                // supposed to be used only in a ChatView
                if (msgPart.IsHighlight) {
                    hasHighlight = true;
                }

                // TODO: implement all types
                if (msgPart is UrlMessagePartModel) {
                    var urlPart = (UrlMessagePartModel) msgPart;
                    var linkText = urlPart.Text ?? urlPart.Url;

                    var url = urlPart.Url;
                    Uri uri;
                    try {
                        uri = new Uri(url);
                    } catch (UriFormatException ex) {
            #if LOG4NET
                        _Logger.Error("AddMessage(): Invalid URL: " + url, ex);
            #endif
                        buffer.Insert(ref iter, linkText);
                        continue;
                    }

                    var tags = new List<Gtk.TextTag>();
                    // link URI tag
                    var linkTag = new LinkTag(uri);
                    linkTag.TextEvent += OnLinkTagTextEvent;
                    _MessageTextTagTable.Add(linkTag);
                    tags.Add(linkTag);

                    // link style tag
                    tags.Add(LinkTag);

                    buffer.InsertWithTags(ref iter, linkText, tags.ToArray());
                } else if (msgPart is TextMessagePartModel) {
                    var tags = new List<Gtk.TextTag>();
                    TextMessagePartModel fmsgti = (TextMessagePartModel) msgPart;
                    if (fmsgti.ForegroundColor != TextColor.None) {
                        var bg = ColorConverter.GetTextColor(BackgroundColor);
                        if (fmsgti.BackgroundColor != TextColor.None) {
                            bg = fmsgti.BackgroundColor;
                        }
                        TextColor color = TextColorTools.GetBestTextColor(
                            fmsgti.ForegroundColor, bg
                        );
                        string tagname = GetTextTagName(color, null);
                        var tag = _MessageTextTagTable.Lookup(tagname);
                        tags.Add(tag);
                    }
                    if (fmsgti.BackgroundColor != TextColor.None) {
                        // TODO: get this from ChatView
                        string tagname = GetTextTagName(null, fmsgti.BackgroundColor);
                        var tag = _MessageTextTagTable.Lookup(tagname);
                        tags.Add(tag);
                    }
                    if (fmsgti.Underline) {
            #if LOG4NET && MSG_DEBUG
                        _Logger.Debug("AddMessage(): fmsgti.Underline is true");
            #endif
                        tags.Add(UnderlineTag);
                    }
                    if (fmsgti.Bold) {
            #if LOG4NET && MSG_DEBUG
                        _Logger.Debug("AddMessage(): fmsgti.Bold is true");
            #endif
                        tags.Add(BoldTag);
                    }
                    if (fmsgti.Italic) {
            #if LOG4NET && MSG_DEBUG
                        _Logger.Debug("AddMessage(): fmsgti.Italic is true");
            #endif
                        tags.Add(ItalicTag);
                    }

                    if (tags.Count > 0) {
                        buffer.InsertWithTags(ref iter, fmsgti.Text, tags.ToArray());
                    } else {
                        buffer.Insert(ref iter, fmsgti.Text);
                    }
                }
            }
            var startIter = buffer.GetIterAtMark(startMark);
            if (msg.MessageType == MessageType.Event) {
                buffer.ApplyTag(EventTag, startIter, iter);
            }
            if (indentTag != null) {
                buffer.ApplyTag(indentTag, startIter, iter);
            }
            var nick = msg.GetNick();
            if (nick != null) {
                // TODO: re-use the same person tag for the same nick
                var personTag = new PersonTag(nick, nick);
                personTag.TextEvent += OnPersonTagTextEvent;
                _MessageTextTagTable.Add(personTag);

                var msgStartIter = buffer.GetIterAtMark(msgStartMark);
                var nickEndIter = msgStartIter;
                nickEndIter.ForwardChars(nick.Length + 2);
                buffer.ApplyTag(PersonTag, msgStartIter, nickEndIter);
                buffer.ApplyTag(personTag, msgStartIter, nickEndIter);
            }
            buffer.DeleteMark(startMark);
            buffer.DeleteMark(msgStartMark);
            if (addLinebreak) {
                buffer.Insert(ref iter, "\n");
            }

            CheckBufferSize();

            if (IsGtk2_17) {
                // HACK: force a redraw of the widget, as for some reason
                // GTK+ 2.17.6 is not redrawing some lines we add here, especially
                // for local messages. See:
                // http://projects.qnetp.net/issues/show/185
                QueueDraw();
            }
            if (Frontend.IsWindows && _LastMessage == null) {
                // HACK: workaround rendering issue on Windows where the
                // first inserted text is not showing up until the next insert
                QueueDraw();
            }

            if (MessageAdded != null) {
                MessageAdded(this, new MessageTextViewMessageAddedEventArgs(msg));
            }

            if (hasHighlight) {
                if (MessageHighlighted != null) {
                    MessageHighlighted(this, new MessageTextViewMessageHighlightedEventArgs(msg));
                }
            }

            _LastMessage = msg;
        }
Ejemplo n.º 2
0
        public void AddMessage(MessageModel msg, bool addLinebreak, bool showTimestamps)
        {
#if MSG_DEBUG
            Trace.Call(msg, addLinebreak);
#endif

            if (msg == null)
            {
                throw new ArgumentNullException("msg");
            }

            var buffer    = Buffer;
            var iter      = buffer.EndIter;
            var startMark = new Gtk.TextMark(null, true);
            buffer.AddMark(startMark, iter);


            var         senderPrefixWidth = GetSenderPrefixWidth(msg);
            Gtk.TextTag indentTag         = null;
            if (senderPrefixWidth != 0)
            {
                // TODO: re-use text tags that have the same indent width
                indentTag = new Gtk.TextTag(null)
                {
                    Indent = -senderPrefixWidth
                };
                _MessageTextTagTable.Add(indentTag);
            }

            if (showTimestamps)
            {
                var msgTimeStamp = msg.TimeStamp.ToLocalTime();
                if (_LastMessage != null)
                {
                    var lastMsgTimeStamp = _LastMessage.TimeStamp.ToLocalTime();
                    var span             = msgTimeStamp.Date - lastMsgTimeStamp.Date;
                    if (span.Days > 0)
                    {
                        var dayLine = new MessageBuilder().
                                      AppendEventPrefix();
                        if (span.Days > 1)
                        {
                            dayLine.AppendText(_("Day changed from {0} to {1}"),
                                               lastMsgTimeStamp.ToShortDateString(),
                                               msgTimeStamp.ToShortDateString());
                        }
                        else
                        {
                            dayLine.AppendText(_("Day changed to {0}"),
                                               msgTimeStamp.ToLongDateString());
                        }
                        dayLine.AppendText("\n");
                        var dayLineMsg = dayLine.ToMessage().ToString();
                        Buffer.InsertWithTags(ref iter, dayLineMsg, EventTag);
                    }
                }

                string timestamp = null;
                try {
                    string format = (string)Frontend.UserConfig["Interface/Notebook/TimestampFormat"];
                    if (!String.IsNullOrEmpty(format))
                    {
                        timestamp = msgTimeStamp.ToString(format);
                    }
                } catch (FormatException e) {
                    timestamp = "Timestamp Format ERROR: " + e.Message;
                }

                if (timestamp != null)
                {
                    timestamp = String.Format("{0} ", timestamp);
                    buffer.Insert(ref iter, timestamp);

                    // apply timestamp width to indent tag
                    if (indentTag != null)
                    {
                        indentTag.Indent -= GetPangoWidth(timestamp);
                    }
                }
            }

            var msgStartMark = new Gtk.TextMark(null, true);
            buffer.AddMark(msgStartMark, iter);

            bool hasHighlight = false;
            foreach (MessagePartModel msgPart in msg.MessageParts)
            {
                // supposed to be used only in a ChatView
                if (msgPart.IsHighlight)
                {
                    hasHighlight = true;
                }

                // TODO: implement all types
                if (msgPart is UrlMessagePartModel)
                {
                    var urlPart  = (UrlMessagePartModel)msgPart;
                    var linkText = urlPart.Text ?? urlPart.Url;

                    Uri uri;
                    try {
                        uri = new Uri(urlPart.Url);
                    } catch (UriFormatException ex) {
#if LOG4NET
                        _Logger.Error("AddMessage(): Invalid URL: " + urlPart.Url, ex);
#endif
                        buffer.Insert(ref iter, linkText);
                        continue;
                    }

                    var tags = new List <Gtk.TextTag>();
                    // link URI tag
                    var linkTag = new LinkTag(uri);
                    linkTag.TextEvent += OnLinkTagTextEvent;
                    _MessageTextTagTable.Add(linkTag);
                    tags.Add(linkTag);

                    // link style tag
                    tags.Add(LinkTag);

                    buffer.InsertWithTags(ref iter, linkText, tags.ToArray());
                }
                else if (msgPart is TextMessagePartModel)
                {
                    var tags = new List <Gtk.TextTag>();
                    TextMessagePartModel fmsgti = (TextMessagePartModel)msgPart;
                    if (fmsgti.ForegroundColor != TextColor.None)
                    {
                        var bg = ColorConverter.GetTextColor(BackgroundColor);
                        if (fmsgti.BackgroundColor != TextColor.None)
                        {
                            bg = fmsgti.BackgroundColor;
                        }
                        TextColor color = TextColorTools.GetBestTextColor(
                            fmsgti.ForegroundColor, bg
                            );
                        string tagname = GetTextTagName(color, null);
                        var    tag     = _MessageTextTagTable.Lookup(tagname);
                        tags.Add(tag);
                    }
                    if (fmsgti.BackgroundColor != TextColor.None)
                    {
                        // TODO: get this from ChatView
                        string tagname = GetTextTagName(null, fmsgti.BackgroundColor);
                        var    tag     = _MessageTextTagTable.Lookup(tagname);
                        tags.Add(tag);
                    }
                    if (fmsgti.Underline)
                    {
#if LOG4NET && MSG_DEBUG
                        _Logger.Debug("AddMessage(): fmsgti.Underline is true");
#endif
                        tags.Add(UnderlineTag);
                    }
                    if (fmsgti.Bold)
                    {
#if LOG4NET && MSG_DEBUG
                        _Logger.Debug("AddMessage(): fmsgti.Bold is true");
#endif
                        tags.Add(BoldTag);
                    }
                    if (fmsgti.Italic)
                    {
#if LOG4NET && MSG_DEBUG
                        _Logger.Debug("AddMessage(): fmsgti.Italic is true");
#endif
                        tags.Add(ItalicTag);
                    }

                    if (tags.Count > 0)
                    {
                        buffer.InsertWithTags(ref iter, fmsgti.Text, tags.ToArray());
                    }
                    else
                    {
                        buffer.Insert(ref iter, fmsgti.Text);
                    }
                }
            }
            var startIter = buffer.GetIterAtMark(startMark);
            if (msg.MessageType == MessageType.Event)
            {
                buffer.ApplyTag(EventTag, startIter, iter);
            }
            if (indentTag != null)
            {
                buffer.ApplyTag(indentTag, startIter, iter);
            }
            var nick = msg.GetNick();
            if (nick != null)
            {
                // TODO: re-use the same person tag for the same nick
                var personTag = new PersonTag(nick, nick);
                personTag.TextEvent += OnPersonTagTextEvent;
                _MessageTextTagTable.Add(personTag);

                var msgStartIter = buffer.GetIterAtMark(msgStartMark);
                var nickEndIter  = msgStartIter;
                nickEndIter.ForwardChars(nick.Length + 2);
                buffer.ApplyTag(PersonTag, msgStartIter, nickEndIter);
                buffer.ApplyTag(personTag, msgStartIter, nickEndIter);
            }
            buffer.DeleteMark(startMark);
            buffer.DeleteMark(msgStartMark);
            if (addLinebreak)
            {
                buffer.Insert(ref iter, "\n");
            }

            CheckBufferSize();

            if (IsGtk2_17)
            {
                // HACK: force a redraw of the widget, as for some reason
                // GTK+ 2.17.6 is not redrawing some lines we add here, especially
                // for local messages. See:
                // http://projects.qnetp.net/issues/show/185
                QueueDraw();
            }
            if (Frontend.IsWindows && _LastMessage == null)
            {
                // HACK: workaround rendering issue on Windows where the
                // first inserted text is not showing up until the next insert
                QueueDraw();
            }

            if (MessageAdded != null)
            {
                MessageAdded(this, new MessageTextViewMessageAddedEventArgs(msg));
            }

            if (hasHighlight)
            {
                if (MessageHighlighted != null)
                {
                    MessageHighlighted(this, new MessageTextViewMessageHighlightedEventArgs(msg));
                }
            }

            _LastMessage = msg;
        }
Ejemplo n.º 3
0
        public void AddMessage(MessageModel msg, bool addLinebreak, bool showTimestamps)
        {
            #if MSG_DEBUG
            Trace.Call(msg, addLinebreak);
            #endif

            if (msg == null) {
                throw new ArgumentNullException("msg");
            }

            var buffer = Buffer;
            var iter = buffer.EndIter;
            var startMark = new Gtk.TextMark(null, true);
            buffer.AddMark(startMark, iter);

            var senderPrefixWidth = GetSenderPrefixWidth(msg);
            Gtk.TextTag indentTag = null;
            if (senderPrefixWidth != 0) {
                // TODO: re-use text tags that have the same indent width
                indentTag = new Gtk.TextTag(null) {
                    Indent = -senderPrefixWidth
                };
                _MessageTextTagTable.Add(indentTag);
            }

            if (showTimestamps) {
                var msgTimeStamp = msg.TimeStamp.ToLocalTime();
                if (_LastMessage != null) {
                    var lastMsgTimeStamp = _LastMessage.TimeStamp.ToLocalTime();
                    var span = msgTimeStamp.Date - lastMsgTimeStamp.Date;
                    if (span.Days > 0) {
                        var dayLine = new MessageBuilder().
                            AppendEventPrefix();
                        if (span.Days > 1) {
                            dayLine.AppendText(_("Day changed from {0} to {1}"),
                                               lastMsgTimeStamp.ToShortDateString(),
                                               msgTimeStamp.ToShortDateString());
                        } else {
                            dayLine.AppendText(_("Day changed to {0}"),
                                               msgTimeStamp.ToLongDateString());
                        }
                        dayLine.AppendText("\n");
                        var dayLineMsg = dayLine.ToMessage().ToString();
                        Buffer.InsertWithTags(ref iter, dayLineMsg, EventTag);
                    }
                }

                string timestamp = null;
                try {
                    string format = (string)Frontend.UserConfig["Interface/Notebook/TimestampFormat"];
                    if (!String.IsNullOrEmpty(format)) {
                        timestamp = msgTimeStamp.ToString(format);
                    }
                } catch (FormatException e) {
                    timestamp = "Timestamp Format ERROR: " + e.Message;
                }

                if (timestamp != null) {
                    InsertTimeStamp(buffer, ref iter, timestamp, msg);

                    // apply timestamp width to indent tag
                    if (indentTag != null) {
                        indentTag.Indent -= GetPangoWidth(timestamp);
                    }
                }
            }

            var msgStartMark = new Gtk.TextMark(null, true);
            buffer.AddMark(msgStartMark, iter);

            bool hasHighlight = false;
            foreach (MessagePartModel msgPart in msg.MessageParts) {
                // supposed to be used only in a ChatView
                if (msgPart.IsHighlight) {
                    hasHighlight = true;
                }

                // TODO: implement all types
                if (msgPart is UrlMessagePartModel) {
                    InsertToBuffer(buffer, ref iter, (UrlMessagePartModel) msgPart);
                } else if (msgPart is TextMessagePartModel) {
                    InsertToBuffer(buffer, ref iter, (TextMessagePartModel) msgPart);
                } else if (msgPart is ImageMessagePartModel) {
                    InsertToBuffer(buffer, ref iter, (ImageMessagePartModel) msgPart);
                }
            }
            var startIter = buffer.GetIterAtMark(startMark);
            if (msg.MessageType == MessageType.Event) {
                buffer.ApplyTag(EventTag, startIter, iter);
            }
            if (indentTag != null) {
                buffer.ApplyTag(indentTag, startIter, iter);
            }
            var nick = msg.GetNick();
            if (nick != null) {
                // TODO: re-use the same person tag for the same nick
                var personTag = new PersonTag(nick, nick);
                personTag.TextEvent += OnPersonTagTextEvent;
                _MessageTextTagTable.Add(personTag);

                var msgStartIter = buffer.GetIterAtMark(msgStartMark);
                var nickEndIter = msgStartIter;
                nickEndIter.ForwardChars(nick.Length + 2);
                buffer.ApplyTag(PersonTag, msgStartIter, nickEndIter);
                buffer.ApplyTag(personTag, msgStartIter, nickEndIter);
            }
            buffer.DeleteMark(startMark);
            buffer.DeleteMark(msgStartMark);
            if (addLinebreak) {
                buffer.Insert(ref iter, "\n");
            }

            CheckBufferSize();

            if (IsGtk2_17) {
                // HACK: force a redraw of the widget, as for some reason
                // GTK+ 2.17.6 is not redrawing some lines we add here, especially
                // for local messages. See:
                // http://projects.qnetp.net/issues/show/185
                QueueDraw();
            }
            if (Frontend.IsWindows && _LastMessage == null) {
                // HACK: workaround rendering issue on Windows where the
                // first inserted text is not showing up until the next insert
                QueueDraw();
            }

            if (MessageAdded != null) {
                MessageAdded(this, new MessageTextViewMessageAddedEventArgs(msg));
            }

            if (hasHighlight) {
                if (MessageHighlighted != null) {
                    MessageHighlighted(this, new MessageTextViewMessageHighlightedEventArgs(msg));
                }
            }

            _LastMessage = msg;
        }
Ejemplo n.º 4
0
        public void AddMessage(MessageModel msg, bool addLinebreak, bool showTimestamps)
        {
#if MSG_DEBUG
            Trace.Call(msg, addLinebreak);
#endif

            if (msg == null)
            {
                throw new ArgumentNullException("msg");
            }

            var buffer    = Buffer;
            var iter      = buffer.EndIter;
            var startMark = new Gtk.TextMark(null, true);
            buffer.AddMark(startMark, iter);


            var         senderPrefixWidth = GetSenderPrefixWidth(msg);
            Gtk.TextTag indentTag         = null;
            if (senderPrefixWidth != 0)
            {
                // TODO: re-use text tags that have the same indent width
                indentTag = new Gtk.TextTag(null)
                {
                    Indent = -senderPrefixWidth
                };
                _MessageTextTagTable.Add(indentTag);
            }

            if (showTimestamps)
            {
                var msgTimeStamp = msg.TimeStamp.ToLocalTime();
                if (_LastMessage != null)
                {
                    var lastMsgTimeStamp = _LastMessage.TimeStamp.ToLocalTime();
                    var span             = msgTimeStamp.Date - lastMsgTimeStamp.Date;
                    if (span.Days > 0)
                    {
                        var dayLine = new MessageBuilder().
                                      AppendEventPrefix();
                        if (span.Days > 1)
                        {
                            dayLine.AppendText(_("Day changed from {0} to {1}"),
                                               lastMsgTimeStamp.ToShortDateString(),
                                               msgTimeStamp.ToShortDateString());
                        }
                        else
                        {
                            dayLine.AppendText(_("Day changed to {0}"),
                                               msgTimeStamp.ToLongDateString());
                        }
                        dayLine.AppendText("\n");
                        var dayLineMsg = dayLine.ToMessage().ToString();
                        Buffer.InsertWithTags(ref iter, dayLineMsg, EventTag);
                    }
                }

                string timestamp = null;
                try {
                    string format = (string)Frontend.UserConfig["Interface/Notebook/TimestampFormat"];
                    if (!String.IsNullOrEmpty(format))
                    {
                        timestamp = msgTimeStamp.ToString(format);
                    }
                } catch (FormatException e) {
                    timestamp = "Timestamp Format ERROR: " + e.Message;
                }

                if (timestamp != null)
                {
                    InsertTimeStamp(buffer, ref iter, timestamp, msg);

                    // apply timestamp width to indent tag
                    if (indentTag != null)
                    {
                        indentTag.Indent -= GetPangoWidth(timestamp);
                    }
                }
            }

            var msgStartMark = new Gtk.TextMark(null, true);
            buffer.AddMark(msgStartMark, iter);

            bool hasHighlight = false;
            foreach (MessagePartModel msgPart in msg.MessageParts)
            {
                // supposed to be used only in a ChatView
                if (msgPart.IsHighlight)
                {
                    hasHighlight = true;
                }

                // TODO: implement all types
                if (msgPart is UrlMessagePartModel)
                {
                    InsertToBuffer(buffer, ref iter, (UrlMessagePartModel)msgPart);
                }
                else if (msgPart is TextMessagePartModel)
                {
                    InsertToBuffer(buffer, ref iter, (TextMessagePartModel)msgPart);
                }
                else if (msgPart is ImageMessagePartModel)
                {
                    InsertToBuffer(buffer, ref iter, (ImageMessagePartModel)msgPart);
                }
            }
            var startIter = buffer.GetIterAtMark(startMark);
            if (msg.MessageType == MessageType.Event)
            {
                buffer.ApplyTag(EventTag, startIter, iter);
            }
            if (indentTag != null)
            {
                buffer.ApplyTag(indentTag, startIter, iter);
            }
            var nick = msg.GetNick();
            if (nick != null)
            {
                // TODO: re-use the same person tag for the same nick
                var personTag = new PersonTag(nick, nick);
                personTag.TextEvent += OnPersonTagTextEvent;
                _MessageTextTagTable.Add(personTag);

                var msgStartIter = buffer.GetIterAtMark(msgStartMark);
                var nickEndIter  = msgStartIter;
                nickEndIter.ForwardChars(nick.Length + 2);
                buffer.ApplyTag(PersonTag, msgStartIter, nickEndIter);
                buffer.ApplyTag(personTag, msgStartIter, nickEndIter);
            }
            buffer.DeleteMark(startMark);
            buffer.DeleteMark(msgStartMark);
            if (addLinebreak)
            {
                buffer.Insert(ref iter, "\n");
            }

            CheckBufferSize();

            if (IsGtk2_17)
            {
                // HACK: force a redraw of the widget, as for some reason
                // GTK+ 2.17.6 is not redrawing some lines we add here, especially
                // for local messages. See:
                // http://projects.qnetp.net/issues/show/185
                QueueDraw();
            }
            if (Frontend.IsWindows && _LastMessage == null)
            {
                // HACK: workaround rendering issue on Windows where the
                // first inserted text is not showing up until the next insert
                QueueDraw();
            }

            if (MessageAdded != null)
            {
                MessageAdded(this, new MessageTextViewMessageAddedEventArgs(msg));
            }

            if (hasHighlight)
            {
                if (MessageHighlighted != null)
                {
                    MessageHighlighted(this, new MessageTextViewMessageHighlightedEventArgs(msg));
                }
            }

            _LastMessage = msg;
        }