Logo Search packages:      
Sourcecode: galaxium version File versions  Download package

MsnChatWidget.cs

/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * Copyright (C) 2007 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;
using System.Web;
using System.Threading;
using System.Collections.Generic;

using Gtk;
using Glade;
using Pango;

using Anculus.Core;
using Anculus.Gui;

using Galaxium.Core;
using Galaxium.Client;
using Galaxium.Protocol;
using Galaxium.Protocol.Gui;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;

namespace Galaxium.Protocol.Msn.GtkGui
{
      public class MsnChatWidget : BasicChatWidget
      {
            // Actual GUI widgets that will be used within a MSN specific chat window.
            protected P2PViewWebcam _webcam = null;
            protected BasicContactTreeView _contactTree = null;
            
            DateTime _lastReceivedTime;
            uint _typingTimer = 0;
            
            // Common properties that we can include.
            public override bool ShowActionToolbar
            {
                  get { return (Conversation.PrimaryContact as MsnContact).ShowActionToolbar; }
                  set { (Conversation.PrimaryContact as MsnContact).ShowActionToolbar = value; if (value) _window.Toolbar.ShowAll(); else _window.Toolbar.Visible = false; }
            }
            
            public override bool ShowInputToolbar
            {
                  get { return (Conversation.PrimaryContact as MsnContact).ShowInputToolbar; }
                  set { (Conversation.PrimaryContact as MsnContact).ShowInputToolbar = value; if (value) _entryToolbar.ShowAll(); else _entryToolbar.Visible = false; }
            }
            
            public override bool ShowAccountImage
            {
                  get { return (Conversation.PrimaryContact as MsnContact).ShowAccountImage; }
                  set { (Conversation.PrimaryContact as MsnContact).ShowAccountImage = value; if (value) _leftInputBox.ShowAll(); else _leftInputBox.Visible = false; }
            }
            
            public override bool ShowContactImage
            {
                  get { return (Conversation.PrimaryContact as MsnContact).ShowContactImage; }
                  set { (Conversation.PrimaryContact as MsnContact).ShowContactImage = value; if (value) _rightInputBox.ShowAll(); else _rightInputBox.Visible = false; }
            }
            
            public override bool ShowPersonalMessage
            {
                  get { return (Conversation.PrimaryContact as MsnContact).ShowPersonalMessage; }
                  set { (Conversation.PrimaryContact as MsnContact).ShowPersonalMessage = value; if (value) _identificationSpacer.ShowAll(); else _identificationSpacer.Visible = false; }
            }
            
            public override bool ShowTimestamps
            {
                  get { return (Conversation.PrimaryContact as MsnContact).ShowTimestamps; }
                  set { (Conversation.PrimaryContact as MsnContact).ShowTimestamps = value; }
            }
            
            public override bool UseDefaultView
            {
                  get { return (Conversation.PrimaryContact as MsnContact).UseDefaultView; }
                  set { (Conversation.PrimaryContact as MsnContact).UseDefaultView = value; }
            }
            
            public override bool EnableLogging
            {
                  get
                  {
                        if (!(Conversation.PrimaryContact as MsnContact).UseDefaultSettings)
                              return Conversation.PrimaryContact.Logging;
                        else
                              return _config.GetBool (Configuration.Conversation.EnableLogging.Name, Configuration.Conversation.EnableLogging.Default);
                  }
                  
                  set
                  {
                        ReportLogging (value);
                        
                        if (!(Conversation.PrimaryContact as MsnContact).UseDefaultSettings)
                              Conversation.PrimaryContact.Logging = value;
                  }
            }
            
            public override bool EnableSounds
            {
                  get { return (Conversation.PrimaryContact as MsnContact).EnableSounds; }
                  set { (Conversation.PrimaryContact as MsnContact).EnableSounds = value; }
            }
            
            public override bool UseDefaultSettings
            {
                  get { return (Conversation.PrimaryContact as MsnContact).UseDefaultSettings; }
                  set { (Conversation.PrimaryContact as MsnContact).UseDefaultSettings = value; }
            }
            
