1 // Smuxi - Smart MUltipleXed Irc
2 //
3 // Copyright (c) 2012-2013 Mirco Bauer <meebey@meebey.net>
4 //
5 // Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20 using System;
21 using System.Collections.Generic;
22 using Smuxi.Common;
23 using Smuxi.Engine;
24 using System.Runtime.InteropServices;
25 
26 namespace Smuxi.Frontend.Gnome
27 {
28     [System.ComponentModel.ToolboxItem(true)]
29     public partial class JoinWidget : Gtk.Bin
30     {
31 #if LOG4NET
32         private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
33 #endif
34         private const string ActiveNetworkConfigKey = "GNOME/JoinBar/ActiveNetwork";
35 
36         public EventHandler<EventArgs> Activated;
37 
38         public new bool HasFocus {
39             get {
40                 return f_ChatEntry.HasFocus;
41             }
42             set {
43                 f_ChatEntry.HasFocus = value;
44             }
45         }
46 
47         public string ActiveNetwork {
48             get {
49                 return f_NetworkComboBox.ActiveText;
50             }
51             set {
52                 var store = (Gtk.ListStore) f_NetworkComboBox.Model;
53                 var idx = 0;
54                 foreach (object[] row in store) {
55                     if ((string) row[0] == value) {
56                         f_NetworkComboBox.Active = idx;
57                         break;
58                     }
59                     idx++;
60                 }
61             }
62         }
63 
64         [DllImport("libgtk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
gtk_entry_set_icon_from_pixbuf(IntPtr entry, int pos, IntPtr pixbuf)65         static extern void gtk_entry_set_icon_from_pixbuf(IntPtr entry, int pos, IntPtr pixbuf);
66 
67         // Since: 2.16
68         // void gtk_entry_set_icon_tooltip_text(GtkEntry *entry, GtkEntryIconPosition icon_pos, const gchar *tooltip)
69         [DllImport("libgtk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
gtk_entry_set_icon_tooltip_text(IntPtr entry, int pos, IntPtr tooltip)70         static extern void gtk_entry_set_icon_tooltip_text(IntPtr entry, int pos, IntPtr tooltip);
71 
72         // Since: 3.2
73         // void gtk_entry_set_placeholder_text (GtkEntry *entry, const gchar *text)
74         [DllImport("libgtk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
gtk_entry_set_placeholder_text(IntPtr entry, string text)75         static extern void gtk_entry_set_placeholder_text(IntPtr entry, string text);
76 
JoinWidget()77         public JoinWidget()
78         {
79             Build();
80 
81             try {
82                 gtk_entry_set_icon_from_pixbuf(f_ChatEntry.Handle, 0, GroupChatView.IconPixbuf.Handle);
83             } catch (Exception ex) {
84 #if LOG4NET
85                 f_Logger.Error("JoinWidget(): gtk_entry_set_icon_from_pixbuf() failed!", ex);
86 #endif
87             }
88             try {
89                 var text = _("Enter which chat to join");
90                 IntPtr textPtr = GLib.Marshaller.StringToPtrGStrdup(text);
91                 gtk_entry_set_icon_tooltip_text(f_ChatEntry.Handle, 0, textPtr);
92                 GLib.Marshaller.Free(textPtr);
93             } catch (Exception ex) {
94 #if LOG4NET
95                 f_Logger.Error("JoinWidget(): gtk_entry_set_icon_tooltip_text() failed!", ex);
96 #endif
97             }
98             try {
99                 //gtk_entry_set_placeholder_text(f_ChatEntry.Handle, "Enter chat name...");
100             } catch (Exception ex) {
101 #if LOG4NET
102                 f_Logger.Error("JoinWidget(): gtk_entry_set_placeholder_text() failed!", ex);
103 #endif
104             }
105 
106             f_ChatEntry.Activated += delegate {
107                 OnActivated(EventArgs.Empty);
108             };
109             f_ChatEntry.KeyPressEvent += OnChatEntryKeyPressEvent;
110 
111             f_JoinButton.Clicked += delegate {
112                 OnActivated(EventArgs.Empty);
113             };
114         }
115 
InitNetworks(IList<string> networks)116         public void InitNetworks(IList<string> networks)
117         {
118             Trace.Call(networks);
119 
120             if (networks == null) {
121                 throw new ArgumentNullException("networks");
122             }
123 
124             f_NetworkComboBox.Clear();
125             var cell = new Gtk.CellRendererText();
126             f_NetworkComboBox.PackStart(cell, false);
127             f_NetworkComboBox.AddAttribute(cell, "text", 0);
128 
129             Gtk.ListStore store = new Gtk.ListStore(typeof(string));
130             foreach (string network in networks) {
131                 if (String.IsNullOrEmpty(network)) {
132                     continue;
133                 }
134                 store.AppendValues(network);
135             }
136             store.SetSortColumnId(0, Gtk.SortType.Ascending);
137             f_NetworkComboBox.Model = store;
138             var activeNetwork = (string) Frontend.FrontendConfig[ActiveNetworkConfigKey];
139             if (String.IsNullOrEmpty(activeNetwork)) {
140                 f_NetworkComboBox.Active = 0;
141             } else {
142                 ActiveNetwork = activeNetwork;
143             }
144             f_NetworkComboBox.Changed += (sender, e) => {
145                 Frontend.FrontendConfig[ActiveNetworkConfigKey] = ActiveNetwork;
146                 Frontend.FrontendConfig.Save();
147             };
148         }
149 
ApplyConfig(UserConfig config)150         public void ApplyConfig(UserConfig config)
151         {
152             if (config == null) {
153                 throw new ArgumentNullException("config");
154             }
155 
156             var servers = new ServerListController(config);
157             InitNetworks(servers.GetNetworks());
158         }
159 
GetChatLink()160         public Uri GetChatLink()
161         {
162             return new Uri(
163                 String.Format("smuxi://{0}/{1}",
164                               f_NetworkComboBox.ActiveText,
165                               f_ChatEntry.Text)
166             );
167         }
168 
Clear()169         public void Clear()
170         {
171             f_ChatEntry.Text = String.Empty;
172         }
173 
OnActivated(EventArgs e)174         protected virtual void OnActivated(EventArgs e)
175         {
176             if (Activated != null) {
177                 Activated(this, e);
178             }
179         }
180 
181         [GLib.ConnectBefore]
OnChatEntryKeyPressEvent(object o, Gtk.KeyPressEventArgs e)182         protected void OnChatEntryKeyPressEvent(object o, Gtk.KeyPressEventArgs e)
183         {
184             var key = e.Event.Key;
185             if ((e.Event.State & Gdk.ModifierType.ControlMask) != 0) {
186                 switch (key) {
187                     case Gdk.Key.x:
188                     case Gdk.Key.X:
189                         // ctrl + x is pressed
190                         e.RetVal = true;
191                         if (f_NetworkComboBox.Active ==
192                             f_NetworkComboBox.Model.IterNChildren() - 1) {
193                             f_NetworkComboBox.Active = 0;
194                         } else {
195                             f_NetworkComboBox.Active++;
196                         }
197                         break;
198                 }
199             }
200         }
201 
_(string msg)202         private static string _(string msg)
203         {
204             return Mono.Unix.Catalog.GetString(msg);
205         }
206     }
207 }
208