Exemple #1
0
 void InitTagTable()
 {
     table = new Gtk.TextTagTable();
     table.Add(new Gtk.TextTag("bold")
     {
         Weight = Pango.Weight.Bold
     });
     table.Add(new Gtk.TextTag("italic")
     {
         Style = Pango.Style.Italic
     });
     table.Add(new Gtk.TextTag("tt")
     {
         Family = "Monospace"
     });
     table.Add(new Gtk.TextTag("li")
     {
         LeftMargin = 14
     });
     table.Add(new Gtk.TextTag("h1")
     {
         Weight = Pango.Weight.Bold,
         Scale  = Pango.Scale.XXLarge
     });
     table.Add(new Gtk.TextTag("h2")
     {
         Weight = Pango.Weight.Bold,
         Scale  = Pango.Scale.XLarge
     });
     table.Add(new Gtk.TextTag("h3")
     {
         Weight = Pango.Weight.Bold,
         Scale  = Pango.Scale.Large
     });
     table.Add(new Gtk.TextTag("h4")
     {
         Scale = Pango.Scale.Large
     });
     table.Add(new Gtk.TextTag("pre")
     {
         Family   = "Monospace",
         Indent   = 14,
         WrapMode = Gtk.WrapMode.None
     });
     table.Add(new Gtk.TextTag("p")
     {
         SizePoints = Math.Max(LineSpacing, ParagraphSpacing),
     });
 }
Exemple #2
0
        void AddEmoji(Gtk.TextBuffer buffer, ref Gtk.TextIter iter,
                      ImageMessagePartModel imgPart, string shortName,
                      Gtk.TextMark emojiMark, string imagePath)
        {
            int width, height;
            int descent;

            using (var layout = CreatePangoLayout(null)) {
                layout.GetPixelSize(out width, out height);
                descent = layout.Context.GetMetrics(layout.FontDescription, null).Descent;
            }

            Gdk.Pixbuf emojiPixBuf;
            try {
                emojiPixBuf = new Gdk.Pixbuf(imagePath, -1, height);
            } catch (Exception ex) {
#if LOG4NET
                _Logger.ErrorFormat(
                    "AddEmoji(): error loading " +
                    "image file: '{0}' " +
                    "emoji: '{1}' into Gdk.Pixbuf(), " +
                    "Exception: {2}",
                    imagePath, shortName, ex
                    );
#endif

                // delete the broken image file, maybe after the
                // next download this will be a valid image
                File.Delete(imagePath);

                // show alternative text as fallback instead
                buffer.DeleteMark(emojiMark);
                AddAlternativeText(buffer, ref iter, imgPart);
                return;
            }

            buffer.InsertPixbuf(ref iter, emojiPixBuf);
            var beforeIter = buffer.GetIterAtMark(emojiMark);
            var emojiTag   = new EmojiTag(emojiMark, imagePath)
            {
                Rise = -descent
            };
            _MessageTextTagTable.Add(emojiTag);
            buffer.ApplyTag(emojiTag, beforeIter, iter);
        }
Exemple #3
0
        static API_Contract()
        {
            // Tags
            boldTag = new Gtk.TextTag("bold")
            {
                Weight = Pango.Weight.Bold
            };
            italicTag = new Gtk.TextTag("italic")
            {
                Style = Pango.Style.Italic
            };

            // GC seems to kill @tagTable, is it's not static
            TagTable.Add(API_Contract.boldTag);
            TagTable.Add(API_Contract.italicTag);

            // Colors
            invalidColor.Red  = invalidColor.Alpha = 1;
            invalidColor.Blue = invalidColor.Green = 0;
            validColor.Blue   = validColor.Green = validColor.Red = validColor.Alpha = 1;
        }
Exemple #4
0
        /*
         * Helper methods
         */
        private Gtk.TextTagTable BuildTagTable()
        {
            // TextTags
            Gtk.TextTagTable      ttt = new Gtk.TextTagTable();
            Gtk.TextTag           tt;
            Pango.FontDescription fd;

            tt          = new Gtk.TextTag("bold");
            fd          = new Pango.FontDescription();
            fd.Weight   = Pango.Weight.Bold;
            tt.FontDesc = fd;
            ttt.Add(tt);

            tt          = new Gtk.TextTag("italic");
            fd          = new Pango.FontDescription();
            fd.Style    = Pango.Style.Italic;
            tt.FontDesc = fd;
            ttt.Add(tt);

            tt           = new Gtk.TextTag("underline");
            tt.Underline = Pango.Underline.Single;
            ttt.Add(tt);

            tt            = new Gtk.TextTag("link");
            tt.Underline  = Pango.Underline.Single;
            tt.Foreground = "darkblue";
            fd            = new Pango.FontDescription();
            tt.FontDesc   = fd;
            ttt.Add(tt);

            tt            = new Gtk.TextTag("event");
            tt.Foreground = "darkgray";
            ttt.Add(tt);

            return(ttt);
        }