            internal MsnChatWidget (IContainerWindow<Widget> window, IConversation conversation) : base (window, conversation)
            {
                  // Here is where we can connect all the events that need to be mapped for the chat window to work.
                  _conversation.Established += ConversationEstablishedEvent;
                  _conversation.Closed += ConversationClosedEvent;
                  _conversation.ContactJoined += ConversationContactJoinedEvent;
                  _conversation.ContactLeft += ConversationContactLeftEvent;
                  _conversation.AllContactsLeft += ConversationAllContactsLeftEvent;
                  _conversation.MessageReceived += ConversationMessageReceivedEvent;
                  (_conversation as MsnConversation).InkReceived += ConversationInkReceivedEvent;
                  (_conversation as MsnConversation).NudgeReceived += ConversationNudgeReceivedEvent;
                  (_conversation as MsnConversation).TypingReceived += ConversationContactTypingEvent;
                  (_conversation as MsnConversation).WinkReceived += ConversationWinkReceived;
                  (_conversation as MsnConversation).VoiceClipReceived += ConversationVoiceClipReceived;
                  (_conversation as MsnConversation).MessageSendFailed += ConversationMessageSendFailed;
                  (_conversation as MsnConversation).WebcamInviteReceived += ConversationWebcamInviteReceived;
                  (_conversation as MsnConversation).CapabilitiesChanged += ConversationCapabilitiesChanged;
                  (_conversation as MsnConversation).ActionMessageReceived += ConversationActionMessageReceived;
                  
                  _conversation.Session.Account.DisplayImageChange += AccountDisplayImageChange;
            }
            
            public override void Initialize ()
            { 
                  // You must call this before anything else.
                  base.Initialize ();
                  
                  ScrolledWindow treeWindow = new ScrolledWindow ();
                  treeWindow.ShadowType = ShadowType.In;
                  _contactTree = new BasicContactTreeView ();
                  
                  // Add any extra contacts into the list.
                  foreach (MsnContact contact in Conversation.ContactCollection)
                  {
                        _contactTree.AddNode (contact);
                        AddEventHandlers (contact);
                  }
                  
                  treeWindow.Add (_contactTree);
                  SetChatWidget (ChatWidgetPositions.RightDisplayPane, treeWindow);
                  
                  AdjustForContacts ();
                  
                  // Load up the conversation history logs.
                  
                  IConversationLog log = Conversation.ConversationLog;
                  int n = _logging_config.GetInt("HistorySize", 5);
                  bool loggingAllowed = _logging_config.GetBool (Configuration.Logging.EnableLogging.Name, Configuration.Logging.EnableLogging.Default);
                  bool enableLogging = UseDefaultSettings ? _config.GetBool (Configuration.Conversation.EnableLogging.Name, Configuration.Conversation.EnableLogging.Default) : EnableLogging;
                  
                  if (loggingAllowed)
                  {
                        if (enableLogging && n > 0)
                        {
                              List<ConversationLogEntry> entries = new List<ConversationLogEntry> ();
                              entries.AddRange (log.GetNLastEntries (n));
                              
                              if (entries.Count > 0)
                              {
                                    try
                                    {
                                          foreach (ConversationLogEntry entry in entries)
                                          {
                                                if (entry.IsEvent)
                                                {
                                                      _messageDisplay.AddSystemMessage (entry.Message);
                                                      continue;
                                                }
                                                
                                                MsnTextMessage message = new MsnTextMessage ((_conversation.Session as MsnSession).FindEntity (entry.UniqueIdentifier),
                                                                                             entry.TimeStamp, new MsnTextStyle (), entry.Message);
                                                
                                                _messageDisplay.AddHistoryMessage (message);
                                          }
                                    }
                                    catch (Exception ex)
                                    {
                                          Anculus.Core.Log.Error (ex, "Error displaying history");
                                    }
                              }
                        }
                  }
                  
                  _historyComplete = true;
                  
                  Update();
                  
                  _nativeWidget.Show ();
            }
            
            protected override void BecomeReady (object sender, EventArgs args)
            {
                  base.BecomeReady (sender, args);
                  //Anculus.Core.Log.Debug ("Ready: {0}", _nativeWidget.GdkWindow);
                  (_conversation as MsnConversation).ListenerReady = true;
            }
            
            public override void SwitchTo ()
            {
                  MenuUtility.FillToolBar ("/Galaxium/Gui/MSN/ContainerWindow/Toolbar", new DefaultExtensionContext (this), _window.Toolbar as Toolbar);
                  MenuUtility.FillMenuBar ("/Galaxium/Gui/MSN/ContainerWindow/Menu", new DefaultExtensionContext (this), _window.Menubar as MenuBar);
                  MenuUtility.FillToolBar ("/Galaxium/Gui/MSN/ContainerWindow/InputToolbar", new DefaultExtensionContext (this), _entryToolbar);
            }
            
