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

MainWindow.cs

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

using Gdk;
using Gtk;
using Glade;

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

using Anculus.Core;
using Anculus.Gui;

using Mono.Addins;

namespace Galaxium.Client.GtkGui
{
      public class MainWindow : IControllerWindow<Widget>
      {
            public event EventHandler VisibleChanged;
            
            [Widget ("MainWindow")]
            private Gtk.Window _main_window;
            [Widget ("menubar")]
            private MenuBar _menu_bar;
            [Widget ("toolbar")]
            private Toolbar _toolbar;
            [Widget ("vbox")]
            private VBox _vbox;
            [Widget ("image")]
            private Gtk.Image _image;
            [Widget ("imageSeparator")]
            private Gtk.HSeparator _image_separator;
            [Widget ("accountBox")]
            private VBox _account_box;
            [Widget ("hboxSessions")]
            private HBox _sessions_hbox;
            [Widget ("lblType")]
            private Label _type_label;
            [Widget ("btnConnect")]
            private Button _connect_button;
            [Widget ("btnDisconnect")]
            private Button _disconnect_button;
            [Widget ("notebook")]
            private Notebook _notebook;
            [Widget ("displayImgBox")]
            private HBox _display_image_box;
            
            const string _menu_path = "/Galaxium/Gui/MainWindow/Menu";
            
            private ImageView _display_image;
            private ImageComboBox<ISession> _sessions_combo;
            private ImageComboBox<IProtocol> _protocols_combo;
            
            private IAccountWidget<Widget> _current_account_widget;
            
            private Dictionary<ISession, int> _page_lookup = new Dictionary<ISession, int> ();
            private Dictionary<ISession, ISessionWidget<Widget>> _widget_lookup = new Dictionary<ISession, ISessionWidget<Widget>> ();
            
            private int _last_page = 0;
            IConfigurationSection _config = Configuration.ContactList.Section;
            int _window_x = 0, _window_y = 0, _window_w = 0, _window_h = 0;
            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 int _auto_connecting = 0;
            
            private System.Timers.Timer _shake_timer = new System.Timers.Timer (25);
            
            public bool Visible
            {
                  get { return(_main_window.Visible); }
                  set
                  {
                        if (value == _main_window.Visible)
                              return;
                        
                        if (!value)
                        {
                              _main_window.GetPosition(out _window_x, out _window_y);
                              _main_window.GetSize(out _window_w, out _window_h);
                        }
                        else
                        {
                              _main_window.Move(_window_x, _window_y);
                              _main_window.Resize (_window_w, _window_h);
                        }
                        
                        _main_window.Visible = value;
                        
                        if (VisibleChanged != null)
                              VisibleChanged(this, EventArgs.Empty);
                  }
            }
            
            public Widget Menubar
            {
                  get { return _menu_bar; }
            }
            
            public Widget Toolbar
            {
                  get { return _toolbar; }
            }
            
