1 /* 2 * Smuxi - Smart MUltipleXed Irc 3 * 4 * Copyright (c) 2005-2013, 2015 Mirco Bauer <meebey@meebey.net> 5 * 6 * Full GPL License: <http://www.gnu.org/licenses/gpl.txt> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23 using System; 24 using System.Collections; 25 using System.Collections.Specialized; 26 using Mono.Unix; 27 using Smuxi.Engine; 28 using Smuxi.Common; 29 30 namespace Smuxi.Frontend.Gnome 31 { 32 public class EngineManagerDialog : Gtk.Dialog 33 { 34 #if LOG4NET 35 private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 36 #endif 37 private Gtk.ComboBox _ComboBox; 38 private Gtk.ListStore _ListStore; 39 private string _SelectedEngine; 40 private EngineManager _EngineManager; 41 private Gtk.Button _EditButton; 42 private Gtk.Button _DeleteButton; 43 new Gtk.Window Parent { get; set; } 44 45 public string SelectedEngine { 46 get { 47 Gtk.TreeIter iter; 48 if (!_ComboBox.GetActiveIter(out iter)) { 49 return null; 50 } 51 return (string) _ComboBox.Model.GetValue(iter, 0); 52 } set { 53 int i = 0; 54 foreach (object[] row in (Gtk.ListStore) _ComboBox.Model) { 55 if ((string) row[0] == value) { 56 _ComboBox.Active = i; 57 return; 58 } 59 i++; 60 } 61 throw new ArgumentException(_("Engine not found."), "value"); 62 } 63 } 64 EngineManagerDialog(Gtk.Window parent, EngineManager engineManager)65 public EngineManagerDialog(Gtk.Window parent, EngineManager engineManager) : 66 base(null, parent, Gtk.DialogFlags.Modal) 67 { 68 Trace.Call(parent, engineManager); 69 70 if (engineManager == null) { 71 throw new ArgumentNullException("engineManager"); 72 } 73 74 Parent = parent; 75 _EngineManager = engineManager; 76 77 Title = "Smuxi - " + _("Engine Manager"); 78 SetPosition(Gtk.WindowPosition.CenterAlways); 79 80 var connect_button = new Gtk.Button(Gtk.Stock.Connect); 81 AddActionWidget(connect_button, 1); 82 83 AddActionWidget(new Gtk.Button(Gtk.Stock.New), 3); 84 85 Gtk.Button edit_button = new Gtk.Button(Gtk.Stock.Edit); 86 _EditButton = edit_button; 87 AddActionWidget(edit_button, 2); 88 89 _DeleteButton = new Gtk.Button(Gtk.Stock.Delete); 90 AddActionWidget(_DeleteButton, 4); 91 AddActionWidget(new Gtk.Button(Gtk.Stock.Quit), 5); 92 Response += new Gtk.ResponseHandler(_OnResponse); 93 94 Gtk.VBox vbox = new Gtk.VBox(); 95 Gtk.Label label = new Gtk.Label("<b>" + 96 _("Select which Smuxi engine you want to connect to") + 97 "</b>"); 98 label.UseMarkup = true; 99 vbox.PackStart(label, false, false, 5); 100 101 Gtk.HBox hbox = new Gtk.HBox(); 102 hbox.PackStart(new Gtk.Label(_("Engine:")), false, false, 5); 103 104 _ListStore = new Gtk.ListStore(typeof(string)); 105 _ComboBox = new Gtk.ComboBox(); 106 Gtk.CellRendererText cell = new Gtk.CellRendererText(); 107 _ComboBox.PackStart(cell, false); 108 _ComboBox.AddAttribute(cell, "text", 0); 109 _ComboBox.Changed += new EventHandler(_OnComboBoxChanged); 110 _ComboBox.Model = _ListStore; 111 _InitEngineList(); 112 113 var lowBandWidthCheckBox = new Gtk.CheckButton(_("Use Low Bandwidth Mode")); 114 lowBandWidthCheckBox.Active = (bool) Frontend.FrontendConfig["UseLowBandwidthMode"]; 115 lowBandWidthCheckBox.Clicked += delegate { 116 Frontend.FrontendConfig["UseLowBandwidthMode"] = 117 lowBandWidthCheckBox.Active; 118 Frontend.FrontendConfig.Save(); 119 }; 120 121 hbox.PackStart(_ComboBox, true, true, 10); 122 123 vbox.PackStart(hbox, false, false, 10); 124 vbox.PackStart(lowBandWidthCheckBox); 125 126 VBox.Add(vbox); 127 128 ShowAll(); 129 } 130 _InitEngineList()131 private void _InitEngineList() 132 { 133 string[] engines = (string[])Frontend.FrontendConfig["Engines/Engines"]; 134 string default_engine = (string)Frontend.FrontendConfig["Engines/Default"]; 135 int item = 0; 136 _ListStore.Clear(); 137 _ListStore.AppendValues("<" + _("Local Engine") + ">"); 138 item++; 139 foreach (string engine in engines) { 140 _ListStore.AppendValues(engine); 141 if (engine == default_engine) { 142 _ComboBox.Active = item; 143 } 144 item++; 145 } 146 } 147 _OnResponse(object sender, Gtk.ResponseArgs e)148 private void _OnResponse(object sender, Gtk.ResponseArgs e) 149 { 150 Trace.Call(sender, e); 151 152 try { 153 #if LOG4NET 154 _Logger.Debug("_OnResponse(): ResponseId: "+e.ResponseId); 155 #endif 156 switch ((int)e.ResponseId) { 157 case 1: 158 _OnConnectButtonPressed(); 159 break; 160 case 2: 161 _OnEditButtonPressed(); 162 break; 163 case 3: 164 _OnNewButtonPressed(); 165 break; 166 case 4: 167 _OnDeleteButtonPressed(); 168 break; 169 case 5: 170 _OnQuitButtonPressed(); 171 break; 172 case (int)Gtk.ResponseType.DeleteEvent: 173 _OnDeleteEvent(); 174 break; 175 } 176 } catch (Exception ex) { 177 #if LOG4NET 178 _Logger.Error(ex); 179 #endif 180 CrashDialog.Show(this, ex); 181 } 182 } 183 _OnConnectButtonPressed()184 private void _OnConnectButtonPressed() 185 { 186 if (_SelectedEngine == null || _SelectedEngine == String.Empty) { 187 Gtk.MessageDialog md = new Gtk.MessageDialog(this, 188 Gtk.DialogFlags.Modal, Gtk.MessageType.Error, 189 Gtk.ButtonsType.Close, _("Please select an engine!")); 190 md.Run(); 191 md.Destroy(); 192 // Re-run the Dialog 193 Run(); 194 return; 195 } 196 197 if (_SelectedEngine == "<" + _("Local Engine") + ">") { 198 Frontend.InitLocalEngine(); 199 Frontend.ConnectEngineToGUI(); 200 Destroy(); 201 return; 202 } 203 204 string engine = _SelectedEngine; 205 try { 206 _EngineManager.Connect(engine); 207 var engineProtocolVersion = _EngineManager.EngineProtocolVersion; 208 var frontendProtocolVersion = new Version(0, 0); 209 if (engineProtocolVersion.Major != frontendProtocolVersion.Major) { 210 throw new ApplicationException( 211 String.Format( 212 _("Your frontend is not compatible with the engine!\n" + 213 "Engine Version: {0} Frontend Version: {1}\n" + 214 "Engine Protocol: {2} Frontend Protocol: {3}"), 215 _EngineManager.EngineAssemblyVersion, Frontend.Version, 216 engineProtocolVersion, frontendProtocolVersion 217 ) 218 ); 219 } 220 221 Frontend.Session = _EngineManager.Session; 222 Frontend.UserConfig = _EngineManager.UserConfig; 223 Frontend.EngineAssemblyVersion = _EngineManager.EngineAssemblyVersion; 224 Frontend.EngineProtocolVersion = _EngineManager.EngineProtocolVersion; 225 Frontend.ConnectEngineToGUI(); 226 } catch (Exception ex) { 227 #if LOG4NET 228 _Logger.Error(ex); 229 #endif 230 // clean-up 231 try { 232 _EngineManager.Disconnect(); 233 } catch (Exception disEx) { 234 #if LOG4NET 235 _Logger.Error(disEx); 236 #endif 237 } 238 239 string error_msg = ex.Message + "\n"; 240 if (ex.InnerException != null) { 241 error_msg += " [" + ex.InnerException.Message + "]\n"; 242 } 243 244 string msg; 245 msg = _("An error occurred while connecting to the engine!") + "\n\n"; 246 msg += String.Format(_("Engine URL: {0}") + "\n", 247 _EngineManager.EngineUrl); 248 249 msg += String.Format(_("Error: {0}"), error_msg); 250 251 Gtk.MessageDialog md = new Gtk.MessageDialog(this, Gtk.DialogFlags.Modal, 252 Gtk.MessageType.Error, Gtk.ButtonsType.Close, msg); 253 md.Run(); 254 md.Destroy(); 255 256 // Re-run the Dialog 257 Run(); 258 } 259 } 260 _OnNewButtonPressed()261 private void _OnNewButtonPressed() 262 { 263 EngineAssistant assistant = new EngineAssistant( 264 Parent, 265 Frontend.FrontendConfig 266 ); 267 assistant.Cancel += delegate { 268 assistant.Destroy(); 269 270 // Restart the Dialog 271 // HACK: holy shit, please refactor this mess! 272 var dialog = new EngineManagerDialog(Parent, _EngineManager); 273 dialog.Run(); 274 dialog.Destroy(); 275 }; 276 assistant.Close += delegate { 277 assistant.Destroy(); 278 279 // Restart the Dialog 280 // HACK: holy shit, please refactor this mess! 281 var dialog = new EngineManagerDialog(Parent, _EngineManager); 282 dialog.Run(); 283 dialog.Destroy(); 284 }; 285 assistant.ShowAll(); 286 } 287 _OnEditButtonPressed()288 private void _OnEditButtonPressed() 289 { 290 EngineAssistant assistant = new EngineAssistant( 291 Parent, 292 Frontend.FrontendConfig, 293 _SelectedEngine 294 ); 295 assistant.Cancel += delegate { 296 assistant.Destroy(); 297 298 // Restart the Dialog 299 // HACK: holy shit, please refactor this mess! 300 var dialog = new EngineManagerDialog(Parent, _EngineManager); 301 dialog.Run(); 302 dialog.Destroy(); 303 }; 304 assistant.Close += delegate { 305 assistant.Destroy(); 306 307 // Restart the Dialog 308 // HACK: holy shit, please refactor this mess! 309 var dialog = new EngineManagerDialog(Parent, _EngineManager); 310 dialog.Run(); 311 dialog.Destroy(); 312 }; 313 assistant.ShowAll(); 314 } 315 _OnDeleteButtonPressed()316 private void _OnDeleteButtonPressed() 317 { 318 string msg = String.Format( 319 _("Are you sure you want to delete the engine \"{0}\"?"), 320 _SelectedEngine); 321 Gtk.MessageDialog md = new Gtk.MessageDialog(this, Gtk.DialogFlags.Modal, 322 Gtk.MessageType.Warning, Gtk.ButtonsType.YesNo, msg); 323 int res = md.Run(); 324 md.Destroy(); 325 326 if ((Gtk.ResponseType)res == Gtk.ResponseType.Yes) { 327 _DeleteEngine(_SelectedEngine); 328 _InitEngineList(); 329 330 // Re-run the Dialog 331 Run(); 332 } 333 } 334 _DeleteEngine(string engine)335 private void _DeleteEngine(string engine) 336 { 337 StringCollection new_engines = new StringCollection(); 338 string[] current_engines = (string[])Frontend.FrontendConfig["Engines/Engines"]; 339 foreach (string eng in current_engines) { 340 if (eng != engine) { 341 new_engines.Add(eng); 342 } 343 } 344 string[] new_engines_array = new string[new_engines.Count]; 345 new_engines.CopyTo(new_engines_array, 0); 346 // UGLY: refactor this to a proper controller class, see ServerListController 347 Frontend.FrontendConfig["Engines/Engines"] = new_engines_array; 348 Frontend.FrontendConfig.Remove("Engines/"+engine+"/Username"); 349 Frontend.FrontendConfig.Remove("Engines/"+engine+"/Password"); 350 Frontend.FrontendConfig.Remove("Engines/"+engine+"/Hostname"); 351 Frontend.FrontendConfig.Remove("Engines/"+engine+"/Port"); 352 Frontend.FrontendConfig.Remove("Engines/"+engine+"/Channel"); 353 Frontend.FrontendConfig.Remove("Engines/"+engine+"/Formatter"); 354 Frontend.FrontendConfig.Remove("Engines/"+engine+"/UseSshTunnel"); 355 Frontend.FrontendConfig.Remove("Engines/"+engine+"/SshHostname"); 356 Frontend.FrontendConfig.Remove("Engines/"+engine+"/SshPort"); 357 Frontend.FrontendConfig.Remove("Engines/"+engine+"/SshUsername"); 358 Frontend.FrontendConfig.Remove("Engines/"+engine); 359 Frontend.FrontendConfig.Save(); 360 Frontend.FrontendConfig.Load(); 361 } 362 _OnQuitButtonPressed()363 private void _OnQuitButtonPressed() 364 { 365 Frontend.Quit(); 366 } 367 _OnDeleteEvent()368 private void _OnDeleteEvent() 369 { 370 Frontend.Quit(); 371 } 372 _OnComboBoxChanged(object sender, EventArgs e)373 private void _OnComboBoxChanged(object sender, EventArgs e) 374 { 375 Trace.Call(sender, e); 376 377 Gtk.TreeIter iter; 378 if (_ComboBox.GetActiveIter(out iter)) { 379 _SelectedEngine = (string )_ComboBox.Model.GetValue(iter, 0); 380 } 381 382 bool isLocalEngine = _SelectedEngine == "<" + _("Local Engine") + ">"; 383 _EditButton.Sensitive = !isLocalEngine; 384 _DeleteButton.Sensitive = !isLocalEngine; 385 } 386 _(string msg)387 private static string _(string msg) 388 { 389 return Mono.Unix.Catalog.GetString(msg); 390 } 391 } 392 } 393