            public void ReportLogging ()
            {
                  ReportLogging (EnableLogging);
            }
            
            private void ReportLogging (bool val)
            {
                  if (_messageDisplay != null)
                  {
                        if (_logging_config.GetBool (Configuration.Logging.EnableLogging.Name, Configuration.Logging.EnableLogging.Default))
                        {
                              if (val)
                                    _messageDisplay.AddSystemMessage ("You are now logging this conversation.");
                              else
                                    _messageDisplay.AddSystemMessage ("You are no longer logging this conversation.");
                        }
                        else
                              _messageDisplay.AddSystemMessage ("Logging is currently disabled in the preferences.");
                  }
            }
            
            public override void Destroy ()
            {
                  (_conversation as MsnConversation).ListenerReady = false;
                  
                  _conversation.Established -= ConversationEstablishedEvent;
                  _conversation.Closed -= ConversationClosedEvent;
                  _conversation.ContactJoined -= ConversationContactJoinedEvent;
                  _conversation.ContactLeft -= ConversationContactLeftEvent;
                  _conversation.AllContactsLeft -= ConversationAllContactsLeftEvent;
                  _conversation.MessageReceived -= ConversationMessageReceivedEvent;
                  (_conversation as MsnConversation).InkReceived -= ConversationInkReceivedEvent;
                  (_conversation as MsnConversation).NudgeReceived -= ConversationNudgeReceivedEvent;
                  (_conversation as MsnConversation).TypingReceived -= ConversationContactTypingEvent;
                  (_conversation as MsnConversation).WinkReceived -= ConversationWinkReceived;
                  (_conversation as MsnConversation).VoiceClipReceived -= ConversationVoiceClipReceived;
                  (_conversation as MsnConversation).MessageSendFailed -= ConversationMessageSendFailed;
                  (_conversation as MsnConversation).WebcamInviteReceived -= ConversationWebcamInviteReceived;
                  (_conversation as MsnConversation).CapabilitiesChanged -= ConversationCapabilitiesChanged;
                  (_conversation as MsnConversation).ActionMessageReceived -= ConversationActionMessageReceived;
            }
            
            [GLib.ConnectBefore     ()]
            protected override void KeyReleaseEvent (object sender, KeyReleaseEventArgs args)
            {
                  (_conversation as MsnConversation).Typing = _messageEntry.Text.Length > 0;
            }
            
            [GLib.ConnectBefore ()]
            protected override void KeyPressEvent (object sender, KeyPressEventArgs args)
            {
                  Gdk.Key key = args.Event.Key;
                  uint state = ((uint)args.Event.State);
                  state &= 1101u;
                  const uint Normal = 0, Shift = 1, Control = 4;//, ShiftControl = 5, Alt = 8;
                  
                  MsnContact contact = Conversation.PrimaryContact as MsnContact;
                  
                  if (contact == null)
                  {
                        Anculus.Core.Log.Error ("There is no primary contact to send messages to in this conversation!");
                        return;
                  }
                  
                  switch (state)
                  {
                        case Normal:
                              if (key == Gdk.Key.Return || key == Gdk.Key.KP_Enter)
                              {
                                    if (_messageEntry.Text.Trim().Length < 1)
                                    {
                                          args.RetVal = true;
                                          return;
                                    }
                              
                                    if (!(_conversation as MsnConversation).CanSendMessage)
                                    {
                                          _messageDisplay.AddSystemMessage ("Galaxium is unable to send a message to this contact");
                                    
                                          args.RetVal = true;
                                          return;
                                    }
                                    
                                    MsnTextStyle style = GetStyle () as MsnTextStyle;
                                    
                                    MsnTextMessage tmessage = new MsnTextMessage(_conversation.Session.Account, DateTime.Now, style, _messageEntry.Text);

                                    ProcessOutgoingMessage (tmessage);
                              
                                    _messageEntry.Clear();
                                    
                                    _messageDisplay.AddMessage(tmessage);
                                    
                                    args.RetVal = true;
                                    
                                    return;
                              }
                              break;
                        case Shift:
                              break;
                        case Control:
                              break;
                        default:
                              break;
                  }
            }
            