Exemple #5
0
        /*
         * Helper methods
         */
        private Gtk.TextTagTable BuildTagTable()
        {
            // TextTags
            Gtk.TextTagTable      ttt = new Gtk.TextTagTable();
            Gtk.TextTag           tt;
            Pango.FontDescription fd;

            // WARNING: the insertion order of tags MATTERS!
            // The attributes of the text tags are applied in the order of
            // insertion to the text table, and not in which order the tags
            // applied in the buffer. This is sick IMHO.
            tt          = new Gtk.TextTag("bold");
            fd          = new Pango.FontDescription();
            fd.Weight   = Pango.Weight.Bold;
            tt.FontDesc = fd;
            BoldTag     = tt;
            ttt.Add(tt);

            tt          = new Gtk.TextTag("italic");
            fd          = new Pango.FontDescription();
            fd.Style    = Pango.Style.Italic;
            tt.FontDesc = fd;
            ItalicTag   = tt;
            ttt.Add(tt);

            tt           = new Gtk.TextTag("underline");
            tt.Underline = Pango.Underline.Single;
            UnderlineTag = tt;
            ttt.Add(tt);

            tt            = new Gtk.TextTag("event");
            tt.Foreground = "darkgray";
            EventTag      = tt;
            ttt.Add(tt);

            tt            = new Gtk.TextTag("link");
            tt.Underline  = Pango.Underline.Single;
            tt.Foreground = "darkblue";
            LinkTag       = tt;
            ttt.Add(tt);

            tt        = new Gtk.TextTag("person");
            PersonTag = tt;
            ttt.Add(tt);

            return(ttt);
        }
Exemple #6
0
		void InitTagTable ()
		{
			table = new Gtk.TextTagTable ();
			table.Add (new Gtk.TextTag ("bold") {
				Weight = Pango.Weight.Bold
			});
			table.Add (new Gtk.TextTag ("italic") {
				Style = Pango.Style.Italic
			});
			table.Add (new Gtk.TextTag ("tt") {
				Family = "Monospace"
			});
			table.Add (new Gtk.TextTag ("li") {
				LeftMargin = 14
			});
			table.Add (new Gtk.TextTag ("h1") {
				Weight = Pango.Weight.Bold,
				Scale = Pango.Scale.XXLarge
			});
			table.Add (new Gtk.TextTag ("h2") {
				Weight = Pango.Weight.Bold,
				Scale = Pango.Scale.XLarge
			});
			table.Add (new Gtk.TextTag ("h3") {
				Weight = Pango.Weight.Bold,
				Scale = Pango.Scale.Large
			});
			table.Add (new Gtk.TextTag ("h4") {
				Scale = Pango.Scale.Large
			});
			table.Add (new Gtk.TextTag ("pre") {
				Family = "Monospace",
				Indent = 14,
				WrapMode = Gtk.WrapMode.None
			});
		}
Exemple #7
0
        /*
         * Helper methods
         */
        private Gtk.TextTagTable BuildTagTable()
        {
            // TextTags
            Gtk.TextTagTable ttt = new Gtk.TextTagTable();
            Gtk.TextTag tt;
            Pango.FontDescription fd;

            // WARNING: the insertion order of tags MATTERS!
            // The attributes of the text tags are applied in the order of
            // insertion to the text table, and not in which order the tags
            // applied in the buffer. This is sick IMHO.
            tt = new Gtk.TextTag("bold");
            fd = new Pango.FontDescription();
            fd.Weight = Pango.Weight.Bold;
            tt.FontDesc = fd;
            BoldTag = tt;
            ttt.Add(tt);

            tt = new Gtk.TextTag("italic");
            fd = new Pango.FontDescription();
            fd.Style = Pango.Style.Italic;
            tt.FontDesc = fd;
            ItalicTag = tt;
            ttt.Add(tt);

            tt = new Gtk.TextTag("underline");
            tt.Underline = Pango.Underline.Single;
            UnderlineTag = tt;
            ttt.Add(tt);

            tt = new Gtk.TextTag("event");
            tt.Foreground = "darkgray";
            EventTag = tt;
            ttt.Add(tt);

            tt = new Gtk.TextTag("link");
            tt.Underline = Pango.Underline.Single;
            tt.Foreground = "darkblue";
            LinkTag = tt;
            ttt.Add(tt);

            tt = new Gtk.TextTag("person");
            PersonTag = tt;
            ttt.Add(tt);

            return ttt;
        }
