diff --git a/Programs/GridProxyGUI/GridProxyGUI.csproj b/Programs/GridProxyGUI/GridProxyGUI.csproj
index 2436b8f4..b3b08437 100755
--- a/Programs/GridProxyGUI/GridProxyGUI.csproj
+++ b/Programs/GridProxyGUI/GridProxyGUI.csproj
@@ -94,6 +94,7 @@
+
diff --git a/Programs/GridProxyGUI/MainWindow.cs b/Programs/GridProxyGUI/MainWindow.cs
index 6dadc208..72030c7d 100755
--- a/Programs/GridProxyGUI/MainWindow.cs
+++ b/Programs/GridProxyGUI/MainWindow.cs
@@ -1,8 +1,8 @@
+using GridProxyGUI;
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using Gtk;
-using GridProxyGUI;
using OpenMetaverse.Packets;
using Logger = OpenMetaverse.Logger;
using System.Timers;
@@ -35,11 +35,12 @@ public partial class MainWindow : Gtk.Window
: base(Gtk.WindowType.Toplevel)
{
Build();
+ LoadSavedSettings();
+
ProxyLogger.Init();
ProxyLogger.OnLogLine += new ProxyLogger.Log(Logger_OnLogLine);
tabsMain.Page = 0;
- mainSplit.Position = 600;
string font;
if (PlatformDetection.IsMac)
@@ -322,17 +323,47 @@ public partial class MainWindow : Gtk.Window
plugins.Store.Clear();
}
- protected void OnDeleteEvent(object sender, DeleteEventArgs a)
+ void LoadSavedSettings()
+ {
+ if (Options.Instance.ContainsKey("main_split_pos"))
+ {
+ mainSplit.Position = Options.Instance["main_split_pos"];
+ mainSplit.PositionSet = true;
+ }
+ if (Options.Instance.ContainsKey("main_width"))
+ {
+ Resize(Options.Instance["main_width"], Options.Instance["main_height"]);
+ Move(Options.Instance["main_x"], Options.Instance["main_y"]);
+ }
+ }
+
+ void OnQuit()
{
StopProxy();
+ Options.Instance["main_split_pos"] = mainSplit.Position;
+ int x, y;
+
+ GetSize(out x, out y); ;
+ Options.Instance["main_width"] = x;
+ Options.Instance["main_height"] = y;
+
+ GetPosition(out x, out y);
+ Options.Instance["main_x"] = x;
+ Options.Instance["main_y"] = y;
+
+ Options.Instance.Save();
Application.Quit();
+ }
+
+ protected void OnDeleteEvent(object sender, DeleteEventArgs a)
+ {
+ OnQuit();
a.RetVal = true;
}
protected void OnExitActionActivated(object sender, EventArgs e)
{
- StopProxy();
- Application.Quit();
+ OnQuit();
}
protected void OnBtnStartClicked(object sender, EventArgs e)
@@ -671,4 +702,5 @@ public partial class MainWindow : Gtk.Window
plugins.LoadPlugin(proxy.Proxy);
}
-}
\ No newline at end of file
+
+}
diff --git a/Programs/GridProxyGUI/Options.cs b/Programs/GridProxyGUI/Options.cs
new file mode 100755
index 00000000..ba3b4199
--- /dev/null
+++ b/Programs/GridProxyGUI/Options.cs
@@ -0,0 +1,256 @@
+//
+// Radegast Metaverse Client
+// Copyright (c) 2009-2013, Radegast Development Team
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the application "Radegast", nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// $Id$
+//
+using System;
+using System.Collections.Generic;
+using System.Collections;
+using System.IO;
+using System.Xml;
+using System.Threading;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+
+namespace GridProxyGUI
+{
+ public class Options : IDictionary
+ {
+ string SettingsFile;
+ OSDMap SettingsData;
+ Timer SaveTimer;
+ int SaveDelay = 10000;
+
+ public delegate void SettingChangedCallback(object sender, SettingsEventArgs e);
+ public event SettingChangedCallback OnSettingChanged;
+
+ static Options instance;
+ public static Options Instance
+ {
+ get
+ {
+ if (instance == null)
+ {
+ throw new NullReferenceException("Using instance of setting without call to CreateInstance() first");
+ }
+ return instance;
+ }
+ }
+
+ public Options(string fileName)
+ {
+ Init(fileName);
+ }
+
+ public static void CreateInstance(string fileName)
+ {
+ instance = new Options(fileName);
+ }
+
+ public void Init(string fileName)
+ {
+ SettingsFile = fileName;
+
+ try
+ {
+ string xml = File.ReadAllText(SettingsFile);
+ SettingsData = (OSDMap)OSDParser.DeserializeLLSDXml(xml);
+ }
+ catch
+ {
+ Logger.DebugLog("Failed openning setting file: " + fileName);
+ SettingsData = new OSDMap();
+ Save();
+ }
+
+ SaveTimer = new Timer((state) => Save(), this, Timeout.Infinite, Timeout.Infinite);
+ }
+
+ public void SaveDelayed()
+ {
+ SaveTimer.Change(SaveDelay, Timeout.Infinite);
+ }
+
+ public void Save()
+ {
+ try
+ {
+ File.WriteAllText(SettingsFile, SerializeLLSDXmlStringFormated(SettingsData));
+ }
+ catch (Exception ex)
+ {
+ Logger.Log("Failed saving settings", Helpers.LogLevel.Warning, ex);
+ }
+ }
+
+ public static string SerializeLLSDXmlStringFormated(OSD data)
+ {
+ using (StringWriter sw = new StringWriter())
+ {
+ using (XmlTextWriter writer = new XmlTextWriter(sw))
+ {
+ writer.Formatting = Formatting.Indented;
+ writer.Indentation = 4;
+ writer.IndentChar = ' ';
+
+ writer.WriteStartElement(String.Empty, "llsd", String.Empty);
+ OSDParser.SerializeLLSDXmlElement(writer, data);
+ writer.WriteEndElement();
+
+ writer.Close();
+
+ return sw.ToString();
+ }
+ }
+ }
+
+ private void FireEvent(string key, OSD val)
+ {
+ if (OnSettingChanged != null)
+ {
+ try { OnSettingChanged(this, new SettingsEventArgs(key, val)); }
+ catch (Exception) { }
+ }
+ }
+
+ #region IDictionary Implementation
+
+ public int Count { get { return SettingsData.Count; } }
+ public bool IsReadOnly { get { return false; } }
+ public ICollection Keys { get { return SettingsData.Keys; } }
+ public ICollection Values { get { return SettingsData.Values; } }
+ public OSD this[string key]
+ {
+ get
+ {
+ return SettingsData[key];
+ }
+ set
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ Logger.DebugLog("Warning: trying to set an emprty setting: " + Environment.StackTrace.ToString());
+ }
+ else
+ {
+ SettingsData[key] = value;
+ FireEvent(key, value);
+ SaveDelayed();
+ }
+ }
+ }
+
+ public bool ContainsKey(string key)
+ {
+ return SettingsData.ContainsKey(key);
+ }
+
+ public void Add(string key, OSD llsd)
+ {
+ SettingsData.Add(key, llsd);
+ FireEvent(key, llsd);
+ SaveDelayed();
+ }
+
+ public void Add(KeyValuePair kvp)
+ {
+ SettingsData.Add(kvp.Key, kvp.Value);
+ FireEvent(kvp.Key, kvp.Value);
+ SaveDelayed();
+ }
+
+ public bool Remove(string key)
+ {
+ bool ret = SettingsData.Remove(key);
+ FireEvent(key, null);
+ SaveDelayed();
+ return ret;
+ }
+
+ public bool TryGetValue(string key, out OSD llsd)
+ {
+ return SettingsData.TryGetValue(key, out llsd);
+ }
+
+ public void Clear()
+ {
+ SettingsData.Clear();
+ SaveDelayed();
+ }
+
+ public bool Contains(KeyValuePair kvp)
+ {
+ // This is a bizarre function... we don't really implement it
+ // properly, hopefully no one wants to use it
+ return SettingsData.ContainsKey(kvp.Key);
+ }
+
+ public void CopyTo(KeyValuePair[] array, int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Remove(KeyValuePair kvp)
+ {
+ bool ret = SettingsData.Remove(kvp.Key);
+ FireEvent(kvp.Key, null);
+ SaveDelayed();
+ return ret;
+ }
+
+ public System.Collections.IDictionaryEnumerator GetEnumerator()
+ {
+ return SettingsData.GetEnumerator();
+ }
+
+ IEnumerator> IEnumerable>.GetEnumerator()
+ {
+ return null;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return SettingsData.GetEnumerator();
+ }
+
+ #endregion IDictionary Implementation
+
+ }
+
+ public class SettingsEventArgs : EventArgs
+ {
+ public string Key = string.Empty;
+ public OSD Value = new OSD();
+
+ public SettingsEventArgs(string key, OSD val)
+ {
+ Key = key;
+ Value = val;
+ }
+ }
+}
diff --git a/Programs/GridProxyGUI/Program.cs b/Programs/GridProxyGUI/Program.cs
index fa143bb7..ad00bf26 100644
--- a/Programs/GridProxyGUI/Program.cs
+++ b/Programs/GridProxyGUI/Program.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using System.Diagnostics;
using Gtk;
@@ -10,6 +11,7 @@ namespace GridProxyGUI
{
try
{
+ InitLogging();
StartGtkApp();
}
catch (Exception ex)
@@ -29,6 +31,28 @@ namespace GridProxyGUI
win.Show();
Application.Run();
}
+
+ static bool InitLogging()
+ {
+ try
+ {
+ string userDir = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData), "GridProxyGUI");
+
+ if (!Directory.Exists(userDir))
+ {
+ Directory.CreateDirectory(userDir);
+ }
+
+ string settingsFile = Path.Combine(userDir, "Settings.xml");
+ Options.CreateInstance(settingsFile);
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
}
public static class NativeApi
@@ -62,7 +86,7 @@ namespace GridProxyGUI
}
else
{
- LinuxMessageBox(title, msg + @" foo ""bar"" baz", "error");
+ LinuxMessageBox(title, msg, "error");
}
Environment.Exit(exitCode);
diff --git a/Programs/GridProxyGUI/gtk-gui/MainWindow.cs b/Programs/GridProxyGUI/gtk-gui/MainWindow.cs
index 7888798a..00ed789b 100755
--- a/Programs/GridProxyGUI/gtk-gui/MainWindow.cs
+++ b/Programs/GridProxyGUI/gtk-gui/MainWindow.cs
@@ -240,7 +240,7 @@ public partial class MainWindow
this.mainSplit = new global::Gtk.HPaned ();
this.mainSplit.CanFocus = true;
this.mainSplit.Name = "mainSplit";
- this.mainSplit.Position = 500;
+ this.mainSplit.Position = 600;
// Container child mainSplit.Gtk.Paned+PanedChild
this.vboxSessions = new global::Gtk.VBox ();
this.vboxSessions.Name = "vboxSessions";
diff --git a/Programs/GridProxyGUI/gtk-gui/gui.stetic b/Programs/GridProxyGUI/gtk-gui/gui.stetic
index 3a09ab84..cb77c84e 100644
--- a/Programs/GridProxyGUI/gtk-gui/gui.stetic
+++ b/Programs/GridProxyGUI/gtk-gui/gui.stetic
@@ -222,7 +222,7 @@ http://login.orgrid.org/
True
- 500
+ 600