            private void ConversationEstablishedEvent (object sender, ConversationEventArgs args)
            {
                  
            }
            
            private void ConversationClosedEvent (object sender, ConversationEventArgs args)
            {
                  
            }
            
            void ConversationContactJoinedEvent (object sender, ContactActionEventArgs args)
            {
                  _contactTree.AddNode (args.Contact);
                  
                  AdjustForContacts ();
                  
                  if (Conversation.ContactCollection.Count > 1)
                        _messageDisplay.AddSystemMessage (MessageUtility.StripMarkup (args.Contact.DisplayIdentifier, args.Contact.Session.Account.Protocol) +
                                                          " has joined the conversation");
                  
                  if (args.Contact != Conversation.PrimaryContact)
                        AddEventHandlers (args.Contact as MsnContact);
            }
            
            void ConversationContactLeftEvent (object sender, ContactActionEventArgs args)
            {
                  foreach (uint node in _contactTree.GetNodes (args.Contact))
                        _contactTree.RemoveNode (node);
                  
                  AdjustForContacts ();
                  
                  if (Conversation.ContactCollection.Count > 1)
                        _messageDisplay.AddSystemMessage (MessageUtility.StripMarkup (args.Contact.DisplayIdentifier, args.Contact.Session.Account.Protocol) + " has left the conversation");
                  
                  if (args.Contact != Conversation.PrimaryContact)
                        RemoveEventHandlers (args.Contact as MsnContact);
            }
            
            void AddEventHandlers (MsnContact contact)
            {
                  contact.DisplayImageChange += ContactDisplayImageChanged;
                  contact.DisplayMessageChange += ContactDisplayMessageChanged;
                  contact.DisplayNameChange += ContactDisplayNameChanged;
                  contact.PresenceChange += ContactPresenceChanged;
                  contact.SupressChange += ContactSupressChanged;
            }
            
            void RemoveEventHandlers (MsnContact contact)
            {
                  contact.DisplayImageChange -= ContactDisplayImageChanged;
                  contact.DisplayMessageChange -= ContactDisplayMessageChanged;
                  contact.DisplayNameChange -= ContactDisplayNameChanged;
                  contact.PresenceChange -= ContactPresenceChanged;
                  contact.SupressChange -= ContactSupressChanged;
            }
            
            void ConversationAllContactsLeftEvent (object sender, ConversationEventArgs args)
            {
                  
            }
            
            void ConversationActionMessageReceived (object sender, ActionMessageEventArgs args)
            {
                  _messageDisplay.AddSystemMessage (args.Message);
                  
                  EmitBecomeActive ();
            }
            
            private void ConversationMessageReceivedEvent (object sender, TextMessageEventArgs args)
            {
                  //Log.Info ("MessageReceived {0}", args.Message.GetText ());
                  ProcessIncomingMessage (args.Message);
            }
            
            private void ConversationInkReceivedEvent (object sender, InkEventArgs args)
            {
                  _messageDisplay.AddImageMessage (args.Source, args.InkData);
                  
                  EmitBecomeActive ();
            }
            
            private void ConversationNudgeReceivedEvent (object sender, ContactEventArgs args)
            {
            
                  _messageDisplay.AddSystemMessage (MessageUtility.StripMarkup (args.Contact.DisplayIdentifier, args.Contact.Session.Account.Protocol) +
                                                    " is nudging you to get your attention!");
                  
                  EmitBecomeActive ();
                  
                  if (_config.GetBool("WindowShake", true))
                        _window.Shake();
                  
                  SoundSetUtility.Play(Sound.Nudge);
            }
            
            private void ConversationContactTypingEvent (object sender, ContactEventArgs args)
            {
                  _activityImage.FromAnimation = IconUtility.GetAnimation ("galaxium-typing_anim");
                  
                  if (_typingTimer != 0)
                        TimerUtility.ResetCallback (_typingTimer);
                  else
                  {
                        _typingTimer = TimerUtility.RequestCallback (delegate
                        {
                              ResetTypingNotification ();
                        }, 6000);
                  }
                  
                  _status_label.Text = MessageUtility.StripMarkup (args.Contact.DisplayIdentifier, args.Contact.Session.Account.Protocol) +" is now typing a message...";
                  EmitBecomingActive ();
            }
            