Exemple #8
0
        public void AddMessage(MessageModel msg, bool addLinebreak)
        {
            Trace.Call(msg, addLinebreak);

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

            var buffer = Buffer;
            var iter   = buffer.EndIter;

            Gdk.Color bgColor = DefaultAttributes.Appearance.BgColor;
            if (_ThemeSettings.BackgroundColor != null)
            {
                bgColor = _ThemeSettings.BackgroundColor.Value;
            }
            TextColor bgTextColor = ColorConverter.GetTextColor(bgColor);

            if (_ShowTimestamps)
            {
                var msgTimeStamp = msg.TimeStamp.ToLocalTime();
                if (_LastMessage != null)
                {
                    var    lastMsgTimeStamp = _LastMessage.TimeStamp.ToLocalTime();
                    var    span             = msgTimeStamp.Date - lastMsgTimeStamp.Date;
                    string dayLine          = null;
                    if (span.Days > 1)
                    {
                        dayLine = String.Format(
                            "-!- " + _("Day changed from {0} to {1}"),
                            lastMsgTimeStamp.ToShortDateString(),
                            msgTimeStamp.ToShortDateString()
                            );
                    }
                    else if (span.Days > 0)
                    {
                        dayLine = String.Format(
                            "-!- " + _("Day changed to {0}"),
                            msgTimeStamp.ToLongDateString()
                            );
                    }

                    if (dayLine != null)
                    {
                        buffer.Insert(ref iter, dayLine + "\n");
                    }
                }

                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);
                    if (msg.MessageType == MessageType.Event)
                    {
                        // get best contrast for the event font color
                        Gtk.TextTag eventTag       = _MessageTextTagTable.Lookup("event");
                        Gdk.Color   eventColor     = eventTag.ForegroundGdk;
                        TextColor   eventTextColor = TextColorTools.GetBestTextColor(
                            ColorConverter.GetTextColor(eventColor),
                            bgTextColor,
                            TextColorContrast.High
                            );
                        eventTag.ForegroundGdk = ColorConverter.GetGdkColor(
                            eventTextColor
                            );
                        buffer.InsertWithTagsByName(ref iter, timestamp, "event");
                    }
                    else
                    {
                        buffer.Insert(ref iter, timestamp);
                    }
                }
            }

            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;
                    // HACK: the engine should set a color for us!
                    var linkStyleTag = _MessageTextTagTable.Lookup("link");
                    var linkColor    = ColorConverter.GetTextColor(
                        linkStyleTag.ForegroundGdk
                        );
                    linkColor = TextColorTools.GetBestTextColor(
                        linkColor, bgTextColor
                        );
                    var linkText = urlPart.Text ?? urlPart.Url;

                    var url = urlPart.Url;
                    // HACK: assume http if no protocol/scheme was specified
                    if (urlPart.Protocol == UrlProtocol.None ||
                        !Regex.IsMatch(url, @"^[a-zA-Z0-9\-]+:"))
                    {
                        url = String.Format("http://{0}", 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 linkTag = new LinkTag(uri);
                    linkTag.ForegroundGdk = ColorConverter.GetGdkColor(linkColor);
                    linkTag.TextEvent    += OnLinkTagTextEvent;
                    _MessageTextTagTable.Add(linkTag);
                    buffer.InsertWithTags(ref iter, linkText, linkStyleTag, linkTag);
                }
                else if (msgPart is TextMessagePartModel)
                {
                    TextMessagePartModel fmsgti = (TextMessagePartModel)msgPart;
                    List <string>        tags   = new List <string>();
                    if (fmsgti.ForegroundColor != TextColor.None)
                    {
                        var bg = bgTextColor;
                        if (fmsgti.BackgroundColor != TextColor.None)
                        {
                            bg = fmsgti.BackgroundColor;
                        }
                        TextColor color = TextColorTools.GetBestTextColor(
                            fmsgti.ForegroundColor, bg
                            );
                        //Console.WriteLine("GetBestTextColor({0}, {1}): {2}",  fmsgti.ForegroundColor, bgTextColor, color);
                        string tagname = GetTextTagName(color, null);
                        //string tagname = _GetTextTagName(fmsgti.ForegroundColor, null);
                        tags.Add(tagname);
                    }
                    if (fmsgti.BackgroundColor != TextColor.None)
                    {
                        // TODO: get this from ChatView
                        string tagname = GetTextTagName(null, fmsgti.BackgroundColor);
                        tags.Add(tagname);
                    }
                    if (fmsgti.Underline)
                    {
#if LOG4NET
                        _Logger.Debug("AddMessage(): fmsgti.Underline is true");
#endif
                        tags.Add("underline");
                    }
                    if (fmsgti.Bold)
                    {
#if LOG4NET
                        _Logger.Debug("AddMessage(): fmsgti.Bold is true");
#endif
                        tags.Add("bold");
                    }
                    if (fmsgti.Italic)
                    {
#if LOG4NET
                        _Logger.Debug("AddMessage(): fmsgti.Italic is true");
#endif
                        tags.Add("italic");
                    }
                    if (msg.MessageType == MessageType.Event &&
                        fmsgti.ForegroundColor == TextColor.None)
                    {
                        // only mark parts that don't have a color set
                        tags.Add("event");
                    }

                    if (tags.Count > 0)
                    {
                        buffer.InsertWithTagsByName(ref iter, fmsgti.Text, tags.ToArray());
                    }
                    else
                    {
                        buffer.Insert(ref iter, fmsgti.Text);
                    }
                }
            }
            if (addLinebreak)
            {
                buffer.Insert(ref iter, "\n");
            }

            CheckBufferSize();

            // 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 (MessageAdded != null)
            {
                MessageAdded(this, new MessageTextViewMessageAddedEventArgs(msg));
            }

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

            _LastMessage = msg;
        }