            public MainWindow ()
            {
                  _page_lookup = new Dictionary<ISession, int> ();
                  _widget_lookup = new Dictionary<ISession, ISessionWidget<Widget>> ();
                  
                  XML.CustomHandler = new XMLCustomWidgetHandler (CreateCustomWidget);
                  XML gxml = new XML (GladeUtility.GetGladeResourceStream (typeof (MainWindow).Assembly, "MainWindow.glade"), null, null);
                  gxml.Autoconnect (this);
                  
                  _main_window.Icon = IconUtility.GetIcon ("galaxium-contactlist", IconSizes.Large);
                  _main_window.AddAccelGroup (MenuUtility.GetAccelGroup (_main_window));
                  
                  _connect_button.Image = new Gtk.Image (IconUtility.GetIcon ("galaxium-start", IconSizes.Small));
                  _disconnect_button.Image = new Gtk.Image (IconUtility.GetIcon ("galaxium-stop", IconSizes.Small));
                  _image.Pixbuf = IconUtility.GetIcon ("galaxium-banner", IconSizes.Other);
                  
                  _protocols_combo.Changed += new EventHandler (SelectedProtocolChanged);
                  
                  foreach (IProtocol protocol in ProtocolUtility.Protocols)
                        _protocols_combo.Append (protocol);
                  
                  string last_protocol_name = Configuration.Protocol.Section.GetString (Configuration.Protocol.LastUsed.Name, Configuration.Protocol.LastUsed.Default);
                  IProtocol lastProtocol = string.IsNullOrEmpty (last_protocol_name) ? null : ProtocolUtility.GetProtocol (last_protocol_name);
                  
                  if (lastProtocol != null)
                        _protocols_combo.Select (lastProtocol);
                  else
                        _protocols_combo.SelectFirst ();
                  
                  _window_x = _config.GetInt ("X", 0);
                  _window_y = _config.GetInt ("Y", 0);
                  _window_w = _config.GetInt ("W", 275);
                  _window_h = _config.GetInt ("H", 400);
                  
                  if (_config.GetBool (Configuration.ContactList.ShowOnStartup.Name, Configuration.ContactList.ShowOnStartup.Default))
                  {
                        _config.SetBool (Configuration.ContactList.ShowOnStartup.Name, true);
                        Visible = true;
                  }
                  
                  UpdateMenu ();
                  
                  _toolbar.Hide ();
                  
                  AddinManager.ExtensionChanged += OnExtensionChanged;
                  
                  SetSwitcherStatus (false);
                  ActivityUtility.Ready = true;
                  
                  // Now that we have finished setting up the window, lets try and
                  // connect the list of connections we should connect rightaway.
                  
                  foreach (IAccount account in AccountUtility.Accounts)
                  {
                        if(account.AutoConnect)
                        {
                              // When we are auto-connecting accounts, we shouldn't let the user connect more just yet.
                              _auto_connecting++;
                              
                              if (_current_account_widget != null)
                                    _current_account_widget.DisableFields (false);
                              
                              IAccountWidget<Widget> account_widget = ProtocolGuiUtility.CreateAccountWidget<Widget> (account.Protocol);
                              account_widget.Initialize ();
                              
                              account_widget.CreateSessionWidget += AccountWidgetCreateSessionWidget;
                              account_widget.CloseSessionWidget += AccountWidgetCloseSessionWidget;
                              account_widget.ShowLastSessionWidget += AccountWidgetShowLastSessionWidget;
                              account_widget.ShowSessionWidget += AccountWidgetShowSessionWidget;
                              account_widget.EnableChange += AccountEnableChange;
                              account_widget.DisableChange += AccountDisableChange;
                              account_widget.AccountChanged += AccountWidgetAccountChanged;
                              
                              account_widget.SelectAccount (account.UniqueIdentifier);
                              
                              account_widget.Connect ();
                        }
                  }
            }
            
            public static void ExecuteEntryPoint (params object[] args)
            {
                  Application.Init ();
                  
                  //Dispatch.Initialize (new GtkGuiDispatcher ());
                  ThreadUtility.Dispatcher = new GtkThreadDispatcher ();
                  
                  GtkUtility.Initialize ();
                  ClientUtility.Initialize();
                  EmoticonUtility.Initialize();
                  SoundSetUtility.Initialize();
                  
                  GalaxiumUtility.Initialize (new MainWindow ());
                  
                  WindowUtility<Widget>.Initialize(new GtkWindowUtility());
                  
                  GtkActivityUtility.Initialize();
                  
                  GLib.ExceptionManager.UnhandledException += delegate (GLib.UnhandledExceptionArgs ea) {
                        Exception ex = ea.ExceptionObject as Exception;
                        
                        Log.Fatal (ex, "Uncaught GLib exception.");
                  };
                  
                  Log.Debug ("Application initialized, continuing...");
                  
                  Application.Run ();
            }
            
            internal void Shutdown ()
            {
                  SaveWindowLocation ();
                  GalaxiumUtility.TransferWindow.SaveWindowLocation();
                  
                  WindowUtility<Widget>.CloseAll ();
                  
                  EmoticonUtility.Shutdown();
                  SoundSetUtility.Shutdown();
                  ClientUtility.Shutdown ();
                  AddinUtility.Shutdown ();
                  
                  _main_window.Destroy ();
                  GalaxiumUtility.TransferWindow.Destroy ();
                  
                  Application.Quit ();
            }
            
