using System; using System.Reflection; using System.Resources; using System.Diagnostics; using System.Collections; using System.IO; using Mono.Unix; using Gtk; namespace FSpot { public class ExceptionDialog : Dialog { private AccelGroup accel_group; private string debugInfo; public ExceptionDialog(Exception e) : base() { debugInfo = BuildExceptionMessage(e); HasSeparator = false; BorderWidth = 5; Resizable = false; Title = Catalog.GetString("F-Spot Encountered a Fatal Error"); VBox.Spacing = 12; ActionArea.Layout = ButtonBoxStyle.End; accel_group = new AccelGroup(); AddAccelGroup(accel_group); HBox hbox = new HBox(false, 12); hbox.BorderWidth = 5; VBox.PackStart(hbox, false, false, 0); Image image = new Image(Stock.DialogError, IconSize.Dialog); image.Yalign = 0.0f; hbox.PackStart(image, true, true, 0); VBox label_vbox = new VBox(false, 0); label_vbox.Spacing = 12; hbox.PackStart(label_vbox, false, false, 0); Label label = new Label(String.Format("{0}", GLib.Markup.EscapeText(Title))); label.UseMarkup = true; label.Justify = Justification.Left; label.LineWrap = true; label.SetAlignment(0.0f, 0.5f); label_vbox.PackStart(label, false, false, 0); label = new Label(e.Message); label.UseMarkup = true; label.Justify = Gtk.Justification.Left; label.LineWrap = true; label.SetAlignment(0.0f, 0.5f); label_vbox.PackStart(label, false, false, 0); Label details_label = new Label(String.Format("{0}", GLib.Markup.EscapeText(Catalog.GetString("Error Details")))); details_label.UseMarkup = true; Expander details_expander = new Expander("Details"); details_expander.LabelWidget = details_label; label_vbox.PackStart(details_expander, true, true, 0); ScrolledWindow scroll = new ScrolledWindow(); TextView view = new TextView(); scroll.HscrollbarPolicy = PolicyType.Automatic; scroll.VscrollbarPolicy = PolicyType.Automatic; scroll.AddWithViewport(view); scroll.SetSizeRequest(450, 250); view.Editable = false; view.Buffer.Text = debugInfo; details_expander.Add(scroll); hbox.ShowAll(); AddButton(Stock.Close, ResponseType.Close, true); } private void AddButton(string stock_id, Gtk.ResponseType response, bool is_default) { Button button = new Button(stock_id); button.CanDefault = true; button.Show(); AddActionWidget(button, response); if(is_default) { DefaultResponse = response; button.AddAccelerator("activate", accel_group, (uint)Gdk.Key.Return, 0, AccelFlags.Visible); } } private string BuildExceptionMessage(Exception e) { System.Text.StringBuilder msg = new System.Text.StringBuilder(); msg.Append(Catalog.GetString("An unhandled exception was thrown: ")); msg.Append(e.Message); msg.Append(String.Format("{0}{0}", Environment.NewLine)); msg.Append(e.StackTrace); msg.Append(Environment.NewLine); msg.Append(".NET Version: " + Environment.Version.ToString()); msg.Append(String.Format("{0}{0}Assembly Version Information:{0}{0}", Environment.NewLine)); foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { AssemblyName name = asm.GetName(); msg.Append(name.Name + " (" + name.Version.ToString () + ")" + Environment.NewLine); } msg.Append(Environment.NewLine + "Platform Information: " + BuildPlatformString()); msg.Append(String.Format("{0}{0}Distribution Information:{0}{0}", Environment.NewLine)); Hashtable lsb = LsbVersionInfo.Harvest; foreach(string lsbfile in lsb.Keys) { msg.Append("[" + lsbfile + "]" + Environment.NewLine); msg.Append(lsb[lsbfile] + Environment.NewLine); } return msg.ToString(); } private string BuildPlatformString() { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.Arguments = "-sirom"; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.UseShellExecute = false; foreach(string unameprog in new string [] { "/usr/bin/uname", "/bin/uname", "/usr/local/bin/uname", "/sbin/uname", "/usr/sbin/uname", "/usr/local/sbin/uname"}) { try { startInfo.FileName = unameprog; Process uname = Process.Start(startInfo); return uname.StandardOutput.ReadLine().Trim(); } catch(Exception) { continue; } } return null; } private class LsbVersionInfo { private string [] filesToCheck = { "*-release", "slackware-version", "debian_version" }; private Hashtable harvest = new Hashtable(); public LsbVersionInfo() { foreach(string pattern in filesToCheck) { foreach(string filename in Directory.GetFiles("/etc/", pattern)) { using(FileStream fs = File.OpenRead(filename)) { harvest[filename] = (new StreamReader(fs)).ReadToEnd(); } } } } public Hashtable Findings { get { return harvest; } } public static Hashtable Harvest { get { return (new LsbVersionInfo()).Findings; } } } } }