Exemple #9
0
        /*
         * Helper methods
         */
        private Gtk.TextTagTable BuildTagTable()
        {
            // TextTags
            Gtk.TextTagTable ttt = new Gtk.TextTagTable();
            Gtk.TextTag tt;
            Pango.FontDescription fd;

            tt = new Gtk.TextTag("bold");
            fd = new Pango.FontDescription();
            fd.Weight = Pango.Weight.Bold;
            tt.FontDesc = fd;
            ttt.Add(tt);

            tt = new Gtk.TextTag("italic");
            fd = new Pango.FontDescription();
            fd.Style = Pango.Style.Italic;
            tt.FontDesc = fd;
            ttt.Add(tt);

            tt = new Gtk.TextTag("underline");
            tt.Underline = Pango.Underline.Single;
            ttt.Add(tt);

            tt = new Gtk.TextTag("url");
            tt.Underline = Pango.Underline.Single;
            tt.Foreground = "darkblue";
            tt.TextEvent += OnTextTagUrlTextEvent;
            fd = new Pango.FontDescription();
            tt.FontDesc = fd;
            ttt.Add(tt);

            tt = new Gtk.TextTag("event");
            tt.Foreground = "darkgray";
            ttt.Add(tt);

            return ttt;
        }
Exemple #10
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;
        }
Exemple #11
0
        void AddEmoji(Gtk.TextBuffer buffer, ref Gtk.TextIter iter, ImageMessagePartModel imgPart, string shortName)
        {
            var unicode = Emojione.ShortnameToUnicode(shortName);

            if (unicode == null)
            {
                AddAlternativeText(buffer, ref iter, imgPart);
                return;
            }

            int width, height;
            int descent;

            using (var layout = CreatePangoLayout(null)) {
                layout.GetPixelSize(out width, out height);
                descent = layout.Context.GetMetrics(layout.FontDescription, null).Descent;
            }

            // A mark here serves two pusposes. One is to allow us to apply the
            // tag across the pixbuf. It also lets us know later where to put
            // the pixbuf if we need to load it from the network
            var mark = new Gtk.TextMark(null, true);

            buffer.AddMark(mark, iter);

            var    emojiName = unicode + ".png";
            string emojiPath;

            if (EmojiCache.TryGetIcon("emojione", emojiName, out emojiPath))
            {
                var emojiFile = new FileInfo(emojiPath);
                if (emojiFile.Exists && emojiFile.Length > 0)
                {
                    var pix = new Gdk.Pixbuf(emojiPath, -1, height);
                    buffer.InsertPixbuf(ref iter, pix);
                    var beforeIter = buffer.GetIterAtMark(mark);
                    var imgTag     = new EmojiTag(mark, emojiFile.FullName);
                    imgTag.Rise = -descent;
                    _MessageTextTagTable.Add(imgTag);
                    buffer.ApplyTag(imgTag, beforeIter, iter);
                }
                else
                {
                    AddAlternativeText(buffer, ref iter, imgPart);
                }

                return;
            }

            var emojiUrl = Emojione.UnicodeToUrl(unicode);

            EmojiCache.BeginDownloadFile("emojione", emojiName, emojiUrl,
                                         (path) => {
                GLib.Idle.Add(delegate {
                    var afterIter = buffer.GetIterAtMark(mark);
                    buffer.InsertPixbuf(ref afterIter, new Gdk.Pixbuf(path, -1, height));
                    var beforeIter = buffer.GetIterAtMark(mark);
                    var emojiTag   = new EmojiTag(mark, path);
                    _MessageTextTagTable.Add(emojiTag);
                    emojiTag.Rise = -descent;
                    buffer.ApplyTag(emojiTag, beforeIter, afterIter);
                    return(false);
                });
            },
                                         (ex) => {
                GLib.Idle.Add(delegate {
                    var markIter = buffer.GetIterAtMark(mark);
                    buffer.DeleteMark(mark);
                    AddAlternativeText(buffer, ref markIter, imgPart);
                    return(false);
                });
            }
                                         );
        }