            public void ShowAccountWidget ()
            {
                  SwitchView (ControllerViews.Account);
            }
            
            public void CloseActiveSession ()
            {
                  if (SessionUtility.ActiveSession != null)
                  {
                        WindowUtility<Widget>.RemoveWindows (SessionUtility.ActiveSession);
                        
                        SessionUtility.ActiveSession.Disconnect ();
                  }
            }
            
            public void CloseAllSessions ()
            {
                  List<ISession> sessions = new List<ISession> (SessionUtility.Sessions);
                  
                  foreach (ISession session in sessions)
                        session.Disconnect ();
            }
            
            public void UpdateAll ()
            {
                  UpdateMenu ();
                  
                  foreach (ISession session in SessionUtility.Sessions)
                  {
                        if (_widget_lookup.ContainsKey (session))
                              _widget_lookup[session].Update ();
                  }
            }
            
            internal ISessionWidget<Widget> GetSessionWidget (ISession session)
            {
                  int index;
                  
                  if (_page_lookup.TryGetValue (session, out index))
                        return _notebook.GetNthPage (index) as ISessionWidget<Widget>;
                  
                  return null;
            }
            
            private Widget CreateCustomWidget (XML gxml, string func_name, string name, string string1, string string2, int int1, int int2)
            {
                  if (name == "cboSessionPlaceHolder")
                  {
                        _sessions_combo = new ImageComboBox<ISession> (new ImageComboTextLookup<ISession> (SessionTextLookup), new ImageComboPixbufLookup<ISession> (SessionImageLookup));
                        _sessions_combo.Changed += new EventHandler (SessionsChanged);
                        _sessions_combo.Show();
                        return _sessions_combo;
                  }
                  else if (name == "cboProtocolPlaceHolder")
                  {
                        _protocols_combo = new ImageComboBox<IProtocol> (new ImageComboTextLookup<IProtocol> (ProtocolTextLookup), new ImageComboPixbufLookup<IProtocol> (ProtocolImageLookup));
                        _protocols_combo.Show();
                        return _protocols_combo;
                  }
                  else if (name == "displayImgPlaceHolder")
                  {
                        _display_image = new ImageView ();
                        _display_image.SetSizeRequest (96, 96);
                        _display_image.ShowAll ();
                        return _display_image;
                  }
                  
                  return new Label ("ERROR");
            }
            
            public void GenerateAlert ()
            {
                  if (!_main_window.HasFocus)
                        _main_window.UrgencyHint = true;
            }
            
            private void SaveWindowLocation ()
            {
                  if (_main_window.Visible)
                  {
                        int x, y, w, h;
                        _main_window.GetSize (out w, out h);
                        _main_window.GetPosition (out x, out y);
                        
                        _config.SetInt ("X", x);
                        _config.SetInt ("Y", y);
                        _config.SetInt ("W", w);
                        _config.SetInt ("H", h);
                  }
            }
            
            public void Shake ()
            {
                  _main_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];
                  