            private void ContactSupressChanged (object sender, EntityChangeEventArgs<bool> args)
            {
                  if ((Conversation.PrimaryContact as MsnContact).SupressImage)
                        _contact_image.FadeTo (PixbufUtility.GetScaledPixbuf (IconUtility.GetIcon ("galaxium-displayimage", IconSizes.Huge), 96, 96));
                  else
                  {
                        try
                        {
                              _contact_image.FadeTo (PixbufUtility.GetScaledPixbuf (new Gdk.Pixbuf(Conversation.PrimaryContact.DisplayImage.ImageBuffer), 96, 96));
                        }
                        catch
                        {
                              _contact_image.FadeTo (PixbufUtility.GetScaledPixbuf (IconUtility.GetIcon ("galaxium-displayimage", IconSizes.Huge), 96, 96));
                        }
                  }
            }
            
            private void ConversationWinkReceived (object sender, WinkEventArgs args)
            {
                  _messageDisplay.AddSystemMessage (MessageUtility.StripMarkup (args.Wink.Creator.DisplayIdentifier, args.Wink.Creator.Session.Account.Protocol) +
                                                    " has sent you the wink '" + args.Wink.Friendly +"'");
                  
                  EmitBecomeActive ();
                  
                  DisplayWink (args.Wink);
            }
            
            void ConversationVoiceClipReceived (object sender, VoiceClipEventArgs args)
            {
                  _messageDisplay.AddSystemMessage (MessageUtility.StripMarkup (args.Clip.Creator.DisplayIdentifier, args.Clip.Creator.Session.Account.Protocol) +
                                                    " has sent you a voice clip");
                  EmitBecomeActive ();
                  
                  args.Clip.Request (delegate
                  {
                        SoundUtility.Play (args.Clip.CacheFilename);
                  });
            }
            
            void ConversationWebcamInviteReceived (object sender, InviteReceivedEventArgs args)
            {
                  _webcam = args.Application as P2PViewWebcam;
                  _webcam.FrameReceived += WebcamFrameReceived;
                  _webcam.P2PSession.Closed += WebcamClosed;
                  _webcam.P2PSession.Activated += WebcamActivated;
                  
                  _messageDisplay.AddSystemMessage (MessageUtility.StripMarkup (args.Application.Remote.DisplayIdentifier, args.Application.Remote.Session.Account.Protocol) +
                                                    " has invited you to view their webcam.");
                  EmitBecomeActive ();
                  
                  //TODO: we need a gui to display/accept/decline invitations
                  /*_webcam.P2PSession.Waiting += delegate
                  {
                        _webcam.Accept ();
                  };*/
            }
            
            void WebcamFrameReceived (object sender, WebcamFrameReceivedEventArgs args)
            {
                  try
                  {
                        _contact_image.SwitchTo (new Gdk.Pixbuf (args.Data, false, 8, args.Width, args.Height, args.Width * 3, null));
                  }
                  catch (Exception)
                  {
                        Anculus.Core.Log.Warn ("Unable to display frame");
                  }
            }
            
            void WebcamActivated (object sender, EventArgs args)
            {
                  _contact_image.ShowLoading ();
                  _contact_image.SetSizeRequest (320, 240);
            }
            
            void WebcamClosed (object sender, EventArgs args)
            {
                  MsnContact contact = _webcam.Remote;
                  _webcam = null;
                  
                  _contact_image.SetSizeRequest (96, 96);
                  
                  if (_webcam == null)
                        SwitchContactImage (contact);
            }
            
            void ContactDisplayNameChanged (object sender, EntityChangeEventArgs<string> args)
            {
                  _messageDisplay.AddSystemMessage (MessageUtility.StripMarkup (args.Old, args.Entity.Session.Account.Protocol) +
                                                    " has changed their name to: " +
                                                    MessageUtility.StripMarkup (args.New, args.Entity.Session.Account.Protocol));
                  
                  foreach (uint node in _contactTree.GetNodes (args.Entity))
                        _contactTree.UpdateNode (node);
            }
            
            void ContactDisplayMessageChanged (object sender, EntityChangeEventArgs<string> args)
            {
                  //MsnContact contact = args.Entity as MsnContact;
                  
                  GeneratePersonalLabel ();
            }