Exemple #12
0
        public ChatView(ChatModel chat)
        {
            Trace.Call(chat);

            _ChatModel = chat;
            _Name = _ChatModel.Name;
            Name = _Name;

            // TextTags
            Gtk.TextTagTable ttt = new Gtk.TextTagTable();
            _OutputTextTagTable = ttt;
            Gtk.TextTag tt;
            Pango.FontDescription fd;

            tt = new Gtk.TextTag("bold");
            fd = new Pango.FontDescription();
            fd.Weight = Pango.Weight.Bold;
            tt.FontDesc = fd;
            ttt.Add(tt);

            tt = new Gtk.TextTag("italic");
            fd = new Pango.FontDescription();
            fd.Style = Pango.Style.Italic;
            tt.FontDesc = fd;
            ttt.Add(tt);

            tt = new Gtk.TextTag("underline");
            tt.Underline = Pango.Underline.Single;
            ttt.Add(tt);

            tt = new Gtk.TextTag("url");
            tt.Underline = Pango.Underline.Single;
            tt.Foreground = "darkblue";
            tt.TextEvent += new Gtk.TextEventHandler(_OnTextTagUrlTextEvent);
            fd = new Pango.FontDescription();
            tt.FontDesc = fd;
            ttt.Add(tt);

            Gtk.TextView tv = new Gtk.TextView();
            tv.Buffer = new Gtk.TextBuffer(ttt);
            _EndMark = tv.Buffer.CreateMark("end", tv.Buffer.EndIter, false);
            tv.Editable = false;
            //tv.CursorVisible = false;
            tv.CursorVisible = true;
            tv.WrapMode = Gtk.WrapMode.Char;
            tv.Buffer.Changed += new EventHandler(_OnTextBufferChanged);
            tv.MotionNotifyEvent += new Gtk.MotionNotifyEventHandler(_OnMotionNotifyEvent);
            _OutputTextView = tv;

            Gtk.ScrolledWindow sw = new Gtk.ScrolledWindow();
            //sw.HscrollbarPolicy = Gtk.PolicyType.Never;
            sw.HscrollbarPolicy = Gtk.PolicyType.Automatic;
            sw.VscrollbarPolicy = Gtk.PolicyType.Always;
            sw.ShadowType = Gtk.ShadowType.In;
            sw.Add(_OutputTextView);
            _OutputScrolledWindow = sw;

            // popup menu
            _TabMenu = new Gtk.Menu();

            Gtk.ImageMenuItem close_item = new Gtk.ImageMenuItem(Gtk.Stock.Close, null);
            close_item.Activated += new EventHandler(OnTabMenuCloseActivated);
            _TabMenu.Append(close_item);

            //FocusChild = _OutputTextView;
            //CanFocus = false;

            _TabLabel = new Gtk.Label();
            _TabLabel.Text = _Name;

            _TabHBox = new Gtk.HBox();
            _TabHBox.PackEnd(new Gtk.Fixed(), true, true, 0);
            _TabHBox.PackEnd(_TabLabel, false, false, 0);
            _TabHBox.ShowAll();

            _TabEventBox = new Gtk.EventBox();
            _TabEventBox.VisibleWindow = false;
            _TabEventBox.ButtonPressEvent += new Gtk.ButtonPressEventHandler(OnTabButtonPress);
            _TabEventBox.Add(_TabHBox);
            _TabEventBox.ShowAll();
        }