                        _main_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)
                  {
                              _main_window.Move(_shake_x, _shake_y);
                        
                        lock (_shake_timer)
                              _shake_timer.Stop();
                        
                        _shake_count = 20;
                  }
            }
            
            public void UpdateMenu ()
            {
                  MenuUtility.FillMenuBar (_menu_path, new DefaultExtensionContext (_main_window), _menu_bar);
            }
            
            public enum ControllerViews { Account, Session };
            
            private void SwitchView (ControllerViews view)
            {
                  // This assumes that the SessionUtility.ActiveSession is already
                  // set to the proper session we would want to view.
                  
                  switch (view)
                  {
                        case ControllerViews.Account:
                              if (_current_account_widget != null)
                                    _current_account_widget.Clear ();
                              
                              _notebook.Page = 0;
                              
                              SetSwitcherStatus (false);
                              
                              UpdateMenu ();
                              
                              SwitchDisplayImage (_current_account_widget.Account);
                              break;
                        
                        case ControllerViews.Session:
                              if (SessionUtility.ActiveSession == null)
                              {
                                    SwitchView (ControllerViews.Account);
                                    return;
                              }
                              
                              if (_page_lookup.ContainsKey (SessionUtility.ActiveSession))
                              {
                                    _notebook.Page = _page_lookup[SessionUtility.ActiveSession];
                                    _sessions_combo.Select(SessionUtility.ActiveSession);
                                    
                                    SetSwitcherStatus (true);
                                    
                                    UpdateMenu ();
                                    
                                    // This should add to the main menu if needed.
                                    _widget_lookup[SessionUtility.ActiveSession].SwitchTo();
                              }
                              else
                              {
                                    SwitchView (ControllerViews.Account);
                                    return;
                              }
                              break;
                  }
            }
            
            public void SetSwitcherStatus (bool enabled)
            {
                  _sessions_hbox.Visible = enabled;
                  SessionUtility.AddingSession = !enabled;
            }
            
            private bool _using_default_image = false;
            
            private void SwitchDisplayImage (IAccount account)
            {
                  byte[] data = null;
                  Pixbuf pbuf = null;
                  
                  if ((account != null) && (account.DisplayImage != null))
                  {
                        data = account.DisplayImage.ImageBuffer;
                        _using_default_image = false;
                  }
                  else if (_using_default_image)
                        return;
                  
                  if ((data != null) && (data.Length > 0))
                  {
                        try
                        {
                              pbuf = new Pixbuf (data);
                        }
                        catch
                        {
                        }
                  }
                  
                  if (pbuf == null)
                  {
                        pbuf = IconUtility.GetIcon ("galaxium-displayimage");
                        _using_default_image = true;
                  }
                  else
                        _using_default_image = false;
                  
                  _display_image.FadeTo (PixbufUtility.GetScaledPixbuf (pbuf, 96, 96));
                  _display_image_box.ShowAll ();
            }
            
            private string SessionTextLookup (ISession item)
            {
                  return item.Account.UniqueIdentifier;
            }
            
            private Gdk.Pixbuf SessionImageLookup (ISession item)
            {
                  return IconUtility.GetIcon (item.Account.Protocol.Image, IconSizes.Small);
            }
            
            private string ProtocolTextLookup (IProtocol item)
            {
                  return item.Description;
            }
            
            private Gdk.Pixbuf ProtocolImageLookup (IProtocol item)
            {
                  return IconUtility.GetIcon (item.Image, IconSizes.Small);
            }
            
            private void RemoveSession (ISession session)
            {
                  int index = 0;
                  
                  if (_page_lookup.TryGetValue (session, out index))
                  {
                        _page_lookup.Remove (session);
                        
                        lock (_page_lookup)
                        {
                              foreach (KeyValuePair<ISession, int> pair in _page_lookup)
                              {
                                    if (pair.Value > index)
                                          _page_lookup[pair.Key] = pair.Value - 1;
                              }
                        }
                        
                        _notebook.RemovePage (index);
                        
                  }
                  
                  _sessions_combo.Remove (session);
                  SessionUtility.RemoveSession (session);
                  
                  session.Dispose ();
            }
            
            void OnExtensionChanged (object o, ExtensionEventArgs args)
            {
                  if (args.PathChanged(_menu_path))
                        UpdateMenu ();
            }
            
            private void OnMainWindowDelete (object sender, DeleteEventArgs args)
            {
                  args.RetVal = true;
                  GalaxiumUtility.MainWindow.Visible = !GalaxiumUtility.MainWindow.Visible;
            }
            
            private void OnConnectClicked (object sender, EventArgs args)
            {
                  ShowAccountWidget ();
            }
            
            private void OnDisconnectClicked (object sender, EventArgs args)
            {
                  CloseActiveSession ();
            }
            
            private void SessionsChanged (object sender, EventArgs e)
            {
                  SessionUtility.ActiveSession = _sessions_combo.GetSelectedItem ();
                  
                  SwitchView (ControllerViews.Session);
            }
            
            private void SelectedProtocolChanged (object sender, EventArgs e)
            {
                  if (_current_account_widget != null)
                  {
                        _account_box.Remove (_current_account_widget.NativeWidget);
                        _current_account_widget = null;
                  }
                  
                  IProtocol protocol = _protocols_combo.GetSelectedItem ();
                  
                  if (protocol != null)
                  {
                        _current_account_widget = ProtocolGuiUtility.CreateAccountWidget<Widget> (protocol);
                        _current_account_widget.Initialize ();
                        
                        _current_account_widget.CreateSessionWidget += AccountWidgetCreateSessionWidget;
                        _current_account_widget.CloseSessionWidget += AccountWidgetCloseSessionWidget;
                        _current_account_widget.ShowLastSessionWidget += AccountWidgetShowLastSessionWidget;
                        _current_account_widget.ShowSessionWidget += AccountWidgetShowSessionWidget;
                        _current_account_widget.EnableChange += AccountEnableChange;
                        _current_account_widget.DisableChange += AccountDisableChange;
                        _current_account_widget.AccountChanged += AccountWidgetAccountChanged;
                        
                        SwitchDisplayImage (_current_account_widget.Account);
                        
                        _account_box.PackStart (_current_account_widget.NativeWidget, true, true, 0);
                        _current_account_widget.ApplyParentLayout (_type_label);
                        
                        Configuration.Protocol.Section.SetString (Configuration.Protocol.LastUsed.Name, protocol.Name);
                  }
            }
            
            private void AccountWidgetCloseSessionWidget (object sender, SessionEventArgs args)
            {
                  _auto_connecting--;
                  
                  if (_auto_connecting >= 0)
                        if (_current_account_widget != null)
                              _current_account_widget.EnableFields ();
                  
                  RemoveSession (args.Session);
                  
                  SwitchView (ControllerViews.Session);
            }
            
            private void AccountWidgetShowLastSessionWidget (object sender, EventArgs args)
            {
                  SwitchView (ControllerViews.Session);
            }
            
            private void AccountWidgetShowSessionWidget (object sender, SessionEventArgs args)
            {
                  SessionUtility.ActiveSession = args.Session;
                  
                  SwitchView (ControllerViews.Session);
            }
            
            private void SessionWidgetActivateChatWidget (object sender, ChatEventArgs args)
            {
                  WindowUtility<Widget>.Activate(args.Conversation, true);
            }
            
            private void AccountWidgetCreateSessionWidget (object sender, SessionEventArgs args)
            {
                  IAccountWidget<Widget> aw = sender as IAccountWidget<Widget>;
                  ISessionWidget<Widget> widget = ProtocolGuiUtility.CreateSessionWidget<Widget> (aw.Protocol, this, args.Session);
                  widget.ActivateChatWidget += SessionWidgetActivateChatWidget;
                  widget.Initialize ();
                  
                  _notebook.AppendPage (widget.NativeWidget, new Label (String.Empty));
                  
                  int page = _notebook.NPages - 1;
                  _widget_lookup.Add(args.Session, widget);
                  _page_lookup.Add (args.Session, page);
                  _sessions_combo.Append (args.Session, false);
                  
                  SessionUtility.AddSession (args.Session);
                  SessionUtility.ActiveSession = args.Session;
                  
                  SwitchView (ControllerViews.Session);
                  
                  _last_page = page;
                  
                  // Now that we have the GUI aspect taken care of, we need to listen for certain
                  // events that we will be creating activities out of.
                  
                  args.Session.TransferInvitationSent += SessionTransferInvitationSent;
                  
                  ActivityUtility.EmitActivity (this, new EntityPresenceChangeActivity (args.Session.Account, args.Session.Account.Presence));
            }
            
            public void SessionTransferInvitationSent (object sender, FileTransferEventArgs args)
            {
                  FileTransferUtility.Add (args.FileTransfer);
                  
                  GalaxiumUtility.TransferWindow.Show ();
            }
            
            private void AccountEnableChange (object sender, EventArgs args)
            {
                  _protocols_combo.Sensitive = true;
            }
            
            private void AccountDisableChange (object sender, EventArgs args)
            {
                  _protocols_combo.Sensitive = false;
            }
            
            void AccountWidgetAccountChanged (object sender, AccountEventArgs args)
            {
                  SwitchDisplayImage (args.Account);
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index