            void GeneratePersonalLabel ()
            {
                  string label = string.Empty;
                  
                  label += "<span size=\"small\"><b>"+_conversation.PrimaryContact.UniqueIdentifier+"</b></span>\n";
                  
                  if (_conversation.PrimaryContact.DisplayMessage != null && _conversation.PrimaryContact.DisplayMessage != String.Empty)
                        label += "<span size=\"small\"><i>"+XmlUtility.GetEncodedString (_conversation.PrimaryContact.DisplayMessage)+"</i></span>";
                  else
                        label += "<span size=\"small\"><i>No personal message.</i></span>";
                  
                  _personalLabel.Markup = label;
                  _personalLabel.Ellipsize = EllipsizeMode.End;
                  _personalLabel.SingleLineMode = false;
            }
            
            void ContactDisplayImageChanged (object sender, EntityChangeEventArgs<IDisplayImage> args)
            {
                  MsnContact contact = args.Entity as MsnContact;
                  
                  if (contact == _conversation.PrimaryContact)
                  {
                        // If the contact has an image, but we've not yet got the data
                        // don't switch the image, this will be called again once the data
                        // is retrieved
                        if ((contact.DisplayImage != null) && (contact.DisplayImage.ImageBuffer.Length == 0))
                              return;
                        
                              if (_webcam == null)
                                    SwitchContactImage (contact);
                  }
            }
            
            void ContactPresenceChanged (object sender, EntityChangeEventArgs<IPresence> args)
            {
                  MsnContact contact = args.Entity as MsnContact;
                  
                  _messageDisplay.AddSystemMessage (MessageUtility.StripMarkup (contact.DisplayIdentifier, MsnProtocol.Instance) +
                                                    " is now " + args.New.State);
                  
                  foreach (uint node in _contactTree.GetNodes (args.Entity))
                        _contactTree.UpdateNode (node);
                  
                  _personalImage.FromPixbuf = IconUtility.GetIcon (MsnPresence.GetIconString (contact.Presence), IconSizes.Small);
            }
            
            /*private void ContactChangedEvent (object sender, ContactEventArgs args)
            {
                  MsnContact contact = args.Contact as MsnContact;
                  
            }*/
            
            private void AccountDisplayImageChange (object sender, EventArgs args)
            {
                  _own_image.FadeTo (GenerateOwnImage ());
            }
            
            private void ProcessIncomingMessage (ITextMessage message)
            {
                  if (message is MsnOfflineTextMessage)
                        _messageDisplay.AddOfflineMessage(message);
                  else
                        _messageDisplay.AddMessage (message);
                  
                  foreach (MsnEmoticon emot in (message as MsnTextMessage).CustomEmoticons)
                        emot.DataChanged += delegate { _messageDisplay.UpdateEmoticon (emot); };
                  
                  _lastReceivedTime = message.TimeStamp;
                  
                  ResetTypingNotification ();
                  
                  if (_window.CurrentWidget != this || !_window.Active)
                        _window.GenerateAlert ();
                  
                  EmitBecomeActive ();
                  
                  SoundSetUtility.Play(Sound.MessageReceived);
            }
            
            void ResetTypingNotification ()
            {
                  if (_typingTimer != 0)
                  {
                        TimerUtility.RemoveCallback (_typingTimer);
                        _typingTimer = 0;
                  }
                  
                  if (_lastReceivedTime > DateTime.MinValue)
                        _status_label.Text = string.Format ("Last message received at: {0} - {1}", _lastReceivedTime.ToShortTimeString (), _lastReceivedTime.ToShortDateString ());
                  else
                        _status_label.Text = string.Empty;
                  
                  _activityImage.FromPixbuf = IconUtility.GetIcon ("galaxium-typing_stopped");
            }
            
            private void ProcessOutgoingMessage (MsnTextMessage message)
            {
                  // This is where we spawn to send the message in question.
                  (_conversation as MsnConversation).SendMessage(message);
                  
                  SoundSetUtility.Play(Sound.MessageSent);
            }
            
            public void SendNudge ()
            {
                  (_conversation as MsnConversation).SendNudge();
                  
                        if (Conversation.ContactCollection.Count == 1)
                              _messageDisplay.AddSystemMessage ("You sent " +
                                                                MessageUtility.StripMarkup (Conversation.PrimaryContact.DisplayIdentifier, MsnProtocol.Instance) +
                                                                " a nudge to get their attention!");
                        else
                              _messageDisplay.AddSystemMessage ("You sent a nudge!");
                        
                        if (_config.GetBool("WindowShake", true))
                              _window.Shake ();
                  
                  SoundSetUtility.Play(Sound.Nudge);
            }
            
