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

ContainerWindow.cs

/*
 * Galaxium Messenger
 * Copyright (C) 2003-2007 Philippe Durand <draekz@gmail.com>
 * Copyright (C) 2007 Ben Motmans <ben.motmans@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.Collections.Generic;
using System.Collections;

using Gtk;
using Glade;
using GLib;

using Anculus.Core;
using Anculus.Gui;

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

namespace Galaxium.Client.GtkGui
{
      public sealed class ContainerWindow : IContainerWindow<Widget>
      {
            public event EventHandler WindowClosed;
            
            [Widget ("ContainerWindow")]
            private Window _window;
            [Widget ("panels")]
            private Notebook _notebook;
            [Widget ("menubar")]
            private MenuBar _menubar;
            [Widget ("toolbar")]
            private Toolbar _toolbar;
            
            private string _uid;
            private int _shake_count = 20;
            private int _shake_step = 0;
            private int _shake_x, _shake_y;
            private int[,] _shake_coords = new int [4,2] {{ -4, -4 }, { +4, +4 }, { +4, -4 }, { -4, +4 }};
            
            private System.Timers.Timer _shake_timer = new System.Timers.Timer (25);
            
            private IConfigurationSection _config = Configuration.Conversation.Section;
            private IList<IChatWidget<Widget>> _widgets;
            private IChatWidget<Widget> _currentWidget;
            private AccelGroup _accelGroup;
            private int _windowX = 0, _windowY = 0, _windowW = 0, _windowH = 0;
            
            public ContainerWindow (string uid)
            {
                  if (uid == null)
                        throw new ArgumentNullException ("uid");
                  
                  _uid = uid;
                  _widgets = new List<IChatWidget<Widget>> ();
                  
                  lock (_shake_timer)
                  {
                        _shake_timer.AutoReset = true;
                        _shake_timer.Elapsed += ShakeTimerElapsed;
                  }
                  
                  _windowX = _config.GetInt ("CX", 0);
                  _windowY = _config.GetInt ("CY", 0);
                  _windowW = _config.GetInt ("CW", 0);
                  _windowH = _config.GetInt ("CH", 0);
                  
                  // This is a tabbed window for all conversations.
                  Initialize();
                  
                  _notebook.SwitchPage += new SwitchPageHandler(PageSwitchedEvent);
            }
            
            public bool Active
            {
                  get { return _window.IsActive; }
            }
            
            public string UniqueIdentifier
            {
                  get { return _uid; }
            }
            
            public Widget Toolbar
            {
                  get { return _toolbar; }
            }
            
            public Widget Menubar
            {
                  get { return _menubar; }
            }
            
            public IChatWidget<Widget> CurrentWidget
            {
                  get { return _currentWidget; }
            }
            
            public IEnumerable<IChatWidget<Widget>> Widgets
            {
                  get { return _widgets; }
            }
            
            public int ConversationCount
            {
                  get { return _widgets.Count; }
            }
            
            public IEnumerable<IConversation> Conversations
            {
                  get
                  {
                        foreach (IChatWidget<Widget> widget in _widgets)
                              yield return widget.Conversation;
                  }
            }
            
            private void SaveWindowLocation ()
            {
                  int x, y, w, h;
                  
                  if (_window.GdkWindow.State == Gdk.WindowState.Maximized ||
                        _window.GdkWindow.State == Gdk.WindowState.Iconified)
                        return;
                  
                  _window.GetSize (out w, out h);
                  _window.GetPosition (out x, out y);
                  
                  _config.SetInt ("CX", x);
                  _config.SetInt ("CY", y);
                  _config.SetInt ("CW", w);
                  _config.SetInt ("CH", h);
            }
            
            public void AddConversation (IConversation conversation)
            {
                  if (conversation == null)
                        throw new ArgumentNullException ("conversation");
                  
                  IChatWidget<Widget> widget = ProtocolGuiUtility.CreateChatWidget<Widget> (conversation.Session.Account.Protocol, this, conversation);
                  _widgets.Add (widget);
                  
                  try
                  {
                        widget.Initialize ();
                  }
                  catch (Exception ex)
                  {
                        Anculus.Core.Log.Error (ex, "Error initializing chat widget");
                        return;
                  }
                  
                  IContact contact = conversation.PrimaryContact;
                  NotebookLabel label = null;
                  
                  if (contact != null)
                        label = new NotebookLabel (widget, "", Markup.EscapeText(contact.DisplayIdentifier), "");
                  else
                        label = new NotebookLabel (widget, "", Markup.EscapeText(conversation.PrimaryContact.UniqueIdentifier), "");
                  
                  label.TabClosed += TabClosedEvent;
                  
                  _notebook.AppendPage (widget.NativeWidget, label);
                  _notebook.SetTabLabelPacking (widget.NativeWidget, true, true, PackType.End);
                  //_notebook.CurrentPage = _notebook.NPages - 1;
                  _notebook.FocusInEvent += delegate {
                        _currentWidget.Focus ();
                  };
                  
                  ToggleTabVisibility ();
            }
            
            public void AddWidget (IChatWidget<Widget> widget)
            {
                  _widgets.Add (widget);
                  
                  IContact contact = widget.Conversation.PrimaryContact;
                  NotebookLabel label = null;
                  
                  if (contact != null)
                        label = new NotebookLabel (widget, "", Markup.EscapeText(contact.DisplayIdentifier), "");
                  else
                        label = new NotebookLabel (widget, "", Markup.EscapeText(widget.Conversation.PrimaryContact.UniqueIdentifier), "");
                  
                  label.TabClosed += TabClosedEvent;
                  
                  _notebook.AppendPage (widget.NativeWidget, label);
                  _notebook.SetTabLabelPacking (widget.NativeWidget, true, true, PackType.End);
                  //_notebook.CurrentPage = _notebook.NPages - 1;
                  
                  ToggleTabVisibility ();
            }
            
            public void ShowConversation (IConversation conversation)
            {
                  if (conversation == null)
                        throw new ArgumentNullException ("conversation");
                  
                  int index = GetConversationIndex (conversation);
                  if (index < 0)
                        return;
                  
                  _notebook.CurrentPage = index;
            }
            
            public void RemoveConversation (IConversation conversation, bool closeWindow)
            {
                  if (conversation == null)
                        throw new ArgumentNullException ("conversation");
                  
                  int index = GetConversationIndex (conversation);
                  if (index < 0)
                        return;
                  
                  IChatWidget<Widget> widget = _widgets[index];
                  
                  _notebook.RemovePage (index);
                  _widgets.RemoveAt (index);
                  
                  widget.Destroy();
                  
                  ToggleTabVisibility ();
                  
                  if (_widgets.Count == 0 && closeWindow)
                        Close ();
            }
            
            public void RemoveConversations (ISession session, bool closeWindow)
            {
                  if (session == null)
                        throw new ArgumentNullException ("session");
                  
                  List<IConversation> tmp = new List<IConversation> ();
                  foreach (IConversation conversation in Conversations)
                        if (conversation.Session == session)
                              tmp.Add (conversation);
                  
                  foreach (IConversation conversation in tmp)
                        RemoveConversation (conversation, closeWindow);
                  
                  ToggleTabVisibility ();
            }
            
            public bool ContainsConversation (IConversation conversation)
            {
                  if (conversation == null)
                        throw new ArgumentNullException ("conversation");
                  
                  foreach (IChatWidget<Widget> widget in _widgets)
                        if (widget.Conversation.UniqueIdentifier == conversation.UniqueIdentifier)
                              return true;
                  
                  return false;
            }
            
            public void Shake ()
            {
                  _window.GetPosition(out _shake_x, out _shake_y);
                  
                  _shake_count = 20;
                  
                  lock (_shake_timer)
                  {
                        if (!_shake_timer.Enabled)
                              _shake_timer.Start ();
                  }
            }
            
            private void ShakeTimerElapsed (object sender, System.Timers.ElapsedEventArgs args)
            {
                  Random rnd = new Random();
                  int change_x = _shake_coords[_shake_step, 0];
                  int change_y = _shake_coords[_shake_step, 1];
                  
                  ThreadUtility.SyncDispatch (new VoidDelegate (delegate
                  {
                        _window.Move(_shake_x + change_x, _shake_y + change_y);
                  }));
                  
                  _shake_step++;
                  _shake_count--;
                  
                  if (_shake_step >= 3)
                        _shake_step = 0;
                  
                  if (_shake_count < 1)
                  {
                        ThreadUtility.SyncDispatch (new VoidDelegate (delegate
                        {
                              _window.Move(_shake_x, _shake_y);
                        }));
                        
                        lock (_shake_timer)
                              _shake_timer.Stop();
                        
                        _shake_count = 20;
                  }
            }
            
            public void Update ()
            {
                  // Go through all the chat widgets and call update.
                  foreach (IChatWidget<Widget> widget in _widgets)
                  {
                        widget.Update ();
                  }
            }
            
            public void Show (bool minimized)
            {
                  bool isVisible = _window.Visible;
                  
                  if (!_window.Visible && minimized)
                        _window.Iconify();
                  else
                        isVisible = true;
                  
                  _window.Present ();
                  
                  // This is weird behavior, i'm not sure why it wont stay iconified when i select it the first time.
                  if (!isVisible && minimized)
                        _window.Iconify();
            }
            
            public void Close ()
            {
                  List<IConversation> tmp = new List<IConversation> ();
                  tmp.AddRange (Conversations);
                  
                  foreach (IConversation conversation in tmp)
                  {
                        conversation.Close ();
                        RemoveConversation (conversation, false);
                  }
                  
                  SaveWindowLocation ();
                  
                  if (WindowClosed != null)
                        WindowClosed (this, new EventArgs());
            }
            
            public void Destroy ()
            {
                  _window.Hide();
                  _window.Destroy();
            }
            
            public void GenerateTitle ()
            {
                  string title = "Error";
                  IConversation conversation = _currentWidget.Conversation;
                  
                  if (conversation != null)
                  {
                        if (conversation.ContactCollection.Count > 1)
                              title = "Group Chat";
                        else
                        {
                              IContact contact = conversation.PrimaryContact;
                              
                              if (contact != null)
                                    title = MessageUtility.StripMarkup (contact.DisplayIdentifier, contact.Session.Account.Protocol);
                        }
                  }
                  
                  _window.Title = title;
            }
            
            public void GenerateAlert ()
            {
                  if (!_window.HasFocus)
                        _window.UrgencyHint = true;
            }
            
            private void Initialize ()
            {
                  XML gxml = new XML (GladeUtility.GetGladeResourceStream (typeof (ContainerWindow).Assembly, "ContainerWindow.glade"), null, null);
                  gxml.Autoconnect (this);
                  
                  _window.Icon = IconUtility.GetIcon ("galaxium-conversation", IconSizes.Large);
                  _window.FocusInEvent += FocusInEvent;
                  _window.FocusChildSet += FocusChildSet;
                  
                  _toolbar.ToolbarStyle = ToolbarStyle.BothHoriz;
                  
                  ToggleTabVisibility ();
                  
                  _window.Move (_windowX, _windowY);
                  
                  // Only resize if the values are non-zero
                  // Otherwise, we'll stick with Gtks chosen size
                  
                  if ((_windowW * _windowH) > 0)
                        _window.Resize (_windowW, _windowH);
            }
            
            private IChatWidget<Widget> GetConversationWidget (IConversation conversation)
            {
                  foreach (IChatWidget<Widget> widget in _widgets)
                        if (widget.Conversation == conversation)
                              return widget;
                  
                  return null;
            }
            
            private int GetConversationIndex (IConversation conversation)
            {
                  for (int i=0; i<_widgets.Count; i++)
                        if (_widgets[i].Conversation == conversation)
                              return i;
                  
                  return -1;
            }
            
            private void FocusChildSet (object sender, EventArgs args)
            {
                  _window.UrgencyHint = false;
                  
                  NotebookLabel label = _notebook.GetTabLabel(_currentWidget.NativeWidget) as NotebookLabel;
                  
                  if (label != null)
                        label.QuietActivity ();
                  
                  //_currentWidget.Focus();
            }
            
            private void FocusInEvent (object sender, EventArgs args)
            {
                  if (_window != null)
                  {
                        _window.UrgencyHint = false;
                        
                        if(_notebook != null && _currentWidget != null)
                        {
                              NotebookLabel label = _notebook.GetTabLabel(_currentWidget.NativeWidget) as NotebookLabel;
                              
                              if (label != null)
                                    label.QuietActivity ();
                              
                              _currentWidget.Focus();
                        }
                  }
            }
            
            private void DeleteEvent (object sender, DeleteEventArgs args)
            {
                  Close ();
                  Destroy ();
            }
            
            private void TabClosedEvent (IConversation conversation)
            {
                  RemoveConversation (conversation, true);
            }
            
            private void ToggleTabVisibility ()
            {
                  if (_notebook.NPages < 2)
                        _notebook.ShowTabs = false;
                  else
                        _notebook.ShowTabs = true;
            }
            
            private void PageSwitchedEvent (object sender, SwitchPageArgs args)
            {
                  _currentWidget = _widgets[(int)args.PageNum];
                  
                  NotebookLabel label = _notebook.GetTabLabel(_currentWidget.NativeWidget) as NotebookLabel;
                  if (label != null)
                        label.QuietActivity ();
                  
                  GenerateTitle ();
                  
                  //regenerate the menu's
                  WindowUtility<Widget>.LastConversationProtocol = _currentWidget.Conversation.Session.Account.Protocol;
                  
                  _currentWidget.SwitchTo ();
                  
                  // add the accel group after SwitchTo so that the menu has chance to be created
                  if (_accelGroup != null)
                        _window.RemoveAccelGroup (_accelGroup);
                  
                  _accelGroup = MenuUtility.GetAccelGroup (_window);
                  _window.AddAccelGroup (_accelGroup);
                  
                  _currentWidget.Focus ();
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index