            public void SendFile ()
            {
                  FileChooserDialog dialog = new FileChooserDialog("Select File", null, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Select", ResponseType.Accept);
                  dialog.SetCurrentFolder(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
                  
                  if (dialog.Run () == (int)ResponseType.Accept)
                  {
                        SendFile(dialog.Filename);
                  }
                  
                  dialog.Destroy();
            }
            
            public override void SendFile (string filename)
            {
                  if (Conversation.PrimaryContact == null)
                  {
                        Anculus.Core.Log.Warn ("There is no primary contact in this conversation to send files to!");
                        return;
                  }
                  
                  // Check to make sure that the file exists.
                  if (File.Exists (filename))
                  {
                        MsnFileTransfer transfer = new MsnFileTransfer (Conversation.Session, Conversation.PrimaryContact, filename);
                        
                        MsnP2PUtility.Add (transfer.P2PTransfer);
                        (Conversation.Session as MsnSession).EmitTransferInvitationSent (new FileTransferEventArgs (transfer));
                  }
                  else
                  {
                        string error = "The URI of the file you dropped is invalid!\n"+filename;
                        MessageDialog errordialog = new MessageDialog (null, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, error);
                        errordialog.Run ();
                        errordialog.Destroy ();
                  }
            }
            
            internal void ShowActivityPopup (Gtk.Widget position)
            {
                  HTMLPopup popup = new HTMLPopup (position, (_conversation as MsnConversation).ActivityPageUrl);
                  popup.ShowAll ();
            }
            
            void AdjustForContacts ()
            {
                  if (_window.CurrentWidget == this)
                        _window.GenerateTitle ();
                  
                  if (_conversation.ContactCollection.Count > 1)
                  {
                        ShowBox (ChatWidgetPositions.RightDisplayPane);
                        HideBox (ChatWidgetPositions.RightInput);
                        
                        _window.Toolbar.ShowAll();
                        _entryToolbar.ShowAll();
                        
                        ShowBox (ChatWidgetPositions.LeftInput);
                        HideBox (ChatWidgetPositions.Identification);
                  }
                  else
                  {
                        HideBox (ChatWidgetPositions.RightDisplayPane);
                        ShowBox (ChatWidgetPositions.RightInput);
                        
                        if (Conversation.PrimaryContact != null)
                        {
                              MsnContact contact = Conversation.PrimaryContact as MsnContact;
                              
                              if (contact.ShowActionToolbar)
                                    _window.Toolbar.ShowAll();
                              else
                                    _window.Toolbar.Visible = false;
                              
                              if (contact.ShowInputToolbar)
                                    _entryToolbar.ShowAll();
                              else
                                    _entryToolbar.Visible = false;
                              
                              if (contact.ShowAccountImage)
                                    ShowBox (ChatWidgetPositions.LeftInput);
                              else
                                    HideBox (ChatWidgetPositions.LeftInput);
                              
                              if (contact.ShowContactImage)
                                    ShowBox (ChatWidgetPositions.RightInput);
                              else
                                    HideBox (ChatWidgetPositions.RightInput);
                              
                              if (contact.ShowPersonalMessage)
                                    ShowBox (ChatWidgetPositions.Identification);
                              else
                                    HideBox (ChatWidgetPositions.Identification);
                              
                              GeneratePersonalLabel ();
                              
                              if (_webcam == null)
                                    SwitchContactImage (contact);
                        }
                        else
                        {
                              Anculus.Core.Log.Error ("There is no primary contact for the conversation this chat widget represents!");
                        }
                  }
            }
            
            void ConversationMessageSendFailed (object sender, TextMessageEventArgs args)
            {
                  _messageDisplay.AddSystemMessage (string.Format ("The message \"{0}\" could not be sent within a reasonable amount of time!", args.Message.GetText ()));
                  EmitBecomeActive ();
            }
            
            void ConversationCapabilitiesChanged (object sender, EventArgs args)
            {
                  if (_window.CurrentWidget == this)
                  {
                        MenuUtility.FillToolBar ("/Galaxium/Gui/MSN/ContainerWindow/Toolbar", new DefaultExtensionContext (this), _window.Toolbar as Toolbar);
                        MenuUtility.FillMenuBar ("/Galaxium/Gui/MSN/ContainerWindow/Menu", new DefaultExtensionContext (this), _window.Menubar as MenuBar);
                        MenuUtility.FillToolBar ("/Galaxium/Gui/MSN/ContainerWindow/InputToolbar", new DefaultExtensionContext (this), _entryToolbar);
                  }
            }
            
#region Font Handling
            public override void LoadFont ()
            {
                  IConfigurationSection config = Configuration.MessageDisplay.Section[_conversation.Session.Account.UniqueIdentifier]["Font"];
                  
                  _messageEntry.Family = config.GetString (Configuration.MessageDisplay.Family.Name, Configuration.MessageDisplay.Family.Default);
                  _messageEntry.Size = config.GetDouble (Configuration.MessageDisplay.Size.Name, Configuration.MessageDisplay.Size.Default);
                  _messageEntry.ColorInt = config.GetInt (Configuration.MessageDisplay.Color.Name, Configuration.MessageDisplay.Color.Default);
                  _messageEntry.Bold = config.GetBool (Configuration.MessageDisplay.Bold.Name, Configuration.MessageDisplay.Bold.Default);
                  _messageEntry.Italic = config.GetBool (Configuration.MessageDisplay.Italic.Name, Configuration.MessageDisplay.Italic.Default);
                  _messageEntry.Underline = config.GetBool (Configuration.MessageDisplay.Underline.Name, Configuration.MessageDisplay.Underline.Default);
                  _messageEntry.Strikethrough = config.GetBool (Configuration.MessageDisplay.Strikethrough.Name, Configuration.MessageDisplay.Strikethrough.Default);
                  
                  MenuUtility.FillToolBar ("/Galaxium/Gui/MSN/ContainerWindow/InputToolbar", new DefaultExtensionContext (this), _entryToolbar);
            }
            
            public override void SaveFont ()
            {
                  IConfigurationSection config = Configuration.MessageDisplay.Section[_conversation.Session.Account.UniqueIdentifier]["Font"];

                  config.SetString (Configuration.MessageDisplay.Family.Name, _messageEntry.Family);
                  config.SetDouble (Configuration.MessageDisplay.Size.Name, _messageEntry.Size);
                  config.SetInt (Configuration.MessageDisplay.Color.Name, _messageEntry.ColorInt);
                  config.SetBool (Configuration.MessageDisplay.Bold.Name, _messageEntry.Bold);
                  config.SetBool (Configuration.MessageDisplay.Italic.Name, _messageEntry.Italic);
                  config.SetBool (Configuration.MessageDisplay.Underline.Name, _messageEntry.Underline);
                  config.SetBool (Configuration.MessageDisplay.Strikethrough.Name, _messageEntry.Strikethrough);
                  
                  if (_fontChangedHandlers[_conversation.Session] != null)
                        _fontChangedHandlers[_conversation.Session] (this, EventArgs.Empty);
            }
            
            private TextStyle GetStyle ()
            {
                  MsnTextStyle style = new MsnTextStyle (_messageEntry.Family, (int)_messageEntry.Size, false, MsnCharacterSet.Default, MsnPitchFamily.Default);

                  style.Bold = _messageEntry.Bold;
                  style.Italic = _messageEntry.Italic;
                  style.Underline = _messageEntry.Underline;
                  style.Strikethrough = _messageEntry.Strikethrough;
                  style.ForeColor = _messageEntry.ColorInt;
                  
                  return style;
            }
#endregion
            
            protected override void OwnImageButtonPressEvent (object sender, ButtonPressEventArgs args)
            {
                  if (args.Event.Type == Gdk.EventType.TwoButtonPress)
                        new SetDisplayImageCommand().Run ();
            }
            
            internal void DisplayWink (MsnWink wink)
            {
                  if (!GtkUtility.EnableSwf)
                  {
                        _messageDisplay.AddSystemMessage ("Install swfdec 0.6 to enable wink playback");
                        return;
                  }
                  
                  wink.Request (delegate
                  {
                        // We now have the wink data
                        
                        //Log.Debug ("Ready to play wink {0}", args.Wink.Animation);
                        
                        //TODO: Queue display until window becomes active
                        try
                        {
                              new WinkDisplay (wink, GetBox (ChatWidgetPositions.LeftDisplayPane)).Show ();
                        }
                        catch (Exception ex)
                        {
                              Anculus.Core.Log.Error (ex, "Error displaying wink");
                        }
                  });
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index